Многие веб-разработчики рано или поздно задумываются: а не написать ли свою CMS? Готовые решения вроде WordPress или Joomla — это хорошо, но иногда хочется полного контроля и гибкости. Yii2 — отличный фреймворк для таких задач. В этой статье мы шаг за шагом разберём, как построить простую, но рабочую систему управления контентом на Yii2. Будет много кода и минимум воды.

Digital-студия WNDER

Почему именно Yii2?

Yii2 — это быстрый, безопасный и хорошо документированный PHP-фреймворк. Он следует парадигме MVC (Model-View-Controller), что упрощает поддержку кода. Для CMS это критично: нужно чётко разделять логику, данные и отображение. К тому же Yii2 имеет мощный генератор кода Gii, который ускоряет создание CRUD-операций.

Вот основные плюсы Yii2 для CMS:

  • Высокая производительность благодаря ленивой загрузке.
  • Встроенные механизмы кэширования, миграций, аутентификации.
  • Гибкая система виджетов и расширений.
  • Активное сообщество и подробная документация.
Правило: Не изобретайте велосипед. Если задача решается стандартными средствами Yii2 — используйте их. Например, для аутентификации берите готовый модуль yii2-user, а не пишите свою систему с нуля.

Проектирование базы данных

Любая CMS начинается с базы данных. Для управления контентом нам понадобятся как минимум три таблицы: articles (статьи), categories (категории) и users (пользователи). Можно добавить теги, комментарии, но для примера ограничимся этим.

Создадим миграции для таблиц. В Yii2 миграции — это способ версионирования схемы БД. Вот пример миграции для таблицы статей:

createTable('{{%articles}}', [
            'id' => $this->primaryKey(),
            'title' => $this->string()->notNull(),
            'content' => $this->text(),
            'category_id' => $this->integer(),
            'author_id' => $this->integer(),
            'created_at' => $this->integer(),
            'updated_at' => $this->integer(),
        ]);

        // Индексы
        $this->createIndex('idx-articles-category_id', '{{%articles}}', 'category_id');
        $this->createIndex('idx-articles-author_id', '{{%articles}}', 'author_id');

        // Внешние ключи
        $this->addForeignKey('fk-articles-category_id', '{{%articles}}', 'category_id', '{{%categories}}', 'id', 'SET NULL', 'CASCADE');
        $this->addForeignKey('fk-articles-author_id', '{{%articles}}', 'author_id', '{{%users}}', 'id', 'SET NULL', 'CASCADE');
    }

    public function down()
    {
        $this->dropTable('{{%articles}}');
    }
}

Аналогично создаются миграции для категорий и пользователей. Не забудьте выполнить php yii migrate в консоли.

Модели и CRUD

После создания таблиц генерируем модели через Gii. Это займёт пару минут. Для каждой таблицы Gii создаст класс с правилами валидации и связями. Например, модель Article будет иметь связь с категорией:

public function getCategory()
{
    return $this->hasOne(Category::class, ['id' => 'category_id']);
}

Далее генерируем CRUD-контроллеры и представления. Gii сделает это автоматически. Но чтобы CMS была удобной, нужно доработать формы и списки. Например, в форме создания статьи добавим выпадающий список категорий:

field($model, 'category_id')->dropDownList(
    ArrayHelper::map(Category::find()->all(), 'id', 'name'),
    ['prompt' => 'Выберите категорию']
) ?>

Для вывода списка статей в административной панели используем GridView с фильтрами и сортировкой. Yii2 предоставляет виджет GridView, который из коробки умеет пагинацию, сортировку и фильтрацию.

Лайфхак: Чтобы не писать однотипный код для каждой сущности, создайте базовый контроллер с общими действиями (например, actionIndex, actionCreate). Затем наследуйте от него остальные контроллеры.

Организация прав доступа

В CMS важно разграничивать права: администратор может всё, редактор — только создавать и редактировать статьи, автор — только свои статьи. В Yii2 есть RBAC (Role-Based Access Control). Настроим его через миграцию или вручную.

Сначала создадим разрешения и роли в консольном контроллере:

$auth = Yii::$app->authManager;

// Создаём разрешения
$createArticle = $auth->createPermission('createArticle');
$createArticle->description = 'Создать статью';
$auth->add($createArticle);

$updateArticle = $auth->createPermission('updateArticle');
$updateArticle->description = 'Редактировать статью';
$auth->add($updateArticle);

// Создаём роль "author"
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createArticle);
$auth->addChild($author, $updateArticle);

Затем в контроллере проверяем доступ через Yii::$app->user->can('createArticle'). Если прав нет — выбрасываем исключение ForbiddenHttpException.

Для удобства можно использовать поведение AccessControl в контроллере:

public function behaviors()
{
    return [
        'access' => [
            'class' => \yii\filters\AccessControl::class,
            'rules' => [
                [
                    'allow' => true,
                    'actions' => ['index', 'view'],
                    'roles' => ['@'],
                ],
                [
                    'allow' => true,
                    'actions' => ['create', 'update', 'delete'],
                    'roles' => ['author'],
                ],
            ],
        ],
    ];
}

Публичная часть и шаблоны

Админка — это хорошо, но CMS должна показывать контент посетителям. Создадим контроллер SiteController с действиями для главной страницы, просмотра статьи и категории. В представлениях используем шаблонизатор Twig или стандартный PHP. Yii2 по умолчанию работает с PHP, но можно подключить Twig.

Пример действия для вывода статьи:

public function actionView($id)
{
    $article = Article::findOne($id);
    if (!$article) {
        throw new NotFoundHttpException('Статья не найдена');
    }
    return $this->render('view', [
        'article' => $article,
    ]);
}

В представлении view.php выводим заголовок, контент, дату и категорию. Не забудьте про SEO: добавьте мета-теги через $this->registerMetaTag().

Для вывода списка статей с пагинацией используйте ActiveDataProvider и виджет LinkPager.

Совет: Кэшируйте часто запрашиваемые страницы. Yii2 поддерживает кэширование фрагментов и данных. Например, список категорий можно закэшировать на час.

Сравнение инструментов Yii2 для CMS

В процессе разработки вы будете использовать различные компоненты Yii2. Вот таблица с основными и их назначением:

Компонент Назначение Пример использования
Gii Генерация кода (модели, CRUD) Быстрое создание админки
RBAC Управление правами доступа Разделение ролей админ/редактор/автор
ActiveRecord Работа с БД через объекты Выборка статей, связей
GridView Отображение табличных данных Список статей в админке
Widget Переиспользуемые блоки Меню, хлебные крошки

Заключение

Создание CMS на Yii2 — задача не на один вечер, но вполне реальная. Главное — правильно спроектировать базу, использовать миграции, Gii и RBAC. Не бойтесь экспериментировать и добавлять свои модули. Yii2 даёт все инструменты для построения гибкой и безопасной системы управления контентом.

В итоге вы получите удобную админку, разграничение прав и публичную часть с кэшированием. А если что-то пойдёт не так — сообщество Yii2 всегда поможет.

Студия WNDER