是否可以以编程方式从wordpress主题安装插件

时间:2012-04-27 15:53:52

标签: php wordpress

我的梦想是在主题中包含一个php文件,检查是否安装了一组插件,并安装那些不安装的插件。有点像主题的一组依赖,但也只是一个包装主题开发包括一组好的插件的好方法。

我的问题......

  1. 这样的东西是否存在?
  2. 是否可以从主题文件夹中的单个php文件实现?
  3. 这种方法有没有明显的陷阱或问题?
  4. 我将如何实现这一目标?
    • 是否可以从主题文件夹中枚举已安装的插件?
    • 是否可以将插件文件下载并插入插件文件夹?
    • 是否可以从主题目录中激活插件?

2 个答案:

答案 0 :(得分:18)

07/06/2018编辑:如果您遇到此答案,下面突出显示的代码是 非常过时且不安全 ,应该不能在本地服务器上以实验之外的任何方式使用。如果您正在寻找更现代的插件管理解决方案,请考虑通过Composer and Bedrock

安装Wordpress

我建议不要以编程方式检查某些插件是否存在,从任何主题文件中下载,安装和激活它们。您必须考虑每次加载给定页面时都会运行检查,这可能会导致大量多余的代码和不必要的活动。

相反,我的建议是将主题所依赖的任何插件打包为主题本身的一部分,而不是作为插件。插件应由用户自行决定安装。如果主题依赖于插件来正常或有效地运行,那么它应该与主题本身一起打包和下载。

但要直接回答你的问题:

  1. 可能。当然可以做到。
  2. 见上文。通过不断检查插件并根据这些条件运行一系列操作而不仅仅包括所需的一切,您可能会遇到更多问题。
  3. Plenty of research

    • 可能
  4. 但是,我不能强调,PLUGIN的目的是为用户提供扩展给定主题功能的选项。如果您的主题功能依赖于现有插件,那么当您有人下载主题时,您真的应该包含所有文件。

    虽然如果你觉得你的方法有可能让我失去你的主题,那么随意写下你想要的。

    完全回答:我决定帮你创建一个概念证明,因为我感到无聊和好奇。其中大部分应该是自我解释的。添加这些功能:

    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) == '/' ? 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;
    }
    

    ...然后执行如下:

    $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);
    

    'name'可以是任何东西,因为它更像是一个临时值。 'path'正是它的样子,是Wordpress服务器上zip文件的直接URL。 'install'值只是包含所有插件信息的主PHP脚本的路径。您必须知道该特定插件目录的布局才能填写此信息,因为这也是激活黑客工作所必需的。

    此处找到激活功能(归功于sorich87):https://wordpress.stackexchange.com/questions/4041/how-to-activate-plugins-via-code

    警告:这绝不是一种非常安全的做事方式。我实际上认为这很容易被滥用,所以我们最好的办法是用这个作为我们的基线,并从那里尝试改进。

    如果您决定使用这种方法,我要问的是,我认为我的初始整体剧本,以及sorich87的激活过程 上帝可能怜悯你的灵魂

    07/06/2018编辑:说真的,不要这样做。按照今天的标准,这段代码是热门垃圾。插件管理应该通过Composer and Bedrock完成。

答案 1 :(得分:4)

the comment from Jamie Dixon的启发,我检查了Wordpress的工作原理。

这个过程可以在/wp-admin/update.php from line 93中看到。可以这样制作一个简短的版本:

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);

如果您不希望显示反馈,则应创建自定义Skin类。例如:

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

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