Actualizar un complemento manteniendo la compatibilidad con la parte posterior: general

4

¿Cómo puedo hacer que las actualizaciones sean un complemento público mío sin romper el complemento para todos los usuarios existentes?

Primero , me gustaría cambiar la clase / espacio de nombres del complemento principal, porque me gustaría que sea similar a otras clases en el complemento que se extiende.

Así que me gustaría cambiar

class some_class(){}

a

class Some_Class(){}

En segundo lugar , toda la clase se crea una instancia y se guarda en una variable global.

global $some_class;
$some_class = new some_class();

En algún lugar aquí, vi un buen ejemplo de cómo crear una instancia de una clase sin un global (no puedo encontrarlo ahora, por supuesto, #doh). El global puede ser utilizado por los usuarios para agregar / eliminar un par de plantillas. ¿Hay alguna forma de deshacerse de lo global sin romper por completo los temas de las personas que podrían usarlo para manipular las plantillas?

En tercer lugar , relacionado con lo anterior, mi archivo de complemento principal se ha vuelto muy grande y me gustaría dividirlo en pedazos para mi propia cordura. Sin embargo, si el método some_templates() está en el some_class() , ¿es posible moverlo al front_end_class() sin romper las cosas para los usuarios?

Por ejemplo

Para desenganchar una acción en mi complemento

function remove_method(){
  global $some_class;
  remove_action('wp_head', array($someclass, 'some_templates'));
}
add_action('init','remove_method');

¿Se puede ajustar la estructura de la clase y la configuración de la variable global sin romper esto? ¿Cómo puedo alertar a las personas que esto ha cambiado? _doing_it_wrong() ?

Finalmente , he estado guardando un meta de publicación como "sí" frente a "no" en lugar de un booleano. ¿Tiene sentido cambiar esto?

    
pregunta helgatheviking 02.03.2013 - 23:31

1 respuesta

4

Los nombres de clase no distinguen entre mayúsculas y minúsculas en PHP (con una excepción ), por lo que Eso no debería ser un problema.

Es posible acceder a la instancia del complemento principal para una clase con el método estático get_instance() ( ejemplo ). No tienes que construir un Singleton para eso. Y no debería romper la compatibilidad hacia atrás.

Si tenía métodos públicos en su código anterior y estos han sido utilizados por un código de terceros, debe conservar la firma exacta. Por lo tanto, mantenga el método y pase la llamada a la instancia de la nueva clase o, si hay muchos de estos métodos, use __call() para capturar todos estos métodos en uno.

(Actualizar) Dado tu ejemplo de remove_action() ... esto es complicado. Si agrega esta devolución de llamada de otra clase ahora, no hay una manera segura de mantener la compatibilidad con versiones anteriores, ya que no puede "ver" remove_action() llamadas.
Puede registrar la devolución de llamada anterior e implementar un Observer para que se note si se ha eliminado. .

Una idea con la que he estado jugando para proyectos futuros: separar la API pública de la lógica interna.

Ejemplo de

: cree una clase Plugin_API y pase todos los objetos de su código working a esa clase cuando estén configurados. Cuando se llama a un método de esa API, pase esa llamada al objeto responsable internamente , sin exponer su estructura de complementos al público.

Código de ejemplo

add_action( 'wp_loaded', array ( Plugin_Controller::get_instance(), 'plugin_setup' ) );

class Plugin_Controller
{
    protected static $instance = NULL;

    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;

        return self::$instance;
    }

    public function plugin_setup()
    {
        $api = Plugin_API::get_instance();
        $api->add_object( 'post_type',    new Plugin_Custom_Post_Type );
        $api->add_object( 'taxonomy',     new Plugin_Custom_Taxonomy );
        $api->add_object( 'options_page', new Plugin_Options_Page );

        add_action( 'wp_head', array ( $api, 'wp_head' ) );
    }
}

class Plugin_Custom_Post_Type {}
class Plugin_Custom_Taxonomy {}
class Plugin_Options_Page {}

class Plugin_API
{
    protected static $instance = NULL;

    protected $objects;

    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;

        return self::$instance;
    }

    public function add_object( $name, $object )
    {
        $this->objects[ $name ] = $object;
    }

    public function wp_head()
    {
        $this->objects['post_type']->wp_head_callback();
        $this->objects['taxonomy']->wp_head_callback();
    }
}

Ahora, otro complemento puede eliminar esa acción con ...

remove_action( 'wp_head', array ( Plugin_API::get_instance(), 'wp_head' ) );

... y aún eres libre de cambiar la estructura de tu complemento cuando lo desees.

Esto es solo una idea, no la he usado. Pero podría valer la pena intentarlo con un complemento complejo con muchas clases. No estoy seguro de cómo funcionará con los filtros, pero estos son más fáciles de mover de todos modos.

Actualizar un número desconocido de campos de metadatos posteriores puede ser costoso. No tocaría eso.

    
respondido por el fuxia 02.03.2013 - 23:59

Lea otras preguntas en las etiquetas