/**
  * Returns the element or attribute form type
  * that should be used with the named attribute
  * of the given model, (the name minus the Element
  * or AttributeForm suffix).
  */
 public static function getDesignerType($model, $attributeName)
 {
     if (!$model->isAttribute($attributeName)) {
         return DerivedAttributeToMixedTypeUtil::getType(get_class($model), $attributeName);
     }
     return ModelAttributeToMixedTypeUtil::getType($model, $attributeName);
 }
 /**
  * Sanitize post data, specifically handling any date and date time conversions from local format to the
  * database format.
  * @param string $importRulesType
  * @param array $postMappingData
  */
 public static function sanitizePostByTypeForSavingMappingData($importRulesType, $postMappingData)
 {
     assert('is_string($importRulesType)');
     assert('is_array($postMappingData)');
     foreach ($postMappingData as $columnName => $mappingData) {
         if (!isset($mappingData['mappingRulesData'])) {
             $postMappingData[$columnName]['mappingRulesData'] = array();
         }
     }
     foreach ($postMappingData as $columnName => $mappingData) {
         foreach ($mappingData['mappingRulesData'] as $mappingRuleFormClassName => $mappingRuleFormData) {
             $model = MappingRuleFormAndElementTypeUtil::makeForm($importRulesType, $mappingData['attributeIndexOrDerivedType'], $mappingRuleFormClassName);
             foreach ($mappingRuleFormData as $attributeName => $value) {
                 if ($value !== null) {
                     if (!is_array($value)) {
                         if ($model->isAttribute($attributeName) && $model->isAttributeSafe($attributeName)) {
                             $type = ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, $model::getAttributeName());
                             if ($type == 'Date') {
                                 $postMappingData[$columnName]['mappingRulesData'][$mappingRuleFormClassName][$attributeName] = DateTimeUtil::resolveValueForDateDBFormatted($value);
                             }
                             if ($type == 'DateTime' && !empty($value)) {
                                 $postMappingData[$columnName]['mappingRulesData'][$mappingRuleFormClassName][$attributeName] = DateTimeUtil::convertDateTimeLocaleFormattedDisplayToDbFormattedDateTimeWithSecondsAsZero($value);
                             }
                         }
                     }
                 }
             }
         }
     }
     return $postMappingData;
 }
 public function testGetValidCastTypesForAllAttributeTypes()
 {
     $model = new TestOperatorTypeModel();
     $this->assertEquals('Integer', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'integerStandard'));
     $this->assertEquals('Date', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'dateStandard'));
     $this->assertEquals('DateTime', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'dateTimeStandard'));
     $this->assertEquals('Decimal', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'floatStandard'));
     $this->assertEquals('Time', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'timeStandard'));
     $this->assertEquals('Email', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'emailStandard'));
     $this->assertEquals('CheckBox', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'booleanStandard'));
     $this->assertEquals('Url', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'urlStandard'));
     //Test all custom fields
     $this->assertEquals('CheckBox', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'checkBox'));
     $this->assertEquals(null, ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'currency'));
     $this->assertEquals('Date', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'date'));
     $this->assertEquals('DateTime', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'dateTime'));
     $this->assertEquals('Decimal', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'decimal'));
     $this->assertEquals(null, ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'dropDown'));
     $this->assertEquals('Integer', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'integer'));
     $this->assertEquals(null, ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'phone'));
     $this->assertEquals(null, ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'radio'));
     $this->assertEquals(null, ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'text'));
     $this->assertEquals(null, ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'textArea'));
     $this->assertEquals('Url', ModelAttributeToMixedTypeUtil::getTypeByModelUsingValidator($model, 'url'));
 }
 /**
  * Given a value, resolve that the value is a correctly formatted number. If not, an
  * InvalidValueToSanitizeException is thrown.
  * @param string $modelClassName
  * @param string $attributeName
  * @param mixed $value
  * @param array $mappingRuleData
  */
 public static function sanitizeValue($modelClassName, $attributeName, $value, $mappingRuleData)
 {
     assert('is_string($modelClassName)');
     assert('is_string($attributeName)');
     assert('$mappingRuleData == null');
     if ($value == null) {
         return $value;
     }
     $sanitizedValue = str_replace('$', '', $value);
     $sanitizedValue = str_replace(',', '', $sanitizedValue);
     // Not Coding Standard
     $model = new $modelClassName(false);
     $type = ModelAttributeToMixedTypeUtil::getType($model, $attributeName);
     $validator = new RedBeanModelNumberValidator();
     if ($validator->integerOnly === true) {
         if (!preg_match($validator->integerPattern, $sanitizedValue)) {
             throw new InvalidValueToSanitizeException(Zurmo::t('ImportModule', 'Invalid integer format.'));
         }
     } else {
         if (!preg_match($validator->numberPattern, $sanitizedValue)) {
             throw new InvalidValueToSanitizeException(Zurmo::t('ImportModule', 'Invalid number format.'));
         }
     }
     return $sanitizedValue;
 }
 /**
  * @see DataAnalyzerInterface::runAndMakeMessages()
  */
 public function runAndMakeMessages(AnalyzerSupportedDataProvider $dataProvider, $columnName)
 {
     assert('is_string($columnName)');
     $this->processAndMakeMessage($dataProvider, $columnName);
     $modelClassName = $this->modelClassName;
     $model = new $modelClassName(false);
     $this->type = ModelAttributeToMixedTypeUtil::getType($model, $this->attributeName);
 }
 /**
  * @param array $attributes
  * @return array
  */
 protected function resolveAttributesForOrderBys(array $attributes)
 {
     $resolvedAttributes = array();
     foreach ($attributes as $attribute => $data) {
         $attributeType = ModelAttributeToMixedTypeUtil::getType($this->model, $attribute);
         if (!in_array($attributeType, array('MultiSelectDropDown', 'TagCloud', 'TextArea'))) {
             $resolvedAttributes[$attribute] = $data;
         }
     }
     return $resolvedAttributes;
 }
 /**
  * Returns HAS_ONE relation attributes
  * and non-relation attributes in an array
  * mapping attribute names to 'attributeLabel' to the
  * attribute label.  Also returns 'isRequired' and 'isAudited' information.
  */
 public function getAttributes()
 {
     $attributes = array();
     ModelAttributeImportMappingCollectionUtil::populateCollection($attributes, 'id', $this->model->getAttributeLabel('id'), 'id', 'Id');
     foreach ($this->model->getAttributes() as $attributeName => $notUsed) {
         if (!$this->model->isRelation($attributeName) || $this->isAttributeAnOwnedCustomFieldRelation($attributeName) || $this->isAttributeAnOwnedMultipleValuesCustomFieldRelation($attributeName) || $this->isAttributeAHasOneNotOwnedRelation($attributeName) || $this->isAttributeAHasOneOwnedRelationThatShouldBehaveAsNotOwnedRelation($attributeName)) {
             $type = ModelAttributeToMixedTypeUtil::getType($this->model, $attributeName);
             $resolvedType = static::resolveAttributeImportTypeByAttributeName($type, $attributeName);
             ModelAttributeImportMappingCollectionUtil::populateCollection($attributes, $attributeName, $this->model->getAttributeLabel($attributeName), $attributeName, $resolvedType, null, $this->model->isAttributeRequired($attributeName));
         } elseif ($this->isAttributeAHasOneOwnedRelation($attributeName)) {
             foreach ($this->model->{$attributeName}->getAttributes() as $relationAttributeName => $notUsed) {
                 if (!$this->model->{$attributeName}->isRelation($relationAttributeName)) {
                     $attributeLabel = $this->model->getAttributeLabel($attributeName) . ' - ' . $this->model->{$attributeName}->getAttributeLabel($relationAttributeName);
                     $type = ModelAttributeToMixedTypeUtil::getType($this->model->{$attributeName}, $relationAttributeName);
                     $resolvedType = static::resolveAttributeImportTypeByAttributeName($type, $relationAttributeName);
                     ModelAttributeImportMappingCollectionUtil::populateCollection($attributes, $attributeName . FormModelUtil::DELIMITER . $relationAttributeName, $attributeLabel, $attributeName, $resolvedType, $relationAttributeName, $this->model->{$attributeName}->isAttributeRequired($relationAttributeName));
                 }
             }
         }
     }
     return $attributes;
 }
