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