diff --git a/Account/Account.php b/Account/Account.php index b26249b62..baed21b9f 100644 --- a/Account/Account.php +++ b/Account/Account.php @@ -109,7 +109,7 @@ class Account implements ArrayableInterface, \JsonSerializable /** * Permissions. * - * @var array + * @var PermissionAbstract[] * @since 1.0.0 */ protected $permissions = []; @@ -125,7 +125,7 @@ class Account implements ArrayableInterface, \JsonSerializable /** * Password. * - * @var Password + * @var string * @since 1.0.0 */ protected $password = ''; @@ -207,11 +207,35 @@ class Account implements ArrayableInterface, \JsonSerializable $this->l11n = $l11n; } + /** + * Set permissions. + * + * @param PermissionAbstract[] $permissions + * + * @return void + * + * @since 1.0.0 + */ public function setPermissions(array $permissions) /* : void */ { $this->permissions = $permissions; } + /** + * Has permissions. + * + * @param int $permission Check if user has this permission + * @param int $unit Unit + * @param string $app App + * @param int $module Module + * @param int $type Type (e.g. customer) + * @param int $element (e.g. customer id) + * @param int $component (e.g. address) + * + * @return bool + * + * @since 1.0.0 + */ public function hasPermission(int $permission, int $unit = null, string $app = null, int $module = null, int $type = null, $element = null, $component = null) : bool { foreach($this->permissions as $p) { diff --git a/Account/PermissionAbstract.php b/Account/PermissionAbstract.php index ee6736ea4..3cdc5824d 100644 --- a/Account/PermissionAbstract.php +++ b/Account/PermissionAbstract.php @@ -13,6 +13,7 @@ */ declare(strict_types=1); namespace phpOMS\Account; +use Modules\Admin\Models\PermissionType; /** * InfoManager class. @@ -27,110 +28,309 @@ namespace phpOMS\Account; */ abstract class PermissionAbstract { + /** + * Permission id. + * + * @var int + * @since 1.0.0 + */ protected $id = 0; + /** + * Unit id. + * + * @var int + * @since 1.0.0 + */ protected $unit = null; + /** + * App name. + * + * @var string + * @since 1.0.0 + */ protected $app = null; + /** + * Module id. + * + * @var int + * @since 1.0.0 + */ protected $module = null; + /** + * Providing module id. + * + * @var int + * @since 1.0.0 + */ protected $from = 0; + /** + * Type. + * + * @var int + * @since 1.0.0 + */ protected $type = null; + /** + * Element id. + * + * @var int + * @since 1.0.0 + */ protected $element = null; + /** + * Component id. + * + * @var int + * @since 1.0.0 + */ protected $component = null; - protected $permission = 0; + /** + * Permission. + * + * @var int + * @since 1.0.0 + */ + protected $permission = PermissionType::NONE; - public function getId() + /** + * Get permission id. + * + * @return int + * + * @since 1.0.0 + */ + public function getId() : int { - return $id; + return $this->id; } - public function getUnit() + /** + * Get unit id. + * + * @return int + * + * @since 1.0.0 + */ + public function getUnit() /* : ?int */ { return $this->unit; } - public function getApp() + /** + * Get app name. + * + * @return string + * + * @since 1.0.0 + */ + public function getApp() /* : ?string */ { return $this->app; } - public function getModule() + /** + * Get module id. + * + * @return int + * + * @since 1.0.0 + */ + public function getModule() /* : ?int */ { return $this->module; } - public function getFrom() + /** + * Get providing module id. + * + * @return int + * + * @since 1.0.0 + */ + public function getFrom() /* : ?int */ { return $this->from; } - public function getType() + /** + * Get type. + * + * @return int + * + * @since 1.0.0 + */ + public function getType() /* : ?int */ { return $this->type; } - public function getElement() + /** + * Get element id. + * + * @return int + * + * @since 1.0.0 + */ + public function getElement() /* : ?int */ { return $this->element; } - public function getComponent() + /** + * Get component id. + * + * @return int + * + * @since 1.0.0 + */ + public function getComponent() /* : ?int */ { return $this->component; } + /** + * Get permission + * + * @return int + * + * @since 1.0.0 + */ public function getPermission() : int { return $this->permission; } + /** + * Set unit id. + * + * @param int $unit Unit + * + * @return void + * + * @since 1.0.0 + */ public function setUnit(int $unit = null) /* : void */ { $this->unit = $unit; } - public function setApp(int $app = null) /* : void */ + /** + * Set app name. + * + * @param string $app App name + * + * @return void + * + * @since 1.0.0 + */ + public function setApp(string $app = null) /* : void */ { $this->app = $app; } + /** + * Set module id. + * + * @param int $module Module + * + * @return void + * + * @since 1.0.0 + */ public function setModule(int $module = null) /* : void */ { $this->module = $module; } + /** + * Set providing module id. + * + * @param int $from Providing module + * + * @return void + * + * @since 1.0.0 + */ public function setFrom(int $from = null) /* : void */ { $this->from = $from; } + /** + * Set type. + * + * @param int $type Type + * + * @return void + * + * @since 1.0.0 + */ public function setType(int $type = null) /* : void */ { $this->type = $type; } + /** + * Set element id. + * + * @param int $element Element id + * + * @return void + * + * @since 1.0.0 + */ public function setElement(int $element = null) /* : void */ { $this->element = $element; } + /** + * Set component id. + * + * @param int $component Component + * + * @return void + * + * @since 1.0.0 + */ public function setComponent(int $component = null) /* : void */ { $this->component = $component; } + /** + * Set permission. + * + * @param int $permission Permission + * + * @return void + * + * @since 1.0.0 + */ public function setPermission(int $permission = 0) /* : void */ { - if($permission === 0) { - $this->permission = 0; - } else { - $this->permission |= $permission; - } + $this->permission = $permission; + } + + /** + * Add permission. + * + * @param int $permission Permission + * + * @return void + * + * @since 1.0.0 + */ + public function addPermission(int $permission = 0) /* : void */ + { + $this->permission |= $permission; } } diff --git a/Account/PermissionType.php b/Account/PermissionType.php new file mode 100644 index 000000000..4722dd7e7 --- /dev/null +++ b/Account/PermissionType.php @@ -0,0 +1,41 @@ + + * @author Dennis Eichhorn + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://orange-management.com + */ +declare(strict_types=1); + +namespace phpOMS\Account; + +use phpOMS\Stdlib\Base\Enum; + +/** + * Permission type enum. + * + * @category Framework + * @package phpOMS\DataStorage\Database + * @author OMS Development Team + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +abstract class PermissionType extends Enum +{ + /* public */ const NONE = 0; + /* public */ const READ = 1; + /* public */ const CREATE = 2; + /* public */ const MODIFY = 4; + /* public */ const DELETE = 8; + /* public */ const PERMISSION = 16; +} diff --git a/Auth/Auth.php b/Auth/Auth.php index 38a80b112..c5b64706d 100644 --- a/Auth/Auth.php +++ b/Auth/Auth.php @@ -16,7 +16,6 @@ declare(strict_types=1); namespace phpOMS\Auth; use phpOMS\DataStorage\Database\Connection\ConnectionAbstract; -use phpOMS\DataStorage\Database\DatabaseType; use phpOMS\DataStorage\Session\SessionInterface; /** diff --git a/Business/Sales/MarketShareEstimation.php b/Business/Sales/MarketShareEstimation.php index 3b870bd16..268923691 100644 --- a/Business/Sales/MarketShareEstimation.php +++ b/Business/Sales/MarketShareEstimation.php @@ -32,7 +32,7 @@ class MarketShareEstimation { * @param float $marketShare (m) * @param float $modifier (s) * - * @return float + * @return int * * @since 1.0.0 */ diff --git a/DataStorage/Database/CreateMapperAbstract.php b/DataStorage/Database/CreateMapperAbstract.php deleted file mode 100644 index 01426b15c..000000000 --- a/DataStorage/Database/CreateMapperAbstract.php +++ /dev/null @@ -1,511 +0,0 @@ -prefix(self::$db->getPrefix())->into(static::$table); - - $properties = $reflectionClass->getProperties(); - - foreach ($properties as $property) { - $propertyName = $property->getName(); - - if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName])) { - continue; - } - - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } - - foreach (static::$columns as $key => $column) { - if (isset(static::$ownsOne[$propertyName]) && $column['internal'] === $propertyName) { - $id = self::createOwnsOne($propertyName, $property->getValue($obj)); - $value = self::parseValue($column['type'], $id); - - $query->insert($column['name'])->value($value, $column['type']); - break; - } elseif (isset(static::$belongsTo[$propertyName]) && $column['internal'] === $propertyName) { - $id = self::createBelongsTo($propertyName, $property->getValue($obj)); - $value = self::parseValue($column['type'], $id); - - $query->insert($column['name'])->value($value, $column['type']); - break; - } elseif ($column['internal'] === $propertyName && $column['type'] !== static::$primaryField) { - $value = self::parseValue($column['type'], $property->getValue($obj)); - - $query->insert($column['name'])->value($value, $column['type']); - break; - } - } - - if (!($isPublic)) { - $property->setAccessible(false); - } - } - - self::$db->con->prepare($query->toSql())->execute(); - - return self::$db->con->lastInsertId(); - } - - /** - * Create base model. - * - * @param Object $obj Model to create - * - * @return mixed - * - * @since 1.0.0 - */ - private static function createModelArray($obj) - { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix())->into(static::$table); - - foreach ($obj as $propertyName => &$property) { - if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName])) { - continue; - } - - foreach (static::$columns as $key => $column) { - if (isset(static::$ownsOne[$propertyName]) && $column['internal'] === $propertyName) { - $id = self::createOwnsOneArray($propertyName, $property); - $value = self::parseValue($column['type'], $id); - - $query->insert($column['name'])->value($value, $column['type']); - break; - } elseif (isset(static::$belongsTo[$propertyName]) && $column['internal'] === $propertyName) { - $id = self::createBelongsToArray($propertyName, $property); - $value = self::parseValue($column['type'], $id); - - $query->insert($column['name'])->value($value, $column['type']); - break; - } elseif ($column['internal'] === $propertyName && $column['type'] !== static::$primaryField) { - $value = self::parseValue($column['type'], $property); - - $query->insert($column['name'])->value($value, $column['type']); - break; - } - } - } - - self::$db->con->prepare($query->toSql())->execute(); - - return self::$db->con->lastInsertId(); - } - - /** - * Create has many - * - * @param \ReflectionClass $reflectionClass Reflection class - * @param Object $obj Object to create - * @param mixed $objId Id to set - * - * @return void - * - * @throws InvalidMapperException - * - * @since 1.0.0 - */ - private static function createHasMany(\ReflectionClass $reflectionClass, $obj, $objId) /* : void */ - { - foreach (static::$hasMany as $propertyName => $rel) { - $property = $reflectionClass->getProperty($propertyName); - - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } - - $values = $property->getValue($obj); - - if (!($isPublic)) { - $property->setAccessible(false); - } - - if (!isset(static::$hasMany[$propertyName]['mapper'])) { - throw new InvalidMapperException(); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasMany[$propertyName]['mapper']; - $objsIds = []; - $relReflectionClass = null; - - foreach ($values as $key => &$value) { - if (!is_object($value)) { - // Is scalar => already in database - $objsIds[$key] = $value; - - continue; - } - - if (!isset($relReflectionClass)) { - $relReflectionClass = new \ReflectionClass(get_class($value)); - } - - $primaryKey = $mapper::getObjectId($value, $relReflectionClass); - - // already in db - if (!empty($primaryKey)) { - $objsIds[$key] = $value; - - continue; - } - - // Setting relation value (id) for relation (since the relation is not stored in an extra relation table) - /** @var string $table */ - /** @var array $columns */ - if (static::$hasMany[$propertyName]['table'] === static::$hasMany[$propertyName]['mapper']::$table) { - $relProperty = $relReflectionClass->getProperty($mapper::$columns[static::$hasMany[$propertyName]['dst']]['internal']); - - if (!$isPublic) { - $relProperty->setAccessible(true); - } - - $relProperty->setValue($value, $objId); - - if (!($isPublic)) { - $relProperty->setAccessible(false); - } - } - - $objsIds[$key] = $mapper::create($value); - } - - self::createRelationTable($propertyName, $objsIds, $objId); - } - } - - /** - * Create has many - * - * @param array $obj Object to create - * @param mixed $objId Id to set - * - * @return void - * - * @throws InvalidMapperException - * - * @since 1.0.0 - */ - private static function createHasManyArray(array &$obj, $objId) /* : void */ - { - foreach (static::$hasMany as $propertyName => $rel) { - $values = $obj[$propertyName]; - - if (!isset(static::$hasMany[$propertyName]['mapper'])) { - throw new InvalidMapperException(); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasMany[$propertyName]['mapper']; - $objsIds = []; - - foreach ($values as $key => &$value) { - if (!is_object($value)) { - // Is scalar => already in database - $objsIds[$key] = $value; - - continue; - } - - $primaryKey = $obj[static::$columns[static::$primaryField]['internal']]; - - // already in db - if (!empty($primaryKey)) { - $objsIds[$key] = $value; - - continue; - } - - // Setting relation value (id) for relation (since the relation is not stored in an extra relation table) - /** @var string $table */ - /** @var array $columns */ - if (static::$hasMany[$propertyName]['table'] === static::$hasMany[$propertyName]['mapper']::$table) { - $value[$mapper::$columns[static::$hasMany[$propertyName]['dst']]['internal']] = $objId; - } - - $objsIds[$key] = $mapper::createArray($value); - } - - self::createRelationTable($propertyName, $objsIds, $objId); - } - } - - private static function createHasOne(\ReflectionClass $reflectionClass, $obj) - { - throw new \Exception(); - - foreach (static::$hasOne as $propertyName => $rel) { - - } - } - - /** - * Create owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to create - * - * @return mixed - * - * @since 1.0.0 - */ - private static function createOwnsOne(string $propertyName, $obj) - { - if (is_object($obj)) { - $mapper = static::$ownsOne[$propertyName]['mapper']; - $primaryKey = $mapper::getObjectId($obj); - - if (empty($primaryKey)) { - return $mapper::create($obj); - } - - return $primaryKey; - } - - return $obj; - } - - /** - * Create owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param array $obj Object to create - * - * @return mixed - * - * @since 1.0.0 - */ - private static function createOwnsOneArray(string $propertyName, array &$obj) - { - if (is_array($obj)) { - $mapper = static::$ownsOne[$propertyName]['mapper']; - $primaryKey = $obj[static::$columns[static::$primaryField]['internal']]; - - if (empty($primaryKey)) { - return $mapper::createArray($obj); - } - - return $primaryKey; - } - - return $obj; - } - - /** - * Create owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to create - * - * @return mixed - * - * @since 1.0.0 - */ - private static function createBelongsTo(string $propertyName, $obj) - { - if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$belongsTo[$propertyName]['mapper']; - $primaryKey = $mapper::getObjectId($obj); - - if (empty($primaryKey)) { - return $mapper::create($obj); - } - - return $primaryKey; - } - - return $obj; - } - - /** - * Create owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to create - * - * @return mixed - * - * @since 1.0.0 - */ - private static function createBelongsToArray(string $propertyName, array $obj) - { - if (is_array($obj)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$belongsTo[$propertyName]['mapper']; - $primaryKey = $obj[static::$columns[static::$primaryField]['internal']]; - - if (empty($primaryKey)) { - return $mapper::createArray($obj); - } - - return $primaryKey; - } - - return $obj; - } - - /** - * Create relation table entry - * - * In case of a many to many relation the relation has to be stored in a relation table - * - * @param string $propertyName Property name to initialize - * @param array $objsIds Object ids to insert - * @param mixed $objId Model to reference - * - * @return mixed - * - * @since 1.0.0 - */ - private static function createRelationTable(string $propertyName, array $objsIds, $objId) - { - /** @var string $table */ - if ( - !empty($objsIds) - && static::$hasMany[$propertyName]['table'] !== static::$table - && static::$hasMany[$propertyName]['table'] !== static::$hasMany[$propertyName]['mapper']::$table - ) { - $relQuery = new Builder(self::$db); - $relQuery->prefix(self::$db->getPrefix()) - ->into(static::$hasMany[$propertyName]['table']) - ->insert(static::$hasMany[$propertyName]['src'], static::$hasMany[$propertyName]['dst']); - - foreach ($objsIds as $key => $src) { - $relQuery->values($src, $objId); - } - - self::$db->con->prepare($relQuery->toSql())->execute(); - } - } -} diff --git a/DataStorage/Database/DataMapperAbstract.php b/DataStorage/Database/DataMapperAbstract.php index 3991f7e37..579820dce 100644 --- a/DataStorage/Database/DataMapperAbstract.php +++ b/DataStorage/Database/DataMapperAbstract.php @@ -268,7 +268,7 @@ class DataMapperAbstract implements DataMapperInterface self::$fields = $objects; - return __CLASS__; + //return __CLASS__; } /** @@ -450,7 +450,7 @@ class DataMapperAbstract implements DataMapperInterface /** * Create base model. * - * @param Object $obj Model to create + * @param array $obj Model to create * * @return mixed * @@ -580,7 +580,7 @@ class DataMapperAbstract implements DataMapperInterface throw new InvalidMapperException(); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasMany[$propertyName]['mapper']; $objsIds = []; $relReflectionClass = null; @@ -651,7 +651,7 @@ class DataMapperAbstract implements DataMapperInterface throw new InvalidMapperException(); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasMany[$propertyName]['mapper']; $objsIds = []; @@ -766,7 +766,7 @@ class DataMapperAbstract implements DataMapperInterface private static function createBelongsTo(string $propertyName, $obj) { if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$belongsTo[$propertyName]['mapper']; $primaryKey = $mapper::getObjectId($obj); @@ -786,7 +786,7 @@ class DataMapperAbstract implements DataMapperInterface * The reference is stored in the main model * * @param string $propertyName Property name to initialize - * @param Object $obj Object to create + * @param array $obj Object to create * * @return mixed * @@ -795,7 +795,7 @@ class DataMapperAbstract implements DataMapperInterface private static function createBelongsToArray(string $propertyName, array $obj) { if (is_array($obj)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$belongsTo[$propertyName]['mapper']; $primaryKey = $obj[static::$columns[static::$primaryField]['internal']]; @@ -912,7 +912,7 @@ class DataMapperAbstract implements DataMapperInterface throw new InvalidMapperException(); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasMany[$propertyName]['mapper']; $objsIds = []; $relReflectionClass = null; @@ -1052,7 +1052,7 @@ class DataMapperAbstract implements DataMapperInterface private static function updateOwnsOne(string $propertyName, $obj) { if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$ownsOne[$propertyName]['mapper']; // todo: delete owned one object is not recommended since it can be owned by by something else? or does owns one mean that nothing else can have a relation to this one? @@ -1078,7 +1078,7 @@ class DataMapperAbstract implements DataMapperInterface private static function updateBelongsTo(string $propertyName, $obj) { if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$belongsTo[$propertyName]['mapper']; return $mapper::update($obj); @@ -1218,7 +1218,7 @@ class DataMapperAbstract implements DataMapperInterface throw new InvalidMapperException(); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasMany[$propertyName]['mapper']; $objsIds = []; $relReflectionClass = null; @@ -1271,7 +1271,7 @@ class DataMapperAbstract implements DataMapperInterface private static function deleteOwnsOne(string $propertyName, $obj) { if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$ownsOne[$propertyName]['mapper']; // todo: delete owned one object is not recommended since it can be owned by by something else? or does owns one mean that nothing else can have a relation to this one? @@ -1296,7 +1296,7 @@ class DataMapperAbstract implements DataMapperInterface private static function deleteBelongsTo(string $propertyName, $obj) { if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$belongsTo[$propertyName]['mapper']; return $mapper::delete($obj); @@ -1485,7 +1485,7 @@ class DataMapperAbstract implements DataMapperInterface foreach ($result as $member => $values) { if (!empty($values) && $reflectionClass->hasProperty($member)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasMany[$member]['mapper']; $reflectionProperty = $reflectionClass->getProperty($member); @@ -1522,7 +1522,7 @@ class DataMapperAbstract implements DataMapperInterface { foreach ($result as $member => $values) { if (!empty($values)) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasMany[$member]['mapper']; $values = array_diff($values, array_keys(self::$initObjects[$mapper] ?? [])); @@ -1560,10 +1560,10 @@ class DataMapperAbstract implements DataMapperInterface $reflectionProperty->setAccessible(true); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasOne[$member]['mapper']; - if(self::isInitialized($mapper, $reflectionProperty->getValue($obj))) { + if(self::isInitialized($mapper, ($id = $reflectionProperty->getValue($obj)))) { $value = self::$initObjects[$mapper][$id]; } else { $value = $mapper::get($reflectionProperty->getValue($obj)); @@ -1592,11 +1592,11 @@ class DataMapperAbstract implements DataMapperInterface public static function populateHasOneArray(array &$obj) /* : void */ { foreach (static::$hasOne as $member => $one) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$hasOne[$member]['mapper']; if(self::isInitialized($mapper, $obj['member'])) { - $value = self::$initObjects[$mapper][$id]; + $value = self::$initObjects[$mapper][$obj['member']]; } else { $value = $mapper::getArray($obj[$member]); } @@ -1629,10 +1629,10 @@ class DataMapperAbstract implements DataMapperInterface $reflectionProperty->setAccessible(true); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$ownsOne[$member]['mapper']; - if(self::isInitialized($mapper, $reflectionProperty->getValue($obj))) { + if(self::isInitialized($mapper, ($id = $reflectionProperty->getValue($obj)))) { $value = self::$initObjects[$mapper][$id]; } else { $value = $mapper::get($reflectionProperty->getValue($obj)); @@ -1661,11 +1661,11 @@ class DataMapperAbstract implements DataMapperInterface public static function populateOwnsOneArray(array &$obj) /* : void */ { foreach (static::$ownsOne as $member => $one) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$ownsOne[$member]['mapper']; if(self::isInitialized($mapper, $obj[$member])) { - $value = self::$initObjects[$mapper][$id]; + $value = self::$initObjects[$mapper][$obj[$member]]; } else { $value = $mapper::getArray($obj[$member]); } @@ -1698,10 +1698,10 @@ class DataMapperAbstract implements DataMapperInterface $reflectionProperty->setAccessible(true); } - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$belongsTo[$member]['mapper']; - if(self::isInitialized($mapper, $reflectionProperty->getValue($obj))) { + if(self::isInitialized($mapper, ($id = $reflectionProperty->getValue($obj)))) { $value = self::$initObjects[$mapper][$id]; } else { $value = $mapper::get($reflectionProperty->getValue($obj)); @@ -1730,11 +1730,11 @@ class DataMapperAbstract implements DataMapperInterface public static function populateBelongsToArray(array &$obj) /* : void */ { foreach (static::$belongsTo as $member => $one) { - /** @var DataMapperAbstract $mapper */ + /** @var string $mapper */ $mapper = static::$belongsTo[$member]['mapper']; if(self::isInitialized($mapper, $obj[$member])) { - $value = self::$initObjects[$mapper][$id]; + $value = self::$initObjects[$mapper][$obj[$member]]; } else { $value = $mapper::get($obj[$member]); } @@ -1905,7 +1905,6 @@ class DataMapperAbstract implements DataMapperInterface self::extend(__CLASS__); $primaryKey = (array) $primaryKey; - $fill = (array) $fill; $obj = []; foreach ($primaryKey as $key => $value) { @@ -2550,6 +2549,17 @@ class DataMapperAbstract implements DataMapperInterface return count($results) === 0; } + /** + * Find database column name by member name + * + * @param string $name member name + * + * @return string + * + * @throws \Exception Throws this exception if the member couldn't be found + * + * @since 1.0.0 + */ private static function getColumnByMember(string $name) : string { foreach(static::$columns as $cName => $column) { diff --git a/DataStorage/Database/DatabaseExceptionFactory.php b/DataStorage/Database/DatabaseExceptionFactory.php index 7a88508d4..99565eb00 100644 --- a/DataStorage/Database/DatabaseExceptionFactory.php +++ b/DataStorage/Database/DatabaseExceptionFactory.php @@ -15,6 +15,8 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database; +use phpOMS\DataStorage\Database\Schema\Exception\TableException; + /** * Database exception factory. * diff --git a/DataStorage/Database/DatabaseStatus.php b/DataStorage/Database/DatabaseStatus.php index db73f88cb..1a1877a05 100644 --- a/DataStorage/Database/DatabaseStatus.php +++ b/DataStorage/Database/DatabaseStatus.php @@ -30,10 +30,10 @@ use phpOMS\Stdlib\Base\Enum; */ abstract class DatabaseStatus extends Enum { - /* public */ const OK = 0; /* Database connection successful */ + /* public */ const OK = 0; /* Database connection successful */ /* public */ const MISSING_DATABASE = 1; /* Couldn't find database */ - /* public */ const MISSING_TABLE = 2; /* One of the core tables couldn't be found */ - /* public */ const FAILURE = 3; /* Unknown failure */ - /* public */ const READONLY = 4; /* Database connection is in readonly (but ok) */ - /* public */ const CLOSED = 5; /* Database connection closed */ + /* public */ const MISSING_TABLE = 2; /* One of the core tables couldn't be found */ + /* public */ const FAILURE = 3; /* Unknown failure */ + /* public */ const READONLY = 4; /* Database connection is in readonly (but ok) */ + /* public */ const CLOSED = 5; /* Database connection closed */ } diff --git a/DataStorage/Database/DatabaseType.php b/DataStorage/Database/DatabaseType.php index f0ac90eb4..2de4a65c0 100644 --- a/DataStorage/Database/DatabaseType.php +++ b/DataStorage/Database/DatabaseType.php @@ -30,9 +30,9 @@ use phpOMS\Stdlib\Base\Enum; */ abstract class DatabaseType extends Enum { - /* public */ const MYSQL = 'mysql'; /* MySQL */ - /* public */ const SQLITE = 'sqlite'; /* SQLITE */ - /* public */ const PGSQL = 2; /* PostgreSQL */ - /* public */ const ORACLE = 3; /* Oracle */ - /* public */ const SQLSRV = 'mssql'; /* Microsoft SQL Server */ + /* public */ const MYSQL = 'mysql'; /* MySQL */ + /* public */ const SQLITE = 'sqlite'; /* SQLITE */ + /* public */ const PGSQL = 2; /* PostgreSQL */ + /* public */ const ORACLE = 3; /* Oracle */ + /* public */ const SQLSRV = 'mssql'; /* Microsoft SQL Server */ } diff --git a/DataStorage/Database/DeleteMapperAbstract.php b/DataStorage/Database/DeleteMapperAbstract.php deleted file mode 100644 index 7ca8fed90..000000000 --- a/DataStorage/Database/DeleteMapperAbstract.php +++ /dev/null @@ -1,295 +0,0 @@ - $rel) { - $property = $reflectionClass->getProperty($propertyName); - - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } - - $values = $property->getValue($obj); - - if (!($isPublic)) { - $property->setAccessible(false); - } - - if (!isset(static::$hasMany[$propertyName]['mapper'])) { - throw new InvalidMapperException(); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasMany[$propertyName]['mapper']; - $objsIds = []; - $relReflectionClass = null; - - foreach ($values as $key => &$value) { - if (!is_object($value)) { - // Is scalar => already in database - $objsIds[$key] = $value; - - continue; - } - - if (!isset($relReflectionClass)) { - $relReflectionClass = new \ReflectionClass(get_class($value)); - } - - $primaryKey = $mapper::getObjectId($value, $relReflectionClass); - - // already in db - if (!empty($primaryKey)) { - if($relations === RelationType::ALL) { - $objsIds[$key] = $mapper::delete($value); - } else { - $objsIds[$key] = $primaryKey; - } - - continue; - } - - // todo: could be a problem, relation needs to be removed first?! - - } - - self::deleteRelationTable($propertyName, $objsIds, $objId); - } - } - - /** - * Delete owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to delete - * - * @return mixed - * - * @since 1.0.0 - */ - private static function deleteOwnsOne(string $propertyName, $obj) - { - if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$ownsOne[$propertyName]['mapper']; - - // todo: delete owned one object is not recommended since it can be owned by by something else? or does owns one mean that nothing else can have a relation to this one? - return $mapper::delete($obj); - } - - return $obj; - } - - /** - * Delete owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to delete - * - * @return mixed - * - * @since 1.0.0 - */ - private static function deleteBelongsTo(string $propertyName, $obj) - { - if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$belongsTo[$propertyName]['mapper']; - - return $mapper::delete($obj); - } - - return $obj; - } - - /** - * Delete object in db. - * - * @param Object $obj Model to delete - * @param mixed $objId Model id - * @param int $relations Delete all relations as well - * @param \ReflectionClass $reflectionClass Reflection class - * - * @return mixed - * - * @since 1.0.0 - */ - private static function deleteModel($obj, $objId, int $relations = RelationType::REFERENCE, \ReflectionClass $reflectionClass = null) /* : void */ - { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->delete() - ->into(static::$table) - ->where(static::$primaryField, '=', $objId); - - $properties = $reflectionClass->getProperties(); - - if($relations === RelationType::ALL) { - foreach ($properties as $property) { - $propertyName = $property->getName(); - - if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName])) { - continue; - } - - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } - - // todo: the order of deletion could be a problem. maybe looping through ownsOne and belongsTo first is better. - // todo: support other relation types as well (belongsto, ownsone) = for better control - - foreach (static::$columns as $key => $column) { - if ($relations === RelationType::ALL && isset(static::$ownsOne[$propertyName]) && $column['internal'] === $propertyName) { - self::deleteOwnsOne($propertyName, $property->getValue($obj)); - break; - } elseif ($relations === RelationType::ALL && isset(static::$belongsTo[$propertyName]) && $column['internal'] === $propertyName) { - self::deleteBelongsTo($propertyName, $property->getValue($obj)); - break; - } - } - - if (!($isPublic)) { - $property->setAccessible(false); - } - } - } - - self::$db->con->prepare($query->toSql())->execute(); - } - - /** - * Delete object in db. - * - * @param mixed $obj Object reference (gets filled with insert id) - * @param int $relations Create all relations as well - * - * @return mixed - * - * @since 1.0.0 - */ - public static function delete($obj, int $relations = RelationType::REFERENCE) - { - self::extend(__CLASS__); - $reflectionClass = new \ReflectionClass(get_class($obj)); - $objId = self::getObjectId($obj, $reflectionClass); - - if(empty($objId)) { - return null; - } - - if ($relations !== RelationType::NONE) { - self::deleteHasMany($reflectionClass, $obj, $objId, $relations); - } - - self::deleteModel($obj, $objId, $relations, $reflectionClass); - - return $objId; - } - - - /** - * Delete relation table entry - * - * @param string $propertyName Property name to initialize - * @param array $objsIds Object ids to insert - * @param mixed $objId Model to reference - * - * @return mixed - * - * @since 1.0.0 - */ - private static function deleteRelationTable(string $propertyName, array $objsIds, $objId) - { - /** @var string $table */ - if ( - !empty($objsIds) - && static::$hasMany[$propertyName]['table'] !== static::$table - && static::$hasMany[$propertyName]['table'] !== static::$hasMany[$propertyName]['mapper']::$table - ) { - foreach ($objsIds as $key => $src) { - $relQuery = new Builder(self::$db); - $relQuery->prefix(self::$db->getPrefix()) - ->into(static::$hasMany[$propertyName]['table']) - ->delete(); - - $relQuery->where(static::$hasMany[$propertyName]['src'], '=', $src) - ->where(static::$hasMany[$propertyName]['dst'], '=', $objId, 'and'); - - self::$db->con->prepare($relQuery->toSql())->execute(); - } - } - } - -} diff --git a/DataStorage/Database/GrammarAbstract.php b/DataStorage/Database/GrammarAbstract.php index 9140a1b6b..bd5bcc1c3 100644 --- a/DataStorage/Database/GrammarAbstract.php +++ b/DataStorage/Database/GrammarAbstract.php @@ -15,8 +15,6 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database; -use phpOMS\Utils\StringUtils; - /** * Grammar. * @@ -79,7 +77,7 @@ abstract class GrammarAbstract /** * Special keywords. * - * @var string + * @var array * @since 1.0.0 */ protected $specialKeywords = [ diff --git a/DataStorage/Database/ReadMapperAbstract.php b/DataStorage/Database/ReadMapperAbstract.php deleted file mode 100644 index ef934f57a..000000000 --- a/DataStorage/Database/ReadMapperAbstract.php +++ /dev/null @@ -1,1126 +0,0 @@ -where(static::$table . '.' . $col['name'], 'LIKE', '%' . $search . '%', 'OR'); - } - } - - return static::getAllByQuery($query); - } - - /** - * Populate data. - * - * @param array $result Result set - * - * @return array - * - * @since 1.0.0 - */ - public static function populateIterable(array $result) : array - { - $row = []; - - foreach ($result as $element) { - if (isset($element[static::$primaryField])) { - $row[$element[static::$primaryField]] = self::populate($element); - } else { - $row[] = self::populate($element); - } - } - - return $row; - } - - /** - * Populate data. - * - * @param array $result Result set - * - * @return array - * - * @since 1.0.0 - */ - public static function populateIterableArray(array $result) : array - { - $row = []; - - foreach ($result as $element) { - if (isset($element[static::$primaryField])) { - $row[$element[static::$primaryField]] = self::populateAbstractArray($element); - } else { - $row[] = self::populateAbstractArray($element); - } - } - - return $row; - } - - /** - * Populate data. - * - * @param array $result Result set - * @param mixed $obj Object to populate - * - * @return mixed - * - * @since 1.0.0 - */ - public static function populate(array $result, $obj = null) - { - $class = static::class; - $class = str_replace('Mapper', '', $class); - - if (count($result) === 0) { - $parts = explode('\\', $class); - $name = $parts[$c = (count($parts) - 1)]; - $parts[$c] = 'Null' . $name; - $class = implode('\\', $parts); - } - - if (!isset($obj)) { - $obj = new $class(); - } - - return self::populateAbstract($result, $obj); - } - - /** - * Populate data. - * - * @param array[] $result Result set - * @param mixed $obj Object to add the relations to - * - * @return void - * - * @since 1.0.0 - */ - public static function populateManyToMany(array $result, &$obj) /* : void */ - { - // todo: maybe pass reflectionClass as optional parameter for performance increase - $reflectionClass = new \ReflectionClass(get_class($obj)); - - foreach ($result as $member => $values) { - if (!empty($values) && $reflectionClass->hasProperty($member)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasMany[$member]['mapper']; - $reflectionProperty = $reflectionClass->getProperty($member); - - $values = array_diff($values, array_keys(self::$initObjects[$mapper] ?? [])); - if(empty($values)) { - continue; - } - - if (!($accessible = $reflectionProperty->isPublic())) { - $reflectionProperty->setAccessible(true); - } - - $objects = $mapper::get($values); - $reflectionProperty->setValue($obj, !is_array($objects) ? [$objects] : $objects); - - if (!$accessible) { - $reflectionProperty->setAccessible(false); - } - } - } - } - - /** - * Populate data. - * - * @param array[] $result Result set - * @param array $obj Object to add the relations to - * - * @return void - * - * @since 1.0.0 - */ - public static function populateManyToManyArray(array $result, array &$obj) /* : void */ - { - foreach ($result as $member => $values) { - if (!empty($values)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasMany[$member]['mapper']; - $values = array_diff($values, array_keys(self::$initObjects[$mapper] ?? [])); - if(empty($values)) { - continue; - } - - $objects = $mapper::getArray($values); - $obj[$member] = $objects; - } - } - } - - /** - * Populate data. - * - * @param mixed $obj Object to add the relations to - * - * @return void - * - * @todo accept reflection class as parameter - * - * @since 1.0.0 - */ - public static function populateHasOne(&$obj) /* : void */ - { - $reflectionClass = new \ReflectionClass(get_class($obj)); - - foreach (static::$hasOne as $member => $one) { - // todo: is that if necessary? performance is suffering for sure! - if ($reflectionClass->hasProperty($member)) { - $reflectionProperty = $reflectionClass->getProperty($member); - - if (!($accessible = $reflectionProperty->isPublic())) { - $reflectionProperty->setAccessible(true); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasOne[$member]['mapper']; - - if(self::isInitialized($mapper, $reflectionProperty->getValue($obj))) { - $value = self::$initObjects[$mapper][$id]; - } else { - $value = $mapper::get($reflectionProperty->getValue($obj)); - } - - $reflectionProperty->setValue($obj, $value); - - if (!$accessible) { - $reflectionProperty->setAccessible(false); - } - } - } - } - - /** - * Populate data. - * - * @param array $obj Object to add the relations to - * - * @return void - * - * @todo accept reflection class as parameter - * - * @since 1.0.0 - */ - public static function populateHasOneArray(array &$obj) /* : void */ - { - foreach (static::$hasOne as $member => $one) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasOne[$member]['mapper']; - - if(self::isInitialized($mapper, $obj['member'])) { - $value = self::$initObjects[$mapper][$id]; - } else { - $value = $mapper::getArray($obj[$member]); - } - - $obj[$member] = $value; - } - } - - /** - * Populate data. - * - * @param mixed $obj Object to add the relations to - * - * @return void - * - * @todo accept reflection class as parameter - * - * @since 1.0.0 - */ - public static function populateOwnsOne(&$obj) /* : void */ - { - $reflectionClass = new \ReflectionClass(get_class($obj)); - - foreach (static::$ownsOne as $member => $one) { - // todo: is that if necessary? performance is suffering for sure! - if ($reflectionClass->hasProperty($member)) { - $reflectionProperty = $reflectionClass->getProperty($member); - - if (!($accessible = $reflectionProperty->isPublic())) { - $reflectionProperty->setAccessible(true); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$ownsOne[$member]['mapper']; - - if(self::isInitialized($mapper, $reflectionProperty->getValue($obj))) { - $value = self::$initObjects[$mapper][$id]; - } else { - $value = $mapper::get($reflectionProperty->getValue($obj)); - } - - $reflectionProperty->setValue($obj, $value); - - if (!$accessible) { - $reflectionProperty->setAccessible(false); - } - } - } - } - - /** - * Populate data. - * - * @param array $obj Object to add the relations to - * - * @return void - * - * @todo accept reflection class as parameter - * - * @since 1.0.0 - */ - public static function populateOwnsOneArray(array &$obj) /* : void */ - { - foreach (static::$ownsOne as $member => $one) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$ownsOne[$member]['mapper']; - - if(self::isInitialized($mapper, $obj[$member])) { - $value = self::$initObjects[$mapper][$id]; - } else { - $value = $mapper::getArray($obj[$member]); - } - - $obj[$member] = $value; - } - } - - /** - * Populate data. - * - * @param mixed $obj Object to add the relations to - * - * @return void - * - * @todo accept reflection class as parameter - * - * @since 1.0.0 - */ - public static function populateBelongsTo(&$obj) /* : void */ - { - $reflectionClass = new \ReflectionClass(get_class($obj)); - - foreach (static::$belongsTo as $member => $one) { - // todo: is that if necessary? performance is suffering for sure! - if ($reflectionClass->hasProperty($member)) { - $reflectionProperty = $reflectionClass->getProperty($member); - - if (!($accessible = $reflectionProperty->isPublic())) { - $reflectionProperty->setAccessible(true); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$belongsTo[$member]['mapper']; - - if(self::isInitialized($mapper, $reflectionProperty->getValue($obj))) { - $value = self::$initObjects[$mapper][$id]; - } else { - $value = $mapper::get($reflectionProperty->getValue($obj)); - } - - $reflectionProperty->setValue($obj, $value); - - if (!$accessible) { - $reflectionProperty->setAccessible(false); - } - } - } - } - - /** - * Populate data. - * - * @param array $obj Object to add the relations to - * - * @return void - * - * @todo accept reflection class as parameter - * - * @since 1.0.0 - */ - public static function populateBelongsToArray(array &$obj) /* : void */ - { - foreach (static::$belongsTo as $member => $one) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$belongsTo[$member]['mapper']; - - if(self::isInitialized($mapper, $obj[$member])) { - $value = self::$initObjects[$mapper][$id]; - } else { - $value = $mapper::get($obj[$member]); - } - - $obj[$member] = $value; - } - } - - /** - * Populate data. - * - * @param array $result Query result set - * @param mixed $obj Object to populate - * - * @return mixed - * - * @throws \UnexpectedValueException - * - * @since 1.0.0 - */ - public static function populateAbstract(array $result, $obj) - { - $reflectionClass = new \ReflectionClass(get_class($obj)); - - foreach ($result as $column => $value) { - if (isset(static::$columns[$column]['internal']) && $reflectionClass->hasProperty(static::$columns[$column]['internal'])) { - $reflectionProperty = $reflectionClass->getProperty(static::$columns[$column]['internal']); - - if (!($accessible = $reflectionProperty->isPublic())) { - $reflectionProperty->setAccessible(true); - } - - if (in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { - settype($value, static::$columns[$column]['type']); - $reflectionProperty->setValue($obj, $value); - } elseif (static::$columns[$column]['type'] === 'DateTime') { - $reflectionProperty->setValue($obj, new \DateTime($value ?? '')); - } elseif (static::$columns[$column]['type'] === 'Json') { - $reflectionProperty->setValue($obj, json_decode($value, true)); - } elseif (static::$columns[$column]['type'] === 'Serializable') { - $member = $reflectionProperty->getValue($obj); - $member->unserialize($value); - } else { - throw new \UnexpectedValueException('Value "' . static::$columns[$column]['type'] . '" is not supported.'); - } - - if (!$accessible) { - $reflectionProperty->setAccessible(false); - } - } - } - - return $obj; - } - - /** - * Populate data. - * - * @param array $result Query result set - * - * @return array - * - * @throws \UnexpectedValueException - * - * @since 1.0.0 - */ - public static function populateAbstractArray(array $result) : array - { - $obj = []; - - foreach ($result as $column => $value) { - if (isset(static::$columns[$column]['internal'])) { - if (in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { - settype($value, static::$columns[$column]['type']); - $obj[static::$columns[$column]['internal']] = $value; - } elseif (static::$columns[$column]['type'] === 'DateTime') { - $obj[static::$columns[$column]['internal']] = new \DateTime($value ?? ''); - } elseif (static::$columns[$column]['type'] === 'Json') { - $obj[static::$columns[$column]['internal']] = json_decode($value, true); - } elseif (static::$columns[$column]['type'] === 'Serializable') { - $obj[static::$columns[$column]['internal']] = $value; - } else { - throw new \UnexpectedValueException('Value "' . static::$columns[$column]['type'] . '" is not supported.'); - } - } - } - - return $obj; - } - - /** - * Get object. - * - * @param mixed $primaryKey Key - * @param int $relations Load relations - * @param mixed $fill Object to fill - * - * @return mixed - * - * @since 1.0.0 - */ - public static function get($primaryKey, int $relations = RelationType::ALL, $fill = null) - { - if(!isset(self::$parentMapper)) { - self::setUpParentMapper(); - } - - self::extend(__CLASS__); - - $primaryKey = (array) $primaryKey; - $fill = (array) $fill; - $obj = []; - $fCount = count($fill); - $toFill = null; - - foreach ($primaryKey as $key => $value) { - if(self::isInitialized(static::class, $value)) { - continue; - } - - if ($fCount > 0) { - $toFill = current($fill); - next($fill); - } - - $obj[$value] = self::populate(self::getRaw($value), $toFill); - - if(method_exists($obj[$value], 'initialize')) { - $obj[$value]->initialize(); - } - - self::addInitialized(static::class, $value); - } - - self::fillRelations($obj, $relations); - self::clear(); - - return count($obj) === 1 ? reset($obj) : $obj; - } - - /** - * Get object. - * - * @param mixed $primaryKey Key - * @param int $relations Load relations - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getArray($primaryKey, int $relations = RelationType::ALL) : array - { - if(!isset(self::$parentMapper)) { - self::setUpParentMapper(); - } - - self::extend(__CLASS__); - - $primaryKey = (array) $primaryKey; - $fill = (array) $fill; - $obj = []; - - foreach ($primaryKey as $key => $value) { - if(self::isInitialized(static::class, $value)) { - continue; - } - - $obj[$value] = self::populateAbstractArray(self::getRaw($value)); - - self::addInitialized(static::class, $value); - } - - self::fillRelationsArray($obj, $relations); - self::clear(); - - return count($obj) === 1 ? reset($obj) : $obj; - } - - /** - * Get object. - * - * @param mixed $refKey Key - * @param string $ref The field that defines the for - * @param int $relations Load relations - * @param mixed $fill Object to fill - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getFor($refKey, string $ref, int $relations = RelationType::ALL, $fill = null) - { - if(!isset(self::$parentMapper)) { - self::setUpParentMapper(); - } - - self::extend(__CLASS__); - - $refKey = (array) $refKey; - $obj = []; - - foreach ($refKey as $key => $value) { - // todo: this only works for belongsTo not for many-to-many relations. Implement many-to-many - $obj[$value] = self::get(self::getPrimaryKeyBy($value, self::getColumnByMember($ref)), $relations, $fill); - } - return count($obj) === 1 ? reset($obj) : $obj; - } - - /** - * Get object. - * - * @param mixed $refKey Key - * @param string $ref The field that defines the for - * @param int $relations Load relations - * @param mixed $fill Object to fill - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getForArray($refKey, string $ref, int $relations = RelationType::ALL, $fill = null) - { - if(!isset(self::$parentMapper)) { - self::setUpParentMapper(); - } - - self::extend(__CLASS__); - - $refKey = (array) $refKey; - $obj = []; - - foreach ($refKey as $key => $value) { - // todo: this only works for belongsTo not for many-to-many relations. Implement many-to-many - $obj[$value] = self::getArray(self::getPrimaryKeyBy($value, self::getColumnByMember($ref)), $relations, $fill); - } - return count($obj) === 1 ? reset($obj) : $obj; - } - - /** - * Get object. - * - * @param int $relations Load relations - * @param string $lang Language - * - * @return array - * - * @since 1.0.0 - */ - public static function getAll(int $relations = RelationType::ALL, string $lang = '') : array - { - if(!isset(self::$parentMapper)) { - self::setUpParentMapper(); - } - - $obj = self::populateIterable(self::getAllRaw($lang)); - self::fillRelations($obj, $relations); - self::clear(); - - return $obj; - } - - /** - * Get object. - * - * @param int $relations Load relations - * @param string $lang Language - * - * @return array - * - * @since 1.0.0 - */ - public static function getAllArray(int $relations = RelationType::ALL, string $lang = '') : array - { - if(!isset(self::$parentMapper)) { - self::setUpParentMapper(); - } - - $obj = self::populateIterableArray(self::getAllRaw($lang)); - self::fillRelationsArray($obj, $relations); - self::clear(); - - return $obj; - } - - /** - * Find data. - * - * @param Builder $query Query - * - * @return array - * - * @since 1.0.0 - */ - public static function listResults(Builder $query) : array - { - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - return self::populateIterable($sth->fetchAll(\PDO::FETCH_ASSOC)); - } - - /** - * Get newest. - * - * This will fall back to the insert id if no datetime column is present. - * - * @param int $limit Newest limit - * @param Builder $query Pre-defined query - * @param int $relations Load relations - * @param string $lang Language - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getNewest(int $limit = 1, Builder $query = null, int $relations = RelationType::ALL, string $lang = '') : array - { - self::extend(__CLASS__); - - $query = $query ?? new Builder(self::$db); - $query = self::getQuery($query); - $query->limit($limit); /* todo: limit is not working, setting this to 2 doesn't have any effect!!! */ - - if (!empty(static::$createdAt)) { - $query->orderBy(static::$table . '.' . static::$columns[static::$createdAt]['name'], 'DESC'); - } else { - $query->orderBy(static::$table . '.' . static::$columns[static::$primaryField]['name'], 'DESC'); - } - - if (!empty(self::$language_field) && !empty($lang)) { - $query->where(static::$table . '.' . static::$language_field, '=', $lang, 'AND'); - } - - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - $results = $sth->fetchAll(\PDO::FETCH_ASSOC); - $obj = self::populateIterable(is_bool($results) ? [] : $results); - - self::fillRelations($obj, $relations); - self::clear(); - - return $obj; - - } - - /** - * Get all by custom query. - * - * @param Builder $query Query - * @param int $relations Relations - * - * @return array - * - * @since 1.0.0 - */ - public static function getAllByQuery(Builder $query, int $relations = RelationType::ALL) : array - { - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - $results = $sth->fetchAll(\PDO::FETCH_ASSOC); - $results = is_bool($results) ? [] : $results; - - $obj = self::populateIterable($results); - self::fillRelations($obj, $relations); - self::clear(); - - return $obj; - } - - /** - * Get random object - * - * @param int $amount Amount of random models - * @param int $relations Relations type - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getRandom(int $amount = 1, int $relations = RelationType::ALL) - { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->random(static::$primaryField) - ->from(static::$table) - ->limit($amount); - - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - return self::get($sth->fetchAll(), $relations); - } - - /** - * Fill object with relations - * - * @param mixed $obj Objects to fill - * @param int $relations Relations type - * - * @return void - * - * @since 1.0.0 - */ - public static function fillRelations(array &$obj, int $relations = RelationType::ALL) /* : void */ - { - $hasMany = !empty(static::$hasMany); - $hasOne = !empty(static::$hasOne); - $ownsOne = !empty(static::$ownsOne); - $belongsTo = !empty(static::$belongsTo); - - if ($relations !== RelationType::NONE && ($hasMany || $hasOne || $ownsOne || $belongsTo)) { - foreach ($obj as $key => $value) { - /* loading relations from relations table and populating them and then adding them to the object */ - if ($hasMany) { - self::populateManyToMany(self::getHasManyRaw($key, $relations), $obj[$key]); - } - - if ($hasOne) { - self::populateHasOne($obj[$key]); - } - - if ($ownsOne) { - self::populateOwnsOne($obj[$key]); - } - - if ($belongsTo) { - self::populateBelongsTo($obj[$key]); - } - } - } - } - - /** - * Fill object with relations - * - * @param mixed $obj Objects to fill - * @param int $relations Relations type - * - * @return void - * - * @since 1.0.0 - */ - public static function fillRelationsArray(array &$obj, int $relations = RelationType::ALL) /* : void */ - { - $hasMany = !empty(static::$hasMany); - $hasOne = !empty(static::$hasOne); - $ownsOne = !empty(static::$ownsOne); - $belongsTo = !empty(static::$belongsTo); - - if ($relations !== RelationType::NONE && ($hasMany || $hasOne || $ownsOne || $belongsTo)) { - foreach ($obj as $key => $value) { - /* loading relations from relations table and populating them and then adding them to the object */ - if ($hasMany) { - self::populateManyToManyArray(self::getHasManyRaw($key, $relations), $obj[$key]); - } - - if ($hasOne) { - self::populateHasOneArray($obj[$key]); - } - - if ($ownsOne) { - self::populateOwnsOneArray($obj[$key]); - } - - if ($belongsTo) { - self::populateBelongsToArray($obj[$key]); - } - } - } - } - - /** - * Get object. - * - * @param mixed $primaryKey Key - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getRaw($primaryKey) : array - { - $query = self::getQuery(); - $query->where(static::$table . '.' . static::$primaryField, '=', $primaryKey); - - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - $results = $sth->fetch(\PDO::FETCH_ASSOC); - - return is_bool($results) ? [] : $results; - } - - /** - * Get object. - * - * @param mixed $refKey Key - * @param string $ref Ref - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getPrimaryKeyBy($refKey, string $ref) : array - { - $query = self::getQuery(); - $query->select(static::$primaryField) - ->from(static::$table) - ->where(static::$table . '.' . $ref, '=', $refKey); - - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - $results = array_column($sth->fetchAll(\PDO::FETCH_NUM) ?? [], 0); - - return $results; - } - - /** - * Get all in raw output. - * - * @param string $lang Language - * - * @return array - * - * @since 1.0.0 - */ - public static function getAllRaw(string $lang = '') : array - { - $query = self::getQuery(); - - if (!empty(self::$language_field) && !empty($lang)) { - $query->where(static::$table . '.' . static::$language_field, '=', $lang, 'AND'); - } - - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - - $results = $sth->fetchAll(\PDO::FETCH_ASSOC); - - return is_bool($results) ? [] : $results; - } - - /** - * Get raw by primary key - * - * @param mixed $primaryKey Primary key - * @param int $relations Load relations - * - * @return array - * - * @since 1.0.0 - */ - public static function getHasManyRaw($primaryKey, int $relations = RelationType::ALL) : array - { - $result = []; - - foreach (static::$hasMany as $member => $value) { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()); - - if ($relations === RelationType::ALL) { - /** @var string $primaryField */ - $src = $value['src'] ?? $value['mapper']::$primaryField; - - $query->select($value['table'] . '.' . $src) - ->from($value['table']) - ->where($value['table'] . '.' . $value['dst'], '=', $primaryKey); - } elseif ($relations === RelationType::NEWEST) { - - /* - SELECT c.*, p1.* - FROM customer c - JOIN purchase p1 ON (c.id = p1.customer_id) - LEFT OUTER JOIN purchase p2 ON (c.id = p2.customer_id AND - (p1.date < p2.date OR p1.date = p2.date AND p1.id < p2.id)) - WHERE p2.id IS NULL; - */ - /* - $query->select(static::$table . '.' . static::$primaryField, $value['table'] . '.' . $value['src']) - ->from(static::$table) - ->join($value['table']) - ->on(static::$table . '.' . static::$primaryField, '=', $value['table'] . '.' . $value['dst']) - ->leftOuterJoin($value['table']) - ->on(new And('1', new And(new Or('d1', 'd2'), 'id'))) - ->where($value['table'] . '.' . $value['dst'], '=', 'NULL'); - */ - } - - $sth = self::$db->con->prepare($query->toSql()); - $sth->execute(); - $result[$member] = $sth->fetchAll(\PDO::FETCH_COLUMN); - } - - return $result; - } - - /** - * Get mapper specific builder - * - * @param Builder $query Query to fill - * - * @return Builder - * - * @since 1.0.0 - */ - public static function getQuery(Builder $query = null) : Builder - { - $query = $query ?? new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->select('*') - ->from(static::$table); - - return $query; - } - - /** - * Get model based on request object - * - * @todo: change to graphql - * - * @param RequestAbstract $request Request object - * - * @return mixed - * - * @since 1.0.0 - */ - public static function getByRequest(RequestAbstract $request) - { - if (!is_null($request->getData('id'))) { - $result = static::get($request->getData('id')); - } elseif (!is_null($filter = $request->getData('filter'))) { - $filter = strtolower($filter); - - if ($filter === 'all') { - $result = static::getAll(); - } elseif ($filter === 'list') { - $list = $request->getData('list'); - $result = static::get(json_decode($list, true)); - } else { - $limit = (int) ($request->getData('limit') ?? 1); - $from = !is_null($request->getData('from')) ? new \DateTime($request->getData('from')) : null; - $to = !is_null($request->getData('to')) ? new \DateTime($request->getData('to')) : null; - - $query = static::getQuery(); - $query->limit($limit); - - if (isset($from, $to) && !empty(static::getCreatedAt())) { - $query->where(static::getCreatedAt(), '>=', $from); - $query->where(static::getCreatedAt(), '<=', $to); - } - - $result = static::getAllByQuery($query); - } - } else { - $class = static::class; - $class = str_replace('Mapper', '', $class); - $parts = explode('\\', $class); - $name = $parts[$c = (count($parts) - 1)]; - $parts[$c] = 'Null' . $name; - $class = implode('\\', $parts); - $result = new $class(); - } - - return $result; - } - - /** - * Add initialized object to local cache - * - * @param string $mapper Mapper name - * @param mixed $id Object id - * @param object $obj Model to cache locally - * - * @return void - * - * @since 1.0.0 - */ - private static function addInitialized(string $mapper, $id, $obj = null) /* : void */ - { - if(!isset(self::$initObjects[$mapper])) { - self::$initObjects[$mapper] = []; - } - - self::$initObjects[$mapper][$id] = $obj; - } - - /** - * Check if a object is initialized - * - * @param string $mapper Mapper name - * @param mixed $id Object id - * - * @return bool - * - * @since 1.0.0 - */ - private static function isInitialized($mapper, $id) : bool - { - return isset(self::$initObjects[$mapper]) && isset(self::$initObjects[$mapper][$id]); - } -} diff --git a/DataStorage/Database/RelationType.php b/DataStorage/Database/RelationType.php index 206e5d019..aedbcd0f4 100644 --- a/DataStorage/Database/RelationType.php +++ b/DataStorage/Database/RelationType.php @@ -30,11 +30,11 @@ use phpOMS\Stdlib\Base\Enum; */ abstract class RelationType extends Enum { - /* public */ const NONE = 0; - /* public */ const NEWEST = 1; + /* public */ const NONE = 0; + /* public */ const NEWEST = 1; /* public */ const BELONGS_TO = 2; - /* public */ const OWNS_ONE = 4; - /* public */ const HAS_MANY = 8; - /* public */ const ALL = 16; - /* public */ const REFERENCE = 32; + /* public */ const OWNS_ONE = 4; + /* public */ const HAS_MANY = 8; + /* public */ const ALL = 16; + /* public */ const REFERENCE = 32; } diff --git a/DataStorage/Database/UpdateMapperAbstract.php b/DataStorage/Database/UpdateMapperAbstract.php deleted file mode 100644 index f3cda33bb..000000000 --- a/DataStorage/Database/UpdateMapperAbstract.php +++ /dev/null @@ -1,326 +0,0 @@ - $rel) { - $property = $reflectionClass->getProperty($propertyName); - - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } - - $values = $property->getValue($obj); - - if (!($isPublic)) { - $property->setAccessible(false); - } - - if (!isset(static::$hasMany[$propertyName]['mapper'])) { - throw new InvalidMapperException(); - } - - /** @var DataMapperAbstract $mapper */ - $mapper = static::$hasMany[$propertyName]['mapper']; - $objsIds = []; - $relReflectionClass = null; - - foreach ($values as $key => &$value) { - if (!is_object($value)) { - // Is scalar => already in database - $objsIds[$key] = $value; - - continue; - } - - if (!isset($relReflectionClass)) { - $relReflectionClass = new \ReflectionClass(get_class($value)); - } - - $primaryKey = $mapper::getObjectId($value, $relReflectionClass); - - // already in db - if (!empty($primaryKey)) { - $objsIds[$key] = $value; - - continue; - } - - // create if not existing - /** @var string $table */ - /** @var array $columns */ - if (static::$hasMany[$propertyName]['table'] === static::$hasMany[$propertyName]['mapper']::$table) { - $relProperty = $relReflectionClass->getProperty($mapper::$columns[static::$hasMany[$propertyName]['dst']]['internal']); - - if (!$isPublic) { - $relProperty->setAccessible(true); - } - - $relProperty->setValue($value, $objId); - - if (!($isPublic)) { - $relProperty->setAccessible(false); - } - } - - $objsIds[$key] = $mapper::create($value); - } - - self::updateRelationTable($propertyName, $objsIds, $objId); - } - } - - /** - * Update relation table entry - * - * Deletes old entries and creates new ones - * - * @param string $propertyName Property name to initialize - * @param array $objsIds Object ids to insert - * @param mixed $objId Model to reference - * - * @return mixed - * - * @throws \Exception - * - * @since 1.0.0 - */ - private static function updateRelationTable(string $propertyName, array $objsIds, $objId) - { - /** @var string $table */ - if ( - !empty($objsIds) - && static::$hasMany[$propertyName]['table'] !== static::$table - && static::$hasMany[$propertyName]['table'] !== static::$hasMany[$propertyName]['mapper']::$table - ) { - $many = self::getHasManyRaw($objId); - - foreach(static::$hasMany as $member => $value) { - // todo: definately an error here. needs testing - throw new \Exception(); - $removes = array_diff_key($many[$member], $objsIds[$member]); - $adds = array_diff_key($objsIds[$member], $many[$member]); - - if(!empty($removes)) { - self::deleteRelationTable($propertyName, $removes, $objId); - } - - if(!empty($adds)) { - self::createRelationTable($propertyName, $adds, $objId); - } - } - } - } - - /** - * Update owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to update - * - * @return mixed - * - * @since 1.0.0 - */ - private static function updateOwnsOne(string $propertyName, $obj) - { - if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$ownsOne[$propertyName]['mapper']; - - // todo: delete owned one object is not recommended since it can be owned by by something else? or does owns one mean that nothing else can have a relation to this one? - - return $mapper::update($obj); - } - - return $obj; - } - - /** - * Update owns one - * - * The reference is stored in the main model - * - * @param string $propertyName Property name to initialize - * @param Object $obj Object to update - * - * @return mixed - * - * @since 1.0.0 - */ - private static function updateBelongsTo(string $propertyName, $obj) - { - if (is_object($obj)) { - /** @var DataMapperAbstract $mapper */ - $mapper = static::$belongsTo[$propertyName]['mapper']; - - return $mapper::update($obj); - } - - return $obj; - } - - /** - * Update object in db. - * - * @param Object $obj Model to update - * @param mixed $objId Model id - * @param \ReflectionClass $reflectionClass Reflection class - * - * @return mixed - * - * @since 1.0.0 - */ - private static function updateModel($obj, $objId, \ReflectionClass $reflectionClass = null) /* : void */ - { - $query = new Builder(self::$db); - $query->prefix(self::$db->getPrefix()) - ->into(static::$table) - ->where(static::$primaryField, '=', $objId); - - $properties = $reflectionClass->getProperties(); - - foreach ($properties as $property) { - $propertyName = $property->getName(); - - if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName])) { - continue; - } - - if (!($isPublic = $property->isPublic())) { - $property->setAccessible(true); - } - - // todo: the order of updating could be a problem. maybe looping through ownsOne and belongsTo first is better. - - foreach (static::$columns as $key => $column) { - if (isset(static::$ownsOne[$propertyName]) && $column['internal'] === $propertyName) { - $id = self::updateOwnsOne($propertyName, $property->getValue($obj)); - $value = self::parseValue($column['type'], $id); - - // todo: should not be done if the id didn't change. but for now don't know if id changed - $query->update($column['name'])->value($value, $column['type']); - break; - } elseif (isset(static::$belongsTo[$propertyName]) && $column['internal'] === $propertyName) { - $id = self::updateBelongsTo($propertyName, $property->getValue($obj)); - $value = self::parseValue($column['type'], $id); - - // todo: should not be done if the id didn't change. but for now don't know if id changed - $query->update($column['name'])->value($value, $column['type']); - break; - } elseif ($column['internal'] === $propertyName && $column['type'] !== static::$primaryField) { - $value = self::parseValue($column['type'], $property->getValue($obj)); - - $query->update($column['name'])->value($value, $column['type']); - break; - } - } - - if (!($isPublic)) { - $property->setAccessible(false); - } - } - - self::$db->con->prepare($query->toSql())->execute(); - } - - /** - * Update object in db. - * - * @param mixed $obj Object reference (gets filled with insert id) - * @param int $relations Create all relations as well - * - * @return int - * - * @since 1.0.0 - */ - public static function update($obj, int $relations = RelationType::ALL) : int - { - self::extend(__CLASS__); - $reflectionClass = new \ReflectionClass(get_class($obj)); - $objId = self::getObjectId($obj, $reflectionClass); - $update = true; - - if(empty($objId)) { - $update = false; - self::create($obj, $relations); - } - - if ($relations === RelationType::ALL) { - self::updateHasMany($reflectionClass, $obj, $objId); - } - - if($update) { - self::updateModel($obj, $objId, $reflectionClass); - } - - return $objId; - } -} diff --git a/Localization/L11nManager.php b/Localization/L11nManager.php index 7d8216e4f..c4157e707 100644 --- a/Localization/L11nManager.php +++ b/Localization/L11nManager.php @@ -16,7 +16,6 @@ declare(strict_types=1); namespace phpOMS\Localization; use phpOMS\Log\FileLogger; -use phpOMS\Log\LoggerInterface; use phpOMS\Module\ModuleAbstract; /** @@ -39,24 +38,13 @@ class L11nManager */ private $language = []; - /** - * Logger. - * - * @var LoggerInterface - * @since 1.0.0 - */ - private $logger = null; - /** * Construct. * - * @param LoggerInterface $logger Logger - * * @since 1.0.0 */ - public function __construct(LoggerInterface $logger = null) + public function __construct() { - $this->logger = $logger; } /** @@ -170,16 +158,10 @@ class L11nManager $this->loadLanguage($code, $module, $class::getLocalization($code, $theme)); if (!isset($this->language[$code][$module][$translation])) { - if(isset($this->logger)) { - $this->logger->warning(FileLogger::MSG_FULL, [ - 'message' => 'Undefined translation for \'' . $code . '/' . $module . '/' . $translation . '\'.', - ]); - } - return 'ERROR'; } - } catch(\Excpetion $e) { - $this->logger->warning(FileLogger::MSG_FULL, [ + } catch(\Exception $e) { + FileLogger::getInstance()->warning(FileLogger::MSG_FULL, [ 'message' => 'Undefined translation for \'' . $code . '/' . $module . '/' . $translation . '\'.', ]); diff --git a/Log/FileLogger.php b/Log/FileLogger.php index 4a23e6319..230df4ad0 100644 --- a/Log/FileLogger.php +++ b/Log/FileLogger.php @@ -17,8 +17,6 @@ namespace phpOMS\Log; use phpOMS\Stdlib\Base\Exception\InvalidEnumValue; use phpOMS\System\File\Local\File; -use phpOMS\System\File\PathException; -use phpOMS\Utils\StringUtils; /** * Logging class. diff --git a/Math/Statistic/Forecast/Regression/RegressionAbstract.php b/Math/Statistic/Forecast/Regression/RegressionAbstract.php index b8f7cda32..8c4068702 100644 --- a/Math/Statistic/Forecast/Regression/RegressionAbstract.php +++ b/Math/Statistic/Forecast/Regression/RegressionAbstract.php @@ -12,13 +12,22 @@ * @link http://orange-management.com */ declare(strict_types=1); - namespace phpOMS\Math\Statistic\Forecast\Regression; +namespace phpOMS\Math\Statistic\Forecast\Regression; use phpOMS\Math\Statistic\Average; use phpOMS\Math\Statistic\Forecast\ForecastIntervalMultiplier; use phpOMS\Math\Statistic\MeasureOfDispersion; use phpOMS\Math\Matrix\Exception\InvalidDimensionException; +/** + * Regression abstract class. + * + * @category Framework + * @package phpOMS\Math\Statistic + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ abstract class RegressionAbstract { /** @@ -146,7 +155,35 @@ abstract class RegressionAbstract return Average::arithmeticMean($y) - $b1 * Average::arithmeticMean($x); } - abstract public static function getSlope(float $b1, float $y, float $x) : float; + /** + * Get slope + * + * @param float $b1 Beta 1 + * @param float $x Obersved x values + * @param float $y Observed y values + * + * @return float + * + * @since 1.0.0 + */ + public static function getSlope(float $b1, float $y, float $x) : float + { + return 0.0; + } - abstract public static function getElasticity(float $b1, float $y, float $x): float; + /** + * Get elasticity + * + * @param float $b1 Beta 1 + * @param float $x Obersved x values + * @param float $y Observed y values + * + * @return float + * + * @since 1.0.0 + */ + public static function getElasticity(float $b1, float $y, float $x): float + { + return 0.0; + } } \ No newline at end of file diff --git a/Math/Stochastic/NaiveBayesFilter.php b/Math/Stochastic/NaiveBayesFilter.php index 99bcee44c..e16a98450 100644 --- a/Math/Stochastic/NaiveBayesFilter.php +++ b/Math/Stochastic/NaiveBayesFilter.php @@ -49,7 +49,7 @@ class NaiveBayesFilter } } - return 1 / (1+exp(M_E, $n)); + return 1 / (1+exp($n)); } private function normalizeDictionary() : array diff --git a/Message/HeaderAbstract.php b/Message/HeaderAbstract.php index 0fd00cc2b..e3ede1c63 100644 --- a/Message/HeaderAbstract.php +++ b/Message/HeaderAbstract.php @@ -85,7 +85,7 @@ abstract class HeaderAbstract /** * Set localization * - * @param int $localization Localization + * @param Localization $l11n Localization * * @return void * @@ -135,7 +135,7 @@ abstract class HeaderAbstract public function setStatusCode(int $status) /* : void */ { $this->status = $status; - $this->header->generate($status); + $this->generate($status); } /** diff --git a/Message/Http/Header.php b/Message/Http/Header.php index f53d0a24b..a8aa9a873 100644 --- a/Message/Http/Header.php +++ b/Message/Http/Header.php @@ -16,7 +16,7 @@ declare(strict_types=1); namespace phpOMS\Message\Http; use phpOMS\Message\HeaderAbstract; -use phpOMS\DataStorage\LockExcpetion; +use phpOMS\DataStorage\LockException; /** * Response class. @@ -68,7 +68,7 @@ class Header extends HeaderAbstract public function set(string $key, string $header, bool $overwrite = false) : bool { if (self::$isLocked) { - throw new LockExcpetion('HTTP header'); + throw new LockException('HTTP header'); } $key = strtolower($key); @@ -145,18 +145,6 @@ class Header extends HeaderAbstract return self::getAllHeaders(); } - /** - * Get pushed header by name. - * - * @return string - * - * @since 1.0.0 - */ - public function getHeader(string $name) : string - { - return self::getAllHeaders()[$name] ?? ''; - } - /** * Get all headers for apache and nginx * @@ -194,7 +182,7 @@ class Header extends HeaderAbstract public function remove(int $key) : bool { if (self::$isLocked) { - throw new \LockException('HTTP header'); + throw new LockException('HTTP header'); } if (isset($this->header[$key])) { @@ -209,7 +197,7 @@ class Header extends HeaderAbstract /** * Get header by name. * - * @param int $key Header key + * @param string $key Header key * * @return array * @@ -219,19 +207,19 @@ class Header extends HeaderAbstract { return $this->header[strtolower($key)] ?? []; } - + /** * {@inheritdoc} */ public function getReasonPhrase() : string { - return $this->header->getHeader('Status'); + return $this->get('Status'); } /** * Check if header is defined. * - * @param int $key Header key + * @param string $key Header key * * @return bool * diff --git a/Message/Http/Request.php b/Message/Http/Request.php index b4ab48c72..086e2e7e3 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -74,10 +74,11 @@ class Request extends RequestAbstract */ public function __construct(Localization $l11n = null, UriInterface $uri = null) { - $this->l11n = $l11n; - $this->uri = $uri; - $this->source = RequestSource::WEB; $this->header = new Header(); + $this->header->setL11n($l11n); + + $this->uri = $uri; + $this->source = RequestSource::WEB; $this->init(); } @@ -110,7 +111,7 @@ class Request extends RequestAbstract * * This is used in order to either initialize the current http request or a batch of GET requests * - * @param mixed $uri URL + * @param void * * @return void * @@ -143,7 +144,7 @@ class Request extends RequestAbstract $this->uri = new Http(Http::getCurrent()); $this->data = $_GET ?? []; $this->files = $_FILES ?? []; - $this->language = $this->loadRequestLanguage(); + $this->header->getL11n()->setLanguage($this->loadRequestLanguage()); if (isset($_SERVER['CONTENT_TYPE'])) { if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { @@ -204,7 +205,7 @@ class Request extends RequestAbstract */ private function setupUriBuilder() /* : void */ { - UriFactory::setQuery('/lang', $this->l11n->getLanguage()); + UriFactory::setQuery('/lang', $this->header->getL11n()->getLanguage()); // todo: flush previous foreach($this->data as $key => $value) { @@ -212,14 +213,6 @@ class Request extends RequestAbstract } } - /** - * {@inheritdoc} - */ - public function getLanguage() : string - { - return $this->language; - } - /** * Create request hashs of current request * diff --git a/Message/Http/Response.php b/Message/Http/Response.php index 61a895671..426e569c9 100644 --- a/Message/Http/Response.php +++ b/Message/Http/Response.php @@ -50,7 +50,7 @@ class Response extends ResponseAbstract implements RenderableInterface public function __construct(Localization $l11n) { $this->header = new Header(); - $this->l11n = $l11n; + $this->header->setL11n($l11n); } /** diff --git a/Message/ResponseAbstract.php b/Message/ResponseAbstract.php index b1375f5aa..1623b5eb3 100644 --- a/Message/ResponseAbstract.php +++ b/Message/ResponseAbstract.php @@ -15,7 +15,6 @@ declare(strict_types=1); namespace phpOMS\Message; -use phpOMS\Localization\Localization; use phpOMS\Utils\ArrayUtils; /** diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index 05678fc14..8dbf6e88b 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -137,7 +137,7 @@ class InstallerAbstract /** * Init routes. * - * @param string $routePath Route Path + * @param string $modulePath Path to the module * @param InfoManager $info Module info * * @return void diff --git a/Module/ModuleManager.php b/Module/ModuleManager.php index e6235cfb9..fd508980a 100644 --- a/Module/ModuleManager.php +++ b/Module/ModuleManager.php @@ -96,6 +96,7 @@ class ModuleManager * Constructor. * * @param ApplicationAbstract $app Application + * @param string $modulePath Path to modules * * @since 1.0.0 */ diff --git a/Stdlib/Base/Iban.php b/Stdlib/Base/Iban.php index 9fc49b8b8..917cece85 100644 --- a/Stdlib/Base/Iban.php +++ b/Stdlib/Base/Iban.php @@ -25,8 +25,6 @@ use phpOMS\Validation\Finance\IbanEnum; * @license OMS License 1.0 * @link http://orange-management.com * @since 1.0.0 - * - * @todo : there is a bug with Hungary ibans since they have two k (checksums) in their definition */ class Iban implements \Serializable { diff --git a/Stdlib/Base/Location.php b/Stdlib/Base/Location.php index 38d421a78..c26de4f17 100644 --- a/Stdlib/Base/Location.php +++ b/Stdlib/Base/Location.php @@ -101,6 +101,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get location id + * * @return int * * @since 1.0.0 @@ -111,6 +113,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get location type + * * @return int * * @since 1.0.0 @@ -120,12 +124,23 @@ class Location implements \JsonSerializable, \Serializable return $this->type; } + /** + * Set location type + * + * @param int $type Location type + * + * @return void + * + * @since 1.0.0 + */ public function setType(int $type) /* : void */ { $this->type = $type; } /** + * Get postal or zip code + * * @return string * * @since 1.0.0 @@ -136,6 +151,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Set postal or zip code + * * @param string $postal * * @return void @@ -148,6 +165,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get city name + * * @return string * * @since 1.0.0 @@ -158,6 +177,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Set city name + * * @param string $city * * @return void @@ -170,6 +191,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get country code + * * @return string * * @since 1.0.0 @@ -180,6 +203,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Set country code + * * @param string $country * * @return void @@ -192,6 +217,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get address + * * @return string * * @since 1.0.0 @@ -202,6 +229,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Set address + * * @param string $address * * @return void @@ -214,6 +243,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get state name + * * @return string * * @since 1.0.0 @@ -224,6 +255,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Set state name + * * @param string $state * * @return void @@ -236,6 +269,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Get geo location + * * @return float[] * * @since 1.0.0 @@ -246,6 +281,8 @@ class Location implements \JsonSerializable, \Serializable } /** + * Set geo location + * * @param float[] $geo * * @return void diff --git a/Stdlib/Base/SmartDateTime.php b/Stdlib/Base/SmartDateTime.php index d11778478..bcba717e2 100644 --- a/Stdlib/Base/SmartDateTime.php +++ b/Stdlib/Base/SmartDateTime.php @@ -63,7 +63,7 @@ class SmartDateTime extends \DateTime * * @since 1.0.0 */ - public static function createFromDateTime(\Datetime $date) : SmartDateTime + public static function createFromDateTime(\DateTime $date) : SmartDateTime { return new self($date->format('Y-m-d H:i:s'), $date->getTimezone()); } @@ -192,6 +192,8 @@ class SmartDateTime extends \DateTime /** * Test year if leap year in gregorian calendar * + * @param int $year Year to check + * * @return bool * * @since 1.0.0 diff --git a/System/File/FileUtils.php b/System/File/FileUtils.php index 4819bb5b9..97f4df391 100644 --- a/System/File/FileUtils.php +++ b/System/File/FileUtils.php @@ -36,11 +36,25 @@ class FileUtils /* public */ const SPREADSHEET_EXTENSION = ['xls', 'xlsm']; /* public */ const IMAGE_EXTENSION = ['png', 'gif', 'jpg', 'jpeg', 'tiff', 'bmp']; + /** + * Constructor. + * + * @since 1.0.0 + */ private function __construct() { } + /** + * Get file extension type. + * + * @param string $extension Extension string + * + * @return int Extension type + * + * @since 1.0.0 + */ public static function getExtensionType(string $extension) : int { $extension = strtolower($extension); diff --git a/System/File/Storage.php b/System/File/Storage.php index 6807dbd39..17a4f52e8 100644 --- a/System/File/Storage.php +++ b/System/File/Storage.php @@ -73,6 +73,7 @@ final class Storage $env = __NAMESPACE__ . '\\' . $env . '\\' . $env . 'Storage'; try { + /** @var StorageAbstract $env */ $env = $env::getInstance(); self::$registered[$stg] = $env; diff --git a/System/File/StorageAbstract.php b/System/File/StorageAbstract.php index d1fb38838..1445cd7b4 100644 --- a/System/File/StorageAbstract.php +++ b/System/File/StorageAbstract.php @@ -52,7 +52,10 @@ abstract class StorageAbstract implements DirectoryInterface, FileInterface * * @since 1.0.0 */ - abstract public static function getInstance() : StorageAbstract; + public static function getInstance() : StorageAbstract + { + return null; + } /** * Get storage type. * diff --git a/UnhandledHandler.php b/UnhandledHandler.php index 414152c13..3babe913a 100644 --- a/UnhandledHandler.php +++ b/UnhandledHandler.php @@ -60,12 +60,21 @@ final class UnhandledHandler */ public static function errorHandler(int $errno, string $errstr, string $errfile, int $errline) : bool { + $logger = FileLogger::getInstance(__DIR__ . '/../Logs'); + if (!(error_reporting() & $errno)) { - // This error code is not included in error_reporting + $logger->error(FileLogger::MSG_FULL, [ + 'message' => 'Undefined error', + 'line' => $errline, + 'file' => $errfile, + ]); + + error_clear_last(); + return false; } - $logger = FileLogger::getInstance(__DIR__ . '/../Logs'); + $logger->error(FileLogger::MSG_FULL, [ 'message' => 'Unhandled error', 'line' => $errline, diff --git a/Uri/Http.php b/Uri/Http.php index b05155738..bc305030a 100644 --- a/Uri/Http.php +++ b/Uri/Http.php @@ -158,7 +158,7 @@ class Http implements UriInterface $this->path = substr($this->path, 0, -4); } - $this->path = strpos($this->path, $this->rootPath) === 0 ? substr($this->path, strlen($this->rootPath), strlen($this->path)) : $this->path; // TODO: this could cause a bug if the rootpath is the same as a regular path which is usually the language + $this->path = strpos($this->path, $this->rootPath) === 0 ? substr($this->path, strlen($this->rootPath), strlen($this->path)) : $this->path; $this->queryString = $url['query'] ?? ''; if (!empty($this->queryString)) { @@ -286,6 +286,9 @@ class Http implements UriInterface return explode('/', $this->path)[$pos]; } + /** + * {@inheritdoc} + */ public function getPathElements() : array { return explode('/', $this->path); diff --git a/Uri/UriInterface.php b/Uri/UriInterface.php index a1e980979..50617e95c 100644 --- a/Uri/UriInterface.php +++ b/Uri/UriInterface.php @@ -103,6 +103,15 @@ interface UriInterface */ public function getPathElement(int $pos) : string; + /** + * Get path elements. + * + * @return array + * + * @since 1.0.0 + */ + public function getPathElements() : array; + /** * Get query. * diff --git a/Utils/EDI/AnsiX12/FunctionalGroupHeader.php b/Utils/EDI/AnsiX12/FunctionalGroupHeader.php index 283d6405a..d5a2b585a 100644 --- a/Utils/EDI/AnsiX12/FunctionalGroupHeader.php +++ b/Utils/EDI/AnsiX12/FunctionalGroupHeader.php @@ -150,7 +150,7 @@ class FunctionalGroupHedaer public function serialize() { return $this->functionalGroupHeader . '*' - . $this->getfunctionalIdentifierCode() . '*' + . $this->getFunctionalIdentifierCode() . '*' . $this->getApplicationSenderCode() . '*' . $this->getApplicationReceiverCode() . '*' . $this->getDate() . '*' diff --git a/Utils/EDI/AnsiX12/InterchangeControlHeader.php b/Utils/EDI/AnsiX12/InterchangeControlHeader.php index a06f6c69e..fcfd74f95 100644 --- a/Utils/EDI/AnsiX12/InterchangeControlHeader.php +++ b/Utils/EDI/AnsiX12/InterchangeControlHeader.php @@ -417,7 +417,7 @@ class InterchangeControlHeader $this->setInterchangeIdQualifier((int) trim($split[5])); $this->setInterchangeSender(trim($split[6])); $this->setInterchangeReceiver(trim($split[8])); - $this->setInterchangeDateTime(new \DateTime(trim($split[9]) . '-' . trim($split[10]))); + $this->setInterchangeDatetime(new \DateTime(trim($split[9]) . '-' . trim($split[10]))); $this->setInterchangeControlStandardId(trim($split[11])); $this->setInterchangeControlVersionNumber((int) trim($split[12])); $this->setInterchangeControlNumber((int) trim($split[13])); diff --git a/Utils/Encoding/Caesar.php b/Utils/Encoding/Caesar.php index 07457d4e1..bcb44d23b 100644 --- a/Utils/Encoding/Caesar.php +++ b/Utils/Encoding/Caesar.php @@ -37,7 +37,7 @@ class Caesar /** * ASCII upper char limit. * - * @var string + * @var int * @since 1.0.0 */ /* public */ const LIMIT_UPPER = 127; diff --git a/Utils/IO/Zip/Gz.php b/Utils/IO/Zip/Gz.php index b131c0541..8dbc19300 100644 --- a/Utils/IO/Zip/Gz.php +++ b/Utils/IO/Zip/Gz.php @@ -29,7 +29,7 @@ class Gz implements ArchiveInterface /** * {@inheritdoc} */ - public static function pack(string $source, string $destination, bool $overwrite = true) : bool + public static function pack($source, string $destination, bool $overwrite = true) : bool { $destination = str_replace('\\', '/', realpath($destination)); if (!$overwrite && file_exists($destination)) { @@ -56,7 +56,7 @@ class Gz implements ArchiveInterface public static function unpack(string $source, string $destination) : bool { $destination = str_replace('\\', '/', realpath($destination)); - if (!$overwrite && file_exists($destination)) { + if (file_exists($destination)) { return false; } @@ -65,8 +65,8 @@ class Gz implements ArchiveInterface } $dest = fopen($destination, 'w'); - while (!gzeof($handle)) { - fwrite($dest, gzread($handle, 4096)); + while (!gzeof($gz)) { + fwrite($dest, gzread($gz, 4096)); } fclose($dest); diff --git a/Utils/IO/Zip/Tar.php b/Utils/IO/Zip/Tar.php index 9b92b52a4..1bbcf4890 100644 --- a/Utils/IO/Zip/Tar.php +++ b/Utils/IO/Zip/Tar.php @@ -29,7 +29,7 @@ class Tar implements ArchiveInterface /** * {@inheritdoc} */ - public static function pack(array $source, string $destination, bool $overwrite = true) : bool + public static function pack($sources, string $destination, bool $overwrite = true) : bool { $destination = str_replace('\\', '/', realpath($destination)); @@ -37,6 +37,7 @@ class Tar implements ArchiveInterface return false; } + /** @var array $sources */ foreach ($sources as $source) { $source = str_replace('\\', '/', realpath($source)); diff --git a/Utils/IO/Zip/TarGz.php b/Utils/IO/Zip/TarGz.php index 7e90813f6..dc4f2ca88 100644 --- a/Utils/IO/Zip/TarGz.php +++ b/Utils/IO/Zip/TarGz.php @@ -29,7 +29,7 @@ class TarGz implements ArchiveInterface /** * {@inheritdoc} */ - public static function pack(array $source, string $destination, bool $overwrite = true) : bool + public static function pack($source, string $destination, bool $overwrite = true) : bool { if(!Tar::pack($source, $destination . '.tmp', $overwrite)) { return false; diff --git a/Utils/IO/Zip/Zip.php b/Utils/IO/Zip/Zip.php index 17f8cfbb6..e06889b06 100644 --- a/Utils/IO/Zip/Zip.php +++ b/Utils/IO/Zip/Zip.php @@ -32,7 +32,7 @@ class Zip implements ArchiveInterface /** * {@inheritdoc} */ - public static function pack(array $sources, string $destination, bool $overwrite = true) : bool + public static function pack($sources, string $destination, bool $overwrite = true) : bool { $destination = str_replace('\\', '/', realpath($destination)); @@ -45,6 +45,7 @@ class Zip implements ArchiveInterface return false; } + /** @var array $sources */ foreach ($sources as $source) { $source = str_replace('\\', '/', realpath($source)); diff --git a/Utils/JobQueue/JobQueue.php b/Utils/JobQueue/JobQueue.php index c75c88701..0ac7b16d0 100644 --- a/Utils/JobQueue/JobQueue.php +++ b/Utils/JobQueue/JobQueue.php @@ -57,7 +57,7 @@ class JobQueue $this->runAsDeamon(); if (posix_setsid() < 0 || $pid = pcntl_fork()) { - return; + return 0; } } diff --git a/Utils/StringCompare.php b/Utils/StringCompare.php index c78fa86db..810ea64f7 100644 --- a/Utils/StringCompare.php +++ b/Utils/StringCompare.php @@ -62,7 +62,7 @@ class StringCompare $bestScore = PHP_INT_MAX; $bestMatch = ''; - foreach($dictionary as $word) { + foreach($this->dictionary as $word) { $score = self::fuzzyMatch($word, $match); if($score < $bestScore) { @@ -145,7 +145,7 @@ class StringCompare * * @param string $s1 Word 1 * @param string $s2 Word 2 - * @param float $prhaseWeight Weighting for phrase score + * @param float $phraseWeight Weighting for phrase score * @param float $wordWeight Weighting for word score * @param float $minWeight Min weight * @param float $maxWeight Max weight @@ -157,9 +157,9 @@ class StringCompare */ public static function fuzzyMatch(string $s1, string $s2, float $phraseWeight = 0.5, float $wordWeight = 1, float $minWeight = 10, float $maxWeight = 1, float $lengthWeight = -0.3) : float { - $phraseValue = valuePhrase($s1, $s2); - $wordValue = valueWords($s1, $s2); - $lengthValue = valueLength($s1, $s2); + $phraseValue = self::valuePhrase($s1, $s2); + $wordValue = self::valueWords($s1, $s2); + $lengthValue = self::valueLength($s1, $s2); return min($phraseValue * $phraseWeight, $wordValue * $wordWeight) * $minWeight + max($phraseValue * $phraseWeight, $wordValue * $wordWeight) * $maxWeight diff --git a/Utils/StringUtils.php b/Utils/StringUtils.php index dcc3a2ce7..67de10468 100644 --- a/Utils/StringUtils.php +++ b/Utils/StringUtils.php @@ -349,7 +349,7 @@ class StringUtils /** * Calculate string entropy * - * @param string $string String to analyze. + * @param string $value String to analyze. * * @return float * @@ -359,10 +359,10 @@ class StringUtils { $entroy = 0.0; $size = mb_strlen($value); - $countChars = self::mb_count_chars($value, 1); + $countChars = self::mb_count_chars($value); - foreach ($countChars as $v) { - $p = $v / $size; + for ($i = 0; $i < $countChars; $i++) { + $p = $value[$i] / $size; $entroy -= $p * log($p) / log(2); } @@ -372,13 +372,14 @@ class StringUtils /** * Count chars of utf-8 string. * - * @param string $string String to count chars. + * @param string $input String to count chars. * * @return int * * @since 1.0.0 */ - public static function mb_count_chars(string $input) { + public static function mb_count_chars(string $input) : int + { $l = mb_strlen($input, 'UTF-8'); $unique = []; diff --git a/Utils/TestUtils.php b/Utils/TestUtils.php index 2bbb4f7c5..4095bbd37 100644 --- a/Utils/TestUtils.php +++ b/Utils/TestUtils.php @@ -29,7 +29,7 @@ class TestUtils /** * Set private object member * - * @param object $object Object to modify + * @param object $obj Object to modify * @param string $name Member name to modify * @param mixed $value Value to set * @@ -63,7 +63,7 @@ class TestUtils /** * Get private object member * - * @param object $object Object to read + * @param object $obj Object to read * @param string $name Member name to read * * @return mixed Returns the member variable value diff --git a/Validation/Finance/Iban.php b/Validation/Finance/Iban.php index 9095b3b87..a7db7f591 100644 --- a/Validation/Finance/Iban.php +++ b/Validation/Finance/Iban.php @@ -39,11 +39,7 @@ abstract class Iban extends ValidatorAbstract } /** - * @param string $value Iban to validate - * - * @return bool - * - * @since 1.0.0 + * {@inheritdoc} */ public static function isValid($value, array $constraints = null) : bool { diff --git a/Validation/Network/Ip.php b/Validation/Network/Ip.php index 4a1788b9a..67cb3a2e0 100644 --- a/Validation/Network/Ip.php +++ b/Validation/Network/Ip.php @@ -46,11 +46,29 @@ class Ip extends ValidatorAbstract return filter_var($value, FILTER_VALIDATE_IP) !== false; } + /** + * Validate IPv6 + * + * @param mixed $value to validate + * + * @return bool + * + * @since 1.0.0 + */ public static function isValidIpv6($value) : bool { return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false; } + /** + * Validate IPv4 + * + * @param mixed $value to validate + * + * @return bool + * + * @since 1.0.0 + */ public static function isValidIpv4($value) : bool { return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; diff --git a/Validation/ValidatorAbstract.php b/Validation/ValidatorAbstract.php index 4f4ef5d85..2258eca5c 100644 --- a/Validation/ValidatorAbstract.php +++ b/Validation/ValidatorAbstract.php @@ -59,6 +59,13 @@ abstract class ValidatorAbstract implements ValidatorInterface return self::$error; } + /** + * Reset error information + * + * @return bool + * + * @since 1.0.0 + */ public static function resetError() /* : void */ { self::$error = 0; diff --git a/Views/View.php b/Views/View.php index 678ce9b3e..f03449053 100644 --- a/Views/View.php +++ b/Views/View.php @@ -164,7 +164,7 @@ class View extends ViewAbstract * @return string * * @throws InvalidModuleException Throws this exception if no data for the defined module could be found. - * @throws InvalidTemplateException Throws this exception if no data for the defined theme could be found. + * @throws InvalidThemeException Throws this exception if no data for the defined theme could be found. * * @since 1.0.0 */ diff --git a/Views/ViewAbstract.php b/Views/ViewAbstract.php index cf962f605..93005ba94 100644 --- a/Views/ViewAbstract.php +++ b/Views/ViewAbstract.php @@ -171,7 +171,7 @@ abstract class ViewAbstract implements \Serializable * @param int $order Order of view * @param bool $overwrite Overwrite existing view * - * @return void + * @return bool * * @since 1.0.0 */ @@ -231,16 +231,16 @@ abstract class ViewAbstract implements \Serializable /** * Get view/template response. * - * @return string|array + * @param array $data Data to pass to renderer + * + * @return array|string * * @since 1.0.0 */ public function render(...$data) { - $ob = ''; - - - $path = __DIR__ . '/../..' . $this->template . '.tpl.php'; + $ob = ''; + $path = __DIR__ . '/../..' . $this->template . '.tpl.php'; if (!file_exists($path)) { throw new PathException($path);