将小部件保存为未定义的变量

时间:2013-02-22 作者:Jeremy

我正在为缓存提要开发一个小部件。小部件本身的工作方式完全符合我的要求,但我注意到,如果我删除小部件,然后在第一次保存时添加一个新的小部件(或者仅仅添加一个新的小部件),我会得到一个未定义的变量错误。这在管理外观->小部件部分。

Notice: Undefined index: cached_feed1450-3 in D:\\Sites\\test.dev\\wordpress\\wp-admin\\includes\\ajax-actions.php on line 1578

在我看来,这可能是WordPress的问题,因为这一行是:

if ( $form = $wp_registered_widget_controls[$widget_id] )
我想他们需要检查一下isset

我将我的小部件粘贴到这里,以确保这不是我的小部件的问题,而是确认这是WordPress错误。我真的希望是后者。。。

感谢您帮助确定此问题。

EDIT:

此错误仅在保存新小部件时发生。这似乎只发生在我的小部件上。编辑时,这不是问题。

我有一个加载插件的引导程序。我用这个add_action( \'widgets_init\', array(\'BootStrap1450\', \'addWidgets\') );

/**
 * Initialize the BootStrap
 */
public static function init() {
    require_once(A1450COM_LIBRARY_PATH.\'Functions1450.php\');

    // Initialize proper components (do not put into a hook!)
    if (is_admin()) {
        require_once(A1450COM_LIBRARY_PATH.\'BackEnd1450.php\');
    } else {
        require_once(A1450COM_LIBRARY_PATH.\'FrontEnd1450.php\');
        FrontEnd1450::init(); // Call manually
    }

    // Initiation of WP hook
    add_action( \'init\', array(\'BootStrap1450\', \'initWP\') );
    add_action( \'widgets_init\', array(\'BootStrap1450\', \'addWidgets\') );
} 
addWidgets是:

/**
 * Adds widgets
 */
public static function addWidgets() {
    include_once(A1450COM_WIDGETS_PATH.\'CachedFeed1450.php\');
}
小部件文件如下所示:

<?php
/**
 * An RSS feed widget with cache controls
 * @package WordPress
 * @subpackage Cached Feed Widget
 * @author Jeremy
 */
class CachedFeed1450 extends WP_Widget {
    const TEXT_DOMAIN = \'cachedfeed\';
    const COUNT_LIMIT = 20;

    /**
     * Register widget with WordPress.
     */
    public function __construct() {

        $widget_options = array(
            \'description\' => __( \'A cached feed widget that gives you custom settings per feed.\', self::TEXT_DOMAIN )
        );

        $control_options = array(
            \'width\' => 300
        );

        parent::__construct(
            \'cached_feed1450\', // Base ID
            __(\'Cached Feed\', self::TEXT_DOMAIN), // Name
            $widget_options,
            $control_options
        );
    }

    /**
     * Front-end display of widget.
     * *Currently only set for google news feed.
     * @todo Create a feed object to handle multiple feeds different data structures
     *
     * @see WP_Widget::widget()
     *
     * @param array $args     Widget arguments.
     * @param array $instance Saved values from database.
     */
    public function widget( $args, $instance ) {
        extract( $args );
        $title = apply_filters( \'widget_title\', $instance[\'title\'] );
        $feedURL = $instance[\'feed\'];
        $count = absint($instance[\'count\']);
        $showWidgetTitle = $instance[\'show_widget_title\'];
        $showTitle = $instance[\'show_title\'];
        $showContent = $instance[\'show_content\'];
        $showAuthor = $instance[\'show_author\'];
        $showDate = $instance[\'show_date\'];
        $enableCache = $instance[\'enable_cache\'];
        $cacheLifetime = $instance[\'cache_lifetime\'];

        echo $before_widget;
        if ( $showWidgetTitle && !empty( $title ) ) {
            echo $before_title . $title . $after_title;
        }

        $results = self::getFeed($widget_id, $feedURL, $count);
        if (!empty($results)) {
            echo \'<ul>\';
            // @todo Design a decent layout
            foreach($results as $feed) {
                echo \'<li>\';

                if ($showTitle)
                    echo $feed->title;

                if ($showContent)
                    echo $feed->description;

                if ($showDate)
                    echo $feed->pubDate;

//                echo $feed->link;

                echo \'</li>\';
            }
            echo \'</ul>\';
        }
        echo $after_widget;
        return;
    }

    /**
     * Sanitize widget form values as they are saved.
     *
     * @see WP_Widget::update()
     *
     * @param array $new_instance Values just sent to be saved.
     * @param array $old_instance Previously saved values from database.
     *
     * @return array Updated safe values to be saved.
     */
    public function update( $new_instance, $old_instance ) {

        $instance = $old_instance; // Sets defaults to old values
        $instance[\'title\'] = strip_tags($new_instance[\'title\']);
        $instance[\'feed\'] = strip_tags($new_instance[\'feed\']);
        $instance[\'count\'] =  absint($new_instance[\'count\']);
        $instance[\'show_title\'] = !empty($new_instance[\'show_title\']) ? \'1\' : \'0\';
        $instance[\'show_content\'] = !empty($new_instance[\'show_content\']) ? \'1\' : \'0\';
        $instance[\'show_author\'] = !empty($new_instance[\'show_author\']) ? \'1\' : \'0\';
        $instance[\'show_date\'] = !empty($new_instance[\'show_date\']) ? \'1\' : \'0\';
        $instance[\'enable_cache\'] = !empty($new_instance[\'enable_cache\']) ? \'1\' : \'0\';
        $instance[\'show_widget_title\'] = !empty($new_instance[\'show_widget_title\']) ? \'1\' : \'0\';
        $instance[\'cache_lifetime\'] =  absint($new_instance[\'cache_lifetime\']) * 60; // * 60 is to convert the seconds to minutes

        // Clean the array
        array_walk($instance, array(__CLASS__, \'trim\'));

        // Fail-safe
        if (empty($instance[\'feed\'])) {
            return false;
        }
        return $instance;
    }

    /**
     * Workaround to trim array on array_walk
     * @param $value
     */
    public static function trim(&$value) {
        $value = trim($value);
    }

    /**
     * Back-end widget form.
     *
     * @see WP_Widget::form()
     *
     * @param array $instance Previously saved values from database.
     */
    public function form( $instance ) {
        // Build data
        $title = !empty($instance[ \'title\' ]) ? $instance[ \'title\' ] : \'\';
        $feed = !empty($instance[ \'feed\' ]) ? $instance[ \'feed\' ] : \'\';
        $count = !empty($instance[ \'count\' ]) ? $instance[ \'count\' ] : 0;
        $cacheLifetime = !empty($instance[ \'cache_lifetime\' ]) ? ($instance[ \'cache_lifetime\' ] / 60) : 3600; // Default is 1 hour
        $showTitle = !empty($instance[ \'show_title\' ]) ? true : false;
        $showContent = !empty($instance[ \'show_content\' ]) ? true : false;
        $showAuthor = !empty($instance[ \'show_author\' ]) ? true : false;
        $showDate = !empty($instance[ \'show_date\' ]) ? true : false;
        $enableCache = !empty($instance[ \'enable_cache\' ]) ? true : false;
        $showWidgetTitle = !empty($instance[ \'show_widget_title\' ]) ? true : false;
        ?>
        <p>
            <label for="<?php echo $this->get_field_id( \'feed\' ); ?>"><?php _e( \'Feed URL:\', self::TEXT_DOMAIN ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( \'feed\' ); ?>" name="<?php echo $this->get_field_name( \'feed\' ); ?>" type="text" value="<?php echo esc_attr( $feed ); ?>" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title: (optional)\', self::TEXT_DOMAIN ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( \'title\' ); ?>" name="<?php echo $this->get_field_name( \'title\' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
        </p>
        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id( \'show_widget_title\' ); ?>" name="<?php echo $this->get_field_name( \'show_widget_title\' ); ?>" value="1" <?php checked($showWidgetTitle, 1) ?> />
            <label for="<?php echo $this->get_field_id( \'show_widget_title\' ); ?>"><?php _e( \'Display the widget title?\', self::TEXT_DOMAIN ); ?></label>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id( \'count\' ); ?>"><?php _e( \'How many items would you like to display?:\', self::TEXT_DOMAIN ); ?></label>
            <select id="<?php echo $this->get_field_id( \'count\' ); ?>" name="<?php echo $this->get_field_name( \'count\' ); ?>" >
                <?php
                for($i=1; $i <= self::COUNT_LIMIT; $i++) {
                    echo \'<option value="\'.$i.\'" \'.selected($i, $count, false).\'>\'.$i.\'</option>\';
                }
                ?>
            </select>
        </p>

        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id( \'show_title\' ); ?>" name="<?php echo $this->get_field_name( \'show_title\' ); ?>" value="1" <?php checked($showTitle, 1) ?> />
            <label for="<?php echo $this->get_field_id( \'show_title\' ); ?>"><?php _e( \'Display the item title?\', self::TEXT_DOMAIN ); ?></label>
        </p>
        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id( \'show_content\' ); ?>" name="<?php echo $this->get_field_name( \'show_content\' ); ?>" value="1" <?php checked($showContent, 1) ?> />
            <label for="<?php echo $this->get_field_id( \'show_content\' ); ?>"><?php _e( \'Display item content?\', self::TEXT_DOMAIN ); ?></label>
        </p>
        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id( \'show_author\' ); ?>" name="<?php echo $this->get_field_name( \'show_author\' ); ?>" value="1" <?php checked($showAuthor, 1) ?> />
            <label for="<?php echo $this->get_field_id( \'show_author\' ); ?>"><?php _e( \'Display item author if available?\', self::TEXT_DOMAIN ); ?></label>
        </p>
        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id( \'show_date\' ); ?>" name="<?php echo $this->get_field_name( \'show_date\' ); ?>" value="1" <?php checked($showDate, 1) ?> />
            <label for="<?php echo $this->get_field_id( \'show_date\' ); ?>"><?php _e( \'Display item date?\', self::TEXT_DOMAIN ); ?></label>
        </p>
        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id( \'enable_cache\' ); ?>" name="<?php echo $this->get_field_name( \'enable_cache\' ); ?>" value="1" <?php checked($enableCache, 1) ?> class="cachedform-cache-toggle" />
            <label for="<?php echo $this->get_field_id( \'enable_cache\' ); ?>"><?php _e( \'Enable Cache?\', self::TEXT_DOMAIN ); ?></label>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id( \'cache_lifetime\' ); ?>"><?php _e( \'Cache lifetime:\', self::TEXT_DOMAIN ); ?></label>
            <input id="<?php echo $this->get_field_id( \'cache_lifetime\' ); ?>" name="<?php echo $this->get_field_name( \'cache_lifetime\' ); ?>" type="text" value="<?php echo esc_attr( $cacheLifetime ); ?>" />
            <span class="description"><?php _e(\'In minutes\', self::TEXT_DOMAIN); ?></span>
        </p>

        <?php
    }

    /**
     * Get the feed data
     * @param string $id
     * @param string $feed_url
     * @param int $limit
     * @param bool $sendRaw
     * @param null $cacheTime
     * @return array|SimpleXmlElement
     */
    private function getFeed($id, $feed_url, $limit = 0, $sendRaw = false, $cacheTime = 0) {
        if (empty($cacheTime)) {
            $cacheTime = 3600; // 1 hour cache by default
        }

        // Define cache file
        $cache_file = get_theme_root() . DIRECTORY_SEPARATOR . get_template() . DIRECTORY_SEPARATOR . \'cached-feed-\'.$id.\'.xml\';

        // Check for cache
        $tmpFileModifiedDate = @filemtime($cache_file);
        $timedif = time() - $tmpFileModifiedDate;
        if (file_exists($cache_file) && $timedif < $cacheTime) {
            $string = file_get_contents($cache_file);
        } else {
            $string = @file_get_contents($feed_url);
            // Check if an error and attempt a quick fix
            if ($string === false) {
                $string = @file_get_contents(urlencode($feed_url));
            }
            if ($string === false) {
                trigger_error(__(\'Cached Feed Error - Fetch feed content\', self::TEXT_DOMAIN));
                return false;
            }
            if ($string) {
                $f = fopen($cache_file, \'w\');
                if ($f === false) {
                    trigger_error(__(\'Cached Feed Error - Failed to write to cache file\', self::TEXT_DOMAIN));
                    return false; // Failed to write to file
                }
                if ($f) {
                    fwrite($f, $string, strlen($string));
                    fclose($f);
                }
            }
        }

        // Return empty array if no data
        if (!$string) {
            return array();
        }

        // Get content from XML
        $x = new SimpleXmlElement($string);
        if ($sendRaw) {
            return $x;
        }
        $entries = array();
        $i = 0;
        foreach ($x->channel->item as $entry) {
            if ($limit > 0 && $i >= $limit) {
                continue;
            }
            $entries[] = $entry;
            $i++;
        }
//            die(\'<pre>\'.print_r($entries, true).\'</pre>\');
        return $entries;
    }
}
register_widget( \'CachedFeed\' );

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

我愿意这样做,因为您尚未初始化widgets池,所以无法复制它。

因此,您可以在主类或插件文件中添加以下内容:

对于类:

add_action ( \'widgets_init\', array (
    &$this,
    \'my_widgets\' 
) );
用于。php文件

add_action ( \'widgets_init\', \'my_widgets\');
然后创建函数

public function my_widgets(){
    register_widget ( \'CachedFeed\' );
}
当然,别忘了包括您的widget类。

结束

相关推荐

Buggy wp_nav_menu?

我希望有人能给我一些线索。我在一个网站上工作,它有一个三级菜单,加载调用三个不同的wp菜单(比如“主菜单”、“项目子菜单”、“二级项目子菜单”,其中“项目子菜单”是类别,“二级项目子菜单”是“项目子菜单”中一个类别的子类别)。但在wp添加当前菜单类指向错误的菜单项。这是指,在访问其子菜单时,它没有激活相应的“项目”项菜单,而是激活了错误的菜单项“新闻”,将类当前菜单项错误地添加到其中。我已经检查了管理面板上的wp菜单好几次,也删除并重新构建了它们,但似乎没有什么可以解决这个问题。以下是指向临时站点的链接: