Skip to content

Instantly share code, notes, and snippets.

@asqd
Last active October 9, 2017 11:48
Show Gist options
  • Save asqd/26aacf778c4cbe6b8bce5418dd6f8390 to your computer and use it in GitHub Desktop.
Save asqd/26aacf778c4cbe6b8bce5418dd6f8390 to your computer and use it in GitHub Desktop.
yii-tutorial Raw

Yii Guide

OSX

Установка Apache и PHP

Устанавливаем Apache

В OSX 10.12 Sierra уже установлен Apache 2.4, но в нем может не хватать некоторых скриптов. По этому лучше переустановить apache через homebrew. Обновляем brew

brew tap homebrew/dupes
brew tap homebrew/versions
brew tap homebrew/php
brew tap homebrew/apache
brew update

Останавливаем apache, удаляем скрипт автозагрузки и устанавливаем новую версию:

sudo apachectl stop
sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null
brew install httpd24 --with-privileged-ports --with-http2

После установки получаем сообщение:

/usr/local/Cellar/httpd24/2.4.23_2: 212 files, 4.4M, built in 1 minute 45 seconds

Нас интересует полный путь установки /usr/local/Cellar/httpd24/2.4.23_2

Создаем новый скрипт автозагрузки, указав свой путь до apache:

sudo cp -v /usr/local/Cellar/httpd24/2.4.23_2/homebrew.mxcl.httpd24.plist /Library/LaunchDaemons
sudo chown -v root:wheel /Library/LaunchDaemons/homebrew.mxcl.httpd24.plist
sudo chmod -v 644 /Library/LaunchDaemons/homebrew.mxcl.httpd24.plist
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.httpd24.plist

Теперь можно перейти на localhost в браузере и проверить запустился ли apache.

Управлять сервером apache можно с помощью apachectl:

// запуск
sudo apachectl start
// остановка
sudo apachectl stop
// перезагрузка, например после изменения конфигурации
sudo apachectl -k restart

Устанавливаем PHP

Выполняем команду, чтобы установить PHP с модулем для Apache

brew install php71 --with-httpd24

Устанавливаем xdebug

Для отладки проекта установим xdebug, выполняем:

brew install php71-xdebug

В файле /usr/local/etc/php/7.1/php.ini раскомментируем строку:

extension_dir = "ext"

И добавим в конец параметры

[XDebug]
xdebug.remote_enable=1
xdebug.remote_host=<домен вашего приложения>
xdebug.remote_port=9000
xdebug.remote_autostart=on
xdebug.remote_handler=dbgp
xdebug.profiler_enable=1

Сохраняем php.ini и перезагружаем apache командой sudo apachectl -k restart

Настройки xdebug можно задавать в /usr/local/etc/php/7.1/conf.d/ext-xdebug.ini, а не только в php.ini

Устанавливаем Composer

Composer — менеджер зависимостей для PHP. Работает на уровне приложения. Умеет автоматически скачивать и устанавливать пакеты из репозиториев.

brew search composer
composer global require "fxp/composer-asset-plugin:^1.3.1"

Создаем новый проект

composer create-project --prefer-dist yiisoft/yii2-app-basic <app_name>

yii2-app-basic - Базовый проект. Одно приложение с общими компонентами системы

composer create-project --prefer-dist yiisoft/yii2-app-advanced <app_name>

yii2-app-advanced - Шаблон с тремя разными Yii-приложениями: frontend, backend и console.

Инициализация приложения

После создания приложения переходим в папку проекта и выполняем команду

php init

Настройка Apache

OSX

Открываем /usr/local/etc/apache2/2.4/httpd.conf любым текстовым редактором и раскомментируем или добавляем строки:

...
LoadModule php7_module        /usr/local/opt/php71/libexec/apache2/libphp7.so

LoadModule rewrite_module libexec/mod_rewrite.so

User your_user
Group staff

# Virtual hosts
Include /usr/local/etc/apache2/2.4/extra/httpd-vhosts.conf
...

