Merge branch '5.3'
authorMatthias Schmidt <gravatronics@live.com>
Tue, 27 Apr 2021 15:15:28 +0000 (17:15 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Tue, 27 Apr 2021 15:15:28 +0000 (17:15 +0200)
1  2 
wcfsetup/install/files/lib/system/form/builder/field/devtools/project/DevtoolsProjectExcludedPackagesFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/devtools/project/DevtoolsProjectInstructionsFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/devtools/project/DevtoolsProjectOptionalPackagesFormField.class.php
wcfsetup/install/files/lib/system/form/builder/field/devtools/project/DevtoolsProjectRequiredPackagesFormField.class.php
wcfsetup/install/files/lib/system/importer/MediaImporter.class.php

index 6ed90d450b46a579e130b602d91a458aef593713,54087f098835160b94e266b5fef11a4b008b264f..975b36b5a87167f3c4bbb6696ab23b351cb885fa
@@@ -8,85 -6,74 +8,87 @@@ use wcf\system\form\builder\field\TDefa
  
  /**
   * Form field implementation for the excluded packages of a devtools project.
 - * 
 - * @author    Matthias Schmidt
 - * @copyright 2001-2019 WoltLab GmbH
 - * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 - * @package   WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 - * @since     5.2
 + *
 + * @author  Matthias Schmidt
 + * @copyright   2001-2019 WoltLab GmbH
 + * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 + * @package WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 + * @since   5.2
   */
 -class DevtoolsProjectExcludedPackagesFormField extends AbstractFormField {
 -      use TDefaultIdFormField;
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $templateName = '__devtoolsProjectExcludedPackagesFormField';
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $value = [];
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function readValue() {
 -              if ($this->getDocument()->hasRequestData($this->getPrefixedId()) && is_array($this->getDocument()->getRequestData($this->getPrefixedId()))) {
 -                      $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 -              }
 -              else {
 -                      $this->value = [];
 -              }
 -              
 -              return $this;
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function validate() {
 -              // everything is already validated by JavaScript thus we skip
 -              // reporting specific errors and simply remove manipulated values
 -              $excludedPackages = [];
 -              $packageIdentifiers = [];
 -              foreach ($this->getValue() as $package) {
 -                      // ensure that all relevant elements are present
 -                      if (!is_array($package) || !isset($package['packageIdentifier']) || !isset($package['version'])) {
 -                              continue;
 -                      }
 -                      
 -                      // validate package identifier
 -                      if (!Package::isValidPackageName($package['packageIdentifier']) || in_array($package['packageIdentifier'], $packageIdentifiers)) {
 -                              continue;
 -                      }
 -                      
 -                      // validate version
 -                      if ($package['version'] !== '' && !Package::isValidVersion($package['version'])) {
 -                              continue;
 -                      }
 -                      
 -                      $excludedPackages[] = $package;
 -              }
 -              
 -              $this->value($excludedPackages);
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected static function getDefaultId() {
 -              return 'excludedPackages';
 -      }
 +class DevtoolsProjectExcludedPackagesFormField extends AbstractFormField
 +{
 +    use TDefaultIdFormField;
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $templateName = '__devtoolsProjectExcludedPackagesFormField';
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $value = [];
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function readValue()
 +    {
 +        if (
 +            $this->getDocument()->hasRequestData($this->getPrefixedId())
 +            && \is_array($this->getDocument()->getRequestData($this->getPrefixedId()))
 +        ) {
 +            $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 +        } else {
 +            $this->value = [];
 +        }
++
++        return $this;
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function validate()
 +    {
 +        // everything is already validated by JavaScript thus we skip
 +        // reporting specific errors and simply remove manipulated values
 +        $excludedPackages = [];
 +        $packageIdentifiers = [];
 +        foreach ($this->getValue() as $package) {
 +            // ensure that all relevant elements are present
 +            if (!\is_array($package) || !isset($package['packageIdentifier']) || !isset($package['version'])) {
 +                continue;
 +            }
 +
 +            // validate package identifier
 +            if (
 +                !Package::isValidPackageName($package['packageIdentifier'])
 +                || \in_array($package['packageIdentifier'], $packageIdentifiers)
 +            ) {
 +                continue;
 +            }
 +
 +            // validate version
 +            if (
 +                $package['version'] !== ''
 +                && $package['version'] !== '*'
 +                && !Package::isValidVersion($package['version'])
 +            ) {
 +                continue;
 +            }
 +
 +            $excludedPackages[] = $package;
 +        }
 +
 +        $this->value($excludedPackages);
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected static function getDefaultId()
 +    {
 +        return 'excludedPackages';
 +    }
  }
index ade536f769717654410a0e813fbb3b430e099fd2,4cc2d491f5bef5a1cd4cc36e4fa36288409b8872..01281db69ad17d92ac5a9545ca1ae85c29832518
@@@ -14,219 -12,213 +14,221 @@@ use wcf\system\WCF
  
  /**
   * Form field implementation for the instructions of a devtools project.
 - * 
 - * @author    Matthias Schmidt
 - * @copyright 2001-2019 WoltLab GmbH
 - * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 - * @package   WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 - * @since     5.2
 + *
 + * @author  Matthias Schmidt
 + * @copyright   2001-2019 WoltLab GmbH
 + * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 + * @package WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 + * @since   5.2
   */
 -class DevtoolsProjectInstructionsFormField extends AbstractFormField {
 -      use TDefaultIdFormField;
 -      
 -      /**
 -       * list of available applications
 -       * @var null|Application[]
 -       */
 -      protected $applications;
 -      
 -      /**
 -       * list of available package installation plugins
 -       * @var null|PackageInstallationPlugin[]
 -       */
 -      protected $packageInstallationPlugins = null;
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $templateName = '__devtoolsProjectInstructionsFormField';
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $value = [];
 -      
 -      /**
 -       * names of package installation plugins that support the `application`
 -       * attribute
 -       * @var string[]
 -       */
 -      protected static $applicationPips = [
 -              'acpTemplate',
 -              'file',
 -              'script',
 -              'template'
 -      ];
 -      
 -      /**
 -       * Returns the applications for which file-based package installation plugins
 -       * can deliver files.
 -       * 
 -       * @return      Application[]
 -       */
 -      public function getApplications() {
 -              if ($this->applications === null) {
 -                      $this->applications = [];
 -                      foreach (ApplicationHandler::getInstance()->getApplications() as $application) {
 -                              $this->applications[$application->getAbbreviation()] = $application;
 -                      }
 -                      
 -                      uasort($this->applications, function(Application $app1, Application $app2) {
 -                              return $app1->getAbbreviation() <=> $app2->getAbbreviation();
 -                      });
 -              }
 -              
 -              return $this->applications;
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function getHtml() {
 -              if ($this->requiresLabel() && $this->getLabel() === null) {
 -                      throw new \UnexpectedValueException("Form field '{$this->getPrefixedId()}' requires a label.");
 -              }
 -              
 -              $this->removeClass('formError');
 -              
 -              return WCF::getTPL()->fetch(
 -                      $this->templateName,
 -                      'wcf',
 -                      [
 -                              'apps' => $this->getApplications(),
 -                              'field' => $this,
 -                              'packageInstallationPlugins' => $this->getPackageInstallationPlugins(),
 -                      ],
 -                      true
 -              );
 -      }
 -      
 -      /**
 -       * Returns the package installation plugins that can be used for instructions.
 -       * 
 -       * @return      PackageInstallationPlugin[]
 -       */
 -      public function getPackageInstallationPlugins() {
 -              if ($this->packageInstallationPlugins === null) {
 -                      $packageInstallationPluginList = new PackageInstallationPluginList();
 -                      $packageInstallationPluginList->sqlOrderBy = 'pluginName ASC';
 -                      $packageInstallationPluginList->readObjects();
 -                      
 -                      foreach ($packageInstallationPluginList as $packageInstallationPlugin) {
 -                              $this->packageInstallationPlugins[$packageInstallationPlugin->pluginName] = $packageInstallationPlugin;
 -                      }
 -              }
 -              
 -              return $this->packageInstallationPlugins;
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function readValue() {
 -              if ($this->getDocument()->hasRequestData($this->getPrefixedId()) && is_array($this->getDocument()->getRequestData($this->getPrefixedId()))) {
 -                      $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 -              }
 -              else {
 -                      $this->value = [];
 -              }
 -              
 -              return $this;
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function validate() {
 -              // everything is already validated by JavaScript thus we skip
 -              // reporting specific errors and simply remove manipulated values
 -              $this->value(array_filter($this->getValue(), function($instructions) {
 -                      if (!is_array($instructions)) {
 -                              return false;
 -                      }
 -                      
 -                      // ensure that all relevant elements are present
 -                      if (!isset($instructions['type'])) {
 -                              return false;
 -                      }
 -                      if (!isset($instructions['instructions'])) {
 -                              $instructions['instructions'] = [];
 -                      }
 -                      if (!is_array($instructions['instructions'])) {
 -                              return false;
 -                      }
 -                      
 -                      if ($instructions['type'] !== 'install' && $instructions['type'] !== 'update') {
 -                              return false;
 -                      }
 -                      
 -                      if ($instructions['type'] === 'update') {
 -                              if (!isset($instructions['fromVersion'])) {
 -                                      return false;
 -                              }
 -                              
 -                              if (strpos($instructions['fromVersion'], '*') !== false) {
 -                                      if (!Package::isValidVersion(str_replace('*', '0', $instructions['fromVersion']))) {
 -                                              return false;
 -                                      }
 -                              }
 -                              else if (!Package::isValidVersion($instructions['fromVersion'])) {
 -                                      return false;
 -                              }
 -                      }
 -                      
 -                      foreach ($instructions['instructions'] as $instruction) {
 -                              if (!isset($instruction['pip']) || !isset($this->getPackageInstallationPlugins()[$instruction['pip']])) {
 -                                      return false;
 -                              }
 -                              
 -                              if (!empty($instruction['application'])) {
 -                                      if (!isset($this->getApplications()[$instruction['application']])) {
 -                                              return false;
 -                                      }
 -                                      
 -                                      if (!in_array($instruction['pip'], static::$applicationPips)) {
 -                                              return false;
 -                                      }
 -                              }
 -                              
 -                              $instruction['runStandalone'] = $instruction['runStandalone'] ?? 0;
 -                              $instruction['value'] = $instruction['value'] ?? '';
 -                      }
 -                      
 -                      return true;
 -              }));
 -              
 -              // the only thing left to validate is to ensure that there are
 -              // installation instructions
 -              $hasInstallInstructions = false;
 -              foreach ($this->getValue() as $instructions) {
 -                      if ($instructions['type'] === 'install') {
 -                              $hasInstallInstructions = true;
 -                              break;
 -                      }
 -              }
 -              
 -              if (!$hasInstallInstructions) {
 -                      $this->addValidationError(
 -                              new FormFieldValidationError(
 -                                      'noInstallationInstructions',
 -                                      'wcf.acp.devtools.project.instructions.error.noInstallationInstructions'
 -                              )
 -                      );
 -              }
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected static function getDefaultId() {
 -              return 'instructions';
 -      }
 +class DevtoolsProjectInstructionsFormField extends AbstractFormField
 +{
 +    use TDefaultIdFormField;
 +
 +    /**
 +     * list of available applications
 +     * @var null|Application[]
 +     */
 +    protected $applications;
 +
 +    /**
 +     * list of available package installation plugins
 +     * @var null|PackageInstallationPlugin[]
 +     */
 +    protected $packageInstallationPlugins;
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $templateName = '__devtoolsProjectInstructionsFormField';
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $value = [];
 +
 +    /**
 +     * names of package installation plugins that support the `application`
 +     * attribute
 +     * @var string[]
 +     */
 +    protected static $applicationPips = [
 +        'acpTemplate',
 +        'file',
 +        'script',
 +        'template',
 +    ];
 +
 +    /**
 +     * Returns the applications for which file-based package installation plugins
 +     * can deliver files.
 +     *
 +     * @return  Application[]
 +     */
 +    public function getApplications()
 +    {
 +        if ($this->applications === null) {
 +            $this->applications = [];
 +            foreach (ApplicationHandler::getInstance()->getApplications() as $application) {
 +                $this->applications[$application->getAbbreviation()] = $application;
 +            }
 +
 +            \uasort($this->applications, static function (Application $app1, Application $app2) {
 +                return $app1->getAbbreviation() <=> $app2->getAbbreviation();
 +            });
 +        }
 +
 +        return $this->applications;
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function getHtml()
 +    {
 +        if ($this->requiresLabel() && $this->getLabel() === null) {
 +            throw new \UnexpectedValueException("Form field '{$this->getPrefixedId()}' requires a label.");
 +        }
 +
 +        $this->removeClass('formError');
 +
 +        return WCF::getTPL()->fetch(
 +            $this->templateName,
 +            'wcf',
 +            [
 +                'apps' => $this->getApplications(),
 +                'field' => $this,
 +                'packageInstallationPlugins' => $this->getPackageInstallationPlugins(),
 +            ],
 +            true
 +        );
 +    }
 +
 +    /**
 +     * Returns the package installation plugins that can be used for instructions.
 +     *
 +     * @return  PackageInstallationPlugin[]
 +     */
 +    public function getPackageInstallationPlugins()
 +    {
 +        if ($this->packageInstallationPlugins === null) {
 +            $packageInstallationPluginList = new PackageInstallationPluginList();
 +            $packageInstallationPluginList->sqlOrderBy = 'pluginName ASC';
 +            $packageInstallationPluginList->readObjects();
 +
 +            foreach ($packageInstallationPluginList as $packageInstallationPlugin) {
 +                $this->packageInstallationPlugins[$packageInstallationPlugin->pluginName] = $packageInstallationPlugin;
 +            }
 +        }
 +
 +        return $this->packageInstallationPlugins;
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function readValue()
 +    {
 +        if (
 +            $this->getDocument()->hasRequestData($this->getPrefixedId())
 +            && \is_array($this->getDocument()->getRequestData($this->getPrefixedId()))
 +        ) {
 +            $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 +        } else {
 +            $this->value = [];
 +        }
++
++        return $this;
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function validate()
 +    {
 +        // everything is already validated by JavaScript thus we skip
 +        // reporting specific errors and simply remove manipulated values
 +        $this->value(\array_filter($this->getValue(), function ($instructions) {
 +            if (!\is_array($instructions)) {
 +                return false;
 +            }
 +
 +            // ensure that all relevant elements are present
 +            if (!isset($instructions['type'])) {
 +                return false;
 +            }
 +            if (!isset($instructions['instructions'])) {
 +                $instructions['instructions'] = [];
 +            }
 +            if (!\is_array($instructions['instructions'])) {
 +                return false;
 +            }
 +
 +            if ($instructions['type'] !== 'install' && $instructions['type'] !== 'update') {
 +                return false;
 +            }
 +
 +            if ($instructions['type'] === 'update') {
 +                if (!isset($instructions['fromVersion'])) {
 +                    return false;
 +                }
 +
 +                if (\strpos($instructions['fromVersion'], '*') !== false) {
 +                    if (!Package::isValidVersion(\str_replace('*', '0', $instructions['fromVersion']))) {
 +                        return false;
 +                    }
 +                } elseif (!Package::isValidVersion($instructions['fromVersion'])) {
 +                    return false;
 +                }
 +            }
 +
 +            foreach ($instructions['instructions'] as $instruction) {
 +                if (!isset($instruction['pip']) || !isset($this->getPackageInstallationPlugins()[$instruction['pip']])) {
 +                    return false;
 +                }
 +
 +                if (!empty($instruction['application'])) {
 +                    if (!isset($this->getApplications()[$instruction['application']])) {
 +                        return false;
 +                    }
 +
 +                    if (!\in_array($instruction['pip'], static::$applicationPips)) {
 +                        return false;
 +                    }
 +                }
 +
 +                $instruction['runStandalone'] = $instruction['runStandalone'] ?? 0;
 +                $instruction['value'] = $instruction['value'] ?? '';
 +            }
 +
 +            return true;
 +        }));
 +
 +        // the only thing left to validate is to ensure that there are
 +        // installation instructions
 +        $hasInstallInstructions = false;
 +        foreach ($this->getValue() as $instructions) {
 +            if ($instructions['type'] === 'install') {
 +                $hasInstallInstructions = true;
 +                break;
 +            }
 +        }
 +
 +        if (!$hasInstallInstructions) {
 +            $this->addValidationError(
 +                new FormFieldValidationError(
 +                    'noInstallationInstructions',
 +                    'wcf.acp.devtools.project.instructions.error.noInstallationInstructions'
 +                )
 +            );
 +        }
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected static function getDefaultId()
 +    {
 +        return 'instructions';
 +    }
  }
index 47c5d7e5417da75e26ae3d42dae6c9cf8f3ef4b5,e6049e3c174ece845f723032a93f51972cd76d3b..a748d8c8c247ea970fe75b8910ae7abcd28dd7fa
@@@ -8,76 -6,69 +8,78 @@@ use wcf\system\form\builder\field\TDefa
  
  /**
   * Form field implementation for the optional packages of a devtools project.
 - * 
 - * @author    Matthias Schmidt
 - * @copyright 2001-2019 WoltLab GmbH
 - * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 - * @package   WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 - * @since     5.2
 + *
 + * @author  Matthias Schmidt
 + * @copyright   2001-2019 WoltLab GmbH
 + * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 + * @package WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 + * @since   5.2
   */
 -class DevtoolsProjectOptionalPackagesFormField extends AbstractFormField {
 -      use TDefaultIdFormField;
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $templateName = '__devtoolsProjectOptionalPackagesFormField';
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $value = [];
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function readValue() {
 -              if ($this->getDocument()->hasRequestData($this->getPrefixedId()) && is_array($this->getDocument()->getRequestData($this->getPrefixedId()))) {
 -                      $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 -              }
 -              else {
 -                      $this->value = [];
 -              }
 -              
 -              return $this;
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function validate() {
 -              // everything is already validated by JavaScript thus we skip
 -              // reporting specific errors and simply remove manipulated values
 -              $excludedPackages = [];
 -              $packageIdentifiers = [];
 -              foreach ($this->getValue() as $package) {
 -                      // ensure that all relevant elements are present
 -                      if (!is_array($package) || !isset($package['packageIdentifier'])) {
 -                              continue;
 -                      }
 -                      
 -                      // validate package identifier
 -                      if (!Package::isValidPackageName($package['packageIdentifier']) || in_array($package['packageIdentifier'], $packageIdentifiers)) {
 -                              continue;
 -                      }
 -                      
 -                      $excludedPackages[] = $package;
 -              }
 -              
 -              $this->value($excludedPackages);
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected static function getDefaultId() {
 -              return 'optionalPackages';
 -      }
 +class DevtoolsProjectOptionalPackagesFormField extends AbstractFormField
 +{
 +    use TDefaultIdFormField;
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $templateName = '__devtoolsProjectOptionalPackagesFormField';
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $value = [];
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function readValue()
 +    {
 +        if (
 +            $this->getDocument()->hasRequestData($this->getPrefixedId())
 +            && \is_array($this->getDocument()->getRequestData($this->getPrefixedId()))
 +        ) {
 +            $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 +        } else {
 +            $this->value = [];
 +        }
++
++        return $this;
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function validate()
 +    {
 +        // everything is already validated by JavaScript thus we skip
 +        // reporting specific errors and simply remove manipulated values
 +        $optionalPackages = [];
 +        $packageIdentifiers = [];
 +        foreach ($this->getValue() as $package) {
 +            // ensure that all relevant elements are present
 +            if (!\is_array($package) || !isset($package['packageIdentifier'])) {
 +                continue;
 +            }
 +
 +            // validate package identifier
 +            if (
 +                !Package::isValidPackageName($package['packageIdentifier'])
 +                || \in_array($package['packageIdentifier'], $packageIdentifiers)
 +            ) {
 +                continue;
 +            }
 +
 +            $optionalPackages[] = $package;
 +        }
 +
 +        $this->value($optionalPackages);
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected static function getDefaultId()
 +    {
 +        return 'optionalPackages';
 +    }
  }
index ce76205ef6d021a10d47afc402ebedb0ffab2142,4646289b68b8b3ee55dbfa5f3a38d60a6fc8eb38..117290f46753d81526c18a25cce58841d47563a5
@@@ -8,88 -6,76 +8,90 @@@ use wcf\system\form\builder\field\TDefa
  
  /**
   * Form field implementation for the required packages of a devtools project.
 - * 
 - * @author    Matthias Schmidt
 - * @copyright 2001-2019 WoltLab GmbH
 - * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 - * @package   WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 - * @since     5.2
 + *
 + * @author  Matthias Schmidt
 + * @copyright   2001-2019 WoltLab GmbH
 + * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 + * @package WoltLabSuite\Core\System\Form\Builder\Field\Devtools\Project
 + * @since   5.2
   */
 -class DevtoolsProjectRequiredPackagesFormField extends AbstractFormField {
 -      use TDefaultIdFormField;
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $templateName = '__devtoolsProjectRequiredPackagesFormField';
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $value = [];
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function readValue() {
 -              if ($this->getDocument()->hasRequestData($this->getPrefixedId()) && is_array($this->getDocument()->getRequestData($this->getPrefixedId()))) {
 -                      $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 -              }
 -              else {
 -                      $this->value = [];
 -              }
 -              
 -              return $this;
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function validate() {
 -              // everything is already validated by JavaScript thus we skip
 -              // reporting specific errors and simply remove manipulated values
 -              $requiredPackages = [];
 -              $packageIdentifiers = [];
 -              foreach ($this->getValue() as $package) {
 -                      // ensure that all relevant elements are present
 -                      if (!is_array($package) || !isset($package['packageIdentifier']) || !isset($package['minVersion']) || !isset($package['file'])) {
 -                              continue;
 -                      }
 -                      
 -                      // validate package identifier
 -                      if (!Package::isValidPackageName($package['packageIdentifier']) || in_array($package['packageIdentifier'], $packageIdentifiers)) {
 -                              continue;
 -                      }
 -                      
 -                      // validate minimum version
 -                      if ($package['minVersion'] !== '' && !Package::isValidVersion($package['minVersion'])) {
 -                              continue;
 -                      }
 -                      
 -                      $package['file'] = intval($package['file']);
 -                      
 -                      $requiredPackages[] = $package;
 -              }
 -              
 -              $this->value($requiredPackages);
 -      }
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      protected static function getDefaultId() {
 -              return 'requiredPackages';
 -      }
 +class DevtoolsProjectRequiredPackagesFormField extends AbstractFormField
 +{
 +    use TDefaultIdFormField;
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $templateName = '__devtoolsProjectRequiredPackagesFormField';
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $value = [];
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function readValue()
 +    {
 +        if (
 +            $this->getDocument()->hasRequestData($this->getPrefixedId())
 +            && \is_array($this->getDocument()->getRequestData($this->getPrefixedId()))
 +        ) {
 +            $this->value = $this->getDocument()->getRequestData($this->getPrefixedId());
 +        } else {
 +            $this->value = [];
 +        }
++
++        return $this;
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function validate()
 +    {
 +        // everything is already validated by JavaScript thus we skip
 +        // reporting specific errors and simply remove manipulated values
 +        $requiredPackages = [];
 +        $packageIdentifiers = [];
 +        foreach ($this->getValue() as $package) {
 +            // ensure that all relevant elements are present
 +            if (
 +                !\is_array($package)
 +                || !isset($package['packageIdentifier'])
 +                || !isset($package['minVersion'])
 +                || !isset($package['file'])
 +            ) {
 +                continue;
 +            }
 +
 +            // validate package identifier
 +            if (
 +                !Package::isValidPackageName($package['packageIdentifier'])
 +                || \in_array($package['packageIdentifier'], $packageIdentifiers)
 +            ) {
 +                continue;
 +            }
 +
 +            // validate minimum version
 +            if ($package['minVersion'] !== '' && !Package::isValidVersion($package['minVersion'])) {
 +                continue;
 +            }
 +
 +            $package['file'] = \intval($package['file']);
 +
 +            $requiredPackages[] = $package;
 +        }
 +
 +        $this->value($requiredPackages);
 +    }
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    protected static function getDefaultId()
 +    {
 +        return 'requiredPackages';
 +    }
  }
index 6ce637a2146983e74ad065acfc89a61877d03070,0ec022913c72f14fe5395d92d0c81d69f4306cac..1170d65d6a890fa92c14c8f0a42feec4a2c0d3f6
@@@ -13,134 -11,119 +13,129 @@@ use wcf\system\WCF
  /**
   * Imports cms media.
   *
 - * @author    Marcel Werk
 - * @copyright 2001-2019 WoltLab GmbH
 - * @license   GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 - * @package   WoltLabSuite\Core\System\Importer
 + * @author  Marcel Werk
 + * @copyright   2001-2019 WoltLab GmbH
 + * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 + * @package WoltLabSuite\Core\System\Importer
   */
 -class MediaImporter extends AbstractImporter {
 -      /**
 -       * @inheritDoc
 -       */
 -      protected $className = Media::class;
 -      
 -      /**
 -       * @var DefaultUploadFileSaveStrategy
 -       */
 -      private $saveStrategy;
 -      
 -      /**
 -       * @inheritDoc
 -       */
 -      public function import($oldID, array $data, array $additionalData = []) {
 -              $data['userID'] = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.user', $data['userID']);
 -              
 -              $contents = [];
 -              if (!empty($additionalData['contents'])) {
 -                      foreach ($additionalData['contents'] as $languageCode => $contentData) {
 -                              $languageID = 0;
 -                              if (!$languageCode) {
 -                                      if (($language = LanguageFactory::getInstance()->getLanguageByCode($languageCode)) !== null) {
 -                                              $languageID = $language->languageID;
 -                                      }
 -                                      else {
 -                                              continue;
 -                                      }
 -                              }
 -                              
 -                              $contents[$languageID] = [
 -                                      'title' => (!empty($contentData['title']) ? $contentData['title'] : ''),
 -                                      'caption' => (!empty($contentData['caption']) ? $contentData['caption'] : ''),
 -                                      'altText' => (!empty($contentData['altText']) ? $contentData['altText'] : '')
 -                              ];
 -                      }
 -                      if (count($contents) > 1) {
 -                              $data['isMultilingual'] = 1;
 -                      }
 -              }
 -              
 -              // handle language
 -              if (!empty($additionalData['languageCode'])) {
 -                      if (($language = LanguageFactory::getInstance()->getLanguageByCode($additionalData['languageCode'])) !== null) {
 -                              $data['languageID'] = $language->languageID;
 -                      }
 -              }
 -              
 -              // check old id
 -              if (ctype_digit((string)$oldID)) {
 -                      $media = new Media($oldID);
 -                      if (!$media->mediaID) $data['mediaID'] = $oldID;
 -              }
 -              
 -              // category
 -              $categoryID = null;
 -              if (!empty($data['categoryID'])) {
 -                      $categoryID = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.media.category', $data['categoryID']);
 -              }
 -              if ($categoryID !== null) {
 -                      $data['categoryID'] = $categoryID;
 -              }
 -              
 -              // save media
 -              $media = MediaEditor::create($data);
 -              
 -              // check media directory
 -              // and create subdirectory if necessary
 -              $dir = dirname($media->getLocation());
 -              if (!@file_exists($dir)) {
 -                      @mkdir($dir, 0777);
 -              }
 -              
 -              // copy file
 -              try {
 -                      if (!copy($additionalData['fileLocation'], $media->getLocation())) {
 -                              throw new SystemException();
 -                      }
 -              }
 -              catch (SystemException $e) {
 -                      // copy failed; delete media
 -                      $editor = new MediaEditor($media);
 -                      $editor->delete();
 -                      
 -                      return 0;
 -              }
 -              
 -              // save media content
 -              $sql = "INSERT INTO     wcf".WCF_N."_media_content
 -                                      (mediaID, languageID, title, caption, altText)
 -                      VALUES          (?, ?, ?, ?, ?)";
 -              $statement = WCF::getDB()->prepareStatement($sql);
 -              foreach ($contents as $languageID => $contentData) {
 -                      $statement->execute([$media->mediaID, $languageID ?: null, $contentData['title'], $contentData['caption'], $contentData['altText']]);
 -              }
 -              
 -              ImportHandler::getInstance()->saveNewID('com.woltlab.wcf.media', $oldID, $media->mediaID);
 -              return $media->mediaID;
 -      }
 -      
 -      /**
 -       * @return DefaultUploadFileSaveStrategy
 -       */
 -      private function getSaveStrategy() {
 -              if ($this->saveStrategy === null) {
 -                      $this->saveStrategy = new DefaultUploadFileSaveStrategy(MediaAction::class); 
 -              }
 -              
 -              return $this->saveStrategy;
 -      }
 +class MediaImporter extends AbstractImporter
 +{
 +    /**
 +     * @inheritDoc
 +     */
 +    protected $className = Media::class;
 +
 +    /**
 +     * @var DefaultUploadFileSaveStrategy
 +     */
 +    private $saveStrategy;
 +
 +    /**
 +     * @inheritDoc
 +     */
 +    public function import($oldID, array $data, array $additionalData = [])
 +    {
 +        $data['userID'] = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.user', $data['userID']);
 +
 +        $contents = [];
 +        if (!empty($additionalData['contents'])) {
 +            foreach ($additionalData['contents'] as $languageCode => $contentData) {
 +                $languageID = 0;
 +                if (!$languageCode) {
 +                    if (($language = LanguageFactory::getInstance()->getLanguageByCode($languageCode)) !== null) {
 +                        $languageID = $language->languageID;
 +                    } else {
 +                        continue;
 +                    }
 +                }
 +
 +                $contents[$languageID] = [
 +                    'title' => (!empty($contentData['title']) ? $contentData['title'] : ''),
 +                    'caption' => (!empty($contentData['caption']) ? $contentData['caption'] : ''),
 +                    'altText' => (!empty($contentData['altText']) ? $contentData['altText'] : ''),
 +                ];
 +            }
 +            if (\count($contents) > 1) {
 +                $data['isMultilingual'] = 1;
 +            }
 +        }
 +
 +        // handle language
 +        if (!empty($additionalData['languageCode'])) {
 +            if (($language = LanguageFactory::getInstance()->getLanguageByCode($additionalData['languageCode'])) !== null) {
 +                $data['languageID'] = $language->languageID;
 +            }
 +        }
 +
 +        // check old id
 +        if (\ctype_digit((string)$oldID)) {
 +            $media = new Media($oldID);
 +            if (!$media->mediaID) {
 +                $data['mediaID'] = $oldID;
 +            }
 +        }
 +
 +        // category
 +        $categoryID = null;
 +        if (!empty($data['categoryID'])) {
 +            $categoryID = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.media.category', $data['categoryID']);
 +        }
 +        if ($categoryID !== null) {
 +            $data['categoryID'] = $categoryID;
 +        }
 +
 +        // save media
 +        $media = MediaEditor::create($data);
 +
 +        // check media directory
 +        // and create subdirectory if necessary
 +        $dir = \dirname($media->getLocation());
 +        if (!@\file_exists($dir)) {
 +            @\mkdir($dir, 0777);
 +        }
 +
 +        // copy file
 +        try {
 +            if (!\copy($additionalData['fileLocation'], $media->getLocation())) {
 +                throw new SystemException();
 +            }
 +        } catch (SystemException $e) {
 +            // copy failed; delete media
 +            $editor = new MediaEditor($media);
 +            $editor->delete();
 +
 +            return 0;
 +        }
 +
 +        // save media content
 +        $sql = "INSERT INTO wcf" . WCF_N . "_media_content
 +                            (mediaID, languageID, title, caption, altText)
 +                VALUES      (?, ?, ?, ?, ?)";
 +        $statement = WCF::getDB()->prepareStatement($sql);
 +        foreach ($contents as $languageID => $contentData) {
 +            $statement->execute([
 +                $media->mediaID,
 +                $languageID ?: null,
 +                $contentData['title'],
 +                $contentData['caption'],
 +                $contentData['altText'],
 +            ]);
 +        }
 +
-         // create thumbnails
-         if ($media->isImage) {
-             $this->getSaveStrategy()->generateThumbnails($media);
-         }
 +        ImportHandler::getInstance()->saveNewID('com.woltlab.wcf.media', $oldID, $media->mediaID);
 +
 +        return $media->mediaID;
 +    }
 +
 +    /**
 +     * @return DefaultUploadFileSaveStrategy
 +     */
 +    private function getSaveStrategy()
 +    {
 +        if ($this->saveStrategy === null) {
 +            $this->saveStrategy = new DefaultUploadFileSaveStrategy(MediaAction::class);
 +        }
 +
 +        return $this->saveStrategy;
 +    }
  }