‪TYPO3CMS  ‪main
DirectoryNode.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
22 
28 {
32  protected ‪$targetPermission = '2775';
33 
41  public function ‪__construct(array $structure, ‪NodeInterface ‪$parent = null)
42  {
43  if (‪$parent === null) {
45  'Node must have parent',
46  1366222203
47  );
48  }
49  $this->parent = ‪$parent;
50 
51  // Ensure name is a single segment, but not a path like foo/bar or an absolute path /foo
52  if (str_contains($structure['name'], '/')) {
54  'Directory name must not contain forward slash',
55  1366226639
56  );
57  }
58  $this->name = $structure['name'];
59 
60  if (isset($structure['targetPermission'])) {
61  $this->‪setTargetPermission($structure['targetPermission']);
62  }
63 
64  if (array_key_exists('children', $structure)) {
65  $this->‪createChildren($structure['children']);
66  }
67  }
68 
74  public function ‪getStatus(): array
75  {
76  $result = [];
77  if (!$this->‪exists()) {
78  $status = new ‪FlashMessage(
79  'The Install Tool can try to create it',
80  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' does not exist',
81  ContextualFeedbackSeverity::WARNING
82  );
83  $result[] = $status;
84  } else {
85  $result = $this->‪getSelfStatus();
86  }
87  $result = array_merge($result, $this->‪getChildrenStatus());
88  return $result;
89  }
90 
96  public function ‪isWritable()
97  {
98  $result = true;
99  if (!$this->‪exists()) {
100  $result = false;
101  } elseif (!$this->‪canFileBeCreated()) {
102  $result = false;
103  }
104  return $result;
105  }
106 
114  public function ‪fix(): array
115  {
116  $result = $this->‪fixSelf();
117  foreach ($this->children as $child) {
119  $result = array_merge($result, $child->fix());
120  }
121  return $result;
122  }
123 
133  protected function ‪fixSelf()
134  {
135  $result = [];
136  if (!$this->‪exists()) {
137  $resultCreateDirectory = $this->‪createDirectory();
138  $result[] = $resultCreateDirectory;
139  if ($resultCreateDirectory->getSeverity() === ContextualFeedbackSeverity::OK &&
140  !$this->isPermissionCorrect()
141  ) {
142  $result[] = $this->‪fixPermission();
143  }
144  } elseif (!$this->‪isWritable()) {
145  // If directory is not writable, we might have permissions to fix that
146  // Try it:
147  $result[] = $this->‪fixPermission();
148  } elseif (!$this->‪isDirectory()) {
149  $fileType = @filetype($this->‪getAbsolutePath());
150  if ($fileType) {
151  $messageBody =
152  'The target ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a directory,' .
153  ' but is of type ' . $fileType . '. This cannot be fixed automatically. Please investigate.'
154  ;
155  } else {
156  $messageBody =
157  'The target ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a directory,' .
158  ' but is of unknown type, probably because an upper level directory does not exist. Please investigate.'
159  ;
160  }
161  $result[] = new ‪FlashMessage(
162  $messageBody,
163  'Path ' . $this->‪getRelativePathBelowSiteRoot() . ' is not a directory',
164  ContextualFeedbackSeverity::ERROR
165  );
166  }
167  return $result;
168  }
169 
175  protected function ‪createDirectory(): ‪FlashMessage
176  {
177  if ($this->‪exists()) {
178  throw new ‪Exception(
179  'Directory ' . $this->‪getAbsolutePath() . ' already exists',
180  1366740091
181  );
182  }
183  $result = @mkdir($this->‪getAbsolutePath());
184  if ($result === true) {
185  return new ‪FlashMessage(
186  '',
187  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' successfully created.'
188  );
189  }
190  return new ‪FlashMessage(
191  'The target directory could not be created. There is probably a'
192  . ' group or owner permission problem on the parent directory.',
193  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' not created!',
194  ContextualFeedbackSeverity::ERROR
195  );
196  }
197 
203  protected function ‪getSelfStatus(): array
204  {
205  $result = [];
206  if (!$this->‪isDirectory()) {
207  $result[] = new ‪FlashMessage(
208  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a directory,'
209  . ' but is of type ' . filetype($this->‪getAbsolutePath()),
210  $this->‪getRelativePathBelowSiteRoot() . ' is not a directory',
211  ContextualFeedbackSeverity::ERROR
212  );
213  } elseif (!$this->‪isWritable()) {
214  $result[] = new ‪FlashMessage(
215  'Path ' . $this->‪getAbsolutePath() . ' exists, but no file underneath it'
216  . ' can be created.',
217  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' is not writable',
218  ContextualFeedbackSeverity::ERROR
219  );
220  } elseif (!$this->‪isPermissionCorrect()) {
221  $result[] = new ‪FlashMessage(
222  'Default configured permissions are ' . $this->‪getTargetPermission()
223  . ' but current permissions are ' . $this->‪getCurrentPermission(),
224  'Directory ' . $this->‪getRelativePathBelowSiteRoot() . ' permissions mismatch',
225  ContextualFeedbackSeverity::NOTICE
226  );
227  } else {
228  $result[] = new ‪FlashMessage(
229  'Is a directory with the configured permissions of ' . $this->‪getTargetPermission(),
230  'Directory ' . $this->‪getRelativePathBelowSiteRoot()
231  );
232  }
233  return $result;
234  }
235 
241  protected function ‪getChildrenStatus(): array
242  {
243  $result = [];
244  foreach ($this->children as $child) {
246  $result = array_merge($result, $child->getStatus());
247  }
248  return $result;
249  }
250 
256  protected function ‪canFileBeCreated()
257  {
258  $testFileName = ‪StringUtility::getUniqueId('installToolTest_');
259  $result = @touch($this->‪getAbsolutePath() . '/' . $testFileName);
260  if ($result === true) {
261  unlink($this->‪getAbsolutePath() . '/' . $testFileName);
262  }
263  return $result;
264  }
265 
271  protected function ‪isDirectory()
272  {
273  $path = $this->‪getAbsolutePath();
274  return !@is_link($path) && @is_dir($path);
275  }
276 
283  protected function ‪createChildren(array $structure)
284  {
285  foreach ($structure as $child) {
286  if (!array_key_exists('type', $child)) {
287  throw new ‪InvalidArgumentException(
288  'Child must have type',
289  1366222204
290  );
291  }
292  if (!array_key_exists('name', $child)) {
293  throw new ‪InvalidArgumentException(
294  'Child must have name',
295  1366222205
296  );
297  }
298  ‪$name = $child['name'];
299  foreach ($this->children as $existingChild) {
301  if ($existingChild->getName() === ‪$name) {
302  throw new ‪InvalidArgumentException(
303  'Child name must be unique',
304  1366222206
305  );
306  }
307  }
308  $this->children[] = new $child['type']($child, $this);
309  }
310  }
311 }
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\isPermissionCorrect
‪bool isPermissionCorrect()
Definition: AbstractNode.php:168
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\exists
‪bool exists()
Definition: AbstractNode.php:127
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\getSelfStatus
‪FlashMessage[] getSelfStatus()
Definition: DirectoryNode.php:202
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getCurrentPermission
‪string getCurrentPermission()
Definition: AbstractNode.php:184
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\isWritable
‪bool isWritable()
Definition: DirectoryNode.php:95
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\createDirectory
‪createDirectory()
Definition: DirectoryNode.php:174
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode
Definition: DirectoryNode.php:28
‪TYPO3\CMS\Install\FolderStructure
Definition: AbstractNode.php:16
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\isDirectory
‪bool isDirectory()
Definition: DirectoryNode.php:270
‪TYPO3\CMS\Install\FolderStructure\Exception\InvalidArgumentException
Definition: InvalidArgumentException.php:23
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\getStatus
‪FlashMessage[] getStatus()
Definition: DirectoryNode.php:73
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\canFileBeCreated
‪bool canFileBeCreated()
Definition: DirectoryNode.php:255
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getRelativePathBelowSiteRoot
‪string getRelativePathBelowSiteRoot($path=null)
Definition: AbstractNode.php:207
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\fix
‪FlashMessage[] fix()
Definition: DirectoryNode.php:113
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\$targetPermission
‪string $targetPermission
Definition: DirectoryNode.php:31
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\$name
‪string $name
Definition: AbstractNode.php:31
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:27
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\setTargetPermission
‪setTargetPermission($permission)
Definition: AbstractNode.php:72
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getTargetPermission
‪string getTargetPermission()
Definition: AbstractNode.php:62
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\fixPermission
‪fixPermission()
Definition: AbstractNode.php:140
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getAbsolutePath
‪string getAbsolutePath()
Definition: AbstractNode.php:105
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\$parent
‪NodeInterface null $parent
Definition: AbstractNode.php:39
‪TYPO3\CMS\Install\FolderStructure\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\__construct
‪__construct(array $structure, NodeInterface $parent=null)
Definition: DirectoryNode.php:40
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\createChildren
‪createChildren(array $structure)
Definition: DirectoryNode.php:282
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\getChildrenStatus
‪FlashMessage[] getChildrenStatus()
Definition: DirectoryNode.php:240
‪TYPO3\CMS\Install\FolderStructure\AbstractNode
Definition: AbstractNode.php:28
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Install\FolderStructure\NodeInterface
Definition: NodeInterface.php:24
‪TYPO3\CMS\Install\FolderStructure\DirectoryNode\fixSelf
‪FlashMessage[] fixSelf()
Definition: DirectoryNode.php:132
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57