Example #8
0
 protected function resolveType()
 {
     $modelClassName = $this->modelClassName;
     $model = new $modelClassName(false);
     return ModelAttributeToMixedTypeUtil::getType($model, $this->attributeName);
 }
Example #9
0
 public static function adaptSearchAttributesToSetInRedBeanModel($searchAttributes, $model)
 {
     assert('$model instanceof RedBeanModel || $model instanceof SearchForm');
     $searchAttributesReadyToSetToModel = array();
     if ($model instanceof SearchForm) {
         $modelToUse = $model->getModel();
     } else {
         $modelToUse = $model;
     }
     foreach ($searchAttributes as $attributeName => $data) {
         if ($modelToUse->isAttribute($attributeName)) {
             $type = ModelAttributeToMixedTypeUtil::getType($modelToUse, $attributeName);
             switch ($type) {
                 case 'CheckBox':
                     if (is_array($data) && isset($data['value'])) {
                         $data = $data['value'];
                     } elseif (is_array($data) && $data['value'] == null) {
                         $data = null;
                     }
                 default:
                     continue;
             }
         }
         $searchAttributesReadyToSetToModel[$attributeName] = $data;
     }
     return $searchAttributesReadyToSetToModel;
 }
 /**
  * @param $model
  * @param $attributeName
  * @return string
  */
 public static function getType($model, $attributeName)
 {
     assert('is_string($attributeName)');
     return ModelAttributeToMixedTypeUtil::getType($model, $attributeName);
 }
 protected static function resolveMergeTagToStandardOrRelatedAttribute($attributeAccessorString, $model, $language, $timeQualifier, $errorOnFirstMissing, $params)
 {
     $attributeName = strtok($attributeAccessorString, '->');
     if (SpecialMergeTagsAdapter::isSpecialMergeTag($attributeName, $timeQualifier)) {
         return SpecialMergeTagsAdapter::resolve($attributeName, $model, $errorOnFirstMissing, $params);
     } else {
         if (!isset($model)) {
             return static::PROPERTY_NOT_FOUND;
         } elseif (!method_exists($model, 'isAttribute') || !$model->isAttribute($attributeName)) {
             if ($model instanceof Activity) {
                 $metadata = $model::getMetadata();
                 $activityItemsModelClassNamesData = $metadata['Activity']['activityItemsModelClassNames'];
                 foreach ($model->activityItems as $activityItem) {
                     if (ucfirst($attributeName) == get_class($activityItem)) {
                         $attributeAccessorString = str_replace($attributeName . '->', '', $attributeAccessorString);
                         return static::resolveMergeTagToStandardOrRelatedAttribute($attributeAccessorString, $activityItem, $language, $timeQualifier, $errorOnFirstMissing, $params);
                     }
                     if (get_class($activityItem) == 'Item' && array_search(ucfirst($attributeName), $activityItemsModelClassNamesData) !== false) {
                         try {
                             $modelDerivationPathToItem = RuntimeUtil::getModelDerivationPathToItem(ucfirst($attributeName));
                             $castedDownModel = $activityItem->castDown(array($modelDerivationPathToItem));
                             if (ucfirst($attributeName) == get_class($castedDownModel)) {
                                 $attributeAccessorString = str_replace($attributeName . '->', '', $attributeAccessorString);
                                 return static::resolveMergeTagToStandardOrRelatedAttribute($attributeAccessorString, $castedDownModel, $language, $timeQualifier, $errorOnFirstMissing, $params);
                             }
                         } catch (NotFoundException $e) {
                             //Do nothing
                         }
                     }
                     unset($activityItemsModelClassNamesData[get_class($activityItem)]);
                 }
                 foreach ($activityItemsModelClassNamesData as $relationModelClassName) {
                     if (ucfirst($attributeName) == $relationModelClassName) {
                         $model = new $relationModelClassName();
                         $attributeAccessorString = str_replace($attributeName . '->', '', $attributeAccessorString);
                         return static::resolveMergeTagToStandardOrRelatedAttribute($attributeAccessorString, $model, $language, $timeQualifier, $errorOnFirstMissing, $params);
                     }
                 }
             }
             return static::PROPERTY_NOT_FOUND;
         } elseif ($model->{$attributeName} instanceof CurrencyValue) {
             $model = $model->{$attributeName};
             if ($attributeName === $attributeAccessorString) {
                 $attributeAccessorString = null;
             } else {
                 $attributeAccessorString = str_replace($attributeName . '->', '', $attributeAccessorString);
             }
             if (empty($attributeAccessorString)) {
                 // If a user specific a relation merge tag but not a property, we assume he meant "value" property.
                 $currencyValueModel = $model;
                 $value = static::getAttributeValue($currencyValueModel, 'value', $timeQualifier);
                 return CLocale::getInstance($language)->getCurrencySymbol($currencyValueModel->currency->code) . $value;
                 // We can't use code below because it converts integer values in flat and also add slashes to '.' in float numbers
                 //return Yii::app()->numberFormatter->formatCurrency($value,
                 //    $currencyValueModel->currency->code);
             }
             return static::resolveMergeTagToStandardOrRelatedAttribute($attributeAccessorString, $model, $language, $timeQualifier, $errorOnFirstMissing, $params);
         } elseif ($model->{$attributeName} instanceof CustomField) {
             $value = static::getAttributeValue($model->{$attributeName}, 'value', $timeQualifier);
             // TODO: @Shoaibi/@Jason: Low: need to apply localizations(Date/time/currency formats, ...) here besides translation
             if ($value) {
                 $value = Zurmo::t($model::getModuleClassName(), $value, array(), null, $language);
             }
             return $value;
         } elseif ($model->isRelation($attributeName)) {
             $model = $model->{$attributeName};
             if ($attributeName === $attributeAccessorString) {
                 $attributeAccessorString = null;
             } else {
                 $attributeAccessorString = str_replace($attributeName . '->', '', $attributeAccessorString);
             }
             if (empty($attributeAccessorString)) {
                 // If a user specific a relation merge tag but not a property, we assume he meant "value" property.
                 if (empty($timeQualifier)) {
                     return strval($model);
                 } else {
                     return static::PROPERTY_NOT_FOUND;
                 }
             }
             if ($model instanceof RedBeanModels) {
                 $modelClassName = $model->getModelClassName();
                 if ($attributeAccessorString == lcfirst($modelClassName)) {
                     $values = array();
                     foreach ($model as $relatedModel) {
                         $values[] = strval($relatedModel);
                     }
                     return ArrayUtil::stringify($values);
                 }
             }
             return static::resolveMergeTagToStandardOrRelatedAttribute($attributeAccessorString, $model, $language, $timeQualifier, $errorOnFirstMissing, $params);
         } else {
             $attributeType = ModelAttributeToMixedTypeUtil::getType($model, $attributeName);
             //We don't have any accessor operator after the attributeName e.g. its the last in list
             if ($attributeName === $attributeAccessorString) {
                 $content = static::getAttributeValue($model, $attributeName, $timeQualifier);
                 if ($attributeType == 'DateTime') {
                     $content .= ' GMT';
                 }
                 return $content;
             } else {
                 return static::PROPERTY_NOT_FOUND;
             }
         }
     }
 }
 /**
  * @return string
  */
 protected function resolveTimeZoneAdjustmentForACalculatedDateTimeModifier()
 {
     $attributeType = ModelAttributeToMixedTypeUtil::getType($this->modelAttributeToDataProviderAdapter->getModel(), $this->modelAttributeToDataProviderAdapter->getAttribute());
     if ($attributeType == 'DateTime') {
         return DatabaseCompatibilityUtil::makeTimeZoneAdjustmentContent();
     }
 }
