[TASK] Refactor element dependency resolving
[Packages/TYPO3.CMS.git] / typo3 / sysext / version / Classes / Dependency / DependencyResolver.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 handle and determine dependent references of elements.
31 */
32 class DependencyResolver {
33
34 /**
35 * @var int
36 */
37 protected $workspace = 0;
38
39 /**
40 * @var \TYPO3\CMS\Version\Dependency\DependencyEntityFactory
41 */
42 protected $factory;
43
44 /**
45 * @var array
46 */
47 protected $elements = array();
48
49 /**
50 * @var array
51 */
52 protected $eventCallbacks = array();
53
54 /**
55 * @var boolean
56 */
57 protected $outerMostParentsRequireReferences = FALSE;
58
59 /**
60 * @var array
61 */
62 protected $outerMostParents;
63
64 /**
65 * Sets the current workspace.
66 *
67 * @param int $workspace
68 */
69 public function setWorkspace($workspace) {
70 $this->workspace = (int) $workspace;
71 }
72
73 /**
74 * Gets the current workspace.
75 *
76 * @return int
77 */
78 public function getWorkspace() {
79 return $this->workspace;
80 }
81
82 /**
83 * Sets a callback for a particular event.
84 *
85 * @param string $eventName
86 * @param \TYPO3\CMS\Version\Dependency\EventCallback $callback
87 * @return \TYPO3\CMS\Version\Dependency\DependencyResolver
88 */
89 public function setEventCallback($eventName, \TYPO3\CMS\Version\Dependency\EventCallback $callback) {
90 $this->eventCallbacks[$eventName] = $callback;
91 return $this;
92 }
93
94 /**
95 * Executes a registered callback (if any) for a particular event.
96 *
97 * @param string $eventName
98 * @param object $caller
99 * @param array $callerArguments
100 * @return mixed
101 */
102 public function executeEventCallback($eventName, $caller, array $callerArguments = array()) {
103 if (isset($this->eventCallbacks[$eventName])) {
104 /** @var $callback \TYPO3\CMS\Version\Dependency\EventCallback */
105 $callback = $this->eventCallbacks[$eventName];
106 return $callback->execute($callerArguments, $caller, $eventName);
107 }
108 return NULL;
109 }
110
111 /**
112 * Sets the condition that outermost parents required at least one child or parent reference.
113 *
114 * @param boolean $outerMostParentsRequireReferences
115 * @return \TYPO3\CMS\Version\Dependency\DependencyResolver
116 */
117 public function setOuterMostParentsRequireReferences($outerMostParentsRequireReferences) {
118 $this->outerMostParentsRequireReferences = (bool) $outerMostParentsRequireReferences;
119 return $this;
120 }
121
122 /**
123 * Adds an element to be checked for dependent references.
124 *
125 * @param string $table
126 * @param integer $id
127 * @param array $data
128 * @return \TYPO3\CMS\Version\Dependency\ElementEntity
129 */
130 public function addElement($table, $id, array $data = array()) {
131 $element = $this->getFactory()->getElement($table, $id, $data, $this);
132 $elementName = $element->__toString();
133 $this->elements[$elementName] = $element;
134 return $element;
135 }
136
137 /**
138 * Gets the outermost parents that define complete dependent structure each.
139 *
140 * @return array|\TYPO3\CMS\Version\Dependency\ElementEntity[]
141 */
142 public function getOuterMostParents() {
143 if (!isset($this->outerMostParents)) {
144 $this->outerMostParents = array();
145 /** @var $element \TYPO3\CMS\Version\Dependency\ElementEntity */
146 foreach ($this->elements as $element) {
147 $this->processOuterMostParent($element);
148 }
149 }
150 return $this->outerMostParents;
151 }
152
153 /**
154 * Processes and registers the outermost parents accordant to the registered elements.
155 *
156 * @param \TYPO3\CMS\Version\Dependency\ElementEntity $element
157 * @return void
158 */
159 protected function processOuterMostParent(\TYPO3\CMS\Version\Dependency\ElementEntity $element) {
160 if ($this->outerMostParentsRequireReferences === FALSE || $element->hasReferences()) {
161 $outerMostParent = $element->getOuterMostParent();
162 if ($outerMostParent !== FALSE) {
163 $outerMostParentName = $outerMostParent->__toString();
164 if (!isset($this->outerMostParents[$outerMostParentName])) {
165 $this->outerMostParents[$outerMostParentName] = $outerMostParent;
166 }
167 }
168 }
169 }
170
171 /**
172 * Gets all nested elements (including the parent) of a particular outermost parent element.
173 *
174 * @throws \RuntimeException
175 * @param \TYPO3\CMS\Version\Dependency\ElementEntity $outerMostParent
176 * @return array
177 */
178 public function getNestedElements(\TYPO3\CMS\Version\Dependency\ElementEntity $outerMostParent) {
179 $outerMostParentName = $outerMostParent->__toString();
180 if (!isset($this->outerMostParents[$outerMostParentName])) {
181 throw new \RuntimeException('Element "' . $outerMostParentName . '" was not detected as outermost parent.', 1289318609);
182 }
183 $nestedStructure = array_merge(array($outerMostParentName => $outerMostParent), $outerMostParent->getNestedChildren());
184 return $nestedStructure;
185 }
186
187 /**
188 * Gets the registered elements.
189 *
190 * @return array
191 */
192 public function getElements() {
193 return $this->elements;
194 }
195
196 /**
197 * Gets an instance of the factory to keep track of element or reference entities.
198 *
199 * @return \TYPO3\CMS\Version\Dependency\DependencyEntityFactory
200 */
201 public function getFactory() {
202 if (!isset($this->factory)) {
203 $this->factory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Version\\Dependency\\DependencyEntityFactory');
204 }
205 return $this->factory;
206 }
207
208 }