【问题标题】:Is it possible to programmatically install plugins from wordpress theme是否可以从 wordpress 主题以编程方式安装插件
【发布时间】:2012-04-27 15:53:51
【问题描述】:

我的梦想是在主题中包含一个 php 文件,该文件检查是否安装了一组插件,并安装未安装的插件。有点像主题的一组依赖项,但也是打包主题开发以包含一组好的插件的好方法。

我的问题...

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

【问题讨论】:

  • 您询问的大多数事情已经是 Wordpress 能够做到的事情,这意味着您可以看看他们是如何做到的。例如,wordpress 允许您安装插件、激活插件等。看看他们是如何做到的。

标签: php wordpress


【解决方案1】:

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


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

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

但是直接回答你的问题:

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

    • 可能
    • 是的
    • 是的

然而,我怎么强调都不为过,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来完成。

【讨论】:

  • 感谢您全面周到的回答。我想我正在尝试解决两个问题。一种是满足所有主题依赖项,您已正确声明应该在没有插件的情况下完成。其次,为了以简单的方式安装所有通用的好插件,我总是最终为客户安装。我希望客户端能够安装主题,然后自动安装所有插件,但如果他们愿意,将来不会失去删除或修改它们的能力。
  • 我想要这个的一个例子是,我可以添加一个插件来修改 html 编辑器,以便为具有主题使用的某个类的 div 定义。它是主题功能的重要组成部分,可以轻松编辑帖子并将部分标记为某个类别。但是,我不想限制客户端进行进一步修改,或者如果他们认为有更好的方法来更改后端系统。你对这一点有什么想法吗?
  • 在这种情况下,如果您包含一系列插件作为建议的工具带,那么我可以看到您的方法比最初想象的更有帮助且不那么突兀。我个人采用的方法是在一些主题文档中(可能在您的主题选项中)简单地包含一系列建议的插件链接,而不是使整个事情自动化。但这真的归结为个人喜好。现在你已经阐明了你的方法,我可以说你在提高可用性方面的想法本质上没有错。
  • @BillyMoon 查看我的更新以获取详细信息。它有点难看,但我毫不怀疑你会发现它在从 Wordpress 服务器下载插件时很有用。祝你好运。
  • 该脚本看起来是一个很好的起点。我想我也可能会采纳您的其他建议,并在执行安装的主题设置页面上放置一个按钮。如果我得到了一个半体面的方法工作证明,我会将它放在 git-hub 上以进行有希望的改进,并在此处发布链接。感谢您的帮助。
【解决方案2】:

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

如果您不希望显示反馈,您应该创建一个自定义皮肤类。例如:

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

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

【讨论】:

  • @thomas :我对 php 和 WordPress 很陌生,但我正在制作一个插件来练习我在这两个方面的技能。我的插件应该检查​​是否安装了其他插件(这有效),如果没有,它应该安装它们(这还不起作用)。我想使用您的方法,因为它使用了 Wordpress 的功能。但是我不明白怎么用是,你能举个例子吗?我尝试安装的第一个插件是 Yoast SEO。感谢您的帮助
猜你喜欢
  • 2018-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多