Example #13
0
 public function testDynamicDateTimeAttributeOnForm()
 {
     $searchForm = new MixedRelationsModelSearchFormTestModel(new MixedRelationsModel());
     //Test get and set.
     $this->assertEquals(null, $searchForm->dateTime__DateTime);
     $searchForm->dateTime__DateTime = 'aTest';
     $this->assertEquals('aTest', $searchForm->dateTime__DateTime);
     //Check some other methods to make sure they work ok.
     $this->assertFalse($searchForm::isRelation('dateTime__DateTime'));
     $this->assertTrue($searchForm->isAttribute('dateTime__DateTime'));
     $this->assertFalse($searchForm->isAttributeRequired('dateTime__DateTime'));
     //Test attributeRules and attributeLabels
     $attributeLabels = $searchForm->attributeLabels();
     $this->assertEquals('Date Time', $attributeLabels['dateTime__DateTime']);
     $this->assertEquals('Date Time 2', $attributeLabels['dateTime2__DateTime']);
     //Test additional methods.
     $mappedData = $searchForm->getAttributesMappedToRealAttributesMetadata();
     $this->assertEquals('resolveEntireMappingByRules', $mappedData['dateTime__DateTime']);
     $mappingRulesType = $searchForm->getSearchFormAttributeMappingRulesTypeByAttribute('dateTime__DateTime');
     $this->assertEquals('MixedDateTimeTypes', $mappingRulesType);
     //Test that the correct elements are used for the dynamic date attribute.
     $elementType = ModelAttributeToMixedTypeUtil::getType($searchForm, 'dateTime__DateTime');
     $this->assertEquals('MixedDateTypesForSearch', $elementType);
 }
 protected function resolveOperatorAndCastsAndAppendClauseAsAndToStructureString($model, $attributeName, $operatorType, $value, &$adaptedMetadataClause, &$structure, &$clauseCount, $previousAttributeName = null)
 {
     assert('$previousAttributeName == null || is_string($previousAttributeName)');
     $modelForTypeOperations = static::resolveAsRedBeanModel($model);
     if ($operatorType == null) {
         $operatorType = ModelAttributeToOperatorTypeUtil::getOperatorType($modelForTypeOperations, $attributeName);
     }
     if (is_array($value) && $model instanceof CustomField) {
         //do nothing, the cast is fine as is. Maybe eventually remove this setting of cast.
     } else {
         $value = ModelAttributeToCastTypeUtil::resolveValueForCast($modelForTypeOperations, $attributeName, $value);
     }
     if ($model instanceof RedBeanModel) {
         $mixedType = ModelAttributeToMixedTypeUtil::getType($model, $attributeName);
         static::resolveBooleanFalseValueAndOperatorTypeForAdaptedMetadataClause($mixedType, $value, $operatorType);
     } elseif ($model instanceof SearchForm) {
         $mixedType = ModelAttributeToMixedTypeUtil::getType($model->getModel(), $attributeName);
         static::resolveBooleanFalseValueAndOperatorTypeForAdaptedMetadataClause($mixedType, $value, $operatorType);
     }
     if ($previousAttributeName == null) {
         $adaptedMetadataClause['attributeName'] = $attributeName;
     } else {
         $adaptedMetadataClause['attributeName'] = $previousAttributeName;
         $adaptedMetadataClause['relatedAttributeName'] = $attributeName;
     }
     $adaptedMetadataClause['operatorType'] = $operatorType;
     $adaptedMetadataClause['value'] = $value;
     $this->resolveAppendClauseAsAndToStructureString($structure, $clauseCount);
 }
 protected static function resolveFormatTypeAndCurrencyCode(&$formatType, &$currencyCode, $model, $attribute)
 {
     assert('is_int($formatType)');
     assert('is_string($currencyCode) || $currencyCode === null');
     $attributeType = ModelAttributeToMixedTypeUtil::getType($model, $attribute);
     if ($attributeType == 'Decimal' && $formatType == self::FORMAT_TYPE_INTEGER) {
         $formatType = self::FORMAT_TYPE_DECIMAL;
     }
     if ($attributeType == 'CurrencyValue' && ($formatType == self::FORMAT_TYPE_INTEGER || $formatType == self::FORMAT_TYPE_DECIMAL)) {
         $formatType = self::FORMAT_TYPE_CURRENCY_VALUE;
     }
     if ($attributeType == 'CurrencyValue' && $currencyCode === null) {
         $currencyCode = $model->{$attribute}->currency->code;
     } elseif ($attributeType == 'CurrencyValue' && $currencyCode != null && $model->{$attribute}->currency->code != $currencyCode) {
         //An empty value, not null, indicates there is mixed currencies
         $currencyCode = '';
     }
 }
 /**
  * @param string $attribute
  * @return string
  */
 public function getRealModelAttributeType($attribute)
 {
     assert('is_string($attribute)');
     return ModelAttributeToMixedTypeUtil::getType($this->model, $attribute);
 }
 protected function resolveOperatorAndCastsAndAppendClauseAsAndToStructureString($model, $attributeName, $operatorType, $value, &$adaptedMetadataClause, &$secondAdaptedMetadataClause, &$structure, &$clauseCount, $previousAttributeName = null)
 {
     assert('$previousAttributeName == null || is_string($previousAttributeName)');
     $modelForTypeOperations = static::resolveAsRedBeanModel($model);
     $mixedType = null;
     if ($operatorType == null) {
         $operatorType = ModelAttributeToOperatorTypeUtil::getOperatorType($modelForTypeOperations, $attributeName);
     }
     if (is_array($value) && $model instanceof CustomField) {
         //do nothing, the cast is fine as is. Maybe eventually remove this setting of cast.
     } else {
         $value = ModelAttributeToCastTypeUtil::resolveValueForCast($modelForTypeOperations, $attributeName, $value);
     }
     if ($model instanceof RedBeanModel) {
         $mixedType = ModelAttributeToMixedTypeUtil::getType($model, $attributeName);
         static::resolveBooleanFalseValueAndOperatorTypeForAdaptedMetadataClause($mixedType, $value, $operatorType);
     } elseif ($model instanceof SearchForm) {
         $mixedType = ModelAttributeToMixedTypeUtil::getType($model->getModel(), $attributeName);
         static::resolveBooleanFalseValueAndOperatorTypeForAdaptedMetadataClause($mixedType, $value, $operatorType);
     }
     if (static::isBooleanNullOrEmptyOperation($mixedType, $operatorType, $value)) {
         $secondAdaptedMetadataClause = $adaptedMetadataClause;
     }
     if ($previousAttributeName == null) {
         $adaptedMetadataClause['attributeName'] = $attributeName;
         if (static::isBooleanNullOrEmptyOperation($mixedType, $operatorType, $value)) {
             $secondAdaptedMetadataClause['attributeName'] = $attributeName;
         }
     } else {
         $adaptedMetadataClause['attributeName'] = $previousAttributeName;
         $adaptedMetadataClause['relatedAttributeName'] = $attributeName;
         if (static::isBooleanNullOrEmptyOperation($mixedType, $operatorType, $value)) {
             $secondAdaptedMetadataClause['attributeName'] = $previousAttributeName;
             $secondAdaptedMetadataClause['relatedAttributeName'] = $attributeName;
         }
     }
     $adaptedMetadataClause['operatorType'] = $operatorType;
     $adaptedMetadataClause['value'] = $value;
     if (static::isBooleanNullOrEmptyOperation($mixedType, $operatorType, $value)) {
         $secondAdaptedMetadataClause['operatorType'] = OperatorRules::TYPE_IS_NULL;
         $secondAdaptedMetadataClause['value'] = null;
         $partialStructure = null;
         $this->resolveAppendClauseAsAndToStructureString($partialStructure, $clauseCount);
         static::appendClauseAsOrToStructureString($partialStructure, $clauseCount);
         $partialStructure = '(' . $partialStructure . ')';
         if ($this->appendStructureAsAnd) {
             if ($structure != null) {
                 $structure .= ' and ' . $partialStructure;
             } else {
                 $structure .= $partialStructure;
             }
         } else {
             if ($structure != null) {
                 $structure .= ' or ' . $partialStructure;
             } else {
                 $structure .= $partialStructure;
             }
         }
         $clauseCount++;
     } else {
         $this->resolveAppendClauseAsAndToStructureString($structure, $clauseCount);
     }
 }
 /**
  * @return array
  */
 protected function getGroupByCalculatedModifierAttributes()
 {
     if (isset(self::$groupByCalculatedModifierAttributes[get_class($this->model)])) {
         return self::$groupByCalculatedModifierAttributes[get_class($this->model)];
     }
     $attributes = array();
     foreach ($this->getAttributesNotIncludingDerivedAttributesData() as $attribute => $data) {
         $attributeType = ModelAttributeToMixedTypeUtil::getType($this->model, $attribute);
         if ($attributeType == 'Date' || $attributeType == 'DateTime') {
             $this->resolveGroupByCalculationAttributeData($attributes, $attribute, self::GROUP_BY_CALCULATION_DAY);
             $this->resolveGroupByCalculationAttributeData($attributes, $attribute, self::GROUP_BY_CALCULATION_WEEK);
             $this->resolveGroupByCalculationAttributeData($attributes, $attribute, self::GROUP_BY_CALCULATION_MONTH);
             $this->resolveGroupByCalculationAttributeData($attributes, $attribute, self::GROUP_BY_CALCULATION_QUARTER);
             $this->resolveGroupByCalculationAttributeData($attributes, $attribute, self::GROUP_BY_CALCULATION_YEAR);
         }
     }
     self::$groupByCalculatedModifierAttributes[get_class($this->model)] = $attributes;
     return self::$groupByCalculatedModifierAttributes[get_class($this->model)];
 }