image


Выбор платформы для бекенда

Чтобы создать качественное и производительное Web-приложение, необходимо уделить должное внимание выбору платформы для разработки. Этим нужно заняться сразу же после того, как вы ознакомились, какие задачи должно выполнять это приложение.


В данном случае, немаловажным фактором в техническом задании была предположительно высокая нагрузка на сервис. На рынке есть много хороших инструментов, с помощью которых можно решить поставленную задачу. Некоторые мы используем в разработке, но в этот раз выбор все-таки пал на Yii2.


Если более детально рассматривать этот фреймворк, можно выделить ряд преимуществ:


  • Высокая производительность;
  • Удобство в работе с базами данных;
  • Кэширование страниц и отдельных фрагментов;
  • Перехват и обработка ошибок;
  • Аутентификация и авторизация;
  • Использование миграции базы данных облегчает командную работу.

Установив шаблон advanced, мы уже получаем некоторые необходимые нам возможности, такие как формы регистрации пользователей и входа на сайт с функциональностью восстановления забытого пароля. Еще одно значительное преимущество этого шаблона, – это то, что приложение делится на frontend (пользовательская часть) и backend (часть администратора).


При проектировании структуры приложения были принято решение разнести логические части на модули. Хотя некоторые модули и зависят друг от друга, модульное программирование позволяет удобно расширять и поддерживать код.


Выбор платформы для фронтенда

Так как наше приложение предполагает наличие множества интерактивных элементов управления, которые будут взаимодействовать друг с другом и с сервером, решили, что jQuery, который идет в коробке c шаблоном advanced, нужно усилить, добавив на фронтэнд AngularJS (потому что Angular для этого и создавался). Он позволяет вводить темплейтинг, не нарушая структуру самого HTML-документа.


Тем самым мы можем сделать верстку, потом добавить темплейт-атрибуты, но верстальщик сможет продолжать работу с документом так, как если бы это был статический HTML. То есть очень просто изменять дизайн в процессе разработки, не опираясь на определенную верстку и атрибуты class, либо id html-элементов. Это большой плюс, особенно, если хочется разделить работу над пользовательским интерфейсом. Эта особенность помогла нам распределить задачи в командной работе. Один человек верстает, второй вводит байндинги и привязывает вьюмодель к бекенду.


К преимуществам использования AngularJS можно отнести:


  • Довольно низкий порог вхождения;
  • Легкость построения сложных цепей зависимостей;
  • Параллельная работа в команде;
  • Возможность по максимуму использовать HTML атрибуты, минимизируя javascript код;
  • Хорошая поддержка со стороны компании и сообщества;
  • Простота работы с REST.

Реализация модульной структуры

Надеемся, что вы знакомы с Yii2 и уже писали хотя бы несколько приложений на этом фреймворке. Далее будем обращать внимание только на те решения, которые мы применили в нашем проекте.


Мы использовали шаблон advanced, ряд преимуществ которого был описан выше. Но уже на этом этапе, при установке yii2-app-advanced через composer, многие пользователи сталкиваются со следующей ошибкой при попытке открыть сайт в браузере:


The file or directory to be published does not exist: D:\OpenServer\domains\yii2-app-advanced/vendor\bower/jquery/dist
image
Необходимо установить composer asset plugin и решить проблему следующими командами:


cd /path/to/your/project
composer global require "fxp/composer-asset-plugin:~1.1"
composer update

Также проверьте, есть ли такие строки в вашем composer.json файле:


{   
    "extra": {
        "asset-installer-paths": {
            "npm-asset-library": "vendor/npm",
            "bower-asset-library": "vendor/bower"
        }
    }
}

Так как мы организовали модульную структуру приложения, первым делом добавим alias для нашей папки с модулями в файл \common\config\bootstrap.php


<?php
Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
Yii::setAlias('@modules', dirname(dirname(__DIR__)) . '/modules');

Теперь все модули, которые мы будим писать, будут располагаться в папке /modules.


Настало время создать первый модуль в этом проекте. Начнем с модуля, который будет отвечать за отоб��ажение основных страниц сайта, таких как “Главная страница”, страница контактов, 404 страница, страница “About us”. Для этого мы можем воспользоваться Gii генератором, который может написать код за нас.


Переходим в вашем браузере по ссылке и попадаем на главную страницу генератора.
image
На данном этапе вы, скорее всего, уже создали базу данных и внесли соответствующие настройки для подключения к ней в файл конфигурации \environments\dev\common\config\main-local.php


