[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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

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