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

Digital-студия WNDER

Почему Yii2, а не что-то ещё?

Прежде чем погружаться в код, давайте разберёмся, почему именно Yii2. Во-первых, это один из самых производительных PHP-фреймворков. Он быстрее многих конкурентов, а это важно, когда ваш сайт начнёт посещать много людей. Во-вторых, Yii2 имеет просто огромное количество готовых инструментов: ActiveRecord для работы с базой данных, встроенный генератор кода Gii, мощную систему виджетов и многое другое. В-третьих, он довольно прост в изучении, особенно если вы уже знакомы с ООП и базовыми принципами MVC. Ну и, конечно, огромное комьюнити — всегда можно найти ответ на любой вопрос.

Представьте, что вы строите дом. Можно взять готовый конструктор (как WordPress), а можно использовать кирпичи и цемент (Yii2) и построить именно то, что нужно. С Yii2 у вас полный контроль над архитектурой, и вы не ограничены чужими решениями.

С чего начать: установка и структура проекта

Для начала нам нужно установить Yii2. Проще всего это сделать через Composer. Если он у вас не установлен, самое время поставить — это менеджер пакетов для PHP, без него сейчас никуда. Откройте терминал и выполните команду:

composer create-project --prefer-dist yiisoft/yii2-app-advanced cms

Эта команда создаст проект с папкой cms и расширенной структурой (advanced). Она включает в себя три части: frontend (то, что видит посетитель), backend (админка) и common (общие файлы, например, модели). Это идеально для CMS: вы разделяете публичную часть и админ-панель.

После установки перейдите в папку проекта и запустите миграции для создания базовых таблиц:

php yii migrate

Теперь у вас есть базовая структура. Зайдите в backend и посмотрите, как выглядит стандартная админка. Она уже почти готова к работе, но мы добавим свои сущности.

Создаём модуль контента: CRUD на все случаи жизни

Самая главная часть CMS — это управление контентом. Обычно контент — это статьи, новости, страницы. Давайте создадим модуль для управления статьями. В Yii2 модуль — это отдельная подсистема, которая группирует связанные контроллеры, модели и представления.

Создадим модуль content в папке backend/modules. Для этого создадим файл ContentModule.php:

<?php
namespace backend\modules\content;

class ContentModule extends \yii\base\Module
{
    public $controllerNamespace = 'backend\modules\content\controllers';

    public function init()
    {
        parent::init();
        // custom initialization code goes here
    }
}

Теперь нам нужна модель для статей. Создадим её в папке common/models, чтобы и фронтенд, и бэкенд могли её использовать. Назовём её Article:

<?php
namespace common\models;

use Yii;
use yii\db\ActiveRecord;

class Article extends ActiveRecord
{
    public static function tableName()
    {
        return '{{%article}}';
    }

    public function rules()
    {
        return [
            [['title', 'content'], 'required'],
            [['content'], 'string'],
            [['title'], 'string', 'max' => 255],
            [['status'], 'integer'],
        ];
    }
}

Обратите внимание на метод rules() — здесь мы определяем правила валидации полей. Всё просто: заголовок и контент обязательны, заголовок не длиннее 255 символов, статус — целое число.

Теперь создадим контроллер в модуле contentArticleController.php. Он будет отвечать за действия CRUD (создание, чтение, обновление, удаление). В Yii2 есть готовый базовый контроллер для этого — CrudController, но мы напишем свой, чтобы показать логику:

<?php
namespace backend\modules\content\controllers;

use Yii;
use common\models\Article;
use yii\web\Controller;
use yii\web\NotFoundHttpException;

class ArticleController extends Controller
{
    public function actionIndex()
    {
        $articles = Article::find()->all();
        return $this->render('index', ['articles' => $articles]);
    }

