在另一个插件中注册子类

时间:2013-05-25 作者:olly

我认为这应该相对容易,但不知何故,我不知道如何做到这一点。本质上,有一个预先存在的插件可以做到这一点:

add_action(\'widgets_init\', create_function(\'\', \'register_widget("Foo");\'));
if ( ! class_exists( \'Foo\' ) ) {
class Foo extends WP_Widget {
        /*constructs etc*/
}}
现在我想写另一个插件(本质上是扩展),它扩展了上述内容。我试着做如下的事情(也试着寻找一些示例/文档,但没有成功)

add_action(\'widgets_init\', create_function(\'\', \'register_widget("Bar");\'));
class Bar extends Foo {     
    function __construct() {
        /*do stuff*/
    }
}
但我得到的只是

<b>Fatal error</b>:  Class \'Foo\' not found in ...
所以我想这是一个让‘Bar’在Foo之后执行的问题,但我不知道如何执行。

如果有任何提示/想法/片段,甚至只是指向文档等的链接,都将不胜感激,因为我在这里的第一个障碍就失败了(

2 个回复
SO网友:s_ha_dum

我怀疑从另一个插件扩展一个类是否明智。你不知道下次其他插件更新时会发生什么。

然而,一般来说,您可以控制函数在钩子“队列”中运行的时间passing a third parameter-- a priority. 因此,传递足够高的优先级,您的函数应该在其他插件的函数之后运行。

add_action(
  \'widgets_init\', 
  create_function(\'\', \'register_widget("Bar");\')
  ,100
);
我不知道这对你是否有效。我从来没有试过。

您还应该知道,由于插件加载顺序的原因,您可能会遇到问题。

Changing Plugin Load Order
Does an activated plugin automatically mean its methods are available to other WP functions?

widget_init runs after plugins_loaded 所以在你的情况下,这可能不会是一个问题。

在进一步调查中。。。我得到的错误涉及构造函数所需的缺少变量。以下工作。

if ( ! class_exists( \'Foo\' ) ) {
  class Foo extends WP_Widget {
      /*constructs etc*/
      function __construct($id = \'twidg\', $descr = \'Test Widget\', $opts = array()) {
    $widget_opts = array();
    parent::__construct($id,$descr,$widget_opts);
      /*do stuff*/
      }
  }
}
function rw_cb() {
register_widget("Foo");
}
add_action(\'widgets_init\', \'rw_cb\');

class Bar extends Foo {     
    function __construct() {
      $widget_opts = array();
      parent::__construct(\'twidgextended\',\'Test Widget 2\',$widget_opts);
    }
}
function rw_cb_2() {
  register_widget("Bar");
}
add_action(\'widgets_init\', \'rw_cb_2\');
当每个组件都粘贴到一个虚拟插件文件中时,它就会工作。我唯一一次遇到涉及找不到类文件的致命错误是,如果我尝试使用Bar 类定义,在具有Foo 定义,这很有意义。

按如下方式包装该块可解决该问题,您可以按任何顺序激活该块。

if (class_exists(\'Foo\')) {
  class Bar extends Foo {     
      function __construct() {
    $widget_opts = array();
    parent::__construct(\'twidgextended\',\'Test Widget 2\',$widget_opts);
      }
  }

  function rw_cb_2() {
    register_widget("Bar");
  }
  add_action(\'widgets_init\', \'rw_cb_2\');
}

SO网友:olly

啊,但你确实给我指出了正确的方向(特别是你的第二个链接)。以下内容(至少在我的场景中是这样)似乎起到了作用。非常感谢。

  add_action( \'widgets_init\', \'extend_foo\' );
function extend_foo(){
    if (class_exists( \'Foo\' ) ) {
        class Bar extends Foo {
            function __construct() {
                parent::__construct();          
            }   
        }
    }
}
(虽然我不确定这是否是最优雅的做事方式……但如果它有效的话……)

结束

相关推荐

widgets in contacts only

我的顶部菜单中列出了几页。这些是:联系人、我的帐户和消息。我在admin的“Pages Sidebar”选项卡中添加了一个地图。但它似乎将地图添加到上面列出的所有3个页面中,但我只希望它出现在联系人页面上,而不是其他2个页面上,因为在其他2个页面中,我希望看到其他内容(可能是针对会员的广告)。我该怎么做?谢谢你的帮助。