Теперь мы можем настроить вирутальные хосты, чтобы использовать удобные ссылки для работы с приложением например cards-client.apch. Здесь мы укажем путь до папки web в приложении frontend для advanced шаблона.

Открываем файл /usr/local/etc/apache2/2.4/extra/httpd-vhosts.conf И настраиваем хосты:

<VirtualHost *:80>
    ServerName cards-client.apch
    DocumentRoot "<полный путь до папки с проектом>/cards-app/frontend/web"

    <Directory "<полный путь до папки с проектом>/cards-app/frontend/web">
        # use mod_rewrite for pretty URL support
        RewriteEngine on
        # If a directory or a file exists, use the request directly
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        # Otherwise forward the request to index.php
        RewriteRule . index.php

        # use index.php as index file
        DirectoryIndex index.php

        # ...other settings...
        # Apache 2.4
        Require all granted

        ## Apache 2.2
        # Order allow,deny
        # Allow from all
    </Directory>
</VirtualHost>

Сохраняем файл и перезагружаем Apache командой sudo apachectl -k restart.

Теперь обновим записи в hosts

sudo nano /etc/hosts

Добавляем строчку

127.0.0.1   cards-client.apch

Нажимаем Ctrl + X, чтобы выйти и выбираем "Yes", чтобы сохранить изменения.

Теперь frontend нашего проекта доступен по адресу cards-client.apch/

Структура директорий

Встроеные псевдонимы путей

  • @yii - директория фрэймворка.
  • @app - корневая директория выполняемого в данный момент приложения.
  • @common - директория common.
  • @frontend - директория веб-приложения frontend.
  • @backend - директория веб-приложения backend.
  • @console - директория console.
  • @runtime - директория runtime исполняемого приложения.
  • @vendor - директория vendor, содержащая пакеты загруженные Composer'ом.
  • @bower - директория vendor, содержащая пакеты bower.
  • @npm - директория vendor, содержащая пакеты npm.
  • @web - базовый URL исполняемого веб-приложения.
  • @webroot - корневая веб-директория исполняемого веб-приложения.

Приложения (шаблон advanced)

Есть общая директория common, она содержит файлы используемые более чем одним приложением.

frontend - приложение, которое обеспечивает взаимодействие системы с пользователем.

backend - административная панель, аналитика и т.п.

console - используется для выполнения заданий по расписанию через cron, низкоуровневого управления сервером, при развёртывании приложения, работы с миграциями и ресурсами.

Псевдонимы для структуры директорий приложения advanced (@common, @frontend, @backend и @console) задаются в common/config/bootstrap.php.

Конфигурации и окружения

Конфигурации - основной элемент для инициализации и настройки объектов в Yii. Они включают в себя названия классов и список первоначальных значений создаваемых объектов. Также в конфигурациях можно указать список обработчиков событий и/или поведений объекта. Конфигурации могут различаться в зависимости от режима работы приложения.

Каждое приложение имеет как минимум 2 режима работы(окружения): development и production. На более крупных проектах используют staging и testing окружения.

В Yii каждое окружение представлено набором файлов в директории environments. Для переключения между окружениями используется команда init. Она копирует файлы из директории окружения в корневую директорию, где находятся все приложения.

Окружение содержит входные скрипты приложения: index.php, файлы конфигурации, с суффиксами -local.php. Эти файлы добавлены в .gitignore и никогда не попадут в репозиторий.

Чтобы избежать дублирования, конфигурации перекрывают друг друга. Например, приложение frontend считывает конфигурацию в следующем порядке:

  • common/config/main.php
  • common/config/main-local.php
  • frontend/config/main.php
  • frontend/config/main-local.php

Параметры считываются в следующем порядке:

  • common/config/params.php
  • common/config/params-local.php
  • frontend/config/params.php
  • frontend/config/params-local.php

Параметры из следующего конфигурационного файла перекрывают аналогичные параметры из предыдущих файлов.

