[BUGFIX] Respect access method with updater in EM
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Utility / UpdateScriptUtility.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16 use TYPO3\CMS\Core\Utility\GeneralUtility;
17
18 /**
19 * Utility to find and execute class.ext_update.php scripts of extensions
20 *
21 * @author Christian Kuhn <lolli@schwarzbu.ch>
22 */
23 class UpdateScriptUtility {
24
25 /**
26 * Returns true, if ext_update class says it wants to run.
27 *
28 * @param string $extensionKey extension key
29 * @return mixed NULL, if update is not available, else update script return
30 */
31 public function executeUpdateIfNeeded($extensionKey) {
32 $this->requireUpdateScript($extensionKey);
33 $scriptObject = new \ext_update;
34 // old em always assumed the method exist, we do so too.
35 // @TODO: Make this smart, let scripts implement interfaces
36 // @TODO: Enforce different update class script names per extension
37 // @TODO: With different class names it would be easily possible to check for updates in list view.
38 $accessReturnValue = $scriptObject->access();
39
40 $result = NULL;
41 if ($accessReturnValue === TRUE) {
42 // @TODO: With current ext_update construct it is impossible
43 // @TODO: to enforce some type of return
44 $result = $scriptObject->main();
45 }
46
47 return $result;
48 }
49
50 /**
51 * Require update script.
52 * Throws exception if update script does not exist, so checkUpdateScriptExists()
53 * should be called before
54 *
55 * @param string $extensionKey
56 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
57 */
58 protected function requireUpdateScript($extensionKey) {
59 if (class_exists('ext_update')) {
60 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(
61 'class ext_update for this run does already exist, requiring impossible',
62 1359748085
63 );
64 }
65
66 $fileLocation = $this->getUpdateFileLocation($extensionKey);
67
68 if (!$this->checkUpdateScriptExists($extensionKey)) {
69 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(
70 'Requested update script of extension does not exist',
71 1359747976
72 );
73
74 }
75 require $fileLocation;
76
77 if (!class_exists('ext_update')) {
78 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(
79 'class.ext_update.php of extension did not declare ext_update class',
80 1359748132
81 );
82 }
83 }
84
85 /**
86 * Checks if an update class file exists.
87 * Does not check if some update is needed.
88 *
89 * @param string $extensionKey Extension key
90 * @return bool True, if there is some update script
91 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
92 */
93 public function checkUpdateScriptExists($extensionKey) {
94 $updateScriptCanBeCalled = FALSE;
95 $updateScript = $this->getUpdateFileLocation($extensionKey);
96 if (file_exists($updateScript)) {
97 // get script contents
98 $scriptSourceCode = GeneralUtility::getUrl($updateScript);
99 // check if it has a namespace
100 if (!preg_match('/<\?php.*namespace\s+([^;]+);.*class/is', $scriptSourceCode, $matches)) {
101 // if no, rename the class with a unique name
102 $className = uniqid('ext_update');
103 $scriptSourceCode = preg_replace('/^\s*class\s+ext_update\s+/m', 'class ' . $className . ' ', $scriptSourceCode);
104 } else {
105 $className = $matches[1] . '\ext_update';
106 }
107 // load class and call access function
108 if (!preg_match('/\?>$/is', $scriptSourceCode)) {
109 $scriptSourceCode .= '?>';
110 }
111 eval('?>' . $scriptSourceCode . '<?php ');
112 if (!class_exists($className)) {
113 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(
114 sprintf('class.ext_update.php of extension "%s" did not declare ext_update class', $extensionKey),
115 1428176468
116 );
117 }
118 $updater = GeneralUtility::makeInstance($className);
119 $updateScriptCanBeCalled = $updater->access();
120 }
121 return $updateScriptCanBeCalled;
122 }
123
124 /**
125 * Determines location of update file.
126 * Does not check if the file exists.
127 *
128 * @param string $extensionKey Extension key
129 * @return string Absolute path to possible update file of extension
130 */
131 protected function getUpdateFileLocation($extensionKey) {
132 return \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName(
133 'EXT:' . $extensionKey . '/class.ext_update.php',
134 FALSE
135 );
136 }
137
138 }