[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/plugins/extension/ -> cli.php (source)

   1  <?php
   2  
   3  use splitbrain\phpcli\Colors;
   4  
   5  /**
   6   * Class cli_plugin_extension
   7   *
   8   * Command Line component for the extension manager
   9   *
  10   * @license GPL2
  11   * @author Andreas Gohr <andi@splitbrain.org>
  12   */
  13  class cli_plugin_extension extends DokuWiki_CLI_Plugin
  14  {
  15      /** @inheritdoc */
  16      protected function setup(\splitbrain\phpcli\Options $options)
  17      {
  18          // general setup
  19          $options->setHelp(
  20              "Manage plugins and templates for this DokuWiki instance\n\n" .
  21              "Status codes:\n" .
  22              "   i - installed\n" .
  23              "   b - bundled with DokuWiki\n" .
  24              "   g - installed via git\n" .
  25              "   d - disabled\n" .
  26              "   u - update available\n"
  27          );
  28  
  29          // search
  30          $options->registerCommand('search', 'Search for an extension');
  31          $options->registerOption('max', 'Maximum number of results (default 10)', 'm', 'number', 'search');
  32          $options->registerOption('verbose', 'Show detailed extension information', 'v', false, 'search');
  33          $options->registerArgument('query', 'The keyword(s) to search for', true, 'search');
  34  
  35          // list
  36          $options->registerCommand('list', 'List installed extensions');
  37          $options->registerOption('verbose', 'Show detailed extension information', 'v', false, 'list');
  38          $options->registerOption('filter', 'Filter by this status', 'f', 'status', 'list');
  39  
  40          // upgrade
  41          $options->registerCommand('upgrade', 'Update all installed extensions to their latest versions');
  42  
  43          // install
  44          $options->registerCommand('install', 'Install or upgrade extensions');
  45          $options->registerArgument('extensions...', 'One or more extensions to install', true, 'install');
  46  
  47          // uninstall
  48          $options->registerCommand('uninstall', 'Uninstall a new extension');
  49          $options->registerArgument('extensions...', 'One or more extensions to install', true, 'uninstall');
  50  
  51          // enable
  52          $options->registerCommand('enable', 'Enable installed extensions');
  53          $options->registerArgument('extensions...', 'One or more extensions to enable', true, 'enable');
  54  
  55          // disable
  56          $options->registerCommand('disable', 'Disable installed extensions');
  57          $options->registerArgument('extensions...', 'One or more extensions to disable', true, 'disable');
  58  
  59  
  60      }
  61  
  62      /** @inheritdoc */
  63      protected function main(\splitbrain\phpcli\Options $options)
  64      {
  65          /** @var helper_plugin_extension_repository $repo */
  66          $repo = plugin_load('helper', 'extension_repository');
  67          if (!$repo->hasAccess(false)) {
  68              $this->warning('Extension Repository API is not accessible, no remote info available!');
  69          }
  70  
  71          switch ($options->getCmd()) {
  72              case 'list':
  73                  $ret = $this->cmdList($options->getOpt('verbose'), $options->getOpt('filter', ''));
  74                  break;
  75              case 'search':
  76                  $ret = $this->cmdSearch(
  77                      implode(' ', $options->getArgs()),
  78                      $options->getOpt('verbose'),
  79                      (int)$options->getOpt('max', 10)
  80                  );
  81                  break;
  82              case 'install':
  83                  $ret = $this->cmdInstall($options->getArgs());
  84                  break;
  85              case 'uninstall':
  86                  $ret = $this->cmdUnInstall($options->getArgs());
  87                  break;
  88              case 'enable':
  89                  $ret = $this->cmdEnable(true, $options->getArgs());
  90                  break;
  91              case 'disable':
  92                  $ret = $this->cmdEnable(false, $options->getArgs());
  93                  break;
  94              case 'upgrade':
  95                  $ret = $this->cmdUpgrade();
  96                  break;
  97              default:
  98                  echo $options->help();
  99                  $ret = 0;
 100          }
 101  
 102          exit($ret);
 103      }
 104  
 105      /**
 106       * Upgrade all extensions
 107       *
 108       * @return int
 109       */
 110      protected function cmdUpgrade()
 111      {
 112          /* @var helper_plugin_extension_extension $ext */
 113          $ext = $this->loadHelper('extension_extension');
 114          $list = $this->getInstalledExtensions();
 115  
 116          $ok = 0;
 117          foreach ($list as $extname) {
 118              $ext->setExtension($extname);
 119              $date = $ext->getInstalledVersion();
 120              $avail = $ext->getLastUpdate();
 121              if ($avail && $avail > $date && !$ext->isBundled()) {
 122                  $ok += $this->cmdInstall([$extname]);
 123              }
 124          }
 125  
 126          return $ok;
 127      }
 128  
 129      /**
 130       * Enable or disable one or more extensions
 131       *
 132       * @param bool $set
 133       * @param string[] $extensions
 134       * @return int
 135       */
 136      protected function cmdEnable($set, $extensions)
 137      {
 138          /* @var helper_plugin_extension_extension $ext */
 139          $ext = $this->loadHelper('extension_extension');
 140  
 141          $ok = 0;
 142          foreach ($extensions as $extname) {
 143              $ext->setExtension($extname);
 144              if (!$ext->isInstalled()) {
 145                  $this->error(sprintf('Extension %s is not installed', $ext->getID()));
 146                  $ok += 1;
 147                  continue;
 148              }
 149  
 150              if ($set) {
 151                  $status = $ext->enable();
 152                  $msg = 'msg_enabled';
 153              } else {
 154                  $status = $ext->disable();
 155                  $msg = 'msg_disabled';
 156              }
 157  
 158              if ($status !== true) {
 159                  $this->error($status);
 160                  $ok += 1;
 161                  continue;
 162              } else {
 163                  $this->success(sprintf($this->getLang($msg), $ext->getID()));
 164              }
 165          }
 166  
 167          return $ok;
 168      }
 169  
 170      /**
 171       * Uninstall one or more extensions
 172       *
 173       * @param string[] $extensions
 174       * @return int
 175       */
 176      protected function cmdUnInstall($extensions)
 177      {
 178          /* @var helper_plugin_extension_extension $ext */
 179          $ext = $this->loadHelper('extension_extension');
 180  
 181          $ok = 0;
 182          foreach ($extensions as $extname) {
 183              $ext->setExtension($extname);
 184              if (!$ext->isInstalled()) {
 185                  $this->error(sprintf('Extension %s is not installed', $ext->getID()));
 186                  $ok += 1;
 187                  continue;
 188              }
 189  
 190              $status = $ext->uninstall();
 191              if ($status) {
 192                  $this->success(sprintf($this->getLang('msg_delete_success'), $ext->getID()));
 193              } else {
 194                  $this->error(sprintf($this->getLang('msg_delete_failed'), hsc($ext->getID())));
 195                  $ok = 1;
 196              }
 197          }
 198  
 199          return $ok;
 200      }
 201  
 202      /**
 203       * Install one or more extensions
 204       *
 205       * @param string[] $extensions
 206       * @return int
 207       */
 208      protected function cmdInstall($extensions)
 209      {
 210          /* @var helper_plugin_extension_extension $ext */
 211          $ext = $this->loadHelper('extension_extension');
 212  
 213          $ok = 0;
 214          foreach ($extensions as $extname) {
 215              $ext->setExtension($extname);
 216  
 217              if (!$ext->getDownloadURL()) {
 218                  $ok += 1;
 219                  $this->error(
 220                      sprintf('Could not find download for %s', $ext->getID())
 221                  );
 222                  continue;
 223              }
 224  
 225              try {
 226                  $installed = $ext->installOrUpdate();
 227                  foreach ($installed as $name => $info) {
 228                      $this->success(sprintf(
 229                              $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'),
 230                              $info['base'])
 231                      );
 232                  }
 233              } catch (Exception $e) {
 234                  $this->error($e->getMessage());
 235                  $ok += 1;
 236              }
 237          }
 238          return $ok;
 239      }
 240  
 241      /**
 242       * Search for an extension
 243       *
 244       * @param string $query
 245       * @param bool $showdetails
 246       * @param int $max
 247       * @return int
 248       * @throws \splitbrain\phpcli\Exception
 249       */
 250      protected function cmdSearch($query, $showdetails, $max)
 251      {
 252          /** @var helper_plugin_extension_repository $repository */
 253          $repository = $this->loadHelper('extension_repository');
 254          $result = $repository->search($query);
 255          if ($max) {
 256              $result = array_slice($result, 0, $max);
 257          }
 258  
 259          $this->listExtensions($result, $showdetails);
 260          return 0;
 261      }
 262  
 263      /**
 264       * @param bool $showdetails
 265       * @param string $filter
 266       * @return int
 267       * @throws \splitbrain\phpcli\Exception
 268       */
 269      protected function cmdList($showdetails, $filter)
 270      {
 271          $list = $this->getInstalledExtensions();
 272          $this->listExtensions($list, $showdetails, $filter);
 273  
 274          return 0;
 275      }
 276  
 277      /**
 278       * Get all installed extensions
 279       *
 280       * @return array
 281       */
 282      protected function getInstalledExtensions()
 283      {
 284          /** @var Doku_Plugin_Controller $plugin_controller */
 285          global $plugin_controller;
 286          $pluginlist = $plugin_controller->getList('', true);
 287          $tpllist = glob(DOKU_INC . 'lib/tpl/*', GLOB_ONLYDIR);
 288          $tpllist = array_map(function ($path) {
 289              return 'template:' . basename($path);
 290          }, $tpllist);
 291          $list = array_merge($pluginlist, $tpllist);
 292          sort($list);
 293          return $list;
 294      }
 295  
 296      /**
 297       * List the given extensions
 298       *
 299       * @param string[] $list
 300       * @param bool $details display details
 301       * @param string $filter filter for this status
 302       * @throws \splitbrain\phpcli\Exception
 303       */
 304      protected function listExtensions($list, $details, $filter = '')
 305      {
 306          /** @var helper_plugin_extension_extension $ext */
 307          $ext = $this->loadHelper('extension_extension');
 308          $tr = new \splitbrain\phpcli\TableFormatter($this->colors);
 309  
 310  
 311          foreach ($list as $name) {
 312              $ext->setExtension($name);
 313  
 314              $status = '';
 315              if ($ext->isInstalled()) {
 316                  $date = $ext->getInstalledVersion();
 317                  $avail = $ext->getLastUpdate();
 318                  $status = 'i';
 319                  if ($avail && $avail > $date) {
 320                      $vcolor = Colors::C_RED;
 321                      $status .= 'u';
 322                  } else {
 323                      $vcolor = Colors::C_GREEN;
 324                  }
 325                  if ($ext->isGitControlled()) $status = 'g';
 326                  if ($ext->isBundled()) $status = 'b';
 327                  if ($ext->isEnabled()) {
 328                      $ecolor = Colors::C_BROWN;
 329                  } else {
 330                      $ecolor = Colors::C_DARKGRAY;
 331                      $status .= 'd';
 332                  }
 333              } else {
 334                  $ecolor = null;
 335                  $date = $ext->getLastUpdate();
 336                  $vcolor = null;
 337              }
 338  
 339              if ($filter && strpos($status, $filter) === false) {
 340                  continue;
 341              }
 342  
 343              echo $tr->format(
 344                  [20, 3, 12, '*'],
 345                  [
 346                      $ext->getID(),
 347                      $status,
 348                      $date,
 349                      strip_tags(sprintf(
 350                              $this->getLang('extensionby'),
 351                              $ext->getDisplayName(),
 352                              $this->colors->wrap($ext->getAuthor(), Colors::C_PURPLE))
 353                      )
 354                  ],
 355                  [
 356                      $ecolor,
 357                      Colors::C_YELLOW,
 358                      $vcolor,
 359                      null,
 360                  ]
 361              );
 362  
 363              if (!$details) continue;
 364  
 365              echo $tr->format(
 366                  [5, '*'],
 367                  ['', $ext->getDescription()],
 368                  [null, Colors::C_CYAN]
 369              );
 370          }
 371      }
 372  }