1

I'm making a class to add metaboxes to Wordpress extending functionality of Metabox.io.

Now you often have metaboxes with the same attributes (for example for the same post type). I want to group these so you don't have to duplicate those attributes.

I have a function add() which simply adds a metabox.

Now I want the group() method to do the following:

$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', ], ] ]); }); 

So my group() method accepts an array of attributes, which need to be added to the array of attributes of every single add() in the Closure.

Laravel does this really beautifully with Routes, looks something like this:

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

What would be the best way to achieve this?

EDIT:

This is my Metabox manager class

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; } ); } } 
5
  • I don't understand. Are you trying to achieve something in Laravel or is Laravel just a showcase of what you want to achieve in WordPresss or whatever toy you're playing with? Commented Feb 18, 2017 at 8:18
  • Laravel was just an example. I want to create something similar: appending to the second parameters' array of the add function in the closure. Commented Feb 18, 2017 at 8:23
  • Manager refers to a singleton class. So currently cannot extend it. Commented Feb 18, 2017 at 8:29
  • Im not using any framework. I will share the code of my Metabox manager in one second Commented Feb 18, 2017 at 8:36
  • Let us continue this discussion in chat. Commented Feb 18, 2017 at 8:39

1 Answer 1

2

Here's one suggestion. When calling the group method, you can store the shareable information within your class and later use it inside your add method.

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. } 

Now, for the add method.

/** * 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; } 

Sidenote: Calling array_merge with $attributes as your second parameter allows you to overwrite group values for just a specific add.

Sign up to request clarification or add additional context in comments.

4 Comments

Aahhh damn that's smart. Why didn't I think of that, let me try this out and I'll let you know!
Works! Thanks for you help. Made some minor changes: since you do $this->group = $attributes you're setting the group variable so it's not necessary to make it empty again (with $this->group = [];). Thanks again!
@MelvinKoopmans If you call the group method, later make a call just to add (without group), it will automatically be grouped if you don't clean it up.
Do you have any idea how I can remove the need to specify use ($manager) when calling the group method? Can I somehow inject an instance into the closure within the group method?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.