Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / package / validation / PackageValidationManager.class.php
1 <?php
2 namespace wcf\system\package\validation;
3 use wcf\data\package\installation\plugin\PackageInstallationPluginList;
4 use wcf\data\package\Package;
5 use wcf\system\package\PackageArchive;
6 use wcf\system\SingletonFactory;
7
8 /**
9 * Manages recursive validation of package archives.
10 *
11 * @author Alexander Ebert
12 * @copyright 2001-2014 WoltLab GmbH
13 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14 * @package com.woltlab.wcf
15 * @subpackage system.package.validation
16 * @category Community Framework
17 */
18 class PackageValidationManager extends SingletonFactory {
19 /**
20 * list of known package installation plugins
21 * @var array<string>
22 */
23 protected $packageInstallationPlugins = array();
24
25 /**
26 * package validation archive object
27 * @var \wcf\system\package\validation\PackageValidationArchive
28 */
29 protected $packageValidationArchive = null;
30
31 /**
32 * virtual package list containing package => packageVersion
33 * @var array<string>
34 */
35 protected $virtualPackageList = array();
36
37 /**
38 * @see \wcf\system\SingletonFactory::init()
39 */
40 protected function init() {
41 $pipList = new PackageInstallationPluginList();
42 $pipList->readObjects();
43 foreach ($pipList as $pip) {
44 $this->packageInstallationPlugins[$pip->pluginName] = $pip->className;
45 }
46 }
47
48 /**
49 * Validates given archive for existance and ability to be installed/updated. If you set the
50 * second parameter $deepInspection to "false", the system will only check if the archive
51 * looks fine, this is useful for a rough check during upload when a more detailed check will
52 * be performed afterwards.
53 *
54 * @param string $archive
55 * @param boolean $deepInspection
56 * @return boolean
57 */
58 public function validate($archive, $deepInspection = true) {
59 $this->virtualPackageList = array();
60 $this->packageValidationArchive = new PackageValidationArchive($archive);
61
62 return $this->packageValidationArchive->validate($deepInspection);
63 }
64
65 /**
66 * Returns package validation archive object.
67 *
68 * @return \wcf\system\package\validation\PackageValidationArchive
69 */
70 public function getPackageValidationArchive() {
71 return $this->packageValidationArchive;
72 }
73
74 /**
75 * Adds a virtual package with the corresponding version, if the package is already known,
76 * the higher version number will be stored.
77 *
78 * @param string $package
79 * @param string $packageVersion
80 * @return boolean
81 */
82 public function addVirtualPackage($package, $packageVersion) {
83 if (isset($this->virtualPackageList[$package])) {
84 if (Package::compareVersion($packageVersion, $this->virtualPackageList[$package], '<')) {
85 return false;
86 }
87 }
88
89 $this->virtualPackageList[$package] = $packageVersion;
90
91 return true;
92 }
93
94 /**
95 * Returns the version number of a virtual package or null if it doesn't exist.
96 *
97 * @param string $package
98 * @return string
99 */
100 public function getVirtualPackage($package) {
101 if (isset($this->virtualPackageList[$package])) {
102 return $this->virtualPackageList[$package];
103 }
104
105 return null;
106 }
107
108 /**
109 * Returns the iteratable package archive list.
110 *
111 * @return \RecursiveIteratorIterator
112 */
113 public function getPackageValidationArchiveList() {
114 $packageValidationArchive = new PackageValidationArchive('');
115 $packageValidationArchive->setChildren(array($this->packageValidationArchive));
116
117 return new \RecursiveIteratorIterator($packageValidationArchive, \RecursiveIteratorIterator::SELF_FIRST);
118 }
119
120 /**
121 * Recursively traverses the package validation archives and returns the first exception message.
122 *
123 * @return string
124 */
125 public function getExceptionMessage() {
126 foreach ($this->getPackageValidationArchiveList() as $packageArchive) {
127 if ($packageArchive->getExceptionMessage()) {
128 return $packageArchive->getExceptionMessage();
129 }
130 }
131
132 return '';
133 }
134
135 /**
136 * Validates an instruction against the corresponding package installation plugin.
137 *
138 * Please be aware that unknown PIPs will silently ignored and cause no error.
139 *
140 * @param \wcf\data\package\PackageArchive $archive
141 * @param string $pip
142 * @param string $instruction
143 * @return boolean
144 */
145 public function validatePackageInstallationPluginInstruction(PackageArchive $archive, $pip, $instruction) {
146 if (isset($this->packageInstallationPlugins[$pip])) {
147 return call_user_func(array($this->packageInstallationPlugins[$pip], 'isValid'), $archive, $instruction);
148 }
149
150 return true;
151 }
152 }