Major overhaul of caching system (work in progress)
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / package / PackageUninstallationDispatcher.class.php
CommitLineData
11ade432
AE
1<?php
2namespace wcf\system\package;
8aa93ba8 3use wcf\data\option\OptionEditor;
2bc9f31d 4use wcf\data\package\installation\queue\PackageInstallationQueue;
11ade432
AE
5use wcf\data\package\Package;
6use wcf\data\package\PackageEditor;
e25413a0 7use wcf\data\package\PackageList;
f1c1fc65 8use wcf\system\application\ApplicationHandler;
b401cd0d 9use wcf\system\cache\builder\PackageCacheBuilder;
11ade432
AE
10use wcf\system\cache\CacheHandler;
11use wcf\system\exception\IllegalLinkException;
12use wcf\system\exception\SystemException;
07e26cb9 13use wcf\system\language\LanguageFactory;
4d4a5125
K
14use wcf\system\package\plugin\ObjectTypePackageInstallationPlugin;
15use wcf\system\package\plugin\SQLPackageInstallationPlugin;
11ade432 16use wcf\system\setup\Uninstaller;
26256aee 17use wcf\system\style\StyleHandler;
2bc9f31d 18use wcf\system\WCF;
f1c1fc65 19use wcf\util\FileUtil;
11ade432
AE
20
21/**
a17de04e 22 * Handles the whole uninstallation process.
9f959ced 23 *
11ade432 24 * @author Alexander Ebert
b401cd0d 25 * @copyright 2001-2013 WoltLab GmbH
11ade432
AE
26 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
27 * @package com.woltlab.wcf
28 * @subpackage system.package
9f959ced 29 * @category Community Framework
11ade432
AE
30 */
31class PackageUninstallationDispatcher extends PackageInstallationDispatcher {
32 /**
33 * Creates a new instance of PackageUninstallationDispatcher.
34 *
9f959ced 35 * @param wcf\data\package\installation\queue\PackageInstallationQueue $queue
11ade432
AE
36 */
37 public function __construct(PackageInstallationQueue $queue) {
38 $this->queue = $queue;
39 $this->nodeBuilder = new PackageUninstallationNodeBuilder($this);
40
41 $this->action = $this->queue->installationType;
42 }
43
44 /**
45 * Uninstalls node components and returns next node.
9f959ced 46 *
11ade432
AE
47 * @param string $node
48 * @return string
49 */
50 public function uninstall($node) {
51 $nodes = $this->nodeBuilder->getNodeData($node);
52
53 // invoke node-specific actions
54 foreach ($nodes as $data) {
55 $nodeData = unserialize($data['nodeData']);
56
57 switch ($data['nodeType']) {
58 case 'package':
59 $this->uninstallPackage($nodeData);
60 break;
61
62 case 'pip':
63 $this->executePIP($nodeData);
64 break;
65 }
66 }
67
68 // mark node as completed
69 $this->nodeBuilder->completeNode($node);
8aa93ba8
AE
70 $node = $this->nodeBuilder->getNextNode($node);
71
07e26cb9 72 // perform post-uninstall actions
8aa93ba8 73 if ($node == '') {
07e26cb9 74 // update options.inc.php if uninstallation is completed
8aa93ba8 75 OptionEditor::resetCache();
f6abc304 76
b401cd0d
AE
77 // clear cache
78 CacheHandler::getInstance()->flushAll();
07e26cb9
AE
79
80 // reset language cache
81 LanguageFactory::getInstance()->clearCache();
82 LanguageFactory::getInstance()->deleteLanguageCache();
83
83c78288
AE
84 // reset stylesheets
85 StyleHandler::resetStylesheets();
86
f1c1fc65
AE
87 // rebuild application paths
88 ApplicationHandler::rebuild();
8aa93ba8 89 }
11ade432 90
82a7de7f
K
91 if ($this->requireRestructureVersionTables) {
92 $this->restructureVersionTables();
93 }
94
11ade432 95 // return next node
8aa93ba8 96 return $node;
11ade432
AE
97 }
98
99 /**
78587b79 100 * @see wcf\system\package\PackageInstallationDispatcher::executePIP()
11ade432
AE
101 */
102 protected function executePIP(array $nodeData) {
103 $pip = new $nodeData['className']($this);
82a7de7f 104
4d4a5125 105 if ($pip instanceof SQLPackageInstallationPlugin || $pip instanceof ObjectTypePackageInstallationPlugin) {
82a7de7f
K
106 $this->requireRestructureVersionTables = true;
107 }
108
11ade432
AE
109 $pip->uninstall();
110 }
111
112 /**
113 * Uninstalls current package.
9f959ced 114 *
11ade432
AE
115 * @param array $nodeData
116 */
117 protected function uninstallPackage(array $nodeData) {
118 PackageEditor::deleteAll(array($this->queue->packageID));
119
a2ad7897
MS
120 // remove localized package infos
121 // todo: license/readme
122 $sql = "DELETE FROM wcf".WCF_N."_language_item
123 WHERE languageItem IN (?, ?)";
124 $statement = WCF::getDB()->prepareStatement($sql);
125 $statement->execute(array(
126 'wcf.acp.package.packageName.package'.$this->queue->packageID,
127 'wcf.acp.package.packageDescription.package'.$this->queue->packageID
128 ));
129
11ade432 130 // reset package cache
b401cd0d 131 PackageCacheBuilder::getInstance()->reset();
11ade432
AE
132 }
133
134 /**
135 * Deletes the given list of files from the target dir.
9f959ced 136 *
39bea7dd
MS
137 * @param string $targetDir
138 * @param string $files
11ade432
AE
139 * @param boolean $deleteEmptyDirectories
140 * @param booelan $deleteEmptyTargetDir
141 */
142 public function deleteFiles($targetDir, $files, $deleteEmptyTargetDir = false, $deleteEmptyDirectories = true) {
143 new Uninstaller($targetDir, $files, $deleteEmptyTargetDir, $deleteEmptyDirectories);
144 }
145
146 /**
147 * Checks whether this package is required by other packages.
148 * If so than a template will be displayed to warn the user that
149 * a further uninstallation will uninstall also the dependent packages
150 */
151 public static function checkDependencies() {
152 $packageID = 0;
36e25b08
MW
153 if (isset($_REQUEST['packageID'])) {
154 $packageID = intval($_REQUEST['packageID']);
11ade432
AE
155 }
156
157 // get packages info
158 try {
159 // create object of uninstalling package
160 $package = new Package($packageID);
161 }
162 catch (SystemException $e) {
163 throw new IllegalLinkException();
164 }
165
166 // can not uninstall wcf package.
167 if ($package->package == 'com.woltlab.wcf') {
168 throw new IllegalLinkException();
169 }
170
171 $dependentPackages = array();
172 $uninstallAvailable = true;
173 if ($package->isRequired()) {
174 // get packages that requires this package
175 $dependentPackages = self::getPackageDependencies($package->packageID);
176 foreach ($dependentPackages as $dependentPackage) {
177 if ($dependentPackage['packageID'] == PACKAGE_ID) {
178 $uninstallAvailable = false;
179 break;
180 }
181 }
182 }
183
184 // add this package to queue
185 self::addQueueEntries($package, $dependentPackages);
186 }
187
11ade432
AE
188 /**
189 * Adds an uninstall entry to the package installation queue.
9f959ced 190 *
11ade432
AE
191 * @param Package $package
192 * @param array $packages
193 */
194 public static function addQueueEntries(Package $package, $packages = array()) {
195 // get new process no
196 $processNo = PackageInstallationQueue::getNewProcessNo();
197
198 // add dependent packages to queue
199 $statementParameters = array();
200 foreach ($packages as $dependentPackage) {
201 $statementParameters[] = array(
202 'packageName' => $dependentPackage['packageName'],
203 'packageID' => $dependentPackage['packageID']
204 );
205 }
206
207 // add uninstalling package to queue
208 $statementParameters[] = array(
209 'packageName' => $package->getName(),
210 'packageID' => $package->packageID
211 );
212
213 // insert queue entry (entries)
214 $sql = "INSERT INTO wcf".WCF_N."_package_installation_queue
215 (processNo, userID, package, packageID, action)
216 VALUES (?, ?, ?, ?, ?)";
217 $statement = WCF::getDB()->prepareStatement($sql);
218 foreach ($statementParameters as $parameter) {
219 $statement->execute(array(
220 $processNo,
221 WCF::getUser()->userID,
222 $parameter['packageName'],
223 $parameter['packageID'],
224 'uninstall'
225 ));
226 }
227
8059b673 228 self::openQueue(0, $processNo);
11ade432
AE
229 }
230}