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