Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
LayoutMetadataAdapter.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
42  {
43  protected $viewClassName;
44  protected $moduleClassName;
45  protected $existingMtadata;
46  protected $designerRules;
47  protected $placeableLayoutAttributes;
48  protected $requiredDerivedLayoutAttributeTypes;
49  protected $message;
50  private $placedAttributeNames = array();
51  private $placedDerivedAttributeTypes = array();
52 
59  private $placedDirectAttributeNamesAsElements = array();
60 
69  public function __construct($viewClassName,
70  $moduleClassName,
71  $existingMetadata,
72  DesignerRules $designerRules,
73  $placeableLayoutAttributes,
74  $requiredDerivedLayoutAttributeTypes
75  )
76  {
77  assert('is_string($viewClassName)');
78  assert('is_string($moduleClassName)');
79  assert('is_array($existingMetadata)');
80  assert('is_array($placeableLayoutAttributes)');
81  assert('is_array($requiredDerivedLayoutAttributeTypes)');
82  $this->viewClassName = $viewClassName;
83  $this->moduleClassName = $moduleClassName;
84  $this->existingMetadata = $existingMetadata;
85  $this->designerRules = $designerRules;
86  $this->placeableLayoutAttributes = $placeableLayoutAttributes;
87  $this->requiredDerivedLayoutAttributeTypes = $requiredDerivedLayoutAttributeTypes;
88  }
89 
96  public function setMetadataFromLayout($layout, $savableMetadata)
97  {
98  assert('is_array($savableMetadata)');
99  if (isset($layout['panels']) &&
100  is_array($layout['panels']) &&
101  count($layout['panels']) > 0)
102  {
103  $atLeastOneElementPlaced = false;
104  foreach ($layout['panels'] as $panelKey => $panel)
105  {
106  $panelMetadata = array();
107  if (isset($panel['rows']) && is_array($panel['rows']))
108  {
109  $savableMetadata['panels'][$panelKey] = $this->adaptPanelSettingsToMetadata($panel, $panelMetadata);
110  foreach ($panel['rows'] as $rowKey => $row)
111  {
112  foreach ($row['cells'] as $cellKey => $cell)
113  {
114  $cellMetadata = array();
115  $cellMetadata = $this->adaptCellElementToMetadata($cell['element'], $cellMetadata);
116  $cellMetadata = $this->adaptCellSettingsToMetadata($cell, $cellMetadata);
117  if (isset($cellMetadata['elements']) && count($cellMetadata['elements']) > 0)
118  {
119  $savableMetadata['panels'][$panelKey]['rows'][$rowKey]['cells'][$cellKey] = $cellMetadata;
120  $atLeastOneElementPlaced = true;
121  }
122  }
123  }
124  }
125  else
126  {
127  $savableMetadata['panels'][$panelKey]['rows'] = array();
128  }
129  }
130  if (!$atLeastOneElementPlaced)
131  {
132  $this->message = Zurmo::t('DesignerModule', 'You must have at least one field placed in order to save a layout.');
133  return false;
134  }
135  }
136  else
137  {
138  $this->message = Zurmo::t('DesignerModule', 'You must have at least one panel in order to save a layout.');
139  return false;
140  }
141  if ($this->designerRules->requireAllRequiredFieldsInLayout() && !$this->areAllRequiredAttributesPlaced())
142  {
143  $this->message = Zurmo::t('DesignerModule', 'All required fields must be placed in this layout.');
144  return false;
145  }
146  if ($this->designerRules->requireOnlyUniqueFieldsInLayout() && !$this->areAllPlacedAttributesUnique())
147  {
148  return false;
149  }
150  $viewsToSetMetadataFor = $this->designerRules->getMetadataViewClassNames($this->viewClassName, $this->moduleClassName);
151  foreach ($viewsToSetMetadataFor as $viewClassName)
152  {
153  $viewClassName::setMetadata($this->makeMergedSaveableMetadata($viewClassName, $savableMetadata));
154  }
155  $this->message = $this->resolveSaveLayoutSuccessMessage();
156  return true;
157  }
158 
166  public function resolveMetadataFromSelectedListAttributes($viewClassName, $selectedListAttributes)
167  {
168  assert('is_string($viewClassName)');
169  assert('is_array($selectedListAttributes)');
170  $metadata = array();
171  $metadata['panels'][0] = array('rows' => array());
172  $rowKey = 0;
173  foreach ($selectedListAttributes as $attributeName)
174  {
175  $cell = array('element' => $attributeName);
176  $cellMetadata = array();
177  $cellMetadata = $this->adaptCellElementToMetadata($cell['element'], $cellMetadata);
178  $cellMetadata = $this->adaptCellSettingsToMetadata($cell, $cellMetadata);
179  if (isset($cellMetadata['elements']) && count($cellMetadata['elements']) > 0)
180  {
181  $metadata['panels'][0]['rows'][$rowKey]['cells'][0] = $cellMetadata;
182  }
183  $rowKey++;
184  }
185  return $this->makeMergedSaveableMetadata($viewClassName, $metadata);
186  }
187 
188  protected function makeMergedSaveableMetadata($viewClassName, $savableMetadata)
189  {
190  $metadata = $this->getExistingMetadataToMerge($viewClassName);
191  $metadata['global']['panels'] = $savableMetadata['panels'];
192  if (count($savableMetadata) > 1)
193  {
194  foreach ($savableMetadata as $keyName => $notUsed)
195  {
196  if ($keyName != 'panels')
197  {
198  $metadata['global'][$keyName] = $savableMetadata[$keyName];
199  }
200  }
201  }
202  return $this->designerRules->formatSavableMetadataFromLayout($metadata, $viewClassName);
203  }
204 
205  protected function getExistingMetadataToMerge($viewClassName)
206  {
207  if ($viewClassName == $this->viewClassName)
208  {
209  $existingMetadata = $this->existingMetadata;
210  }
211  else
212  {
213  $existingMetadata = $viewClassName::getMetadata();
214  }
215  return $existingMetadata;
216  }
217 
222  public function getMessage()
223  {
224  return $this->message;
225  }
226 
227  protected function adaptCellElementToMetadata($elementName, $cellMetadata)
228  {
229  assert('is_string($elementName)');
230  $derivedAttributes = $this->getDerivedAttributesFromMetadata();
231  $placeElement = false;
232  if (in_array($elementName, $derivedAttributes))
233  {
234  $element = array('attributeName' => 'null', 'type' => $elementName); // Not Coding Standard
235  $elementClassName = $elementName . 'Element';
236  $attributesUsed = $elementClassName::getModelAttributeNames();
237  $this->placedAttributeNames = array_merge($this->placedAttributeNames, $attributesUsed);
238  $this->placedDerivedAttributeTypes[] = $elementName;
239  $this->placedDirectAttributeNamesAsElements = array_merge($this->placedDirectAttributeNamesAsElements,
240  $attributesUsed);
241  $placeElement = true;
242  }
243  elseif (isset($this->placeableLayoutAttributes[$elementName]) &&
244  $this->placeableLayoutAttributes[$elementName]['elementType'] == 'DropDownDependency')
245  {
246  $moduleClassName = $this->moduleClassName;
247  $modelClassName = $moduleClassName::getPrimaryModelName();
249  getByNameAndModelClassName($elementName, $modelClassName);
250  $this->placedAttributeNames = array_merge($this->placedAttributeNames,
251  $metadata->getUsedAttributeNames());
252  $this->placedAttributeNames[] = $elementName;
253  $this->placedDirectAttributeNamesAsElements[] = $elementName;
254  $element = array(
255  'attributeName' => $elementName,
256  'type' => $this->placeableLayoutAttributes[$elementName]['elementType']
257  );
258  $placeElement = true;
259  }
260  elseif (isset($this->placeableLayoutAttributes[$elementName]))
261  {
262  $element = array(
263  'attributeName' => $elementName,
264  'type' => $this->placeableLayoutAttributes[$elementName]['elementType']
265  );
266  $this->placedAttributeNames[] = $elementName;
267  $this->placedDirectAttributeNamesAsElements[] = $elementName;
268  $placeElement = true;
269  }
270  else
271  {
272  if ($this->designerRules->shouldPlaceNullElement())
273  {
274  $element = array('attributeName' => null, 'type' => 'Null'); // Not Coding Standard
275  $placeElement = true;
276  }
277  }
278  if ($placeElement)
279  {
280  $cellMetadata['elements'][] = $element;
281  }
282  return $cellMetadata;
283  }
284 
285  protected function adaptPanelSettingsToMetadata($panel, $panelMetadata)
286  {
287  assert('is_array($panel)');
288  assert('isset($panel["rows"])');
289  $settingsAttributes = $this->designerRules->getPanelSettingsAttributes();
290  foreach ($settingsAttributes as $elementInformation)
291  {
292  $elementclassname = $elementInformation['type'] . 'LayoutSettingElement';
293  $element = new $elementclassname($elementInformation['attributeName']);
294  $panelMetadata = $element->processToMetadata($panel, $panelMetadata);
295  }
296  return $panelMetadata;
297  }
298 
299  protected function adaptCellSettingsToMetadata($cell, $cellMetadata)
300  {
301  assert('is_array($cell)');
302  assert('isset($cell["element"])');
303  $settingsAttributes = $this->designerRules->getCellSettingsAttributes();
304  foreach ($settingsAttributes as $elementInformation)
305  {
306  $elementclassname = $elementInformation['type'] . 'LayoutSettingElement';
307  $element = new $elementclassname($elementInformation['attributeName']);
308  $cellMetadata = $element->processToMetadata($cell, $cellMetadata);
309  }
310  return $cellMetadata;
311  }
312 
313  protected function getDerivedAttributesFromMetadata()
314  {
315  if (isset($this->existingMetadata['global']['derivedAttributeTypes']))
316  {
317  assert('is_array($this->existingMetadata["global"]["derivedAttributeTypes"])');
318  return $this->existingMetadata['global']['derivedAttributeTypes'];
319  }
320  return array();
321  }
322 
323  protected function areAllRequiredAttributesPlaced()
324  {
325  foreach ($this->placeableLayoutAttributes as $attributeName => $attributeInformation)
326  {
327  if ($attributeInformation['isRequired'] &&
328  !in_array($attributeName, $this->placedAttributeNames))
329  {
330  if (method_exists($this->designerRules, 'isRequiredAttributeExemptFromBeingPlacedInLayout') &&
331  $this->designerRules->isRequiredAttributeExemptFromBeingPlacedInLayout($attributeName))
332  {
333  continue;
334  }
335  $elementClassName = $attributeInformation['elementType'] . 'Element';
336  if (!$elementClassName::isReadOnly())
337  {
338  return false;
339  }
340  }
341  }
342  foreach ($this->requiredDerivedLayoutAttributeTypes as $attributeType)
343  {
344  if (!in_array($attributeType, $this->placedDerivedAttributeTypes))
345  {
346  return false;
347  }
348  }
349  if (method_exists($this->designerRules, 'areAllPseudoRequiredDerivedAttributeTypesPlacedInLayout') &&
350  !$this->designerRules->areAllPseudoRequiredDerivedAttributeTypesPlacedInLayout($this->placedDerivedAttributeTypes))
351  {
352  return false;
353  }
354  return true;
355  }
356 
357  protected function areAllPlacedAttributesUnique()
358  {
359  $moduleClassName = $this->moduleClassName;
360  $modelClassName = $moduleClassName::getPrimaryModelName();
361  foreach ($this->placedDirectAttributeNamesAsElements as $attributeName)
362  {
363  if (isset($this->placeableLayoutAttributes[$attributeName]))
364  {
365  $elementType = $this->placeableLayoutAttributes[$attributeName]['elementType'];
366  if ($elementType == 'DropDownDependency')
367  {
369  getByNameAndModelClassName($attributeName, $modelClassName);
370  $usedAttributeNames = $metadata->getUsedAttributeNames();
371  foreach ($usedAttributeNames as $usedAttribute)
372  {
373  if (in_array($usedAttribute, $this->placedDirectAttributeNamesAsElements))
374  {
375  $this->message =
376  Zurmo::t('DesignerModule', 'All fields placed must be unique. Two of the placed ' .
377  'fields: {field1Label} and {field2Label} contain the same fields.',
378  array('{field1Label}' => $this->placeableLayoutAttributes
379  [$attributeName]['attributeLabel'],
380  '{field2Label}' => $this->placeableLayoutAttributes
381  [$usedAttribute]['attributeLabel']));
382  return false;
383  }
384  }
385  }
386  }
387  else
388  {
389  //Do nothing. This means a real attribute is only placable as part of a derived attribute.
390  }
391  }
392  return true;
393  }
394 
398  protected function resolveSaveLayoutSuccessMessage()
399  {
400  $designerRulesClass = get_class($this->designerRules);
401  return $designerRulesClass::getSavedLayoutSuccessMessage();
402  }
403  }
404 ?>
__construct($viewClassName, $moduleClassName, $existingMetadata, DesignerRules $designerRules, $placeableLayoutAttributes, $requiredDerivedLayoutAttributeTypes)
resolveMetadataFromSelectedListAttributes($viewClassName, $selectedListAttributes)
setMetadataFromLayout($layout, $savableMetadata)
static getByNameAndModelClassName($name, $modelClassName)
Generated on Sun Jul 12 2020 07:10:30
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.