public function __construct(&$config) { parent::__construct($config); }
public function generateAll() { ob_start(); $this->db->loadSchema(); echo '<' . '?' . "php\n"; //echo "/**\n"; //echo " * @license Copyright (c) 2008-2016 Robert Frunzke. All rights reserved.\n"; //echo " * For licensing, see LICENSE.md\n"; //echo " */\n"; //echo "\n"; echo "// this file was generated automatically\n"; echo "\n"; $all_fks = $this->db->getForeignKeys(); $root_class_name = $this->get_ORM_class_name('root', false); //'reOMRoot'; // item objects foreach ($this->db->getTables() as $table_name => $table) { if (!$this->get_ORM_use_class($table_name)) { continue; } $table_fks = $table->getForeignKeys(); $columns = $table->getColumns(); echo "/**\n"; echo " * ORM wrapper class for items of DB " . ($table->isView() ? "view" : "table") . " " . $table_name . ".\n"; echo " * \n"; echo " * DB Schema:\n"; foreach (explode("\n", (string) $table) as $line) { echo " * " . $line . "\n"; } echo " */\n"; echo "class " . $this->get_ORM_class_name($table_name, false) . " extends " . $this->item_base_class . " {\n"; echo "\n"; // table meta data echo "\tprivate static \$_metadata = [ 'table_name' => '" . $table->getName() . "',\n"; echo "\t 'is_view' => " . ($table->isView() ? 'true' : 'false') . ",\n"; echo "\t 'columns' => [\n"; foreach ($columns as $column_name => $column) { echo "\t ['" . $column_name . "','" . $this->getPHPTypeForColumn($column) . "','" . $column->getType() . "'],\n"; } echo "\t ]\n"; echo "\t ];\n"; echo "\n"; // column value members foreach ($columns as $column_name => $column) { echo "\t/**\n"; echo "\t * @var " . $this->getPHPTypeForColumn($column) . "\n"; echo "\t */\n"; echo "\tprivate \$" . $this->getPHPNameForColumn($column) . ";\n"; } echo "\n"; // constructor - sets normalized values, according to sql column data type (e.g. ints, bigints, ...) echo "\t/**\n"; echo "\t * constructor\n"; echo "\t * @param " . $root_class_name . " \$root\n"; echo "\t * @param array \$data\n"; echo "\t */\n"; echo "\tpublic function __construct( " . $root_class_name . " \$root, array \$data ) {\n"; echo "\t\tparent::__construct(\$root);\n"; foreach ($columns as $column_name => $column) { echo "\t\t\$this->" . $this->getPHPNameForColumn($column) . " = " . $this->getPHPCastCodeForColumn($column, "\$data['" . $column_name . "']") . ";\n"; } echo "\t}\n"; echo "\n"; // toArray() - return data in an associative array echo "\t/**\n"; echo "\t * return all properties in plain array\n"; echo "\t * @return array\n"; echo "\t */\n"; echo "\tpublic function toArray() {\n"; echo "\t\treturn [\n"; foreach ($columns as $column_name => $column) { echo "\t\t\t'" . $column_name . "'=>\$this->" . $this->getPHPNameForColumn($column) . ",\n"; } echo "\t\t];\n"; echo "\t}\n"; echo "\n"; echo "\t/" . "**\n"; echo "\t * return class metadata (i.e. table metadata)\n"; echo "\t * @return array\n"; echo "\t *" . "/\n"; echo "\tpublic static function _getMetadata() {\n"; echo "\t\treturn self::\$_metadata;\n"; echo "\t}\n"; echo "\n"; echo "\t/" . "**\n"; echo "\t * return item class metadata (i.e. table metadata)\n"; echo "\t * @return array\n"; echo "\t *" . "/\n"; echo "\tpublic function _getClassMetadata() {\n"; echo "\t\treturn self::\$_metadata;\n"; echo "\t}\n"; echo "\n"; echo "\t// --- column value getter --- \n\n"; foreach ($columns as $column_name => $column) { echo "\t/**\n"; echo "\t * @return " . $this->getPHPTypeForColumn($column) . "\n"; echo "\t */\n"; echo "\tpublic function get" . $this->get_ORM_item_name($column_name, false) . "() {\n"; //echo "\t\treturn \$this->_data['".$column_name."'];\n"; echo "\t\treturn \$this->" . $this->getPHPNameForColumn($column) . ";\n"; echo "\t}\n"; } echo "\n"; echo "\t// --- common column value getter (legacy: will be deprecated) --- \n\n"; echo "\tpublic function __get( \$name ) {\n"; echo "\t\ttrigger_error('Direct access to entity properties is deprecated (while trying to get '.\$name.' on " . $this->get_ORM_class_name($table_name, false) . ")',E_USER_NOTICE);\n"; echo "\t\tif( property_exists(\$this,\$name) ) return \$this->\$name;\n"; echo "\t\t\$trace = debug_backtrace();\n"; echo "\t\ttrigger_error('Undefined property via __get(): '.\$name.' in '.\$trace[0]['file'].' on line '.\$trace[0]['line'],E_USER_NOTICE);\n"; echo "\t\treturn null;\n"; echo "\t}\n"; echo "\n"; echo "\t// --- common column value setter (legacy: will be deprecated) --- \n\n"; echo "\tpublic function __set( \$name, \$value ) {\n"; echo "\t\ttrigger_error('Direct write access to entity properties is deprecated (while trying to set '.\$name.' on " . $this->get_ORM_class_name($table_name, false) . ")',E_USER_NOTICE);\n"; echo "\t\tif( property_exists(\$this,\$name) ) {\n"; echo "\t\t\t\$this->\$name = \$value;\n"; echo "\t\t\treturn;\n"; echo "\t\t}\n"; echo "\t\t\$trace = debug_backtrace();\n"; echo "\t\ttrigger_error('Undefined property via __set(): '.\$name.' in '.\$trace[0]['file'].' on line '.\$trace[0]['line'],E_USER_NOTICE);\n"; echo "\t}\n"; echo "\n"; if ($table->isView()) { // --- nothing yet --- } else { echo "\t// --- referenced objects --- \n\n"; foreach ($table_fks as $constraint_name => $fk) { $fk_ref_table = $fk->getReferencesTable(); $fk_ref_table_name = $fk_ref_table->getName(); if ($this->get_ORM_use_class($fk_ref_table_name)) { $fk_col_refs = $fk->getColumnReferences(); echo "\t/**\n"; echo "\t * @return " . $this->get_ORM_class_name($fk_ref_table_name, true) . "\n"; echo "\t */\n"; echo "\tpublic function get" . $this->get_ORM_fk_name($fk) . "() {\n"; echo "\t\treturn \$this->_getRoot()->get" . $this->get_ORM_item_name($fk_ref_table_name, true) . "("; $tmp = []; // TODO: match parameter order to order of columns in primary key foreach ($fk_col_refs as $column_name => $referenced_column_name) { $column = $columns[$column_name]; $tmp[] = "\$this->" . $this->getPHPNameForColumn($column); } echo implode(',', $tmp); echo ");\n"; echo "\t}\n"; } } echo "\n"; $use_fk_constraint_names = isset($this->table_hints[$table_name]['use_fk_constraint_names']) ? !!$this->table_hints[$table_name]['use_fk_constraint_names'] : $this->use_fk_constraint_names; echo "\t// --- objects referencing this one --- \n\n"; foreach ($all_fks as $constraint_name => $fk) { if ($table === $fk->getReferencesTable()) { $fk_table = $fk->getTable(); $fk_table_name = $fk_table->getName(); if ($this->get_ORM_use_class($fk_table_name)) { $flt_data = []; foreach ($fk->getColumnReferences() as $column_name => $references_column_name) { $references_column = $columns[$references_column_name]; $flt_data[] = "'" . $column_name . "'=>\$this->" . $this->getPHPNameForColumn($references_column); } echo "\t/**\n"; echo "\t * @return " . $this->get_ORM_class_name($fk_table_name, true) . "[]\n"; echo "\t */\n"; if ($use_fk_constraint_names) { // extended style: derive getter name from constraint name... /* $gc_name = strncmp(substr($constraint_name,-5,5),'_fkey',5)===0 ? substr($constraint_name,0,-5) : $constraint_name; $fktnl = strlen($fk_table_name); if( strncmp($gc_name,$fk_table_name.'_',$fktnl+1)===0 ) $gc_name = substr($gc_name,$fktnl+1); $tmp_getter_name = $this->get_ORM_item_name($fk_table_name,false) . '_' . $gc_name; */ $tmp_getter_name = $this->get_ORM_item_name($fk_table_name, false) . 'By' . $this->get_ORM_fk_name($fk); } else { // simple/classic style: just use fk table name in getter name // --> THIS WILL NOT WORK when one table has multiple foreign key constraints to a target table // --> use extended style in these cases! $tmp_getter_name = $this->get_ORM_item_name($fk_table_name, false); } echo "\tpublic function get" . $tmp_getter_name . "( array \$filter=null, \$order_by=null ) {\n"; echo "\t\t return \$this->_getRoot()->get" . $this->get_ORM_item_name($fk_table_name) . "List(\$filter===null?[" . implode(',', $flt_data) . "]:array_merge(\$filter,[" . implode(',', $flt_data) . "]),\$order_by);\n"; echo "\t}\n"; } } } echo "\n"; } echo "}\n\n"; } // the root object echo "class " . $root_class_name . " extends reOMRoot {\n"; echo "\n"; foreach ($this->db->getTables() as $table_name => $table) { if ($this->get_ORM_use_class($table_name)) { $table_pk_column_names = null; if ($table->isView()) { $table_pk = isset($this->table_hints[$table_name]['pseudo_view_pk']) ? $this->table_hints[$table_name]['pseudo_view_pk'] : null; if ($table_pk !== null) { $table_pk_column_names = is_array($table_pk) ? $table_pk : [$table_pk]; } } else { $table_pk = $table->getPrimaryKey(); if ($table_pk !== null) { $table_pk_column_names = $table_pk->getColumnNames(); } } if ($table_pk_column_names !== null) { $php_para = []; $sql_para = []; $table_columns = $table->getColumns(); foreach ($table_pk_column_names as $column_name) { $column = $table_columns[$column_name]; $php_para[] = '$' . $this->getPHPNameForColumn($column); $sql_para[] = $column->getEscapedName() . '=?'; } // get item object by primary key $class_name = $this->get_ORM_class_name($table_name, true); echo "\t/**\n"; echo "\t * @return " . $class_name . "\n"; echo "\t */\n"; echo "\tpublic function get" . $this->get_ORM_item_name($table_name, true) . "( " . implode(', ', $php_para) . " ) {\n"; echo "\t\treturn \$this->_createObject('" . $class_name . "','SELECT * FROM " . $table->getEscapedName() . " WHERE " . implode(' AND ', $sql_para) . "',[" . implode(',', $php_para) . "]);\n"; echo "\t}\n"; } // get item object lists $lists_filter = isset($this->table_hints[$table_name]['lists_filter']) ? $this->table_hints[$table_name]['lists_filter'] : ""; $default_order_by = $this->get_ORM_order_by($table); $class_name = $this->get_ORM_class_name($table_name, true); echo "\t/**\n"; echo "\t * @return " . $class_name . "[] \n"; echo "\t */\n"; echo "\tpublic function get" . $this->get_ORM_item_name($table_name, true) . "List( array \$filter=null, \$order_by=null ) {\n"; echo "\t\tif( \$order_by===null ) \$order_by = '" . $default_order_by . "';\n"; echo "\t\treturn \$this->_createObjectListWithFilter('" . $class_name . "','SELECT * FROM " . $table->getEscapedName() . " WHERE true" . ($lists_filter ? " AND (" . $lists_filter . ")" : "") . "',\$order_by?' ORDER BY '.\$order_by:'',\$filter);\n"; echo "\t}\n\n"; } } echo "}\n\n"; /*** echo "/"."*\n"; echo "source schema:\n\n"; echo (string)$this->db; echo "*"."/\n\n"; ***/ return ob_get_clean(); }
/** * create & return an array of item instances, according to given class, sql and filter * @param string $class_name * @param string $sql1 * @param string $sql2 * @param array $filter * @throws reException * @return reOMItem[] */ public function _createObjectListWithFilter($class_name, $sql1, $sql2, array $filter = null) { $para = []; if ($filter !== null) { foreach ($filter as $c => $v) { $sql1 .= ' AND '; if (is_array($v)) { switch ($v[0]) { case '=': case '<': case '>': case '<=': case '>=': case '<>': $sql1 .= $c . $v[0] . '?'; $para[] = $v[1]; break; case 'sql': $sql1 .= '(' . $c . ' ' . $v[1] . ')'; break; case 'rawsql': $sql1 .= '(' . $v[1] . ')'; break; default: throw new reException('unknown query filter operator: ' . $v[0]); } } else { $sql1 .= $c . '=?'; $para[] = $v; } } } $objs = []; foreach ($this->_db->queryAssoc($sql1 . $sql2, $para) as $row) { $objs[] = new $class_name($this, $row); } return $objs; }