/** * Module build * * @return mixed * @throws \Phalcon\Builder\BuilderException */ public function build() { if (!$this->options->contains('name')) { throw new BuilderException('You must specify the table name'); } if ($this->options->contains('directory')) { $this->path->setRootPath($this->options->get('directory')); } $config = $this->getConfig(); if (!($modelsDir = $this->options->get('modelsDir'))) { if (!$config->get('application') || !isset($config->get('application')->modelsDir)) { throw new BuilderException("Builder doesn't know where is the models directory."); } $modelsDir = $config->get('application')->modelsDir; } $modelsDir = rtrim($modelsDir, '/\\') . DIRECTORY_SEPARATOR; $modelPath = $modelsDir; if (false == $this->isAbsolutePath($modelsDir)) { $modelPath = $this->path->getRootPath($modelsDir); } $methodRawCode = array(); $className = $this->options->get('className'); $modelPath .= $className . '.php'; if (file_exists($modelPath) && !$this->options->contains('force')) { throw new BuilderException(sprintf('The model file "%s.php" already exists in models dir', $className)); } if (!isset($config->database)) { throw new BuilderException('Database configuration cannot be loaded from your config file.'); } if (!isset($config->database->adapter)) { throw new BuilderException("Adapter was not found in the config. " . "Please specify a config variable [database][adapter]"); } if (isset($config->devtools->loader)) { require_once $config->devtools->loader; } $namespace = ''; if ($this->options->contains('namespace') && $this->checkNamespace($this->options->get('namespace'))) { $namespace = 'namespace ' . $this->options->get('namespace') . ';' . PHP_EOL . PHP_EOL; } $genDocMethods = $this->options->get('genDocMethods', false); $useSettersGetters = $this->options->get('genSettersGetters', false); $adapter = $config->database->adapter; $this->isSupportedAdapter($adapter); $adapter = 'Mysql'; if (isset($config->database->adapter)) { $adapter = $config->database->adapter; } if (is_object($config->database)) { $configArray = $config->database->toArray(); } else { $configArray = $config->database; } // An array for use statements $uses = array(); $adapterName = 'Phalcon\\Db\\Adapter\\Pdo\\' . $adapter; unset($configArray['adapter']); /** @var \Phalcon\Db\Adapter\Pdo $db */ $db = new $adapterName($configArray); $initialize = array(); if ($this->options->contains('schema')) { $schema = $this->options->get('schema'); } else { $schema = Utils::resolveDbSchema($config->database); } if ($schema && $schema != $config->database->dbname) { $initialize['schema'] = $this->snippet->getThisMethod('setSchema', $schema); } $table = $this->options->get('name'); if ($this->options->get('fileName') != $table && !isset($initialize['schema'])) { $initialize[] = $this->snippet->getThisMethod('setSource', $table); } if (!$db->tableExists($table, $schema)) { throw new BuilderException(sprintf('Table "%s" does not exist.', $table)); } $fields = $db->describeColumns($table, $schema); foreach ($db->listTables() as $tableName) { foreach ($db->describeReferences($tableName, $schema) as $reference) { if ($reference->getReferencedTable() != $this->options->get('name')) { continue; } $entityNamespace = ''; if ($this->options->contains('namespace')) { $entityNamespace = $this->options->get('namespace') . "\\"; } $refColumns = $reference->getReferencedColumns(); $columns = $reference->getColumns(); $initialize[] = $this->snippet->getRelation('hasMany', $this->options->get('camelize') ? Utils::lowerCamelize($refColumns[0]) : $refColumns[0], $entityNamespace . Utils::camelize($tableName), $this->options->get('camelize') ? Utils::lowerCamelize($columns[0]) : $columns[0], "array('alias' => '" . Utils::camelize($tableName) . "')"); } } foreach ($db->describeReferences($this->options->get('name'), $schema) as $reference) { $entityNamespace = ''; if ($this->options->contains('namespace')) { $entityNamespace = $this->options->get('namespace') . "\\"; } $refColumns = $reference->getReferencedColumns(); $columns = $reference->getColumns(); $initialize[] = $this->snippet->getRelation('belongsTo', $this->options->get('camelize') ? Utils::lowerCamelize($columns[0]) : $columns[0], $entityNamespace . Utils::camelize($reference->getReferencedTable()), $this->options->get('camelize') ? Utils::lowerCamelize($refColumns[0]) : $refColumns[0], "array('alias' => '" . Utils::camelize($reference->getReferencedTable()) . "')"); } $alreadyInitialized = false; $alreadyValidations = false; $alreadyFind = false; $alreadyFindFirst = false; $alreadyColumnMapped = false; $alreadyGetSourced = false; if (file_exists($modelPath)) { try { $possibleMethods = array(); if ($useSettersGetters) { foreach ($fields as $field) { /** @var \Phalcon\Db\Column $field */ $methodName = Utils::camelize($field->getName()); $possibleMethods['set' . $methodName] = true; $possibleMethods['get' . $methodName] = true; } } $possibleMethods['getSource'] = true; require $modelPath; $linesCode = file($modelPath); $fullClassName = $this->options->get('className'); if ($this->options->contains('namespace')) { $fullClassName = $this->options->get('namespace') . '\\' . $fullClassName; } $reflection = new ReflectionClass($fullClassName); foreach ($reflection->getMethods() as $method) { if ($method->getDeclaringClass()->getName() != $fullClassName) { continue; } $methodName = $method->getName(); if (isset($possibleMethods[$methodName])) { continue; } $indent = PHP_EOL; if ($method->getDocComment()) { $firstLine = $linesCode[$method->getStartLine() - 1]; preg_match('#^\\s+#', $firstLine, $matches); if (isset($matches[0])) { $indent .= $matches[0]; } } $methodDeclaration = join('', array_slice($linesCode, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1)); $methodRawCode[$methodName] = $indent . $method->getDocComment() . PHP_EOL . $methodDeclaration; switch ($methodName) { case 'initialize': $alreadyInitialized = true; break; case 'validation': $alreadyValidations = true; break; case 'find': $alreadyFind = true; break; case 'findFirst': $alreadyFindFirst = true; break; case 'columnMap': $alreadyColumnMapped = true; break; case 'getSource': $alreadyGetSourced = true; break; } } } catch (ReflectionException $e) { } } $validations = array(); foreach ($fields as $field) { if ($field->getType() === Column::TYPE_CHAR) { if ($this->options->get('camelize')) { $fieldName = Utils::lowerCamelize($field->getName()); } else { $fieldName = $field->getName(); } $domain = array(); if (preg_match('/\\((.*)\\)/', $field->getType(), $matches)) { foreach (explode(',', $matches[1]) as $item) { $domain[] = $item; } } if (count($domain)) { $varItems = join(', ', $domain); $validations[] = $this->snippet->getValidateInclusion($fieldName, $varItems); } } if ($field->getName() == 'email') { if ($this->options->get('camelize')) { $fieldName = Utils::lowerCamelize($field->getName()); } else { $fieldName = $field->getName(); } $validations[] = $this->snippet->getValidateEmail($fieldName); $uses[] = $this->snippet->getUseAs('Phalcon\\Mvc\\Model\\Validator\\Email', 'Email'); } } if (count($validations)) { $validations[] = $this->snippet->getValidationFailed(); } // Check if there has been an extender class $extends = $this->options->get('extends', '\\Phalcon\\Mvc\\Model'); // Check if there have been any excluded fields $exclude = array(); if ($this->options->contains('excludeFields')) { $keys = explode(',', $this->options->get('excludeFields')); if (count($keys) > 0) { foreach ($keys as $key) { $exclude[trim($key)] = ''; } } } $attributes = array(); $setters = array(); $getters = array(); foreach ($fields as $field) { if (array_key_exists(strtolower($field->getName()), $exclude)) { continue; } $type = $this->getPHPType($field->getType()); $fieldName = $this->options->get('camelize') ? Utils::lowerCamelize($field->getName()) : $field->getName(); $attributes[] = $this->snippet->getAttributes($type, $useSettersGetters ? 'protected' : 'public', $field, $this->options->has('annotate'), $fieldName); if ($useSettersGetters) { $methodName = Utils::camelize($field->getName()); $setters[] = $this->snippet->getSetter($fieldName, $type, $methodName); if (isset($this->_typeMap[$type])) { $getters[] = $this->snippet->getGetterMap($fieldName, $type, $methodName, $this->_typeMap[$type]); } else { $getters[] = $this->snippet->getGetter($fieldName, $type, $methodName); } } } $validationsCode = ''; if ($alreadyValidations == false && count($validations) > 0) { $validationsCode = $this->snippet->getValidationsMethod($validations); } $initCode = ''; if ($alreadyInitialized == false && count($initialize) > 0) { $initCode = $this->snippet->getInitialize($initialize); } $license = ''; if (file_exists('license.txt')) { $license = trim(file_get_contents('license.txt')) . PHP_EOL . PHP_EOL; } if (false == $alreadyGetSourced) { $methodRawCode[] = $this->snippet->getModelSource($this->options->get('name')); } if (false == $alreadyFind) { $methodRawCode[] = $this->snippet->getModelFind($className); } if (false == $alreadyFindFirst) { $methodRawCode[] = $this->snippet->getModelFindFirst($className); } $content = join('', $attributes); if ($useSettersGetters) { $content .= join('', $setters) . join('', $getters); } $content .= $validationsCode . $initCode; foreach ($methodRawCode as $methodCode) { $content .= $methodCode; } $classDoc = ''; if ($genDocMethods) { $classDoc = $this->snippet->getClassDoc($className, $namespace); } if ($this->options->contains('mapColumn') && false == $alreadyColumnMapped) { $content .= $this->snippet->getColumnMap($fields, $this->options->get('camelize')); } $useDefinition = ''; if (!empty($uses)) { $useDefinition = join('', $uses) . PHP_EOL . PHP_EOL; } $abstract = $this->options->contains('abstract') ? 'abstract ' : ''; $code = $this->snippet->getClass($namespace, $useDefinition, $classDoc, $abstract, $className, $extends, $content, $license); if (file_exists($modelPath) && !is_writable($modelPath)) { throw new BuilderException(sprintf('Unable to write to %s. Check write-access of a file.', $modelPath)); } if (!file_put_contents($modelPath, $code)) { throw new BuilderException(sprintf('Unable to write to %s', $modelPath)); } if ($this->isConsole()) { $msgSuccess = ($this->options->contains('abstract') ? 'Abstract ' : '') . 'Model "%s" was successfully created.'; $this->_notifySuccess(sprintf($msgSuccess, Utils::camelize($this->options->get('name')))); } }
/** * @param \Phalcon\Db\ColumnInterface[] $fields * @param bool $camelize * @return string */ public function getColumnMap($fields, $camelize = false) { $template = <<<EOD /** * Independent Column Mapping. * Keys are the real names in the table and the values their names in the application * * @return array */ public function columnMap() { return array( %s ); } EOD; $contents = array(); foreach ($fields as $field) { $name = $field->getName(); $contents[] = sprintf('\'%s\' => \'%s\'', $name, $camelize ? Utils::lowerCamelize($name) : $name); } return PHP_EOL . sprintf($template, join(",\n ", $contents)) . PHP_EOL; }