proklung/wp-core-symfony

Wordpress 的核心 Symfony 功能

1.96 2022-01-27 07:49 UTC

README

安装

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 - 调试模式

配置

  1. 在拉取的配置中,compile.container 选项 - 是否编译容器到文件。如果没有设置,则为“不编译”。对于不等于“dev”的环境有意义。即选项控制容器在 prod 上的导出。

容器导出的存储位置:<容器变量 kernel.cache_dir>/symfony-app/containers

缓存和日志的路径

AppKernel 类定义。默认情况下

  • 缓存路径(kernel.cache_dir) - /wp-content/cache
  • 日志路径(kernel.logs_dir) - '/../../logs'(比 DOCUMENT_ROOT 高两级 - 使用 Bitrix 所用构建的特点)

要更改这些,需要从 AppKernel 类继承并重写几个变量

use Prokl\ServiceProvider\Services\AppKernel;

class MyKernel extends AppKernel
{
   protected $cacheDir = '/bitrix/cache/mycache';
    
   protected $logDir = '/logs-saver';
}

(第二种方案 - 从 AppKernel 继承并重写 getCacheDirgetLogDir 方法)。

通过继承核心类进行更改

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 的服务先启动。

自动绑定到 WordPress 插件

标签: custom.events.init

  1. type - add_action、add_filter 等 默认: add_action
  2. event - 插件名称。
  3. method - 服务中的处理方法
  4. 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(和别名)- 服务容器本身
  • app.request - 全局变量到 Request 的转换器
  • custom.post.type.registrator - 在 WordPress 中注册自定义帖子类型
  • 服务的同义词 kernel
  • delegated_container_manipulator - 委派容器操作器。

助手

  1. container() - 返回容器实例(充当服务定位器)
$kernel = container()->get('kernel');
  1. 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' }