4f7b8628649d1eb658070909b6321ed40f7f939b
[Packages/TYPO3.CMS.git] / typo3 / sysext / version / Classes / Dependency / ElementEntity.php
1 <?php
2 namespace TYPO3\CMS\Version\Dependency;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Oliver Hader <oliver@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the text file GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * Object to hold information on a dependent database element in abstract.
31 */
32 class ElementEntity {
33
34 const REFERENCES_ChildOf = 'childOf';
35 const REFERENCES_ParentOf = 'parentOf';
36 const EVENT_Construct = 'TYPO3\\CMS\\Version\\Dependency\\ElementEntity::construct';
37 const EVENT_CreateChildReference = 'TYPO3\\CMS\\Version\\Dependency\\ElementEntity::createChildReference';
38 const EVENT_CreateParentReference = 'TYPO3\\CMS\\Version\\Dependency\\ElementEntity::createParentReference';
39 const RESPONSE_Skip = 'TYPO3\\CMS\\Version\\Dependency\\ElementEntity->skip';
40
41 /**
42 * @var bool
43 */
44 protected $invalid = FALSE;
45
46 /**
47 * @var string
48 */
49 protected $table;
50
51 /**
52 * @var integer
53 */
54 protected $id;
55
56 /**
57 * @var array
58 */
59 protected $data;
60
61 /**
62 * @var array
63 */
64 protected $record;
65
66 /**
67 * @var \TYPO3\CMS\Version\Dependency\DependencyResolver
68 */
69 protected $dependency;
70
71 /**
72 * @var array
73 */
74 protected $children;
75
76 /**
77 * @var array
78 */
79 protected $parents;
80
81 /**
82 * @var boolean
83 */
84 protected $traversingParents = FALSE;
85
86 /**
87 * @var \TYPO3\CMS\Version\Dependency\ElementEntity
88 */
89 protected $outerMostParent;
90
91 /**
92 * @var array
93 */
94 protected $nestedChildren;
95
96 /**
97 * Creates this object.
98 *
99 * @param string $table
100 * @param integer $id
101 * @param array $data (optional)
102 * @param \TYPO3\CMS\Version\Dependency\DependencyResolver $dependency
103 */
104 public function __construct($table, $id, array $data = array(), \TYPO3\CMS\Version\Dependency\DependencyResolver $dependency) {
105 $this->table = $table;
106 $this->id = (int)$id;
107 $this->data = $data;
108 $this->dependency = $dependency;
109 $this->dependency->executeEventCallback(self::EVENT_Construct, $this);
110 }
111
112 /**
113 * @param bool $invalid
114 */
115 public function setInvalid($invalid) {
116 $this->invalid = (bool)$invalid;
117 }
118
119 /**
120 * @return bool
121 */
122 public function isInvalid() {
123 return $this->invalid;
124 }
125
126 /**
127 * Gets the table.
128 *
129 * @return string
130 */
131 public function getTable() {
132 return $this->table;
133 }
134
135 /**
136 * Gets the id.
137 *
138 * @return integer
139 */
140 public function getId() {
141 return $this->id;
142 }
143
144 /**
145 * Sets the id.
146 *
147 * @param int $id
148 */
149 public function setId($id) {
150 $this->id = (int)$id;
151 }
152
153 /**
154 * Gets the data.
155 *
156 * @return array
157 */
158 public function getData() {
159 return $this->data;
160 }
161
162 /**
163 * Gets a value for a particular key from the data.
164 *
165 * @param string $key
166 * @return mixed
167 */
168 public function getDataValue($key) {
169 $result = NULL;
170 if ($this->hasDataValue($key)) {
171 $result = $this->data[$key];
172 }
173 return $result;
174 }
175
176 /**
177 * Sets a value for a particular key in the data.
178 *
179 * @param string $key
180 * @param mixed $value
181 * @return void
182 */
183 public function setDataValue($key, $value) {
184 $this->data[$key] = $value;
185 }
186
187 /**
188 * Determines whether a particular key holds data.
189 *
190 * @param string $key
191 * @return
192 */
193 public function hasDataValue($key) {
194 return isset($this->data[$key]);
195 }
196
197 /**
198 * Converts this object for string representation.
199 *
200 * @return string
201 */
202 public function __toString() {
203 return self::getIdentifier($this->table, $this->id);
204 }
205
206 /**
207 * Gets the parent dependency object.
208 *
209 * @return \TYPO3\CMS\Version\Dependency\DependencyResolver
210 */
211 public function getDependency() {
212 return $this->dependency;
213 }
214
215 /**
216 * Gets all child references.
217 *
218 * @return array
219 */
220 public function getChildren() {
221 if (!isset($this->children)) {
222 $this->children = array();
223 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_refindex', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->table, 'sys_refindex') . ' AND recuid=' . $this->id . ' AND workspace=' . $this->dependency->getWorkspace(), '', 'sorting');
224 if (is_array($rows)) {
225 foreach ($rows as $row) {
226 $arguments = array('table' => $row['ref_table'], 'id' => $row['ref_uid'], 'field' => $row['field'], 'scope' => self::REFERENCES_ChildOf);
227 $callbackResponse = $this->dependency->executeEventCallback(self::EVENT_CreateChildReference, $this, $arguments);
228 if ($callbackResponse !== self::RESPONSE_Skip) {
229 $this->children[] = $this->getDependency()->getFactory()->getReferencedElement(
230 $row['ref_table'],
231 $row['ref_uid'],
232 $row['field'],
233 array(),
234 $this->getDependency()
235 );
236 }
237 }
238 }
239 }
240 return $this->children;
241 }
242
243 /**
244 * Gets all parent references.
245 *
246 * @return array
247 */
248 public function getParents() {
249 if (!isset($this->parents)) {
250 $this->parents = array();
251 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_refindex', 'ref_table=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->table, 'sys_refindex') . ' AND deleted=0 AND ref_uid=' . $this->id . ' AND workspace=' . $this->dependency->getWorkspace(), '', 'sorting');
252 if (is_array($rows)) {
253 foreach ($rows as $row) {
254 $arguments = array('table' => $row['tablename'], 'id' => $row['recuid'], 'field' => $row['field'], 'scope' => self::REFERENCES_ParentOf);
255 $callbackResponse = $this->dependency->executeEventCallback(self::EVENT_CreateParentReference, $this, $arguments);
256 if ($callbackResponse !== self::RESPONSE_Skip) {
257 $this->parents[] = $this->getDependency()->getFactory()->getReferencedElement(
258 $row['tablename'],
259 $row['recuid'],
260 $row['field'],
261 array(),
262 $this->getDependency()
263 );
264 }
265 }
266 }
267 }
268 return $this->parents;
269 }
270
271 /**
272 * Determines whether there are child or parent references.
273 *
274 * @return boolean
275 */
276 public function hasReferences() {
277 return count($this->getChildren()) > 0 || count($this->getParents()) > 0;
278 }
279
280 /**
281 * Gets the outermost parent element.
282 *
283 * @return \TYPO3\CMS\Version\Dependency\ElementEntity
284 */
285 public function getOuterMostParent() {
286 if (!isset($this->outerMostParent)) {
287 $parents = $this->getParents();
288 if (count($parents) === 0) {
289 $this->outerMostParent = $this;
290 } else {
291 $this->outerMostParent = FALSE;
292 /** @var $parent \TYPO3\CMS\Version\Dependency\ReferenceEntity */
293 foreach ($parents as $parent) {
294 $outerMostParent = $parent->getElement()->getOuterMostParent();
295 if ($outerMostParent instanceof \TYPO3\CMS\Version\Dependency\ElementEntity) {
296 $this->outerMostParent = $outerMostParent;
297 break;
298 } elseif ($outerMostParent === FALSE) {
299 break;
300 }
301 }
302 }
303 }
304 return $this->outerMostParent;
305 }
306
307 /**
308 * Gets nested children accumulated.
309 *
310 * @return array
311 */
312 public function getNestedChildren() {
313 if (!isset($this->nestedChildren)) {
314 $this->nestedChildren = array();
315 $children = $this->getChildren();
316 /** @var $child \TYPO3\CMS\Version\Dependency\ReferenceEntity */
317 foreach ($children as $child) {
318 $this->nestedChildren = array_merge($this->nestedChildren, array($child->getElement()->__toString() => $child->getElement()), $child->getElement()->getNestedChildren());
319 }
320 }
321 return $this->nestedChildren;
322 }
323
324 /**
325 * Converts the object for string representation.
326 *
327 * @param string $table
328 * @param integer $id
329 * @return string
330 */
331 static public function getIdentifier($table, $id) {
332 return $table . ':' . $id;
333 }
334
335 /**
336 * Gets the database record of this element.
337 *
338 * @return array
339 */
340 public function getRecord() {
341 if (empty($this->record['uid']) || (int)$this->record['uid'] !== $this->id) {
342 $this->record = array();
343 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,pid,t3ver_wsid,t3ver_state,t3ver_oid', $this->getTable(), 'uid=' . $this->getId());
344 if (is_array($rows)) {
345 $this->record = $rows[0];
346 }
347 }
348 return $this->record;
349 }
350
351 }