…
   'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=your-db-name',
            'username' => 'db-user-name',
            'password' => 'db-user-password',
            'charset' => 'utf8',
        ],
…

Нажимаем кнопку Start в блоке ‘Module Generator’ и попадаем в просмотр генерации модуля.


Заполняем два инпута следующим образом:


Module Class:
modules\site\Module
Module ID:
site

Жмем кнопку ‘Preview’, затем ‘Generate’ и смотрим, как создаются файлы первого модуля. Осталось только подключить его в конфигурационном файле так, как подсказывает Gii генератор.


Добавим следующие строки в файл \common\config\main.php


  ......
    'modules' => [
        'site' => [
            'class' => 'modules\site\Module',
        ],
    ],
    ......

И подправим конфигурационный файл фронтенда \frontend\config\main.php, добавив строчку:


 ......
    'defaultRoute' => 'site/site/index',
    ......

Она определяет то, что главная страница у нас находится по роуту 'site/site/index', то есть в нашем модуле Site.


В этом же файле мы удаляем строку


'controllerNamespace' => 'frontend\controllers'

Это необходимо сделать, потому что теперь в каждом модуле будут определяться свои неймспейсы для контроллеров. Поговорим об этом далее.


Так как мы хотим, чтобы наши модули были максимально независимы друг от друга, и их можно было использовать от проекта к проекту (одни модули подключать к проекту, а другие отключать), будем поддерживать в модуле функционал фронтенда и функционал управления контентом модуля в части администратора. Поэтому контроллеры, модели и view каждой из этих частей мы будем хранить в отдельных каталогах. Структура каталогов модуля будет следующая:


…
site
-- controllers
-- -- backend
-- -- frontend
-- models
    -- -- backend
    -- -- frontend
    -- views
    -- -- backend
    -- -- frontend
…

Соответственно, имеющиеся уже у нас в модуле контроллер и view, необходимо перенести в соответствующие папки frontend и не забыть изменить namespace в контроллере на namespace modules\site\controllers\frontend;


Код файла модуля мы перепишем так, чтобы было понятно, к какому контролеру ему обращаться при работе на фронтенде, и к какому при работе в панели администратора. Таким образом на фронтенде он будет обращаться к контроллеру в папке /modules/site/controllers/frontend, а при работе в админ-панели задействовать контроллер в папке /modules/site/controllers/backend.


<?php

namespace modules\site;

/**
 * site module definition class
 */
class Module extends \yii\base\Module
{
    /**
     * @inheritdoc
     */
    public $controllerNamespace = 'modules\site\controllers\frontend';

    /**
     * @var boolean Если модуль используется для админ-панели.
     */
    public $isBackend;

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();

        // Это здесь для того, чтобы переключаться между frontend и backend
        if ($this->isBackend === true) {
            $this->controllerNamespace = 'modules\site\controllers\backend';
            $this->setViewPath('@modules/site/views/backend');
        } else {
            $this->setViewPath('@modules/site/views/frontend');
        }
    }
}

А для того, чтобы настроить доступ к модулю site на бекенде, нужно обозначить его в конфигурационном файле бекенда \backend\config\main.php следующим образом:


...
   'modules' => [
        'site' => [
            'isBackend' => true,
        ]
    ],
...

и заменить строку


'controllerNamespace' => 'backend\controllers',

на


'defaultRoute' => 'site/site/index',

Теперь можно создавать контроллеры в папке /modules/site/controllers/backend для бекенда. Я перенесу контроллер SiteController.php с папки /backend/controllers в /modules/site/controllers/backend и заменю в нем namespace, соответственно.


После проведения манипуляций по рефакторингу существующих контроллеров, моделей и представлений и переноса их в наш модуль site, он стал преображаться и приобретать следующий вид:
image
B этой статье я постарался изложить все плюсы выбранных нами технологий для интересного крупного проекта, предложил способ реализации модульного приложения на Yii2 фреймворке. Это первый пост из цикла статей, в которых я хочу поделиться с вами всеми теми способами, которые мы использовали при решении различного рода нетипичных задач при разработке данного проекта.


В следующей статье я опишу настройку роутинга и создания URL при помощи urlManager для каждого модуля по отдельности. А также разложу по полочкам процесс создания собственных правил для специфических URL с помощью написания класса, который расширяет UrlRuleInterface.


Спасибо за внимание!


Материал подготовлен: greebn9k(Сергей Грибняк), pavel-berezhnoy(Павел Бережной), silmarilion(Андрей Хахарев)