wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
class.InsertController.php
Go to the documentation of this file.
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2014 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of any of the following licenses
7  * at your choice:
8  *
9  * - GNU Lesser General Public License (LGPL)
10  * http://www.gnu.org/licenses/lgpl.html
11  * - Eclipse Public License (EPL)
12  * http://www.eclipse.org/org/documents/epl-v10.php
13  *
14  * See the license.txt file distributed with this work for
15  * additional information.
16  *
17  * $Id: class.InsertController.php 1462 2014-02-04 23:52:27Z iherwig $
18  */
19 require_once(BASE."wcmf/lib/presentation/class.Controller.php");
20 require_once(BASE."wcmf/lib/persistence/class.PersistenceFacade.php");
21 require_once(BASE."wcmf/lib/model/class.Node.php");
22 require_once(BASE."wcmf/lib/model/class.NodeUtil.php");
23 require_once(BASE."wcmf/lib/model/class.NodeIterator.php");
24 require_once(BASE."wcmf/lib/visitor/class.CommitVisitor.php");
25 
26 /**
27  * @class InsertController
28  * @ingroup Controller
29  * @brief InsertController is a controller that inserts Nodes.
30  *
31  * <b>Input actions:</b>
32  * - unspecified: Create Nodes of given type
33  *
34  * <b>Output actions:</b>
35  * - @em ok In any case
36  *
37  * @param[in] poid The oid of the Node to add the new type to (if needed)
38  * @param[in] newtype The type of Node to create
39  * @param[in] <type:...> A Node instance that defines the values of the new node (optional)
40  * @param[out] oid The object id of the last created Node
41  *
42  * @author ingo herwig <ingo@wemove.com>
43  */
45 {
46  /**
47  * @see Controller::validate()
48  */
49  function validate()
50  {
51  if(!$this->_request->hasValue('newtype'))
52  {
53  $this->appendErrorMsg("No 'newtype' given in data.");
54  return false;
55  }
56  return true;
57  }
58  /**
59  * @see Controller::hasView()
60  */
61  function hasView()
62  {
63  return false;
64  }
65  /**
66  * Add new Nodes to parent Node.
67  * @return Array of given context and action 'ok' in every case.
68  * @see Controller::executeKernel()
69  */
70  function executeKernel()
71  {
72  $persistenceFacade = &PersistenceFacade::getInstance();
73  $nodeUtil = new NodeUtil();
74 
75  // start the persistence transaction
76  $persistenceFacade->startTransaction();
77 
78  // load parent node if a valid poid is given, add to root else
79  $parentNode = null;
80  $possibleChildren = null;
81  $poid = $this->_request->getValue('poid');
83  {
84  $parentNode = &$persistenceFacade->load($poid, BUILDDEPTH_SINGLE);
85  $poidParts = PersistenceFacade::decomposeOID($poid);
86  $parentTemplate = &$persistenceFacade->create($poidParts['type'], 1);
87  $possibleChildren = $nodeUtil->getPossibleChildren($parentNode, $parentTemplate);
88  }
89 
90  // construct child to insert
91  $newType = $this->_request->getValue('newtype');
92  if ($parentNode != null)
93  {
94  // check insertion as child of another object
95  if (!in_array($newType, array_keys($possibleChildren)))
96  {
97  $this->appendErrorMsg(Message::get("%1% does not accept children of type %2%. The parent type is not compatible.", array($poid, $newType)));
98  return true;
99  }
100  else
101  {
102  $template = &$possibleChildren[$newType];
103  if (!$template->getProperty('canCreate'))
104  {
105  $this->appendErrorMsg(Message::get("%1% does not accept children of type %2%. The maximum number of children of that type is reached.", array($poid, $newType)));
106  return true;
107  }
108  }
109  }
110  $newNode = &$persistenceFacade->create($newType, BUILDDEPTH_REQUIRED);
111 
112  // look for a node template in the request parameters
113  $localizationTpl = null;
114  foreach($this->_request->getData() as $key => $value)
115  {
116  if (PersistenceFacade::isValidOID($key) && PersistenceFacade::getOIDParameter($key, 'type') == $newType)
117  {
118  $tpl = &$value;
119 
120  if ($this->isLocalizedRequest())
121  {
122  // copy values from the node template to the localization template for later use
123  $localizationTpl = &$persistenceFacade->create($newType, BUIDLDEPTH_SINGLE);
124  $tpl->copyValues($localizationTpl, array(DATATYPE_ATTRIBUTE));
125  }
126  else
127  {
128  // copy values from the node template to the new node
129  $tpl->copyValues($newNode, array(DATATYPE_ATTRIBUTE));
130  }
131  break;
132  }
133  }
134 
135  if ($this->confirmInsert($newNode) && $parentNode != null)
136  $parentNode->addChild($newNode);
137 
138  $this->modify($newNode);
139  $needCommit = true;
140 
141  // commit changes
142  if ($needCommit)
143  {
144  // commit the new node and its descendants
145  // we need to use the CommitVisitor because many to many objects maybe included
146  $nIter = new NodeIterator($newNode);
147  $cv = new CommitVisitor();
148  $cv->startIterator($nIter);
149  }
150 
151  // if the request is localized, use the localization template as translation
152  if ($this->isLocalizedRequest() && $localizationTpl != null)
153  {
154  $localizationTpl->setOID($newNode->getOID());
155  $localization = Localization::getInstance();
156  $localization->saveTranslation($localizationTpl, $this->_request->getValue('language'));
157  }
158 
159  // after insert
160  $this->afterInsert($newNode);
161 
162  // end the persistence transaction
163  $persistenceFacade->commitTransaction();
164 
165  // return the oid of the inserted node
166  $this->_response->setValue('oid', $newNode->getOID());
167 
168  $this->_response->setAction('ok');
169  return true;
170  }
171  /**
172  * Confirm insert action on given Node. This method is called before modify()
173  * @note subclasses will override this to implement special application requirements.
174  * @param node A reference to the Node to confirm.
175  * @return True/False whether the Node should be inserted [default: true].
176  */
177  function confirmInsert(&$node)
178  {
179  return true;
180  }
181  /**
182  * Modify a given Node before insert action.
183  * @note subclasses will override this to implement special application requirements.
184  * @param node A reference to the Node to modify.
185  * @return True/False whether the Node was modified [default: false].
186  */
187  function modify(&$node)
188  {
189  return false;
190  }
191  /**
192  * Called after insert.
193  * @note subclasses will override this to implement special application requirements.
194  * @param node A reference to the Node inserted.
195  * @note The method is called for all insert candidates even if they are not inserted (use PersistentObject::getState() to confirm).
196  */
197  function afterInsert(&$node) {}
198 }
199 ?>
200 
The CommitVisitor is used to commit the object's changes to the object storage. The objects must impl...
get($message, $parameters=null, $domain='', $lang='')
const DATATYPE_ATTRIBUTE
NodeIterator is used to iterate over a tree/list build of objects using a Depth-First-Algorithm. Classes used with the NodeIterator must implement the getChildren() and getOID() methods. NodeIterator implements the 'Iterator Pattern'. The base class NodeIterator defines the interface for all specialized Iterator classes.
NodeUtil provides services for the Node class. All methods are static.
InsertController is a controller that inserts Nodes.
Controller is the base class of all controllers. If a Controller has a view it is expected to reside ...
decomposeOID($oid, $validate=true)
const BUILDDEPTH_REQUIRED
getOIDParameter($oid, $param, $validate=true)
const BUILDDEPTH_SINGLE