WordPress PSR-4 Namespaced插件访问另一个Namespaced插件

iVi*_*ios 5 php wordpress plugins namespaces

很快,我正在尝试使用WordPress构建一个"生态系统",我有一个核心插件,然后是额外的附加插件.

更深入的是,每个附加插件都需要核心插件才能运行.我已经使用WordPress标准编码和文件结构实践实现了这一目标.我正在重新设计这个项目,现在使用Namespacing PSR-4,作曲家,凉亭等.

标准WordPress安装

|
|__www
  |
  |___wp-admin
  |
  |___wp-content
  |   | 
  |   |___plugins
  |   |   |
  |   |   |___my-core-plugin
  |   |   |   |
  |   |   |   |___library
  |   |   |   |    |
  |   |   |   |    |___class-post-register.php
  |   |   |   |
  |   |   |   |___vendor
  |   |   |   |    |
  |   |   |   |    |___autoload.php
  |   |   |   |
  |   |   |   |___composer.json
  |   |   |   |
  |   |   |   |___core.php
  |   |   |
  |   |   |___my-first-addon-plugin
  |   |   |   |
  |   |   |   |___library
  |   |   |   |
  |   |   |   |___vendor
  |   |   |   |    |
  |   |   |   |    |___autoload.php
  |   |   |   |
  |   |   |   |___composer.json
  |   |   |   |
  |   |   |   |___core.php
  |   |   |
  |   |   |___my-second-addon-plugin
  |   |   |   |
  |   |   |   |___library
  |   |   |   |
  |   |   |   |___vendor
  |   |   |   |    |
  |   |   |   |    |___autoload.php
  |   |   |   |
  |   |   |   |___composer.json
  |   |   |   |
  |   |   |   |___core.php
  |   |   |
  |   |___themes
  |   |   |   
  |   |   |___my-custom-theme
  |   |
  |   wp-includes
Run Code Online (Sandbox Code Playgroud)

核心插件psr4通过作曲家

"autoload": {
    "psr-4": {
        "CorePlugin\\Library\\": "library"
    }
}
Run Code Online (Sandbox Code Playgroud)

示例核心插件类

<?php 

namespace CorePlugin\library;

class Post_Register {

    private __construct() {
        // ... code
     }

    private init() {

    }

    private register( $data ) {
        // .. code to register a custom post for example.
    }

}
Run Code Online (Sandbox Code Playgroud)

第一个通过composer加载插件psr4

"autoload": {
    "psr-4": {
        "FirstAddon\\Library\\": "library"
    }
}
Run Code Online (Sandbox Code Playgroud)

来自附加插件的类

下面是我困惑的地方.我正在尝试在不同的命名空间中使用核心插件中的类,我收到错误:

致命错误:在'...中找不到类'CorePlugin\Library\Post_Register'

两个插件自动加载他们各自的作曲家生成自动加载文件,所以我虽然我能够use命名空间.在我深入研究PHP手册(http://php.net/manual/en/language.namespaces.php)的这一部分之前,我来到这里询问,在那里我可能尝试使用子命名空间.

<?php 

namespace FirstAddon;

use CorePlugin\Library\Post_Register;

class First_Addon {

    private __construct() {
        // ... code
     }

    private init() {

    }

    private another_function() {

    }

}
Run Code Online (Sandbox Code Playgroud)

另外,我对使用带括号的子命名空间犹豫不决,例如,在laravel中,usefoo\bar; 和use酒吧\ foo; 像这样.

<?php namespace App\Services;

use App\User;
use Validator;
use Illuminate\Contracts\Auth\Registrar as RegistrarContract;

class Registrar implements RegistrarContract {
Run Code Online (Sandbox Code Playgroud)

Dar*_*ron 0

我确信你已经离开了这个,但我想我无论如何都会回答,以防其他人尝试让插件相互依赖。我在插件中使用类和命名空间。我的插件重用彼此的类。

命名空间插件

首先,它基本上取决于 WordPress 加载插件的顺序。我自己来自 C#/Java,最初对 WP 的工作方式感到困惑。您要确保您要使用的插件已加载。执行此操作的最佳方法是通过后期挂钩实例化该类 - 您知道这是在加载插件后发生的。一个例子可以是

add_action('plugins_loaded', function () { new whatever() });
Run Code Online (Sandbox Code Playgroud)

然后让构造函数使用其他插件中的类(或者您需要的地方):

function __construct() {
  $other_plugin_class = new \Namespace\To\Other\Plugin\MyClass();
}
Run Code Online (Sandbox Code Playgroud)

依赖关系

如果插件相互依赖,并且需要根据启用和未启用的插件进行不同的操作,您可以这样做:

if ( ! function_exists( 'is_plugin_active' ) )
  require_once( ABSPATH . '/wp-admin/includes/plugin.php' );

if ( is_admin() and is_plugin_active('myplugin1/plugin1.php') ) {
  add_action( 'admin_menu', array( $this, 'add_a_menu_depending_on_another_plugin' ), 99 );
}
Run Code Online (Sandbox Code Playgroud)

首先它确保我们需要的功能已加载,然后检查相关插件是否启用。

自动装载机

值得一提的是,我使用内置的自动加载器:

spl_autoload_register( 'my_autoloader' );
function my_autoloader( $class_name ) {
  if ( false !== strpos( $class_name, 'Nuvobook' ) ) {
    $classes_dir = plugin_dir_path( __DIR__ );
    $class_file = strtolower(str_replace( '_', '-', str_replace( '\\', DIRECTORY_SEPARATOR, $class_name ) ) . '.php');
    include_once $classes_dir . $class_file;
  }
}
Run Code Online (Sandbox Code Playgroud)

..它将我的类命名约定 My_Class 映射到文件名 my-class.php

这一切都非常有效。

希望对某人有帮助。