summaryrefslogtreecommitdiff
path: root/platform/www/lib/plugins/extension/cli.php
diff options
context:
space:
mode:
Diffstat (limited to 'platform/www/lib/plugins/extension/cli.php')
-rw-r--r--platform/www/lib/plugins/extension/cli.php372
1 files changed, 372 insertions, 0 deletions
diff --git a/platform/www/lib/plugins/extension/cli.php b/platform/www/lib/plugins/extension/cli.php
new file mode 100644
index 0000000..a293f87
--- /dev/null
+++ b/platform/www/lib/plugins/extension/cli.php
@@ -0,0 +1,372 @@
+<?php
+
+use splitbrain\phpcli\Colors;
+
+/**
+ * Class cli_plugin_extension
+ *
+ * Command Line component for the extension manager
+ *
+ * @license GPL2
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class cli_plugin_extension extends DokuWiki_CLI_Plugin
+{
+ /** @inheritdoc */
+ protected function setup(\splitbrain\phpcli\Options $options)
+ {
+ // general setup
+ $options->setHelp(
+ "Manage plugins and templates for this DokuWiki instance\n\n" .
+ "Status codes:\n" .
+ " i - installed\n" .
+ " b - bundled with DokuWiki\n" .
+ " g - installed via git\n" .
+ " d - disabled\n" .
+ " u - update available\n"
+ );
+
+ // search
+ $options->registerCommand('search', 'Search for an extension');
+ $options->registerOption('max', 'Maximum number of results (default 10)', 'm', 'number', 'search');
+ $options->registerOption('verbose', 'Show detailed extension information', 'v', false, 'search');
+ $options->registerArgument('query', 'The keyword(s) to search for', true, 'search');
+
+ // list
+ $options->registerCommand('list', 'List installed extensions');
+ $options->registerOption('verbose', 'Show detailed extension information', 'v', false, 'list');
+ $options->registerOption('filter', 'Filter by this status', 'f', 'status', 'list');
+
+ // upgrade
+ $options->registerCommand('upgrade', 'Update all installed extensions to their latest versions');
+
+ // install
+ $options->registerCommand('install', 'Install or upgrade extensions');
+ $options->registerArgument('extensions...', 'One or more extensions to install', true, 'install');
+
+ // uninstall
+ $options->registerCommand('uninstall', 'Uninstall a new extension');
+ $options->registerArgument('extensions...', 'One or more extensions to install', true, 'uninstall');
+
+ // enable
+ $options->registerCommand('enable', 'Enable installed extensions');
+ $options->registerArgument('extensions...', 'One or more extensions to enable', true, 'enable');
+
+ // disable
+ $options->registerCommand('disable', 'Disable installed extensions');
+ $options->registerArgument('extensions...', 'One or more extensions to disable', true, 'disable');
+
+
+ }
+
+ /** @inheritdoc */
+ protected function main(\splitbrain\phpcli\Options $options)
+ {
+ /** @var helper_plugin_extension_repository $repo */
+ $repo = plugin_load('helper', 'extension_repository');
+ if (!$repo->hasAccess(false)) {
+ $this->warning('Extension Repository API is not accessible, no remote info available!');
+ }
+
+ switch ($options->getCmd()) {
+ case 'list':
+ $ret = $this->cmdList($options->getOpt('verbose'), $options->getOpt('filter', ''));
+ break;
+ case 'search':
+ $ret = $this->cmdSearch(
+ implode(' ', $options->getArgs()),
+ $options->getOpt('verbose'),
+ (int)$options->getOpt('max', 10)
+ );
+ break;
+ case 'install':
+ $ret = $this->cmdInstall($options->getArgs());
+ break;
+ case 'uninstall':
+ $ret = $this->cmdUnInstall($options->getArgs());
+ break;
+ case 'enable':
+ $ret = $this->cmdEnable(true, $options->getArgs());
+ break;
+ case 'disable':
+ $ret = $this->cmdEnable(false, $options->getArgs());
+ break;
+ case 'upgrade':
+ $ret = $this->cmdUpgrade();
+ break;
+ default:
+ echo $options->help();
+ $ret = 0;
+ }
+
+ exit($ret);
+ }
+
+ /**
+ * Upgrade all extensions
+ *
+ * @return int
+ */
+ protected function cmdUpgrade()
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+ $list = $this->getInstalledExtensions();
+
+ $ok = 0;
+ foreach ($list as $extname) {
+ $ext->setExtension($extname);
+ $date = $ext->getInstalledVersion();
+ $avail = $ext->getLastUpdate();
+ if ($avail && $avail > $date) {
+ $ok += $this->cmdInstall([$extname]);
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Enable or disable one or more extensions
+ *
+ * @param bool $set
+ * @param string[] $extensions
+ * @return int
+ */
+ protected function cmdEnable($set, $extensions)
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+
+ $ok = 0;
+ foreach ($extensions as $extname) {
+ $ext->setExtension($extname);
+ if (!$ext->isInstalled()) {
+ $this->error(sprintf('Extension %s is not installed', $ext->getID()));
+ $ok += 1;
+ continue;
+ }
+
+ if ($set) {
+ $status = $ext->enable();
+ $msg = 'msg_enabled';
+ } else {
+ $status = $ext->disable();
+ $msg = 'msg_disabled';
+ }
+
+ if ($status !== true) {
+ $this->error($status);
+ $ok += 1;
+ continue;
+ } else {
+ $this->success(sprintf($this->getLang($msg), $ext->getID()));
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Uninstall one or more extensions
+ *
+ * @param string[] $extensions
+ * @return int
+ */
+ protected function cmdUnInstall($extensions)
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+
+ $ok = 0;
+ foreach ($extensions as $extname) {
+ $ext->setExtension($extname);
+ if (!$ext->isInstalled()) {
+ $this->error(sprintf('Extension %s is not installed', $ext->getID()));
+ $ok += 1;
+ continue;
+ }
+
+ $status = $ext->uninstall();
+ if ($status) {
+ $this->success(sprintf($this->getLang('msg_delete_success'), $ext->getID()));
+ } else {
+ $this->error(sprintf($this->getLang('msg_delete_failed'), hsc($ext->getID())));
+ $ok = 1;
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Install one or more extensions
+ *
+ * @param string[] $extensions
+ * @return int
+ */
+ protected function cmdInstall($extensions)
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+
+ $ok = 0;
+ foreach ($extensions as $extname) {
+ $ext->setExtension($extname);
+
+ if (!$ext->getDownloadURL()) {
+ $ok += 1;
+ $this->error(
+ sprintf('Could not find download for %s', $ext->getID())
+ );
+ continue;
+ }
+
+ try {
+ $installed = $ext->installOrUpdate();
+ foreach ($installed as $name => $info) {
+ $this->success(sprintf(
+ $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'),
+ $info['base'])
+ );
+ }
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ $ok += 1;
+ }
+ }
+ return $ok;
+ }
+
+ /**
+ * Search for an extension
+ *
+ * @param string $query
+ * @param bool $showdetails
+ * @param int $max
+ * @return int
+ * @throws \splitbrain\phpcli\Exception
+ */
+ protected function cmdSearch($query, $showdetails, $max)
+ {
+ /** @var helper_plugin_extension_repository $repository */
+ $repository = $this->loadHelper('extension_repository');
+ $result = $repository->search($query);
+ if ($max) {
+ $result = array_slice($result, 0, $max);
+ }
+
+ $this->listExtensions($result, $showdetails);
+ return 0;
+ }
+
+ /**
+ * @param bool $showdetails
+ * @param string $filter
+ * @return int
+ * @throws \splitbrain\phpcli\Exception
+ */
+ protected function cmdList($showdetails, $filter)
+ {
+ $list = $this->getInstalledExtensions();
+ $this->listExtensions($list, $showdetails, $filter);
+
+ return 0;
+ }
+
+ /**
+ * Get all installed extensions
+ *
+ * @return array
+ */
+ protected function getInstalledExtensions()
+ {
+ /** @var Doku_Plugin_Controller $plugin_controller */
+ global $plugin_controller;
+ $pluginlist = $plugin_controller->getList('', true);
+ $tpllist = glob(DOKU_INC . 'lib/tpl/*', GLOB_ONLYDIR);
+ $tpllist = array_map(function ($path) {
+ return 'template:' . basename($path);
+ }, $tpllist);
+ $list = array_merge($pluginlist, $tpllist);
+ sort($list);
+ return $list;
+ }
+
+ /**
+ * List the given extensions
+ *
+ * @param string[] $list
+ * @param bool $details display details
+ * @param string $filter filter for this status
+ * @throws \splitbrain\phpcli\Exception
+ */
+ protected function listExtensions($list, $details, $filter = '')
+ {
+ /** @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+ $tr = new \splitbrain\phpcli\TableFormatter($this->colors);
+
+
+ foreach ($list as $name) {
+ $ext->setExtension($name);
+
+ $status = '';
+ if ($ext->isInstalled()) {
+ $date = $ext->getInstalledVersion();
+ $avail = $ext->getLastUpdate();
+ $status = 'i';
+ if ($avail && $avail > $date) {
+ $vcolor = Colors::C_RED;
+ $status .= 'u';
+ } else {
+ $vcolor = Colors::C_GREEN;
+ }
+ if ($ext->isGitControlled()) $status = 'g';
+ if ($ext->isBundled()) $status = 'b';
+ if ($ext->isEnabled()) {
+ $ecolor = Colors::C_BROWN;
+ } else {
+ $ecolor = Colors::C_DARKGRAY;
+ $status .= 'd';
+ }
+ } else {
+ $ecolor = null;
+ $date = $ext->getLastUpdate();
+ $vcolor = null;
+ }
+
+ if ($filter && strpos($status, $filter) === false) {
+ continue;
+ }
+
+ echo $tr->format(
+ [20, 3, 12, '*'],
+ [
+ $ext->getID(),
+ $status,
+ $date,
+ strip_tags(sprintf(
+ $this->getLang('extensionby'),
+ $ext->getDisplayName(),
+ $this->colors->wrap($ext->getAuthor(), Colors::C_PURPLE))
+ )
+ ],
+ [
+ $ecolor,
+ Colors::C_YELLOW,
+ $vcolor,
+ null,
+ ]
+ );
+
+ if (!$details) continue;
+
+ echo $tr->format(
+ [5, '*'],
+ ['', $ext->getDescription()],
+ [null, Colors::C_CYAN]
+ );
+ }
+ }
+}