LazyRecord\Schema\Factory\BaseModelClassFactory::create PHP Method

create() public static method

public static create ( DeclareSchema $schema, $baseClass )
$schema LazyRecord\Schema\DeclareSchema
    public static function create(DeclareSchema $schema, $baseClass)
    {
        $cTemplate = new ClassFile($schema->getBaseModelClass());
        $cTemplate->useClass('LazyRecord\\Schema\\SchemaLoader');
        $cTemplate->useClass('LazyRecord\\Result');
        $cTemplate->useClass('SQLBuilder\\Bind');
        $cTemplate->useClass('SQLBuilder\\ArgumentArray');
        $cTemplate->useClass('PDO');
        $cTemplate->useClass('SQLBuilder\\Universal\\Query\\InsertQuery');
        $cTemplate->addConsts(array('SCHEMA_CLASS' => get_class($schema), 'SCHEMA_PROXY_CLASS' => $schema->getSchemaProxyClass(), 'COLLECTION_CLASS' => $schema->getCollectionClass(), 'MODEL_CLASS' => $schema->getModelClass(), 'TABLE' => $schema->getTable(), 'READ_SOURCE_ID' => $schema->getReadSourceId(), 'WRITE_SOURCE_ID' => $schema->getWriteSourceId(), 'PRIMARY_KEY' => $schema->primaryKey));
        $cTemplate->addProtectedProperty('table', $schema->getTable());
        $cTemplate->addPublicProperty('readSourceId', $schema->getReadSourceId() ?: 'default');
        $cTemplate->addPublicProperty('writeSourceId', $schema->getWriteSourceId() ?: 'default');
        $cTemplate->addMethod('public', 'getSchema', [], ['if ($this->_schema) {', '   return $this->_schema;', '}', 'return $this->_schema = SchemaLoader::load(' . var_export($schema->getSchemaProxyClass(), true) . ');']);
        $cTemplate->addStaticVar('column_names', $schema->getColumnNames());
        $cTemplate->addStaticVar('column_hash', array_fill_keys($schema->getColumnNames(), 1));
        $cTemplate->addStaticVar('mixin_classes', array_reverse($schema->getMixinSchemaClasses()));
        if ($traitClasses = $schema->getModelTraitClasses()) {
            foreach ($traitClasses as $traitClass) {
                $cTemplate->useTrait($traitClass);
            }
        }
        $schemaReflection = new ReflectionClass($schema);
        $schemaDocComment = $schemaReflection->getDocComment();
        // TODO: apply settings from schema...
        $codegenSettings = [];
        preg_match_all('/@codegen (\\w+)(?:\\s*=\\s*(\\S+))?$/m', $schemaDocComment, $allMatches);
        for ($i = 0; $i < count($allMatches[0]); ++$i) {
            $key = $allMatches[1][$i];
            $value = $allMatches[2][$i];
            if ($value === '') {
                $value = true;
            } else {
                if (strcasecmp($value, 'true') == 0 || strcasecmp($value, 'false') == 0) {
                    $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
                } elseif (preg_match('/^\\d+$/', $value)) {
                    $value = intval($value);
                }
            }
            $codegenSettings[$key] = $value;
        }
        /*
        if ($codegenSettings['validateColumn']) {
            $codegenSettings['handleValidationError'] = true;
        }
        */
        if (!empty($codegenSettings)) {
            $reflectionModel = new ReflectionClass('LazyRecord\\BaseModel');
            $createMethod = $reflectionModel->getMethod('create');
            $methodFile = $createMethod->getFilename();
            $startLine = $createMethod->getStartLine();
            $endLine = $createMethod->getEndLine();
            $lines = file($methodFile);
            $methodLines = array_slice($lines, $startLine + 1, $endLine - $startLine - 2);
            // exclude '{', '}'
            $blockRanges = array();
            $blockLines = array();
            // parse code blocks
            for ($i = 0; $i < count($methodLines); ++$i) {
                $line = rtrim($methodLines[$i]);
                if (preg_match('/@codegenBlock (\\w+)/', $line, $matches)) {
                    $blockId = $matches[1];
                    for ($j = $i; $j < count($methodLines); ++$j) {
                        $line = rtrim($methodLines[$j]);
                        $blockLines[$blockId][] = $line;
                        if (preg_match('/@codegenBlockEnd/', $line)) {
                            $blockRanges[$blockId] = [$i, $j];
                            $i = $j;
                            break;
                        }
                    }
                }
            }
            $overrideCreateMethod = $cTemplate->addMethod('public', 'create', ['array $args', 'array $options = array()']);
            $overrideBlock = $overrideCreateMethod->getBlock();
            for ($i = 0; $i < count($methodLines); ++$i) {
                $line = rtrim($methodLines[$i]);
                if (preg_match('/@codegenBlock (\\w+)/', $line, $matches)) {
                    $blockId = $matches[1];
                    if (isset($codegenSettings[$matches[1]]) && isset($blockLines[$blockId])) {
                        if ($codegenSettings[$matches[1]]) {
                            $overrideBlock[] = $blockLines[$blockId];
                            list($startLine, $endLine) = $blockRanges[$blockId];
                            $i = $endLine;
                            continue;
                        } else {
                            list($startLine, $endLine) = $blockRanges[$blockId];
                            $i = $endLine;
                            continue;
                        }
                    }
                }
                $overrideBlock[] = $line;
            }
        }
        // TODO: refacory this into factory method
        // Generate findByPrimaryKey SQL query
        $arguments = new ArgumentArray();
        $findByPrimaryKeyQuery = new SelectQuery();
        $findByPrimaryKeyQuery->from($schema->getTable());
        $primaryKey = $schema->primaryKey;
        $readFrom = $schema->getReadSourceId();
        $readConnection = ConnectionManager::getInstance()->getConnection($readFrom);
        $readQueryDriver = $readConnection->createQueryDriver();
        $primaryKeyColumn = $schema->getColumn($primaryKey);
        $findByPrimaryKeyQuery->select('*')->where()->equal($primaryKey, new Bind($primaryKey));
        $findByPrimaryKeyQuery->limit(1);
        $findByPrimaryKeySql = $findByPrimaryKeyQuery->toSql($readQueryDriver, $arguments);
        $cTemplate->addConst('FIND_BY_PRIMARY_KEY_SQL', $findByPrimaryKeySql);
        foreach ($schema->getColumns() as $column) {
            if (!$column->findable) {
                continue;
            }
            $columnName = $column->name;
            $findMethodName = 'findBy' . ucfirst(Inflector::camelize($columnName));
            $findMethod = $cTemplate->addMethod('public', $findMethodName, ['$value']);
            $block = $findMethod->block;
            $arguments = new ArgumentArray();
            $findByColumnQuery = new SelectQuery();
            $findByColumnQuery->from($schema->getTable());
            $columnName = $column->name;
            $readFrom = $schema->getReadSourceId();
            $findByColumnQuery->select('*')->where()->equal($columnName, new Bind($columnName));
            $findByColumnQuery->limit(1);
            $findByColumnSql = $findByColumnQuery->toSql($readQueryDriver, $arguments);
            $block[] = '$conn  = $this->getReadConnection();';
            $block[] = 'if (!isset($this->_preparedFindStms[' . var_export($columnName, true) . '])) {';
            $block[] = '    $this->_preparedFindStms[' . var_export($columnName, true) . '] = $conn->prepare(' . var_export($findByColumnSql, true) . ');';
            $block[] = '}';
            $block[] = '$this->_preparedFindStms[' . var_export($columnName, true) . ']->execute([' . var_export(":{$columnName}", true) . ' => $value ]);';
            $block[] = 'if (false === ($this->_data = $this->_preparedFindStms[' . var_export($columnName, true) . ']->fetch(PDO::FETCH_ASSOC)) ) {';
            $block[] = '    return $this->reportError("Record not found", [';
            $block[] = '        "sql" => ' . var_export($findByColumnSql, true) . ',';
            $block[] = '    ]);';
            $block[] = '}';
            $block[] = '$this->_preparedFindStms[' . var_export($columnName, true) . ']->closeCursor();';
            $block[] = 'return $this->reportSuccess( "Data loaded", array( ';
            $block[] = '    "sql" => ' . var_export($findByColumnSql, true) . ',';
            $block[] = '    "type" => Result::TYPE_LOAD,';
            $block[] = '));';
        }
        $cTemplate->extendClass('\\' . $baseClass);
        // interfaces
        if ($ifs = $schema->getModelInterfaces()) {
            foreach ($ifs as $iface) {
                $cTemplate->implementClass($iface);
            }
        }
        // Create column accessor
        if ($schema->enableColumnAccessors) {
            foreach ($schema->getColumnNames() as $columnName) {
                $accessorMethodName = 'get' . ucfirst(Inflector::camelize($columnName));
                $cTemplate->addMethod('public', $accessorMethodName, [], ['    return $this->get(' . var_export($columnName, true) . ');']);
            }
        }
        return $cTemplate;
    }

Usage Example

Esempio n. 1
0
 public function generateSchema(SchemaInterface $schema, $overwrite = false)
 {
     $classMap = array();
     $cTemplates = array();
     $cTemplates[] = BaseModelClassFactory::create($schema, $this->getBaseModelClass());
     $cTemplates[] = SchemaProxyClassFactory::create($schema);
     $cTemplates[] = BaseCollectionClassFactory::create($schema, $this->getBaseCollectionClass());
     foreach ($cTemplates as $cTemplate) {
         if ($result = $this->updateClassFile($cTemplate, $schema, $overwrite)) {
             list($className, $classFile) = $result;
             $classMap[$className] = $classFile;
         }
     }
     if ($result = $this->generateCollectionClass($schema, false)) {
         list($className, $classFile) = $result;
         $classMap[$className] = $classFile;
     }
     if ($result = $this->generateModelClass($schema, false)) {
         list($className, $classFile) = $result;
         $classMap[$className] = $classFile;
     }
     return $classMap;
 }
All Usage Examples Of LazyRecord\Schema\Factory\BaseModelClassFactory::create
BaseModelClassFactory