如何“修改”一个闭包

时间:2017-02-18 08:14:18

标签: php wordpress laravel closures php-7

我正在创建一个类来向Wordpress添加元文件扩展Metabox.io的功能。

现在,您经常使用具有相同属性的元数据库(例如,对于相同的帖子类型)。我想对这些进行分组,因此您无需复制这些属性。

我有一个函数add(),只需添加一个元数据集。

现在我希望group()方法执行以下操作:

$manager->group([
    'post_types' =>'page',
], function() use ($manager) {

    $manager->add('metaboxfromgroup', [
        'title'      => __( 'Metabox added from group!', 'textdomain' ),
        'context'    => 'normal',
        'fields'     => [
            [
                'name'  => __( 'Here is a field', 'textdomain' ),
                'id'    => 'fname',
                'type'  => 'text',
            ],
        ]
    ]);

});

所以我的group()方法接受一个属性数组,需要将它们添加到Closure中每个add()的属性数组中。

Laravel使用Routes做得非常漂亮,看起来像这样:

Route::group(['middleware' => 'auth'], function () {
    Route::get('/', function ()    {
        // Uses Auth Middleware
    });

    Route::get('user/profile', function () {
        // Uses Auth Middleware
    });
}); 

实现这一目标的最佳方式是什么?

编辑:

这是我的Metabox经理班

namespace Vendor\Lib;

use Vendor\App\Config as Config;

final class Metabox {

    /** @var string */
    protected $prefix;

    /** @var array */
    static private $metaboxes = [];

    public static function getInstance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new Metabox();
        }
        return $inst;
    }

    /**
     * Metabox constructor.
     *
     * @param string $prefix
     */
    private function __construct() {
        $this->prefix = Config::get('metabox.prefix');
    }

    /**
     * Add a new metabox.
     *
     * @param string $id
     * @param array $attributes
     */
    public function add( $id, array $attributes ) {
        $attributes['id'] = $id;

        array_walk_recursive( $attributes, function ( &$value, $key ) {
            if (
                $key === 'id'
                && substr( $value, 0, strlen( $this->prefix ) ) !== $this->prefix
            ) {
                $value = $this->prefix . $value; // auto prefix
            }
        } );

        self::$metaboxes[] = $attributes;
    }

    public function group( $attributes, $function) {
        // here comes group method
    }

    /**
     * Register the metaboxes.
     */
    public function register() {
        add_filter( 'rwmb_meta_boxes', function () {
            return self::$metaboxes;
        } );
    }

}

1 个答案:

答案 0 :(得分:2)

这是一个建议。调用group方法时,您可以将可共享信息存储在班级中,然后在add方法中使用。

final class Metabox {
    private $group = [];
    ...
}

public function group( $attributes, $function) {
    $this->group = $attributes;
    $function(); // Invoke the closure, I don't remember if this is the right way.
    $this->group = [];  // Clean up the group.
}

现在,对于add方法。

/**
 * Add a new metabox.
 *
 * @param string $id
 * @param array $attributes
 */
public function add( $id, array $attributes ) {
    if(!empty($this->group))
       $attributes = array_merge($group, $attributes);

    $attributes['id'] = $id;

    array_walk_recursive( $attributes, function ( &$value, $key ) {
        if (
            $key === 'id'
            && substr( $value, 0, strlen( $this->prefix ) ) !== $this->prefix
        ) {
            $value = $this->prefix . $value; // auto prefix
        }
    } );

    self::$metaboxes[] = $attributes;
}

旁注:调用带有$attributes的array_merge作为第二个参数,可以覆盖特定添加的组值。