Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

php - Trying to create a loop method to add WordPress meta boxes based on files with form fields in folder

I wrote a method to scan a directory for XML files and dynamically create WordPress metaboxes for page and post types. All works fine except when looping to load the file within the add_meta_box() callback function enclosure.

The desired output

Should return only the fields associated with each meta box.

desired output of fields

The actual output

Each box returns the same fields from all files found.

erroneous output

The coding

public static function getForms($dir)
{
    global $metaboxes, $configforms;
    $metaboxes = mb::filelist($dir, '^metabox_', true); // returns an array of full path files
    
    if( !empty($metaboxes) ) 
    {
        add_action('add_meta_boxes', function() 
        {
            global $metaboxes, $metabox_path;
            $metabox_path=[];
            foreach($metaboxes as $metabox) 
            {
                $form = simplexml_load_file($metabox);
                $boxval = $form->attributes();
                
                $boxid = strtolower(str_replace(' ', '-', (string)$boxval->boxlabel)).'-metaboxid';
                $posttypes = (isset($boxval->posttype) ? explode(',', (string)$boxval->posttype) : get_post_types());
                $col = (isset($boxval->col) ? (string)$boxval->col : 'normal');
                $priority = (isset($boxval->priority) ? (string)$boxval->priority : '');
                $metabox_path[] = substr($metabox,0,-4);
                
                // create each metabox
                foreach($posttypes as $posttype) 
                {
                    add_meta_box($boxid, (string)$boxval->boxlabel, function() 
                    {
                        global $metabox_path;

                        foreach($metabox_path as $path) 
                        {
                            // pass the XML file to the form field processor
                            // the method will echo the output
                            self::form($path);
                        }
                        
                    }, strtolower($posttype), $col, $priority);
                }
                
            }
        });
    }
}

The XML file content

metabox_photos.xml

<?xml version="1.0" encoding="utf-8"?>
<form boxlabel="Photo Boxes">
    <fields>
        <fieldset>
            <field type="text" name="sosphoto" label="The List" />
        </fieldset>
    </fields>
</form>

Other XML metabox_woofield.xml

<?xml version="1.0" encoding="utf-8"?>
<form posttype="post,page" col="normal" priority="high" boxlabel="Woo Fields">
    <fields>
        <fieldset>
            <field type="text" name="woobox" label="Wooten" />
        </fieldset>
    </fields>
</form>

I've tried conditions within the add_meta_box() function closure to match current metabox ID using the global var $wp_meta_boxes and compare to the $boxid variable, and the erroneous result persisted.

How can I get this method to deliver the desired result?

question from:https://stackoverflow.com/questions/66059540/trying-to-create-a-loop-method-to-add-wordpress-meta-boxes-based-on-files-with-f

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Solution defined!

I removed the global variables and implemented the PHP keyword use, then wrapped the add_meta_box() function withing the foreach() loop and passed the $path variable to the closure.

public static function getForms($dir)
{
    $metaboxes = mb::filelist($dir, '^metabox_', true);
    
    if( !empty($metaboxes) ) 
    {
        add_action('add_meta_boxes', function() use ($metaboxes)
        {
            $metabox_path=[];
            foreach($metaboxes as $metabox) 
            {
                $form = simplexml_load_file($metabox);
                $boxval = $form->attributes();
                
                $boxid = strtolower(str_replace(' ', '-', (string)$boxval->boxlabel)).'-metaboxid';
                $posttypes = (isset($boxval->posttype) ? explode(',', (string)$boxval->posttype) : get_post_types());
                $col = (isset($boxval->col) ? (string)$boxval->col : 'normal');
                $priority = (isset($boxval->priority) ? (string)$boxval->priority : '');
                $metabox_path[] = substr($metabox,0,-4);
                
                
                foreach($posttypes as $posttype) 
                {
                    foreach($metabox_path as $path) 
                    {
                        add_meta_box($boxid, (string)$boxval->boxlabel, function() use ($path) {
                            self::form($path);
                            
                        }, strtolower($posttype), $col, $priority);
                    }
                }
                
            }
        });

The result

correct output

The XML files loaded per meta box

metabox_photos.xml

<?xml version="1.0" encoding="utf-8"?>
<form boxlabel="Photo Boxes">
    <fields>
        <fieldset>
            <field type="text" name="sosphoto" label="The List" />
            <field type="textarea" name="flood" label="World" />
        </fieldset>
    </fields>
</form>

metabox_woofield.xml

<?xml version="1.0" encoding="utf-8"?>
<form posttype="post,page" col="normal" priority="high" boxlabel="Woo Fields">
    <fields>
        <fieldset>
            <field type="text" name="woobox" label="Wooten" />
        </fieldset>
    </fields>
</form>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...