/** * @param string $modelName * @param string $relationName * @return array * @throws \Exception if not found relation info */ public static function calculateRelationVariables($modelName, $relationName) { $relationName = Inflector::underscore($relationName); if (!empty(self::$_variablesCache[$modelName . $relationName])) { return self::$_variablesCache[$modelName . $relationName]; } $modelStructure = ModelStructure::getInstanceForModel($modelName); $relationInfo = $modelStructure->getRelationInfo($relationName); if (is_null($relationInfo)) { throw new \Exception('Relation ' . $relationName . ' is not found, probably capitalization'); } if (!is_array($relationInfo)) { $relationInfo = array(); } $info = array(); $info['localTable'] = $modelStructure->getTableName(); foreach ($relationInfo as $key => $value) { $info[lcfirst(Inflector::camelize($key))] = $value; } if (!isset($info['model']) && !isset($info['table'])) { $info['model'] = ucfirst(Inflector::singularize($relationName)); } if (isset($info['model'])) { $relatedStructure = ModelStructure::getInstanceForModel($info['model']); $info['foreignTable'] = $relatedStructure->getTableName(); $info['relatedModelName'] = $info['model']; $info['hydration'] = 'model'; unset($info['model']); } else { $info['relatedModelName'] = ucfirst(Inflector::singularize($info['table'])); $info['foreignTable'] = $info['table']; unset($info['table']); $info['hydration'] = 'simple'; if (empty($info['fields'])) { $info['fields'] = '*'; } $info['fieldsToRetrieve'] = $info['fields']; unset($info['fields']); $relatedStructure = null; } if (!isset($info['localKey'])) { $info['localKey'] = $modelStructure->getPrimaryKey(); } if (!isset($info['foreignKey'])) { $info['foreignKey'] = empty($relatedStructure) ? 'id' : $relatedStructure->getPrimaryKey(); } $foreignTable = $relatedStructure ? $relatedStructure->getTableName() : (isset($info['table']) ? $info['table'] : $relationName); $autoLocalField = 'id_' . Inflector::underscore($info['relatedModelName']); $autoForeignField = 'id_' . Inflector::underscore($modelName); $hasLocalField = false; $hasForeignField = false; if ($info['hydration'] == 'model') { if ($relatedStructure->hasColumn($autoForeignField)) { if (empty($info['type'])) { $info['type'] = 'one_to_many'; } if (empty($info['foreignField'])) { $info['foreignField'] = $autoForeignField; } $hasForeignField = true; } if ($modelStructure->hasColumn($autoLocalField)) { if (empty($info['type'])) { $info['type'] = 'many_to_one'; } if (empty($info['localField'])) { $info['localField'] = $autoLocalField; } $hasLocalField = true; } if (!$hasForeignField && !$hasLocalField) { if (empty($info['type'])) { $info['type'] = 'many_to_many'; } if (empty($info['foreignField'])) { $info['foreignField'] = $autoForeignField; } if (empty($info['localField'])) { $info['localField'] = $autoLocalField; } } } $info['relationToMany'] = substr($info['type'], -4) == 'many' ? true : false; $info['relationType'] = $info['type']; unset($info['type']); if (strpos($info['relatedModelName'], '\\') === false) { $info['relatedModelName'] = 'Entities\\' . $info['relatedModelName']; } if (empty($info['manyTable'])) { $info['manyTable'] = $info['localTable'] > $foreignTable ? $info['localTable'] . '_' . $foreignTable : $foreignTable . '_' . $info['localTable']; } self::$_variablesCache[$modelName . $relationName] = $info; return $info; }
/** * Updates many to many tables * @param $info * @return mixed */ public function updateManyTable($info) { $structure = array('table' => $info['manyTable'], 'columns' => array(), 'indexes' => array(), 'constraints' => array()); $localName = Inflector::singularize($info['localTable']); $foreignName = Inflector::singularize($info['foreignTable']); $structure['columns']['id'] = array('type' => 'int(11) unsigned', 'auto_increment' => true); $structure['columns']['id_' . $localName] = 'int(11) unsigned'; $structure['columns']['id_' . $foreignName] = 'int(11) unsigned'; $structure['indexes']['primary'] = array('columns' => array('id'), 'type' => 'primary'); $structure['indexes']['unique_id_' . $localName . '_id_' . $foreignName] = array('columns' => array('id_' . $localName, 'id_' . $foreignName), 'type' => 'unique'); $foreignKeysInfo = array('local_table' => $info['manyTable'], 'foreign_table' => $info['localTable'], 'local_field' => 'id_' . $localName, 'foreign_field' => $info['foreignKey']); $structure['constraints'][$this->generateForeignKeyName($foreignKeysInfo)] = $foreignKeysInfo; $foreignKeysInfo = array('local_table' => $info['manyTable'], 'foreign_table' => $info['foreignTable'], 'local_field' => 'id_' . $foreignName, 'foreign_field' => $info['foreignKey']); $structure['constraints'][$this->generateForeignKeyName($foreignKeysInfo)] = $foreignKeysInfo; $diffs = $this->getDifferenceSQL($structure, $info['manyTable']); if ($diffs['result'] === true) { QC::executeSQL('SET FOREIGN_KEY_CHECKS = 0'); if (!empty($diffs['sql']['ADD'])) { try { QC::executeArrayOfSQL($diffs['sql']['ADD']); } catch (\Exception $e) { var_dump($e->getMessage()); die; } } } return $diffs['result']; }
public function testSingularize() { $this->assertEquals('winner', Inflector::singularize('winners'), 'simple singularization'); $this->assertEquals('man', Inflector::singularize('men'), 'the \'man\' word'); $this->assertEquals('person', Inflector::singularize('people'), 'the exceptions word'); }