Code style fixes

This commit is contained in:
Dmitry Khomutov 2016-04-20 21:39:48 +06:00
commit 0868eb9c69
63 changed files with 1413 additions and 1494 deletions

View file

@ -5,424 +5,376 @@
*/
namespace b8\Database;
use b8\Database;
class Generator
{
protected $_db = null;
protected $_map = null;
protected $_tables = null;
protected $_ns = null;
protected $_path = null;
public function __construct(Database $db, $namespace, $path)
{
$this->_db = $db;
$this->_ns = $namespace;
$this->_path = $path;
$this->_map = new Map($this->_db);
$this->_tables = $this->_map->generate();
}
public function generate()
{
error_reporting(E_ERROR & E_WARNING);
$di = new \DirectoryIterator($this->_path);
$this->_todo = array(
'drop_fk' => array(),
'drop_index'=> array(),
'create' => array(),
'alter' => array(),
'add_index' => array(),
'add_fk' => array(),
);
foreach($di as $file)
{
if($file->isDot())
{
continue;
}
$fileName = explode('.', $file->getBasename());
if ($fileName[count($fileName)-1] != 'php')
{
continue;
}
$modelName = '\\' . $this->_ns . '\\Model\\Base\\' . str_replace('.php', '', $file->getFilename());
require_once($this->_path . $file->getFilename());
$model = new $modelName();
$columns = $model->columns;
$indexes = $model->indexes;
$foreignKeys = $model->foreignKeys;
$tableName = $model->getTableName();
if(!array_key_exists($tableName, $this->_tables))
{
$this->_createTable($tableName, $columns, $indexes, $foreignKeys);
continue;
}
else
{
$table = $this->_tables[$tableName];
$this->_updateColumns($tableName, $table, $columns);
$this->_updateRelationships($tableName, $table, $foreignKeys);
$this->_updateIndexes($tableName, $table, $indexes);
}
}
print 'DROP FK: ' . count($this->_todo['drop_fk']) . PHP_EOL;
print 'DROP INDEX: ' . count($this->_todo['drop_index']) . PHP_EOL;
print 'CREATE TABLE: ' . count($this->_todo['create']) . PHP_EOL;
print 'ALTER TABLE: ' . count($this->_todo['alter']) . PHP_EOL;
print 'ADD INDEX: ' . count($this->_todo['add_index']) . PHP_EOL;
print 'ADD FK: ' . count($this->_todo['add_fk']) . PHP_EOL;
$order = array_keys($this->_todo);
while($group = array_shift($order))
{
if(!isset($this->_todo[$group]) || !is_array($this->_todo[$group]) || !count($this->_todo[$group]))
{
continue;
}
foreach($this->_todo[$group] as $query)
{
try
{
//print $query . PHP_EOL;
$this->_db->query($query);
}
catch(\Exception $ex)
{
print 'FAILED TO EXECUTE: ' . $query . PHP_EOL;
print $ex->getMessage().PHP_EOL.PHP_EOL;
}
}
}
}
protected function _createTable($tbl, $cols, $idxs, $fks)
{
$defs = array();
$pks = array();
foreach($cols as $colName => $def)
{
$add = '`' . $colName . '` ' . $def['type'];
switch($def['type'])
{
case 'text':
case 'longtext':
case 'mediumtext':
case 'date':
case 'datetime':
case 'float':
$add .= '';
break;
default:
$add .= !empty($def['length']) ? '(' . $def['length'] . ')' : '';
break;
}
if(empty($def['nullable']) || !$def['nullable'])
{
$add .= ' NOT NULL ';
}
if(!empty($def['default']))
{
$add .= ' DEFAULT ' . (is_numeric($def['default']) ? $def['default'] : '\'' . $def['default'] . '\'');
}
if(!empty($def['auto_increment']) && $def['auto_increment'])
{
$add .= ' AUTO_INCREMENT ';
}
if(!empty($def['primary_key']) && $def['primary_key'])
{
$pks[] = '`' . $colName . '`';
}
$defs[] = $add;
}
if(count($pks))
{
$defs[] = 'PRIMARY KEY (' . implode(', ', $pks) . ')';
}
$stmt = 'CREATE TABLE `' . $tbl . '` (' . PHP_EOL;
$stmt .= implode(", \n", $defs);
$stmt .= PHP_EOL . ') ENGINE=InnoDB DEFAULT CHARSET=utf8';
$stmt .= PHP_EOL;
$this->_todo['create'][] = $stmt;
foreach($idxs as $name => $idx)
{
$this->_addIndex($tbl, $name, $idx);
}
foreach($fks as $name => $fk)
{
$this->_addFk($tbl, $name, $fk);
}
}
protected function _updateColumns($tableName, $table, $columns)
{
$currentColumns = $table['columns'];
while($column = array_shift($currentColumns))
{
if(!array_key_exists($column['name'], $columns))
{
$this->_todo['alter'][$tableName.'.'.$column['name']] = 'ALTER TABLE `' . $tableName . '` DROP COLUMN `' . $column['name'] . '`';
}
else
{
$model = $columns[$column['name']];
$model['nullable'] = !isset($model['nullable']) ? false : $model['nullable'];
$model['default'] = !isset($model['default']) ? false : $model['default'];
$model['auto_increment'] = !isset($model['auto_increment']) ? false : $model['auto_increment'];
$model['primary_key'] = !isset($model['primary_key']) ? false : $model['primary_key'];
$column['is_primary_key'] = !isset($column['is_primary_key']) ? false : $column['is_primary_key'];
if( $column['type'] != $model['type'] ||
($column['length'] != $model['length'] && !in_array($model['type'], array('text', 'longtext', 'mediumtext', 'date', 'datetime', 'float'))) ||
$column['null'] != $model['nullable'] ||
$column['default'] != $model['default'] ||
$column['auto'] != $model['auto_increment'])
{
$this->_updateColumn($tableName, $column['name'], $column['name'], $model);
}
}
unset($columns[$column['name']]);
}
if(count($columns))
{
foreach($columns as $name => $model)
{
// Check if we're renaming a column:
if(isset($model['rename']))
{
unset($this->_todo['alter'][$tableName.'.'.$model['rename']]);
$this->_updateColumn($tableName, $model['rename'], $name, $model);
continue;
}
// New column
$add = '`' . $name . '` ' . $model['type'];;
switch($model['type'])
{
case 'text':
case 'longtext':
case 'mediumtext':
case 'date':
case 'datetime':
case 'float':
$add .= '';
break;
default:
$add .= !empty($model['length']) ? '(' . $model['length'] . ')' : '';
break;
}
if(empty($model['nullable']) || !$model['nullable'])
{
$add .= ' NOT NULL ';
}
if(!empty($model['default']))
{
$add .= ' DEFAULT ' . (is_numeric($model['default']) ? $model['default'] : '\'' . $model['default'] . '\'');
}
if(!empty($model['auto_increment']) && $model['auto_increment'])
{
$add .= ' AUTO_INCREMENT ';
}
if(!empty($model['primary_key']) && $model['primary_key'] && !isset($table['indexes']['PRIMARY']))
{
$add .= ' PRIMARY KEY ';
}
$this->_todo['alter'][] = 'ALTER TABLE `' . $tableName . '` ADD COLUMN ' . $add;
}
}
}
protected function _updateColumn($tableName, $prevName, $newName, $model)
{
$add = '`' . $newName . '` ' . $model['type'];;
switch($model['type'])
{
case 'text':
case 'longtext':
case 'mediumtext':
case 'date':
case 'datetime':
case 'float':
$add .= '';
break;
default:
$add .= !empty($model['length']) ? '(' . $model['length'] . ')' : '';
break;
}
if(empty($model['nullable']) || !$model['nullable'])
{
$add .= ' NOT NULL ';
}
if(!empty($model['default']))
{
$add .= ' DEFAULT ' . (is_numeric($model['default']) ? $model['default'] : '\'' . $model['default'] . '\'');
}
if(!empty($model['auto_increment']) && $model['auto_increment'])
{
$add .= ' AUTO_INCREMENT ';
}
$this->_todo['alter'][] = 'ALTER TABLE `' . $tableName . '` CHANGE COLUMN `' . $prevName . '` ' . $add;
}
protected function _updateRelationships($tableName, $table, $foreignKeys)
{
$current = $table['relationships']['toOne'];
while($foreignKey = array_shift($current))
{
if(!array_key_exists($foreignKey['fk_name'], $foreignKeys))
{
$this->_dropFk($tableName, $foreignKey['fk_name']);
}
elseif( $foreignKey['from_col'] != $foreignKeys[$foreignKey['fk_name']]['local_col'] ||
$foreignKey['table'] != $foreignKeys[$foreignKey['fk_name']]['table'] ||
$foreignKey['col'] != $foreignKeys[$foreignKey['fk_name']]['col'] ||
$foreignKey['fk_update'] != $foreignKeys[$foreignKey['fk_name']]['update'] ||
$foreignKey['fk_delete'] != $foreignKeys[$foreignKey['fk_name']]['delete'])
{
$this->_alterFk($tableName, $foreignKey['fk_name'], $foreignKeys[$foreignKey['fk_name']]);
}
unset($foreignKeys[$foreignKey['fk_name']]);
}
if(count($foreignKeys))
{
foreach($foreignKeys as $name => $foreignKey)
{
// New column
$this->_addFk($tableName, $name, $foreignKey);
}
}
}
protected function _updateIndexes($tableName, $table, $indexes)
{
$current = $table['indexes'];
while($index = array_shift($current))
{
if(!array_key_exists($index['name'], $indexes))
{
$this->_dropIndex($tableName, $index['name']);
}
elseif( $index['unique'] != $indexes[$index['name']]['unique'] ||
$index['columns'] != $indexes[$index['name']]['columns'])
{
$this->_alterIndex($tableName, $index['name'], $index);
}
unset($indexes[$index['name']]);
}
if(count($indexes))
{
foreach($indexes as $name => $index)
{
if($name == 'PRIMARY')
{
continue;
}
// New index
$this->_addIndex($tableName, $name, $index);
}
}
}
protected function _addIndex($table, $name, $idx, $stage = 'add_index')
{
if($name == 'PRIMARY')
{
return;
}
$q = 'CREATE ' . (isset($idx['unique']) && $idx['unique'] ? 'UNIQUE' : '') . ' INDEX `' . $name . '` ON `' . $table . '` (' . $idx['columns'] . ')';
$this->_todo[$stage][] = $q;
}
protected function _alterIndex($table, $name, $idx, $stage = 'index')
{
$this->_dropIndex($table, $name, $stage);
$this->_addIndex($table, $name, $idx, $stage);
}
protected function _dropIndex($table, $idxName, $stage = 'drop_index')
{
if($idxName == 'PRIMARY')
{
return;
}
$q = 'DROP INDEX `' . $idxName . '` ON `' . $table . '`';
$this->_todo[$stage][] = $q;
}
protected function _addFk($table, $name, $fk)
{
$q = 'ALTER TABLE `' . $table . '` ADD CONSTRAINT `' . $name . '` FOREIGN KEY (`' . $fk['local_col'] . '`) REFERENCES `'.$fk['table'].'` (`'.$fk['col'].'`)';
if(!empty($fk['delete']))
{
$q .= ' ON DELETE ' . $fk['delete'] . ' ';
}
if(!empty($fk['update']))
{
$q .= ' ON UPDATE ' . $fk['update'] . ' ';
}
$this->_todo['add_fk'][] = $q;
}
protected function _alterFk($table, $name, $fk)
{
$this->_dropFk($table, $name);
$this->_addFk($table, $name, $fk);
}
protected function _dropFk($table, $name)
{
$q = 'ALTER TABLE `'.$table.'` DROP FOREIGN KEY `' . $name . '`';
$this->_todo['drop_fk'][] = $q;
}
protected $_db = null;
protected $_map = null;
protected $_tables = null;
protected $_ns = null;
protected $_path = null;
public function __construct(Database $db, $namespace, $path)
{
$this->_db = $db;
$this->_ns = $namespace;
$this->_path = $path;
$this->_map = new Map($this->_db);
$this->_tables = $this->_map->generate();
}
public function generate()
{
error_reporting(E_ERROR & E_WARNING);
$di = new \DirectoryIterator($this->_path);
$this->_todo = [
'drop_fk' => [],
'drop_index' => [],
'create' => [],
'alter' => [],
'add_index' => [],
'add_fk' => [],
];
foreach ($di as $file) {
if ($file->isDot()) {
continue;
}
$fileName = explode('.', $file->getBasename());
if ($fileName[count($fileName) - 1] != 'php') {
continue;
}
$modelName = '\\' . $this->_ns . '\\Model\\Base\\' . str_replace('.php', '', $file->getFilename());
require_once($this->_path . $file->getFilename());
$model = new $modelName();
$columns = $model->columns;
$indexes = $model->indexes;
$foreignKeys = $model->foreignKeys;
$tableName = $model->getTableName();
if (!array_key_exists($tableName, $this->_tables)) {
$this->_createTable($tableName, $columns, $indexes, $foreignKeys);
continue;
} else {
$table = $this->_tables[$tableName];
$this->_updateColumns($tableName, $table, $columns);
$this->_updateRelationships($tableName, $table, $foreignKeys);
$this->_updateIndexes($tableName, $table, $indexes);
}
}
print 'DROP FK: ' . count($this->_todo['drop_fk']) . PHP_EOL;
print 'DROP INDEX: ' . count($this->_todo['drop_index']) . PHP_EOL;
print 'CREATE TABLE: ' . count($this->_todo['create']) . PHP_EOL;
print 'ALTER TABLE: ' . count($this->_todo['alter']) . PHP_EOL;
print 'ADD INDEX: ' . count($this->_todo['add_index']) . PHP_EOL;
print 'ADD FK: ' . count($this->_todo['add_fk']) . PHP_EOL;
$order = array_keys($this->_todo);
while ($group = array_shift($order)) {
if (!isset($this->_todo[$group]) || !is_array($this->_todo[$group]) || !count($this->_todo[$group])) {
continue;
}
foreach ($this->_todo[$group] as $query) {
try {
//print $query . PHP_EOL;
$this->_db->query($query);
} catch (\Exception $ex) {
print 'FAILED TO EXECUTE: ' . $query . PHP_EOL;
print $ex->getMessage() . PHP_EOL . PHP_EOL;
}
}
}
}
protected function _createTable($tbl, $cols, $idxs, $fks)
{
$defs = [];
$pks = [];
foreach ($cols as $colName => $def) {
$add = '`' . $colName . '` ' . $def['type'];
switch ($def['type']) {
case 'text':
case 'longtext':
case 'mediumtext':
case 'date':
case 'datetime':
case 'float':
$add .= '';
break;
default:
$add .= !empty($def['length']) ? '(' . $def['length'] . ')' : '';
break;
}
if (empty($def['nullable']) || !$def['nullable']) {
$add .= ' NOT NULL ';
}
if (!empty($def['default'])) {
$add .= ' DEFAULT ' . (is_numeric($def['default']) ? $def['default'] : '\'' . $def['default'] . '\'');
}
if (!empty($def['auto_increment']) && $def['auto_increment']) {
$add .= ' AUTO_INCREMENT ';
}
if (!empty($def['primary_key']) && $def['primary_key']) {
$pks[] = '`' . $colName . '`';
}
$defs[] = $add;
}
if (count($pks)) {
$defs[] = 'PRIMARY KEY (' . implode(', ', $pks) . ')';
}
$stmt = 'CREATE TABLE `' . $tbl . '` (' . PHP_EOL;
$stmt .= implode(", \n", $defs);
$stmt .= PHP_EOL . ') ENGINE=InnoDB DEFAULT CHARSET=utf8';
$stmt .= PHP_EOL;
$this->_todo['create'][] = $stmt;
foreach ($idxs as $name => $idx) {
$this->_addIndex($tbl, $name, $idx);
}
foreach ($fks as $name => $fk) {
$this->_addFk($tbl, $name, $fk);
}
}
protected function _updateColumns($tableName, $table, $columns)
{
$currentColumns = $table['columns'];
while ($column = array_shift($currentColumns)) {
if (!array_key_exists($column['name'], $columns)) {
$this->_todo['alter'][$tableName . '.' . $column['name']] = 'ALTER TABLE `' . $tableName . '` DROP COLUMN `' . $column['name'] . '`';
} else {
$model = $columns[$column['name']];
$model['nullable'] = !isset($model['nullable']) ? false : $model['nullable'];
$model['default'] = !isset($model['default']) ? false : $model['default'];
$model['auto_increment'] = !isset($model['auto_increment']) ? false : $model['auto_increment'];
$model['primary_key'] = !isset($model['primary_key']) ? false : $model['primary_key'];
$column['is_primary_key'] = !isset($column['is_primary_key']) ? false : $column['is_primary_key'];
if (
$column['type'] != $model['type'] || (
$column['length'] != $model['length'] &&
!in_array($model['type'], ['text', 'longtext', 'mediumtext', 'date', 'datetime', 'float'])
) ||
$column['null'] != $model['nullable'] ||
$column['default'] != $model['default'] ||
$column['auto'] != $model['auto_increment']
) {
$this->_updateColumn($tableName, $column['name'], $column['name'], $model);
}
}
unset($columns[$column['name']]);
}
if (count($columns)) {
foreach ($columns as $name => $model) {
// Check if we're renaming a column:
if (isset($model['rename'])) {
unset($this->_todo['alter'][$tableName . '.' . $model['rename']]);
$this->_updateColumn($tableName, $model['rename'], $name, $model);
continue;
}
// New column
$add = '`' . $name . '` ' . $model['type'];;
switch ($model['type']) {
case 'text':
case 'longtext':
case 'mediumtext':
case 'date':
case 'datetime':
case 'float':
$add .= '';
break;
default:
$add .= !empty($model['length']) ? '(' . $model['length'] . ')' : '';
break;
}
if (empty($model['nullable']) || !$model['nullable']) {
$add .= ' NOT NULL ';
}
if (!empty($model['default'])) {
$add .= ' DEFAULT ' . (is_numeric($model['default']) ? $model['default'] : '\'' . $model['default'] . '\'');
}
if (!empty($model['auto_increment']) && $model['auto_increment']) {
$add .= ' AUTO_INCREMENT ';
}
if (!empty($model['primary_key']) && $model['primary_key'] && !isset($table['indexes']['PRIMARY'])) {
$add .= ' PRIMARY KEY ';
}
$this->_todo['alter'][] = 'ALTER TABLE `' . $tableName . '` ADD COLUMN ' . $add;
}
}
}
protected function _updateColumn($tableName, $prevName, $newName, $model)
{
$add = '`' . $newName . '` ' . $model['type'];;
switch ($model['type']) {
case 'text':
case 'longtext':
case 'mediumtext':
case 'date':
case 'datetime':
case 'float':
$add .= '';
break;
default:
$add .= !empty($model['length']) ? '(' . $model['length'] . ')' : '';
break;
}
if (empty($model['nullable']) || !$model['nullable']) {
$add .= ' NOT NULL ';
}
if (!empty($model['default'])) {
$add .= ' DEFAULT ' . (is_numeric($model['default']) ? $model['default'] : '\'' . $model['default'] . '\'');
}
if (!empty($model['auto_increment']) && $model['auto_increment']) {
$add .= ' AUTO_INCREMENT ';
}
$this->_todo['alter'][] = 'ALTER TABLE `' . $tableName . '` CHANGE COLUMN `' . $prevName . '` ' . $add;
}
protected function _updateRelationships($tableName, $table, $foreignKeys)
{
$current = $table['relationships']['toOne'];
while ($foreignKey = array_shift($current)) {
if (!array_key_exists($foreignKey['fk_name'], $foreignKeys)) {
$this->_dropFk($tableName, $foreignKey['fk_name']);
} elseif ($foreignKey['from_col'] != $foreignKeys[$foreignKey['fk_name']]['local_col'] ||
$foreignKey['table'] != $foreignKeys[$foreignKey['fk_name']]['table'] ||
$foreignKey['col'] != $foreignKeys[$foreignKey['fk_name']]['col'] ||
$foreignKey['fk_update'] != $foreignKeys[$foreignKey['fk_name']]['update'] ||
$foreignKey['fk_delete'] != $foreignKeys[$foreignKey['fk_name']]['delete']
) {
$this->_alterFk($tableName, $foreignKey['fk_name'], $foreignKeys[$foreignKey['fk_name']]);
}
unset($foreignKeys[$foreignKey['fk_name']]);
}
if (count($foreignKeys)) {
foreach ($foreignKeys as $name => $foreignKey) {
// New column
$this->_addFk($tableName, $name, $foreignKey);
}
}
}
protected function _updateIndexes($tableName, $table, $indexes)
{
$current = $table['indexes'];
while ($index = array_shift($current)) {
if (!array_key_exists($index['name'], $indexes)) {
$this->_dropIndex($tableName, $index['name']);
} elseif ($index['unique'] != $indexes[$index['name']]['unique'] ||
$index['columns'] != $indexes[$index['name']]['columns']
) {
$this->_alterIndex($tableName, $index['name'], $index);
}
unset($indexes[$index['name']]);
}
if (count($indexes)) {
foreach ($indexes as $name => $index) {
if ($name == 'PRIMARY') {
continue;
}
// New index
$this->_addIndex($tableName, $name, $index);
}
}
}
protected function _addIndex($table, $name, $idx, $stage = 'add_index')
{
if ($name == 'PRIMARY') {
return;
}
$q = 'CREATE ' . (isset($idx['unique']) && $idx['unique'] ? 'UNIQUE' : '') . ' INDEX `' . $name . '` ON `' . $table . '` (' . $idx['columns'] . ')';
$this->_todo[$stage][] = $q;
}
protected function _alterIndex($table, $name, $idx, $stage = 'index')
{
$this->_dropIndex($table, $name, $stage);
$this->_addIndex($table, $name, $idx, $stage);
}
protected function _dropIndex($table, $idxName, $stage = 'drop_index')
{
if ($idxName == 'PRIMARY') {
return;
}
$q = 'DROP INDEX `' . $idxName . '` ON `' . $table . '`';
$this->_todo[$stage][] = $q;
}
protected function _addFk($table, $name, $fk)
{
$q = 'ALTER TABLE `' . $table . '` ADD CONSTRAINT `' . $name . '` FOREIGN KEY (`' . $fk['local_col'] . '`) REFERENCES `' . $fk['table'] . '` (`' . $fk['col'] . '`)';
if (!empty($fk['delete'])) {
$q .= ' ON DELETE ' . $fk['delete'] . ' ';
}
if (!empty($fk['update'])) {
$q .= ' ON UPDATE ' . $fk['update'] . ' ';
}
$this->_todo['add_fk'][] = $q;
}
protected function _alterFk($table, $name, $fk)
{
$this->_dropFk($table, $name);
$this->_addFk($table, $name, $fk);
}
protected function _dropFk($table, $name)
{
$q = 'ALTER TABLE `' . $table . '` DROP FOREIGN KEY `' . $name . '`';
$this->_todo['drop_fk'][] = $q;
}
}

