support app installation via cli
authormutec <webmaster@mysterycode.de>
Sun, 8 Jul 2018 13:36:48 +0000 (15:36 +0200)
committermutec <webmaster@mysterycode.de>
Sun, 8 Jul 2018 13:37:33 +0000 (15:37 +0200)
this implements support for installation of apps via php-cli.
The user will be prompted to provide additional information like installation path, domain and domain path.
Example:
```mysterycode@demo: / $ php cli.php
                                                                           WoltLab Suite (tm) 3.1.4
   Benutzername> Administrator
   Kennwort> **********
   >package install https://update.mysterycode.de/package-file/460/
   Installationsverzeichnis> /guestbook/
   Domain> 499bf03.demo.mysterycode.de:8081
   Pfad> /guestbook/
   100% [###############################################################################################################] Installation abgeschlossen
   >```

wcfsetup/install/files/lib/system/cli/command/PackageCLICommand.class.php

index 2e52a83eaf5b8e0e91162d2706fd16bb5ec6afe9..9ecfa2f9873c2b7de2958362c6d0ff7f3706c668 100644 (file)
@@ -13,8 +13,10 @@ use wcf\system\package\PackageArchive;
 use wcf\system\package\PackageInstallationDispatcher;
 use wcf\system\package\PackageUninstallationDispatcher;
 use wcf\system\CLIWCF;
+use wcf\system\WCF;
 use wcf\util\FileUtil;
 use wcf\util\JSON;
+use wcf\util\StringUtil;
 use Zend\Console\Exception\RuntimeException as ArgvException;
 use Zend\Console\Getopt as ArgvParser;
 use Zend\ProgressBar\Adapter\Console as ConsoleProgressBar;
@@ -35,6 +37,12 @@ class PackageCLICommand implements IArgumentedCLICommand {
         */
        protected $argv = null;
        
+       /**
+        * required data for app installation
+        * @var string[]
+        */
+       protected $appData = [];
+       
        /**
         * Initializes the argument parser.
         */
@@ -135,15 +143,32 @@ class PackageCLICommand implements IArgumentedCLICommand {
                        if (!$archive->isValidInstall()) {
                                $this->error('noValidInstall');
                        }
-                       else if ($archive->getPackageInfo('isApplication')) {
-                               // applications cannot be installed via CLI
-                               $this->error('cli.installIsApplication');
+                       else if ($archive->getPackageInfo('isApplication') && $archive->hasUniqueAbbreviation()) {
+                               $this->error('noUniqueAbbrevation');
                        }
                        else if ($archive->isAlreadyInstalled()) {
                                $this->error('uniqueAlreadyInstalled');
                        }
-                       else if ($archive->getPackageInfo('isApplication') && $archive->hasUniqueAbbreviation()) {
-                               $this->error('noUniqueAbbrevation');
+                       else if ($archive->getPackageInfo('isApplication') && !$archive->isAlreadyInstalled()) {
+                               $this->appData['abbreviation'] = Package::getAbbreviation($archive->getPackageInfo('name'));
+                               
+                               $directory = CLIWCF::getReader()->readLine(WCF::getLanguage()->get('wcf.acp.package.packageDir.input').'> ');
+                               if ($directory === null) exit;
+                               $directory = StringUtil::trim($directory);
+                               $this->appData['installationDirectory'] = FileUtil::removeTrailingSlash(FileUtil::addTrailingSlash($directory));
+                               
+                               if (file_exists($directory . 'global.php')) {
+                                       $this->error('directoryAlreadyInUse');
+                               }
+                               
+                               $domain = CLIWCF::getReader()->readLine(WCF::getLanguage()->get('wcf.acp.application.domainName').'> ');
+                               if ($domain === null) exit;
+                               $this->appData['domainName'] = StringUtil::trim($domain);
+                               $this->appData['cookieDomain'] = $this->appData['domainName'];
+                               
+                               $domainPath = CLIWCF::getReader()->readLine(WCF::getLanguage()->get('wcf.acp.application.domainPath').'> ');
+                               if ($domainPath === null) exit;
+                               $this->appData['domainPath'] = StringUtil::trim($domainPath);
                        }
                }
                
@@ -158,7 +183,8 @@ class PackageCLICommand implements IArgumentedCLICommand {
                        'packageName' => $archive->getLocalizedPackageInfo('packageName'),
                        'packageID' => ($package !== null) ? $package->packageID : null,
                        'archive' => $file,
-                       'action' => $package !== null ? 'update' : 'install'
+                       'action' => $package !== null ? 'update' : 'install',
+                       'isApplication' => ($package !== null) ? $package->isApplication : intval($archive->getPackageInfo('isApplication'))
                ]);
                
                // PackageInstallationDispatcher::openQueue()
@@ -300,6 +326,14 @@ class PackageCLICommand implements IArgumentedCLICommand {
                                
                                case 'install':
                                        // InstallPackageAction::stepInstall()
+                                       // workaround for app installation via CLI
+                                       if (!empty($this->appData)) {
+                                               WCF::getSession()->register('__wcfSetup_directories', [
+                                                       $this->appData['abbreviation'] => $this->appData['installationDirectory']
+                                               ]);
+                                               if (empty($_SERVER['HTTP_HOST'])) $_SERVER['HTTP_HOST'] = $this->appData['domainName'];
+                                       }
+                                       
                                        $step_ = $installation->install($node);
                                        $queueID = $installation->nodeBuilder->getQueueByNode($installation->queue->processNo, $step_->getNode());