291f73ce5dadd1f5ef8d3741469ddab63da9e813
[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\Install\Status;
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 = array();
43
44 /**
45 * Get name
46 *
47 * @return string Name
48 */
49 public function getName() {
50 return $this->name;
51 }
52
53 /**
54 * Get target permission
55 *
56 * Make sure to call octdec on the value when passing this to chmod
57 *
58 * @return string Permissions as a 4 character octal string, i.e. 2775 or 0644
59 */
60 protected function getTargetPermission() {
61 return $this->targetPermission;
62 }
63
64 /**
65 * Set target permission
66 *
67 * @param string $permission Permissions as a 4 character octal string, i.e. 2775 or 0644
68 *
69 * @return void
70 */
71 protected function setTargetPermission($permission) {
72 // Normalize the permission string to "4 characters", padding with leading "0" if necessary:
73 $permission = substr($permission, 0, 4);
74 $permission = str_pad($permission, 4, '0', STR_PAD_LEFT);
75 $this->targetPermission = $permission;
76 }
77
78 /**
79 * Get children
80 *
81 * @return array
82 */
83 protected function getChildren() {
84 return $this->children;
85 }
86
87 /**
88 * Get parent
89 *
90 * @return NULL|NodeInterface
91 */
92 protected function getParent() {
93 return $this->parent;
94 }
95
96 /**
97 * Get absolute path of node
98 *
99 * @return string
100 */
101 public function getAbsolutePath() {
102 return $this->getParent()->getAbsolutePath() . '/' . $this->name;
103 }
104
105 /**
106 * Current node is writable if parent is writable
107 *
108 * @return bool TRUE if parent is writable
109 */
110 public function isWritable() {
111 return $this->getParent()->isWritable();
112 }
113
114 /**
115 * Checks if node exists.
116 * Returns TRUE if it is there, even if it is only a link.
117 * Does not check the type!
118 *
119 * @return bool
120 */
121 protected function exists() {
122 if (@is_link($this->getAbsolutePath())) {
123 return TRUE;
124 } else {
125 return @file_exists($this->getAbsolutePath());
126 }
127 }
128
129 /**
130 * Fix permission if they are not equal to target permission
131 *
132 * @throws Exception
133 * @return \TYPO3\CMS\Install\Status\StatusInterface
134 */
135 protected function fixPermission() {
136 if ($this->isPermissionCorrect()) {
137 throw new Exception(
138 'Permission on ' . $this->getAbsolutePath() . ' are already ok',
139 1366744035
140 );
141 }
142 $result = @chmod($this->getAbsolutePath(), octdec($this->getTargetPermission()));
143 if ($result === TRUE) {
144 $status = new Status\OkStatus();
145 $status->setTitle('Fixed permission on ' . $this->getRelativePathBelowSiteRoot() . '.');
146 } else {
147 $status = new Status\NoticeStatus();
148 $status->setTitle('Permission change on ' . $this->getRelativePathBelowSiteRoot() . ' not successful');
149 $status->setMessage(
150 'Permissions could not be changed to ' . $this->getTargetPermission() .
151 '. This only is a problem if files and folders within this node cannot be written.'
152 );
153 }
154 return $status;
155 }
156
157 /**
158 * Checks if current permission are identical to target permission
159 *
160 * @return bool
161 */
162 protected function isPermissionCorrect() {
163 if ($this->isWindowsOs()) {
164 return TRUE;
165 }
166 if ($this->getCurrentPermission() === $this->getTargetPermission()) {
167 return TRUE;
168 } else {
169 return FALSE;
170 }
171 }
172
173 /**
174 * Get current permission of node
175 *
176 * @return string, eg. 2775 for dirs, 0664 for files
177 */
178 protected function getCurrentPermission() {
179 $permissions = decoct(fileperms($this->getAbsolutePath()));
180 return substr($permissions, -4);
181 }
182
183 /**
184 * Returns TRUE if OS is windows
185 *
186 * @return bool TRUE on windows
187 */
188 protected function isWindowsOs() {
189 if (TYPO3_OS === 'WIN') {
190 return TRUE;
191 }
192 return FALSE;
193 }
194
195 /**
196 * Cut off PATH_site from given path
197 *
198 * @param string $path Given path
199 * @return string Relative path, but beginning with /
200 * @throws Exception\InvalidArgumentException
201 */
202 protected function getRelativePathBelowSiteRoot($path = NULL) {
203 if (is_null($path)) {
204 $path = $this->getAbsolutePath();
205 }
206 $pathSiteWithoutTrailingSlash = substr(PATH_site, 0, -1);
207 if (strpos($path, $pathSiteWithoutTrailingSlash, 0) !== 0) {
208 throw new \TYPO3\CMS\Install\FolderStructure\Exception\InvalidArgumentException(
209 'PATH_site is not first part of given path',
210 1366398198
211 );
212 }
213 $relativePath = substr($path, strlen($pathSiteWithoutTrailingSlash), strlen($path));
214 // Add a forward slash again, so we don't end up with an empty string
215 if (strlen($relativePath) === 0) {
216 $relativePath = '/';
217 }
218 return $relativePath;
219 }
220
221 }