pinkcrab/plugin-framework

该软件包已被废弃且不再维护。作者建议使用 pinkcrab/perique-framework-core 软件包。

PinkCrab Perique 框架的核心包。


README

PinkCrab Perique 插件框架

欢迎使用 PinkCrab Perique 插件框架的核心包,它以前被称为 PinkCrab 插件框架。

alt text Open Source Love codecov

有关更多详细信息,请访问我们的文档。 https://app.gitbook.com/@glynn-quelch/s/pinkcrab/

版本 0.5.3

原因是什么?

WordPress 是一种强大的工具,可以用于构建各种网站,但由于其年龄和对向后兼容性的承诺,使用更现代的工具进行工作往往令人沮丧。

Perique 允许创建用于更复杂网站的插件、主题和 MU 库。

核心包仅提供对 Hook_Loader、注册、DI(DICE 依赖注入容器)、App_Config 和基本(本地)PHP 渲染引擎的访问。

什么是 Perique?

Perique 是一种罕见的烟叶,产于路易斯安那州圣詹姆斯教区。这种历史悠久的烟叶在该地区已经生产了几百年,将烟叶取下,在压力下装入桶中,并存放超过12个月。 resulting tobacco has a strong and pungent quality, which is used to heavily enhance a tobaccos flavor, nicotine content and aroma with only a small quantity used. This is something we strive to produce in this framework; a small amount of existing code that can be used to enhance any codebase to be big, bold and striking.

设置

$ composer require pinkcrab/perique

首先,您需要创建您的 composer.json 和 plugin.php 文件。

plugin.php

// @file plugin.php 
<?php
     
/**
 * @wordpress-plugin
 * Plugin Name:     ##PLUGIN NAME##
 * Plugin URI:      ##YOUR URL##
 * Description:     ##YOUR PLUGIN DESC##
 * Version:         ##VERSION##
 * Author:          ##AUTHOR##
 * Author URI:      ##YOUR URL##
 * License:         GPL-2.0+
 * License URI:     https://gnu.ac.cn/licenses/gpl-2.0.txt
 * Text Domain:     ##TEXT DOMAIN##
 */

require_once __DIR__ . '/vendor/autoload.php';

// Creates an App loaded with the WP_Dice DI container and basic DI rules
// Allows for the passing of wpdb and the App's own instance.
$app = ( new App_Factory )->with_wp_dice( true );

// Set rules and configure DI Container
$app->di_rules(include __DIR__ . '/config/dependencies.php');

// Pass settings for App_Config
$app->app_config( include __DIR__ . '/config/settings.php' )

// Pass all class names which should be used during registration
$app->registration_classses(include __DIR__ . '/config/registration.php' );

// Add custom Regisration Middleware
$app->registration_middleware(new Eaxmple_Rest_Route_Registration_Middleware('my_base/route'));

// Then just boot the application.
$app->boot();

配置文件

虽然您可以将数组传递给 container_config()、app_config() 和 registration_classes(),但这些可能会变得相当庞大。从文件返回它们可能会有所帮助。

这些文件可以放在任何位置,但在上述示例和我们的模板中,这三个文件都放在 /config 目录中。

dependencies.php

用于定义所有自定义规则,有关如何与接口和其他无法自动装配的类一起使用 Dice 的更多详细信息,请参阅 完整文档

使用完整类名至关重要,因此请确保包含所有需要的 use 语句。

// @file config/dependencies.php

<?php

use Some\Namespace\{Some_Interface, Some_Implementation};

return array(
    // Your custom rules
	Some_Interface::class => array(
		'instanceOf' => Some_Implementation::class
	)
);

registration.php

当应用启动时,所有具有钩子调用或需要调用的类都通过此数组传递。

默认情况下,可注册的中间件将被传递,因此所有实现Registerable接口的类都将被调用。添加自定义注册中间件可以让你在启动时将它们传递到这个数组中进行初始化。

使用完整类名至关重要,因此请确保包含所有需要的 use 语句。

// @file config/registration.php

<?php

use Some\Namespace\Some_Controller;

return array(
    Some_Controller::class
);

settings.php

应用持有一个内部配置类,这可以用作大量定义常量的辅助方法的注入集合。

除了通常需要的路径和URL值外,您还可以设置命名空间(rest,cache)、帖子类型(meta和slug)、分类(slug & term meta)、数据库表名和自定义值。

// @file config/settings.php
<?php
    
// Assumes the base directory of the plugin, is 1 level up.
$base_path  = \dirname( __DIR__, 1 );
$plugin_dir = \basename( $base_path );

// Useful WP helpers
$wp_uploads = \wp_upload_dir();
global $wpdb;

