¿Es posible instalar complementos mediante programación desde el tema de wordpress?

9 minutos de lectura

Mi sueño es incluir un archivo php en un tema que verifique si un conjunto de complementos está instalado e instala los que no lo están. Algo así como un conjunto de dependencias para el tema, pero también una buena manera de empaquetar el desarrollo del tema para incluir un conjunto de buenos complementos.

Mis preguntas…

  1. ¿Hay algo así en existencia?
  2. ¿Es posible lograr desde un solo archivo php en una carpeta de tema?
  3. ¿Hay trampas o problemas obvios con este enfoque?
  4. ¿Cómo haría para lograr esto?
    • ¿Es posible enumerar los complementos instalados desde la carpeta del tema?
    • ¿Es posible descargar y colocar archivos de complementos en la carpeta de complementos?
    • ¿Es posible activar complementos desde el directorio de temas?

  • La mayoría de las cosas sobre las que pregunta ya son cosas que WordPress es capaz de hacer, lo que significa que puede ver cómo lo hacen. Por ejemplo, wordpress le permite instalar complementos, activar complementos, etc. Vea cómo lo hacen.

    – Jamie Dixon

    27 de abril de 2012 a las 15:56

avatar de usuario
maiorano84

07/06/2018 EDITAR: Si se encuentra con esta respuesta, el código resaltado a continuación es extremadamente anticuado e inseguro y no debe usarse en ninguna capacidad fuera de la experimentación en un servidor local. Si está buscando una solución más moderna para la administración de complementos, considere instalar WordPress a través de Compositor y base


Aconsejaría NO verificar programáticamente la existencia de ciertos complementos, descargarlos, instalarlos y activarlos desde cualquier archivo de tema. Debe tener en cuenta que la verificación se ejecutará cada vez que se cargue la página dada, y puede generar una gran cantidad de código superfluo y actividad innecesaria.

En cambio, mi consejo sería empaquetar cualquier complemento del que dependa su tema como parte del tema en sí, y NO como un complemento. Los complementos deben instalarse a discreción del usuario. Si un tema depende de un complemento para funcionar de manera adecuada o eficiente, entonces realmente debería empaquetarse y descargarse con el tema en sí.

Pero para responder a sus preguntas directamente:

  1. Probablemente. Ciertamente es posible hacerlo.
  2. Sí.
  3. Vea lo anterior. Es posible que se encuentre con más problemas al verificar constantemente los complementos y ejecutar una serie de acciones basadas en esas condiciones en lugar de simplemente incluir todo lo necesario.
  4. un montón de investigación

    • Probablemente

Sin embargo, no puedo enfatizar lo suficiente que el propósito de un PLUGIN es darle al usuario la opción de ampliar las capacidades de un tema determinado. Si las capacidades de su tema DEPENDEN de los complementos existentes, entonces REALMENTE debería incluir todos los archivos cuando alguien descargue su tema.

Aunque si sientes que tu enfoque beneficia tu tema en formas que yo podría estar perdiendo, siéntete libre de escribirlo como quieras.

RESPUESTA COMPLETA: Decidí ayudar a crear una prueba de concepto para ti, porque me aburría y sentía curiosidad. Gran parte de esto debería explicarse por sí mismo. Agregue estas funciones:

function mm_get_plugins($plugins)
{
    $args = array(
            'path' => ABSPATH.'wp-content/plugins/',
            'preserve_zip' => false
    );

    foreach($plugins as $plugin)
    {
            mm_plugin_download($plugin['path'], $args['path'].$plugin['name'].'.zip');
            mm_plugin_unpack($args, $args['path'].$plugin['name'].'.zip');
            mm_plugin_activate($plugin['install']);
    }
}
function mm_plugin_download($url, $path) 
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    curl_close($ch);
    if(file_put_contents($path, $data))
            return true;
    else
            return false;
}
function mm_plugin_unpack($args, $target)
{
    if($zip = zip_open($target))
    {
            while($entry = zip_read($zip))
            {
                    $is_file = substr(zip_entry_name($entry), -1) == "https://stackoverflow.com/" ? false : true;
                    $file_path = $args['path'].zip_entry_name($entry);
                    if($is_file)
                    {
                            if(zip_entry_open($zip,$entry,"r")) 
                            {
                                    $fstream = zip_entry_read($entry, zip_entry_filesize($entry));
                                    file_put_contents($file_path, $fstream );
                                    chmod($file_path, 0777);
                                    //echo "save: ".$file_path."<br />";
                            }
                            zip_entry_close($entry);
                    }
                    else
                    {
                            if(zip_entry_name($entry))
                            {
                                    mkdir($file_path);
                                    chmod($file_path, 0777);
                                    //echo "create: ".$file_path."<br />";
                            }
                    }
            }
            zip_close($zip);
    }
    if($args['preserve_zip'] === false)
    {
            unlink($target);
    }
}
function mm_plugin_activate($installer)
{
    $current = get_option('active_plugins');
    $plugin = plugin_basename(trim($installer));

    if(!in_array($plugin, $current))
    {
            $current[] = $plugin;
            sort($current);
            do_action('activate_plugin', trim($plugin));
            update_option('active_plugins', $current);
            do_action('activate_'.trim($plugin));
            do_action('activated_plugin', trim($plugin));
            return true;
    }
    else
            return false;
}

… y luego ejecutar así:

$plugins = array(
    array('name' => 'jetpack', 'path' => 'http://downloads.wordpress.org/plugin/jetpack.1.3.zip', 'install' => 'jetpack/jetpack.php'),
    array('name' => 'buddypress', 'path' => 'http://downloads.wordpress.org/plugin/buddypress.1.5.5.zip', 'install' => 'buddypress/bp-loader.php'),
    array('name' => 'tumblr-importer', 'path' => 'http://downloads.wordpress.org/plugin/tumblr-importer.0.5.zip', 'install' => 'tumblr-importer/tumblr-importer.php')
);
mm_get_plugins($plugins);

