限制个别类别组合

时间:2013-12-26 作者:Ali

在为一篇文章分配多个类别时,我需要根据已经分配给特定文章的其他类别来限制文章的类别选择。

例如,假设我们有类别A、B和C。
对于任何帖子,我们希望限制同时有类别B和C。因此帖子可能有以下分配:

A、B、CNo post 应该有Band C

我怎样才能做到这一点?

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

好的,我有几分钟的空闲时间,所以我写了一个小插件

以下内容进入一个新的插件文件tf-restrict-categories/tf-restrict-categories.php:

导言

<?php
/**
 * Plugin Name: Restrict Categories
 * Description: Individually restrict category combinations.
 * License: MIT
 * License URI: http://opensource.org/licenses/MIT
 * Text Domain: tf-restrict-categories
 * Domain Path: /languages
 */


if (! class_exists(\'TFRestrictCategories\')) :


/**
 * Main (and only) class.
 */
class TFRestrictCategories {

    /**
     * Plugin instance.
     *
     * @type    object
     */
    protected static $instance = null;


    /**
     * basename() of global $pagenow.
     *
     * @type    string
     */
    protected static $page_base;


    /**
     * Plugin textdomain.
     *
     * @type    string
     */
    protected $textdomain = \'tf-restrict-categories\';


    /**
     * Plugin option name.
     *
     * @type    string
     */
    protected $option_name = \'tf_restrict_categories\';


    /**
     * Plugin settings page name.
     *
     * @type    string
     */
    protected $settings_page_name = \'tf-restrict-categories\';


    /**
     * Plugin settings page.
     *
     * @type    string
     */
    protected $settings_page;
基础知识
    /**
     * Constructor. Registers activation routine.
     *
     * @hook    wp_loaded
     * @return  void
     */
    public function __construct() {
        register_activation_hook(__FILE__, array(__CLASS__, \'activation\'));
    } // function __construct


    /**
     * Get plugin instance.
     *
     * @hook    wp_loaded
     * @return  object TFRestrictCategories
     */
    public static function get_instance() {
        if (null === self::$instance)
            self::$instance = new self;

        return self::$instance;
    } // function get_instance


    /**
     * Registers uninstall routine.
     *
     * @hook    activation
     * @return  void
     */
    public static function activation() {
        register_uninstall_hook(__FILE__, array(__CLASS__, \'uninstall\'));
    } // function activation


    /**
     * Checks if the plugin has to be loaded.
     *
     * @return  boolean
     */
    public static function has_to_be_loaded() {
        global $pagenow;

        if (empty($pagenow))
            return false;

        self::$page_base = basename($pagenow, \'.php\');

        // Load plugin for all admin pages
        return is_admin();
    } // function has_to_be_loaded


    /**
     * Registers plugin actions and filters.
     *
     * @hook    wp_loaded
     * @return  void
     */
    public function init() {
        add_action(\'admin_menu\', array($this, \'add_settings_page\'));
        add_action(\'wp_insert_post\', array($this, \'restrict_categories\'));

        $pages = array(
            \'edit\',
            \'post\',
            \'post-new\',
        );
        if (in_array(self::$page_base, $pages))
            add_action(\'admin_print_scripts-posts_page_tf-restrict-categories\', array($this, \'enqueue_scripts\'));

        if (\'plugins\' === self::$page_base)
            add_filter(\'plugin_action_links_\'.plugin_basename(__FILE__), array($this, \'add_settings_link\'));

        if (\'options\' === self::$page_base)
            add_action(\'admin_init\', array($this, \'register_setting\'));
    } // function init


    /**
     * Wrapper for get_option().
     *
     * @param   string $key Option name.
     * @param   mixed $default Return value for missing key.
     * @return  mixed|$default Option value.
     */
    protected function get_option($key = null, $default = false) {
        static $option = null;
        if (null === $option) {
            $option = get_option($this->option_name, false);
            if (false === $option)
                $option = array(
                );
        }

        if (null === $key)
            return $option;

        if (! isset($option[$key]))
            return $default;

        return $option[$key];
    } // function get_option
这就是行动的所在
    /**
     * Adds custom settings page to posts settings.
     *
     * @hook    admin_menu
     * @return  void
     */
    public function add_settings_page() {
        $this->settings_page = add_posts_page(\'Restrict Categories\', \'Restrict Categories\', \'manage_categories\', $this->settings_page_name, array($this, \'print_settings_page\'));
    } // function add_settings_page


    /**
     * Prints settings page.
     *
     * @see     add_settings_page()
     * @return  void
     */
    public function print_settings_page() {
        $this->load_textdomain();
        ?>
        <div class="wrap">
            <h2>Restrict Categories</h2>
            <div class="tool-box">
                <form method="post" action="<?php echo admin_url(\'options.php\'); ?>">
                    <?php
                    settings_fields($this->option_name);
                    $args = array(
                        \'hide_empty\' => 0,
                    );
                    if (count($categories = get_categories($args))) {
                        $option = $this->get_option($this->option_name, array());
                        ?>
                        <table id="tf-restrict-categories" class="widefat">
                            <thead>
                                <tr>
                                    <th></th>
                                    <?php
                                    foreach ($categories as $category) {
                                        ?>
                                        <th><?php echo $category->name; ?></th>
                                        <?php
                                    }
                                    ?>
                                </tr>
                            </thead>
                            <tbody>
                                <?php
                                $alternate = true;
                                foreach ($categories as $category) {
                                    $class = ($alternate) ? \' class="alternate"\' : \'\';
                                    $alternate = ! $alternate;
                                    ?>
                                    <tr<?php echo $class; ?>>
                                        <td id=""><?php echo $category->name; ?></td>
                                        <?php
                                        foreach ($categories as $second_category) {
                                            ?>
                                            <td id="restrict-category-<?php echo $category->term_id; ?>-<?php echo $second_category->term_id; ?>">
                                                <?php
                                                if ($category->term_id !== $second_category->term_id) {
                                                    $checked = (
                                                        isset($option[$category->term_id]) && isset($option[$category->term_id][$second_category->term_id])
                                                        || isset($option[$second_category->term_id]) && isset($option[$second_category->term_id][$category->term_id])
                                                    );
                                                    $checked = ($checked) ? \' checked="checked"\' : \'\';
                                                    $disabled = (isset($option[$second_category->term_id]) && isset($option[$second_category->term_id][$category->term_id]));
                                                    $disabled = ($disabled) ? \' disabled="disabled"\' : \'\';
                                                    ?>
                                                    <input type="checkbox" id="<?php echo $category->term_id; ?>-<?php echo $second_category->term_id; ?>" name="<?php echo $this->option_name; ?>[<?php echo $category->term_id; ?>][<?php echo $second_category->term_id; ?>]" value="1"<?php echo $checked.$disabled; ?> />
                                                    <?php
                                                }
                                                ?>
                                            </td>
                                            <?php
                                        }
                                        ?>
                                    </tr>
                                    <?php
                                }
                                ?>
                            </tbody>
                        </table>
                        <div class="submit">
                            <input type="submit" class="button-primary" value="<?php _e(\'Save Changes\'); ?>" />
                        </div>
                        <?php
                    } else
                        _e("No categories found.", \'tf-restrict-categories\');
                    ?>
                </form>
            </div>
        </div>
        <?php
        $this->unload_textdomain();
    } // function print_settings_page


    /**
     * Restricts categories according to stored plugin settings.
     *
     * @hook    wp_insert_post
     * @param   int $id Post ID.
     * @return  void
     */
    public function restrict_categories($id) {
        $args = array(
            \'fields\' => \'ids\',
            \'orderby\' => \'term_id\'
        );
        if (
            count($option = $this->get_option($this->option_name, array()))
            && count($categories = wp_get_object_terms($id, \'category\', $args))
        ) {
            foreach ($option as $master_key => $restrict)
                foreach($restrict as $restrict_key => $v)
                    if (in_array($master_key, $categories))
                        foreach($categories as $key => $category)
                            if ($category === $restrict_key)
                                unset($categories[$key]);

            wp_set_object_terms($id, $categories, \'category\');
        }
    } // function restrict_categories


    /**
     * Adds a link to the settings to the plugin list.
     *
     * @hook    plugin_action_links_{$file}
     * @param   array $links Already existing links.
     * @return  array
     */
    public function add_settings_link($links) {
        $settings_link = array(
            \'<a href="\'.admin_url(\'edit.php?page=\'.$this->settings_page_name).\'">\'.__("Settings").\'</a>\'
        );

        return array_merge($settings_link, $links);
    } // function add_settings_link


    /**
     * Enqueues necessary script files.
     *
     * @hook    admin_print_scripts-posts_page_tf-restrict-categories
     * @return  void
     */
    public function enqueue_scripts() {
        $this->load_textdomain();
        wp_enqueue_script(\'tf-restrict-categories-js\', plugin_dir_url(__FILE__).\'js/tf-restrict-categories.js\', array(\'jquery\'), filemtime(plugin_dir_path(__FILE__).\'js/tf-restrict-categories.js\'), true);
        $this->unload_textdomain();
    } // function enqueue_scripts


    /**
     * Registers setting for custom options page.
     *
     * @hook    admin_init
     * @return  void
     */
    public function register_setting() {
        register_setting($this->option_name, $this->option_name, array($this, \'save_setting\'));
    } // function register_setting


    /**
     * Prepares option values before they are saved.
     *
     * @param   array $data Original option values.
     * @return  array Sanitized option values.
     */
    public function save_setting($data) {
        $sanitized_data = $this->get_option();
        if (isset($data) && ! empty($data))
            $sanitized_data[$this->option_name] = $data;
        else
            unset($sanitized_data[$this->option_name]);

        return $sanitized_data;
    } // function save_setting
结束
    /**
     * Loads plugin textdomain.
     *
     * @return  boolean
     */
    protected function load_textdomain() {
        return load_plugin_textdomain($this->textdomain, false, plugin_basename(dirname(__FILE__)).\'/languages\');
    } // function load_textdomain


    /**
     * Remove translations from memory.
     *
     * @return  void
     */
    protected function unload_textdomain() {
        unset($GLOBALS[\'l10n\'][$this->textdomain]);
    } // function unload_textdomain


    /**
     * Deletes plugin data on uninstall.
     *
     * @hook    uninstall
     * @return  void
     */
    public static function uninstall() {
        delete_option(self::get_instance()->option_name);
    } // function uninstall

} // class TFRestrictCategories


if (TFRestrictCategories::has_to_be_loaded())
    add_action(\'wp_loaded\', array(TFRestrictCategories::get_instance(), \'init\'));


endif; // if (! class_exists(\'TFRestrictCategories\'))
以下内容进入一个新的插件文件tf-restrict-categories/js/tf-restrict-categories.js:

JavaScript

jQuery(function($) {

    $(\'#tf-restrict-categories [type="checkbox"]\').click(function() {
        var $this = $(this);
        if (! $this.is(\':disabled\')) {
            var n = this.id.split(\'-\');
            $(\'#tf-restrict-categories [type="checkbox"][name$="\\\\[\'+n[1]+\'\\\\]\\\\[\'+n[0]+\'\\\\]"]\')
                .attr(\'disabled\', $this.is(\':checked\'))
                .attr(\'checked\', $this.is(\':checked\'));
        }
    });

});
复制(&H);将代码粘贴到两个文件中,上载到plugins 文件夹中,激活插件并找到新的设置页面。

快乐限制。:)

好吧,好吧,解释一下。。。

该插件的工作原理如下。在设置页面上,我们定义了一些类别组合。比方说,我们希望有规则,如果存在“Cat A”,则不允许使用“Cat C”。这可以通过选中row Cat Acolumn Cat C. 这意味着:行类别是主类别,列类别将受到限制
当然,您可以有多个与A类(以及多个其他类别)的组合。

保存/更新帖子时(或者,更准确地说:当having saved/updated 根据存储的插件设置检查类别,并进行调整。

还有别的吗?

SO网友:Bendoh

似乎没有任何钩子可以用来改变wp_create_postwp_update_post 被称为。

但是,您始终可以在wp_insert_post 保存或更新帖子后更新类别的操作:

function update_post_categories( $postID, $post, $is_update ) {
   $categories = wp_get_object_terms( $postID, \'category\' );

   // Figure out which categories are invalid,
   // Put only the valid categories in $new_categories...

   wp_set_object_terms( $postID, $new_categories, \'category\', false );
}
add_action( \'wp_insert_post\', \'update_post_categories\', 10, 3 );
上面的代码片段所做的是获取将分配给帖子的类别,只留下应该分配给中的类别$new_categories, 然后写了那篇文章的分类。

正如您所看到的,我省略了逻辑来确定哪些类别是有效的,因为您没有描述该逻辑是什么。

结束

相关推荐

How can I find plugins' slug?

我想知道如何才能找到插件的slug(slug=WordPress用来更新插件和确定哪些插件当前处于活动状态的内部名称)?它通常是插件的文件夹名,但如果插件没有文件夹,则是其文件名(如hello.php)。是否有其他例外情况?大小写字符重要吗</插件的slug是否可以与其文件夹名不同?如果有一个叫做hello的插件呢。php和另一个/您好。php/您好。php