composer.json:
"repositories": [
{
"type": "git",
"url": "https://github.com/proklung/wp.core.symfony"
}
]composer require proklung/wp-core-symfonyВ wp-config.php:
use Prokl\ServiceProvider\LoadEnvironment;
/** Загрузить окружение. Параметр конструктора - путь к .env файлам */
$environment = new LoadEnvironment($_SERVER['DOCUMENT_ROOT']);
$environment->load();
$environment->process();В functions.php темы:
use Prokl\ServiceProvider\ServiceProvider;
$serviceProvider = new ServiceProvider(
'app/symfony/services.yaml',
$_ENV['APP_ENV'],
(bool)$_ENV['APP_DEBUG'],
'/config/bundles.php'
);Для обеспечения "преемственности" (похожести) с оригиналом можно задать путь к файлу конфигурации
(скажем, bundles.php) бандлов четвертым (необязательным) параметром конструктора.
APP_ENV- код окружения (dev, prod, test и т.д.)APP_DEBUG- режим отладки
- Опция
compile.containerв подтягиваемом конфиге - компилировать ли контейнер в файл. Если не задана, то "нет, не компилировать". Имеет смысл для окружения, не равного "dev". Т.е. опция управляет дампированием контейнера на проде.
Место, где хранятся дампы контейнеров: <значение переменной контейнера kernel.cache_dir>/symfony-app/containers
Определяются классом AppKernel. По умолчанию:
- путь к кэшу (
kernel.cache_dir) -/wp-content/cache - путь к логам (
kernel.logs_dir) -'/../../logs'(два уровня выше DOCUMENT_ROOT - особенности используемой сборки Битрикс)
Чтобы это изменить нужно отнаследоваться от класса AppKernel и переопределить несколько переменных:
use Prokl\ServiceProvider\Services\AppKernel;
class MyKernel extends AppKernel
{
protected $cacheDir = '/bitrix/cache/mycache';
protected $logDir = '/logs-saver';
}(второй вариант - отнаследоваться от AppKernel и переопределить методы getCacheDir и getLogDir).
Изменить через наследование класс ядра:
class MyServiceProvider extends ServiceProvider
{
protected $kernelServiceClass = MyKernel::class;
protected $cacheDir = '/wp-content/my-cache';
}Второй вариант - отнаследоваться от ServiceProvider и заменить метод getPathCacheDirectory своей логикой.
Файл конфигурации - /config/standalone_bundles.php. Этот путь можно изменить через конструктор.
Папка, где лежат конфигурации - /config. Конфигурации бандлов - /config/packages.
Согласно концепции Symfony все сервисы (в идеале) должны быть приватными и инжектиться. Но в кастомном случае
часто нужно получать их через хелпер-сервис-локатор. Для превращения нужных сервисов в публичные предлагается
такое решение. В общем разделе параметров контейнера появилась опция publicable_services:
parameters:
publicable_services:
- 'snc_redis.default'После компиляции контейнера приватный сервис snc_redis.default станет публичным.
Отдельные контейнеры - со своим конфигом, полностью изолированные (для модулей, плагинов и т.п.).
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Prokl\ServiceProvider\Micro\AbstractStandaloneServiceProvider;
use Prokl\ServiceProvider\Micro\ExampleAppKernel;
class ExampleMicroServiceProvider extends AbstractStandaloneServiceProvider
{
/**
* @var ContainerBuilder $containerBuilder Контейнер.
*/
protected static $containerBuilder;
/**
* @var string $pathBundlesConfig Путь к конфигурации бандлов.
*/
protected $pathBundlesConfig = '/src/Micro/example.config/standalone_bundles.php';
/**
* @var string $configDir Папка, где лежат конфиги.
*/
protected $configDir = '/src/Micro/example.config/example.config/example.yaml';
/**
* @var string $kernelServiceClass Класс, реализующий сервис kernel.
* Нужен для того, чтобы экземпляры контейнеров в kernel сервисе не перемешивались.
*/
protected $kernelServiceClass = ExampleAppKernel::class;
}Пример класса ExampleAppKernel:
/**
* Class ExampleAppKernel
* @package Prokl\ServiceProvider\Micro
*/
use Prokl\ServiceProvider\Micro\AbstractKernel;
class ExampleAppKernel extends AbstractKernel
{
protected static $kernelContainer;
}Где надо - инициализация:
$micro = new ExampleMicroServiceProvider(
'src/SymfonyDI/Micro/example.config/example.yaml',
$_ENV['APP_ENV'],
(bool)$_ENV['APP_DEBUG']
);Хэлпер container заточен под работу с микро-сервис-провайдерами:
var_dump(container($micro)->getParameter('example'));Чтобы сервис запустился автоматически после инициализации контейнера, он должен быть помечен тэгом service.bootstrap.
app.options:
class: Local\Services\AppOptions
arguments: ['%kernel.environment%', '@parameter_bag']
tags: ['service.bootstrap']Поддерживается приоритет запуска. Тогда надо так:
app.options:
class: Local\Services\AppOptions
arguments: ['%kernel.environment%', '@parameter_bag']
tags:
- { name: 'service.bootstrap', priority: 100 }Сервис с приоритетом 100 запустится раньше сервиса с приоритетом 200.
Тэг: custom.events.init.
type- add_action, add_filter & etc По умолчанию:add_action.event- название хука.method- метод-обработчик в сервисеpriority- приоритет
Local\Events\CometCacheClearMemcachedEvent:
tags:
- { name: 'custom.events.init', event: 'post_class', method: 'handler', type: 'add_filter', priority: 100 }Тэг: post.type.
Реализует интерфейс PostTypeDataInterface с двумя методами:
getNameTypePost- название типа постаgetRegistrationData- массив с традиционными для объявления типа поста данными. Типа такого:
return [
'labels' => [
'name' => __('Instagram'),
'singular_name' => __('Instagram'),
],
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => 'instagram',
'capability_type' => 'post',
'has_archive' => 'instagram',
'hierarchical' => false,
'menu_position' => null,
'supports' => ['title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments'],
];Local\PostTypes\InstagramPostType:
tags:
- { name: 'post.type' }Автоматом регистрируются несколько сервисов:
service_container(и alias) - сервис-контейнер целикомapp.request- конвертор глобалов в Requestcustom.post.type.registrator- регистратор кастомных типов постов в Wordpress- синонимы сервиса
kernel. delegated_container_manipulator- манипулятор делегированными контейнерами.
container()- отдает экземпляр контейнера (выступает в роли сервис-локатора):
$kernel = container()->get('kernel');delegatedContainer()- отдает экземпляр манипулятора (реализующего интерфейсSymfony\Component\DependencyInjection\ContainerInterface) делегированными контейнерами.
$moduleService = delegatedContainer()->get('my_module_id.service');Делегированный контейнер - автономный контейнер, сформированные в модуле, плагине и тому подобных местах.
В контейнере он помечается тэгом delegated.container (их может быть сколь угодно много):
module_notifier_container:
class: Symfony\Component\DependencyInjection\ContainerInterface
factory: ['Proklung\Notifier\DI\Services', 'getInstance']
tags:
- { name: 'delegated.container' }