Схема загрузки файлов конфигурации:

advanced-app-configs

Создание ссылок на frontend из backend

Каждое из приложений может использовать собственную конфигурацию URL. Чтобы создать ссылку из backend на frontend нужно указать ее в конфигурации backend: Часто приходится создавать ссылки из приложения backend на приложение frontend. Так как frontend может использовать собственную конфигурация менеджера URL, вам придётся продублировать её в конфигурации backend под новым именем:

return [
    'components' => [
        'urlManager' => [
            // конфигурация основного менеджера URL в конфигурации backend
        ],
        'urlManagerFrontend' => [
            // конфигурация менеджера URL из frontend
        ],

    ],
];

После этого можно получить URL, указывающий на frontend:

echo Yii::$app->urlManagerFrontend->createUrl(...);

Работа с Yii

В каждом приложении Yii есть точка входа в приложение, web/index.php это единственный PHP-скрипт доступный для выполнения из Web. Он принимает входящий запрос и создает экземпляр приложения. Приложение обрабатывает входящие запросы при помощи компонентов и отправляет запрос контроллеру. Виджеты используются в Представлениях для построения динамических интерфейсов сайта.

Структура приложения

структура приложения

Жизненный цикл запроса

жизненный цикл запроса

  1. Пользователь обращается к точке входа web/index.php.
  2. Скрипт загружает конфигурацию configuration и создает экземпляр приложения для дальнейшей обработки запроса.
  3. Приложение определяет маршрут запроса при помощи компонента приложения запрос.
  4. Приложение создает экземпляр контроллера для выполнения запроса.
  5. Контроллер создает действие и применяет на него фильтры.
  6. Если хотя бы один фильтр дает сбой, выполнение приложения останавливается.
  7. Если все фильтры пройдены - приложение выполняется.
  8. Действие загружает модель данных.
  9. Действие генерирует представление, отображая в нем данные.
  10. Сгенерированное представление приложения передается как компонент ответ.
  11. Компонент ответ отправляет готовый результат работы приложения браузеру пользователя.

Миграции баз данных

Миграции - это удобный способ изменять схему вашей базы данных используя DSL на php. Также миграции позволяют использовать абстрактные типы данных, вместо физических. Поскольку нет необходимости писать SQL-код вручную, схема становится независимой от конкретной СУБД.

Yii содержит набор инструментов для миграций из командной строки, которые позволяют:

  • создавать новые миграции
  • применять миграции
  • отменять миграции
  • применять миграции повторно
  • показывать историю и статус миграций

Создание миграций

Чтобы создать новую миграцию надо выполнить команду:

./yii migrate/create <name>

Аргумент name задаёт краткое описание новой миграции.

Настройка базы данных

Пример для PostgreSQL. Подключимся и создадим новую базу данных:

psql -p5432 -d "user"
CREATE DATABASE very_test;

Создаем файл config/db.php:

<?php
return [
  'class' => 'yii\db\Connection',
    'dsn' => 'pgsql:host=127.0.0.1;port=5432;dbname=very_test',
    'username' => 'user',
    'password' => '',
    'charset' => 'utf8',
];

В файле confing/main-local.php подключаем наши настройки:

<?php
return [
  'components' => [
    'db' => require(__DIR__ . '/db.php'),
    // ...
  ]
];

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

Выполняем команду /.yii migrate.

Полный список доступных команд можно получить командой ./yii

Заходим на test-app.dev/site/signup и пробуем зарегистрироваться.

Теперь мы можем зайти на сайт с помощью логина/пароля под которым только что зарегистрировались.

Генерация миграций

Миграции позволяют описать правила создания/изменения/удаления таблиц в БД на php. Создадим таблицу, которая будет хранить карточки слов в базе данных. У каждой карточки будет поле word - само слово и definition - описание или перевод слова.

Чтобы создать новую таблицу в БД выполняем:

./yii migrate/create create_cards_table

