在另一个筛选器中使用一个筛选器的变量

时间:2015-12-29 作者:Ivan Topić

我有一个用于Gallery快捷码的过滤器,在那里我获取帖子中使用的图像的ID,并使用ID获取它们的元数据。现在我需要一种使用$copyright 过滤器中用于抓取的变量post_content 所以我可以回显该变量的内容。

有没有一种方法可以在不同的过滤器中重用变量,或者有没有更好的方法来实现我想要实现的目标?

function wpse_get_full_size_gallery_images( $gallery, $post, $galleries ) { 
    $ids        = explode( \',\', $galleries[\'include\'] );
    $copyright  = array();

    foreach( $ids as $id )
        $copyright[] = get_post_meta( $id, \'wiki_copyright\', true );

    return $gallery;
}
add_filter( \'shortcode_atts_gallery\', \'wpse_get_full_size_gallery_images\', 10, 3 );

function my_the_content_filter( $content ) {
    //pass here the copyright array and append it at the end
    $content .= $copyright;

    return $content;
}
add_filter( \'the_content\', \'my_the_content_filter\', 20 );

2 个回复
最合适的回答,由SO网友:jgraup 整理而成

对于全局变量来说,这可能是一个很好的例子。只需确保在添加到数组之前以及在何时尝试输出内容之前将其设置为数组。在添加到内容之前,将数组转换为字符串。

此外,在添加到数组之前,请确保元数据存在,这样就不会添加空的版权值。

GLOBAL VERSION

function wpse_get_full_size_gallery_images($gallery, $post, $galleries) {

    // reference the global variable
    global $copyright;

    // make sure it\'s set
    if( ! isset($copyright)) $copyright = array();

    // grab the IDS
    $ids = explode(\',\', $galleries[ \'include\' ]);

    foreach($ids as $id) {
       // get the possible meta
       $meta = get_post_meta($id, \'wiki_copyright\', true);

       // add them to the copyright array   
       // make sure to only add if it exists
       if( !empty($meta)) $copyright[] = $meta;
    }

    return $gallery;
}

add_filter(\'shortcode_atts_gallery\', \'wpse_get_full_size_gallery_images\', 10, 3);

function my_the_content_filter($content) {

    // reference the global variable
    global $copyright;

    // add copyright array converted to string if we have content
    if( ! empty($copyright)) $content .= implode(\',\', $copyright);

    return $content;
}

add_filter(\'the_content\', \'my_the_content_filter\', 20);

STATIC VERSION

如果您不喜欢使用globals,无论出于何种原因,请考虑static 作为替补variable scope 在PHP中。

变量作用域的另一个重要特性是静态变量。静态变量仅存在于局部函数作用域中,但当程序执行离开此作用域时,它不会丢失其值。

由于持久变量绑定到单个函数作用域,我们需要在任何循环之外创建函数,然后重用它来添加值以及检索这些值。

如果传递新值;add it. 如果未传递值;get all values.

if( ! function_exists(\'copyrights\')) {
    function copyrights($value = \'\') {

        // only this function has access to $_copyrights
        static $_copyrights;

        // expressions can\'t be assigned as defaults
        // but we still want to initialize the value
        if( ! isset($_copyrights)) {
            $_copyrights = array();
        }

        // if we\'re passing new values then add them
        if( ! empty($value)) {
            $_copyrights[] = $value;

            return true; // success
        }
        else {
            // otherwise return uniques
            $unique_list = array_unique($_copyrights);

            // convert to string before they leave
            return implode(", ", $unique_list);
        }
    }
}

add_filter(\'shortcode_atts_gallery\', function($gallery, $post, $galleries) {
    $ids = explode(\',\', $galleries[ \'include\' ]);
    foreach($ids as $id) 
        if( ! empty($meta = get_post_meta($id, \'wiki_copyright\', true)))
            copyrights($meta);

    return $gallery;
}, 10, 3);

add_filter(\'the_content\', function($content) {
    return $content . copyrights();
}, 20);
测试

copyrights ( 123 );
copyrights ( 223 );
copyrights ( 333 );
copyrights ( 123 );
copyrights ( 111 );
copyrights ( 111 );
copyrights ( 111 );

echo ( copyrights() ); // 123, 223, 333, 111

SINGLETON VERSION

实际上我从来没有用过globals,因为Singleton Pattern 是我的首选方法。

其思想是将所有方法放在类的实例上,但只能通过静态方法访问它。通过这样做,该类确保只创建一个实例。

if( ! class_exists(\'Copyrights\')) {
    class Copyrights {

        private        $copyrights;
        private static $instance;

        // PRIVATE CONSTRUCTOR

        private function __construct() {

            // initialize the array
            $this->copyrights = array();
        }

        // STATIC SINGLETON

        public static function getInstance() {
            if(is_null(self::$instance)) {
                self::$instance = new self();
            }

            return self::$instance;
        }

        // PUBLIC METHODS

        public function toString() {
            $unique_list = array_unique($this->copyrights);

            return implode(", ", $unique_list);
        }

        public function add($value = \'\') {
            if( ! empty($value)) {
                $this->copyrights[] = $value;
            }
        }
    }
}

add_filter(\'shortcode_atts_gallery\', function($gallery, $post, $galleries) {

    $ids = explode(\',\', $galleries[ \'include\' ]);

    foreach($ids as $id)
        if( ! empty($meta = get_post_meta($id, \'wiki_copyright\', true))) 
            Copyrights::getInstance()->add($meta);

    return $gallery;
}, 10, 3);

add_filter(\'the_content\', function($content) {
    return $content . Copyrights::getInstance()->toString();
}, 20);
测试

Copyrights::getInstance()->add ( 123 );
Copyrights::getInstance()->add ( 223 );
Copyrights::getInstance()->add ( 333 );
Copyrights::getInstance()->add ( 123 );
Copyrights::getInstance()->add ( 111 );
Copyrights::getInstance()->add ( 111 );
Copyrights::getInstance()->add ( 111 );

echo Copyrights::getInstance()->toString(); // 123, 223, 333, 111

SINGLETON PER POST VERSION

也许是在global vs。the sky is falling 上述解决方案(以及提议的备选方案)是否只针对一个职位。如果你想在一个循环中添加你的版权,那你就完了,因为所有的帖子都会被添加到一个数组中。

对于singleton类,添加每个ID的singleton很简单,可以说是最好的选择。

if( ! class_exists(\'Copyrights\')) {
    class Copyrights {

        private static $instance;
        private        $copyrights;
        public         $post_id;

        // PRIVATE CONSTRUCTOR

        private function __construct($post_id) {

            // save the id
            $this->post_id = $post_id;

            // initialize the array
            $this->copyrights = array();
        }

        // SINGLETON

        public static function getInstance($post_id = \'NO ID\') {
            if(is_null(self::$instance)) self::$instance = array();
            if(is_null(self::$instance[ $post_id ])) {
                self::$instance[ $post_id ] = new self($post_id);
            }

            return self::$instance[ $post_id ];
        }

        // PUBLIC METHODS

        public function toString() {
            $unique_list = array_unique($this->copyrights);

            return implode(", ", $unique_list);
        }

        public function add($value = \'\') {
            if( ! empty($value)) {
                $this->copyrights[] = $value;
            }
        }
    }
}

add_filter(\'shortcode_atts_gallery\', function($gallery, $post, $galleries) {

    $ids = explode(\',\', $galleries[ \'include\' ]);

    foreach($ids as $id)
        if( ! empty($meta = get_post_meta($id, \'wiki_copyright\', true)))
            Copyrights::getInstance($post->ID)->add($meta);

    return $gallery;
}, 10, 3);

add_filter(\'the_content\', function($content) {
    global $post;
    return $content . Copyrights::getInstance($post->ID)->toString();
}, 20);
测试

如您所见,使用ID 钥匙使事情保持灵活。

Copyrights::getInstance( 1 )->add ( 123 );
Copyrights::getInstance( 1 )->add ( 223 );
Copyrights::getInstance( 2 )->add ( 333 );
Copyrights::getInstance( 2 )->add ( 123 );
Copyrights::getInstance( 2 )->add ( 111 );
Copyrights::getInstance( 2 )->add ( 111 );
Copyrights::getInstance( 2 )->add ( 111 );
Copyrights::getInstance()->add ( 111 );
Copyrights::getInstance()->add ( 444 );
Copyrights::getInstance()->add ( 555 );
Copyrights::getInstance()->add ( 888 );

echo Copyrights::getInstance( 1 )->toString(); // 123, 223
echo Copyrights::getInstance( 2 )->toString(); // 333, 123, 111
echo Copyrights::getInstance()->toString(); // 111, 444, 555, 888
当有人认为在database 因为他们不懂PHP,所以现在是反思问题的好时机。

<小时>

UPDATE

solved 使用global 变量,但重新思考问题您可以通过使用the content 仅使用过滤器挂钩—使问题保持本地化。

在这种情况下,当the_content 运行,我们检查all galleries 并仅输出relevant data.

不需要全局、静态、单例、选项或额外函数。

最重要的是,这将在一个循环中工作,不会出现复杂情况。

add_filter(\'the_content\', \'add_copyright_to_content\');

function add_copyright_to_content($content) {

    //  pull all galleries from the post
    $galleries = get_post_galleries(get_post(), false);

    //  no gallery? then let\'s get out of here
    if(empty($galleries)) return $content;

    $all = \'\';

    //  gather all ids
    foreach($galleries as $gallery) $all .= $gallery[ \'ids\' ] . \',\';

    //  convert them to an array with unique ids
    $all = array_unique(array_filter(explode(\',\', $all)));

    //  replace id for copyright info on the image meta
    foreach($all as $key => $id) $all [ $key ] = get_post_meta($id, \'wiki_copyright\', true);

    //  return non-empty values to the end of the content
    return $content . implode(\', \', array_filter($all));
}

SO网友:Pieter Goosen

。。。也许有更好的方法来实现我的目标?

总是有额外的选择需要考虑。全球化变量当然不是其中之一,您应该避免这样做。全球化是解决任何问题的一种简单方法,但相信我,如果某个问题破坏了全局设置,您将花费数天时间调试一个不会给您带来任何调试错误的问题。

WordPress总是把globals搞得一团糟。只需浏览本网站上的问题和答案,并检查有多少人在使用globals$wp_query, $posts$post 作为局部变量。

我个人使用$copyright 作为保存日期信息的变量。如果我们全球化$copyright 在你的例子中,如果使用一个id字符串,要么我的变量将破坏全局变量,要么全局变量将破坏我的变量。最糟糕的是,我不会得到任何调试错误,也不知道我的值在哪里更改。所以永远不要全球化变量,嗯,这是一个很糟糕的做法,因为还有很多其他的选择

想到的一个快速选项是使用Options API存储数据。这很容易,并且不需要大量开销,因为选项是缓存的,并且可以保存以供使用。

让我们尝试以下操作:(NOTE: 所有代码都未经测试,因此请确保首先在本地安装上进行测试。该代码还需要PHP5。4+)

add_filter( \'shortcode_atts_gallery\', function ( $gallery, $post, $galleries ) 
{ 
    // Get all the ids
    $ids = $galleries[\'include\'];
    // Instead of overloading the shortcode, lets just save the id\'s for later use
    if ( !$ids ) // Always make sure we have values
        return $gallery;

    // Add our ids in an option
    $option = get_option( \'custom_copyright_ids\' );
    if (    false !== $option // Make sure that the option does not yet exist
         || $option !== $ids // We only want the update if $id\'s change
    ) {
        // Lets update or add our option
        update_option( \'custom_copyright_ids\', $ids );
    }

    return $gallery;
}, 10, 3 );
我们现在可以创建一个“全局”功能,可以随身携带和使用(safely) 我们想在哪里使用它。(下面的函数是静态的,您可以将其设置为动态的)

function get_global_copyright_ids()
{
    $output = \'\';

    // Get our ids
    $ids = get_option( \'custom_copyright_ids\' );

    // Make sure we have a value for $option, either return an empty string
    if ( false === $ids )
        return $output;

    // We have ids, lets continue
    // We expect $ids to be an array, so lets turn the string into an array
    $ids = explode( \',\', trim( $ids ) );

    foreach ( $ids as $id ) {
        // Get our post meta
        $meta = get_post_meta( $id, \'wiki_copyright\', true );
        if ( !$meta )
            continue;
        // We have meta, add it to our $output string. Add any markup here
        $output .= $meta
    } // endforeach $ids

    // Return our string of post meta
    return $output;
}
我们现在可以使用get_global_copyright_ids() 我们想去的任何地方

add_filter( \'the_content\', function ( $content )
{
    // Get our content to add from our "global" function
    $extra = \'\';
    if ( function_exists( \'get_global_copyright_ids\' ) ) {
        $extra = get_global_copyright_ids();
    }

    if ( !$extra )
        return $content;

    // Append $extra to $content
    return $content . $extra;
}):
这里有一个更好、更安全的系统,非常容易调试,而且是最好的YOU KEPT THE GLOBAL SCOPE CLEAN!!!

相关推荐

已修改Backbone JS中的wp.media.view.Settings.Gallery,但无法编辑

我已经添加到普通的WordPress gallery弹出窗口(在WordPress编辑器中单击“添加媒体”时),以便选择我的自定义库类型(与WordPress gallery主快捷码交互/使用)。我可以选择我的自定义图库类型(我有两种)或“本机”(这是普通的WordPress图库)。目前,在创建库时,一切都按预期工作(如果选择了非本机库类型,则除了我的非本机库使用的几个其他选项外,gallerytype会添加到发送给编辑器的短代码中)。然而,问题是,当想要编辑我已经创建的图库时,我用来选择图库类型(本机或