return array(g
	'plugin'     => array(
		'version' => '1.2.5',
	),
	'path'       => array(
		'plugin'         => $base_path,
		'view'           => $base_path . '/views',
		'assets'         => $base_path . '/assets',
		'upload_root'    => $wp_uploads['basedir'],
		'upload_current' => $wp_uploads['path'],
	),
	'url'        => array(
		'plugin'         => plugins_url( $plugin_dir ),
		'view'           => plugins_url( $plugin_dir ) . '/views',
		'assets'         => plugins_url( $plugin_dir ) . '/assets',
		'upload_root'    => $wp_uploads['baseurl'],
		'upload_current' => $wp_uploads['url'],
	),
	'db_table' => array(
		'subscriptions' => $wpdb->table_prefix . 'some_plugin_subscribers'
	),
	'additional' => array(
		// Custom values go here (Config::additiona('key'); = value)
	),
);

完整的选项集可以在文档中找到。

注册服务

应用程序的核心是注册过程。类可以在初始化时堆叠并执行。这允许注册到核心WP API、触发远程API调用,以及所有其他在加载所有WP核心时需要设置的事情。

Registerable

Loader::class 加载器已被弃用,并替换为新的 Hook_Loader::class

Perique附带了一个单独的Registration_Middleware。Renderable接口和Renderable_Middleware对使注册任何钩子、短代码、帖子类型、分类、管理页面和REST端点变得简单。任何需要处理的类,都实现了Renderable接口,并创建了function register(Hook_Hook_Loader $loader): void {...}

class Some_Controller implements Registerable {
	public function register(Hook_Loader $loader): void{
		$loader->admin_action('some_action', [$this, 'some_action']);
	}
	public function some_action($some_arg): void {...}
}

现在当调用init钩子(优先级1)时,some_action钩子将被添加。只要请求来自wp-admin。

有关Registerable和Hook_Loader的更多详细信息,请参阅完整文档

注册中间件

可以使用Registration_Middleware添加自定义注册过程。您可以轻松创建自己的中间件,该中间件实现了PinkCrab\Perique\Interfaces\Registration_Middleware接口。该接口由一个方法组成 process(object $class): void,每个类都可以使用。

<?php

class Does_Something implements PinkCrab\Perique\Interfaces\Registration_Middleware {

	/** @var Some_Service */
	protected $some_service;
	
	public function __cosntruct(Some_Service $some_service){
		$this->some_service = $some_service;
	}

	public function process(object $class): void {
		// Use interfaces or abstract classes to ensure you only process classes you expected
		if ( in_array( Some_Interface::class, class_implements( $class ) ?: array(), true ) ) {
			$this->some_service->so_something($class);
		}
	}
}

对象是完全使用DI_Container构建的

然后,您可以在启动时将这些自定义Registration_Middlewares传递给应用程序。

<?php 

$app = ( new App_Factory )->with_wp_dice( true )
	// Rest of bootstrapping
	->registration_middleware(new Does_Something(new Some_Service()))
	->boot();

静态辅助工具

App对象有几个可以静态调用的辅助方法(要么从实例调用,要么从其名称调用)。

App::make(string $class, array $args = array()): object

  • @param string $class 完整命名空间类名
  • @param array $args 如果需要,构造函数参数
  • @return object 对象实例
  • @throws App_Initialization_Exception 如果应用程序未初始化,则返回代码4。

make() 可以用来访问DI容器,以完全解析对象的依赖项。

$emailer = App::make(Customer_Emailer::class);
$emailer->mail(ADMIN_EMAIL, 'Some Report', $email_body);
$emailer->send();

App::config(string $key, ...$child): mixed

  • @param string $key 要调用的配置键
  • @param ...string $child 传递的附加参数。
  • @return mixed
  • @throws App_Initialization_Exception 如果应用程序未初始化,则返回代码4。

一旦应用程序启动,您可以通过传递App_Config作为依赖项或使用应用程序的帮助程序来访问App_Config值。

// Get post type slug
$args = ['post_type' => App::config('post_types', 'my_cpt')];

// Get current plugin version.
$version = App::config('version');

有关App_Config及其各种用法的更多详细信息,请查看完整文档

App::view(): 视图

  • @return 视图
  • @throws App_Initialization_Exception 错误码 4

如果您需要渲染或返回模板,可以使用view()辅助函数。返回View类的实例,其中包含当前定义的引擎(默认使用PHP)。

App::view()->render('signup/form', ['user' => wp_get_current_user(), 'nonce' => $nonce]);

尽管View和Config辅助函数有时很有用,但始终最好将它们注入(App_Config::class或View::class)。

钩子

我们有多个钩子可以用来扩展或修改应用程序的工作方式。我们所有的内部钩子都有pinkcrab/pf/app/前缀,但我们提供了一组常量类,您可以使用PinkCrab\Perique\Application\Hooks::APP_INIT_*

Hooks::APP_INIT_PRE_BOOT

这主要用于内部,用于在启动过程中进行最后时刻的更改。由于此钩子的使用方式(在加载plugin.php时调用),它不应在您的代码外部使用,因为您可以确保外部代码首先加载。