Yii создаст файл migrations/m170706_104008_create_cards_table.php

<?php

use yii\db\Migration;

/**
 * Handles the creation of table `cards`.
 */
class m170706_104008_create_cards_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('cards', [
            'id' => $this->primaryKey(),
            'word' => $this->text(),
            'definition' => $this->text(),
            // кто создал
            'author_id' => $this->integer(),
        ]);
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('cards');
    }
}

Выполним команду ./yii migrate чтобы провести миграцию.

Генерация кода с помощью Gii

Теперь в базе есть таблица cards. Создадим модель, контроллер, представление и простой интерфейс для управлениями. Воспользуемся автогенерацией кода.

Gii - расширение, предлагающее консольный или веб-интерфейс для генерации кода моделей, контроллеров, CRUD, форм и прочего. Список команд можно получить командой ./yii gii.

Справку по каждой команде можно получить с помощью ./yii help <команда>, например ./yii help gii/crud.

Сначала сгенерируем модель для нашей таблицы cards:

./yii gii/model --tableName=cards --modelClass=Card --queryNs='frontend\models' --ns='frontend\models'

Модель - объект, который содержит в себе данные и логику работы с ними.

Чтобы сгенерировать CRUD интерефейс для наших карточек, выполняем команду

./yii gii/crud --controllerClass="frontend\controllers\CardController" --modelClass="frontend\models\Card" --searchModelClass="frontend\models\TestSearch" --viewPath="frontend\views\card"

Для базового шаблона вместо frontend\..\.. указываем app\..\...

Теперь можно зайти в браузер по адресу test-app.dev/card и попробовать создать несолько карточек.

Панель отладки

По умолчанию в development окружении панель отладки включена. Проверьте config\main-local.php:

if (!YII_ENV_TEST) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
    ];

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
    ];
}

Добавим в панель отладки наши карточки. Для этого создадим файл panels/CardPanel.php:

<?php
namespace frontend\panels;

use yii\base\Event;
use frontend\models\Card;
use yii\debug\Panel;

class CardPanel extends Panel
{
  private $_cards = [];

  public function init()
  {
    parent::init();
    Event::on(Card::ClassName(), Card::EVENT_AFTER_FIND, function ($event) {
      $this->_cards[] = $event->sender->word;
    });
  }

  /**
   * @inheritdoc
   */
  public function getName()
  {
    return 'Cards';
  }

  /**
   * @inheritdoc
   */
  public function getSummary()
  {
    $url = $this->getUrl();
    $count = count($this->data);
    return "<div class=\"yii-debug-toolbar__block\">
      <a href=\"$url\">Cards
        <span class=\"yii-debug-toolbar__label\">$count</span>
      </a>
    </div>";
  }

  /**
   * @inheritdoc
   */
  public function getDetail()
  {
    return '<ol><li>' . join('</li>', $this->data) . '</ol>';
  }

  /**
   * @inheritdoc
   */
  public function save()
  {
    return $this->_cards;
  }

};

Для шаблона advanced надо указывать в какое именно пространство приложение (frontend, backend, common) входит наш класс. Для шаблона basic вместо

namespace frontend\panels;

указываем

namespace app\panels;

Теперь добавим в config\main-local.php нашу панель CardPanel:

if (!YII_ENV_TEST) {
    // ...
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
        'panels' => [
            'cards' => ['class' => 'frontend\panels\CardPanel']
        ]
    ];
    // ...
}

Теперь в панели отладки должна появиться вкладка Cards

Тестирование

Yii 2 интегрирован с фреймворком Codeception, который позволяет проводить следующие типы тестов:

  • Модульное тестирование - проверяет работу отдельных модулей/классов изолированно друг от друга.
  • Функциональное тестирование - на основе пользовательских сценариев проверяет работу приложения через эмуляцию браузера.
  • Приёмочное тестирование - функционально тестирование пользовательских сценариев в браузере. Проверяет уровень готовности системы к работе.