    public function actionCreate()
    {
        $model = new Article();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }
        return $this->render('create', ['model' => $model]);
    }

    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }
        return $this->render('update', ['model' => $model]);
    }

    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
        return $this->redirect(['index']);
    }

    public function actionView($id)
    {
        return $this->render('view', ['model' => $this->findModel($id)]);
    }

    protected function findModel($id)
    {
        if (($model = Article::findOne($id)) !== null) {
            return $model;
        }
        throw new NotFoundHttpException('Статья не найдена.');
    }
}

Как видите, ничего сложного. Каждый метод отвечает за одно действие. В реальном проекте вы бы использовали Gii для генерации всего этого кода автоматически, но сейчас мы делаем руками, чтобы понять суть.

Представления: делаем удобную админку

Теперь нужно создать представления (views) для нашего контроллера. В папке backend/modules/content/views/article создадим файлы index.php, create.php, update.php, view.php. Не буду приводить полный код, чтобы не раздувать статью, но покажу основные моменты.

В index.php выводим список статей с ссылками на редактирование и удаление:

<?php
use yii\helpers\Html;
use yii\grid\GridView;
?>

<h1>Статьи</h1>
<p><?= Html::a('Создать статью', ['create'], ['class' => 'btn btn-success']) ?></p>

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        'title',
        'status',
        [
            'class' => 'yii\grid\ActionColumn',
        ],
    ],
]) ?>

В create.php и update.php используем форму с полями:

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>

<h1><?= Html::encode($this->title) ?></h1>

<?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'title') ?>
    <?= $form->field($model, 'content')->textarea(['rows' => 6]) ?>
    <?= $form->field($model, 'status')->dropDownList([0 => 'Черновик', 1 => 'Опубликовано']) ?>

    <div class="form-group">
        <?= Html::submitButton('Сохранить', ['class' => 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>

Не забывайте, что для корректной работы нужно настроить маршрутизацию. В файле backend/config/main.php добавьте модуль:

'modules' => [
    'content' => [
        'class' => 'backend\modules\content\ContentModule',
    ],
],

Теперь, если вы перейдёте по адресу http://your-site/backend/web/index.php?r=content/article, вы увидите список статей. Ура, админка работает!

Практические советы и лайфхаки

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

  • Используйте Gii — генератор кода, который идёт в комплекте с Yii2. Он создаст модели, контроллеры и представления за вас. Вы только нажмёте «Generate». Это колоссальная экономия времени.
  • Разделяйте логику — не пишите всё в контроллерах. Выносите сложные запросы в модели, а повторяющиеся куски кода — в компоненты или сервисы.
  • Используйте миграции — это как система контроля версий для базы данных. Все изменения структуры БД должны быть в миграциях, чтобы вы могли легко развернуть проект на другом сервере.
  • Настройте права доступа — обязательно используйте RBAC (Role-Based Access Control), чтобы не каждый мог удалить статью. Yii2 предоставляет готовый механизм, просто настройте его.
Правило золотого кода: Никогда не доверяйте входящим данным. Всегда валидируйте и фильтруйте пользовательский ввод, даже если вы уверены, что пользователь — ваш друг. Yii2 предоставляет мощные механизмы валидации — используйте их по максимуму.

Также стоит помнить о производительности. Yii2 быстрый, но вы можете сделать его ещё быстрее, используя кэширование. Например, кэшируйте запросы к базе данных с помощью DbCache или кэшируйте целые страницы. Это особенно важно, если у вас много контента.

Заключение

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

Главное, что вы должны вынести из этой статьи: Yii2 — это отличный инструмент для создания CMS. Он даёт вам полный контроль над кодом, при этом избавляет от рутины, предоставляя готовые решения для типовых задач. Не бойтесь экспериментировать, читайте документацию и создавайте свои шедевры.

Если вы хотите, чтобы ваш проект разработали профессионалы, обращайтесь в Digital-студию WNDER — мы с радостью поможем вам воплотить любые идеи в жизнь.

Студия WNDER