예제 #1
0
 /**
  * @return bool
  * @throws \Exception
  */
 public function build()
 {
     $options = $this->_options;
     if (Tools::getDb()) {
         $config = Tools::getDb();
     }
     if (!isset($config->adapter)) {
         throw new \Exception("Adapter was not found in the config. Please specify a config variable [database][adapter]");
     }
     $adapter = ucfirst($config->adapter);
     $this->isSupportedAdapter($adapter);
     $di = new FactoryDefault();
     $di->set('db', function () use($adapter, $config) {
         if (isset($config->adapter)) {
             $adapter = $config->adapter;
         } else {
             $adapter = 'Mysql';
         }
         if (is_object($config)) {
             $configArray = $config->toArray();
         } else {
             $configArray = $config;
         }
         $adapterName = 'Phalcon\\Db\\Adapter\\Pdo\\' . $adapter;
         unset($configArray['adapter']);
         return new $adapterName($configArray);
     });
     $options['manager'] = $di->getShared('modelsManager');
     $options['className'] = $options['name'];
     $options['fileName'] = str_replace('_', '-', Text::uncamelize($options['className']));
     $modelsNamespace = $options['modelsNamespace'];
     if (isset($modelsNamespace) && substr($modelsNamespace, -1) !== '\\') {
         $modelsNamespace .= "\\";
     }
     $modelName = $options['name'];
     $modelClass = $modelsNamespace . $modelName;
     if (!@dir($options['modelsDir'])) {
         if (!@mkdir($options['modelsDir'])) {
             throw new \Exception('Could not create directory on ' . $options['modelsDir']);
         }
         @chmod($options['modelsDir'], 0777);
     }
     $modelPath = $options['modelsDir'] . DIRECTORY_SEPARATOR . $modelName . '.php';
     if (!file_exists($modelPath)) {
         $modelBuilder = new ModelBuilder(array('module' => $options['module'], 'name' => null, 'tableName' => $options['tableName'], 'schema' => $options['schema'], 'baseClass' => null, 'namespace' => $options['modelsNamespace'], 'foreignKeys' => true, 'defineRelations' => true, 'genSettersGetters' => $options['genSettersGetters'], 'directory' => $options['modelsDir'], 'force' => $options['force']));
         $modelBuilder->build();
     }
     if (!class_exists($modelClass)) {
         require_once $modelPath;
     }
     $entity = new $modelClass();
     $metaData = $di['modelsMetadata'];
     $attributes = $metaData->getAttributes($entity);
     $dataTypes = $metaData->getDataTypes($entity);
     $identityField = $metaData->getIdentityField($entity);
     $primaryKeys = $metaData->getPrimaryKeyAttributes($entity);
     $setParams = array();
     $selectDefinition = array();
     $relationField = '';
     $options['name'] = Text::uncamelize($options['name']);
     $options['plural'] = $this->_getPossiblePlural($options['name']);
     $options['singular'] = $this->_getPossibleSingular($options['name']);
     $options['modelClass'] = $options['modelsNamespace'] . '\\' . $this->_options['name'];
     $options['entity'] = $entity;
     $options['setParams'] = $setParams;
     $options['attributes'] = $attributes;
     $options['dataTypes'] = $dataTypes;
     $options['primaryKeys'] = $primaryKeys;
     $options['identityField'] = $identityField;
     $options['relationField'] = $relationField;
     $options['selectDefinition'] = $selectDefinition;
     $options['autocompleteFields'] = array();
     $options['belongsToDefinitions'] = array();
     //Build Controller
     $this->_makeController($options);
     if (isset($options['templateEngine']) && $options['templateEngine'] == 'volt') {
         //View layouts
         //    $this->_makeLayoutsVolt($options);
         //View index.phtml
         $this->_makeViewIndexVolt(null, $options);
         //View search.phtml
         $this->_makeViewSearchVolt(null, $options);
         //View new.phtml
         $this->_makeViewNewVolt(null, $options);
         //View edit.phtml
         $this->_makeViewEditVolt(null, $options);
     } else {
         //View layouts
         //     $this->_makeLayouts(null, $options);
         //View index.phtml
         $this->_makeViewIndex(null, $options);
         //View search.phtml
         $this->_makeViewSearch(null, $options);
         //View new.phtml
         $this->_makeViewNew(null, $options);
         //View edit.phtml
         $this->_makeViewEdit(null, $options);
     }
     return true;
 }