Настройки тестового окружения находятся в config/test.php и config/test-local.php Тесты располагаются в папке tests каждого из приложений. Например frontend/tests.

Для запуска всех тестов можно выполнить в консоли:

vendor/bin/codecept run

Для запуска определенного типа тестов нужно перейти в папку приложения и выполнить:

./vendor/bin/codecept run suite_name file_path -c app_name

# suite_name - functional, unit, acceptance
# file_path - путь к файлу
# app_name - приложение, например frontend

# Например
./vendor/bin/codecept run functional frontend/tests/functional/SignupCest.php -c frontend

Консольные команды

Напишем свою консольную команду. Она удалит все карточки из базы и заполнит базу тестовыми данными. Создадим файл console/controllers/CardController для advanced или commands/CardController для basic:

<?php
namespace console\controllers;

use Yii;
use yii\console\Controller;
use frontend\models\Card;

class CardController extends Controller
{
  public function actionLoadCards()
  {
    Card::deleteAll();

    // Данные для карточек
    $cardData = [
      [
        'word' => '味',
        'definition' => 'flavour'
      ],
      [
        'word' => '遊',
        'definition' => 'play'
      ],
      [
        'word' => '安心',
        'definition' => 'relief'
      ],
      [
        'word' => '動',
        'definition' => 'move'
      ]
    ];

    // Создаем карточки в базе через ActiveRecord
    foreach ($cardData as $data) {
      $card = new Card($data);
      $card->save();
    }
  }
};
;

Теперь мы можем заполнить базу с помощью команды ./yii card/load-cards.

Заходим на `test-app.dev/card/ и смотрим результат.

Интернационализация

По умолчанию в Yii приложении определены два языка: sourceLanguage - исходный язык и language - язык перевода.

Сообщения в коде приложения пишутся на исходном языке. По умолчанию исходный язык - анлийский. Для перевода можно использовать код:

echo \Yii::t('app', 'I am a message!');

Язык перевода определяет на какой язык будут переведены оригинальные сообщения. Этот параметр определяется в конфигурации приложения:

return [
    'id' => 'appID',
    // ...
    'language' => 'ru-RU',
    // ...
]

Сгенерируем файлы локализации. Для этого:

  1. Создадим папку messages в корне приложения (basic) или в папке common (advanced)
  2. Создадим файл config/i18n.php для basic или common/config/i18n.php для advanced шаблона.
<?php
$dirSep = DIRECTORY_SEPARATOR;

$messagePath = __DIR__. $dirSep . '..'

// $sourcePath for basic app
$sourcePath = __DIR__. $dirSep . '..'

// $sourcePath for advanced app
$sourcePath = __DIR__. $dirSep . '..' . $dirSep . '..' . $dirSep

return [
    'sourcePath' => $sourcePath,
    // в параметре languages можно указать несколько языков
    'languages' => ['ru-RU'],
    'translator' => 'Yii::t',
    'sort' => false,
    'removeUnused' => false,
    'only' => ['*.php'],
    'except' => [
        '.svn',
        '.git',
        '.gitignore',
        '.gitkeep',
        '.hgignore',
        '.hgkeep',
        '/messages',
        '/vendor',
    ],
    'format' => 'php',
    'messagePath' => $messagePath,
    'overwrite' => true,
];
  1. Добавим наш компонент в файл конфигурации main.php и укажем язык перевода.
<?php
return [
    'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
    'language' => 'ru-RU',
    'components' => [
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'i18n' => [
            'translations' => [
                // файлы перевода для модуля frontend
                'frontend*' => [
                    'class' => 'yii\i18n\PhpMessageSource',
                    'basePath' => '@common/messages',
                ],
                // файлы перевода для модуля backend
                'backend*' => [
                    'class' => 'yii\i18n\PhpMessageSource',
                    'basePath' => '@common/messages',
                ],
                // общиие файлы перевода
                'common*' => [
                    'class' => 'yii\i18n\PhpMessageSource',
                    'basePath' => '@common/messages',
                ],
            ],
        ],
    ],
];
  1. Запустим скрипт, который сгенерирует файлы перевода для всех строк, которые найдет в коде.
yii message/extract @common/config/i18n.php

Скрипт пройдет по всему дереву каталогов приложения, потому что мы указали корневую папку приложения в переменной sourcePath.

Файлы локализации появятся в папке, которую мы указали в messagePath.

common/
  ...
  messages/
    ru-RU/
      backend.php
      common.php
      frontend.php
      yii.php
  ...

Теперь для перевода можно вызывать метод Yii::t() с нужными нам параметрами:

Yii::t('frontend', 'About')

Объекты доступа к данным (DAO)

DAO в Yii - это расширение PDO для php, на его основе построены конструктор запросов и интерфейс active record.

Выполнение SQL запросов

Выше мы уже настроили подключение к базе данных, теперь можно получить доступ к подключению БД с помощью вызова Yii::$app->db.

Для создания запроса к БД мы должны выполнить следующие шаги:

  1. создать команду из SQL-запроса
  2. привязать параметры
  3. вызвать команду выполнения запроса
// возвращает набор строк. каждая строка - ассоциативный массив с именами столбцов и значений.
// если выборка ничего не вернёт, то будет получен пустой массив.
$posts = Yii::$app->db->createCommand('SELECT * FROM cards')
            ->queryAll();

// вернёт первую найденную строку
// false, если выборка пустая
$post = Yii::$app->db->createCommand('SELECT * FROM cards WHERE id > 1')
           ->queryOne();

// вернёт первый столбец или пустой массив, при отсутствии результата
$titles = Yii::$app->db->createCommand('SELECT word FROM cards')
             ->queryColumn();

// вернёт скалярное значение или false, при отсутствии результата
$count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM cards')
             ->queryScalar();

Все данные извлекаются как строки, даже если тип поля в базе данных является числовым

Привязка параметров

Для предотвращения SQL-инъекций в запросах используют привязку параметров. Привязка осуществляется с помощью маркера - строки начинающейся с двоеточия, например ":id".

Пример:

$params = [':id' => 1];

$post = Yii::$app->db->createCommand('SELECT * FROM cards WHERE id > :id')
           ->bindValues($params)
           ->queryOne();

$post = Yii::$app->db->createCommand('SELECT * FROM cards WHERE id > :id', $params)
           ->queryOne();

Выполнение не SELECT запросов

Для выполнения запросов, не возвращающих данные, нужно использовать метод Command::execute:

Yii::$app->db->createCommand('UPDATE cards SET definition="flavour, charm" WHERE id = 1')
   ->execute();

Метод execute возращает количество обработанных запросом строк.

Для запросов INSERT, UPDATE и DELETE можно использовать соответствующие методы Command::insert, Command::update и Command::delete.

// INSERT (table name, column values)
Yii::$app->db->createCommand()->insert('cards', [
    'word' => '働',
    'definition' => 'work',
])->execute();

// UPDATE (table name, column values, condition)
Yii::$app->db->createCommand()->update('cards',
    ["definition" => "flavour, charm"],
    'id = 1'
)->execute();

// DELETE (table name, condition)
Yii::$app->db->createCommand()->delete('cards', 'id = 0')->execute();

Для вставки нескольких значений за один вызов можно использовать Command::batchInsert:

Yii::$app->db->createCommand()->batchInsert('cards',
    ['word', 'definition'], [
        ['若', 'young'],
        ['早', 'early']
])->execute();

Imagemagick

Для обработки изображений потребуется библиотека Imagemagick и модуль imagick для PHP. Устанавливаем imagick:

brew install homebrew/php/php71-imagick

Чтобы включить поддержку imagick в PHP в файл /usr/local/etc/php/7.1/php.ini добавляем строку: extension = /usr/local/Cellar/php71-imagick/3.4.3_3/imagick.so

Вместо 3.4.3_3 указываем свою версию

Проверка установки:

php -r "print(class_exists('imagick'));"

Пример использования:

$im = new \Imagick("~/cards-app/frontend/web/public/images/IMG_20160416_093653.jpg");
$im->thumbnailImage(100, 0);

Создание собственных виджетов

Виджеты - компоненты, используемые несколько раз в представлениях для создания настраиваемых элементов пользовательского интерфейса.

Создание виджета

Чтобы создать свой виджет, создадим класс, наследуемый от базового класса Widget и переопределить функции - run() и init().

Метод init() вызывает родительский метод и содержит код для инициализации свойств виджета.

public function init()
    {
        parent::init();
        if ($this->message === null) {
            $this->message = 'Hello World';
        }
    }

Метод run() возвращает результат рендеринга виджета.

public function run()
   {
       return Html::encode($this->message);
   }

Создадим собственный виджет для отображения информации о зданиях.

Создадим папку components в директории frontend. Классы виджетов должны размещаться в папке components, а их представления - в components\views.

Внутри components создаём файл, содержащий класс виджета, название файла = название класса. Например BuildingSnippetWidget.php

<?php

namespace frontend\components;
use yii\base\Widget;


class BuildingSnippetWidget extends Widget
{
    public $building;

    public function init() {
        parent::init();
    }
    /**
     * @return object
     */
    public function run() {
        return $this->render('buildingSnippet', ['building' => $this->building]);
    }
}

Создадим представление в поддиректории views с названием buildingSnippet.php:

<div class="search-serp__item">
  <div class="table-building-element">
    <div class ='image-container'>
      <?php echo "<a class='link' href='/building/view?id={$building->id}' target='_blank'>"?>
      <?php echo "<img src='' alt='Аренда офисов в {$building->name}'>"?>
      </a>
    </div>
    <div class="info-container">
      <div class="name_class_and_stars">
        <?php echo "<a class='name two-line-clip' href='/building/view?id={$building->id}' target='_blank' title='{$building->name}'>
          <noindex>
            {$building->name}
          </noindex>" ?>
        </a>
        <div class='class bc-rank_b_plus bc-rank_large search-serp-cat'>
          <?php echo "{$building->bc_class}"?>
        </div>
      </div>
      <div class="price_and_square">
      <?php
        if ($building->rooms_count > 0) {
          echo "Площади от {$building->min_area}м² до {$building->total_area}м². <br> Арендная ставка от {$building->price}руб./м².";
        }
        else
        {
          echo "<b> Свободные блоки не обнаружены </b>";
        }
      ?>
      </div>
        <?php echo "<a href='/building/view?id={$building->id}' target='_blank'>" ?>
          Аренда офисов, 
        </a>
        <?php echo "<span> {$building->rooms_count} → </span>" ?>
    </div>
    <div class="favorite-container">
      <!-- = add-favorite session=session favorites=favorites store=store typeId=building.id type='building' -->
    </div>
  </div>
</div>

Теперь мы можем использовать вижджет в представлении. Для этого необходимо вызвать метод yii\base\Widget::widget(). Метод принимает массив настроек для инициализации виджета и возвращает результат рендера.

Пример использования написанного виджета из представления /frontend/views/building/index.php:

<?php
use frontend\components\BuildingSnippetWidget;
...
?>

<?php
    echo "<div id='search-result-container'>";
    // $buildings -  массив объектов БД - зданий
    foreach ($buildings as $building) {
    ?>
        <?=
        BuildingSnippetWidget::widget([
            'building' => $building,
        ]);
        ?>
    <?php
    }
    echo "</div>";
?>

Работа с Ассетами

Управление ассетами

AssetBundle - это набор .css и .js файлов, расположенных в определенной директории. Для того, чтобы приложение могло использовать эти файлы их нужно зарегистрировать в представлении.

Комплект ассетов - класс, который расширяется от AssetBundle. При создании комплекта ассетов обычно указывается где и какие ресурсы содержит комплект и от каких комплектов он зависит.

Создадим главный набор ассетов для приложения.

<?php

namespace site\assets;

use yii\web\AssetBundle;

/**
 * Main site application asset bundle.
 */
class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/site.css',
    ];
    public $js = [
    ];
    public $depends = [
        'common\assets\CustomAsset',
    ];
}

Свойства AssetBundle:

  • sourcePath задает корневую директорию, в которой лежат ресурсы. Если корневая директория отличается от web

  • basePath задает базовый путь к файлам ресурсов, если они уже размещены в web и их не нужно повторно публиковать. Когда свойство sourcePath задано, то менеджер опубликует ассеты в web и перепишет данное свойство.

  • baseUrl - URL базовой директории

  • js - массив JavaScript файлов, которые содержатся в комплекте. Можно указать

    • относительный путь для локального js файла. Например js/script.js. Путь к файлу будет определен как basePath + baseUrl + js/script.js
    • абсолютный URL для внешнего файла, например //ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
  • css - массив CSS файлов, содержащихся в комплекте. Формат пути такой же, как и у массива js

  • depends - массив, перечисляющий комплекты ассетов, от которых зависит данный комплект

Настройка AssetManager

Коплекты ресурсов в Yii управляются через assetManager. Можно переопределить поведение для некоторых ресурсов, настроив свойство bundles. Например, если нам нужно использовать более новую версию jQuery или Bootstrap:

'assetManager' => [
    'class' => 'yii\web\AssetManager',
    'forceCopy' => true,
    'bundles' => [
        'yii\bootstrap\BootstrapPluginAsset' => [
            'sourcePath' => '@common/themes/custom',
            'js' => [
                'js/tether.min.js',
                'js/bootstrap.min.js',
            ]
        ],
        'yii\web\JqueryAsset' => [
            'sourcePath' => '@common/themes/custom',
            'js' => [
                'js/jquery-3.1.1.min.js',
            ]
        ],
        'yii\bootstrap\BootstrapAsset' => [
            'sourcePath' => '@common/themes/custom',
            'css' => [
                'css/bootstrap.min.css'
            ]
        ],
    ],
],

Интерактивная консоль Yii shell

Yii shell - интерактивная консоль/отладчик для Yii на основе PsySH Установить можно с помощью composer

cd <yii project app>
composer require yiisoft/yii2-shell

Запускается из корневой папки проекта командой

./yii shell

Команда help показывает список служебных команд

  • help Show a list of commands. Type help [foo] for information about [foo]. Aliases: ?
  • ls List local, instance or class variables, methods and constants.Aliases: list, dir
  • dumpDump an object or primitive.
  • doc Read the documentation for an object, class, constant, method or property. Aliases: rtfm, man
  • show Show the code for an object, class, constant, method or property.
  • wtf Show the backtrace of the most recent exception. Aliases: last-exception, wtf?
  • whereami Show where you are in the code.
  • throw-up Throw an exception out of the Psy Shell.
  • trace Show the current call stack.
  • buffer Show (or clear) the contents of the code input buffer. Aliases: buf
  • clear Clear the Psy Shell screen.
  • history Show the Psy Shell history. Aliases: hist
  • exit End the current session and return to caller. Aliases: quit, q

Пример работы с консолью

>>> $user = common\models\User::find()->limit(1)->one();
=> common\models\User {#204
     id: 1,
     username: "admin",
     auth_key: "_w968_6obOn59xQjGh0cedeW9xFiVznE",
     password_hash: "$2y$13$gRoSumyiiSQUvYrCJYEKFeD9eKi5khpAl0YNg5lUcjsavDZflcqCC",
     password_reset_token: null,
     email: "admin@admin.ru",
     status: 10,
     created_at: 1499774434,
     updated_at: 1501077189,
   }

>>> $user->name
=> "admin"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment