TYPO3 CMS  TYPO3_8-7
LinkNode.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 
18 
22 class LinkNode extends AbstractNode implements NodeInterface
23 {
27  protected $target = '';
28 
36  public function __construct(array $structure, NodeInterface $parent = null)
37  {
38  if (is_null($parent)) {
39  throw new Exception\InvalidArgumentException(
40  'Link node must have parent',
41  1380485700
42  );
43  }
44  $this->parent = $parent;
45 
46  // Ensure name is a single segment, but not a path like foo/bar or an absolute path /foo
47  if (strstr($structure['name'], '/') !== false) {
48  throw new Exception\InvalidArgumentException(
49  'File name must not contain forward slash',
50  1380546061
51  );
52  }
53  $this->name = $structure['name'];
54 
55  if (isset($structure['target']) && $structure['target'] !== '') {
56  $this->target = $structure['target'];
57  }
58  }
59 
68  public function getStatus()
69  {
70  if ($this->isWindowsOs()) {
71  $status = new Status\InfoStatus();
72  $status->setTitle($this->getRelativePathBelowSiteRoot() . ' should be a link, but this support is incomplete for Windows.');
73  $status->setMessage(
74  'This node is not handled for Windows OS and should be checked manually.'
75  );
76  return [$status];
77  }
78 
79  if (!$this->exists()) {
80  $status = new Status\ErrorStatus();
81  $status->setTitle($this->getRelativePathBelowSiteRoot() . ' should be a link, but it does not exist');
82  $status->setMessage('Links cannot be fixed by this system');
83  return [$status];
84  }
85 
86  if (!$this->isLink()) {
87  $status = new Status\WarningStatus();
88  $status->setTitle('Path ' . $this->getRelativePathBelowSiteRoot() . ' is not a link');
89  $type = @filetype($this->getAbsolutePath());
90  if ($type) {
91  $status->setMessage(
92  'The target ' . $this->getRelativePathBelowSiteRoot() . ' should be a link,' .
93  ' but is of type ' . $type . '. This cannot be fixed automatically. Please investigate.'
94  );
95  } else {
96  $status->setMessage(
97  'The target ' . $this->getRelativePathBelowSiteRoot() . ' should be a file,' .
98  ' but is of unknown type, probably because an upper level directory does not exist. Please investigate.'
99  );
100  }
101  return [$status];
102  }
103 
104  if (!$this->isTargetCorrect()) {
105  $status = new Status\ErrorStatus();
106  $status->setTitle($this->getRelativePathBelowSiteRoot() . ' is a link, but link target is not as specified');
107  $status->setMessage(
108  'Link target should be ' . $this->getTarget() . ' but is ' . $this->getCurrentTarget()
109  );
110  return [$status];
111  }
112 
113  $status = new Status\OkStatus();
114  $message = 'Is a link';
115  if ($this->getTarget() !== '') {
116  $message .= ' and correctly points to target ' . $this->getTarget();
117  }
118  $status->setTitle($this->getRelativePathBelowSiteRoot());
119  $status->setMessage($message);
120  return [$status];
121  }
122 
130  public function fix()
131  {
132  return [];
133  }
134 
140  protected function getTarget()
141  {
142  return $this->target;
143  }
144 
151  protected function isLink()
152  {
153  if (!$this->exists()) {
154  throw new Exception\InvalidArgumentException(
155  'Link does not exist',
156  1380556246
157  );
158  }
159  return @is_link($this->getAbsolutePath());
160  }
161 
168  protected function isTargetCorrect()
169  {
170  if (!$this->exists()) {
171  throw new Exception\InvalidArgumentException(
172  'Link does not exist',
173  1380556245
174  );
175  }
176  if (!$this->isLink()) {
177  throw new Exception\InvalidArgumentException(
178  'Node is not a link',
179  1380556247
180  );
181  }
182 
183  $result = false;
184  $expectedTarget = $this->getTarget();
185  if (empty($expectedTarget)) {
186  $result = true;
187  } else {
188  $actualTarget = $this->getCurrentTarget();
189  if ($expectedTarget === rtrim($actualTarget, '/')) {
190  $result = true;
191  }
192  }
193  return $result;
194  }
195 
201  protected function getCurrentTarget()
202  {
203  return readlink($this->getAbsolutePath());
204  }
205 }