예제 #2
0
    public function build()
    {
        $getSource = "\n    public function getSource()\n    {\n        return '%s';\n    }\n";
        $templateThis = "        \$this->%s(%s);" . PHP_EOL;
        $templateRelation = "        \$this->%s('%s', '%s', '%s', %s);" . PHP_EOL;
        $templateSetter = "\n    /**\n     * Method to set the value of field %s\n     *\n     * @param %s \$%s\n     * @return \$this\n     */\n    public function set%s(\$%s)\n    {\n        \$this->%s = \$%s;\n\n        return \$this;\n    }\n";
        $templateValidateInclusion = "\n        \$this->validate(\n            new InclusionIn(\n                array(\n                    'field'    => '%s',\n                    'domain'   => array(%s),\n                    'required' => true,\n                )\n            )\n        );";
        $templateValidateEmail = "\n        \$this->validate(\n            new Email(\n                array(\n                    'field'    => '%s',\n                    'required' => true,\n                )\n            )\n        );";
        $templateValidationFailed = "\n        if (\$this->validationHasFailed() == true) {\n            return false;\n        }";
        $templateAttributes = "\n    /**\n     * @var %s\n     */\n    %s \$%s;\n";
        $templateGetterMap = "\n    /**\n     * Returns the value of field %s\n     *\n     * @return %s\n     */\n    public function get%s()\n    {\n        if (\$this->%s) {\n            return new %s(\$this->%s);\n        } else {\n           return null;\n        }\n    }\n";
        $templateGetter = "\n    /**\n     * Returns the value of field %s\n     *\n     * @return %s\n     */\n    public function get%s()\n    {\n        return \$this->%s;\n    }\n";
        $templateValidations = "\n    /**\n     * Validations and business logic\n     */\n    public function validation()\n    {\n%s\n    }\n";
        $templateInitialize = "\n    /**\n     * Initialize method for model.\n     */\n    public function initialize()\n    {\n%s\n    }\n";
        $templateFind = "\n    /**\n     * @return %s[]\n     */\n    public static function find(\$parameters = array())\n    {\n        return parent::find(\$parameters);\n    }\n\n    /**\n     * @return %s\n     */\n    public static function findFirst(\$parameters = array())\n    {\n        return parent::findFirst(\$parameters);\n    }\n";
        $templateUse = 'use %s;';
        $templateUseAs = 'use %s as %s;';
        $templateCode = "<?php\n%s%s%s%s\nclass %s extends %s\n{\n%s\n}\n";
        $methodRawCode = array();
        $modelPath = $this->_options['directory'] . DIRECTORY_SEPARATOR . $this->_options['name'] . '.php';
        if (file_exists($modelPath)) {
            if (!$this->_options['force']) {
                throw new \Exception("The model file '" . $this->_options['name'] . ".php' already exists in " . $this->_options['directory']);
            }
        }
        if (Tools::getDb()) {
            $dbConfig = Tools::getDb();
        }
        if (!isset($dbConfig->adapter)) {
            throw new \Exception("Adapter was not found in the config. " . "Please specify a config variable [database][adapter]");
        }
        if (isset($this->_options['namespace'])) {
            $namespace = PHP_EOL . PHP_EOL . 'namespace ' . $this->_options['namespace'] . ';' . PHP_EOL . PHP_EOL;
            $methodRawCode[] = sprintf($getSource, $this->_options['tableName']);
        } else {
            $namespace = '';
        }
        $useSettersGetters = $this->_options['genSettersGetters'];
        if (isset($this->_options['genDocMethods'])) {
            $genDocMethods = $this->_options['genDocMethods'];
        } else {
            $genDocMethods = false;
        }
        $this->isSupportedAdapter($dbConfig->adapter);
        if (isset($dbConfig->adapter)) {
            $adapter = $dbConfig->adapter;
        } else {
            $adapter = 'Mysql';
        }
        $configArray = $dbConfig->toArray();
        // An array for use statements
        $uses = array(sprintf($templateUse, $this->_options['baseClass']));
        $adapterName = '\\Phalcon\\Db\\Adapter\\Pdo\\' . $adapter;
        unset($configArray['adapter']);
        $db = new $adapterName($configArray);
        $initialize = array();
        if (isset($this->_options['schema'])) {
            if ($this->_options['schema'] != $dbConfig->dbname) {
                $initialize[] = sprintf($templateThis, 'setSchema', '"' . $this->_options['schema'] . '"');
            }
            $schema = $this->_options['schema'];
        } elseif ($adapter == 'Postgresql') {
            $schema = 'public';
            $initialize[] = sprintf($templateThis, 'setSchema', '"' . $schema . '"');
        } else {
            $schema = $dbConfig->dbname;
        }
        if ($this->_options['name'] != $this->_options['tableName']) {
            $initialize[] = sprintf($templateThis, 'setSource', '\'' . $this->_options['tableName'] . '\'');
        }
        $table = $this->_options['tableName'];
        if ($db->tableExists($table, $schema)) {
            $fields = $db->describeColumns($table, $schema);
        } else {
            throw new \Exception('Table "' . $table . '" does not exist');
        }
        foreach ($db->listTables() as $tableName) {
            foreach ($db->describeReferences($tableName) as $reference) {
                if ($reference->getReferencedTable() == $this->_options['tableName']) {
                    if (isset($this->_options['namespace'])) {
                        $entityNamespace = "{$this->_options['namespace']}\\";
                    } else {
                        $entityNamespace = '';
                    }
                    $initialize[] = sprintf($templateRelation, 'hasMany', $reference->getReferencedColumns()[0], $entityNamespace . ucfirst($tableName), $reference->getColumns()[0], "array('alias' => '" . ucfirst($tableName) . "')");
                }
            }
        }
        foreach ($db->describeReferences($this->_options['tableName']) as $reference) {
            if (isset($this->_options['namespace'])) {
                $entityNamespace = "{$this->_options['namespace']}\\";
            } else {
                $entityNamespace = '';
            }
            $initialize[] = sprintf($templateRelation, 'belongsTo', $reference->getColumns()[0], $entityNamespace . ucfirst($reference->getReferencedTable()), $reference->getReferencedColumns()[0], "array('alias' => '" . ucfirst($reference->getReferencedTable()) . "')");
        }
        if (isset($this->_options['hasMany'])) {
            if (count($this->_options['hasMany'])) {
                foreach ($this->_options['hasMany'] as $relation) {
                    if (is_string($relation['fields'])) {
                        $entityName = $relation['camelizedName'];
                        if (isset($this->_options['namespace'])) {
                            $entityNamespace = "{$this->_options['namespace']}\\";
                            $relation['options']['alias'] = $entityName;
                        } else {
                            $entityNamespace = '';
                        }
                        $initialize[] = sprintf($templateRelation, 'hasMany', $relation['fields'], $entityNamespace . $entityName, $relation['relationFields'], $this->_buildRelationOptions(isset($relation['options']) ? $relation["options"] : NULL));
                    }
                }
            }
        }
        if (isset($this->_options['belongsTo'])) {
            if (count($this->_options['belongsTo'])) {
                foreach ($this->_options['belongsTo'] as $relation) {
                    if (is_string($relation['fields'])) {
                        $entityName = $relation['referencedModel'];
                        if (isset($this->_options['namespace'])) {
                            $entityNamespace = "{$this->_options['namespace']}\\";
                            $relation['options']['alias'] = $entityName;
                        } else {
                            $entityNamespace = '';
                        }
                        $initialize[] = sprintf($templateRelation, 'belongsTo', $relation['fields'], $entityNamespace . $entityName, $relation['relationFields'], $this->_buildRelationOptions(isset($relation['options']) ? $relation["options"] : NULL));
                    }
                }
            }
        }
        $alreadyInitialized = false;
        $alreadyValidations = false;
        if (file_exists($modelPath)) {
            try {
                $possibleMethods = array();
                if ($useSettersGetters) {
                    foreach ($fields as $field) {
                        $methodName = Text::camelize($field->getName());
                        $possibleMethods['set' . $methodName] = true;
                        $possibleMethods['get' . $methodName] = true;
                    }
                }
                require_once $modelPath;
                $linesCode = file($modelPath);
                $fullClassName = $this->_options['namespace'];
                $reflection = new \ReflectionClass($fullClassName);
                foreach ($reflection->getMethods() as $method) {
                    if ($method->getDeclaringClass()->getName() == $fullClassName) {
                        $methodName = $method->getName();
                        if (!isset($possibleMethods[$methodName])) {
                            $methodRawCode[$methodName] = join('', array_slice($linesCode, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1));
                        } else {
                            continue;
                        }
                        if ($methodName == 'initialize') {
                            $alreadyInitialized = true;
                        } else {
                            if ($methodName == 'validation') {
                                $alreadyValidations = true;
                            }
                        }
                    }
                }
            } catch (\ReflectionException $e) {
            }
        }
        $validations = array();
        foreach ($fields as $field) {
            if ($field->getType() === Column::TYPE_CHAR) {
                $domain = array();
                if (preg_match('/\\((.*)\\)/', $field->getType(), $matches)) {
                    foreach (explode(',', $matches[1]) as $item) {
                        $domain[] = $item;
                    }
                }
                if (count($domain)) {
                    $varItems = join(', ', $domain);
                    $validations[] = sprintf($templateValidateInclusion, $field->getName(), $varItems);
                }
            }
            if ($field->getName() == 'email') {
                $validations[] = sprintf($templateValidateEmail, $field->getName());
                $uses[] = sprintf($templateUse, '\\Phalcon\\Mvc\\Model\\Validator\\Email');
            }
        }
        if (count($validations)) {
            $validations[] = $templateValidationFailed;
        }
        /**
         * Check if there have been any excluded fields
         */
        $exclude = array();
        if (isset($this->_options['excludeFields'])) {
            if (!empty($this->_options['excludeFields'])) {
                $keys = explode(',', $this->_options['excludeFields']);
                if (count($keys) > 0) {
                    foreach ($keys as $key) {
                        $exclude[trim($key)] = '';
                    }
                }
            }
        }
        $attributes = array();
        $setters = array();
        $getters = array();
        foreach ($fields as $field) {
            $type = $this->getPHPType($field->getType());
            if ($useSettersGetters) {
                if (!array_key_exists(strtolower($field->getName()), $exclude)) {
                    $attributes[] = sprintf($templateAttributes, $type, 'protected', $field->getName());
                    $setterName = Text::camelize($field->getName());
                    $setters[] = sprintf($templateSetter, $field->getName(), $type, $field->getName(), $setterName, $field->getName(), $field->getName(), $field->getName());
                    if (isset($this->_typeMap[$type])) {
                        $getters[] = sprintf($templateGetterMap, $field->getName(), $type, $setterName, $field->getName(), $this->_typeMap[$type], $field->getName());
                    } else {
                        $getters[] = sprintf($templateGetter, $field->getName(), $type, $setterName, $field->getName());
                    }
                }
            } else {
                $attributes[] = sprintf($templateAttributes, $type, 'public', $field->getName());
            }
        }
        if ($alreadyValidations == false) {
            if (count($validations) > 0) {
                $validationsCode = sprintf($templateValidations, join('', $validations));
            } else {
                $validationsCode = '';
            }
        } else {
            $validationsCode = '';
        }
        if ($alreadyInitialized == false) {
            if (count($initialize) > 0) {
                $initCode = sprintf($templateInitialize, rtrim(join('', $initialize)));
            } else {
                $initCode = '';
            }
        } else {
            $initCode = '';
        }
        $content = join('', $attributes);
        if ($useSettersGetters) {
            $content .= join('', $setters) . join('', $getters);
        }
        $content .= $validationsCode . $initCode;
        foreach ($methodRawCode as $methodCode) {
            $content .= $methodCode;
        }
        if ($genDocMethods) {
            $content .= sprintf($templateFind, $this->_options['name'], $this->_options['name']);
        }
        if (isset($this->_options['mapColumn'])) {
            $content .= $this->_genColumnMapCode($fields);
        }
        $str_use = implode(PHP_EOL, $uses) . PHP_EOL . PHP_EOL;
        $str_doc = '/**
 * Class ' . $this->_options['name'] . '
 * @package ' . $this->_options['namespace'] . '
 */';
        $base = explode('\\', $this->_options['baseClass']);
        $baseClass = end($base);
        $code = sprintf($templateCode, Tools::getCopyright(), $namespace, $str_use, $str_doc, $this->_options['name'], $baseClass, $content);
        if (!@is_dir($this->_options['directory'])) {
            @mkdir($this->_options['directory']);
            @chmod($this->_options['directory'], 0777);
        }
        if (!@file_put_contents($modelPath, $code)) {
            throw new \Exception("Unable to write to '{$modelPath}'");
        }
        @chmod($modelPath, 0777);
    }