<?php
add_action( 
	Hooks::APP_INIT_PRE_BOOT, 
	function( App_Config $app_config, Hook_Loader $loader, DI_Container $container ): void {
		// do something cool
	}
);

Hooks::APP_INIT_PRE_REGISTRATION

在启动过程中,所有传递给注册的类都在初始化钩子中处理,优先级为1。APP_INIT_PRE_REGISTRATION钩子在这些类被添加之前触发。这允许您将额外功能连接到应用程序。这允许您通过其他插件扩展您的插件。

<?php
add_action( 
	Hooks::APP_INIT_PRE_REGISTRATION, 
	function( App_Config $app_config, Hook_Loader $loader, DI_Container $container ): void {
		$some_controller = $container->create(Some_Other\Namespace\Some_Controller::class);
		$some_controller->load_hooks($loader);
	}
);

Hooks::APP_INIT_POST_REGISTRATION

所有注册过程完成后,此钩子被触发。这允许您检查所有内容是否正确加载或是否缺少任何内容。然后您可以根据其结果发出通知或禁用功能。内部加载器在此之后被触发,因此您仍然可以在初始化之前使用后续的钩子。

<?php
add_action( 
	Hooks::APP_INIT_POST_REGISTRATION, 
	function( App_Config $app_config, Hook_Loader $loader, DI_Container $container ): void {
		if( ! has_action('some_action') ){
			// Do something due to action not being added.
		}
	}
);

Hooks::APP_INIT_CONFIG_VALUES

当App_Config类使用从config/settings.php传递的所有值构建时,此过滤器在初始启动过程中触发,并且实际上主要用于内部目的。遗憾的是,由于我们使用此过滤器的时间,它并不适合扩展插件。

<?php
add_filter(Hooks::APP_INIT_CONFIG_VALUES, 
	function( array $config ): array {
		$config['additional']['some_key'] = 'some value';
		return $config;
	}
);

Hooks::APP_INIT_REGISTRATION_CLASS_LIST

在处理传递给注册服务器的类之前过滤所有类。这允许从其他插件中进行钩子连接。

<?php
add_filter(Hooks::APP_INIT_REGISTRATION_CLASS_LIST, 
	function( array $class_list ): array {
		$class_list[] = 'My\Other\Plugin\Service';
		$class_list[] = Another_Service::class;
		return $class_list;
	}
);

Hooks::APP_INIT_SET_DI_RULES

当DI规则设置到容器中时,此过滤器应用于所有定义。这允许从外部插件和代码中进行钩子连接以使用DI_Container。结合其他钩子,允许完全扩展您的插件。

<?php
add_filter(Hooks::APP_INIT_SET_DI_RULES, 
	function( array $di_rules ): array {
		$di_rules['*'][Some_Interface::class] = Some_Class_Implementation::class;
		return $di_rules;
	}
);

许可证

MIT许可证

https://open-source.org.cn/licenses/mit-license.html

变更日志

  • 0.5.3 - 由于现有问题,迁移到新composer名称。
  • 0.5.2 - 将主命名空间从 PinkCrab\Perique 更新为 PinkCrab\Perique。在 composer.json 中修正了包名中的拼写错误,从 perqiue 改为 perique。
  • 0.5.1 - 移除了最后一个 Loader::class 类型提示和引用。现在所有内容都使用 Hook_Loader::class。
  • 0.5.0
    • 迁移到新的 Hook_Loader 类型。
    • 对 App_Config 进行更新(创建元子部分并移至简单的键值对以用于文章类型和分类法)。
    • 向 Registration_Middleware 接口添加了 setup() 和 teaspotifyr_down() 方法。
    • 将 Collection 迁移到其自己的仓库中。[链接](https://github.com/Pink-Crab/Collection "外部链接")
    • 移除了未使用的服务容器接口。
  • 0.4.1 - 更新测试以反映新的 Hook_Loader 内部结构(测试时访问受保护的属性)。
  • 0.4.0 - 引入新的应用,包含应用工厂以帮助进行更干净的初始化。重新引入了在 0.2.0 中移除的 Registration_Middleware。将可注册项移至默认中间件中,该中间件在启动时自动添加。添加了一系列围绕 init 回调的动作,该回调运行注册过程。
  • 0.3.9 - 将 Loader 迁移到自己的库中,所有测试和使用语句都已更新。
  • 0.3.8 - 添加了缺失的 Hook_Removal 和 Loader 测试。
  • 0.3.7 - 添加了 Hook_Removal 并对 Loader 测试进行了少量修改。
  • 0.3.6 - 向 Loader 添加了 remove_action() 和 remove_filter()。
  • 0.3.5 - 将覆盖率报告添加到 gitignore。
  • 0.3.4 - 改进了测试并连接到 codecov。
  • 0.3.3 - 从服务容器中移除了对象类型提示。
  • 0.3.2 - 添加了测试并扩展了视图。
  • 0.3.1 - 为 phpstan lv8 进行了小的 docblock 修改。