Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
SearchForm.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 
41  abstract class SearchForm extends ModelForm
42  {
43  const ANY_MIXED_ATTRIBUTES_SCOPE_NAME = 'anyMixedAttributesScope';
44 
45  const SELECTED_LIST_ATTRIBUTES = 'selectedListAttributes';
46 
47  private $dynamicAttributeData;
48 
49  private $dynamicAttributeNames = array();
50 
51  private $attributeNamesThatCanBeSplitUsingDelimiter = array();
52 
53  private $supportsMixedSearch;
54 
60  public $anyMixedAttributes;
61 
67  private $anyMixedAttributesScope;
68 
73  private $listAttributesSelector;
74 
79  public $filterByStarred;
80 
85  private $kanbanBoard;
86 
87  public function __construct(RedBeanModel $model)
88  {
89  parent::__construct($model);
90  $modelAttributesAdapter = new ModelAttributesAdapter($this->model);
91  $attributeInformation = $modelAttributesAdapter->getAttributes();
92  foreach ($attributeInformation as $attributeName => $attributeData)
93  {
94  if (in_array($attributeData['elementType'], static::getDynamicAttributeTypes()))
95  {
96  $this->dynamicAttributeNames[] = $attributeName .
97  FormModelUtil::DELIMITER . $attributeData['elementType'];
98  }
99  }
100  }
101 
102  protected function getModelModuleClassName()
103  {
104  return $this->model->getModuleClassName();
105  }
106 
107  protected function addAttributeNamesThatCanBeSplitUsingDelimiter($value)
108  {
109  $this->attributeNamesThatCanBeSplitUsingDelimiter[] = $value;
110  }
111 
112  public function setAnyMixedAttributesScope($anyMixedAttributesScope)
113  {
114  $this->anyMixedAttributesScope = $anyMixedAttributesScope;
115  }
116 
117  public function getAnyMixedAttributesScope()
118  {
119  return $this->anyMixedAttributesScope;
120  }
121 
126  public function rules()
127  {
128  $dynamicAttributeRules = array();
129  foreach ($this->dynamicAttributeNames as $attributeName)
130  {
131  $dynamicAttributeRules[] = array($attributeName, 'safe');
132  }
133  $rules = array_merge(parent::rules(), $dynamicAttributeRules);
134  return array_merge($rules, $this->getMixedSearchRules());
135  }
136 
141  public function attributeLabels()
142  {
143  $dynamicAttributeLabels = array();
144  foreach ($this->dynamicAttributeNames as $attributeName)
145  {
146  $delimiter = FormModelUtil::DELIMITER;
147  list($realAttributeName, $type) = explode($delimiter, $attributeName);
148  $dynamicAttributeLabels[$attributeName] = $this->model->getAttributeLabel($realAttributeName);
149  }
150  $attributeLabels = array_merge(parent::attributeLabels(), $dynamicAttributeLabels);
151  return array_merge($attributeLabels, $this->getMixedSearchAttributeLabels());
152  }
153 
158  public function __set($name, $value)
159  {
160  if (static::doesNameResolveNameForDelimiterSplit($name))
161  {
162  return $this->dynamicAttributeData[$name] = $value;
163  }
164  parent::__get($name);
165  }
166 
171  public function __get($name)
172  {
173  if (static::doesNameResolveNameForDelimiterSplit($name))
174  {
175  return $this->dynamicAttributeData[$name];
176  }
177  return parent::__get($name);
178  }
179 
183  public function isAttributeOnForm($attributeName)
184  {
185  if (property_exists($this, $attributeName))
186  {
187  return true;
188  }
189  if (static::doesNameResolveNameForDelimiterSplit($attributeName))
190  {
191  return true;
192  }
193  return false;
194  }
195 
199  public static function isAttributeSearchable($attributeName)
200  {
201  if (in_array($attributeName, static::getNonSearchableAttributes()))
202  {
203  return false;
204  }
205  return true;
206  }
207 
208  public static function getNonSearchableAttributes()
209  {
210  return array(self::ANY_MIXED_ATTRIBUTES_SCOPE_NAME,
211  self::SELECTED_LIST_ATTRIBUTES,
212  KanbanBoard::GROUP_BY_ATTRIBUTE_VISIBLE_VALUES,
213  KanbanBoard::SELECTED_THEME,
214  'filterByStarred');
215  }
216 
217  public function getSearchableAttributes()
218  {
219  $searchableAttributes = array();
220  foreach ($this->getAttributes() as $attributeName => $notUsed)
221  {
222  if (!in_array($attributeName, static::getNonSearchableAttributes()))
223  {
224  $searchableAttributes[$attributeName] = $notUsed;
225  }
226  }
227  return $searchableAttributes;
228  }
229 
234  public function getMetadata()
235  {
236  $metadata = parent::getMetadata();
237  $dynamicAttributeToElementTypes = static::getDynamicAttributeToElementTypes();
238  foreach ($this->dynamicAttributeNames as $attributeName)
239  {
240  $delimiter = FormModelUtil::DELIMITER;
241  list($realAttributeName, $type) = explode($delimiter, $attributeName);
242  assert('$dynamicAttributeToElementTypes[$type] != null');
243  $metadata[get_called_class()]['elements'][$attributeName] = $dynamicAttributeToElementTypes[$type];
244  }
245  foreach ($this->attributeNamesThatCanBeSplitUsingDelimiter as $attributeName)
246  {
247  $delimiter = FormModelUtil::DELIMITER;
248  list($realAttributeName, $type) = explode($delimiter, $attributeName);
249  assert('$dynamicAttributeToElementTypes[$type] != null');
250  $metadata[get_called_class()]['elements'][$attributeName] = $dynamicAttributeToElementTypes[$type];
251  }
252  //add something to resolve for global search....
253  $this->resolveMixedSearchAttributeElementForMetadata($metadata[get_called_class()]['elements']);
254  return $metadata;
255  }
256 
261  public static function isRelation($attributeName)
262  {
263  if (static::doesNameResolveNameForDelimiterSplit($attributeName))
264  {
265  return false;
266  }
267  return parent::isRelation($attributeName);
268  }
269 
274  public static function getRelationModelClassName($relationName)
275  {
276  if (static::doesNameResolveNameForDelimiterSplit($relationName))
277  {
278  return false;
279  }
280  return parent::getRelationModelClassName($relationName);
281  }
282 
287  public function isAttribute($attributeName)
288  {
289  assert('is_string($attributeName)');
290  assert('$attributeName != ""');
291  if (static::doesNameResolveNameForDelimiterSplit($attributeName))
292  {
293  return true;
294  }
295  return parent::isAttribute($attributeName);
296  }
297 
302  public function isAttributeRequired($attribute)
303  {
304  if (static::doesNameResolveNameForDelimiterSplit($attribute))
305  {
306  return false;
307  }
308  return parent::isAttributeRequired($attribute);
309  }
310 
315  public function attributeNames()
316  {
317  $attributeNames = parent::attributeNames();
318  return array_merge($attributeNames, $this->dynamicAttributeNames);
319  }
320 
325  public function setAttributes($values, $safeOnly = true)
326  {
327  $nonDynamicAttributeValues = array();
328  foreach ($values as $name => $value)
329  {
330  if (static::doesNameResolveNameForDelimiterSplit($name))
331  {
332  $this->$name = $value;
333  }
334  else
335  {
336  $nonDynamicAttributeValues[$name] = $value;
337  }
338  }
339  //Dropdowns can be searched on as mulit-selects. This below foreach resolves the issue of needing to show
340  //multiple values in the dropdown.
341  foreach ($values as $name => $value)
342  {
343  $modelClassName = get_class($this->model);
344  if ($value != null && $this->model->isAttribute($name) && $modelClassName::isRelation($name))
345  {
346  $relationModelClassName = $modelClassName::getRelationModelClassName($name);
347  if (($relationModelClassName == 'CustomField' ||
348  is_subclass_of($relationModelClassName, 'CustomField') && isset($value['value']) &&
349  is_array($value['value']) && count($value['value']) > 0))
350  {
351  $this->model->$name->value = $value['value'];
352  }
353  }
354  }
355  parent::setAttributes($nonDynamicAttributeValues, $safeOnly);
356  }
357 
366  protected static function doesNameResolveNameForDelimiterSplit($name)
367  {
368  assert('is_string($name)');
369  $delimiter = FormModelUtil::DELIMITER;
370  $parts = explode($delimiter, $name);
371  if (isset($parts[1]) && $parts[1] != null)
372  {
373  if (in_array($parts[1], static::getDynamicAttributeTypes()))
374  {
375  return true;
376  }
377  else
378  {
379  throw new NotSupportedException();
380  }
381  }
382  return false;
383  }
384 
389  protected static function getDynamicAttributeTypes()
390  {
391  return array('Date', 'DateTime');
392  }
393 
397  protected static function getDynamicAttributeToElementTypes()
398  {
399  return array('Date' => 'MixedDateTypesForSearch', 'DateTime' => 'MixedDateTypesForSearch');
400  }
401 
408  {
409  $dynamicMappingData = array();
410  foreach ($this->dynamicAttributeNames as $attributeName)
411  {
412  $dynamicMappingData[$attributeName] = 'resolveEntireMappingByRules';
413  }
414  return $dynamicMappingData;
415  }
416 
421  protected static function shouldIgnoreRequiredValidator()
422  {
423  return true;
424  }
425 
429  protected static function getSearchFormAttributeMappingRulesTypes()
430  {
431  return array();
432  }
433 
438  public static function getSearchFormAttributeMappingRulesTypeByAttribute($attributeName)
439  {
440  assert('is_string($attributeName)');
441  if (static::doesNameResolveNameForDelimiterSplit($attributeName))
442  {
443  $delimiter = FormModelUtil::DELIMITER;
444  list($realAttributeName, $type) = explode($delimiter, $attributeName);
445  if ($type == 'Date')
446  {
447  return 'MixedDateTypes';
448  }
449  elseif ($type == 'DateTime')
450  {
451  return 'MixedDateTimeTypes';
452  }
453  else
454  {
455  throw new NotSupportedException();
456  }
457  }
458  else
459  {
460  $ruleTypesIndexedByAttributeName = static::getSearchFormAttributeMappingRulesTypes();
461  if (isset($ruleTypesIndexedByAttributeName[$attributeName]))
462  {
463  return $ruleTypesIndexedByAttributeName[$attributeName];
464  }
465  else
466  {
467  throw new NotSupportedException();
468  }
469  }
470  }
471 
472  private function supportsMixedSearch()
473  {
474  if ($this->supportsMixedSearch === null)
475  {
476  $this->supportsMixedSearch = false;
477  $moduleClassName = $this->model->getModuleClassName();
478  if ($moduleClassName != null && $moduleClassName::getGlobalSearchFormClassName() != null)
479  {
480  $this->supportsMixedSearch = true;
481  }
482  }
483  return $this->supportsMixedSearch;
484  }
485 
486  private function getMixedSearchRules()
487  {
488  if ($this->supportsMixedSearch())
489  {
490  return array(array('anyMixedAttributes', 'safe'));
491  }
492  return array();
493  }
494 
495  private function getMixedSearchAttributeLabels()
496  {
497  if ($this->supportsMixedSearch())
498  {
499  return array('anyMixedAttributes' => Zurmo::t('Core', 'Basic Search Fields'));
500  }
501  return array();
502  }
503 
508  public function resolveMixedSearchAttributeMappedToRealAttributesMetadata(& $realAttributesMetadata)
509  {
510  assert('is_array($realAttributesMetadata)');
511  if ($this->supportsMixedSearch())
512  {
513  $moduleClassName = $this->getModelModuleClassName();
514  $metadata = $moduleClassName::getMetadata();
515  $data = array('anyMixedAttributes' => array());
516  if (isset($metadata['global']['globalSearchAttributeNames']) &&
517  $metadata['global']['globalSearchAttributeNames'] != null)
518  {
519  foreach ($metadata['global']['globalSearchAttributeNames'] as $attributeName)
520  {
521  if ($this->anyMixedAttributesScope == null ||
522  in_array($attributeName, $this->anyMixedAttributesScope))
523  {
524  if (!isset($realAttributesMetadata[$attributeName]))
525  {
526  $data['anyMixedAttributes'][] = array($attributeName);
527  }
528  elseif (isset($realAttributesMetadata[$attributeName]) &&
529  is_array($realAttributesMetadata[$attributeName]))
530  {
531  foreach ($realAttributesMetadata[$attributeName] as $mixedAttributeMetadata)
532  {
533  $data['anyMixedAttributes'][] = $mixedAttributeMetadata;
534  }
535  }
536  else
537  {
538  throw new NotSupportedException();
539  }
540  }
541  }
542  }
543  $realAttributesMetadata = array_merge($realAttributesMetadata, $data);
544  }
545  }
546 
547  protected function resolveMixedSearchAttributeElementForMetadata(& $metadata)
548  {
549  if ($this->supportsMixedSearch())
550  {
551  $metadata['anyMixedAttributes'] = 'AnyMixedAttributesSearch';
552  }
553  }
554 
560  {
561  $namesAndLabels = array();
562  if ($this->supportsMixedSearch())
563  {
564  $moduleClassName = $this->getModelModuleClassName();
565  $metadata = $moduleClassName::getMetadata();
566  if (isset($metadata['global']['globalSearchAttributeNames']) &&
567  $metadata['global']['globalSearchAttributeNames'] != null)
568  {
569  foreach ($metadata['global']['globalSearchAttributeNames'] as $attributeName)
570  {
571  if ($this->isAttribute($attributeName))
572  {
573  $namesAndLabels[$attributeName] = $this->getAttributeLabel($attributeName);
574  }
575  else
576  {
577  $namesAndLabels[$attributeName] = $this->model->getAttributeLabel($attributeName);
578  }
579  }
580  }
581  }
582  else
583  {
584  throw new NotSupportedException();
585  }
586  return array_merge(array('All' => Zurmo::t('Core', 'All')), $namesAndLabels);
587  }
588 
592  public function setListAttributesSelector(ListAttributesSelector $listAttributesSelector)
593  {
594  $this->listAttributesSelector = $listAttributesSelector;
595  }
596 
600  public function getListAttributesSelector()
601  {
602  return $this->listAttributesSelector;
603  }
604 
608  public function setKanbanBoard(KanbanBoard $kanbanBoard)
609  {
610  $this->kanbanBoard = $kanbanBoard;
611  }
612 
616  public function getKanbanBoard()
617  {
618  return $this->kanbanBoard;
619  }
620  }
621 ?>
getListAttributesSelector()
Definition: SearchForm.php:600
__get($name)
Definition: SearchForm.php:171
isAttribute($attributeName)
Definition: SearchForm.php:287
setAttributes($values, $safeOnly=true)
Definition: SearchForm.php:325
static doesNameResolveNameForDelimiterSplit($name)
Definition: SearchForm.php:366
setListAttributesSelector(ListAttributesSelector $listAttributesSelector)
Definition: SearchForm.php:592
static getSearchFormAttributeMappingRulesTypes()
Definition: SearchForm.php:429
__set($name, $value)
Definition: SearchForm.php:158
static isRelation($attributeName)
Definition: SearchForm.php:261
isAttributeRequired($attribute)
Definition: SearchForm.php:302
getGlobalSearchAttributeNamesAndLabelsAndAll()
Definition: SearchForm.php:559
static getSearchFormAttributeMappingRulesTypeByAttribute($attributeName)
Definition: SearchForm.php:438
static isAttributeSearchable($attributeName)
Definition: SearchForm.php:199
getAttributesMappedToRealAttributesMetadata()
Definition: SearchForm.php:407
setKanbanBoard(KanbanBoard $kanbanBoard)
Definition: SearchForm.php:608
resolveMixedSearchAttributeMappedToRealAttributesMetadata(&$realAttributesMetadata)
Definition: SearchForm.php:508
isAttributeOnForm($attributeName)
Definition: SearchForm.php:183
static getDynamicAttributeTypes()
Definition: SearchForm.php:389
static getDynamicAttributeToElementTypes()
Definition: SearchForm.php:397
static getRelationModelClassName($relationName)
Definition: SearchForm.php:274
static shouldIgnoreRequiredValidator()
Definition: SearchForm.php:421
Generated on Wed Jul 8 2020 07:10:30
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.