‪TYPO3CMS  ‪main
FileNode.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 
21 
27 {
31  protected ‪$targetPermission = '0664';
32 
36  protected ‪$targetContent;
37 
45  public function ‪__construct(array $structure, ‪NodeInterface ‪$parent = null)
46  {
47  if (‪$parent === null) {
49  'File node must have parent',
50  1366927513
51  );
52  }
53  $this->parent = ‪$parent;
54 
55  // Ensure name is a single segment, but not a path like foo/bar or an absolute path /foo
56  if (str_contains($structure['name'], '/')) {
58  'File name must not contain forward slash',
59  1366222207
60  );
61  }
62  $this->name = $structure['name'];
63 
64  if (isset($structure['targetPermission'])) {
65  $this->‪setTargetPermission($structure['targetPermission']);
66  }
67 
68  if (isset($structure['targetContent']) && isset($structure['targetContentFile'])) {
70  'Either targetContent or targetContentFile can be set, but not both',
71  1380364361
72  );
73  }
74 
75  if (isset($structure['targetContent'])) {
76  $this->targetContent = $structure['targetContent'];
77  }
78  if (isset($structure['targetContentFile'])) {
79  if (!is_readable($structure['targetContentFile'])) {
81  'targetContentFile ' . $structure['targetContentFile'] . ' does not exist or is not readable',
82  1380364362
83  );
84  }
85  $fileContent = file_get_contents($structure['targetContentFile']);
86  if ($fileContent === false) {
88  'Error while reading targetContentFile ' . $structure['targetContentFile'],
89  1380364363
90  );
91  }
92  $this->targetContent = $fileContent;
93  }
94  }
95 
103  public function ‪getStatus(): array
104  {
105  $result = [];
106  if (!$this->‪exists()) {
107  $result[] = new ‪FlashMessage(
108  'By using "Try to fix errors" we can try to create it',
109  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' does not exist',
110  ContextualFeedbackSeverity::WARNING
111  );
112  } else {
113  $result = $this->‪getSelfStatus();
114  }
115  return $result;
116  }
117 
125  public function ‪fix(): array
126  {
127  $result = $this->‪fixSelf();
128  return $result;
129  }
130 
136  protected function ‪fixSelf(): array
137  {
138  $result = [];
139  if (!$this->‪exists()) {
140  $resultCreateFile = $this->‪createFile();
141  $result[] = $resultCreateFile;
142  if ($resultCreateFile->getSeverity() === ContextualFeedbackSeverity::OK
143  && $this->targetContent !== null
144  ) {
145  $result[] = $this->‪setContent();
146  if (!$this->‪isPermissionCorrect()) {
147  $result[] = $this->‪fixPermission();
148  }
149  }
150  } elseif (!$this->‪isFile()) {
151  $fileType = @filetype($this->‪getAbsolutePath());
152  if ($fileType) {
153  $messageBody =
154  'The target ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a file,' .
155  ' but is of type ' . $fileType . '. This cannot be fixed automatically. Please investigate.'
156  ;
157  } else {
158  $messageBody =
159  'The target ' . $this->‪getRelativePathBelowSiteRoot() . ' should be a file,' .
160  ' but is of unknown type, probably because an upper level directory does not exist. Please investigate.'
161  ;
162  }
163  $result[] = new ‪FlashMessage(
164  $messageBody,
165  'Path ' . $this->‪getRelativePathBelowSiteRoot() . ' is not a file',
166  ContextualFeedbackSeverity::ERROR
167  );
168  } elseif (!$this->‪isPermissionCorrect()) {
169  $result[] = $this->‪fixPermission();
170  }
171  return $result;
172  }
173 
179  protected function ‪createFile(): ‪FlashMessage
180  {
181  if ($this->‪exists()) {
182  throw new ‪Exception(
183  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' already exists',
184  1367048077
185  );
186  }
187  $result = @touch($this->‪getAbsolutePath());
188  if ($result === true) {
189  return new ‪FlashMessage(
190  '',
191  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' successfully created.'
192  );
193  }
194  return new ‪FlashMessage(
195  'The target file could not be created. There is probably a'
196  . ' group or owner permission problem on the parent directory.',
197  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' not created!',
198  ContextualFeedbackSeverity::ERROR
199  );
200  }
201 
207  protected function ‪getSelfStatus(): array
208  {
209  $result = [];
210  if (!$this->‪isFile()) {
211  $result[] = new ‪FlashMessage(
212  'Path ' . $this->‪getAbsolutePath() . ' should be a file,'
213  . ' but is of type ' . filetype($this->‪getAbsolutePath()),
214  $this->‪getRelativePathBelowSiteRoot() . ' is not a file',
215  ContextualFeedbackSeverity::ERROR
216  );
217  } elseif (!$this->‪isWritable()) {
218  $result[] = new ‪FlashMessage(
219  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' exists, but is not writable.',
220  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' is not writable',
221  ContextualFeedbackSeverity::NOTICE
222  );
223  } elseif (!$this->‪isPermissionCorrect()) {
224  $result[] = new ‪FlashMessage(
225  'Default configured permissions are ' . $this->‪getTargetPermission()
226  . ' but file permissions are ' . $this->‪getCurrentPermission(),
227  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' permissions mismatch',
228  ContextualFeedbackSeverity::NOTICE
229  );
230  }
231  if ($this->‪isFile() && !$this->‪isContentCorrect()) {
232  $result[] = new ‪FlashMessage(
233  'File content is not identical to default content. This file may have been changed manually.'
234  . ' The Install Tool will not overwrite the current version!',
235  'File ' . $this->‪getRelativePathBelowSiteRoot() . ' content differs',
236  ContextualFeedbackSeverity::NOTICE
237  );
238  } else {
239  $result[] = new ‪FlashMessage(
240  'Is a file with the default content and configured permissions of ' . $this->‪getTargetPermission(),
241  'File ' . $this->‪getRelativePathBelowSiteRoot()
242  );
243  }
244  return $result;
245  }
246 
253  protected function ‪isContentCorrect()
254  {
255  $absolutePath = $this->‪getAbsolutePath();
256  if (is_link($absolutePath) || !is_file($absolutePath)) {
257  throw new ‪Exception(
258  'File ' . $absolutePath . ' must exist',
259  1367056363
260  );
261  }
262  $result = false;
263  if ($this->targetContent === null) {
264  $result = true;
265  } else {
266  $targetContentHash = md5($this->targetContent);
267  $currentContentHash = md5((string)file_get_contents($absolutePath));
268  if ($targetContentHash === $currentContentHash) {
269  $result = true;
270  }
271  }
272  return $result;
273  }
274 
280  protected function ‪setContent(): ‪FlashMessage
281  {
282  $absolutePath = $this->‪getAbsolutePath();
283  if (is_link($absolutePath) || !is_file($absolutePath)) {
284  throw new ‪Exception(
285  'File ' . $absolutePath . ' must exist',
286  1367060201
287  );
288  }
289  if ($this->targetContent === null) {
290  throw new ‪Exception(
291  'Target content not defined for ' . $absolutePath,
292  1367060202
293  );
294  }
295  $result = @file_put_contents($absolutePath, $this->targetContent);
296  if ($result !== false) {
297  return new ‪FlashMessage(
298  '',
299  'Set content to ' . $this->‪getRelativePathBelowSiteRoot()
300  );
301  }
302  return new ‪FlashMessage(
303  'Setting content of the file failed for unknown reasons.',
304  'Setting content to ' . $this->‪getRelativePathBelowSiteRoot() . ' failed',
305  ContextualFeedbackSeverity::ERROR
306  );
307  }
308 
314  protected function ‪isFile()
315  {
316  $path = $this->‪getAbsolutePath();
317  return !is_link($path) && is_file($path);
318  }
319 }
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\isPermissionCorrect
‪bool isPermissionCorrect()
Definition: AbstractNode.php:168
‪TYPO3\CMS\Install\FolderStructure\FileNode\fixSelf
‪FlashMessage[] fixSelf()
Definition: FileNode.php:134
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\exists
‪bool exists()
Definition: AbstractNode.php:127
‪TYPO3\CMS\Install\FolderStructure\FileNode\fix
‪FlashMessage[] fix()
Definition: FileNode.php:123
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getCurrentPermission
‪string getCurrentPermission()
Definition: AbstractNode.php:184
‪TYPO3\CMS\Install\FolderStructure\FileNode\setContent
‪setContent()
Definition: FileNode.php:278
‪TYPO3\CMS\Install\FolderStructure
Definition: AbstractNode.php:16
‪TYPO3\CMS\Install\FolderStructure\FileNode\$targetPermission
‪string $targetPermission
Definition: FileNode.php:30
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Install\FolderStructure\FileNode\__construct
‪__construct(array $structure, NodeInterface $parent=null)
Definition: FileNode.php:43
‪TYPO3\CMS\Install\FolderStructure\Exception\InvalidArgumentException
Definition: InvalidArgumentException.php:23
‪TYPO3\CMS\Install\FolderStructure\FileNode\getStatus
‪FlashMessage[] getStatus()
Definition: FileNode.php:101
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\getRelativePathBelowSiteRoot
‪string getRelativePathBelowSiteRoot($path=null)
Definition: AbstractNode.php:207
‪TYPO3\CMS\Install\FolderStructure\AbstractNode\isWritable
‪bool isWritable()
Definition: AbstractNode.php:115
‪TYPO3\CMS\Install\FolderStructure\FileNode
Definition: FileNode.php:27
‪TYPO3\CMS\Install\FolderStructure\FileNode\$targetContent
‪string null $targetContent
Definition: FileNode.php:34
‪TYPO3\CMS\Install\FolderStructure\FileNode\isFile
‪bool isFile()
Definition: FileNode.php:312
‪TYPO3\CMS\Install\FolderStructure\FileNode\getSelfStatus
‪FlashMessage[] getSelfStatus()
Definition: FileNode.php:205
‪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\FileNode\isContentCorrect
‪bool isContentCorrect()
Definition: FileNode.php:251
‪TYPO3\CMS\Install\FolderStructure\AbstractNode
Definition: AbstractNode.php:28
‪TYPO3\CMS\Install\FolderStructure\FileNode\createFile
‪createFile()
Definition: FileNode.php:177
‪TYPO3\CMS\Install\FolderStructure\NodeInterface
Definition: NodeInterface.php:24