View file

@ -1,12 +1,13 @@
<?php
namespace b8\Database;
use b8\Database;
class Map
{
protected $_db = null;
protected $_tables = array();
protected $_db = null;
protected $_tables = [];
public function __construct(Database $db)
{
@ -18,10 +19,9 @@ class Map
$tables = $this->_getTables();
foreach($tables as $table)
{
$this->_tables[$table] = array();
$this->_tables[$table]['php_name'] = $this->_generatePhpName($table);
foreach ($tables as $table) {
$this->_tables[$table] = [];
$this->_tables[$table]['php_name'] = $this->_generatePhpName($table);
}
$this->_getRelationships();
@ -35,10 +35,9 @@ class Map
{
$details = $this->_db->getDetails();
$rtn = array();
$rtn = [];
foreach($this->_db->query('SHOW TABLES')->fetchAll(\PDO::FETCH_ASSOC) as $tbl)
{
foreach ($this->_db->query('SHOW TABLES')->fetchAll(\PDO::FETCH_ASSOC) as $tbl) {
$rtn[] = $tbl['Tables_in_' . $details['db']];
}
@ -47,47 +46,63 @@ class Map
protected function _getRelationships()
{
foreach($this->_tables as $table => $t)
{
$res = $this->_db->query('SHOW CREATE TABLE `'.$table.'`')->fetchAll(\PDO::FETCH_ASSOC);
foreach ($this->_tables as $table => $t) {
$res = $this->_db->query('SHOW CREATE TABLE `' . $table . '`')->fetchAll(\PDO::FETCH_ASSOC);
foreach($res as $r)
{
foreach ($res as $r) {
$str = $r['Create Table'];
$matches = array();
if(preg_match_all('/CONSTRAINT\s+\`([a-zA-Z0-9_]+)\`\s+FOREIGN\s+KEY\s+\(\`([a-zA-Z0-9_]+)\`\)\s+REFERENCES\s+\`([a-zA-Z0-9_]+)\`\s+\(\`([a-zA-Z0-9_]+)\`\)(\s+ON (DELETE|UPDATE) (SET NULL|NO ACTION|CASCADE|RESTRICT))?(\s+ON (DELETE|UPDATE) (SET NULL|NO ACTION|CASCADE|RESTRICT))?/', $str, $matches))
{
for($i = 0; $i < count($matches[0]); $i++)
{
$fromTable = $table;
$fromCol = $matches[2][$i];
$toTable = $matches[3][$i];
$toCol = $matches[4][$i];
$fkName = $matches[1][$i];
$fk = array();
$matches = [];
if (preg_match_all('/CONSTRAINT\s+\`([a-zA-Z0-9_]+)\`\s+FOREIGN\s+KEY\s+\(\`([a-zA-Z0-9_]+)\`\)\s+REFERENCES\s+\`([a-zA-Z0-9_]+)\`\s+\(\`([a-zA-Z0-9_]+)\`\)(\s+ON (DELETE|UPDATE) (SET NULL|NO ACTION|CASCADE|RESTRICT))?(\s+ON (DELETE|UPDATE) (SET NULL|NO ACTION|CASCADE|RESTRICT))?/',
$str, $matches)) {
for ($i = 0; $i < count($matches[0]); $i++) {
$fromTable = $table;
$fromCol = $matches[2][$i];
$toTable = $matches[3][$i];
$toCol = $matches[4][$i];
$fkName = $matches[1][$i];
$fk = [];
if(isset($matches[6][$i]))
{
if (isset($matches[6][$i])) {
$fk[$matches[6][$i]] = $matches[7][$i];
}
if(isset($matches[9][$i]))
{
if (isset($matches[9][$i])) {
$fk[$matches[9][$i]] = $matches[10][$i];
}
$fk['UPDATE'] = empty($fk['UPDATE']) ? '' : $fk['UPDATE'];
$fk['DELETE'] = empty($fk['DELETE']) ? '' : $fk['DELETE'];
if(isset($this->_tables[$fromTable]) && isset($this->_tables[$toTable]))
{
if (isset($this->_tables[$fromTable]) && isset($this->_tables[$toTable])) {
$phpName = $this->_generateFkName($fromCol, $this->_tables[$fromTable]['php_name']);
$this->_tables[$fromTable]['relationships']['toOne'][$fromCol] = array('fk_name' => $fkName, 'fk_delete' => $fk['DELETE'], 'fk_update' => $fk['UPDATE'], 'table_php_name' => $this->_tables[$toTable]['php_name'], 'from_col_php' => $this->_generatePhpName($fromCol), 'from_col' => $fromCol, 'php_name' => $phpName, 'table' => $toTable, 'col' => $toCol, 'col_php' => $this->_generatePhpName($toCol));
$this->_tables[$fromTable]['relationships']['toOne'][$fromCol] = [
'fk_name' => $fkName,
'fk_delete' => $fk['DELETE'],
'fk_update' => $fk['UPDATE'],
'table_php_name' => $this->_tables[$toTable]['php_name'],
'from_col_php' => $this->_generatePhpName($fromCol),
'from_col' => $fromCol,
'php_name' => $phpName,
'table' => $toTable,
'col' => $toCol,
'col_php' => $this->_generatePhpName($toCol)
];
$phpName = $this->_generateFkName($fromCol, $this->_tables[$fromTable]['php_name']) . $this->_tables[$fromTable]['php_name'].'s';
$this->_tables[$toTable]['relationships']['toMany'][] = array('from_col_php' => $this->_generatePhpName($fromCol), 'php_name' => $phpName, 'thisCol' => $toCol, 'table' => $fromTable, 'table_php' => $this->_generatePhpName($fromTable), 'fromCol' => $fromCol, 'col_php' => $this->_generatePhpName($toCol));
$phpName = $this->_generateFkName(
$fromCol,
$this->_tables[$fromTable]['php_name']
) . $this->_tables[$fromTable]['php_name'] . 's';
$this->_tables[$toTable]['relationships']['toMany'][] = [
'from_col_php' => $this->_generatePhpName($fromCol),
'php_name' => $phpName,
'thisCol' => $toCol,
'table' => $fromTable,
'table_php' => $this->_generatePhpName($fromTable),
'fromCol' => $fromCol,
'col_php' => $this->_generatePhpName($toCol)
];
}
}
}
@ -97,12 +112,10 @@ class Map
protected function _getColumns()
{
foreach($this->_tables as $key => &$val)
{
$cols = array();
foreach($this->_db->query('DESCRIBE `' . $key . '`')->fetchAll(\PDO::FETCH_ASSOC) as $column)
{
$col = $this->_processColumn(array(), $column, $val);
foreach ($this->_tables as $key => &$val) {
$cols = [];
foreach ($this->_db->query('DESCRIBE `' . $key . '`')->fetchAll(\PDO::FETCH_ASSOC) as $column) {
$col = $this->_processColumn([], $column, $val);
$cols[$col['name']] = $col;
}
@ -113,25 +126,21 @@ class Map
protected function _getIndexes()
{
foreach($this->_tables as $key => &$val)
{
$indexes = array();
foreach ($this->_tables as $key => &$val) {
$indexes = [];
foreach($this->_db->query('SHOW INDEXES FROM `' . $key . '`')->fetchAll(\PDO::FETCH_ASSOC) as $idx)
{
if(!isset($indexes[$idx['Key_name']]))
{
$indexes[$idx['Key_name']] = array();
$indexes[$idx['Key_name']]['name'] = $idx['Key_name'];
$indexes[$idx['Key_name']]['unique'] = ($idx['Non_unique'] == '0') ? true : false;
$indexes[$idx['Key_name']]['columns'] = array();
foreach ($this->_db->query('SHOW INDEXES FROM `' . $key . '`')->fetchAll(\PDO::FETCH_ASSOC) as $idx) {
if (!isset($indexes[$idx['Key_name']])) {
$indexes[$idx['Key_name']] = [];
$indexes[$idx['Key_name']]['name'] = $idx['Key_name'];
$indexes[$idx['Key_name']]['unique'] = ($idx['Non_unique'] == '0') ? true : false;
$indexes[$idx['Key_name']]['columns'] = [];
}
$indexes[$idx['Key_name']]['columns'][$idx['Seq_in_index']] = $idx['Column_name'];
}
$indexes = array_map(function($idx)
{
$indexes = array_map(function ($idx) {
ksort($idx['columns']);
$idx['columns'] = implode(', ', $idx['columns']);
@ -144,21 +153,20 @@ class Map
protected function _processColumn($col, $column, &$table)
{
$col['name'] = $column['Field'];
$col['php_name']= $this->_generatePhpName($col['name']);
$matches = array();
$col['name'] = $column['Field'];
$col['php_name'] = $this->_generatePhpName($col['name']);
$matches = [];
preg_match('/^([a-zA-Z]+)(\()?([0-9\,]+)?(\))?/', $column['Type'], $matches);
$col['type'] = strtolower($matches[1]);
$col['type'] = strtolower($matches[1]);
if(isset($matches[3]))
{
if (isset($matches[3])) {
$col['length'] = $matches[3];
}
$col['null'] = strtolower($column['Null']) == 'yes' ? true : false;
$col['auto'] = strtolower($column['Extra']) == 'auto_increment' ? true : false;
$col['null'] = strtolower($column['Null']) == 'yes' ? true : false;
$col['auto'] = strtolower($column['Extra']) == 'auto_increment' ? true : false;
if ($column['Default'] == 'NULL' || is_null($column['Default'])) {
$col['default_is_null'] = true;
@ -167,63 +175,56 @@ class Map
$col['default'] = $column['Default'];
}
if(!empty($column['Key']))
{
if($column['Key'] == 'PRI')
{
$col['is_primary_key'] = true;
$table['primary_key'] = array('column' => $col['name'], 'php_name' => $col['php_name']);
if (!empty($column['Key'])) {
if ($column['Key'] == 'PRI') {
$col['is_primary_key'] = true;
$table['primary_key'] = ['column' => $col['name'], 'php_name' => $col['php_name']];
}
if($column['Key'] == 'PRI' || $column['Key'] == 'UNI')
{
$col['unique_indexed'] = true;
}
else
{
$col['many_indexed'] = true;
if ($column['Key'] == 'PRI' || $column['Key'] == 'UNI') {
$col['unique_indexed'] = true;
} else {
$col['many_indexed'] = true;
}
}
$col['validate']= array();
$col['validate'] = [];
if(!$col['null'])
{
if (!$col['null']) {
$col['validate_null'] = true;
}
switch($col['type'])
{
switch ($col['type']) {
case 'tinyint':
case 'smallint':
case 'int':
case 'mediumint':
case 'bigint':
$col['php_type'] = 'int';
$col['to_php'] = '_sqlToInt';
$col['validate_int']= true;
$col['php_type'] = 'int';
$col['to_php'] = '_sqlToInt';
$col['validate_int'] = true;
break;
case 'float':
case 'decimal':
$col['php_type'] = 'float';
$col['to_php'] = '_sqlToFloat';
$col['php_type'] = 'float';
$col['to_php'] = '_sqlToFloat';
$col['validate_float'] = true;
break;
case 'datetime':
case 'date':
$col['php_type'] = 'DateTime';
$col['to_php'] = '_sqlToDateTime';
$col['to_sql'] = '_dateTimeToSql';
$col['php_type'] = 'DateTime';
$col['to_php'] = '_sqlToDateTime';
$col['to_sql'] = '_dateTimeToSql';
$col['validate_date'] = true;
break;
case 'varchar':
case 'text':
default:
$col['php_type'] = 'string';
$col['validate_string'] = true;
$col['php_type'] = 'string';
$col['validate_string'] = true;
break;
}
@ -244,8 +245,7 @@ class Map
{
$fkMethod = substr($sqlName, 0, strripos($sqlName, '_'));
if(empty($fkMethod))
{
if (empty($fkMethod)) {
$fkMethod = (substr(strtolower($sqlName), -2) == 'id') ? substr($sqlName, 0, -2) : $tablePhpName;
}

View file

@ -1,21 +1,21 @@
<?php
namespace b8\Form\Element;
use b8\View,
b8\Form\Input;
use b8\View, b8\Form\Input;
class Select extends Input
{
protected $_options = array();
protected $_options = [];
public function setOptions(array $options)
{
$this->_options = $options;
}
public function setOptions(array $options)
{
$this->_options = $options;
}
protected function _onPreRender(View &$view)
{
parent::_onPreRender($view);
$view->options = $this->_options;
}
protected function _onPreRender(View &$view)
{
parent::_onPreRender($view);
$view->options = $this->_options;
}
}

View file

@ -1,106 +1,84 @@
<?php
namespace b8\Form;
use b8\Form\Element,
b8\Form\Input,
b8\View;
use b8\Form\Element, b8\View;
class FieldSet extends Element
{
protected $_children = array();
protected $_children = [];
public function getValues()
{
$rtn = array();
public function getValues()
{
$rtn = [];
foreach ($this->_children as $field) {
if ($field instanceof FieldSet) {
$fieldName = $field->getName();
foreach($this->_children as $field)
{
if($field instanceof FieldSet)
{
$fieldName = $field->getName();
if (empty($fieldName)) {
$rtn = array_merge($rtn, $field->getValues());
} else {
$rtn[$fieldName] = $field->getValues();
}
} elseif ($field instanceof Input) {
if ($field->getName()) {
$rtn[$field->getName()] = $field->getValue();
}
}
}
if(empty($fieldName))
{
$rtn = array_merge($rtn, $field->getValues());
}
else
{
$rtn[$fieldName] = $field->getValues();
}
}
elseif($field instanceof Input)
{
if($field->getName())
{
$rtn[$field->getName()] = $field->getValue();
}
}
}
return $rtn;
}
return $rtn;
}
public function setValues(array $values)
{
foreach ($this->_children as $field) {
if ($field instanceof FieldSet) {
$fieldName = $field->getName();
public function setValues(array $values)
{
foreach($this->_children as $field)
{
if($field instanceof FieldSet)
{
$fieldName = $field->getName();
if (empty($fieldName) || !isset($values[$fieldName])) {
$field->setValues($values);
} else {
$field->setValues($values[$fieldName]);
}
} elseif ($field instanceof Input) {
$fieldName = $field->getName();
if(empty($fieldName) || !isset($values[$fieldName]))
{
$field->setValues($values);
}
else
{
$field->setValues($values[$fieldName]);
}
}
elseif($field instanceof Input)
{
$fieldName = $field->getName();
if (isset($values[$fieldName])) {
$field->setValue($values[$fieldName]);
}
}
}
}
if(isset($values[$fieldName]))
{
$field->setValue($values[$fieldName]);
}
}
}
}
public function addField(Element $field)
{
$this->_children[$field->getName()] = $field;
$field->setParent($this);
}
public function addField(Element $field)
{
$this->_children[$field->getName()] = $field;
$field->setParent($this);
}
public function validate()
{
$rtn = true;
public function validate()
{
$rtn = true;
foreach ($this->_children as $child) {
if (!$child->validate()) {
$rtn = false;
}
}
foreach($this->_children as $child)
{
if(!$child->validate())
{
$rtn = false;
}
}
return $rtn;
}
return $rtn;
}
protected function _onPreRender(View &$view)
{
$rendered = [];
foreach ($this->_children as $child) {
$rendered[] = $child->render();
}
protected function _onPreRender(View &$view)
{
$rendered = array();
foreach($this->_children as $child)
{
$rendered[] = $child->render();
}
$view->children = $rendered;
}
$view->children = $rendered;
}
public function getChildren()
{

View file

@ -1,16 +1,17 @@
<?php
namespace b8\Form;
use b8\Form\Element,
b8\View;
b8\View;
class Input extends Element
{
protected $_required = false;
protected $_pattern;
protected $_validator;
protected $_value;
protected $_error;
protected $_required = false;
protected $_pattern;
protected $_validator;
protected $_value;
protected $_error;
protected $_customError = false;
public static function create($name, $label, $required = false)
@ -23,89 +24,82 @@ class Input extends Element
return $el;
}
public function getValue()
{
return $this->_value;
}
public function getValue()
{
return $this->_value;
}
public function setValue($value)
{
$this->_value = $value;
public function setValue($value)
{
$this->_value = $value;
return $this;
}
}
public function getRequired()
{
return $this->_required;
}
public function getRequired()
{
return $this->_required;
}
public function setRequired($required)
{
$this->_required = (bool)$required;
public function setRequired($required)
{
$this->_required = (bool)$required;
return $this;
}
}
public function getValidator()
{
return $this->_validator;
}
public function getValidator()
{
return $this->_validator;
}
public function setValidator($validator)
{
if(is_callable($validator) || $validator instanceof \Closure)
{
$this->_validator = $validator;
}
public function setValidator($validator)
{
if (is_callable($validator) || $validator instanceof \Closure) {
$this->_validator = $validator;
}
return $this;
}
}
public function getPattern()
{
return $this->_pattern;
}
public function getPattern()
{
return $this->_pattern;
}
public function setPattern($pattern)
{
$this->_pattern = $pattern;
public function setPattern($pattern)
{
$this->_pattern = $pattern;
return $this;
}
}
public function validate()
{
if($this->getRequired() && empty($this->_value))
{
$this->_error = $this->getLabel() . ' is required.';
return false;
}
public function validate()
{
if ($this->getRequired() && empty($this->_value)) {
$this->_error = $this->getLabel() . ' is required.';
return false;
}
if($this->getPattern() && !preg_match('/'.$this->getPattern().'/', $this->_value))
{
$this->_error = 'Invalid value entered.';
return false;
}
if ($this->getPattern() && !preg_match('/' . $this->getPattern() . '/', $this->_value)) {
$this->_error = 'Invalid value entered.';
return false;
}
$validator = $this->getValidator();
$validator = $this->getValidator();
if(is_callable($validator))
{
try
{
call_user_func_array($validator, array($this->_value));
}
catch(\Exception $ex)
{
$this->_error = $ex->getMessage();
return false;
}
}
if (is_callable($validator)) {
try {
call_user_func_array($validator, [$this->_value]);
} catch (\Exception $ex) {
$this->_error = $ex->getMessage();
return false;
}
}
if ($this->_customError) {
return false;
}
return true;
}
return true;
}
public function setError($message)
{
@ -114,11 +108,11 @@ class Input extends Element
return $this;
}
protected function _onPreRender(View &$view)
{
$view->value = $this->getValue();
$view->error = $this->_error;
$view->pattern = $this->_pattern;
$view->required = $this->_required;
}
protected function _onPreRender(View &$view)
{
$view->value = $this->getValue();
$view->error = $this->_error;
$view->pattern = $this->_pattern;
$view->required = $this->_required;
}
}

View file

@ -5,18 +5,18 @@ namespace b8\Http;
class Request
{
/**
* @var array
*/
protected $params = array();
* @var array
*/
protected $params = [];
/**
* Request data.
*/
protected $data = array();
* Request data.
*/
protected $data = [];
/**
* Set up the request.
*/
* Set up the request.
*/
public function __construct()
{
$this->parseInput();
@ -40,7 +40,7 @@ class Request
}
// Remove index.php from the URL if it is present:
$path = str_replace(array('/index.php', 'index.php'), '', $path);
$path = str_replace(['/index.php', 'index.php'], '', $path);
// Also cut out the query string:
$path = explode('?', $path);
@ -50,22 +50,20 @@ class Request
}
/**
* Parse incoming variables, incl. $_GET, $_POST and also reads php://input for PUT/DELETE.
*/
* Parse incoming variables, incl. $_GET, $_POST and also reads php://input for PUT/DELETE.
*/
protected function parseInput()
{
$params = $_REQUEST;
if(!isset($_SERVER['REQUEST_METHOD']) || in_array($_SERVER['REQUEST_METHOD'], array('PUT', 'DELETE')))
{
if (!isset($_SERVER['REQUEST_METHOD']) || in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'DELETE'])) {
$vars = file_get_contents('php://input');
if(!is_string($vars) || strlen(trim($vars)) === 0)
{
if (!is_string($vars) || strlen(trim($vars)) === 0) {
$vars = '';
}
$inputData = array();
$inputData = [];
parse_str($vars, $inputData);
$params = array_merge($params, $inputData);
@ -75,17 +73,17 @@ class Request
}
/**
* Returns all request parameters.
* @return array
*/
* Returns all request parameters.
* @return array
*/
public function getParams()
{
return $this->params;
}
/**
* Return a specific request parameter, or a default value if not set.
*/
* Return a specific request parameter, or a default value if not set.
*/
public function getParam($key, $default = null)
{
if (isset($this->params[$key])) {
@ -96,24 +94,24 @@ class Request
}
/**
* Set or override a request parameter.
*/
* Set or override a request parameter.
*/
public function setParam($key, $value = null)
{
$this->params[$key] = $value;
}
/**
* Set an array of request parameters.
*/
* Set an array of request parameters.
*/
public function setParams(array $params)
{
$this->params = array_merge($this->params, $params);
}
/**
* Un-set a specific parameter.
*/
* Un-set a specific parameter.
*/
public function unsetParam($key)
{
unset($this->params[$key]);

View file

@ -4,129 +4,128 @@ namespace b8\Http;
class Response
{
protected $data = array();
protected $data = [];
public function __construct(Response $createFrom = null)
{
if (!is_null($createFrom)) {
$this->data = $createFrom->getData();
}
}
public function __construct(Response $createFrom = null)
{
if (!is_null($createFrom)) {
$this->data = $createFrom->getData();
}
}
public function hasLayout()
{
return !isset($this->data['layout']) ? true : $this->data['layout'];
}
public function hasLayout()
{
return !isset($this->data['layout']) ? true : $this->data['layout'];
}
public function disableLayout()
{
$this->data['layout'] = false;
}
public function disableLayout()
{
$this->data['layout'] = false;
}
public function enableLayout()
{
$this->data['layout'] = true;
}
public function enableLayout()
{
$this->data['layout'] = true;
}
public function getData()
{
return $this->data;
}
public function getData()
{
return $this->data;
}
public function setResponseCode($code)
{
$this->data['code'] = (int)$code;
}
public function setResponseCode($code)
{
$this->data['code'] = (int)$code;
}
public function setHeader($key, $val)
{
$this->data['headers'][$key] = $val;
}
public function setHeader($key, $val)
{
$this->data['headers'][$key] = $val;
}
public function clearHeaders()
{
$this->data['headers'] = array();
}
public function clearHeaders()
{
$this->data['headers'] = [];
}
public function setContent($content)
{
$this->data['body'] = $content;
}
public function setContent($content)
{
$this->data['body'] = $content;
}
public function getContent()
{
return $this->data['body'];
}
public function getContent()
{
return $this->data['body'];
}
public function flush()
{
$this->sendResponseCode();
public function flush()
{
$this->sendResponseCode();
if (isset($this->data['headers'])) {
foreach ($this->data['headers'] as $header => $val) {
header($header . ': ' . $val, true);
}
}
return $this->flushBody();
}
if (isset($this->data['headers'])) {
foreach ($this->data['headers'] as $header => $val) {
header($header . ': ' . $val, true);
}
}
protected function sendResponseCode()
{
if (!isset($this->data['code'])) {
$this->data['code'] = 200;
}
return $this->flushBody();
}
switch ($this->data['code'])
{
// 300 class
case 301:
$text = 'Moved Permanently';
break;
case 302:
$text = 'Moved Temporarily';
break;
protected function sendResponseCode()
{
if (!isset($this->data['code'])) {
$this->data['code'] = 200;
}
// 400 class errors
case 400:
$text = 'Bad Request';
break;
case 401:
$text = 'Not Authorized';
break;
case 403:
$text = 'Forbidden';
break;
case 404:
$text = 'Not Found';
break;
switch ($this->data['code']) {
// 300 class
case 301:
$text = 'Moved Permanently';
break;
case 302:
$text = 'Moved Temporarily';
break;
// 500 class errors
case 500:
$text = 'Internal Server Error';
break;
// 400 class errors
case 400:
$text = 'Bad Request';
break;
case 401:
$text = 'Not Authorized';
break;
case 403:
$text = 'Forbidden';
break;
case 404:
$text = 'Not Found';
break;
// OK
case 200:
default:
$text = 'OK';
break;
}
// 500 class errors
case 500:
$text = 'Internal Server Error';
break;
header('HTTP/1.1 ' . $this->data['code'] . ' ' . $text, true, $this->data['code']);
}
// OK
case 200:
default:
$text = 'OK';
break;
}
protected function flushBody()
{
if (isset($this->data['body'])) {
return $this->data['body'];
}
header('HTTP/1.1 ' . $this->data['code'] . ' ' . $text, true, $this->data['code']);
}
return '';
}
protected function flushBody()
{
if (isset($this->data['body'])) {
return $this->data['body'];
}
public function __toString()
{
return $this->flush();
}
return '';
}
public function __toString()
{
return $this->flush();
}
}

View file

@ -6,25 +6,25 @@ use b8\Http\Response;
class JsonResponse extends Response
{
public function __construct(Response $createFrom = null)
{
parent::__construct($createFrom);
public function __construct(Response $createFrom = null)
{
parent::__construct($createFrom);
$this->setContent(array());
$this->setHeader('Content-Type', 'application/json');
}
$this->setContent([]);
$this->setHeader('Content-Type', 'application/json');
}
public function hasLayout()
{
return false;
}
public function hasLayout()
{
return false;
}
protected function flushBody()
{
if (isset($this->data['body'])) {
return json_encode($this->data['body']);
}
protected function flushBody()
{
if (isset($this->data['body'])) {
return json_encode($this->data['body']);
}
return json_encode(null);
}
return json_encode(null);
}
}

View file

@ -26,7 +26,7 @@ class Router
/**
* @var array
*/
protected $routes = array(array('route' => '/:controller/:action', 'callback' => null, 'defaults' => array()));
protected $routes = [['route' => '/:controller/:action', 'callback' => null, 'defaults' => []]];
public function __construct(Application $application, Request $request, Config $config)
{
@ -37,7 +37,7 @@ class Router
public function clearRoutes()
{
$this->routes = array();
$this->routes = [];
}
/**
@ -46,13 +46,13 @@ class Router
* @param callable $callback
* @throws \InvalidArgumentException
*/
public function register($route, $options = array(), $callback = null)
public function register($route, $options = [], $callback = null)
{
if (!is_callable($callback)) {
throw new \InvalidArgumentException('$callback must be callable.');
}
array_unshift($this->routes, array('route' => $route, 'callback' => $callback, 'defaults' => $options));
array_unshift($this->routes, ['route' => $route, 'callback' => $callback, 'defaults' => $options]);
}
public function dispatch()
@ -110,7 +110,13 @@ class Router
$thisArgs = $pathParts;
if ($routeMatches) {
$route = array('namespace' => $thisNamespace, 'controller' => $thisController, 'action' => $thisAction, 'args' => $thisArgs, 'callback' => $route['callback']);
$route = [
'namespace' => $thisNamespace,
'controller' => $thisController,
'action' => $thisAction,
'args' => $thisArgs,
'callback' => $route['callback']
];
if ($this->application->isValidRoute($route)) {
return $route;

View file

@ -1,65 +1,64 @@
<?php
namespace b8\Store;
use b8\Config;
class Factory
{
/**
* @var \b8\Store\Factory
*/
protected static $instance;
/**
* @var \b8\Store\Factory
*/
protected static $instance;
/**
* A collection of the stores currently loaded by the factory.
* @var \b8\Store[]
*/
protected $loadedStores = array();
/**
* A collection of the stores currently loaded by the factory.
* @var \b8\Store[]
*/
protected $loadedStores = [];
/**
* @return Factory
*/
public static function getInstance()
{
if(!isset(self::$instance))
{
self::$instance = new self();
}
/**
* @return Factory
*/
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
return self::$instance;
}
/**
* @param $storeName string Store name (should match a model name).
*
* @return \b8\Store
*/
public static function getStore($storeName, $namespace = null)
{
$factory = self::getInstance();
return $factory->loadStore($storeName, $namespace);
}
/**
* @param $storeName string Store name (should match a model name).
*
* @return \b8\Store
*/
public static function getStore($storeName, $namespace = null)
{
$factory = self::getInstance();
return $factory->loadStore($storeName, $namespace);
}
protected function __construct()
{
}
protected function __construct()
{
}
/**
* @param $store
*
* @return \b8\Store;
*/
public function loadStore($store, $namespace = null)
{
if(!isset($this->loadedStores[$store]))
{
/**
* @param $store
*
* @return \b8\Store;
*/
public function loadStore($store, $namespace = null)
{
if (!isset($this->loadedStores[$store])) {
$namespace = is_null($namespace) ? Config::getInstance()->get('b8.app.namespace') : $namespace;
$class = $namespace . '\\Store\\' . $store . 'Store';
$obj = new $class();
$class = $namespace . '\\Store\\' . $store . 'Store';
$obj = new $class();
$this->loadedStores[$store] = $obj;
}
$this->loadedStores[$store] = $obj;
}
return $this->loadedStores[$store];
}
return $this->loadedStores[$store];
}
}

View file

@ -1,21 +1,25 @@
<?php
namespace b8\View;
use b8\View;
class Template extends View
{
public static $templateFunctions = array();
protected static $extension = 'html';
public static $templateFunctions = [];
protected static $extension = 'html';
public function __construct($viewCode)
{
$this->viewCode = $viewCode;
public function __construct($viewCode)
{
$this->viewCode = $viewCode;
if (!count(self::$templateFunctions)) {
self::$templateFunctions = array('include' => array($this, 'includeTemplate'), 'call' => array($this, 'callHelperFunction'));
self::$templateFunctions = [
'include' => [$this, 'includeTemplate'],
'call' => [$this, 'callHelperFunction']
];
}
}
}
public static function createFromFile($file, $path = null)
{
@ -42,113 +46,113 @@ class Template extends View
unset(self::$templateFunctions[$name]);
}
public function render()
{
return $this->parse($this->viewCode);
}
public function render()
{
return $this->parse($this->viewCode);
}
protected function parse($string)
{
$lastCond = null;
$keywords = array('ifnot', 'if', 'else', 'for', 'loop', '@', '/ifnot', '/if', '/for', '/loop');
protected function parse($string)
{
$lastCond = null;
$keywords = ['ifnot', 'if', 'else', 'for', 'loop', '@', '/ifnot', '/if', '/for', '/loop'];
foreach (self::$templateFunctions as $function => $handler) {
$keywords[] = $function;
}
$stack = array('children' => array(array('type' => 'string', 'body' => '')));
$stack['children'][0]['parent'] =& $stack;
$current =& $stack['children'][0];
$stack = ['children' => [['type' => 'string', 'body' => '']]];
$stack['children'][0]['parent'] =& $stack;
$current =& $stack['children'][0];
while (!empty($string)) {
$current['body'] .= $this->readUntil('{', $string);
while (!empty($string)) {
$current['body'] .= $this->readUntil('{', $string);
if (!empty($string)) {
$gotKeyword = false;
if (!empty($string)) {
$gotKeyword = false;
foreach($keywords as $keyword) {
$kwLen = strlen($keyword) + 1;
foreach ($keywords as $keyword) {
$kwLen = strlen($keyword) + 1;
if (substr($string, 0, $kwLen) == '{' . $keyword) {
$gotKeyword = true;
$item = array('type' => $keyword, 'cond' => '', 'children' => '');
$string = substr($string, $kwLen);
if (substr($string, 0, $kwLen) == '{' . $keyword) {
$gotKeyword = true;
$item = ['type' => $keyword, 'cond' => '', 'children' => ''];
$string = substr($string, $kwLen);
$cond = trim($this->readUntil('}', $string));
$item['cond'] = $cond;
$lastCond = $cond;
$string = substr($string, 1);
$cond = trim($this->readUntil('}', $string));
$item['cond'] = $cond;
$lastCond = $cond;
$string = substr($string, 1);
if (array_key_exists($keyword, self::$templateFunctions)) {
$item['function_name'] = $keyword;
$item['type'] = 'function';
}
$str = array('type' => 'string', 'body' => '');
$parent =& $current['parent'];
$str = ['type' => 'string', 'body' => ''];
$parent =& $current['parent'];
if (substr($current['body'], (0 - strlen(PHP_EOL))) === PHP_EOL) {
$current['body'] = substr($current['body'], 0, strlen($current['body']) - strlen(PHP_EOL));
}
if (substr($current['body'], (0 - strlen(PHP_EOL))) === PHP_EOL) {
$current['body'] = substr($current['body'], 0, strlen($current['body']) - strlen(PHP_EOL));
}
$item['parent'] =& $parent;
$item['parent'] =& $parent;
$parent['children'][] = $item;
$parent['children'][] = $item;
if ($keyword == '@' || $item['type'] == 'function') {
// If we're processing a variable, add a string to the parent and move up to that as current.
$parent['children'][] = $str;
$current =& $parent['children'][count($parent['children']) - 1];
$current['parent'] =& $parent;
} elseif (substr($keyword, 0, 1) == '/') {
// If we're processing the end of a block (if/loop), add a string to the parent's parent and move up to that.
$parent =& $parent['parent'];
$parent['children'][] = $str;
$current =& $parent['children'][count($parent['children']) - 1];
$current['parent'] =& $parent;
} else {
$parent['children'][count($parent['children']) - 1]['children'][] = $str;
$current =& $parent['children'][count($parent['children']) - 1]['children'][0];
$current['parent'] =& $parent['children'][count($parent['children']) - 1];
}
if ($keyword == '@' || $item['type'] == 'function') {
// If we're processing a variable, add a string to the parent and move up to that as current.
$parent['children'][] = $str;
$current =& $parent['children'][count($parent['children']) - 1];
$current['parent'] =& $parent;
} elseif (substr($keyword, 0, 1) == '/') {
// If we're processing the end of a block (if/loop), add a string to the parent's parent and move up to that.
$parent =& $parent['parent'];
$parent['children'][] = $str;
$current =& $parent['children'][count($parent['children']) - 1];
$current['parent'] =& $parent;
} else {
$parent['children'][count($parent['children']) - 1]['children'][] = $str;
$current =& $parent['children'][count($parent['children']) - 1]['children'][0];
$current['parent'] =& $parent['children'][count($parent['children']) - 1];
}
break;
}
}
break;
}
}
if (!$gotKeyword) {
$current['body'] .= substr($string, 0, 1);
$string = substr($string, 1);
}
}
}
if (!$gotKeyword) {
$current['body'] .= substr($string, 0, 1);
$string = substr($string, 1);
}
}
}
return $this->processStack($stack);
}
return $this->processStack($stack);
}
protected function processStack($stack)
{
$res = '';
protected function processStack($stack)
{
$res = '';
while (count($stack['children'])) {
$current = array_shift($stack['children']);
while (count($stack['children'])) {
$current = array_shift($stack['children']);
switch ($current['type']) {
case 'string':
$res .= $current['body'];
break;
switch ($current['type']) {
case 'string':
$res .= $current['body'];
break;
case '@':
$res .= $this->doParseVar($current['cond']);
break;
case '@':
$res .= $this->doParseVar($current['cond']);
break;
case 'if':
$res .= $this->doParseIf($current['cond'], $current);
break;
case 'if':
$res .= $this->doParseIf($current['cond'], $current);
break;
case 'ifnot':
$res .= $this->doParseIfNot($current['cond'], $current);
break;
case 'ifnot':
$res .= $this->doParseIfNot($current['cond'], $current);
break;
case 'loop':
$res .= $this->doParseLoop($current['cond'], $current);
@ -161,64 +165,64 @@ class Template extends View
case 'function':
$res .= $this->doParseFunction($current);
break;
}
}
}
}
return $res;
}
return $res;
}
protected function readUntil($until, &$string)
{
$read = '';
protected function readUntil($until, &$string)
{
$read = '';
while (!empty($string)) {
$char = substr($string, 0, 1);
while (!empty($string)) {
$char = substr($string, 0, 1);
if ($char == $until) {
break;
}
if ($char == $until) {
break;
}
$read .= $char;
$string = substr($string, 1);
}
$read .= $char;
$string = substr($string, 1);
}
return $read;
}
return $read;
}
protected function doParseVar($var)
{
if($var == 'year')
{
return date('Y');
}
protected function doParseVar($var)
{
if ($var == 'year') {
return date('Y');
}
$val = $this->processVariableName($var);
return $val;
}
$val = $this->processVariableName($var);
return $val;
}
protected function doParseIf($condition, $stack)
{
protected function doParseIf($condition, $stack)
{
if ($this->ifConditionIsTrue($condition)) {
return $this->processStack($stack);
} else {
return '';
}
}
}
protected function doParseIfNot($condition, $stack)
{
protected function doParseIfNot($condition, $stack)
{
if (!$this->ifConditionIsTrue($condition)) {
return $this->processStack($stack);
} else {
return '';
}
}
}
protected function ifConditionIsTrue($condition)
{
$matches = array();
$matches = [];
if (preg_match('/([a-zA-Z0-9_\-\(\):\s.\"]+)\s+?([\!\=\<\>]+)?\s+?([a-zA-Z0-9\(\)_\-:\s.\"]+)?/', $condition, $matches)) {
if (preg_match('/([a-zA-Z0-9_\-\(\):\s.\"]+)\s+?([\!\=\<\>]+)?\s+?([a-zA-Z0-9\(\)_\-:\s.\"]+)?/', $condition,
$matches)) {
$left = is_numeric($matches[1]) ? intval($matches[1]) : $this->processVariableName($matches[1]);
$right = is_numeric($matches[3]) ? intval($matches[3]) : $this->processVariableName($matches[3]);
$operator = $matches[2];
@ -248,42 +252,40 @@ class Template extends View
}
}
protected function doParseLoop($var, $stack)
{
$working = $this->processVariableName($var);
protected function doParseLoop($var, $stack)
{
$working = $this->processVariableName($var);
if(is_null($working))
{
return '';
}
if (is_null($working)) {
return '';
}
if(!is_array($working))
{
$working = array($working);
}
if (!is_array($working)) {
$working = [$working];
}
$rtn = '';
foreach ($working as $key => $val) {
$rtn = '';
foreach ($working as $key => $val) {
// Make sure we support nesting loops:
$keyWas = isset($this->key) ? $this->key : null;
$valWas = isset($this->value) ? $this->value : null;
$itemWas = isset($this->item) ? $this->item : null;
$keyWas = isset($this->key) ? $this->key : null;
$valWas = isset($this->value) ? $this->value : null;
$itemWas = isset($this->item) ? $this->item : null;
// Set up the necessary variables within the stack:
$this->parent = $this;
$this->item = $val;
$this->parent = $this;
$this->item = $val;
$this->key = $key;
$this->value = $val;
$rtn .= $this->processStack($stack);
$rtn .= $this->processStack($stack);
// Restore state for any parent nested loops:
$this->item = $itemWas;
$this->key = $keyWas;
$this->value = $valWas;
}
}
return $rtn;
}
return $rtn;
}
/**
* Processes loops in templates, of the following styles:
@ -325,7 +327,7 @@ class Template extends View
// Process variable & incrementor / decrementor:
$parts[1] = trim($parts[1]);
$matches = array();
$matches = [];
if (preg_match('/([a-zA-Z0-9_]+)(\+\+|\-\-)/', $parts[1], $matches)) {
$varName = $matches[1];
$direction = $matches[2] == '++' ? 'increment' : 'decrement';
@ -367,8 +369,8 @@ class Template extends View
throw new \Exception('Invalid range in for loop: ' . $part);
}
public function processVariableName($varName)
{
public function processVariableName($varName)
{
// Case one - Test for function calls:
if (substr($varName, 0, 1) == '(' && substr($varName, -1) == ')') {
@ -403,23 +405,21 @@ class Template extends View
return null;
}
// Case five - Process as a variable:
$varPart = explode('.', $varName);
$thisPart = array_shift($varPart);
// Case five - Process as a variable:
$varPart = explode('.', $varName);
$thisPart = array_shift($varPart);
if(!array_key_exists($thisPart, $this->_vars))
{
return null;
}
if (!array_key_exists($thisPart, $this->_vars)) {
return null;
}
$working = $this->{$thisPart};
$working = $this->{$thisPart};
while(count($varPart))
{
$thisPart = array_shift($varPart);
while (count($varPart)) {
$thisPart = array_shift($varPart);
if(is_object($working)) {
if (is_object($working)) {
// Check if we're working with an actual property:
if (property_exists($working, $thisPart)) {
$working = $working->{$thisPart};
@ -434,34 +434,30 @@ class Template extends View
}
if(is_array($working) && array_key_exists($thisPart, $working))
{
$working = $working[$thisPart];
continue;
}
if (is_array($working) && array_key_exists($thisPart, $working)) {
$working = $working[$thisPart];
continue;
}
if($thisPart == 'toLowerCase')
{
$working = strtolower($working);
continue;
}
if ($thisPart == 'toLowerCase') {
$working = strtolower($working);
continue;
}
if($thisPart == 'toUpperCase')
{
$working = strtoupper($working);
continue;
}
if ($thisPart == 'toUpperCase') {
$working = strtoupper($working);
continue;
}
if ($thisPart == 'isNumeric')
{
return is_numeric($working);
}
if ($thisPart == 'isNumeric') {
return is_numeric($working);
}
return null;
}
return null;
}
return $working;
}
return $working;
}
protected function doParseFunction($stack)
{
@ -481,7 +477,7 @@ class Template extends View
protected function processFunctionArguments($args)
{
$rtn = array();
$rtn = [];
$args = explode(';', $args);
@ -515,7 +511,7 @@ class Template extends View
if (isset($args['variables'])) {
if (!is_array($args['variables'])) {
$args['variables'] = array($args['variables']);
$args['variables'] = [$args['variables']];
}
foreach ($args['variables'] as $variable) {