public function testSingularize() { $testData = ['moves' => 'move', 'feet' => 'foot', 'children' => 'child', 'humans' => 'human', 'men' => 'man', 'staff' => 'staff', 'teeth' => 'tooth', 'people' => 'person', 'mice' => 'mouse', 'touches' => 'touch', 'hashes' => 'hash', 'shelves' => 'shelf', 'potatoes' => 'potato', 'buses' => 'bus', 'tests' => 'test', 'cars' => 'car']; foreach ($testData as $testIn => $testOut) { $this->assertEquals($testOut, Inflector::singularize($testIn)); $this->assertEquals(ucfirst($testOut), ucfirst(Inflector::singularize($testIn))); } }
public function getModelByTableName($name) { $returnName = str_replace($this->tablePrefix, '', $name); $returnName = Inflector::id2camel($returnName, '_'); if ($this->singularEntities) { $returnName = Inflector::singularize($returnName); } return $returnName; }
/** * Changes: * - load an AR model and use constant name * @param $modelClass namespace * @param $tableSuffix string new tables suffix, most often the model's table name in singular form with _changes appended, ex. order_status_changes * @param $relation string name of relation from model pointing to the main model, ex. orders * @param $schema */ public function actionCreate($modelClass, $tableSuffix, $relation, $schema = '') { $model = new $modelClass(); $modelRelation = $model->getRelation($relation); $mainModel = new $modelRelation->modelClass(); $name = 'm' . gmdate('ymd_His') . '_install_fsm'; $content = strtr($this->getTemplate(), ['{ClassName}' => $name, '{TableName}' => $model->tableName(), '{TableSuffix}' => $tableSuffix, '{Schema}' => !empty($schema) ? $schema . '.' : null, '{PrimaryKey}' => $model::primaryKey()[0], '{ForeignKey}' => Inflector::singularize($mainModel::tableName()) . '_id', '{MainTableName}' => $mainModel->tableName(), '{MainPrimaryKey}' => $mainModel::primaryKey()[0]]); $file = $this->migrationPath . DIRECTORY_SEPARATOR . $name . '.php'; if ($this->confirm("Create new migration '{$file}'?")) { file_put_contents($file, $content); echo "New migration created successfully.\n"; } }
/** * https://github.com/yiisoft/yii2/issues/1282#issuecomment-29071134 * https://github.com/yiisoft/yii2/issues/1282#issuecomment-29072322 * https://github.com/yiisoft/yii2/issues/1282#issuecomment-124382968 * @return array */ public function getModelRelations() { $db = $this->getDbConnection(); $modelClass = $this->modelClass; if ($this->isModelGenerator()) { $modelClass = $this->ns . '\\' . $this->modelClass; } $reflector = new \ReflectionClass($modelClass); $model = new $modelClass(); $className = StringHelper::basename($modelClass); $stack = []; $baseClassMethods = get_class_methods('yii\\db\\ActiveRecord'); foreach ($reflector->getMethods() as $i => $method) { if (in_array($method->name, $baseClassMethods)) { continue; } try { $relation = call_user_func([$model, $method->name]); if ($relation instanceof \yii\db\ActiveQuery) { $relationNameUppercase = str_replace('get', '', $method->name); $stack[$i]['name'] = $this->variablize($relationNameUppercase); $stack[$i]['nameUppercase'] = $relationNameUppercase; $stack[$i]['method'] = $method->name; $stack[$i]['isMultiple'] = $relation->multiple; $tableSchema = $db->getTableSchema($model::tableName()); $stack[$i]['isJunctionTable'] = $this->checkJunctionTable($tableSchema); //$stack[$i]['isJunctionTable'] = false; if ($relation->multiple) { /*TODO: (ruben) Make the detection of the NM table using ReflectionClass, not parsing text*/ $nameRelatedTablePlural = str_replace($className, '', str_replace('get', '', $method->name)); $nameRelatedTable = Inflector::singularize($nameRelatedTablePlural); $pkRelatedTable = $this->variablize($nameRelatedTable) . '_id'; $classNMName = Inflector::singularize($relationNameUppercase); $stack[$i]['pkRelatedTable'] = $pkRelatedTable; $stack[$i]['nameRelatedTable'] = $nameRelatedTable; $stack[$i]['variableRelatedTable'] = $this->variablize($nameRelatedTable); $stack[$i]['nameRelatedTablePlural'] = $nameRelatedTablePlural; $stack[$i]['nameRelatedTablePluralLowercase'] = $this->variablize($nameRelatedTablePlural); $stack[$i]['classNMName'] = $classNMName; /*TODO: change the way junction table is detected*/ //$stack[$i]['isJunctionTable'] = strlen(preg_replace('![^A-Z]+!', '', $classNMName)) > 1; } } } catch (UnknownMethodException $e) { continue; } catch (ErrorException $e) { continue; } } return $stack; }
// get relation info $ prepare add button $model = new $generator->modelClass(); $showAllRecords = false; if ($relation->via !== null) { $pivotName = Inflector::pluralize($generator->getModelByTableName($relation->via->from[0])); $pivotRelation = $model->{'get' . $pivotName}(); $pivotPk = key($pivotRelation->link); $addButton = " <?= {{html.a(\n '<span class=\"glyphicon glyphicon-link\"></span> Attach " . Inflector::singularize(Inflector::camel2words($name)) . "', ['" . $generator->createRelationRoute($pivotRelation, 'create') . "', '" . Inflector::singularize($pivotName) . "':{'" . key($pivotRelation->link) . "':\$model->{$model->primaryKey()[0]} } },\n {'class': 'btn btn-info btn-xs'}\n ) }} \n"; } else { $addButton = ''; } // relation list, add, create buttons echo "<p class='pull-right'>\n"; echo " <?= {{html.a(\n '<span class=\"glyphicon glyphicon-list\"></span> List All " . Inflector::camel2words($name) . "',\n {'" . $generator->createRelationRoute($relation, 'index') . "'},\n {'class': 'btn btn-muted btn-xs'}\n ) }} \n"; // TODO: support multiple PKs, VarDumper? echo " <?= {{html.a(\n '<span class=\"glyphicon glyphicon-plus\"></span> New " . Inflector::singularize(Inflector::camel2words($name)) . "',\n {'" . $generator->createRelationRoute($relation, 'create') . "', '" . Inflector::singularize($name) . "': {'" . key($relation->link) . "':\$model->" . $model->primaryKey()[0] . "} },\n {'class': 'btn btn-success btn-xs'}\n ) }} \n"; echo $addButton; echo "</p><div class='clearfix'></div>\n"; // render pivot grid if ($relation->via !== null) { $pjaxId = "pjax-{$pivotName}"; $gridRelation = $pivotRelation; $gridName = $pivotName; } else { $pjaxId = "pjax-{$name}"; $gridRelation = $relation; $gridName = $name; } $output = $generator->relationGrid([$gridRelation, $gridName, $showAllRecords]); // render relation grid if (!empty($output)) {
/** * Get foreign model name. * * @param [[@doctodo param_type:tableName]] $tableName [[@doctodo param_description:tableName]] * * @return [[@doctodo return_type:getForeignModelName]] [[@doctodo return_description:getForeignModelName]] */ public function getForeignModelName($tableName) { return Inflector::singularize(Inflector::id2camel($tableName, '_')); }
public function validateClass($attribute, $params) { if ($this->singularEntities) { $this->{$attribute} = Inflector::singularize($this->{$attribute}); } parent::validateClass($attribute, $params); }
/** * Generates a class name from the specified table name. * @param string $tableName the table name (which may contain schema prefix) * @return string the generated class name */ protected function generateClassName($tableName) { if (isset($this->_classNames[$tableName])) { return $this->_classNames[$tableName]; } if (($pos = strrpos($tableName, '.')) !== false) { $tableName = substr($tableName, $pos + 1); } $db = $this->getDbConnection(); $patterns = []; $patterns[] = "/^{$db->tablePrefix}(.*?)\$/"; $patterns[] = "/^(.*?){$db->tablePrefix}\$/"; if (strpos($this->tableName, '*') !== false) { $pattern = $this->tableName; if (($pos = strrpos($pattern, '.')) !== false) { $pattern = substr($pattern, $pos + 1); } $patterns[] = '/^' . str_replace('*', '(\\w+)', $pattern) . '$/'; } $className = $tableName; foreach ($patterns as $pattern) { if (preg_match($pattern, $tableName, $matches)) { $className = $matches[1]; break; } } $className = Inflector::id2camel($className, '_'); $className = preg_split('/(?=[A-Z])/', $className); $lastName = array_pop($className); $lastName = Inflector::singularize($lastName); array_push($className, $lastName); $className = implode($className); return $this->_classNames[$tableName] = $className; }
$pivotRelation = $model->{'get' . $pivotName}(); $pjaxId = "pjax-{$pivotName}"; $gridRelation = $pivotRelation; $gridName = $pivotName; } else { $pjaxId = "pjax-{$name}"; $gridRelation = $relation; $gridName = $name; } $gridModel = new $gridRelation->modelClass(); $showAllRecords = false; if ($relation->via !== null) { $pivotName = Inflector::pluralize($generator->getModelByTableName($relation->via->from[0])); $pivotRelation = $model->{'get' . $pivotName}(); $pivotPk = key($pivotRelation->link); $addButton = " <?= Html::a(\n '<span class=\"glyphicon glyphicon-link\"></span> ' . " . $generator->generateString('Attach') . " . ' " . Inflector::singularize(Inflector::camel2words($name)) . "', ['" . $generator->createRelationRoute($pivotRelation, 'create') . "', '" . Inflector::singularize($pivotName) . "'=>['" . key($pivotRelation->link) . "'=>\$model->{$model->primaryKey()[0]}]],\n ['class'=>'btn btn-info btn-xs']\n ) ?>\n"; } else { $addButton = ''; } // HEADER, relation list, add, create buttons $headerLabel = Inflector::camel2words($name); echo "\n <div class=\"clearfix crud-navigation\">\n <div class=\"pull-left\">\n <h2>" . $headerLabel . "</h2>\n </div> \n <div class=\"pull-right\">\n <div class=\"btn-group\">\n <?= Html::a(\n '<span class=\"glyphicon glyphicon-list\"></span> ' . " . $generator->generateString('List All') . " . ' " . Inflector::camel2words($name) . "',\n ['" . $generator->createRelationRoute($relation, 'index') . "'],\n ['class'=>'btn text-muted btn-xs']\n ) ?>\n <?= Html::a(\n '<span class=\"glyphicon glyphicon-plus\"></span> ' . " . $generator->generateString('New') . ",\n ['" . $generator->createRelationRoute($relation, 'create') . "', '" . $gridModel->formName() . "' => ['" . key($relation->link) . "' => \$model->" . $model->primaryKey()[0] . "]],\n ['class'=>'btn btn-success btn-xs']\n ); \n ?>\n <?= Html::a(\n '<span class=\"glyphicon glyphicon-plus\"></span> ' . " . $generator->generateString('Add row') . ",\n ['" . $generator->createRelationRoute($relation, 'create-for-rel') . "', '" . $gridModel->formName() . "' => ['" . key($relation->link) . "' => \$model->" . $model->primaryKey()[0] . "]],\n ['class'=>'btn btn-success btn-xs']\n );?>\n " . $addButton . " \n </div>\n </div>\n </div>\n"; $output = $generator->relationGridEditable($gridName, $gridRelation, $showAllRecords); // render relation grid if (!empty($output)) { echo "<?php Pjax::begin(['id'=>'pjax-{$name}', 'enableReplaceState'=> false, 'linkSelector'=>'#pjax-{$name} ul.pagination a, th a', 'clientOptions' => ['pjax:success'=>'function(){alert(\"yo\")}']]) ?>\n"; echo ' <div class="table-responsive">' . PHP_EOL; echo ' <?php ' . $output . "?>\n"; echo ' </div>' . PHP_EOL; echo "<?php Pjax::end() ?>\n"; }
/** * Get model's singular name. * * @param string|\yii\db\ActiveRecord $model * @return string */ public function getSingularName($model) { if (is_string($model)) { $model = $this->loadModel($model); } if (!isset($model->adminNames)) { return Inflector::singularize(Inflector::camel2words(StringHelper::basename($model->className()))); } else { return $model->adminNames[1]; } }
/** * @param array $generatedRelations * @return array */ protected function fixRelations(array $generatedRelations) { foreach ($generatedRelations as $tableName => $tableRelations) { $fixRelationNames = []; foreach ($tableRelations as $relationName => $relation) { if (preg_match('~^(\\D+)\\d+$~', $relationName, $match)) { $fixRelationNames[] = $match[1]; } } foreach ($fixRelationNames as $fixRelationName) { foreach ($tableRelations as $relationName => $relation) { if ($relationName == $fixRelationName) { if (isset($tableRelations[$relationName])) { $tableRelations[$relationName . '99'] = $tableRelations[$relationName]; unset($tableRelations[$relationName]); } if (isset($generatedRelations[$tableName][$relationName])) { $generatedRelations[$tableName][$relationName . '99'] = $generatedRelations[$tableName][$relationName]; unset($generatedRelations[$tableName][$relationName]); } if (isset($this->allRelations[$tableName][$relationName])) { $this->allRelations[$tableName][$relationName . '99'] = $this->allRelations[$tableName][$relationName]; unset($this->allRelations[$tableName][$relationName]); } if (isset($this->singularRelations[$tableName][$relationName])) { $this->singularRelations[$tableName][$relationName . '99'] = $this->singularRelations[$tableName][$relationName]; unset($this->singularRelations[$tableName][$relationName]); } if (isset($this->pluralRelations[$tableName][$relationName])) { $this->pluralRelations[$tableName][$relationName . '99'] = $this->pluralRelations[$tableName][$relationName]; unset($this->pluralRelations[$tableName][$relationName]); } } } } foreach ($fixRelationNames as $fixRelationName) { foreach ($tableRelations as $relationName => $relation) { if (preg_match('~^(\\D+)\\d+$~', $relationName, $match) && $match[1] == $fixRelationName) { $relation = $this->allRelations[$tableName][$relationName]; if ($relation['hasMany']) { $linkKeys = array_keys($relation['link']); if (count($linkKeys) == 1) { $linkKey = preg_replace('~_id$~', '', $linkKeys[0]); if ($tableName == $linkKey) { $relationName2 = $fixRelationName; } else { $relationName2 = Inflector::classify($linkKey); $relationName2 = str_replace(Inflector::singularize($fixRelationName), '', $relationName2); $relationName2 .= $fixRelationName; } echo $relationName, ' -> ', $relationName2, "\n"; if (isset($tableRelations[$relationName])) { $tableRelations[$relationName2] = $tableRelations[$relationName]; unset($tableRelations[$relationName]); } if (isset($generatedRelations[$tableName][$relationName])) { $generatedRelations[$tableName][$relationName2] = $generatedRelations[$tableName][$relationName]; unset($generatedRelations[$tableName][$relationName]); } if (isset($this->allRelations[$tableName][$relationName])) { $this->allRelations[$tableName][$relationName2] = $this->allRelations[$tableName][$relationName]; unset($this->allRelations[$tableName][$relationName]); } if (isset($this->singularRelations[$tableName][$relationName])) { $this->singularRelations[$tableName][$relationName2] = $this->singularRelations[$tableName][$relationName]; unset($this->singularRelations[$tableName][$relationName]); } if (isset($this->pluralRelations[$tableName][$relationName])) { $this->pluralRelations[$tableName][$relationName2] = $this->pluralRelations[$tableName][$relationName]; unset($this->pluralRelations[$tableName][$relationName]); } } } } } } } return $generatedRelations; }
protected function typeToFormName($type) { return Inflector::id2camel(Inflector::singularize($type)); }
* @inheritdoc */ // public function getTitleText() // { // return $this->', implode(' . static::TITLE_SEPARATOR . $this->', $titleKey->key), '; // } '; } // methods "new" foreach ($allRelations as $relationName => $relation) { if (!$relation['direct'] && !$relation['viaTable']) { if ($relation['hasMany']) { if (preg_match('~^(.*\\D)(\\d+)$~', $relationName, $match)) { $methodName = 'new' . Inflector::singularize($match[1]) . $match[2]; } else { $methodName = 'new' . Inflector::singularize($relationName); } } else { $methodName = 'new' . $relationName; } if (!in_array($methodName, $methods)) { $methods[] = $methodName; echo ' /** * @param array $config * @return ', $relation['className'], ' */ public function ', $methodName, '(array $config = []) { $model = new ', $relation['className'], '($config); ';
/** * Generates a class name from the specified table name. * * @param string $tableName the table name (which may contain schema prefix) * * @return string the generated class name */ public function generateClassName($tableName, $useSchemaName = null) { #Yii::trace("Generating class name for '{$tableName}'...", __METHOD__); if (isset($this->classNames2[$tableName])) { #Yii::trace("Using '{$this->classNames2[$tableName]}' for '{$tableName}' from classNames2.", __METHOD__); return $this->classNames2[$tableName]; } if (isset($this->tableNameMap[$tableName])) { Yii::trace("Converted '{$tableName}' from tableNameMap.", __METHOD__); return $this->classNames2[$tableName] = $this->tableNameMap[$tableName]; } if (($pos = strrpos($tableName, '.')) !== false) { $tableName = substr($tableName, $pos + 1); } $db = $this->getDbConnection(); $patterns = []; $patterns[] = "/^{$this->tablePrefix}(.*?)\$/"; $patterns[] = "/^(.*?){$this->tablePrefix}\$/"; $patterns[] = "/^{$db->tablePrefix}(.*?)\$/"; $patterns[] = "/^(.*?){$db->tablePrefix}\$/"; if (strpos($this->tableName, '*') !== false) { $pattern = $this->tableName; if (($pos = strrpos($pattern, '.')) !== false) { $pattern = substr($pattern, $pos + 1); } $patterns[] = '/^' . str_replace('*', '(\\w+)', $pattern) . '$/'; } $className = $tableName; foreach ($patterns as $pattern) { if (preg_match($pattern, $tableName, $matches)) { $className = $matches[1]; Yii::trace("Mapping '{$tableName}' to '{$className}' from pattern '{$pattern}'.", __METHOD__); break; } } $returnName = Inflector::id2camel($className, '_'); if ($this->singularEntities) { $returnName = Inflector::singularize($returnName); } Yii::trace("Converted '{$tableName}' to '{$returnName}'.", __METHOD__); return $this->classNames2[$tableName] = $returnName; }
/** * @inheritdoc */ public function parseRequest($manager, $request) { $modelName = Inflector::camel2id(StringHelper::basename($this->modelClass)); $resourceName = isset($this->resourceName) ? $this->resourceName : Inflector::pluralize($modelName); $link_attribute = isset($this->linkAttribute) ? $this->linkAttribute : $modelName . '_id'; $this->config['prefix'] = $resourceName . '/<' . $link_attribute . ':\\d+>'; foreach ($this->relations as $key => $value) { if (is_int($key)) { $relation = $value; $urlName = Inflector::camel2id(Inflector::pluralize($relation)); $controller = Inflector::camel2id(Inflector::singularize($relation)); } else { $relation = $key; if (is_array($value)) { list($urlName, $controller) = each($value); } else { $urlName = Inflector::camel2id(Inflector::pluralize($relation)); $controller = $value; } } if (YII_DEBUG) { (new $this->modelClass())->getRelation($relation); } $modulePrefix = isset($this->modulePrefix) ? $this->modulePrefix . '/' : ''; $this->config['controller'][$urlName] = $modulePrefix . $controller; $this->setRulesFactory($this->config); $routeObj = $this->rulesFactory->parseRequest($manager, $request); if ($routeObj) { $routeObj[1]['relativeClass'] = $this->modelClass; $routeObj[1]['relationName'] = $relation; $routeObj[1]['linkAttribute'] = $link_attribute; return $routeObj; } } return false; }
foreach ($generator->getModelRelations($generator->modelClass, ['has_many']) as $name => $relation) { echo "\n<?php \$this->beginBlock('{$name}'); ?>\n"; $showAllRecords = false; if ($relation->via !== null) { $pivotName = Inflector::pluralize($generator->getModelByTableName($relation->via->from[0])); $pivotRelation = $model->{'get' . $pivotName}(); $pivotPk = key($pivotRelation->link); $addButton = " <?= Html::a(\n '<span class=\"glyphicon glyphicon-link\"></span> ' . " . $generator->generateString('Attach') . " . ' " . Inflector::singularize(Inflector::camel2words($name)) . "', ['" . $generator->createRelationRoute($pivotRelation, 'create') . "', '" . Inflector::singularize($pivotName) . "'=>['" . key($pivotRelation->link) . "'=>\$model->{$model->primaryKey()[0]}]],\n ['class'=>'btn btn-info btn-xs']\n ) ?>\n"; } else { $addButton = ''; } // relation list, add, create buttons echo "<div style='position: relative'><div style='position:absolute; right: 0px; top: 0px;'>\n"; echo " <?= Html::a(\n '<span class=\"glyphicon glyphicon-list\"></span> ' . " . $generator->generateString('List All') . " . ' " . Inflector::camel2words($name) . "',\n ['" . $generator->createRelationRoute($relation, 'index') . "'],\n ['class'=>'btn text-muted btn-xs']\n ) ?>\n"; // TODO: support multiple PKs echo " <?= Html::a(\n '<span class=\"glyphicon glyphicon-plus\"></span> ' . " . $generator->generateString('New') . " . ' " . Inflector::singularize(Inflector::camel2words($name)) . "',\n ['" . $generator->createRelationRoute($relation, 'create') . "', '" . Inflector::singularize($name) . "' => ['" . key($relation->link) . "' => \$model->" . $model->primaryKey()[0] . "]],\n ['class'=>'btn btn-success btn-xs']\n ); ?>\n"; echo $addButton; echo "</div></div>"; #<div class='clearfix'></div>\n"; // render pivot grid if ($relation->via !== null) { $pjaxId = "pjax-{$pivotName}"; $gridRelation = $pivotRelation; $gridName = $pivotName; } else { $pjaxId = "pjax-{$name}"; $gridRelation = $relation; $gridName = $name; } $output = $generator->relationGrid($gridName, $gridRelation, $showAllRecords); // render relation grid
// get relation info $ prepare add button $model = new $generator->modelClass(); $showAllRecords = false; if ($relation->via !== null) { $pivotName = Inflector::pluralize($generator->getModelByTableName($relation->via->from[0])); $pivotRelation = $model->{'get' . $pivotName}(); $pivotPk = key($pivotRelation->link); $addButton = " <?= \\yii\\helpers\\Html::a('<span class=\"glyphicon glyphicon-link\"></span> Attach " . Inflector::singularize(Inflector::camel2words($name)) . "', ['" . $generator->createRelationRoute($pivotRelation, 'create') . "', '" . Inflector::singularize($pivotName) . "'=>['" . key($pivotRelation->link) . "'=>\$model->{$model->primaryKey()[0]}]], ['class'=>'btn btn-info btn-xs']) ?>\n"; } else { $addButton = ''; } // relation list, add, create buttons echo "\t<p class='pull-right'>\n"; echo "\t\t<?= \\yii\\helpers\\Html::a('<span class=\"glyphicon glyphicon-list\"></span> List All " . Inflector::camel2words($name) . "', ['" . $generator->createRelationRoute($relation, 'index') . "'], ['class'=>'btn text-muted btn-xs'] ) ?>\n"; // TODO: support multiple PKs, VarDumper? echo "\t\t<?= \\yii\\helpers\\Html::a('<span class=\"glyphicon glyphicon-plus\"></span> New " . Inflector::singularize(Inflector::camel2words($name)) . "', ['" . $generator->createRelationRoute($relation, 'create') . "', '" . Inflector::singularize($name) . "'=>['" . key($relation->link) . "'=>\$model->" . $model->primaryKey()[0] . "]], ['class'=>'btn btn-success btn-xs']) ?>\n"; echo $addButton; echo "\t</p>\n\n"; echo "\t<div class='clearfix'></div>\n\n"; // render pivot grid if ($relation->via !== null) { $pjaxId = "pjax-{$pivotName}"; $gridRelation = $pivotRelation; $gridName = $pivotName; } else { $pjaxId = "pjax-{$name}"; $gridRelation = $relation; $gridName = $name; } $output = $generator->relationGrid([$gridRelation, $gridName, $showAllRecords]); // render relation grid
/** * Generates a class name from the specified table name. * @param string $tableName the table name (which may contain schema prefix) * @param boolean $useSchemaName should schema name be included in the class name, if present * @return string the generated class name */ protected function generateClassName($tableName, $useSchemaName = null) { if (isset($this->classNames[$tableName])) { return $this->classNames[$tableName]; } $className = $this->baseGenerateClassName($tableName, $useSchemaName); return $this->classNames[$tableName] = Inflector::singularize($className); }