Плагины
CakePHP позволяет вам настроить комбинацию контроллеров, моделей,
и просматривать и выпускать их в виде готовых к использованию приложений,
которые другие пользователи могут использовать в своих приложения CakePHP.
Если вы создали отличный менеджер пользователей, простой блог или модуль
веб-сервисов в одном из ваших приложений, почему бы не упаковать его как
плагин CakePHP? Таким образом, вы может повторно использовать его в других
приложениях и делиться им с сообществом!
Плагин CakePHP в конечном счёте отделён от самого хост-приложения
и, как правило, предоставляет некоторые чётко определенные функции, которые могут быть
аккуратно упакованы и повторно использованы с небольшими усилиями в других приложениях.
Приложение и плагин работают в своих соответствующих пространствах, но совместно используют
свойства хост-приложения (например, параметры подключения к базе данных), которые определены
и разделены через конфигурацию приложения.
В CakePHP 3.0 каждый плагин определяет собственное пространство имён верхнего уровня.
Например: DebugKit
. По соглашению, плагины используют своё имя пакета в качестве
своего пространства имен. Если вы хотите использовать другое пространство имён, вы
можете настроить плагину пространство имен, когда загружаются плагины.
Установка плагина с Composer
Многие плагины доступны на Packagist
и могут быть установлены с помощью Composer
. Чтобы установить DebugKit, вам
нужно сделать следующее:
php composer.phar require cakephp/debug_kit
Это установит последнюю версию DebugKit и обновит ваш composer.json,
файл composer.lock, обновит vendor/cakephp-plugins.php, и обновит
ваш автозагрузчик.
Если плагин, который вы хотите установить, недоступен на packagist.org, вы можете
клонировать или копировать код плагина в каталог plugins.
Предполагая, что вы хотите установить плагин с именем „ContactManager“, у вас должна
быть папка в plugins с именем „ContactManager“.
В этом каталоге будут находится src, тесты и любые другие каталоги данного плагина.
Файл карты плагина
При установке плагинов через Composer вы можете заметить, что создаётся
vendor/cakephp-plugins.php. Этот файл конфигурации содержит карту имён
плагинов и их путей в файловой системе. Это позволяет устанавливать плагины
в стандартный каталог поставщиков, который находится за пределами обычных
путей поиска. Класс Plugin
будет использовать этот файл для поиска
плагинов, когда они загружаются с помощью load()
или loadAll()
.
Вам обычно не нужно будет редактировать этот файл вручную, поскольку
Composer и пакет plugin-installer
будут управлять ими за вас.
Загрузка плагина
После установки плагина и настройки автозагрузчика вы должны загрузить
плагин. Вы можете загружать плагины по одному или все, одним из способов:
// В config/bootstrap.php
// Или в in Application::bootstrap()
// Загружает один плагин
Plugin::load('ContactManager');
// Загружает плагин с пространством имён поставщиков на верхнем уровне.
Plugin::load('AcmeCorp/ContactManager');
// Loads all plugins at once
Plugin::loadAll();
loadAll()
загружает все доступные плагины, позволяя вам устанавливать
определённые настройки для определённых плагинов. load()
работает
аналогично, но загружает только те плагины, которые вы явно указываете.
Примечание
Plugin::loadAll()
не будет загружать плагины с расширением имён
поставщиков, которые не определены в vendor/cakephp-plugins.php.
Также есть удобная команда оболочки для включения плагина. Выполните следующую строку:
bin/cake plugin load ContactManager
Это приведёт к загрузке Plugin::load('ContactManager');
snippet в bootstrap для вас.
Автозагрузка классов плагина
При использовании bake
для создания плагина или при установке плагина с использованием
Composer, вам обычно не нужно вносить какие-либо изменения в ваше приложение, чтобы CakePHP
распознавал классы, которые живут внутри него.
В любых других случаях, вам может потребоваться изменить файл composer.json вашего приложения
чтобы внести следующую информацию:
"psr-4": {
(...)
"MyPlugin\\": "plugins/MyPlugin/src/",
"MyPlugin\\Test\\": "plugins/MyPlugin/tests/"
}
Если вы используете пространства имён поставщиков для своих плагинов, сопоставление
пространства имён в пути должно выглядеть следующим образом:
"psr-4": {
(...)
"AcmeCorp\\Users\\": "plugins/AcmeCorp/Users/src/",
"AcmeCorp\\Users\\Test\\": "plugins/AcmeCorp/Users/tests/"
}
Кроме того, вам нужно будет сообщить Composer об обновлении кеша автозагрузки:
$ php composer.phar dumpautoload
Если вы не можете использовать Composer по какой-либо причине, вы также
можете использовать резервную автозагрузку для своего плагина:
Plugin::load('ContactManager', ['autoload' => true]);
Конфигурация плагина
Методы load()
и loadAll()
могут помочь в настройке и маршрутизации плагинов.
Возможно, вы хотите загрузить все плагины автоматически, указав собственные
маршруты и файлы начальной загрузки для определенных плагинов:
// В config/bootstrap.php,
// или в Application::bootstrap()
// Используем loadAll()
Plugin::loadAll([
'Blog' => ['routes' => true],
'ContactManager' => ['bootstrap' => true],
'WebmasterTools' => ['bootstrap' => true, 'routes' => true],
]);
Или вы можете загружать плагины индивидуально:
// Загрузка только блога и включение маршрутов
Plugin::load('Blog', ['routes' => true]);
// Включить файл конфигурации начальной загрузки / инициализации.
Plugin::load('ContactManager', ['bootstrap' => true]);
При любом подходе, вам больше не нужно ручное подключение конфигурации
плагина или файла маршрутов через include()
или require()
,
- это происходит автоматически в нужное время и в нужном месте.
Вы можете указать набор значений по умолчанию для loadAll()
, который
будет применяться к каждому плагину, который не имеет более конкретной
конфигурации.
Следующий пример загрузит загрузочный файл из всех плагинов, а также
маршруты из плагина Blog:
Plugin::loadAll([
['bootstrap' => true],
'Blog' => ['routes' => true]
]);
Обратите внимание, что все указанные файлы должны фактически существовать в
настроенных плагине(-ах), или PHP выдаст предупреждения для каждого файла,
который он не может загрузить. Вы можете избежать возможных предупреждений,
используя опцию ignoreMissing
:
Plugin::loadAll([
['ignoreMissing' => true, 'bootstrap' => true],
'Blog' => ['routes' => true]
]);
При загрузке плагинов, используемое имя плагина должно соответствовать
пространству имён. Например, если у вас есть плагин с пространством имён
верхнего уровня Users
, вы должны загрузить его с помощью:
Если вы предпочитаете иметь имя своего поставщика как верхний уровень и иметь
пространство имён, например AcmeCorp/Users
, то вы должны загрузить
плагин так:
Plugin::load('AcmeCorp/Users');
Это обеспечивает правильное разрешение имён классов при использовании
plugin syntax.
В большинстве плагинов в их документации указывается правильная процедура их настройки и
настройка базы данных. Некоторые плагины потребуют больше настроек, чем другие.
Использование плагинов
Вы можете ссылаться на контроллеры плагинов, модели, компоненты, поведение и помощники,
перед этим, предварительно указав имя плагина.
Например, предположим, что вы хотите использовать ContactInfoHelper плагина ContactManager
для вывода некоторой контактной информации в одном из ваших представлений. В вашем
контроллере ваш массив $helpers
может выглядеть так:
public $helpers = ['ContactManager.ContactInfo'];
Примечание
Затем вы сможете получить доступ к ContactInfoHelper
, как и к любому другому помощнику
в вашем представлении, например:
echo $this->ContactInfo->address($contact);
Создание собственных плагинов
В качестве рабочего примера давайте начнём создавать плагин ContactManager, упомянутый выше.
Для начала мы создадим нашу базовую структуру плагина. Это должно выглядеть так:
/src
/plugins
/ContactManager
/config
/src
/Controller
/Component
/Model
/Table
/Entity
/Behavior
/View
/Helper
/Template
/Layout
/tests
/TestCase
/Fixture
/webroot
Обратите внимание на имя папки плагина, „ContactManager“. Важно, чтобы эта папка
имела то же имя, что и плагин.
Внутри папки плагина вы заметите, что он очень похож на приложение CakePHP,
и это в основном то, что есть. Вам не нужно включать какие-либо папки,
которые вы не используете. Некоторые плагины могут определять только компонент
и поведение, и в этом случае они могут полностью опустить каталог „Template“.
Плагин также может содержать любые другие каталоги, которые могут использовать
ваше приложение, такие как Config, Console, webroot и т. Д.
Создание плагина с использованием Bake
Процесс создания плагинов может быть значительно упрощён с использованием оболочки bake.
Чтобы испечь(создать) плагин, используйте следующую команду:
bin/cake bake plugin ContactManager
Теперь вы можете дальше создавать ваше приложение, используя те же соглашения, которые применяются
к остальной части вашего приложения. Например - контроллеры для выпечки:
bin/cake bake controller --plugin ContactManager Contacts
Пожалуйста, обратитесь к главе Генерация кода с помощью Bake, если у вас возникли проблемы
с использованием командной строки. Обязательно заново создайте автозагрузчик
после создания плагина:
$ php composer.phar dumpautoload
Маршрутизация плагина
Плагины могут предоставлять файлы маршрутов, содержащие их маршруты
Каждый плагин может содержать файл config/routes.php. Этот файл маршрутов
может быть загружен при добавлении плагина или загружен в файл маршрутов приложения.
Чтобы создать маршруты плагинов ContactManager, введите следующее в
plugins/ContactManager/config/routes.php:
<?php
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\Router;
Router::plugin(
'ContactManager',
['path' => '/contact-manager'],
function ($routes) {
$routes->get('/contacts', ['controller' => 'Contacts']);
$routes->get('/contacts/:id', ['controller' => 'Contacts', 'action' => 'view']);
$routes->put('/contacts/:id', ['controller' => 'Contacts', 'action' => 'update']);
}
);
Вышеуказанное свяжет стандартные маршруты для вашего плагина. Вы можете настроить
этот файл с более конкретными маршрутами позже.
Прежде чем вы сможете получить доступ к своим контроллерам, вам необходимо убедиться,
что плагин загружен и загружены маршруты плагина. В вашем config/bootstrap.php
добавьте следующее:
Plugin::load('ContactManager', ['routes' => true]);
Вы также можете загружать маршруты плагинов в список маршрутов вашего приложения.
Это даёт вам больший контроль над тем, как загружаются маршруты плагинов, и позволяет
вам переносить маршруты плагинов в дополнительные области или префиксы:
Router::scope('/', function ($routes) {
// Подключаем другие маршруты.
$routes->scope('/backend', function ($routes) {
$routes->loadPlugin('ContactManager');
});
});
Вышеизложенное приведёт к URL-адресам, таким как /backend/contact_manager/contacts
.
Добавлено в версии 3.5.0: RouteBuilder::loadPlugin()
был добавлен в 3.5.0
Контроллеры плагина
Контроллеры для нашего плагина ContactManager будут храниться в
plugins/ContactManager/src/Controller/.
Поскольку главное, что мы будем делать, это управление контактами,
нам понадобится ContactController для этого плагина.
Итак, мы размещаем наш новый ContactController в
plugins/ContactManager/src/Controller и это выглядит так:
// plugins/ContactManager/src/Controller/ContactsController.php
namespace ContactManager\Controller;
use ContactManager\Controller\AppController;
class ContactsController extends AppController
{
public function index()
{
//...
}
}
Также создайте AppController
, если у вас его еще нет:
// plugins/ContactManager/src/Controller/AppController.php
namespace ContactManager\Controller;
use App\Controller\AppController as BaseController;
class AppController extends BaseController
{
}
Плагины AppController
(а) могут содержать логику контроллера, общую для всех
контроллеров в плагине, но не обязательно, если вы не хотите её использовать.
Если вы хотите получить доступ к тому, что у нас уже есть, посетите
/contact-manager/contacts
. Вы должны получить ошибку «Отсутствующая модель»,
потому что у нас ещё нет модели контактов.
Если ваше приложение включает в себя маршрутизацию по умолчанию CakePHP, вы сможете
получить доступ к своим контроллерам плагинов, используя URL-адреса, такие как:
// Получаем доступ к указательному маршруту контроллера плагина.
/contact-manager/contacts
// Любые действия над контроллером плагина.
/contact-manager/contacts/view/1
Если ваше приложение определяет префикс маршрутизации, то по умолчанию маршрутизация
CakePHP будет также включать маршруты, которые используют следующий шаблон:
/:prefix/:plugin/:controller
/:prefix/:plugin/:controller/:action
См. Раздел о Конфигурация плагина для получения информации о том, как загружать
файлы маршрутов с плагинами.
Для плагинов, которые вы не создавали с помощью bake, вам также нужно будет отредактировать
файл composer.json, чтобы добавить ваш плагин к классам автозагрузки, это можно сделать
в соответствии с документацией Автозагрузка классов плагина.
Модели плагина
Модели для плагина хранятся в plugins/ContactManager/src/Model.
Мы уже определили ContactController для этого плагина, поэтому давайте
создадим таблицу и объект для этого контроллера:
// plugins/ContactManager/src/Model/Entity/Contact.php:
namespace ContactManager\Model\Entity;
use Cake\ORM\Entity;
class Contact extends Entity
{
}
// plugins/ContactManager/src/Model/Table/ContactsTable.php:
namespace ContactManager\Model\Table;
use Cake\ORM\Table;
class ContactsTable extends Table
{
}
Если вам нужно ссылаться на модель внутри вашего плагина при создании ассоциаций
или определении классов сущностей, вам нужно указать имя плагина с именем класса,
разделённым точкой. Например:
// plugins/ContactManager/src/Model/Table/ContactsTable.php:
namespace ContactManager\Model\Table;
use Cake\ORM\Table;
class ContactsTable extends Table
{
public function initialize(array $config)
{
$this->hasMany('ContactManager.AltName');
}
}
Если вы предпочитаете, чтобы в ключах массива для ассоциации не был установлен
префикс плагина, используйте альтернативный синтаксис:
// plugins/ContactManager/src/Model/Table/ContactsTable.php:
namespace ContactManager\Model\Table;
use Cake\ORM\Table;
class ContactsTable extends Table
{
public function initialize(array $config)
{
$this->hasMany('AltName', [
'className' => 'ContactManager.AltName',
]);
}
}
Вы можете использовать TableRegistry
для загрузки таблиц ваших плагиновых,
используя знакомый plugin syntax:
use Cake\ORM\TableRegistry;
// Prior to 3.6 use TableRegistry::get('ContactManager.Contacts')
$contacts = TableRegistry::getTableLocator()->get('ContactManager.Contacts');
Кроме того, из контекста контроллера вы можете использовать:
$this->loadModel('ContactsMangager.Contacts');
Представления плагина
Представления ведут себя точно так же, как в обычных приложениях. Просто поместите
их в нужную папку внутри папки plugins/[PluginName]/src/Template/
. Для нашего
плагина ContactManager нам понадобится представление для нашего действия
ContactsController::index()
, поэтому давайте это сделаем:
// plugins/ContactManager/src/Template/Contacts/index.ctp:
<h1>Контакты</h1>
<p>Ниже приведён отсортированный список ваших контактов</p>
<!-- Здесь будет отсортированный список контактов....-->
Плагины могут предоставлять свои собственные макеты. Чтобы добавить плагины, разместите
файлы шаблонов внутри plugins/[PluginName]/src/Template/Layout
. Чтобы использовать
плагин в вашем контроллере, вы можете сделать следующее:
public $layout = 'ContactManager.admin';
Если префикс плагина опущен, файл layout/view (макета/представления) будет нормально расположен.
Примечание
Для получения информации о том, как использовать элементы из плагина, посмотрите
Элементы
Переопределение шаблонов плагинов изнутри вашего приложения
Вы можете переопределить любые виды плагинов внутри вашего приложения, используя
специальные пути. Если у вас есть плагин с именем „ContactManager“, вы можете
переопределить файлы шаблонов плагина с помощью конкретной логики представления,
создав файлы, использующие следующий шаблон
src/Template/Plugin/[Plugin]/[Controller]/[view].ctp. Для контроллера контактов
вы можете сделать следующий файл:
src/Template/Plugin/ContactManager/Contacts/index.ctp
Создание этого файла позволит вам переопределить
plugins/ContactManager/src/Template/Contacts/index.ctp.
Если ваш плагин находится в зависимости от composer (т.е. „TheVendor/ThePlugin“),
путь к представлению „index“ пользовательского контроллера будет следующим:
src/Template/Plugin/TheVendor/ThePlugin/Custom/index.ctp
Создание этого файла позволит вам переопределить
vendor/thevendor/theplugin/src/Template/Custom/index.ctp.
Если плагин реализует префикс маршрутизации, вы должны включить префикс маршрутизации в
свои переопределения шаблона приложения.
Например, если плагин „ContactManager“ реализовал префикс „admin“, путь должен быть:
src/Template/Plugin/ContactManager/Admin/ContactManager/index.ctp
Ресурсы плагина
Веб-ресурсы плагина (но не файлы PHP) могут быть отправлены через директорию webroot
плагина, как и основные ресурсы приложения:
/plugins/ContactManager/webroot/
css/
js/
img/
flash/
pdf/
Вы можете поместить любой тип файла в любой каталог, как и обычно в webroot.
Предупреждение
Обработка статических активов (таких как изображения, файлы JavaScript и CSS)
через Диспетчер очень неэффективна. См. symlink-assets для получения
дополнительной информации.
Связывание с активами в плагине
Вы можете использовать plugin syntax при связывании с активами плагина с
помощью View\Helper\HtmlHelper
скриптов, изображений или
css-методов:
// Создаёт URL-адрес /contact_manager/css/styles.css
echo $this->Html->css('ContactManager.styles');
// Создаёт URL-адрес /contact_manager/js/widget.js
echo $this->Html->script('ContactManager.widget');
// Создаёт URL-адрес /contact_manager/img/logo.jpg
echo $this->Html->image('ContactManager.logo');
Активы плагина передаются с использованием фильтра диспетчера AssetFilter
по умолчанию. Это рекомендуется только для разработки. В производстве вы должны
использовать symlink plugin assets для повышения
производительности.
Если вы не используете помощников(helpers), вы можете добавить /plugin_name/ в
начало URL-адреса для актива в этом плагине для его обслуживания.
Связывание с „/contact_manager/js/some_file.js“ будет служить активу
plugins/ContactManager/webroot/js/some_file.js.
Компоненты, Помощники и Поведение
Плагин может содержать компоненты, помощники и поведение, как обычное приложение CakePHP.
Вы даже можете создавать плагины, которые состоят только из Компонентов, Помощников или Поведений,
которые могут быть отличным способом для создания повторно используемых компонентов, которые
можно использовать в любом другом проекте.
Построение этих компонентов точно такое же, как создание его в рамках обычного приложения, т.е
производится без специального соглашения об именах.
Обращаясь к вашему компоненту изнутри или снаружи вашего плагина, требуется только указать имя
плагина перед именем компонента. Например:
// Компонент, определённый в плагине 'ContactManager'
namespace ContactManager\Controller\Component;
use Cake\Controller\Component;
class ExampleComponent extends Component
{
}
// Внутри ваших контроллеров
public function initialize()
{
parent::initialize();
$this->loadComponent('ContactManager.Example');
}
Тот же метод применяется к Помощникам и Поведению.
Расширьте свой плагин
Этот пример создал хорошее начало для плагина, но возможностей намного больше.
Как правило, все, что вы можете сделать с вашим приложением, вы можете делать
и внутри плагина.
Идите дальше - включите некоторые сторонние библиотеки в „vendor“, добавьте новые
оболочки в консоль cake и не забудьте создать тестовые примеры, чтобы ваши
пользователи плагина могли автоматически протестировать функциональность вашего
плагина!
В нашем примере ContactManager мы могли бы добавить действия создания/удаления
/редактирования в ContactController, реализовать проверку в модели Contact и
реализовать функции, которые можно было бы ожидать при управлении своими контактами.
Вам решать, что реализовать в своих плагинах. Просто не забывайте делиться своим
кодом с сообществом, чтобы каждый мог воспользоваться вашими удивительными,
многоразовыми компонентами!
Опубликуйте свой плагин
Убедитесь, что вы добавили плагин в
plugins.cakephp.org <https://plugins.cakephp.org> _.
Таким образом, другие люди могут использовать его как зависимость в composer.
Вы также можете предложить свой плагин в список
awesome-cakephp <https://github.com/FriendsOfCake/awesome-cakephp> _.
Выберите семантически значимое имя для пакета. В идеале это должен быть префикс
зависимости „cakephp“ в качестве основы. Имя поставщика обычно
будет вашим именем пользователя GitHub. Не используйте пространство имён
CakePHP (cakephp), поскольку это зарезервировано для CakePHP, принадлежащих
плагинам. Соглашение заключается в использовании строчных букв и тире в качестве
разделителя.
Поэтому, если вы создали плагин „Logging“ с вашей учетной записью GitHub „FooBar“,
хорошим именем будет foo-bar/cakephp-logging. И CakePHP, принадлежащий плагину
„Localized“, можно найти под cakephp/localized соответственно.
Управление плагинами с помощью Микшера
Другой способ обнаружения и управления плагинами в вашем приложении CakePHP -
Mixer. Это плагин CakePHP, который помогает вам
устанавливать плагины из Packagist. Это также поможет вам управлять существующими плагинами.
Примечание
IMPORTANT: Не используйте это в продакшене.