Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
RedBeanModelMemberRulesToColumnAdapter.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  {
45  const ASSUME_SIGNED = true;
46 
51  const DEFAULT_MODEL_CLASS = 'Item';
52 
57 
61  const CACHE_KEY = 'RedBeanModelMemberRulesToColumnAdapter_uniqueIndexes';
62 
68  public static function resolveUniqueIndexesFromValidator($modelClassName)
69  {
70  $uniqueIndexes = GeneralCache::getEntry(static::CACHE_KEY, array());
71  if (isset($uniqueIndexes[$modelClassName]))
72  {
73  return $uniqueIndexes[$modelClassName];
74  }
75  return null;
76  }
77 
85  public static function resolve($modelClassName, array $rules, & $messageLogger)
86  {
87  if (empty($rules))
88  {
89  return false;
90  }
91  $member = $rules[0][0];
92  assert('strpos($member, " ") === false');
93  $name = RedBeanModelMemberToColumnUtil::resolve($member);
94  $type = null;
95  $length = null;
96  $notNull = null;
97  $default = null;
98  static::resolveColumnTypeAndLengthFromRules($modelClassName, $member, $rules, $type, $length,
99  $notNull, $default, $messageLogger);
100  if (!isset($type))
101  {
102  return false;
103  }
104  return RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($name, $type, $length, null, $notNull, $default, null);
105  }
106 
107  protected static function resolveColumnTypeAndLengthFromRules($modelClassName, $member, array $rules,
108  & $type, & $length, & $notNull,
109  & $default, & $messageLogger)
110  {
111  $suitableModelClassName = static::findSuitableModelClassName($modelClassName);
112  if (!$suitableModelClassName)
113  {
114  $messageLogger->addErrorMessage(Zurmo::t('Core', 'Unable to find a suitable non-abstract class for' .
115  ' validators against {{model}}', array('{{model}}' => $modelClassName)));
116  return;
117  }
118  $model = $suitableModelClassName::model();
119  $yiiValidators = CValidator::$builtInValidators;
120  $yiiValidatorsToRedBeanValidators = RedBeanModel::getYiiValidatorsToRedBeanValidators();
121  foreach ($rules as $validatorMetadata)
122  {
123  assert('isset($validatorMetadata[0])');
124  assert('isset($validatorMetadata[1])');
125  $validatorName = $validatorMetadata[1];
126  $validatorParameters = array_slice($validatorMetadata, 2);
127  if (isset($yiiValidators[$validatorName]))
128  {
129  $validatorName = $yiiValidators[$validatorName];
130  }
131  if (isset($yiiValidatorsToRedBeanValidators[$validatorName]))
132  {
133  $validatorName = $yiiValidatorsToRedBeanValidators[$validatorName];
134  }
135  if (!@class_exists($validatorName))
136  {
137  continue;
138  }
139  $validator = CValidator::createValidator($validatorName, $model, $member, $validatorParameters);
140 
141  switch ($validatorName)
142  {
143  case 'RedBeanModelTypeValidator':
144  case 'TypeValidator':
145  case 'CTypeValidator':
146  if (in_array($validator->type, array('blob', 'boolean', 'date', 'datetime', 'longblob',
147  'string', 'float', 'integer', 'time', 'text', 'longtext')))
148  {
149  if (!isset($type) || $validator->type == 'float') // another validator such as CNumberValidator(integer) might have set type to more precise one.
150  {
151  $type = $validator->type;
152  }
153  }
154  break;
155  case 'CBooleanValidator':
156  $type = 'boolean';
157  break;
158  case 'CStringValidator':
159  if ((!isset($type) || $type == 'string'))
160  {
161  static::resolveStringTypeAndLengthByMaxLength($type, $length, $validator->max);
162  }
163  break;
164  case 'CUrlValidator':
165  $type = 'string';
166  if (!isset($length))
167  {
168  $length = 255;
169  }
170  break;
171  case 'CEmailValidator':
172  $type = 'string';
173  if (!isset($length))
174  {
175  $length = 255;
176  }
177  break;
178  case 'RedBeanModelNumberValidator':
179  case 'CNumberValidator':
180  if ((!isset($type) || $type == 'integer') && !isset($validator->precision))
181  {
182  static::resolveIntegerTypeByMinAndMaxValue($type, $validator->min, $validator->max);
183  }
184  break;
185  case 'RedBeanModelDefaultValueValidator':
186  case 'CDefaultValueValidator':
187  // Left here for future use if we want to set defaults on db level too.
188  //$default = 'DEFAULT ' . $validator->value;
189  break;
190  case 'RedBeanModelRequiredValidator':
191  case 'CRequiredValidator':
192  //$notNull = 'NOT NULL'; // Not Coding Standard
193  // Left here for future use if we want to set required on db level too.
194  break;
195  case 'RedBeanModelUniqueValidator':
196  case 'CUniqueValidator':
197  static::registerUniqueIndexByMemberName($member, $modelClassName);
198  break;
199  }
200  }
201  // we have a string and we don't know anything else about it, better to set it as text.
202  if ($type == 'string' && !isset($length))
203  {
204  $type = 'text';
205  }
206  }
207 
208  protected static function findSuitableModelClassName($modelClassName)
209  {
210  if (!static::FORCE_DEFAULT_MODEL_CLASS)
211  {
212  $suitableModelClassName = static::findFirstNonAbstractModelInHierarchy($modelClassName);
213  if ($suitableModelClassName)
214  {
215  return $suitableModelClassName;
216  }
217  }
218  if (static::DEFAULT_MODEL_CLASS)
219  {
220  return static::DEFAULT_MODEL_CLASS;
221  }
222  return false;
223  }
224 
225  protected static function findFirstNonAbstractModelInHierarchy($modelClassName)
226  {
227  if (!$modelClassName || $modelClassName == 'RedBeanModel')
228  {
229  return null;
230  }
231  $model = new ReflectionClass($modelClassName);
232  if ($model->isAbstract())
233  {
234  return static::findFirstNonAbstractModelInHierarchy(get_parent_class($modelClassName));
235  }
236  else
237  {
238  return $modelClassName;
239  }
240  }
241 
242  protected static function registerUniqueIndexByMemberName($member, $modelClassName)
243  {
245  $uniqueIndexes = GeneralCache::getEntry(static::CACHE_KEY, array());
246  $uniqueIndexes[$modelClassName][$indexName] = array('members' => array($member), 'unique' => true);
247  GeneralCache::cacheEntry(static::CACHE_KEY, $uniqueIndexes);
248  }
249 
250  public static function resolveStringTypeAndLengthByMaxLength(& $type, & $length, $maxLength = null)
251  {
252  $type = 'text';
253  if (isset($maxLength) && $maxLength > 0)
254  {
255  if ($maxLength > 65535)
256  {
257  $type = 'longtext';
258  }
259  elseif ($maxLength <= 255)
260  {
261  $type = 'string';
262  $length = $maxLength;
263  }
264  }
265  // Begin Not Coding Standard
266  // TODO: @Shoaibi: Critical: redo this:
267  /*
268  TINYTEXT - 256 bytes
269  TEXT - 65,535 bytes
270  MEDIUMTEXT - 16,777,215 bytes
271  LONGTEXT - 4,294,967,295 bytes
272  */
273  // End Not Coding Standard
274  }
275 
276  public static function resolveIntegerTypeByMinAndMaxValue(& $type, $min, $max)
277  {
278  $intMaxValuesAllows = DatabaseCompatibilityUtil::resolveIntegerMaxAllowedValuesByType(static::ASSUME_SIGNED);
279  $type = 'integer';
280  if (isset($max))
281  {
282  foreach ($intMaxValuesAllows as $relatedType => $valueLimit)
283  {
284  $maxAllowedValue = $valueLimit;
285  $minAllowedValue = 0;
286  if (static::ASSUME_SIGNED)
287  {
288  $minAllowedValue = -1 * $valueLimit;
289  }
290  if ((!isset($min) || $min >= $minAllowedValue) &&
291  $max < $maxAllowedValue)
292  {
293  $type = $relatedType;
294  break;
295  }
296  }
297  }
298  }
299  }
300 ?>
static resolve($modelClassName, array $rules, &$messageLogger)
Generated on Sun Jul 12 2020 07:10:26
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.