‘nombre’ puede ser cualquier cosa, ya que sirve para ser más un valor temporal. ‘ruta’ es exactamente lo que parece, y es la URL directa al archivo zip en el servidor de WordPress. El valor de ‘instalación’ es simplemente la ruta al script PHP principal que tiene toda la información del complemento. Deberá conocer el diseño de ese directorio de complementos en particular para completar esta información, ya que esto también es necesario para que funcione el truco de activación.

La función de activación se encontró aquí (crédito a sorich87): https://wordpress.stackexchange.com/questions/4041/how-to-activate-plugins-via-code

ADVERTENCIA: Esta no es una forma muy segura de hacer las cosas. De hecho, creo que se puede abusar de esto con bastante facilidad, por lo que nuestra mejor apuesta es usar esto como nuestra línea de base e intentar mejorar a partir de ahí.

Si decide utilizar este enfoque, todo lo que pido es que me acrediten con el guión general inicial, junto con sorich87 por su proceso de activación Que Dios se apiade de tu alma.

07/06/2018 EDITAR: En serio, no hagas esto. Según los estándares actuales, este código es basura caliente. La administración de complementos debe realizarse a través de Compositor y base.

  • Gracias por su completa y reflexiva respuesta. Supongo que estoy tratando de abordar dos problemas. Una es cumplir con todas las dependencias del tema, que usted ha declarado correctamente que debe hacerse sin complementos. Y segundo, para instalar de forma sencilla todos los plugins de buen sentido general que siempre termino instalando para los clientes. Me gustaría que el cliente pueda instalar el tema y luego tener todos los complementos instalados automáticamente, pero sin perder la capacidad de eliminarlos o modificarlos en el futuro si así lo desean.

    –Billy Luna

    27 de abril de 2012 a las 16:37

  • Un ejemplo de por qué quiero esto es que puedo agregar un complemento para modificar el editor html para tener definiciones para div con una determinada clase que usa el tema. Es una parte esencial de cómo funciona el tema, para permitir una fácil edición de publicaciones y etiquetar partes como pertenecientes a una determinada clase. Sin embargo, no quiero limitar al cliente para que no realice más modificaciones o cambie el sistema de back-end si cree que tiene una mejor manera de hacerlo. ¿Tiene alguna idea sobre este punto?

    –Billy Luna

    27/04/2012 a las 16:40

  • En ese caso, si estuviera incluyendo una serie de complementos como un cinturón de herramientas sugerido, entonces puedo ver que su enfoque es útil y menos molesto de lo que se pensaba originalmente. El enfoque que tomaría personalmente en lugar de automatizar todo sería incluir simplemente una serie de enlaces de complementos sugeridos en alguna documentación del tema (quizás en sus opciones de tema). Pero realmente se reduce a preferencias personales. Ahora que ha aclarado su enfoque, puedo decir que no hay nada intrínsecamente malo en sus ideas para mejorar la usabilidad.

    – maiorano84

    27 de abril de 2012 a las 16:47

  • @BillyMoon Revise mi actualización para obtener más detalles. Es un poco feo, pero no tengo ninguna duda de que lo encontrará útil para descargar complementos del servidor de WordPress. Buena suerte.

    – maiorano84

    27 de abril de 2012 a las 17:32

  • Ese guión parece un gran punto de partida. Creo que también podría tomar su otra sugerencia y poner un botón en la página de configuración del tema que lleva a cabo la instalación. Si obtengo una prueba medio decente del funcionamiento del método, la subiré a git-hub para mejorar y publicaré el enlace aquí. Gracias por la ayuda.

    –Billy Luna

    27 de abril de 2012 a las 17:46

avatar de usuario
Tomás

Inspirado por el comentario de Jamie Dixon, inspeccioné cómo funciona WordPress.

El proceso se puede ver en /wp-admin/update.php de la línea 93. Se podría hacer una versión corta como esta:

include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api..

$plugin = 'plugin-name';

$api = plugins_api( 'plugin_information', array(
    'slug' => $plugin,
    'fields' => array(
        'short_description' => false,
        'sections' => false,
        'requires' => false,
        'rating' => false,
        'ratings' => false,
        'downloaded' => false,
        'last_updated' => false,
        'added' => false,
        'tags' => false,
        'compatibility' => false,
        'homepage' => false,
        'donate_link' => false,
    ),
));

//includes necessary for Plugin_Upgrader and Plugin_Installer_Skin
include_once( ABSPATH . 'wp-admin/includes/file.php' );
include_once( ABSPATH . 'wp-admin/includes/misc.php' );
include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );

$upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( compact('title', 'url', 'nonce', 'plugin', 'api') ) );
$upgrader->install($api->download_link);

Si no desea que se muestren los comentarios, debe crear una clase de máscara personalizada. Por ejemplo:

$upgrader = new \Plugin_Upgrader( new Quiet_Skin() );

class Quiet_Skin extends \WP_Upgrader_Skin {
    public function feedback($string)
    {
        // just keep it quiet
    }
}

  • @thomas: Soy bastante nuevo en php y WordPress, pero estoy creando un complemento para practicar mis habilidades en ambos. Mi complemento debería verificar si otros complementos están instalados (esto funciona) y, si no, debería instalarlos (esto aún no funciona). Me gustaría usar su método porque usa la funcionalidad de WordPress. Pero no entiendo cómo usarlo, ¿puedes dar un ejemplo? el primer complemento que intento instalar es Yoast SEO. Gracias por la ayuda

    – interruptor87

    06/01/2017 a las 14:30

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad