‪TYPO3CMS  9.5
DirectoryNode.php
Go to the documentation of this file.
1 <?php
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 
19 
25 {
29  protected ‪$targetPermission = '2775';
30 
38  public function ‪__construct(array $structure, ‪NodeInterface ‪$parent = null)
39  {
40  if (‪$parent === null) {
41  throw new Exception\InvalidArgumentException(
42  'Node must have parent',
43  1366222203
44  );
45  }
46  $this->parent = ‪$parent;
47 
48  // Ensure name is a single segment, but not a path like foo/bar or an absolute path /foo
49  if (strstr($structure['name'], '/') !== false) {
50  throw new Exception\InvalidArgumentException(
51  'Directory name must not contain forward slash',
52  1366226639
53  );
54  }
55  $this->name = $structure['name'];
56 
57  if (isset($structure['targetPermission'])) {
58  $this->‪setTargetPermission($structure['targetPermission']);
59  }
60 
61  if (array_key_exists('children', $structure)) {
62  $this->‪createChildren($structure['children']);
63  }
64  }
65 
71  public function ‪getStatus(): array
72  {
73  $result = [];
74  if (!$this->‪exists()) {
75  $status = new ‪FlashMessage(
76  'The Install Tool can try to create it',
77  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' does not exist',
79  );
80  $result[] = $status;
81  } else {
82  $result = $this->‪getSelfStatus();
83  }
84  $result = array_merge($result, $this->‪getChildrenStatus());
85  return $result;
86  }
87 
93  public function ‪isWritable()
94  {
95  $result = true;
96  if (!$this->‪exists()) {
97  $result = false;
98  } elseif (!$this->‪canFileBeCreated()) {
99  $result = false;
100  }
101  return $result;
102  }
103 
111  public function ‪fix(): array
112  {
113  $result = $this->‪fixSelf();
114  foreach ($this->children as $child) {
116  $result = array_merge($result, $child->fix());
117  }
118  return $result;
119  }
120 
130  protected function ‪fixSelf()
131  {
132  $result = [];
133  if (!$this->‪exists()) {
134  $resultCreateDirectory = $this->‪createDirectory();
135  $result[] = $resultCreateDirectory;
136  if ($resultCreateDirectory->getSeverity() === ‪FlashMessage::OK &&
137  !$this->isPermissionCorrect()
138  ) {
139  $result[] = $this->‪fixPermission();
140  }
141  } elseif (!$this->‪isWritable()) {
142  // If directory is not writable, we might have permissions to fix that
143  // Try it:
144  $result[] = $this->‪fixPermission();
145  } elseif (!$this->‪isDirectory()) {
146  $fileType = @filetype($this->‪getAbsolutePath());
147  if ($fileType) {
148  $messageBody =
149  'The target ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a directory,' .
150  ' but is of type ' . $fileType . '. This cannot be fixed automatically. Please investigate.'
151  ;
152  } else {
153  $messageBody =
154  'The target ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a directory,' .
155  ' but is of unknown type, probably because an upper level directory does not exist. Please investigate.'
156  ;
157  }
158  $result[] = new ‪FlashMessage(
159  $messageBody,
160  'Path ' . $this->‪getRelativePathBelowSiteRoot() . ' is not a directory',
162  );
163  }
164  return $result;
165  }
166 
173  protected function ‪createDirectory(): ‪FlashMessage
174  {
175  if ($this->‪exists()) {
176  throw new ‪Exception(
177  'Directory ' . $this->‪getAbsolutePath() . ' already exists',
178  1366740091
179  );
180  }
181  $result = @mkdir($this->‪getAbsolutePath());
182  if ($result === true) {
183  return new ‪FlashMessage(
184  '',
185  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' successfully created.'
186  );
187  }
188  return new ‪FlashMessage(
189  'The target directory could not be created. There is probably a'
190  . ' group or owner permission problem on the parent directory.',
191  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' not created!',
193  );
194  }
195 
201  protected function ‪getSelfStatus(): array
202  {
203  $result = [];
204  if (!$this->‪isDirectory()) {
205  $result[] = new ‪FlashMessage(
206  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a directory,'
207  . ' but is of type ' . filetype($this->‪getAbsolutePath()),
208  $this->‪getRelativePathBelowSiteRoot() . ' is not a directory',
210  );
211  } elseif (!$this->‪isWritable()) {
212  $result[] = new ‪FlashMessage(
213  'Path ' . $this->‪getAbsolutePath() . ' exists, but no file underneath it'
214  . ' can be created.',
215  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' is not writable',
217  );
218  } elseif (!$this->‪isPermissionCorrect()) {
219  $result[] = new ‪FlashMessage(
220  'Default configured permissions are ' . $this->‪getTargetPermission()
221  . ' but current permissions are ' . $this->‪getCurrentPermission(),
222  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' permissions mismatch',
224  );
225  } else {
226  $result[] = new ‪FlashMessage(
227  'Is a directory with the configured permissions of ' . $this->‪getTargetPermission(),
228  'Directory ' . $this->‪getRelativePathBelowSiteRoot()
229  );
230  }
231  return $result;
232  }
233 
239  protected function ‪getChildrenStatus(): array
240  {
241  $result = [];
242  foreach ($this->children as $child) {
244  $result = array_merge($result, $child->getStatus());
245  }
246  return $result;
247  }
248 
254  protected function ‪canFileBeCreated()
255  {
256  $testFileName = ‪StringUtility::getUniqueId('installToolTest_');
257  $result = @touch($this->‪getAbsolutePath() . '/' . $testFileName);
258  if ($result === true) {
259  unlink($this->‪getAbsolutePath() . '/' . $testFileName);
260  }
261  return $result;
262  }
263 
269  protected function ‪isDirectory()
270  {
271  $path = $this->‪getAbsolutePath();
272  return !@is_link($path) && @is_dir($path);
273  }
274 
281  protected function ‪createChildren(array $structure)
282  {
283  foreach ($structure as $child) {
284  if (!array_key_exists('type', $child)) {
285  throw new Exception\InvalidArgumentException(
286  'Child must have type',
287  1366222204
288  );
289  }
290  if (!array_key_exists('name', $child)) {
291  throw new Exception\InvalidArgumentException(
292  'Child must have name',
293  1366222205
294  );
295  }
296  ‪$name = $child['name'];
297  foreach ($this->children as $existingChild) {
299  if ($existingChild->getName() === ‪$name) {
300  throw new Exception\InvalidArgumentException(
301  'Child name must be unique',
302  1366222206
303  );
304  }
305  }
306  $this->children[] = new $child['type']($child, $this);
307  }
308  }
309 }
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\isPermissionCorrect
‪bool isPermissionCorrect()
Definition: AbstractNode.php:166
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\exists
‪bool exists()
Definition: AbstractNode.php:124
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\$targetPermission
‪int null $targetPermission
Definition: DirectoryNode.php:28
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\getSelfStatus
‪FlashMessage[] getSelfStatus()
Definition: DirectoryNode.php:200
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\isWritable
‪bool isWritable()
Definition: DirectoryNode.php:92
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode
Definition: DirectoryNode.php:25
‪TYPO3\CMS\Install\FolderStructure
Definition: AbstractNode.php:2
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getCurrentPermission
‪getCurrentPermission()
Definition: AbstractNode.php:182
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\isDirectory
‪bool isDirectory()
Definition: DirectoryNode.php:268
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\getStatus
‪FlashMessage[] getStatus()
Definition: DirectoryNode.php:70
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\canFileBeCreated
‪bool canFileBeCreated()
Definition: DirectoryNode.php:253
‪TYPO3\CMS\Core\Messaging\AbstractMessage\WARNING
‪const WARNING
Definition: AbstractMessage.php:28
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getRelativePathBelowSiteRoot
‪string getRelativePathBelowSiteRoot($path=null)
Definition: AbstractNode.php:205
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\fix
‪FlashMessage[] fix()
Definition: DirectoryNode.php:110
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\fixPermission
‪FlashMessage fixPermission()
Definition: AbstractNode.php:138
‪TYPO3\CMS\Core\Messaging\AbstractMessage\OK
‪const OK
Definition: AbstractMessage.php:27
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\$name
‪string $name
Definition: AbstractNode.php:28
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static string getUniqueId($prefix='')
Definition: StringUtility.php:91
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:22
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\setTargetPermission
‪setTargetPermission($permission)
Definition: AbstractNode.php:69
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getTargetPermission
‪string getTargetPermission()
Definition: AbstractNode.php:59
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\createDirectory
‪FlashMessage createDirectory()
Definition: DirectoryNode.php:172
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getAbsolutePath
‪string getAbsolutePath()
Definition: AbstractNode.php:102
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\$parent
‪NodeInterface null $parent
Definition: AbstractNode.php:36
‪TYPO3\CMS\Install\FolderStructure\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Messaging\AbstractMessage\NOTICE
‪const NOTICE
Definition: AbstractMessage.php:25
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\__construct
‪__construct(array $structure, NodeInterface $parent=null)
Definition: DirectoryNode.php:37
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\createChildren
‪createChildren(array $structure)
Definition: DirectoryNode.php:280
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\getChildrenStatus
‪FlashMessage[] getChildrenStatus()
Definition: DirectoryNode.php:238
‪TYPO3\CMS\Install\FolderStructure\AbstractNode
Definition: AbstractNode.php:25
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:21
‪TYPO3\CMS\Install\FolderStructure\NodeInterface
Definition: NodeInterface.php:23
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:29
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\fixSelf
‪FlashMessage[] fixSelf()
Definition: DirectoryNode.php:129