public function testGetMetadataForDynamicDateTimeAttributeThatIsOnManyRelatedModel()
 {
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     $searchForm = new ASearchFormTestModel(new MixedRelationsModel());
     //Make sure the timeZone is different than UTC for testing.
     Yii::app()->user->userModel->timeZone = 'America/Chicago';
     //TEST when no value present
     $metadata = SearchFormAttributesToSearchDataProviderMetadataUtil::getMetadata($searchForm, 'dateDateTimeADate__Date', null);
     $compareData = array(array('manyMany' => array('value' => array('aDate' => null))));
     $this->assertEquals($compareData, $metadata);
     //Test Date = Today
     $value = array();
     $value['type'] = MixedDateTypesSearchFormAttributeMappingRules::TYPE_TODAY;
     $metadata = SearchFormAttributesToSearchDataProviderMetadataUtil::getMetadata($searchForm, 'dateDateTimeADateTime__DateTime', $value);
     $todayDateTime = new DateTime(null, new DateTimeZone(Yii::app()->timeZoneHelper->getForCurrentUser()));
     $today = Yii::app()->dateFormatter->format(DatabaseCompatibilityUtil::getDateFormat(), $todayDateTime->getTimeStamp());
     $compareData = array(array('manyMany' => array('value' => array('aDateTime' => DateTimeUtil::convertDateIntoTimeZoneAdjustedDateTimeBeginningOfDay($today)), 'operatorType' => 'greaterThanOrEqualTo', 'appendStructureAsAnd' => true)), array('manyMany' => array('value' => array('aDateTime' => DateTimeUtil::convertDateIntoTimeZoneAdjustedDateTimeEndOfDay($today)), 'operatorType' => 'lessThanOrEqualTo', 'appendStructureAsAnd' => true)));
     $this->assertEquals($compareData, $metadata);
 }
 protected function populateAdaptedMetadataFromSearchFormAttributes($model, $attributeName, $value, &$adaptedMetadataClauses, &$clauseCount, &$structure, $adaptedMetadataClauseBasePart = array(), $depth = 0)
 {
     assert('$model instanceof SearchForm || $model instanceof RedBeanModel');
     assert('is_string($attributeName)');
     assert('is_array($adaptedMetadataClauses) || $adaptedMetadataClauses == null');
     assert('is_int($clauseCount)');
     assert('$structure == null || is_string($structure)');
     $tempStructure = null;
     $metadataFromSearchFormAttributes = SearchFormAttributesToSearchDataProviderMetadataUtil::getMetadata($model, $attributeName, $value);
     foreach ($metadataFromSearchFormAttributes as $searchFormClause) {
         if (isset($searchFormClause['concatedAttributeNames'])) {
             assert('is_array($searchFormClause["concatedAttributeNames"][0]) &&
                          count($searchFormClause["concatedAttributeNames"][0]) == 2');
             assert('!isset($searchFormClause["concatedAttributeNames"]["operatorType"])');
             assert('!isset($searchFormClause["concatedAttributeNames"]["appendStructureAsAnd"])');
             $oldAppendStructureAsAndValue = $this->appendStructureAsAnd;
             $this->appendStructureAsAnd = false;
             $basePartAtRequiredDepth = static::getAdaptedMetadataClauseBasePartAtRequiredDepth($adaptedMetadataClauseBasePart, $depth);
             $currentClauseCount = $clauseCount;
             if ($searchFormClause['concatedAttributeNames']['value'] != null) {
                 $this->populateClausesAndStructureForConcatedAttributes($model, $searchFormClause['concatedAttributeNames'][0], $searchFormClause['concatedAttributeNames']['value'], $basePartAtRequiredDepth, $clauseCount, $tempStructure, false);
                 $adaptedMetadataClauses[$currentClauseCount] = static::getAppendedAdaptedMetadataClauseBasePart($adaptedMetadataClauseBasePart, $basePartAtRequiredDepth, $depth);
             }
             $this->appendStructureAsAnd = $oldAppendStructureAsAndValue;
         } else {
             foreach ($searchFormClause as $searchFormAttributeName => $searchFormStructure) {
                 if (isset($searchFormStructure['operatorType'])) {
                     $operatorType = $searchFormStructure['operatorType'];
                 } else {
                     $operatorType = null;
                 }
                 //setting a temp value is not ideal. But it avoids passing the parameter.
                 $oldAppendStructureAsAndValue = $this->appendStructureAsAnd;
                 if (isset($searchFormStructure['appendStructureAsAnd'])) {
                     $this->appendStructureAsAnd = $searchFormStructure['appendStructureAsAnd'];
                 } else {
                     $this->appendStructureAsAnd = false;
                 }
                 $this->populateClausesAndStructureForAttribute($model, $searchFormAttributeName, $searchFormStructure['value'], $adaptedMetadataClauses, $clauseCount, $tempStructure, $adaptedMetadataClauseBasePart, $operatorType, $depth);
                 $this->appendStructureAsAnd = $oldAppendStructureAsAndValue;
             }
         }
     }
     if ($tempStructure != null) {
         $tempStructure = '(' . $tempStructure . ')';
         if ($this->appendStructureAsAnd) {
             static::appendClauseAsAndToStructureString($structure, $tempStructure);
         } else {
             static::appendClauseAsOrToStructureString($structure, $tempStructure);
         }
     }
 }