/**
  * Generates Table schema for a model class using its metadata of members, relations, mixins and indexes.
  * @param string $modelClassName
  * @param $messageLogger
  * @return array|bool
  */
 public static function resolve($modelClassName, &$messageLogger)
 {
     if (empty($modelClassName) || !@class_exists($modelClassName) || !$modelClassName::getCanHaveBean()) {
         return false;
     }
     $metadata = $modelClassName::getMetadata();
     $modelMetadata = array();
     if (isset($metadata[$modelClassName])) {
         $modelMetadata = $metadata[$modelClassName];
     }
     $memberColumns = array();
     $relationColumns = array();
     $indexes = array();
     $uniqueIndexesFromValidators = array();
     $parentColumnName = null;
     if (isset($modelMetadata['members'])) {
         if (!isset($modelMetadata['rules'])) {
             $errorMessage = Zurmo::t('Core', '{{model}} must have both, members and rules, set.', array('{{model}}' => $modelClassName));
             $messageLogger->addErrorMessage($errorMessage);
             throw new CException($errorMessage);
         }
         $memberColumns = RedBeanModelMemberRulesToColumnsAdapter::resolve($modelClassName, $modelMetadata['members'], $modelMetadata['rules'], $messageLogger);
         $uniqueIndexesFromValidators = RedBeanModelMemberRulesToColumnAdapter::resolveUniqueIndexesFromValidator($modelClassName);
     }
     if (isset($modelMetadata['relations'])) {
         $relationColumns = RedBeanModelRelationsToColumnsAdapter::resolve($modelClassName, $modelMetadata['relations'], $messageLogger);
     }
     if (isset($modelMetadata['indexes']) || !empty($uniqueIndexesFromValidators)) {
         $indexesMetadata = $uniqueIndexesFromValidators;
         if (!empty($modelMetadata['indexes'])) {
             if (!empty($indexesMetadata)) {
                 $indexesMetadata = CMap::mergeArray($indexesMetadata, $modelMetadata['indexes']);
             } else {
                 $indexesMetadata = $modelMetadata['indexes'];
             }
         }
         if (!empty($indexesMetadata)) {
             $indexes = RedBeanModelMemberIndexesMetadataAdapter::resolve($modelClassName, $indexesMetadata, $messageLogger);
         }
     }
     $parentColumnName = RedBeanModelChildParentRelationshipToColumnAdapter::resolve($modelClassName);
     if ($parentColumnName) {
         $memberColumns[] = $parentColumnName;
     }
     $mixinColumns = RedBeanModelMixinsToColumnsAdapter::resolve($modelClassName, $messageLogger);
     $columns = CMap::mergeArray($memberColumns, $mixinColumns, $relationColumns);
     $tableName = $modelClassName::getTableName();
     $schemaDefinition = array($tableName => array('columns' => $columns, 'indexes' => $indexes));
     return $schemaDefinition;
 }
 /**
  * @depends testResolveWithOnlyRequiredValidatorForMember
  */
 public function testResolveWithMixedRules()
 {
     $modelClassName = 'AuditEvent';
     $expectedColumns = array(array('name' => 'type', 'type' => 'INT(11)', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => null, 'default' => 'DEFAULT NULL'), array('name' => 'modelclassname', 'type' => 'VARCHAR(64)', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => 'COLLATE utf8_unicode_ci', 'default' => 'DEFAULT NULL'), array('name' => 'name', 'type' => 'VARCHAR(64)', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => 'COLLATE utf8_unicode_ci', 'default' => 'DEFAULT NULL'), array('name' => 'subject', 'type' => 'VARCHAR(64)', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => 'COLLATE utf8_unicode_ci', 'default' => 'DEFAULT NULL'), array('name' => 'language', 'type' => 'VARCHAR(2)', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => 'COLLATE utf8_unicode_ci', 'default' => 'DEFAULT NULL'), array('name' => 'htmlcontent', 'type' => 'TEXT', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => 'COLLATE utf8_unicode_ci', 'default' => 'DEFAULT NULL'), array('name' => 'textcontent', 'type' => 'TEXT', 'unsigned' => null, 'notNull' => 'NULL', 'collation' => 'COLLATE utf8_unicode_ci', 'default' => 'DEFAULT NULL'));
     $members = array('type', 'modelClassName', 'name', 'subject', 'language', 'htmlContent', 'textContent');
     $rules = array(array('type', 'required'), array('type', 'type', 'type' => 'integer'), array('type', 'numerical'), array('modelClassName', 'required'), array('modelClassName', 'type', 'type' => 'string'), array('modelClassName', 'length', 'max' => 64), array('modelClassName', 'ModelExistsAndIsReadableValidator'), array('name', 'required'), array('name', 'type', 'type' => 'string'), array('name', 'length', 'min' => 3, 'max' => 64), array('subject', 'required'), array('subject', 'type', 'type' => 'string'), array('subject', 'length', 'min' => 3, 'max' => 64), array('language', 'type', 'type' => 'string'), array('language', 'length', 'min' => 2, 'max' => 2), array('language', 'SetToUserDefaultLanguageValidator'), array('htmlContent', 'type', 'type' => 'string'), array('textContent', 'type', 'type' => 'string'), array('htmlContent', 'AtLeastOneContentAreaRequiredValidator'), array('textContent', 'AtLeastOneContentAreaRequiredValidator'), array('htmlContent', 'EmailTemplateMergeTagsValidator'), array('textContent', 'EmailTemplateMergeTagsValidator'));
     $columns = RedBeanModelMemberRulesToColumnsAdapter::resolve($modelClassName, $members, $rules, static::$messageLogger);
     $this->assertNotEmpty($columns);
     $this->assertCount(7, $columns);
     foreach ($columns as $index => $column) {
         $this->assertCount(6, $column);
         $this->assertArrayHasKey('name', $column);
         $this->assertArrayHasKey('type', $column);
         $this->assertArrayHasKey('unsigned', $column);
         $this->assertArrayHasKey('notNull', $column);
         $this->assertArrayHasKey('collation', $column);
         $this->assertArrayHasKey('default', $column);
         $this->assertEquals($expectedColumns[$index], $column);
     }
 }