WordPress : Classe wrapper : comment se débarrasser de l’avertissement call_user_func_array() ?

Publié par Jean-Michel le

J’ai plusieurs installations de wordpress et j’essaie maintenant de créer mon propre petit framework afin de pouvoir créer et maintenir mes thèmes plus efficacement. Ce que je voudrais faire, c’est avoir un emballage pour les crochets proposés par wordpress.

Je voudrais appeler des crochets comme celui-ci dans mon application

$_addThumb = function(){
add_theme_support('post-thumbnails');
};

 $core->registerAction(array('tag' => 'after_theme_setup',
                             'callback' => $_redirect
                             ));

Dans ma classe, je gère la logique comme ceci (c’est un extrait, tout le code est ci-dessous)

    if (!empty($this -> _actions)) {
        foreach ($this->_actions as $action) {
            add_action($action[0], array($this, call_user_func($action[1])));
        }
    }

Le problème est que si j’ajoute le mot-clé $this à l’appel add_action comme ceci…

add_action($tag, array($this, $callback))

… Je reçois cet avertissement :

Avertissement : call_user_func_array() s’attend à ce que le paramètre 1 soit un rappel valide, le deuxième membre du tableau n’est pas une méthode valide dans Z:Websitewp-includesplugin.php

Et si je ne l’ajoute pas comme ça…

add_action($tag, $callback)

Puis je reçois cet avis :

Décalage non défini : 0 dans Z:Websitewp-includesplugin.php

Sur les deux scénarios, tout fonctionne cependant. Je voudrais juste comprendre pourquoi cela se produit et au moins me débarrasser de l’avertissement.

Voici mon code complet :

class Core {

/**
 * theme features
 */
protected $_features = array();
private $_actions = array();


/**
 * register extra functions so you can add actions to the theme
 *@param array mixed
 */
public function registerAction($args) {

    if (!is_array($args)) {
        $args = func_get_args();
    }
    if (count($args) < 2) {
        throw new InvalidArgumentException(sprintf('Not enough arguments(registerCallback needs at least two arguments): %s.', print_r($args, true)));
    }
    $arg_list = array_values($args);

    /**
     * sets the default priority
     */
    if (!isset($arg_list[2])) {
        $arg_list[2] = 10;
    }
    /**
     * sets default args
     */
    if (!isset($arg_list[3])) {
        $arg_list[3] = 0;
    }

    if (!is_callable($arg_list[1])) {
        throw new Exception("callback not callable : Core:13");
    }

    $this -> _actions[] = $arg_list;

}

/**
 * TODO: development only
 */
public function get_actions() {
    echo "<pre>";
    print_r($this -> _actions);
    echo "</pre>";
}

/**
 * set theme features
 * 'post-formats'
 * 'post-thumbnails'
 * 'custom-background'
 * 'custom-header'
 * 'automatic-feed-links'
 * 'menus'
 * @param string (required) name of the feature to be added
 * @param array (optional) optional arguments
 */
public function set_feature($feature, $options = array()) {

    if (is_array($options) && !empty($options)) {
        $this -> _features[]['args'] = array($feature, $options);
    } else {
        $this -> _features[]['name'] = $feature;
    }
}

public function get_features() {
    return $this->_features;
}

function __construct() {

}

public function init($tag = '', $function = '') {
    add_action('after_setup_theme', array($this, 'initial_setup'));

    if (!empty($this -> _actions)) {
        foreach ($this->_actions as $action) {
            add_action($action[0], array($this, call_user_func($action[1])), $action[2], $action[3]);
        }
    }
}

public function initial_setup() {

    // check if we have ay features so we can add them to our theme
    if (!empty($this -> _features)) {
        foreach ($this->_features as $feature) {
            if (isset($feature['args'])) {
                add_theme_support($feature['args'][0], $feature['args'][1]);
            } else {
                add_theme_support($feature['name']);
            }
        }
    }
}

}

mes fonctions.php

$core = new Core();

$core->set_feature('automatic-feed-links');

