dtnpf35197 2018-11-04 08:37
浏览 38
已采纳

无法在嵌入式类中获取WordPress钩子

I am trying to build some nice metabox functionality with some oop.

I have my main DazSEO class, which inside contains a Metabox Class.

When I set WordPress save data hooks up inside the metabox class, they won't fire, but when I set them up from the root class, they will.

Is using hooks inside embedded classes incompatible with the WordPress hook system?

Any help would be appreciated here as I have spent a lot of time trying to figure out what is the issue here, I guess it is some object scope issue for the wp engine, but I am not convinced. class DazSEO { public static $plugins = array();

public $metaBox;    

public function __construct() {

    add_action('admin_init', array($this, 'adminInit') );
    add_action('init', array($this, 'init'));
}

public function adminInit() {
    $this->setupMetaBox();
}    

public function setupMetaBox() {   
    if( $pagenow === 'term.php' ) { // returns true

        if( isset($_GET['taxonomy']) ) { 
            $term = get_term( $_GET['tag_ID'], $_GET['taxonomy'], OBJECT );

            require_once('admin\metabox\TermMetaBox.php'); 
            $this->metaBox = new TermMetabox( $_GET['taxonomy'] ); // confirmed this does fire

            DazSEO::$mode = 'term';
            DazSEO::$wpID = $_GET['tag_ID'];
            DazSEO::$typeName = $_GET['taxonomy'];
        } 
    }
}    
}

class TermMetabox extends MetaBoxBase {
  private $_taxonomy;

  public function __construct(string $taxonomy) {        
    if( strlen($taxonomy) === 0 ) { echo 'no taxonomy passed'; exit(); }

    $this->_taxonomy = $taxonomy;

    add_action(  $this->_taxonomy . '_edit_form', array($this, 'buildMetaBox') );       

    add_action('edit_terms', array($this, 'onTermSave')); // SETUP TERM SAVE     
}


  public function loadHooks() {

}


// NOT BEING CALLED
public function onTermSave(int $term_id) {

    echo '<pre>' . print_r($_REQUEST, 1) . '</pre>'; exit(); 

    if( $this->onSaveChecks($term_id) ) {
        return;
    }

    foreach(DazSEO::$plugins as $plugin) {
        $plugin->onTermSave($term_id, $_REQUEST);
    }
}
}

The TermMetabox:: onTermSave never gets called

If this is called from the root class (DazSEO), and I move the save method in there too it works...

add_action('edit_terms', array($this, 'onTermSave'));

But it's messy design like that.

This plugin is initialized like this...

$dazSEO = new DazSEO();
$wpCleanHeader = new RemoveWPHeaderJunk();
$dazSEO->loadPlugin($wpCleanHeader);
  • 写回答

1条回答 默认 最新

  • dtbrd80422 2018-11-05 03:33
    关注

    If the $pagenow is a global WordPress admin variable, then these may answer the question: (the PHP files mentioned below are saved in wp-admin)

    1. When you visit the term.php (i.e. the taxonomy term edit) page, $_GET['taxonomy'] and $_GET['tag_ID'] are set/available by default (and required by WordPress for determining which term you're editing). Therefore isset($_GET['taxonomy']) evaluates to true.

    2. However, in your TermMetabox class constructor, you are hooking TermMetabox::onTermSave() to the edit_terms action which is (again, by default) not fired on the term.php page.

    3. The taxonomy edit form on term.php is coming from edit-tag-form.php, where the opening <form> tag looks like:

      <form name="edittag" id="edittag" method="post" action="edit-tags.php" ...>
      

      and it contains the following hidden input fields:

      <input type="hidden" name="action" value="editedtag"/> <- the action
      <input type="hidden" name="tag_ID" ...>
      <input type="hidden" name="taxonomy" ...>
      

      So as you can see, the form is to be submitted using the POST method to edit-tags.php with the action editedtag.

    4. On edit-tags.php, if the action is editedtag, wp_update_term() would be called and you'd eventually brought back to term.php. And if you don't know yet, wp_update_term() fires the edit_terms action.

    So with your existing code, you can fix it like so, where I'm checking if $pagenow is edit-tags.php, and that I use $_POST instead of $_GET:

    public function setupMetaBox() {
        // global $pagenow; // I used this when testing.
        if( $pagenow === 'edit-tags.php' ) {
    
            if( isset($_POST['taxonomy']) ) {
                ...
    
                require_once('admin\metabox\TermMetaBox.php');
                $this->metaBox = new TermMetabox( $_POST['taxonomy'] );
    
                ...
            }
        }
    }
    

    Alternatively, instead of the $pagenow === 'edit-tags.php' check, you can use the load-edit-tags.php action, like so:

    • DazSEO::adminInit():

      public function adminInit() {
          add_action( 'load-edit-tags.php', array( $this, 'setupMetaBox' ) );
      }
      
    • DazSEO::setupMetaBox():

      public function setupMetaBox() {
          if( isset($_POST['taxonomy']) ) {
              ...
      
              require_once('admin\metabox\TermMetaBox.php');
              $this->metaBox = new TermMetabox( $_POST['taxonomy'] );
      
              ...
          }
      }
      
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法