TreeController.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2020 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
12 
19 
20 /**
21  * TreeController is used to visualize nodes in a tree view.
22  *
23  * The controller supports the following actions:
24  *
25  * <div class="controller-action">
26  * <div> __Action__ _default_ </div>
27  * <div>
28  * Load the cild nodes of the given Node.
29  * | Parameter | Description
30  * |------------------------|-------------------------
31  * | _in_ `oid` | The object id of the parent Node whose children should be loaded (optional)
32  * | _in_ `sort` | The attribute to sort the children by (optional)
33  * | _in_ `rootTypes` | Name of a configuration value in configuration section 'application', that defines an array of root types of the tree (optional, defaults to 'rootTypes')
34  * | _out_ `list` | An array of associative arrays with keys 'oid', 'displayText', 'isFolder', 'hasChildren'
35  * | __Response Actions__ | |
36  * | `ok` | In all cases
37  * </div>
38  * </div>
39  *
40  * @author ingo herwig <ingo@wemove.com>
41  */
42 class TreeController extends Controller {
43 
44  /**
45  * @see Controller::doExecute()
46  */
47  protected function doExecute($method=null) {
48  $request = $this->getRequest();
49  $response = $this->getResponse();
50 
51  $oidStr = $request->getValue('oid');
52  if ($oidStr == 'root') {
53  // types below root node
54  $objects = $this->getRootTypes();
55  }
56  else {
57  $oid = ObjectId::parse($oidStr);
58  if ($oid != null) {
59  // load children
60  $objects = $this->getChildren($oid);
61  }
62  }
63 
64  // sort nodes if requested
65  if ($request->hasValue('sort')) {
66  $objects = Node::sort($objects, $request->getValue('sort'));
67  }
68 
69  // create response
70  $responseObjects = [];
71  for ($i=0, $count=sizeof($objects); $i<$count; $i++) {
72  $object = $objects[$i];
73  if ($this->isVisible($object)) {
74  $responseObjects[] = $this->getViewNode($object);
75  }
76  }
77  $response->setValue('list', $responseObjects);
78 
79  // success
80  $response->setAction('ok');
81  }
82 
83  /**
84  * Get the children for a given oid.
85  * @param $oid The object id
86  * @return Array of Node instances.
87  */
88  protected function getChildren($oid) {
89  $permissionManager = $this->getPermissionManager();
90  $persistenceFacade = $this->getPersistenceFacade();
91 
92  // check read permission on type
93  $type = $oid->getType();
94  if (!$permissionManager->authorize($type, '', PersistenceAction::READ)) {
95  return [];
96  }
97 
98  $objectsTmp = [];
99  if ($this->isRootTypeNode($oid)) {
100  // load instances of type
101  $objectsTmp = $persistenceFacade->loadObjects($type, BuildDepth::SINGLE);
102  }
103  else {
104  // load children of node
105  if ($permissionManager->authorize($oid, '', PersistenceAction::READ)) {
106  $node = $persistenceFacade->load($oid, 1);
107  if ($node) {
108  $objectsTmp = $node->getChildren();
109  }
110  }
111  }
112 
113  // check read permission on instances
114  $objects = [];
115  foreach ($objectsTmp as $object) {
116  if ($permissionManager->authorize($object->getOID(), '', PersistenceAction::READ)) {
117  $objects[] = $object;
118  }
119  }
120 
121  return $objects;
122  }
123 
124  /**
125  * Get the oids of the root nodes.
126  * @return An array of object ids.
127  */
128  protected function getRootOIDs() {
129  // types below root node
130  return $this->getRootTypes();
131  }
132 
133  /**
134  * Get the view of a Node
135  * @param $node The Node to create the view for
136  * @param $displayText The text to display (will be taken from TreeController::getDisplayText() if not specified) (default: '')
137  * @return An associative array whose keys correspond to Ext.tree.TreeNode config parameters
138  */
139  protected function getViewNode(Node $node, $displayText='') {
140  if (strlen($displayText) == 0) {
141  $displayText = trim($this->getDisplayText($node));
142  }
143  if (strlen($displayText) == 0) {
144  $displayText = '-';
145  }
146  $oid = $node->getOID();
147  $isFolder = $oid->containsDummyIds();
148  $hasChildren = $this->isRootTypeNode($oid) || sizeof($node->getNumChildren()) > 0;
149  return [
150  'oid' => $node->getOID()->__toString(),
151  'displayText' => $displayText,
152  'isFolder' => $isFolder,
153  'hasChildren' => $hasChildren
154  ];
155  }
156 
157  /**
158  * Test if a Node should be displayed in the tree
159  * @param $node Node to display
160  * @return Boolean
161  */
162  protected function isVisible(Node $node) {
163  return true;
164  }
165 
166  /**
167  * Get the display text for a Node
168  * @param $node Node to display
169  * @return The display text.
170  */
171  protected function getDisplayText(Node $node) {
172  if ($this->isRootTypeNode($node->getOID())) {
173  $mapper = $node->getMapper();
174  return $mapper->getTypeDisplayName($this->getMessage());
175  }
176  else {
177  return strip_tags(preg_replace("/[\r\n']/", " ", NodeUtil::getDisplayValue($node)));
178  }
179  }
180 
181  /**
182  * Get all root types
183  * @return Array of Node instances
184  */
185  protected function getRootTypes() {
186  $types = null;
187  $config = $this->getConfiguration();
188 
189  // get root types from configuration
190  // try request value first
191  $request = $this->getRequest();
192  $rootTypeVar = $request->getValue('rootTypes');
193  if ($config->hasValue($rootTypeVar, 'application')) {
194  $types = $config->getValue($rootTypeVar, 'application');
195  if (!is_array($types)) {
196  $types = null;
197  }
198  }
199  if ($types == null) {
200  // fall back to root types
201  $types = $config->hasValue('rootTypes', 'application');
202  }
203 
204  // filter types by read permission
205  $permissionManager = $this->getPermissionManager();
206  $persistenceFacade = $this->getPersistenceFacade();
207  $nodes = [];
208  foreach($types as $type) {
209  if ($permissionManager->authorize($type, '', PersistenceAction::READ)) {
210  $node = $persistenceFacade->create($type, BuildDepth::SINGLE);
211  $nodes[] = $node;
212  }
213  }
214  return $nodes;
215  }
216 
217  /**
218  * Check if the given oid belongs to a root type node
219  * @param $oid The object id
220  * @return Boolean
221  */
222  protected function isRootTypeNode(ObjectId $oid) {
223  if ($oid->containsDummyIds()) {
224  $type = $oid->getType();
225  $rootTypes = $this->getRootTypes();
226  foreach ($rootTypes as $rootType) {
227  if ($rootType->getType() == $type) {
228  return true;
229  }
230  }
231  }
232  return false;
233  }
234 }
235 ?>
containsDummyIds()
Check if this object id contains a dummy id.
Definition: ObjectId.php:247
isVisible(Node $node)
Test if a Node should be displayed in the tree.
getConfiguration()
Get the Configuration instance.
Definition: Controller.php:323
getNumChildren($memOnly=true)
Get the number of children of the Node.
Definition: Node.php:502
static getDisplayValue(Node $node, $language=null)
Get the display value for a Node defined by the 'displayValues' property.
Definition: NodeUtil.php:152
getViewNode(Node $node, $displayText='')
Get the view of a Node.
getDisplayText(Node $node)
Get the display text for a Node.
getChildren($oid)
Get the children for a given oid.
ObjectId is the unique identifier of an object.
Definition: ObjectId.php:28
TreeController is used to visualize nodes in a tree view.
getPermissionManager()
Get the PermissionManager instance.
Definition: Controller.php:291
BuildDepth values are used to define the depth when loading object trees.
Definition: BuildDepth.php:19
getMessage()
Get the Message instance.
Definition: Controller.php:315
getRootOIDs()
Get the oids of the root nodes.
static parse($oid)
Parse a serialized object id string into an ObjectId instance.
Definition: ObjectId.php:135
getType()
Get the type (including namespace)
Definition: ObjectId.php:97
getPersistenceFacade()
Get the PersistenceFacade instance.
Definition: Controller.php:283
getRequest()
Get the Request instance.
Definition: Controller.php:251
Node adds the concept of relations to PersistentObject.
Definition: Node.php:34
Application controllers.
Definition: namespaces.php:3
Controller is the base class of all controllers.
Definition: Controller.php:49
getResponse()
Get the Response instance.
Definition: Controller.php:259
NodeUtil provides services for the Node class.
Definition: NodeUtil.php:28
PersistenceAction values are used to define actions on PersistentObject instances.
isRootTypeNode(ObjectId $oid)
Check if the given oid belongs to a root type node.