$core->set_feature('post-formats', array('aside',
                                         'image',
                                         'link',
                                         'quote',
                                         'status',
                                         'gallery',
                                         'video' ));
$_addThumb = function(){
    add_theme_support('post-thumbnails');
};

$_sidebars = function() {
    register_sidebar( array(
        'name'          => __( 'Main Widget Area', 'twentythirteen' ),
        'id'            => 'sidebar-1',
        'description'   => __( 'Appears in the footer section of the site.', 'twentythirteen' ),
        'before_widget' => '<aside id="%1$s" class="widget %2$s">',
        'after_widget'  => '</aside>',
        'before_title'  => '<h3 class="widget-title">',
        'after_title'   => '</h3>',
    ) );

    register_sidebar( array(
        'name'          => __( 'Secondary Widget Area', 'twentythirteen' ),
        'id'            => 'sidebar-2',
        'description'   => __( 'Appears on posts and pages in the sidebar.', 'twentythirteen' ),
        'before_widget' => '<aside id="%1$s" class="widget %2$s">',
        'after_widget'  => '</aside>',
        'before_title'  => '<h3 class="widget-title">',
        'after_title'   => '</h3>',
    ) );
};

$_adminHead = function(){

echo '<style>[for="wp_welcome_panel-hide"] {display: none !important; } #normal-sortables{display:none !important;}</style>';

};

/** i don't get a notiche with this **/
$core->registerAction(array('tag' => 'after_theme_setup', 'callback' => $_addThumb));

/** it works but i get this warning
 * arning: call_user_func_array() expects parameter 1 to be a valid callback, second array member is not a valid method in Z:Armen Websitewp-includesplugin.php on line
 */
$core->registerAction(array('tag' =>'admin_head', 'callback' => $_adminHead));
$core->registerAction(array('tag' => 'widgets_init', 'callback' => $_sidebars));
$core->init();

Solution n°1 trouvée

Je comprends. le problème est que add_action attend un objet avec une méthode. add_action($action[0], array($this, call_user_func($action[1])));je passe l’objet avec le mot-clé $this mais la méthode n’est pas reconnue car c’est une fermeture donc c’est en dehors de la portée de la classe la meilleure solution serait de lier la fermeture à l’objet cependant j’utilise php 5.3 et la liaison de fermeture est disponible sur la version 5.4 uniquement. Donc, ce que j’ai fini par faire, c’est de créer un registre pour toutes les fermetures et de lui attacher un alias afin que chaque fermeture ressemble à une méthode de la classe. ce qui m’a donné cette idée était cette réponse https://stackoverflow.com/a/420030/1287608 et c’est ainsi que je finis par le faire. remarquez comment j’ajoute une nouvelle méthode au registre avec un alias « loadAction » dans ce cas.$this->register($closure, "loadAction{$i}")

public function init($tag = '', $function = '') {

    add_action('after_setup_theme', array($this, 'initial_setup'));

    if (!empty($this -> _actions)) {
        $i = 0;
        foreach ($this->_actions as $action) {
            $this->register($action[1], "loadAction{$i}");
            $success = add_action($action[0], array($this, "loadAction{$i}"), $action[2], $action[3]);
        $i++;
        }
    }
}

Solution n°2 trouvée

Comme vous l’avez déjà remarqué, $thisne fonctionnera pas comme prévu avant PHP 5.4. Vous pouvez lire ceci dans le wiki PHP. La raison:

Pour PHP 5.3 $this, la prise en charge des fermetures a été supprimée car aucun consensus n’a pu être atteint sur la manière de l’implémenter de manière saine. Cette RFC décrit les chemins possibles qui peuvent être empruntés pour l’implémenter dans la prochaine version de PHP.

Une solution de contournement simple consiste à copier simplement $thisà l’avant, puis à utiliser la nouvelle référence/variable :

$subject = clone $this;
Catégories : Wordpress

0 commentaire

Laisser un commentaire

Avatar placeholder

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *