[CLEANUP] The correct case must be used for standard PHP types in phpdoc
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / FolderStructure / AbstractNode.php
1 <?php
2 namespace TYPO3\CMS\Install\FolderStructure;
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
17 use TYPO3\CMS\Core\Messaging\FlashMessage;
18
19 /**
20 * Abstract node implements common methods
21 */
22 abstract class AbstractNode
23 {
24 /**
25 * @var string Name
26 */
27 protected $name = '';
28
29 /**
30 * @var null|string Target permissions for unix, eg. '2775' or '0664' (4 characters string)
31 */
32 protected $targetPermission = null;
33
34 /**
35 * @var null|NodeInterface Parent object of this structure node
36 */
37 protected $parent = null;
38
39 /**
40 * @var array Directories and root may have children, files and link always empty array
41 */
42 protected $children = [];
43
44 /**
45 * Get name
46 *
47 * @return string Name
48 */
49 public function getName()
50 {
51 return $this->name;
52 }
53
54 /**
55 * Get target permission
56 *
57 * Make sure to call octdec on the value when passing this to chmod
58 *
59 * @return string Permissions as a 4 character octal string, i.e. 2775 or 0644
60 */
61 protected function getTargetPermission()
62 {
63 return $this->targetPermission;
64 }
65
66 /**
67 * Set target permission
68 *
69 * @param string $permission Permissions as a 4 character octal string, i.e. 2775 or 0644
70 */
71 protected function setTargetPermission($permission)
72 {
73 // Normalize the permission string to "4 characters", padding with leading "0" if necessary:
74 $permission = substr($permission, 0, 4);
75 $permission = str_pad($permission, 4, '0', STR_PAD_LEFT);
76 $this->targetPermission = $permission;
77 }
78
79 /**
80 * Get children
81 *
82 * @return array
83 */
84 protected function getChildren()
85 {
86 return $this->children;
87 }
88
89 /**
90 * Get parent
91 *
92 * @return null|NodeInterface
93 */
94 protected function getParent()
95 {
96 return $this->parent;
97 }
98
99 /**
100 * Get absolute path of node
101 *
102 * @return string
103 */
104 public function getAbsolutePath()
105 {
106 return $this->getParent()->getAbsolutePath() . '/' . $this->name;
107 }
108
109 /**
110 * Current node is writable if parent is writable
111 *
112 * @return bool TRUE if parent is writable
113 */
114 public function isWritable()
115 {
116 return $this->getParent()->isWritable();
117 }
118
119 /**
120 * Checks if node exists.
121 * Returns TRUE if it is there, even if it is only a link.
122 * Does not check the type!
123 *
124 * @return bool
125 */
126 protected function exists()
127 {
128 if (@is_link($this->getAbsolutePath())) {
129 return true;
130 }
131 return @file_exists($this->getAbsolutePath());
132 }
133
134 /**
135 * Fix permission if they are not equal to target permission
136 *
137 * @throws Exception
138 * @return FlashMessage
139 */
140 protected function fixPermission(): FlashMessage
141 {
142 if ($this->isPermissionCorrect()) {
143 throw new Exception(
144 'Permission on ' . $this->getAbsolutePath() . ' are already ok',
145 1366744035
146 );
147 }
148 $result = @chmod($this->getAbsolutePath(), octdec($this->getTargetPermission()));
149 if ($result === true) {
150 return new FlashMessage(
151 '',
152 'Fixed permission on ' . $this->getRelativePathBelowSiteRoot() . '.'
153 );
154 }
155 return new FlashMessage(
156 'Permissions could not be changed to ' . $this->getTargetPermission()
157 . '. This only is a problem if files and folders within this node cannot be written.',
158 'Permission change on ' . $this->getRelativePathBelowSiteRoot() . ' not successful',
159 FlashMessage::NOTICE
160 );
161 }
162
163 /**
164 * Checks if current permission are identical to target permission
165 *
166 * @return bool
167 */
168 protected function isPermissionCorrect()
169 {
170 if ($this->isWindowsOs()) {
171 return true;
172 }
173 if ($this->getCurrentPermission() === $this->getTargetPermission()) {
174 return true;
175 }
176 return false;
177 }
178
179 /**
180 * Get current permission of node
181 *
182 * @return string, eg. 2775 for dirs, 0664 for files
183 */
184 protected function getCurrentPermission()
185 {
186 $permissions = decoct(fileperms($this->getAbsolutePath()));
187 return substr($permissions, -4);
188 }
189
190 /**
191 * Returns TRUE if OS is windows
192 *
193 * @return bool TRUE on windows
194 */
195 protected function isWindowsOs()
196 {
197 if (TYPO3_OS === 'WIN') {
198 return true;
199 }
200 return false;
201 }
202
203 /**
204 * Cut off PATH_site from given path
205 *
206 * @param string $path Given path
207 * @return string Relative path, but beginning with /
208 * @throws Exception\InvalidArgumentException
209 */
210 protected function getRelativePathBelowSiteRoot($path = null)
211 {
212 if (is_null($path)) {
213 $path = $this->getAbsolutePath();
214 }
215 $pathSiteWithoutTrailingSlash = substr(PATH_site, 0, -1);
216 if (strpos($path, $pathSiteWithoutTrailingSlash, 0) !== 0) {
217 throw new Exception\InvalidArgumentException(
218 'PATH_site is not first part of given path',
219 1366398198
220 );
221 }
222 $relativePath = substr($path, strlen($pathSiteWithoutTrailingSlash), strlen($path));
223 // Add a forward slash again, so we don't end up with an empty string
224 if ($relativePath === '') {
225 $relativePath = '/';
226 }
227 return $relativePath;
228 }
229 }