Merge pull request #124 from Orange-Management/develop

Semi stable stage
This commit is contained in:
Dennis Eichhorn 2017-10-20 20:01:17 +02:00 committed by GitHub
commit 7c24bdbbcc
183 changed files with 5317 additions and 2327 deletions

View File

@ -21,7 +21,10 @@ use phpOMS\Localization\NullLocalization;
use phpOMS\Validation\Network\Email;
/**
* Account manager class.
* Account class.
*
* The account class is the base model for accounts. This model contains the most common account
* information. This model is not comparable to a profile which contains much more information.
*
* @category Framework
* @package phpOMS\Account
@ -109,7 +112,7 @@ class Account implements ArrayableInterface, \JsonSerializable
/**
* Permissions.
*
* @var array
* @var PermissionAbstract[]
* @since 1.0.0
*/
protected $permissions = [];
@ -125,7 +128,7 @@ class Account implements ArrayableInterface, \JsonSerializable
/**
* Password.
*
* @var Password
* @var string
* @since 1.0.0
*/
protected $password = '';
@ -156,6 +159,8 @@ class Account implements ArrayableInterface, \JsonSerializable
/**
* Constructor.
*
* The constructor automatically sets the created date as well as the last activity to now.
*
* @param int $id Account id
*
@ -183,6 +188,8 @@ class Account implements ArrayableInterface, \JsonSerializable
/**
* Get localization.
*
* Every account can have a different localization which can be accessed here.
*
* @return Localization
*
@ -193,6 +200,35 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->l11n;
}
/**
* Get groups.
*
* Every account can belong to multiple groups.
* These groups usually are used for permissions and categorize accounts.
*
* @return array Returns array of all groups
*
* @since 1.0.0
*/
public function getGroups() : array
{
return $this->groups;
}
/**
* Add group.
*
* @param mixed $group Group to add
*
* @return void
*
* @since 1.0.0
*/
public function addGroup($group) /* : void */
{
$this->groups[] = $group;
}
/**
* Set localization.
*
@ -207,6 +243,102 @@ class Account implements ArrayableInterface, \JsonSerializable
$this->l11n = $l11n;
}
/**
* Set permissions.
*
* The method accepts an array of permissions. All existing permissions are replaced.
*
* @param PermissionAbstract[] $permissions
*
* @return void
*
* @since 1.0.0
*/
public function setPermissions(array $permissions) /* : void */
{
$this->permissions = $permissions;
}
/**
* Add permissions.
*
* Adds permissions to the account
*
* @param PermissionAbstract[] $permissions Array of permissions to add to the account
*
* @return void
*
* @since 1.0.0
*/
public function addPermissions(array $permissions) /* : void */
{
$this->permissions = array_merge($this->permissions, $permissions);
}
/**
* Add permission.
*
* Adds a single permission to the account
*
* @param PermissionAbstract $permission Permission to add to the account
*
* @return void
*
* @since 1.0.0
*/
public function addPermission(PermissionAbstract $permission) /* : void */
{
$this->permissions[] = $permission;
}
/**
* Get permissions.
*
* @return array
*
* @since 1.0.0
*/
public function getPermissions() : array
{
return $this->permissions;
}
/**
* Has permissions.
*
* Checks if the account has a permission defined
*
* @param int $permission Permission to check
* @param int $unit Unit Unit to check (null if all are acceptable)
* @param string $app App App to check (null if all are acceptable)
* @param int $module Module Module to check (null if all are acceptable)
* @param int $type Type (e.g. customer) (null if all are acceptable)
* @param int $element (e.g. customer id) (null if all are acceptable)
* @param int $component (e.g. address) (null if all are acceptable)
*
* @return bool Returns true if the account has the permission, false otherwise
*
* @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
{
$app = isset($app) ? strtolower($app) : $app;
foreach($this->permissions as $p) {
if(($p->getUnit() === $unit || $p->getUnit() === null || !isset($unit))
&& ($p->getApp() === $app || $p->getApp() === null || !isset($app))
&& ($p->getModule() === $module || $p->getModule() === null || !isset($module))
&& ($p->getType() === $type || $p->getType() === null || !isset($type))
&& ($p->getElement() === $element || $p->getElement() === null || !isset($element))
&& ($p->getComponent() === $component || $p->getComponent() === null || !isset($component))
&& ($p->getPermission() | $permission) === $p->getPermission()) {
return true;
}
}
return false;
}
/**
* Get name.
*
@ -231,6 +363,20 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->name1;
}
/**
* Set name1.
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName1(string $name) /* : void */
{
$this->name1 = $name;
}
/**
* Get name2.
*
@ -243,6 +389,20 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->name2;
}
/**
* Set name2.
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName2(string $name) /* : void */
{
$this->name2 = $name;
}
/**
* Get name3.
*
@ -255,6 +415,20 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->name3;
}
/**
* Set name3.
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName3(string $name) /* : void */
{
$this->name3 = $name;
}
/**
* Get email.
*
@ -267,6 +441,26 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->email;
}
/**
* Set email.
*
* @param string $email Email
*
* @return void
*
* @throws \InvalidArgumentException Exception is thrown if the provided string is not a valid email
*
* @since 1.0.0
*/
public function setEmail(string $email) /* : void */
{
if (!Email::isValid($email)) {
throw new \InvalidArgumentException();
}
$this->email = mb_strtolower($email);
}
/**
* Get status.
*
@ -281,6 +475,24 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->status;
}
/**
* Get status.
*
* @param int $status Status
*
* @return void
*
* @since 1.0.0
*/
public function setStatus(int $status) /* : void */
{
if (!AccountStatus::isValidValue($status)) {
throw new \InvalidArgumentException();
}
$this->status = $status;
}
/**
* Get type.
*
@ -295,6 +507,24 @@ class Account implements ArrayableInterface, \JsonSerializable
return $this->type;
}
/**
* Get type.
*
* @param int $type Type
*
* @return void
*
* @since 1.0.0
*/
public function setType(int $type) /* : void */
{
if (!AccountType::isValidValue($type)) {
throw new \InvalidArgumentException();
}
$this->type = $type;
}
/**
* Get last activity.
*
@ -347,102 +577,6 @@ class Account implements ArrayableInterface, \JsonSerializable
$this->login = $name;
}
/**
* Set name1.
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName1(string $name) /* : void */
{
$this->name1 = $name;
}
/**
* Set name2.
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName2(string $name) /* : void */
{
$this->name2 = $name;
}
/**
* Set name3.
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName3(string $name) /* : void */
{
$this->name3 = $name;
}
/**
* Set email.
*
* @param string $email Email
*
* @return void
*
* @since 1.0.0
*/
public function setEmail(string $email) /* : void */
{
if (!Email::isValid($email)) {
throw new \InvalidArgumentException();
}
$this->email = mb_strtolower($email);
}
/**
* Get status.
*
* @param int $status Status
*
* @return void
*
* @since 1.0.0
*/
public function setStatus(int $status) /* : void */
{
if (!AccountStatus::isValidValue($status)) {
throw new \InvalidArgumentException();
}
$this->status = $status;
}
/**
* Get type.
*
* @param int $type Type
*
* @return void
*
* @since 1.0.0
*/
public function setType(int $type) /* : void */
{
if (!AccountType::isValidValue($type)) {
throw new \InvalidArgumentException();
}
$this->type = $type;
}
/**
* Update last activity.
*
@ -455,6 +589,18 @@ class Account implements ArrayableInterface, \JsonSerializable
$this->lastActive = new \DateTime('NOW');
}
/**
* Get string representation.
*
* @return string
*
* @since 1.0.0
*/
public function __toString()
{
return json_encode($this->toArray());
}
/**
* {@inheritdoc}
*/
@ -476,18 +622,6 @@ class Account implements ArrayableInterface, \JsonSerializable
];
}
/**
* Get string representation.
*
* @return string
*
* @since 1.0.0
*/
public function __toString()
{
return json_encode($this->toArray());
}
/**
* Json serialize.
*

View File

@ -21,6 +21,8 @@ use phpOMS\DataStorage\Session\SessionInterface;
/**
* Account manager class.
*
* The account manager is used to manage multiple accounts.
*
* @category Framework
* @package phpOMS\Account
@ -47,14 +49,6 @@ class AccountManager implements \Countable
*/
private $session = null;
/**
* Database connection instance.
*
* @var ConnectionAbstract
* @since 1.0.0
*/
private $connection = null;
/**
* Authenticator.
*
@ -66,16 +60,14 @@ class AccountManager implements \Countable
/**
* Constructor.
*
* @param ConnectionAbstract $connection Database connection
* @param SessionInterface $session Session
*
* @since 1.0.0
*/
public function __construct(ConnectionAbstract $connection, SessionInterface $session)
public function __construct(SessionInterface $session)
{
$this->connection = $connection;
$this->session = $session;
$this->auth = new Auth($this->connection, $this->session);
$this->auth = new Auth($this->session);
}
/**
@ -102,6 +94,18 @@ class AccountManager implements \Countable
return $this->accounts[$id] ?? new NullAccount();
}
/**
* Returns the authentication manager
*
* @return Auth
*
* @since 1.0.0
*/
public function getAuth() : Auth
{
return $this->auth;
}
/**
* Add account.
*

View File

@ -28,8 +28,8 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class AccountStatus extends Enum
{
/* public */ const ACTIVE = 1;
/* public */ const INACTIVE = 2;
/* public */ const TIMEOUT = 3;
/* public */ const BANNED = 4;
/* public */ const ACTIVE = 1;
/* public */ const INACTIVE = 2;
/* public */ const TIMEOUT = 3;
/* public */ const BANNED = 4;
}

View File

@ -21,13 +21,13 @@ use phpOMS\Stdlib\Base\Enum;
* Account type enum.
*
* @category Framework
* @package phpOMS\DataStorage\Database
* @package phpOMS\Account
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
abstract class AccountType extends Enum
{
/* public */ const USER = 0;
/* public */ const GROUP = 1;
/* public */ const USER = 0;
/* public */ const GROUP = 1;
}

View File

@ -191,18 +191,6 @@ class Group implements ArrayableInterface, \JsonSerializable
return json_encode($this->toArray());
}
/**
* Json serialize.
*
* @return string
*
* @since 1.0.0
*/
public function jsonSerialize()
{
return $this->toArray();
}
/**
* {@inheritdoc}
*/
@ -216,4 +204,16 @@ class Group implements ArrayableInterface, \JsonSerializable
'members' => $this->members,
];
}
/**
* Json serialize.
*
* @return string
*
* @since 1.0.0
*/
public function jsonSerialize()
{
return $this->toArray();
}
}

View File

@ -20,17 +20,15 @@ use phpOMS\Stdlib\Base\Enum;
/**
* Accept status enum.
*
* @category Calendar
* @package Modules
* @category Framework
* @package phpOMS\Account
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
abstract class GroupStatus extends Enum
{
/* public */ const ACTIVE = 1;
/* public */ const INACTIVE = 2;
/* public */ const HIDDEN = 4;
/* public */ const ACTIVE = 1;
/* public */ const INACTIVE = 2;
/* public */ const HIDDEN = 4;
}

View File

@ -0,0 +1,351 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Account;
/**
* Permission class.
*
* This permission abstract is the basis for all permissions. Contrary to it's name it is not an
* abstract class and can be used directly if needed.
*
* @category Framework
* @package phpOMS\Account
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
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;
/**
* Permission.
*
* @var int
* @since 1.0.0
*/
protected $permission = PermissionType::NONE;
/**
* Get permission id.
*
* @return int
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
/**
* Get unit id.
*
* @return int
*
* @since 1.0.0
*/
public function getUnit() /* : ?int */
{
return $this->unit;
}
/**
* Set unit id.
*
* @param int $unit Unit
*
* @return void
*
* @since 1.0.0
*/
public function setUnit(int $unit = null) /* : void */
{
$this->unit = $unit;
}
/**
* Get app name.
*
* @return string
*
* @since 1.0.0
*/
public function getApp() /* : ?string */
{
return $this->app;
}
/**
* Set app name.
*
* @param string $app App name
*
* @return void
*
* @since 1.0.0
*/
public function setApp(string $app = null) /* : void */
{
$this->app = $app;
}
/**
* Get module id.
*
* @return int
*
* @since 1.0.0
*/
public function getModule() /* : ?int */
{
return $this->module;
}
/**
* Set module id.
*
* @param int $module Module
*
* @return void
*
* @since 1.0.0
*/
public function setModule(int $module = null) /* : void */
{
$this->module = $module;
}
/**
* Get providing module id.
*
* @return int
*
* @since 1.0.0
*/
public function getFrom() /* : ?int */
{
return $this->from;
}
/**
* 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;
}
/**
* Get type.
*
* @return int
*
* @since 1.0.0
*/
public function getType() /* : ?int */
{
return $this->type;
}
/**
* Set type.
*
* @param int $type Type
*
* @return void
*
* @since 1.0.0
*/
public function setType(int $type = null) /* : void */
{
$this->type = $type;
}
/**
* Get element id.
*
* @return int
*
* @since 1.0.0
*/
public function getElement() /* : ?int */
{
return $this->element;
}
/**
* Set element id.
*
* @param int $element Element id
*
* @return void
*
* @since 1.0.0
*/
public function setElement(int $element = null) /* : void */
{
$this->element = $element;
}
/**
* Get component id.
*
* @return int
*
* @since 1.0.0
*/
public function getComponent() /* : ?int */
{
return $this->component;
}
/**
* Set component id.
*
* @param int $component Component
*
* @return void
*
* @since 1.0.0
*/
public function setComponent(int $component = null) /* : void */
{
$this->component = $component;
}
/**
* Get permission
*
* @return int
*
* @since 1.0.0
*/
public function getPermission() : int
{
return $this->permission;
}
/**
* Set permission.
*
* @param int $permission Permission
*
* @return void
*
* @since 1.0.0
*/
public function setPermission(int $permission = 0) /* : void */
{
$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;
}
/**
* Has permission.
*
* @param int $permission Permission
*
* @return void
*
* @since 1.0.0
*/
public function hasPermission(int $permission) : bool
{
return ($this->permission | $permission) === $this->permission;
}
}

View File

@ -0,0 +1,37 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @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\Account
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
abstract class PermissionType extends Enum
{
/* public */ const NONE = 1;
/* public */ const READ = 2;
/* public */ const CREATE = 4;
/* public */ const MODIFY = 8;
/* public */ const DELETE = 16;
/* public */ const PERMISSION = 32;
}

View File

@ -35,14 +35,6 @@ class ApplicationAbstract
*/
protected $appName = '';
/**
* Config.
*
* @var array
* @since 1.0.0
*/
protected $config = [];
/**
* Database object.
*
@ -153,7 +145,7 @@ class ApplicationAbstract
*/
public function __set($name, $value)
{
if(!empty($this->$name) || $name === 'config') {
if(!empty($this->$name)) {
return;
}
@ -173,10 +165,6 @@ class ApplicationAbstract
*/
public function __get($name)
{
if($name === 'config') {
return [];
}
return $this->$name;
}
}

View File

@ -28,7 +28,7 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class AssetType extends Enum
{
/* public */ const CSS = 0;
/* public */ const JS = 1;
/* public */ const JSLATE = 2;
/* public */ const CSS = 0;
/* public */ const JS = 1;
/* public */ const JSLATE = 2;
}

View File

@ -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;
/**
@ -40,26 +39,16 @@ class Auth
*/
private $session = null;
/**
* Database connection instance.
*
* @var ConnectionAbstract
* @since 1.0.0
*/
private $connection = null;
/**
* Constructor.
*
* @param ConnectionAbstract $connection Database connection
* @param SessionInterface $session Session
*
* @since 1.0.0
*/
public function __construct(ConnectionAbstract $connection, SessionInterface $session)
public function __construct(SessionInterface $session)
{
$this->connection = $connection;
$this->session = $session;
$this->session = $session;
}
/**
@ -73,11 +62,7 @@ class Auth
{
$uid = $this->session->get('UID');
if (empty($uid)) {
return 0;
}
return $uid;
return empty($uid) ? 0 : $uid;
}
/**

View File

@ -30,14 +30,14 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class LoginReturnType extends Enum
{
/* public */ const OK = 0; /* Everything is ok and the user got authed */
/* public */ const FAILURE = -1; /* Authentication resulted in a unexpected failure */
/* public */ const WRONG_PASSWORD = -2; /* Authentication with wrong password */
/* public */ const WRONG_USERNAME = -3; /* Authentication with unknown user */
/* public */ const WRONG_PERMISSION = -4; /* User doesn't have permission to authenticate */
/* public */ const NOT_ACTIVATED = -5; /* The user is not activated yet */
/* public */ const OK = 0; /* Everything is ok and the user got authed */
/* public */ const FAILURE = -1; /* Authentication resulted in a unexpected failure */
/* public */ const WRONG_PASSWORD = -2; /* Authentication with wrong password */
/* public */ const WRONG_USERNAME = -3; /* Authentication with unknown user */
/* public */ const WRONG_PERMISSION = -4; /* User doesn't have permission to authenticate */
/* public */ const NOT_ACTIVATED = -5; /* The user is not activated yet */
/* public */ const WRONG_INPUT_EXCEEDED = -6; /* Too many wrong logins recently */
/* public */ const TIMEOUTED = -7; /* User received a timeout and can not log in until a certain date */
/* public */ const BANNED = -8; /* User is banned */
/* public */ const INACTIVE = -9; /* User is inactive */
/* public */ const TIMEOUTED = -7; /* User received a timeout and can not log in until a certain date */
/* public */ const BANNED = -8; /* User is banned */
/* public */ const INACTIVE = -9; /* User is inactive */
}

View File

@ -17,5 +17,51 @@ namespace phpOMS\Business\Finance;
class Depreciation
{
public static function getLinearDepreciationRate(float $start, int $duration) : float
{
return $start / $duration;
}
public static function getLinearDepreciationResidualInT(float $start, int $duration, int $t) : float
{
return $start - self::getLinearDepreciationRate($start, $duration) * $t;
}
public static function getArithmeticProgressivDepreciationRate(float $start, int $duration) : float
{
return $start / ($duration * ($duration+1) / 2);
}
public static function getArithmeticProgressivDepreciationInT(float $start, int $duration, int $t) : float
{
return $t * self::getArithmeticProgressivDepreciationRate($start, $duration);
}
public static function getArithmeticProgressivDepreciationResidualInT(float $start, int $duration, int $t) : float
{
return $start - self::getArithmeticProgressivDepreciationRate($start, $duration) * $t * ($t + 1) / 2;
}
public static function getGeometicProgressivDepreciationRate(float $start, float $residual, int $duration) : float
{
return (1-pow($residual / $start, 1 / $duration));
}
public static function getGeometicDegressivDepreciationInT(float $start, float $residual, int $duration, int $t) : float
{
return $start * (1 - self::getGeometicDegressivDepreciationRate($start, $residual, $duration)) ** $t;
}
public static function getGeometicDegressivDepreciationResidualInT(float $start, float $residual, int $duration, int $t) : float
{
}
public static function getGeometicProgressivDepreciationInT(float $start, float $residual, int $duration, int $t) : float
{
return $start * (1 - self::getGeometicProgressivDepreciationRate($start, $residual, $duration)) ** ($duration - $t + 1);
}
public static function getGeometicProgressivDepreciationResidualInT(float $start, float $residual, int $duration, int $t) : float
{
}
}

View File

@ -1197,14 +1197,14 @@ class FinanceFormulas
/**
* Rate of Inflation
*
* @param float $oldCPI Consumer price index old
* @param float $newCPI Consumer price index new
* @param float $oldCPI Consumer price index old
*
* @return float
*
* @since 1.0.0
*/
public static function getRateOfOnflation(float $oldCPI, float $newCPI) : float
public static function getRateOfOnflation(float $newCPI, float $oldCPI) : float
{
return $newCPI / $oldCPI - 1;
}
@ -1315,6 +1315,54 @@ class FinanceFormulas
return $P * $r * $t;
}
/**
* Simple Interest Rate
*
* @param float $I Interest
* @param float $P Principal
* @param int $t Time
*
* @return float
*
* @since 1.0.0
*/
public static function getSimpleInterestRate(float $I, float $P, int $t) : float
{
return $I / ($P * $t);
}
/**
* Simple Interest Principal
*
* @param float $I Interest
* @param float $r Rate
* @param int $t Time
*
* @return float
*
* @since 1.0.0
*/
public static function getSimpleInterestPrincipal(float $I, float $r, int $t) : float
{
return $I / ($r * $t);
}
/**
* Simple Interest Principal
*
* @param float $I Interest
* @param float $P Principal
* @param float $r Rate
*
* @return int
*
* @since 1.0.0
*/
public static function getSimpleInterestTime(float $I, float $P, float $r) : int
{
return (int) round($I / ($P * $r));
}
/**
* Relative market share by share
*

View File

@ -16,7 +16,9 @@ declare(strict_types=1);
namespace phpOMS\Business\Marketing;
/**
* Net Promoter Score
* Marketing Metrics
*
* This class provided basic marketing metric calculations
*
* @category Framework
* @package phpOMS\Business

View File

@ -17,6 +17,9 @@ namespace phpOMS\Business\Marketing;
/**
* Net Promoter Score
*
* The net promoter score is a basic evaluation of the happiness of customers.
* Instead of customers the NPS can also be transferred to non-customers.
*
* @category Framework
* @package phpOMS\Business
@ -65,8 +68,8 @@ class NetPromoterScore {
*/
public function getScore() : int
{
$promoters = 0;
$passives = 0;
$promoters = 0;
$passives = 0;
$detractors = 0;
foreach($this->scores as $score) {

View File

@ -12,9 +12,13 @@
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Business\Programming;
/**
* Programming metrics
*
* This class provides basic programming metric calculations.
*
* @category Framework
* @package phpOMS\Business
@ -40,4 +44,22 @@ class Metrics {
{
return (int) sqrt($a*$a+$b*$b+$c*$c);
}
/**
* Calculate the C.R.A.P score
*
* @latex r = \sqrt{a^{2} + b^{2} + c^{2}}
*
* @param int $a Assignments
* @param int $b Branches
* @param int $c Conditionals
*
* @return int
*
* @since 1.0.0
*/
public static function CRAP(int $complexity, float $coverage) : int
{
return (int) ($complexity ** 2 * (1 - $coverage) ** 3 + $complexity);
}
}

View File

@ -12,9 +12,14 @@
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Business\Sales;
/**
* Market share calculations (Zipf function)
*
* This class can be used to calculate the market share based on a rank or vice versa
* the rank based on a marketshare in a Zipf distributed market.
*
* @category Framework
* @package phpOMS\Business
@ -24,15 +29,15 @@ namespace phpOMS\Business\Sales;
*/
class MarketShareEstimation {
/**
* Calculate rank (r) based on marketshare (m)
* Calculate rank (r) based on market share (m)
*
* @latex r = \sqrt[s]{\frac{1}{m \times \sum_{n=1}^N{\frac{1}{n^{s}}}}}
*
* @param int $participants (p)
* @param float $marketShare (m)
* @param float $modifier (s)
* @param int $participants The amount of existing participants in the market or compentitors (N)
* @param float $marketShare The absolute own market share (m)
* @param float $modifier Distribution modifier (s)
*
* @return float
* @return int Returns the rank
*
* @since 1.0.0
*/
@ -47,15 +52,15 @@ class MarketShareEstimation {
}
/**
* Calculate marketshare (m) based on rank (r)
* Calculate market share (m) based on rank (r)
*
* @latex m = \frac{\frac{1}{r^{s}}}{\sum_{n=1}^N{\frac{1}{n^{s}}}}
*
* @param int $participants (p)
* @param int $rank (r)
* @param float $modifier (s)
* @param int $participants The amount of existing participants in the market or compentitors (N)
* @param int $rank The absolute own rank in the market (r)
* @param float $modifier Distribution modifier (s)
*
* @return float
* @return float Returns the Market share
*
* @since 1.0.0
*/

View File

@ -104,12 +104,16 @@ class CachePool implements OptionsInterface
*
* @since 1.0.0
*/
public function get(string $key) /* : ?CacheInterface */
public function get(string $key = '') /* : ?CacheInterface */
{
if (!isset($this->pool[$key])) {
if((!empty($key) && !isset($this->pool[$key])) || empty($this->pool)) {
return null;
}
if(empty($key)) {
return reset($this->pool);
}
return $this->pool[$key];
}

View File

@ -83,7 +83,7 @@ class FileCache implements CacheInterface
public function __construct(string $path)
{
if (!Directory::exists(File::parent($path))) {
Directory::create($path);
Directory::create($path, 0664, true);
}
$this->cachePath = realpath($path);

View File

@ -127,9 +127,13 @@ class CookieJar
throw new LockException('CookieJar');
}
setcookie($id, '', time() - 3600);
if(!headers_sent()) {
setcookie($id, '', time() - 3600);
return true;
return true;
}
return false;
}
return false;

View File

@ -110,6 +110,42 @@ abstract class ConnectionAbstract implements ConnectionInterface
return $this->status;
}
/**
* Get database name.
*
* @return string
*
* @since 1.0.0
*/
public function getDatabase() : string
{
return $this->dbdata['database'] ?? '';
}
/**
* Get database host.
*
* @return string
*
* @since 1.0.0
*/
public function getHost() : string
{
return $this->dbdata['host'] ?? '';
}
/**
* Get database port.
*
* @return int
*
* @since 1.0.0
*/
public function getPort() : int
{
return (int) $this->dbdata['port'] ?? 0;
}
/**
* Get table prefix.
*

View File

@ -33,6 +33,7 @@ class ConnectionFactory
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,437 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\DataStorage\Database;
use phpOMS\DataStorage\Database\Connection\ConnectionAbstract;
use phpOMS\DataStorage\Database\Query\Builder;
/**
* Datamapper for databases.
*
* DB, Cache, Session
*
* @category Framework
* @package phpOMS\DataStorage\Database
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
class DataMapperBaseAbstract
{
/**
* Database connection.
*
* @var ConnectionAbstract
* @since 1.0.0
*/
protected static $db = null;
/**
* Overwriting extended values.
*
* @var bool
* @since 1.0.0
*/
protected static $overwrite = true;
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
protected static $primaryField = '';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
protected static $createdAt = '';
/**
* Language
*
* @var string
* @since 1.0.0
*/
protected static $language_field = '';
/**
* Columns.
*
* @var array
* @since 1.0.0
*/
protected static $columns = [];
/**
* Relations.
*
* Relation is defined in a relation table
*
* @var string[]
* @since 1.0.0
*/
protected static $hasMany = [];
/**
* Relations.
*
* Relation is defined in the model
*
* @var string[]
* @since 1.0.0
*/
protected static $hasOne = [];
/**
* Relations.
*
* Relation is defined in current mapper
*
* @var string[]
* @since 1.0.0
*/
protected static $ownsOne = [];
/**
* Relations.
*
* Relation is defined in current mapper
*
* @var string[]
* @since 1.0.0
*/
protected static $belongsTo = [];
/**
* Table.
*
* @var string
* @since 1.0.0
*/
protected static $table = '';
/**
* Fields to load.
*
* @var array[]
* @since 1.0.0
*/
protected static $fields = [];
/**
* Initialized objects for cross reference to reduce initialization costs
*
* @var array[]
* @since 1.0.0
*/
protected static $initObjects = [];
/**
* Highest mapper to know when to clear initialized objects
*
* @var DataMapperAbstract
* @since 1.0.0
*/
protected static $parentMapper = null;
/**
* Extended value collection.
*
* @var array
* @since 1.0.0
*/
protected static $collection = [
'primaryField' => [],
'createdAt' => [],
'columns' => [],
'hasMany' => [],
'hasOne' => [],
'ownsOne' => [],
'table' => [],
];
/**
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
}
/**
* Clone.
*
* @return void
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __clone()
{
}
/**
* Set database connection.
*
* @param ConnectionAbstract $con Database connection
*
* @return void
*
* @since 1.0.0
*/
public static function setConnection(ConnectionAbstract $con) /* : void */
{
self::$db = $con;
}
/**
* Get primary field.
*
* @return string
*
* @since 1.0.0
*/
public static function getPrimaryField() : string
{
return static::$primaryField;
}
/**
* Get main table.
*
* @return string
*
* @since 1.0.0
*/
public static function getTable() : string
{
return static::$table;
}
/**
* Collect values from extension.
*
* @param mixed $class Current extended mapper
*
* @return void
*
* @since 1.0.0
*/
private static function extend($class) /* : void */
{
/* todo: have to implement this in the queries, so far not used */
self::$collection['primaryField'][] = $class::$primaryField;
self::$collection['createdAt'][] = $class::$createdAt;
self::$collection['columns'][] = $class::$columns;
self::$collection['hasMany'][] = $class::$hasMany;
self::$collection['hasOne'][] = $class::$hasOne;
self::$collection['ownsOne'][] = $class::$ownsOne;
self::$collection['table'][] = $class::$table;
if (($parent = get_parent_class($class)) !== false && !$class::$overwrite) {
self::extend($parent);
}
}
/**
* Resets all loaded mapper variables.
*
* This is used after one action is performed otherwise other models would use wrong settings.
*
* @return void
*
* @since 1.0.0
*/
public static function clear() /* : void */
{
self::$overwrite = true;
self::$primaryField = '';
self::$createdAt = '';
self::$columns = [];
self::$hasMany = [];
self::$hasOne = [];
self::$ownsOne = [];
self::$table = '';
self::$fields = [];
self::$collection = [
'primaryField' => [],
'createdAt' => [],
'columns' => [],
'hasOne' => [],
'ownsMany' => [],
'ownsOne' => [],
'table' => [],
];
// clear parent and objects
if(static::class === self::$parentMapper) {
self::$initObjects = [];
self::$parentMapper = null;
}
}
/**
* Get created at column
*
* @return string
*
* @since 1.0.0
*/
public static function getCreatedAt() : string
{
return static::$createdAt;
}
/**
* Get id of object
*
* @param Object $obj Model to create
* @param \ReflectionClass $reflectionClass Reflection class
*
* @return mixed
*
* @since 1.0.0
*/
private static function getObjectId($obj, \ReflectionClass $reflectionClass = null)
{
$reflectionClass = $reflectionClass ?? new \ReflectionClass(get_class($obj));
$reflectionProperty = $reflectionClass->getProperty(static::$columns[static::$primaryField]['internal']);
if (!($isPublic = $reflectionProperty->isPublic())) {
$reflectionProperty->setAccessible(true);
}
$objectId = $reflectionProperty->getValue($obj);
if (!$isPublic) {
$reflectionProperty->setAccessible(false);
}
return $objectId;
}
/**
* Set id to model
*
* @param \ReflectionClass $reflectionClass Reflection class
* @param Object $obj Object to create
* @param mixed $objId Id to set
*
* @return void
*
* @since 1.0.0
*/
private static function setObjectId(\ReflectionClass $reflectionClass, $obj, $objId) /* : void */
{
$reflectionProperty = $reflectionClass->getProperty(static::$columns[static::$primaryField]['internal']);
if (!($isPublic = $reflectionProperty->isPublic())) {
$reflectionProperty->setAccessible(true);
}
settype($objId, static::$columns[static::$primaryField]['type']);
$reflectionProperty->setValue($obj, $objId);
if (!$isPublic) {
$reflectionProperty->setAccessible(false);
}
}
/**
* Parse value
*
* @param string $type Value type
* @param mixed $value Value to parse
*
* @return mixed
*
* @since 1.0.0
*/
private static function parseValue(string $type, $value)
{
if (is_null($value)) {
return null;
} elseif ($type === 'DateTime') {
return $value->format('Y-m-d H:i:s');
} elseif ($type === 'Json' || $type === 'jsonSerializable') {
return json_encode($value);
} elseif ($type === 'Serializable') {
return $value->serialize();
} elseif ($value instanceof \JsonSerializable) {
return json_encode($value->jsonSerialize());
} elseif (is_object($value) && method_exists($value, 'getId')) {
return $value->getId();
} elseif ($type === 'int') {
return (int) $value;
} elseif ($type === 'string') {
return (string) $value;
} elseif ($type === 'float') {
return (float) $value;
} elseif ($type === 'bool') {
return (bool) $value;
}
return $value;
}
/**
* 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;
}
/**
* Define the highest mapper of this request
*
* @return void
*
* @since 1.0.0
*/
private static function setUpParentMapper() /* : void */
{
self::$parentMapper = static::class;
}
private static function getColumnByMember(string $name) : string
{
foreach(static::$columns as $cName => $column) {
if($column['internal'] === $name) {
return $cName;
}
}
throw \Exception();
}
}

View File

@ -15,6 +15,8 @@ declare(strict_types=1);
namespace phpOMS\DataStorage\Database;
use phpOMS\DataStorage\Database\Schema\Exception\TableException;
/**
* Database exception factory.
*

View File

@ -77,10 +77,14 @@ class DatabasePool
*
* @since 1.0.0
*/
public function get(string $key = 'core') /* : ?ConnectionAbstract */
public function get(string $key = '') /* : ?ConnectionAbstract */
{
if (!isset($this->pool[$key])) {
return null; /* todo: return nullconnection */
if((!empty($key) && !isset($this->pool[$key])) || empty($this->pool)) {
return null;
}
if(empty($key)) {
return reset($this->pool);
}
return $this->pool[$key];

View File

@ -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 */
}

View File

@ -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 */
}

View File

@ -24,7 +24,7 @@ namespace phpOMS\DataStorage\Database\Exception;
* @link http://orange-management.com
* @since 1.0.0
*/
class InvalidConnectionConfigException extends \RuntimeException
class InvalidConnectionConfigException extends \InvalidArgumentException
{
/**
* Constructor.

View File

@ -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 = [
@ -170,6 +168,41 @@ abstract class GrammarAbstract
{
$expression = '';
foreach ($elements as $key => $element) {
if (is_string($element) && $element !== '*') {
if(strpos($element, '.') === false) {
$prefix = '';
}
$expression .= $this->compileSystem($element, $prefix) . ', ';
} elseif (is_string($element) && $element === '*') {
$expression .= '*, ';
} elseif ($element instanceof \Closure) {
$expression .= $element() . ', ';
} elseif ($element instanceof BuilderAbstract) {
$expression .= $element->toSql() . ', ';
} else {
throw new \InvalidArgumentException();
}
}
return rtrim($expression, ', ');
}
/**
* Expressionize elements.
*
* @param array $elements Elements
* @param string $prefix Prefix for table
*
* @return string
*
* @since 1.0.0
*/
protected function expressionizeTable(array $elements, string $prefix = '') : string
{
$expression = '';
foreach ($elements as $key => $element) {
if (is_string($element) && $element !== '*') {
$expression .= $this->compileSystem($element, $prefix) . ', ';
@ -205,7 +238,7 @@ abstract class GrammarAbstract
$identifier = $this->systemIdentifier;
foreach($this->specialKeywords as $keyword) {
if(StringUtils::startsWith($system, $keyword)) {
if($keyword === '' || strrpos($system, $keyword, -strlen($system)) !== false) {
$prefix = '';
$identifier = '';
}

View File

@ -45,6 +45,22 @@ class Builder extends BuilderAbstract
*/
public $selects = [];
/**
* Columns.
*
* @var array
* @since 1.0.0
*/
public $updates = [];
/**
* Stupid work around because value needs to be not null for it to work in Grammar.
*
* @var array
* @since 1.0.0
*/
public $deletes = [1];
/**
* Into.
*
@ -69,6 +85,14 @@ class Builder extends BuilderAbstract
*/
public $values = [];
/**
* Into columns.
*
* @var array
* @since 1.0.0
*/
public $sets = [];
/**
* Distinct.
*
@ -165,12 +189,6 @@ class Builder extends BuilderAbstract
*/
public $raw = '';
protected $unionLimit = null;
protected $unionOffset = null;
protected $unionOrders = [];
/**
* Comparison OPERATORS.
*
@ -312,7 +330,7 @@ class Builder extends BuilderAbstract
*/
public function newQuery() : Builder
{
return new static($this->connection, $this->grammar);
return new static($this->connection, $this->isReadOnly);
}
/**
@ -352,7 +370,7 @@ class Builder extends BuilderAbstract
}
$this->type = QueryType::RAW;
$this->raw = $raw;
$this->raw = rtrim($raw, ';');
return $this;
}
@ -521,14 +539,9 @@ class Builder extends BuilderAbstract
*
* @since 1.0.0
*/
public function andWhere(Where $where) : Builder
public function andWhere($where, $operator = null, $values = null) : Builder
{
$this->wheres[][] = [
'column' => $where,
'boolean' => 'and',
];
return $this;
return $this->where($where, $operator, $values, 'and');
}
/**
@ -540,14 +553,9 @@ class Builder extends BuilderAbstract
*
* @since 1.0.0
*/
public function orWhere(Where $where) : Builder
public function orWhere($where, $operator = null, $values = null) : Builder
{
$this->wheres[][] = [
'column' => $where,
'boolean' => 'or',
];
return $this;
return $this->where($where, $operator, $values, 'or');
}
/**
@ -669,10 +677,14 @@ class Builder extends BuilderAbstract
public function orderBy($columns, $order = 'DESC') : Builder
{
if (is_string($columns) || $columns instanceof \Closure) {
$this->orders[] = ['column' => $columns, 'order' => $order];
if(!isset($this->orders[$order])) {
$this->orders[$order] = [];
}
$this->orders[$order][] = $columns;
} elseif (is_array($columns)) {
foreach ($columns as $key => $column) {
$this->orders[] = ['column' => $column, 'order' => $order[$key]];
$this->orders[is_string($order) ? $order : $order[$key]][] = $column;
}
} else {
throw new \InvalidArgumentException();
@ -781,15 +793,6 @@ class Builder extends BuilderAbstract
return $this->select('COUNT(' . $table . ')');
}
/**
* Check if exists.
*
* @since 1.0.0
*/
public function exists()
{
}
/**
* Select minimum.
*
@ -902,6 +905,39 @@ class Builder extends BuilderAbstract
return $this;
}
/**
* Values to insert.
*
* @param array $sets Values
*
* @return Builder
*
* @since 1.0.0
*/
public function sets(...$sets) : Builder
{
$this->sets[] = $sets;
return $this;
}
/**
* Values to insert.
*
* @param mixed $set Values
* @param string $type Data type to insert
*
* @return Builder
*
* @since 1.0.0
*/
public function set($set, string $type = 'string') : Builder
{
$this->sets[key($set)] = current($set);
return $this;
}
/**
* Update columns.
*
@ -911,7 +947,7 @@ class Builder extends BuilderAbstract
*
* @since 1.0.0
*/
public function update(...$columns) : Builder
public function update(...$tables) : Builder
{
if($this->isReadOnly) {
throw new \Exception();
@ -919,13 +955,28 @@ class Builder extends BuilderAbstract
$this->type = QueryType::UPDATE;
foreach ($columns as $key => $column) {
$this->inserts[] = $column;
foreach ($tables as $key => $table) {
if (is_string($table) || $table instanceof \Closure) {
$this->updates[] = $table;
} else {
throw new \InvalidArgumentException();
}
}
return $this;
}
public function delete() : Builder
{
if($this->isReadOnly) {
throw new \Exception();
}
$this->type = QueryType::DELETE;
return $this;
}
/**
* Increment value.
*

View File

@ -78,6 +78,18 @@ class Grammar extends GrammarAbstract
'wheres',
];
/**
* Update components.
*
* @var string[]
* @since 1.0.0
*/
protected $deleteComponents = [
'deletes',
'from',
'wheres',
];
/**
* Random components.
*
@ -111,10 +123,10 @@ class Grammar extends GrammarAbstract
$components = $this->insertComponents;
break;
case QueryType::UPDATE:
$components = [];
$components = $this->updateComponents;
break;
case QueryType::DELETE:
$components = [];
$components = $this->deleteComponents;
break;
case QueryType::RANDOM:
$components = $this->selectComponents;
@ -157,6 +169,42 @@ class Grammar extends GrammarAbstract
return ($query->distinct ? 'SELECT DISTINCT ' : 'SELECT ') . $expression;
}
/**
* Compile select.
*
* @param Builder $query Builder
* @param array $columns Columns
*
* @return string
*
* @since 1.0.0
*/
protected function compileUpdates(Builder $query, array $table) : string
{
$expression = $this->expressionizeTable($table, $query->getPrefix());
if ($expression === '') {
return '';
}
return 'UPDATE ' . $expression;
}
/**
* Compile select.
*
* @param Builder $query Builder
* @param array $columns Columns
*
* @return string
*
* @since 1.0.0
*/
protected function compileDeletes(Builder $query, array $columns) : string
{
return 'DELETE';
}
/**
* Compile from.
*
@ -169,7 +217,7 @@ class Grammar extends GrammarAbstract
*/
protected function compileFrom(Builder $query, array $table) : string
{
$expression = $this->expressionizeTableColumn($table, $query->getPrefix());
$expression = $this->expressionizeTable($table, $query->getPrefix());
if ($expression === '') {
return '';
@ -200,7 +248,7 @@ class Grammar extends GrammarAbstract
}
}
if ($expression == '') {
if ($expression === '') {
return '';
}
@ -240,6 +288,9 @@ class Grammar extends GrammarAbstract
if (isset($element['value'])) {
$expression .= ' ' . strtoupper($element['operator']) . ' ' . $this->compileValue($element['value'], $query->getPrefix());
} else {
$operator = strtoupper($element['operator']) === '=' ? 'IS' : 'IS NOT';
$expression .= ' ' . $operator . ' ' . $this->compileValue($element['value'], $query->getPrefix());
}
return $expression;
@ -282,15 +333,17 @@ class Grammar extends GrammarAbstract
return '(' . rtrim($values, ', ') . ')';
} elseif ($value instanceof \DateTime) {
return $this->valueQuotes . $value->format('Y-m-d h:m:s') . $this->valueQuotes;
return $this->valueQuotes . $value->format('Y-m-d H:i:s') . $this->valueQuotes;
} elseif (is_null($value)) {
return 'NULL';
} elseif (is_bool($value)) {
return (string) ((int) $value);
} elseif (is_float($value)) {
return (string) $value;
} elseif ($value instanceof Column) {
return $this->compileSystem($value->getColumn(), $prefix);
} else {
throw new \InvalidArgumentException();
throw new \InvalidArgumentException(gettype($value));
}
}
@ -366,11 +419,16 @@ class Grammar extends GrammarAbstract
{
$expression = '';
foreach ($orders as $order) {
$expression .= $this->compileSystem($order['column'], $query->getPrefix()) . ' ' . $order['order'] . ', ';
foreach ($orders as $key => $order) {
foreach($order as $column) {
$expression .= $this->compileSystem($column, $query->getPrefix()) . ', ';
}
$expression = rtrim($expression, ', ');
$expression .= ' ' . $key . ', ';
}
if ($expression == '') {
if ($expression === '') {
return '';
}
@ -422,7 +480,7 @@ class Grammar extends GrammarAbstract
$cols .= $this->compileSystem($column) . ', ';
}
if ($cols == '') {
if ($cols === '') {
return '';
}
@ -447,10 +505,38 @@ class Grammar extends GrammarAbstract
$vals .= $this->compileValue($value) . ', ';
}
if ($vals == '') {
if ($vals === '') {
return '';
}
return 'VALUES ' . rtrim($vals, ', ');
}
/**
* Compile insert values.
*
* @param Builder $query Builder
* @param array $values Values
*
* @return string
*
* @since 1.0.0
*/
protected function compileSets(Builder $query, array $values) : string
{
$vals = '';
foreach ($values as $column => $value) {
// todo change expressionizeTableColumn to accept single column and create additionl for Columns
$expression = $this->expressionizeTableColumn([$column], $query->getPrefix());
$vals .= $expression . ' = ' . $this->compileValue($value) . ', ';
}
if ($vals === '') {
return '';
}
return 'SET ' . rtrim($vals, ', ');
}
}

View File

@ -30,11 +30,11 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class RelationType extends Enum
{
/* 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 NONE = 1;
/* public */ const NEWEST = 2;
/* public */ const BELONGS_TO = 4;
/* public */ const OWNS_ONE = 8;
/* public */ const HAS_MANY = 16;
/* public */ const ALL = 32;
/* public */ const REFERENCE = 64;
}

View File

@ -86,8 +86,10 @@ class HttpSession implements SessionInterface
$this->inactivityInterval = $inactivityInterval;
session_set_cookie_params($liftetime, '/', '', false, true);
session_start();
if(session_status() !== PHP_SESSION_ACTIVE && !headers_sent()) {
session_set_cookie_params($liftetime, '/', '', false, true);
session_start();
}
if($this->inactivityInterval > 0 && ($this->inactivityInterval + ($_SESSION['lastActivity'] ?? 0) < time())) {
$this->destroy();

View File

@ -135,9 +135,7 @@ class Dispatcher
{
$views = [];
foreach ($controller as $controllerSingle) {
foreach ($controllerSingle as $c) {
$views += $this->dispatch($c, ...$data);
}
$views += $this->dispatch($controllerSingle, ...$data);
}
return $views;

View File

@ -1,40 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Html;
use phpOMS\Stdlib\Base\Enum;
/**
* Tag type enum.
*
* @category Framework
* @package phpOMS\Html
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
abstract class TagType extends Enum
{
/* public */ const INPUT = 0; /* <input> */
/* public */ const BUTTON = 1; /* <button> */
/* public */ const LINK = 2; /* <a> */
/* public */ const SYMMETRIC = 3; /* <span><div>... */
/* public */ const TEXTAREA = 4; /* <textarea> */
/* public */ const SELECT = 5; /* <select> */
/* public */ const LABEL = 6; /* <label> */
/* public */ const ULIST = 7; /* <ul> */
/* public */ const OLIST = 8; /* <ul> */
}

View File

@ -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 . '\'.',
]);

View File

@ -220,6 +220,8 @@ class Localization
*/
public function setLanguage(string $language) /* : void */
{
$language = strtolower($language);
if (!ISO639x1Enum::isValidValue($language)) {
throw new InvalidEnumValue($language);
}

View File

@ -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.
@ -44,7 +42,7 @@ class FileLogger implements LoggerInterface
* @var array
* @since 1.0.0
*/
private $timings = [];
private static $timings = [];
/**
* Instance.
@ -152,6 +150,7 @@ class FileLogger implements LoggerInterface
* Closes the logging file
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function __destruct()
{
@ -164,6 +163,7 @@ class FileLogger implements LoggerInterface
* Protect instance from getting copied from outside.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __clone()
{
@ -174,16 +174,22 @@ class FileLogger implements LoggerInterface
*
* @param string $id the ID by which this time measurement gets identified
*
* @return void
* @return bool
*
* @since 1.0.0
*/
public function startTimeLog($id = '') /* : void */
public static function startTimeLog($id = '') : bool
{
if(isset(self::$timings[$id])) {
return false;
}
$mtime = explode(' ', microtime());
$mtime = $mtime[1] + $mtime[0];
$this->timings[$id] = ['start' => $mtime];
self::$timings[$id] = ['start' => $mtime];
return true;
}
/**
@ -195,29 +201,15 @@ class FileLogger implements LoggerInterface
*
* @since 1.0.0
*/
public function endTimeLog($id = '') : int
public static function endTimeLog($id = '') : float
{
$mtime = explode(' ', microtime());
$mtime = $mtime[1] + $mtime[0];
$this->timings[$id]['end'] = $mtime;
$this->timings[$id]['time'] = $mtime - $this->timings[$id]['start'];
self::$timings[$id]['end'] = $mtime;
self::$timings[$id]['time'] = $mtime - self::$timings[$id]['start'];
return $this->timings[$id]['time'];
}
/**
* Sorts timings descending.
*
* @param array [float] &$timings the timing array to sort
*
* @return void
*
* @since 1.0.0
*/
public function timingSort(&$timings) /* : void */
{
uasort($timings, [$this, 'orderSort']);
return self::$timings[$id]['time'];
}
/**
@ -261,25 +253,6 @@ class FileLogger implements LoggerInterface
return strtr($message, $replace);
}
/**
* Sorts all timings descending.
*
* @param array $a
* @param array $b
*
* @return int
*
* @since 1.0.0
*/
private function orderSort($a, $b) : int
{
if ($a['time'] == $b['time']) {
return 0;
}
return ($a['time'] > $b['time']) ? -1 : 1;
}
/**
* Write to file.
*

View File

@ -1,622 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Business\Finance\Forecasting\SmoothingType;
use phpOMS\Math\Statistic\Average;
use phpOMS\Math\Statistic\Forecast\Error;
class ExponentialSmoothing
{
private $data = [];
private $errors = [];
private $rmse = 0.0;
private $mse = 0.0;
private $mae = 0.0;
private $sse = 0.0;
public function __construct(array $data)
{
$this->data = $data;
}
public function getRMSE() : float
{
return $this->rmse;
}
public function getMSE() : float
{
return $this->mse;
}
public function getMAE() : float
{
return $this->mae;
}
public function getSSE() : float
{
return $this->sse;
}
public function getErrors() : array
{
return $this->errors;
}
public function getForecast(int $future, int $trendType = TrendType::NONE, int $seasonalType = SeasonalType::NONE, int $cycle = 12, float $damping = 1) : array
{
$this->rmse = PHP_INT_MAX;
if($trendType === TrendType::ALL || $seasonalType === SeasonalType::ALL) {
$trends = [$trendType];
if($trendType === TrendType::ALL) {
$trends = [TrendType::NONE, TrendType::ADDITIVE, TrendType::MULTIPLICATIVE];
}
$seasonals = [$seasonalType];
if($seasonalType === SeasonalType::ALL) {
$seasonals = [SeasonalType::NONE, SeasonalType::ADDITIVE, SeasonalType::MULTIPLICATIVE];
}
$forecast = [];
$bestError = PHP_INT_MAX;
foreach($trends as $trend) {
foreach($seasonals as $seasonal) {
$tempForecast = $this->getForecast($future, $trend, $seasonal, $cycle, $damping);
if ($this->rmse < $bestError) {
$bestError = $this->rmse;
$forecast = $tempForecast;
}
}
}
return $forecast;
} elseif($trendType === TrendType::NONE && $seasonalType === SeasonalType::NONE) {
return $this->getNoneNone($future);
} elseif($trendType === TrendType::NONE && $seasonalType === SeasonalType::ADDITIVE) {
return $this->getNoneAdditive($future, $cycle);
} elseif($trendType === TrendType::NONE && $seasonalType === SeasonalType::MULTIPLICATIVE) {
return $this->getNoneMultiplicative($future, $cycle);
} elseif($trendType === TrendType::ADDITIVE && $seasonalType === SeasonalType::NONE) {
return $this->getAdditiveNone($future, $damping);
} elseif($trendType === TrendType::ADDITIVE && $seasonalType === SeasonalType::ADDITIVE) {
return $this->getAdditiveAdditive($future, $cycle, $damping);
} elseif($trendType === TrendType::ADDITIVE && $seasonalType === SeasonalType::MULTIPLICATIVE) {
return $this->getAdditiveMultiplicative($future, $cycle, $damping);
} elseif($trendType === TrendType::MULTIPLICATIVE && $seasonalType === SeasonalType::NONE) {
return $this->getMultiplicativeNone($future, $damping);
} elseif($trendType === TrendType::MULTIPLICATIVE && $seasonalType === SeasonalType::ADDITIVE) {
return $this->getMultiplicativeAdditive($future, $cycle, $damping);
} elseif($trendType === TrendType::MULTIPLICATIVE && $seasonalType === SeasonalType::MULTIPLICATIVE) {
return $this->getMultiplicativeMultiplicative($future, $cycle, $damping);
}
throw new \Exception();
}
private function dampingSum(float $damping, int $length) : float
{
if(abs($damping - 1) < 0.001) {
return $length;
}
$sum = 0;
for($i = 0; $i < $length; $i++) {
$sum += pow($damping, $i);
}
return $sum;
}
public function getNoneNone(int $future) : array
{
$level = [$this->data[0]];
$dataLength = count($this->data) + $future;
$forecast = [];
$alpha = 0.00;
while ($alpha < 1) {
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$level[$i] = $alpha * ($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) + (1 - $alpha) * $level[$i-1];
$tempForecast[$i] = $level[$i];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getNoneAdditive(int $future, int $cycle) : array
{
$level = [$this->data[0]];
$dataLength = count($this->data) + $future;
$forecast = [];
$seasonal = [];
for($i = 1; $i < $cycle+1; $i++) {
$seasonal[$i] = $this->data[$i-1] - $level[0];
}
$alpha = 0.00;
while ($alpha < 1) {
$gamma = 0.00;
while($gamma < 1) {
$gamma_ = $gamma * (1 - $alpha);
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$hm = (int) floor(($i-1) % $cycle) + 1;
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) - $seasonal[$i]) + (1 - $alpha) * $level[$i-1];
$seasonal[$i+$cycle] = $gamma_*(($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) - $level[$i-1]) + (1 - $gamma_) * $seasonal[$i];
$tempForecast[$i] = $level[$i] + $seasonal[$i+$hm];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$gamma += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getNoneMultiplicative(int $future, int $cycle) : array
{
$level = [$this->data[0]];
$dataLength = count($this->data) + $future;
$forecast = [];
$seasonal = [];
for($i = 1; $i < $cycle+1; $i++) {
$seasonal[$i] = $this->data[$i] / $level[0];
}
$alpha = 0.00;
while ($alpha < 1) {
$gamma = 0.00;
while($gamma < 1) {
$gamma_ = $gamma * (1 - $alpha);
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$hm = (int) floor(($i-1) % $cycle) + 1;
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) / $seasonal[$i]) + (1 - $alpha) * $level[$i-1];
$seasonal[$i+$cycle] = $gamma_*(($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) / $level[$i-1]) + (1 - $gamma_) * $seasonal[$i];
$tempForecast[$i] = $level[$i] + $seasonal[$i+$hm];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$gamma += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getAdditiveNone(int $future, float $damping) : array
{
$level = [$this->data[0]];
$trend = [$this->data[1] - $this->data[0]];
$dataLength = count($this->data) + $future;
$forecast = [];
$alpha = 0.00;
while ($alpha < 1) {
$beta = 0.00;
while($beta < 1) {
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$level[$i] = $alpha * ($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) + (1 - $alpha) * ($level[$i-1] + $damping * $trend[$i-1]);
$trend[$i] = $beta * ($level[$i] - $level[$i-1]) + (1 - $beta) * $damping * $trend[$i-1];
$tempForecast[$i] = $level[$i] + $this->dampingSum($damping, $i) * $trend[$i];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$beta += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getAdditiveAdditive(int $future, int $cycle, float $damping) : array
{
$level = [1 / $cycle * array_sum(array_slice($this->data, 0, $cycle))];
$trend = [1 / $cycle];
$dataLength = count($this->data) + $future;
$forecast = [];
$seasonal = [];
$sum = 0;
for($i = 1; $i < $cycle+1; $i++) {
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
}
$trend[0] *= $sum;
for($i = 1; $i < $cycle+1; $i++) {
$seasonal[$i] = $this->data[$i-1] - $level[0];
}
$alpha = 0.00;
while ($alpha < 1) {
$beta = 0.00;
while($beta < 1) {
$gamma = 0.00;
while($gamma < 1) {
$gamma_ = $gamma * (1 - $alpha);
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$hm = (int) floor(($i-1) % $cycle) + 1;
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) - $seasonal[$i]) + (1 - $alpha) * ($level[$i-1] + $damping * $trend[$i-1]);
$trend[$i] = $beta * ($level[$i] - $level[$i-1]) + (1 - $beta) * $damping * $trend[$i-1];
$seasonal[$i+$cycle] = $gamma_*(($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) - $level[$i-1]) + (1 - $gamma_) * $seasonal[$i];
$tempForecast[$i] = $level[$i] + $this->dampingSum($damping, $i) * $trend[$i] + $seasonal[$i+$hm];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$gamma += 0.01;
}
$beta += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getAdditiveMultiplicative(int $future, int $cycle, float $damping) : array
{
$level = [1 / $cycle * array_sum(array_slice($this->data, 0, $cycle))];
$trend = [1 / $cycle];
$dataLength = count($this->data) + $future;
$forecast = [];
$seasonal = [];
$gamma_ = $gamma * (1 - $alpha);
$sum = 0;
for($i = 1; $i < $cycle+1; $i++) {
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
}
$trend[0] *= $sum;
for($i = 1; $i < $cycle+1; $i++) {
$seasonal[$i] = $this->data[$i] / $level[0];
}
$alpha = 0.00;
while ($alpha < 1) {
$beta = 0.00;
while($beta < 1) {
$gamma = 0.00;
while($gamma < 1) {
$gamma_ = $gamma * (1 - $alpha);
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$hm = (int) floor(($i-1) % $cycle) + 1;
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) / $seasonal[$i]) + (1 - $alpha) * ($level[$i-1] + $damping * $trend[$i-1]);
$trend[$i] = $beta * ($level[$i] - $level[$i-1]) + (1 - $beta) * $damping * $trend[$i-1];
$seasonal[$i+$cycle] = $gamma_*($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) / ($level[$i-1] + $damping * $trend[$i-1]) + (1 - $gamma_) * $seasonal[$i];
$tempForecast[] = ($level[$i] + $this->dampingSum($damping, $i) * $trend[$i-1]) * $seasonal[$i+$hm];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$gamma += 0.01;
}
$beta += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getMultiplicativeNone(int $future, float $damping) : array
{
$level = [$this->data[0]];
$trend = [$this->data[1] / $this->data[0]];
$dataLength = count($this->data) + $future;
$forecast = [];
$alpha = 0.00;
while ($alpha < 1) {
$beta = 0.00;
while($beta < 1) {
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$level[$i] = $alpha * ($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) + (1 - $alpha) * $level[$i-1] * pow($trend[$i-1], $damping);
$trend[$i] = $beta * ($level[$i] / $level[$i-1]) + (1 - $beta) * pow($trend[$i-1], $damping);
$tempForecast[$i] = $level[$i] * pow($trend[$i], $this->dampingSum($damping, $i));
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$beta += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getMultiplicativeAdditive(int $future, int $cycle, float $damping) : array
{
$level = [$this->data[0]];
$trend = [1 / $cycle];
$dataLength = count($this->data) + $future;
$forecast = [];
$seasonal = [];
$sum = 0;
for($i = 1; $i < $cycle+1; $i++) {
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
}
$trend[0] *= $sum;
for($i = 1; $i < $cycle+1; $i++) {
$seasonal[$i] = $this->data[$i-1] - $level[0];
}
$alpha = 0.00;
while ($alpha < 1) {
$beta = 0.00;
while($beta < 1) {
$gamma = 0.00;
while($gamma < 1) {
$gamma_ = $gamma * (1 - $alpha);
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$hm = (int) floor(($i-1) % $cycle) + 1;
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) - $seasonal[$i]) + (1 - $alpha) * $level[$i-1] * pow($trend[$i-1], $damping);
$trend[$i] = $beta * ($level[$i] / $level[$i-1]) + (1 - $beta) * pow($trend[$i-1], $damping);
$seasonal[$i+$cycle] = $gamma_*(($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) - $level[$i-1] * pow($trend[$i-1], $damping)) + (1 - $gamma_) * $seasonal[$i];
$tempForecast[$i] = $level[$i] * pow($trend[$i], $this->dampingSum($damping, $i)) + $seasonal[$i+$hm];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$gamma += 0.01;
}
$beta += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
public function getMultiplicativeMultiplicative(int $future, int $cycle, float $damping) : array
{
$level = [$this->data[0]];
$trend = [1 / $cycle];
$dataLength = count($this->data) + $future;
$forecast = [];
$seasonal = [];
$sum = 0;
for($i = 1; $i < $cycle+1; $i++) {
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
}
$trend[0] *= $sum;
for($i = 1; $i < $cycle+1; $i++) {
$seasonal[$i] = $this->data[$i] / $level[0];
}
$alpha = 0.00;
while ($alpha < 1) {
$beta = 0.00;
while($beta < 1) {
$gamma = 0.00;
while($gamma < 1) {
$gamma_ = $gamma * (1 - $alpha);
$error = [];
$tempForecast = [];
for($i = 1; $i < $dataLength; $i++) {
$hm = (int) floor(($i-1) % $cycle) + 1;
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) / $seasonal[$i]) + (1 - $alpha) * $level[$i-1] * pow($trend[$i-1], $damping);
$trend[$i] = $beta * ($level[$i] / $level[$i-1]) + (1 - $beta) * pow($trend[$i-1], $damping);
$seasonal[$i+$cycle] = $gamma_*($i < $dataLength - $future ? $this->data[$i-1] : $tempForecast[$i-1]) / ($level[$i-1] * pow($trend[$i-1], $damping)) + (1 - $gamma_) * $seasonal[$i];
$tempForecast[$i] = $level[$i] * pow($trend[$i], $this->dampingSum($damping, $i)) * $seasonal[$i+$hm];
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
}
$tempRMSE = Error::getRootMeanSquaredError($error);
if ($tempRMSE < $this->rmse) {
$this->rmse = $tempRMSE;
$forecast = $tempForecast;
}
$gamma += 0.01;
}
$beta += 0.01;
}
$alpha += 0.01;
}
$this->errors = $error;
$this->mse = Error::getMeanSquaredError($error);
$this->mae = Error::getMeanAbsoulteError($error);
$this->sse = Error::getSumSquaredError($error);
return $forecast;
}
}

View File

@ -227,7 +227,7 @@ class Functions
*/
public static function isOdd($a) : bool
{
return $a & 1;
return (bool) ($a & 1);
}
/**
@ -241,7 +241,7 @@ class Functions
*/
public static function isEven($a) : bool
{
return !($a & 1);
return !((bool) ($a & 1));
}
/**
@ -254,7 +254,7 @@ class Functions
* @param mixed $length Circle size
* @param mixed $start Start value
*
* @return int
* @return int Lowest value is 0 and highest value is length - 1
*
* @since 1.0.0
*/

View File

@ -40,34 +40,32 @@ final class MonotoneChain
public static function createConvexHull(array $points) : array
{
if (($n = count($points)) > 1) {
$k = 0;
$h = [];
uasort($points, [self::class, 'sort']);
$k = 0;
$result = [];
// Lower hull
for ($i = 0; $i < $n; ++$i) {
while ($k >= 2 && self::cross($h[$k - 2], $h[$k - 1], $points[$i]) <= 0) {
while ($k >= 2 && self::cross($result[$k - 2], $result[$k - 1], $points[$i]) <= 0) {
$k--;
}
$h[$k++] = $points[$i];
$result[$k++] = $points[$i];
}
// Upper hull
for ($i = $n - 2, $t = $k + 1; $i >= 0; $i--) {
while ($k >= $t && self::cross($h[$k - 2], $h[$k - 1], $points[$i]) <= 0) {
for ($i = $n - 2, $t = $k+1; $i >= 0; $i--) {
while ($k >= $t && self::cross($result[$k - 2], $result[$k - 1], $points[$i]) <= 0) {
$k--;
}
$h[$k++] = $points[$i];
$result[$k++] = $points[$i];
}
if ($k > 1) {
$h = array_splice($h, $k - 1);
}
ksort($result);
return $h;
return array_slice($result, 0, $k-1);
}
return $points;

View File

@ -1,21 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Math\Matrix;
class Cholesky
{
}

View File

@ -0,0 +1,105 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Math\Matrix;
class CholeskyDecomposition
{
private $L = [];
private $m = 0;
private $isSpd = true;
public function __construct(Matrix $M)
{
$this->L = $M->toArray();
$this->m = $M->getM();
for($i = 0; $i < $this->m; ++$i) {
for($j = $i; $j < $this->m; ++$j) {
for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) {
$sum -= $this->L[$i][$k] * $this->L[$j][$k];
}
if ($i == $j) {
if ($sum >= 0) {
$this->L[$i][$i] = sqrt($sum);
} else {
$this->isSpd = false;
}
} else {
if ($this->L[$i][$i] != 0) {
$this->L[$j][$i] = $sum / $this->L[$i][$i];
}
}
}
for ($k = $i+1; $k < $this->m; ++$k) {
$this->L[$i][$k] = 0.0;
}
}
}
public function isSpd()
{
return $this->isSpd;
}
public function getL()
{
$matrix = new Matrix();
$matrix->setMatrix($this->L);
return $matrix;
}
public function solve(Matrix $B)
{
if ($B->getM() !== $this->m) {
// invalid dimension
}
if (!$this->isSpd) {
// is not positive definite
}
$X = $B->toArray();
$nx = $B->getN();
for ($k = 0; $k < $this->m; ++$k) {
for ($i = $k + 1; $i < $this->m; ++$i) {
for ($j = 0; $j < $nx; ++$j) {
$X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k];
}
}
for ($j = 0; $j < $nx; ++$j) {
$X[$k][$j] /= $this->L[$k][$k];
}
}
for ($k = $this->m - 1; $k >= 0; --$k) {
for ($j = 0; $j < $nx; ++$j) {
$X[$k][$j] /= $this->L[$k][$k];
}
for ($i = 0; $i < $k; ++$i) {
for ($j = 0; $j < $nx; ++$j) {
$X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i];
}
}
}
return new Matrix($X, $this->m, $nx);
}
}

View File

@ -0,0 +1,185 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Math\Matrix;
class LUDecomposition
{
private $LU = [];
private $m = 0;
private $n = 0;
private $pivSign = 1;
private $piv = [];
public function __construct(Matrix $M)
{
$this->LU = $M->toArray();
$this->m = $M->getM();
$this->n = $M->getN();
for ($i = 0; $i < $this->m; ++$i) {
$this->piv[$i] = $i;
}
$this->pivSign = 1;
$LUrowi = $LUcolj = [];
for ($j = 0; $j < $this->n; ++$j) {
// Make a copy of the j-th column to localize references.
for ($i = 0; $i < $this->m; ++$i) {
$LUcolj[$i] = &$this->LU[$i][$j];
}
// Apply previous transformations.
for ($i = 0; $i < $this->m; ++$i) {
$LUrowi = $this->LU[$i];
// Most of the time is spent in the following dot product.
$kmax = min($i,$j);
$s = 0.0;
for ($k = 0; $k < $kmax; ++$k) {
$s += $LUrowi[$k] * $LUcolj[$k];
}
$LUrowi[$j] = $LUcolj[$i] -= $s;
}
// Find pivot and exchange if necessary.
$p = $j;
for ($i = $j+1; $i < $this->m; ++$i) {
if (abs($LUcolj[$i]) > abs($LUcolj[$p])) {
$p = $i;
}
}
if ($p != $j) {
for ($k = 0; $k < $this->n; ++$k) {
$t = $this->LU[$p][$k];
$this->LU[$p][$k] = $this->LU[$j][$k];
$this->LU[$j][$k] = $t;
}
$k = $this->piv[$p];
$this->piv[$p] = $this->piv[$j];
$this->piv[$j] = $k;
$this->pivSign = $this->pivSign * -1;
}
// Compute multipliers.
if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) {
for ($i = $j+1; $i < $this->m; ++$i) {
$this->LU[$i][$j] /= $this->LU[$j][$j];
}
}
}
}
public function getL()
{
for ($i = 0; $i < $this->m; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
if ($i > $j) {
$L[$i][$j] = $this->LU[$i][$j];
} elseif ($i == $j) {
$L[$i][$j] = 1.0;
} else {
$L[$i][$j] = 0.0;
}
}
}
$matrix = new Matrix();
$matrix->setMatrix($L);
return $matrix;
}
public function getU()
{
for ($i = 0; $i < $this->n; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
if ($i <= $j) {
$U[$i][$j] = $this->LU[$i][$j];
} else {
$U[$i][$j] = 0.0;
}
}
}
$matrix = new Matrix();
$matrix->setMatrix($U);
return $matrix;
}
public function getPivot()
{
return $this->piv;
}
public function isNonsingular() : bool
{
for ($j = 0; $j < $this->n; ++$j) {
if ($this->LU[$j][$j] == 0) {
return false;
}
}
return true;
}
public function det()
{
$d = $this->pivSign;
for ($j = 0; $j < $this->n; ++$j) {
$d *= $this->LU[$j][$j];
}
return $d;
}
public function solve(Matrix $B)
{
if ($B->getM() !== $this->m) {
}
if (!$this->isNonsingular()) {
}
var_dump($this->piv);
$nx = $B->getM();
$X = $B->getMatrix($this->piv, 0, $nx-1);
// Solve L*Y = B(piv,:)
for ($k = 0; $k < $this->n; ++$k) {
for ($i = $k+1; $i < $this->n; ++$i) {
for ($j = 0; $j < $nx; ++$j) {
$X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
}
}
}
// Solve U*X = Y;
for ($k = $this->n-1; $k >= 0; --$k) {
for ($j = 0; $j < $nx; ++$j) {
$X->A[$k][$j] /= $this->LU[$k][$k];
}
for ($i = 0; $i < $k; ++$i) {
for ($j = 0; $j < $nx; ++$j) {
$X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
}
}
}
return $X;
}
}

View File

@ -68,7 +68,7 @@ class Matrix implements \ArrayAccess, \Iterator
*
* @since 1.0.0
*/
public function __construct(int $m, int $n = 1)
public function __construct(int $m = 1, int $n = 1)
{
$this->n = $n;
$this->m = $m;
@ -146,6 +146,18 @@ class Matrix implements \ArrayAccess, \Iterator
return $this->matrix;
}
/**
* Get matrix array.
*
* @return array
*
* @since 1.0.0
*/
public function toArray() : array
{
return $this->matrix;
}
/**
* Get matrix rank.
*
@ -171,10 +183,8 @@ class Matrix implements \ArrayAccess, \Iterator
*/
public function setMatrix(array $matrix) : Matrix
{
if ($this->m !== count($matrix) || $this->n !== count($matrix[0])) {
throw new InvalidDimensionException(count($matrix) . 'x' . count($matrix[0]));
}
$this->m = count($matrix);
$this->n = count($matrix[0] ?? 1);
$this->matrix = $matrix;
return $this;
@ -491,16 +501,7 @@ class Matrix implements \ArrayAccess, \Iterator
*/
public function inverse(int $algorithm = InverseType::GAUSS_JORDAN) : Matrix
{
if ($this->n !== $this->m) {
throw new InvalidDimensionException($this->m . 'x' . $this->n);
}
switch ($algorithm) {
case InverseType::GAUSS_JORDAN:
return $this->inverseGaussJordan();
default:
throw new \Exception('Inversion algorithm');
}
return $this->solve(new IdentityMatrix($this->m, $this->m));
}
/**
@ -561,9 +562,11 @@ class Matrix implements \ArrayAccess, \Iterator
return $newMatrix;
}
public function solve($b, int $algorithm) : Matrix
public function solve(Matrix $B) : Matrix
{
return $this->gaussElimination($b);
$M = $this->m === $this->n ? new LUDecomposition($this) : new QRDecomposition($this);
return $M->solve($B);
}
private function gaussElimination($b) : Matrix
@ -671,18 +674,8 @@ class Matrix implements \ArrayAccess, \Iterator
*/
public function det() : float
{
if ($this->n === 1) {
return $this->matrix[0][0];
}
$trianglize = $this->matrix;
$prod = $this->upperTrianglize($trianglize);
for ($i = 0; $i < $this->n; $i++) {
$prod *= $trianglize[$i][$i];
}
return $prod;
$L = new LUDecomposition($this);
return $L->det();
}
/**
@ -809,32 +802,4 @@ class Matrix implements \ArrayAccess, \Iterator
unset($this->matrix[$row][$offset - $row * $this->n]);
}
/**
* Decompose matrix using cholesky algorithm.
*
* @return Matrix
*
* @since 1.0.0
*/
private function decompositionCholesky() : Matrix
{
$newMatrix = new Matrix($this->n, $this->n);
$newMatrixArr = $newMatrix->getMatrix();
for ($i = 0; $i < $this->n; $i++) {
for ($j = 0; $j < $i + 1; $j++) {
$temp = 0;
for ($c = 0; $c < $j; $c++) {
$temp += $newMatrixArr[$i][$c] * $newMatrixArr[$j][$c];
}
$newMatrixArr[$i][$j] = ($i == $j) ? sqrt($this->matrix[$i][$i] - $temp) : (1 / $newMatrixArr[$j][$j] * ($this->matrix[$i][$j] - $temp));
}
}
$newMatrix->setMatrix($newMatrixArr);
return $newMatrix;
}
}

View File

@ -0,0 +1,187 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Math\Matrix;
class QRDecomposition
{
private $QR = [];
private $m = 0;
private $n = 0;
private $Rdiag = [];
public function __construct(Matrix $M)
{
// Initialize.
$this->QR = $M->toArray();
$this->m = $M->getRowDimension();
$this->n = $M->getColumnDimension();
// Main loop.
for ($k = 0; $k < $this->n; ++$k) {
// Compute 2-norm of k-th column without under/overflow.
$nrm = 0.0;
for ($i = $k; $i < $this->m; ++$i) {
$nrm = hypo($nrm, $this->QR[$i][$k]);
}
if ($nrm != 0.0) {
// Form k-th Householder vector.
if ($this->QR[$k][$k] < 0) {
$nrm = -$nrm;
}
for ($i = $k; $i < $this->m; ++$i) {
$this->QR[$i][$k] /= $nrm;
}
$this->QR[$k][$k] += 1.0;
// Apply transformation to remaining columns.
for ($j = $k+1; $j < $this->n; ++$j) {
$s = 0.0;
for ($i = $k; $i < $this->m; ++$i) {
$s += $this->QR[$i][$k] * $this->QR[$i][$j];
}
$s = -$s/$this->QR[$k][$k];
for ($i = $k; $i < $this->m; ++$i) {
$this->QR[$i][$j] += $s * $this->QR[$i][$k];
}
}
}
$this->Rdiag[$k] = -$nrm;
}
}
public function isFullRank() : bool
{
for ($j = 0; $j < $this->n; ++$j) {
if ($this->Rdiag[$j] == 0) {
return false;
}
}
return true;
}
public function getH()
{
for ($i = 0; $i < $this->m; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
if ($i >= $j) {
$H[$i][$j] = $this->QR[$i][$j];
} else {
$H[$i][$j] = 0.0;
}
}
}
$matrix = new Matrix();
$matrix->setArray($H);
return $this->matrix;
}
public function getR()
{
for ($i = 0; $i < $this->n; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
if ($i < $j) {
$R[$i][$j] = $this->QR[$i][$j];
} elseif ($i == $j) {
$R[$i][$j] = $this->Rdiag[$i];
} else {
$R[$i][$j] = 0.0;
}
}
}
$matrix = new Matrix();
$matrix->setArray($R);
return $this->matrix;
}
public function getQ()
{
for ($k = $this->n-1; $k >= 0; --$k) {
for ($i = 0; $i < $this->m; ++$i) {
$Q[$i][$k] = 0.0;
}
$Q[$k][$k] = 1.0;
for ($j = $k; $j < $this->n; ++$j) {
if ($this->QR[$k][$k] != 0) {
$s = 0.0;
for ($i = $k; $i < $this->m; ++$i) {
$s += $this->QR[$i][$k] * $Q[$i][$j];
}
$s = -$s/$this->QR[$k][$k];
for ($i = $k; $i < $this->m; ++$i) {
$Q[$i][$j] += $s * $this->QR[$i][$k];
}
}
}
}
$matrix = new Matrix();
$matrix->setArray($Q);
return $this->matrix;
}
public function solve(Matrix $B)
{
if ($B->getRowDimension() !== $this->m) {
}
if (!$this->isFullRank()) {
}
$nx = $B->getColumnDimension();
$X = $B->getArrayCopy();
// Compute Y = transpose(Q)*B
for ($k = 0; $k < $this->n; ++$k) {
for ($j = 0; $j < $nx; ++$j) {
$s = 0.0;
for ($i = $k; $i < $this->m; ++$i) {
$s += $this->QR[$i][$k] * $X[$i][$j];
}
$s = -$s/$this->QR[$k][$k];
for ($i = $k; $i < $this->m; ++$i) {
$X[$i][$j] += $s * $this->QR[$i][$k];
}
}
}
// Solve R*X = Y;
for ($k = $this->n-1; $k >= 0; --$k) {
for ($j = 0; $j < $nx; ++$j) {
$X[$k][$j] /= $this->Rdiag[$k];
}
for ($i = 0; $i < $k; ++$i) {
for ($j = 0; $j < $nx; ++$j) {
$X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k];
}
}
}
$matrix = new Matrix();
$matrix->setArray($X);
return $matrix->getMatrix(0, $this->n-1, 0, $nx);
}
}

View File

@ -28,13 +28,13 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class NumberType extends Enum
{
/* public */ const INTEGER = 1;
/* public */ const NATURAL = 21;
/* public */ const EVEN = 211;
/* public */ const UNEVEN = 212;
/* public */ const PRIME = 22;
/* public */ const REAL = 3;
/* public */ const RATIONAL = 4;
/* public */ const IRRATIONAL = 5;
/* public */ const COMPLEX = 6;
/* public */ const N_INTEGER = 0;
/* public */ const N_NATURAL = 1;
/* public */ const N_EVEN = 2;
/* public */ const N_UNEVEN = 4;
/* public */ const N_PRIME = 8;
/* public */ const N_REAL = 16;
/* public */ const N_RATIONAL = 32;
/* public */ const N_IRRATIONAL = 64;
/* public */ const N_COMPLEX = 128;
}

View File

@ -30,7 +30,6 @@ class MultipleLinearRegression
$Y = new Matrix(count($y));
$Y->setMatrix($y);
return $XT->mult($X)->inverse()->mult($XT)->mult($Y)->getMatrix();
}

View File

@ -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;
}
}

View File

@ -49,7 +49,7 @@ class NaiveBayesFilter
}
}
return 1 / (1+exp(M_E, $n));
return 1 / (1+exp($n));
}
private function normalizeDictionary() : array

View File

@ -70,6 +70,29 @@ abstract class HeaderAbstract
$this->l11n = new Localization();
}
/**
* Set header locked.
*
* @since 1.0.0
*/
public static function lock() /* : void */
{
// todo: maybe pass session as member and make lock not static
self::$isLocked = true;
}
/**
* Is header locked?
*
* @return bool
*
* @since 1.0.0
*/
public static function isLocked() : bool
{
return self::$isLocked;
}
/**
* Get Localization
*
@ -81,11 +104,11 @@ abstract class HeaderAbstract
{
return $this->l11n;
}
/**
* Set localization
*
* @param int $localization Localization
* @param Localization $l11n Localization
*
* @return void
*
@ -121,7 +144,6 @@ abstract class HeaderAbstract
{
$this->account = $account;
}
/**
* Set status code
@ -135,9 +157,18 @@ abstract class HeaderAbstract
public function setStatusCode(int $status) /* : void */
{
$this->status = $status;
$this->header->generate($status);
$this->generate($status);
}
/**
* Generate header based on status code.
*
* @param int $statusCode Status code
*
* @since 1.0.0
*/
abstract public function generate(int $statusCode) /* : void */;
/**
* Get status code
*
@ -149,7 +180,7 @@ abstract class HeaderAbstract
{
return $this->status;
}
/**
* Get protocol version.
*
@ -170,15 +201,6 @@ abstract class HeaderAbstract
*/
abstract public function set(string $key, string $value, bool $overwrite = false);
/**
* Generate header based on status code.
*
* @param int $statusCode Status code
*
* @since 1.0.0
*/
abstract public function generate(int $statusCode) /* : void */;
/**
* Get header by key.
*
@ -200,27 +222,4 @@ abstract class HeaderAbstract
* @since 1.0.0
*/
abstract public function has(string $key) : bool;
/**
* Set header locked.
*
* @since 1.0.0
*/
public static function lock() /* : void */
{
// todo: maybe pass session as member and make lock not static
self::$isLocked = true;
}
/**
* Is header locked?
*
* @return bool
*
* @since 1.0.0
*/
public static function isLocked() : bool
{
return self::$isLocked;
}
}

View File

@ -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);
@ -76,7 +76,7 @@ class Header extends HeaderAbstract
if (!$overwrite && isset($this->header[$key])) {
return false;
} elseif ($overwrite || !isset($this->header[$key])) {
if ($this->isSecurityHeader($key) && isset($this->header[$key])) {
if (self::isSecurityHeader($key) && isset($this->header[$key])) {
throw new \Exception('Cannot change security headers.');
}
@ -92,14 +92,6 @@ class Header extends HeaderAbstract
return true;
}
/**
* {@inheritdoc}
*/
public function getProtocolVersion() : string
{
return $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1';
}
/**
* Is security header.
*
@ -109,12 +101,22 @@ class Header extends HeaderAbstract
*
* @since 1.0.0
*/
private function isSecurityHeader(string $key) : bool
public static function isSecurityHeader(string $key) : bool
{
return $key === 'content-security-policy' ||
$key === 'x-xss-protection' ||
$key === 'x-content-type-options' ||
$key === 'x-frame-options';
$key = strtolower($key);
return $key === 'content-security-policy'
|| $key === 'x-xss-protection'
|| $key === 'x-content-type-options'
|| $key === 'x-frame-options';
}
/**
* {@inheritdoc}
*/
public function getProtocolVersion() : string
{
return $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1';
}
/**
@ -127,34 +129,10 @@ class Header extends HeaderAbstract
public function getStatusCode() : int
{
if($this->status === 0) {
$this->status = \http_response_code();
$this->status = (int) \http_response_code();
}
return $this->status;
}
/**
* Returns all pushed headers.
*
* @return array
*
* @since 1.0.0
*/
public function getHeaders() : array
{
return self::getAllHeaders();
}
/**
* Get pushed header by name.
*
* @return string
*
* @since 1.0.0
*/
public function getHeader(string $name) : string
{
return self::getAllHeaders()[$name] ?? '';
return parent::getStatusCode();
}
/**
@ -164,7 +142,7 @@ class Header extends HeaderAbstract
*
* @since 1.0.0
*/
private static function getAllHeaders() : array
public static function getAllHeaders() : array
{
if (function_exists('getallheaders')) {
return getallheaders();
@ -183,7 +161,7 @@ class Header extends HeaderAbstract
/**
* Remove header by ID.
*
* @param int $key Header key
* @param mixed $key Header key
*
* @return bool
*
@ -191,10 +169,10 @@ class Header extends HeaderAbstract
*
* @since 1.0.0
*/
public function remove(int $key) : bool
public function remove($key) : bool
{
if (self::$isLocked) {
throw new \LockException('HTTP header');
throw new LockException('HTTP header');
}
if (isset($this->header[$key])) {
@ -206,10 +184,20 @@ class Header extends HeaderAbstract
return false;
}
/**
* {@inheritdoc}
*/
public function getReasonPhrase() : string
{
$phrases = $this->get('Status');
return empty($phrases) ? '' : $phrases[0];
}
/**
* Get header by name.
*
* @param int $key Header key
* @param string $key Header key
*
* @return array
*
@ -219,19 +207,11 @@ class Header extends HeaderAbstract
{
return $this->header[strtolower($key)] ?? [];
}
/**
* {@inheritdoc}
*/
public function getReasonPhrase() : string
{
return $this->header->getHeader('Status');
}
/**
* Check if header is defined.
*
* @param int $key Header key
* @param string $key Header key
*
* @return bool
*
@ -341,22 +321,7 @@ class Header extends HeaderAbstract
*/
private function generate407() /* : void */
{
}
/**
* Generate predefined header.
*
* @return void
*
* @since 1.0.0
*/
private function generate500() /* : void */
{
$this->set('HTTP', 'HTTP/1.0 500 Internal Server Error');
$this->set('Status', 'Status: 500 Internal Server Error');
$this->set('Retry-After', 'Retry-After: 300');
\http_response_code(500);
\http_response_code(407);
}
/**
@ -373,4 +338,19 @@ class Header extends HeaderAbstract
$this->set('Retry-After', 'Retry-After: 300');
\http_response_code(503);
}
/**
* Generate predefined header.
*
* @return void
*
* @since 1.0.0
*/
private function generate500() /* : void */
{
$this->set('HTTP', 'HTTP/1.0 500 Internal Server Error');
$this->set('Status', 'Status: 500 Internal Server Error');
$this->set('Retry-After', 'Retry-After: 300');
\http_response_code(500);
}
}

View File

@ -30,27 +30,27 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class OSType extends Enum
{
/* public */ const WINDOWS_81 = 'windows nt 6.3'; /* Windows 8.1 */
/* public */ const WINDOWS_8 = 'windows nt 6.2'; /* Windows 8 */
/* public */ const WINDOWS_7 = 'windows nt 6.1'; /* Windows 7 */
/* public */ const WINDOWS_VISTA = 'windows nt 6.0'; /* Windows Vista */
/* public */ const WINDOWS_81 = 'windows nt 6.3'; /* Windows 8.1 */
/* public */ const WINDOWS_8 = 'windows nt 6.2'; /* Windows 8 */
/* public */ const WINDOWS_7 = 'windows nt 6.1'; /* Windows 7 */
/* public */ const WINDOWS_VISTA = 'windows nt 6.0'; /* Windows Vista */
/* public */ const WINDOWS_SERVER = 'windows nt 5.2'; /* Windows Server 2003/XP x64 */
/* public */ const WINDOWS_XP = 'windows nt 5.1'; /* Windows XP */
/* public */ const WINDOWS_XP_2 = 'windows xp'; /* Windows XP */
/* public */ const WINDOWS_2000 = 'windows nt 5.0'; /* Windows 2000 */
/* public */ const WINDOWS_ME = 'windows me'; /* Windows ME */
/* public */ const WINDOWS_98 = 'win98'; /* Windows 98 */
/* public */ const WINDOWS_95 = 'win95'; /* Windows 95 */
/* public */ const WINDOWS_311 = 'win16'; /* Windows 3.11 */
/* public */ const MAC_OS_X = 'macintosh'; /* Mac OS X */
/* public */ const MAC_OS_X_2 = 'mac os x'; /* Mac OS X */
/* public */ const MAC_OS_9 = 'mac_powerpc'; /* Mac OS 9 */
/* public */ const LINUX = 'linux'; /* Linux */
/* public */ const UBUNTU = 'ubuntu'; /* Ubuntu */
/* public */ const IPHONE = 'iphone'; /* IPhone */
/* public */ const IPOD = 'ipod'; /* IPod */
/* public */ const IPAD = 'ipad'; /* IPad */
/* public */ const ANDROID = 'android'; /* Android */
/* public */ const BLACKBERRY = 'blackberry'; /* Blackberry */
/* public */ const MOBILE = 'webos'; /* Mobile */
/* public */ const WINDOWS_XP = 'windows nt 5.1'; /* Windows XP */
/* public */ const WINDOWS_XP_2 = 'windows xp'; /* Windows XP */
/* public */ const WINDOWS_2000 = 'windows nt 5.0'; /* Windows 2000 */
/* public */ const WINDOWS_ME = 'windows me'; /* Windows ME */
/* public */ const WINDOWS_98 = 'win98'; /* Windows 98 */
/* public */ const WINDOWS_95 = 'win95'; /* Windows 95 */
/* public */ const WINDOWS_311 = 'win16'; /* Windows 3.11 */
/* public */ const MAC_OS_X = 'macintosh'; /* Mac OS X */
/* public */ const MAC_OS_X_2 = 'mac os x'; /* Mac OS X */
/* public */ const MAC_OS_9 = 'mac_powerpc'; /* Mac OS 9 */
/* public */ const LINUX = 'linux'; /* Linux */
/* public */ const UBUNTU = 'ubuntu'; /* Ubuntu */
/* public */ const IPHONE = 'iphone'; /* IPhone */
/* public */ const IPOD = 'ipod'; /* IPod */
/* public */ const IPAD = 'ipad'; /* IPad */
/* public */ const ANDROID = 'android'; /* Android */
/* public */ const BLACKBERRY = 'blackberry'; /* Blackberry */
/* public */ const MOBILE = 'webos'; /* Mobile */
}

View File

@ -67,50 +67,28 @@ class Request extends RequestAbstract
/**
* Constructor.
*
* @param Localization $l11n Localization
* @param UriInterface $uri Uri
* @param Localization $l11n Localization
*
* @since 1.0.0
*/
public function __construct(Localization $l11n = null, UriInterface $uri = null)
public function __construct(UriInterface $uri = null, Localization $l11n = null)
{
$this->l11n = $l11n;
$this->uri = $uri;
$this->source = RequestSource::WEB;
$this->header = new Header();
$this->header->setL11n($l11n ?? new Localization());
$this->uri = $uri;
$this->source = RequestSource::WEB;
$this->init();
}
/**
* Create request from super globals.
*
* @param Localization $l11n Localization
*
* @return Request
*
* @since 1.0.0
*/
public static function createFromSuperglobals(Localization $l11n = null) : Request
{
return new self($l11n);
}
/**
* {@inheritdoc}
*/
public function setUri(UriInterface $uri) /* : void */
{
$this->uri = $uri;
$this->data += $uri->getQueryArray();
}
/**
* Init request.
*
* 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
*
@ -140,10 +118,10 @@ class Request extends RequestAbstract
*/
private function initCurrentRequest() /* : void */
{
$this->uri = new Http(Http::getCurrent());
$this->data = $_GET ?? [];
$this->files = $_FILES ?? [];
$this->language = $this->loadRequestLanguage();
$this->uri = new Http(Http::getCurrent());
$this->data = $_GET ?? [];
$this->files = $_FILES ?? [];
$this->header->getL11n()->setLanguage($this->loadRequestLanguage());
if (isset($_SERVER['CONTENT_TYPE'])) {
if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
@ -204,7 +182,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,12 +190,25 @@ class Request extends RequestAbstract
}
}
/**
* Create request from super globals.
*
* @return Request
*
* @since 1.0.0
*/
public static function createFromSuperglobals() : Request
{
return new self();
}
/**
* {@inheritdoc}
*/
public function getLanguage() : string
public function setUri(UriInterface $uri) /* : void */
{
return $this->language;
parent::setUri($uri);
$this->data += $uri->getQueryArray();
}
/**
@ -330,6 +321,7 @@ class Request extends RequestAbstract
if (!isset($this->os)) {
$arr = OSType::getConstants();
$http_request_type = strtolower($_SERVER['HTTP_USER_AGENT']);
foreach ($arr as $key => $val) {
if (stripos($http_request_type, $val)) {
$this->os = $val;
@ -385,21 +377,6 @@ class Request extends RequestAbstract
|| ($_SERVER['SERVER_PORT'] ?? '') == $port;
}
/**
* Stringify request.
*
* @return string
*
* @since 1.0.0
*/
public function __toString()
{
$lastElement = end($this->hash);
reset($this->hash);
return $lastElement;
}
/**
* {@inheritdoc}
*/

View File

@ -28,10 +28,10 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class RequestMethod extends Enum
{
/* public */ const GET = 'GET'; /* GET */
/* public */ const POST = 'POST'; /* POST */
/* public */ const PUT = 'PUT'; /* PUT */
/* public */ const DELETE = 'DELETE'; /* DELETE */
/* public */ const HEAD = 'HEAD'; /* HEAD */
/* public */ const TRACE = 'TRACE'; /* TRACE */
/* public */ const GET = 'GET'; /* GET */
/* public */ const POST = 'POST'; /* POST */
/* public */ const PUT = 'PUT'; /* PUT */
/* public */ const DELETE = 'DELETE'; /* DELETE */
/* public */ const HEAD = 'HEAD'; /* HEAD */
/* public */ const TRACE = 'TRACE'; /* TRACE */
}

View File

@ -29,112 +29,58 @@ use phpOMS\Stdlib\Base\Enum;
abstract class RequestStatus extends Enum
{
/* public */ const R_100 = 'Continue';
/* public */ const R_101 = 'Switching Protocols';
/* public */ const R_102 = 'Processing';
/* public */ const R_200 = 'OK';
/* public */ const R_201 = 'Created';
/* public */ const R_202 = 'Accepted';
/* public */ const R_203 = 'Non-Authoritative Information';
/* public */ const R_204 = 'No Content';
/* public */ const R_205 = 'Reset Content';
/* public */ const R_206 = 'Partial Content';
/* public */ const R_207 = 'Multi-Status';
/* public */ const R_300 = 'Multiple Choices';
/* public */ const R_301 = 'Moved Permanently';
/* public */ const R_302 = 'Found';
/* public */ const R_303 = 'See Other';
/* public */ const R_304 = 'Not Modified';
/* public */ const R_305 = 'Use Proxy';
/* public */ const R_306 = 'Switch Proxy';
/* public */ const R_307 = 'Temporary Redirect';
/* public */ const R_400 = 'Bad Request';
/* public */ const R_401 = 'Unauthorized';
/* public */ const R_402 = 'Payment Required';
/* public */ const R_403 = 'Forbidden';
/* public */ const R_404 = 'Not Found';
/* public */ const R_405 = 'Method Not Allowed';
/* public */ const R_406 = 'Not Acceptable';
/* public */ const R_407 = 'Proxy Authentication Required';
/* public */ const R_408 = 'Request Timeout';
/* public */ const R_409 = 'Conflict';
/* public */ const R_410 = 'Gone';
/* public */ const R_411 = 'Length Required';
/* public */ const R_412 = 'Precondition Failed';
/* public */ const R_413 = 'Request Entity Too Large';
/* public */ const R_414 = 'Request-URI Too Long';
/* public */ const R_415 = 'Unsupported Media Type';
/* public */ const R_416 = 'Requested Range Not Satisfiable';
/* public */ const R_417 = 'Expectation Failed';
/* public */ const R_418 = 'I\'m a teapot';
/* public */ const R_422 = 'Unprocessable Entity';
/* public */ const R_423 = 'Locked';
/* public */ const R_424 = 'Failed Dependency';
/* public */ const R_425 = 'Unordered Collection';
/* public */ const R_426 = 'Upgrade Required';
/* public */ const R_449 = 'Retry With';
/* public */ const R_450 = 'Blocked by Windows Parental Controls';
/* public */ const R_500 = 'Internal Server Error';
/* public */ const R_501 = 'Not Implemented';
/* public */ const R_502 = 'Bad Gateway';
/* public */ const R_503 = 'Service Unavailable';
/* public */ const R_504 = 'Gateway Timeout';
/* public */ const R_505 = 'HTTP Version Not Supported';
/* public */ const R_506 = 'Variant Also Negotiates';
/* public */ const R_507 = 'Insufficient Storage';
/* public */ const R_509 = 'Bandwidth Limit Exceeded';
/* public */ const R_510 = 'Not Extended';
}

View File

@ -28,112 +28,58 @@ use phpOMS\Stdlib\Base\Enum;
abstract class RequestStatusCode extends Enum
{
/* public */ const R_100 = 100;
/* public */ const R_101 = 101;
/* public */ const R_102 = 102;
/* public */ const R_200 = 200;
/* public */ const R_201 = 201;
/* public */ const R_202 = 202;
/* public */ const R_203 = 203;
/* public */ const R_204 = 204;
/* public */ const R_205 = 205;
/* public */ const R_206 = 206;
/* public */ const R_207 = 207;
/* public */ const R_300 = 300;
/* public */ const R_301 = 301;
/* public */ const R_302 = 302;
/* public */ const R_303 = 303;
/* public */ const R_304 = 304;
/* public */ const R_305 = 305;
/* public */ const R_306 = 306;
/* public */ const R_307 = 307;
/* public */ const R_400 = 400;
/* public */ const R_401 = 401;
/* public */ const R_402 = 402;
/* public */ const R_403 = 403;
/* public */ const R_404 = 404;
/* public */ const R_405 = 405;
/* public */ const R_406 = 406;
/* public */ const R_407 = 407;
/* public */ const R_408 = 408;
/* public */ const R_409 = 409;
/* public */ const R_410 = 410;
/* public */ const R_411 = 411;
/* public */ const R_412 = 412;
/* public */ const R_413 = 413;
/* public */ const R_414 = 414;
/* public */ const R_415 = 415;
/* public */ const R_416 = 416;
/* public */ const R_417 = 417;
/* public */ const R_418 = 418;
/* public */ const R_422 = 422;
/* public */ const R_423 = 423;
/* public */ const R_424 = 424;
/* public */ const R_425 = 425;
/* public */ const R_426 = 426;
/* public */ const R_449 = 449;
/* public */ const R_450 = 450;
/* public */ const R_500 = 500;
/* public */ const R_501 = 501;
/* public */ const R_502 = 502;
/* public */ const R_503 = 503;
/* public */ const R_504 = 504;
/* public */ const R_505 = 505;
/* public */ const R_506 = 506;
/* public */ const R_507 = 507;
/* public */ const R_509 = 509;
/* public */ const R_510 = 510;
}

View File

@ -47,10 +47,10 @@ class Response extends ResponseAbstract implements RenderableInterface
*
* @since 1.0.0
*/
public function __construct(Localization $l11n)
public function __construct(Localization $l11n = null)
{
$this->header = new Header();
$this->l11n = $l11n;
$this->header->setL11n($l11n ?? new Localization());
}
/**

View File

@ -24,7 +24,7 @@ namespace phpOMS\Message\Mail;
* @link http://orange-management.com
* @since 1.0.0
*/
class MailAbstract
class EmailAbstract
{
/**
* Host.

View File

@ -15,7 +15,6 @@ declare(strict_types=1);
namespace phpOMS\Message;
use phpOMS\Localization\Localization;
use phpOMS\Utils\ArrayUtils;
/**
@ -72,7 +71,9 @@ abstract class ResponseAbstract implements MessageInterface, \JsonSerializable
*/
public function set($key, $response, bool $overwrite = true) /* : void */
{
$this->response = ArrayUtils::setArray((string) $key, $this->response, $response, ':', $overwrite);
// This is not working since the key kontains :: from http://
//$this->response = ArrayUtils::setArray((string) $key, $this->response, $response, ':', $overwrite);
$this->response[$key] = $response;
}
/**

View File

@ -55,9 +55,9 @@ class InfoManager
*
* @since 1.0.0
*/
public function __construct($path)
public function __construct(string $path)
{
$this->path = realpath($path);
$this->path = $path;
}
/**
@ -83,8 +83,8 @@ class InfoManager
*/
public function load() /* : void */
{
if ($this->path === false || !file_exists($this->path)) {
throw new PathException((string) $this->path);
if (!file_exists($this->path)) {
throw new PathException($this->path);
}
$this->info = json_decode(file_get_contents($this->path), true);
@ -99,7 +99,7 @@ class InfoManager
*/
public function update() /* : void */
{
if ($this->path === false || !file_exists($this->path)) {
if (!file_exists($this->path)) {
throw new PathException((string) $this->path);
}

View File

@ -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

View File

@ -34,6 +34,7 @@ abstract class ModuleAbstract
* @since 1.0.0
*/
/* public */ const MODULE_NAME = '';
/**
* Module path.
*
@ -41,6 +42,7 @@ abstract class ModuleAbstract
* @since 1.0.0
*/
/* public */ const MODULE_PATH = __DIR__ . '/../../Modules';
/**
* Module version.
*
@ -48,6 +50,15 @@ abstract class ModuleAbstract
* @since 1.0.0
*/
/* public */ const MODULE_VERSION = '1.0.0';
/**
* Module id.
*
* @var string
* @since 1.0.0
*/
/* public */ const MODULE_ID = 0;
/**
* Receiving modules from?
*
@ -96,15 +107,6 @@ abstract class ModuleAbstract
$this->app = $app;
}
/**
* Install external.
*
* @since 1.0.0
*/
public static function installExternal() /* : void */
{
}
/**
* Get language files.
*
@ -160,16 +162,4 @@ abstract class ModuleAbstract
/** @noinspection PhpUndefinedFieldInspection */
return static::$dependencies;
}
/**
* Get event id prefix.
*
* @return string
*
* @since 1.0.0
*/
public function getEventId() : string
{
return static::class;
}
}

View File

@ -15,8 +15,8 @@ declare(strict_types=1);
namespace phpOMS\Module;
use phpOMS\ApplicationAbstract;
use phpOMS\Autoloader;
use phpOMS\ApplicationAbstract;
/**
* ModuleFactory class.
@ -54,6 +54,7 @@ class ModuleFactory
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{

View File

@ -96,6 +96,7 @@ class ModuleManager
* Constructor.
*
* @param ApplicationAbstract $app Application
* @param string $modulePath Path to modules
*
* @since 1.0.0
*/
@ -105,80 +106,6 @@ class ModuleManager
$this->modulePath = $modulePath;
}
/**
* Get modules that run on this page.
*
* @param Request $request Request
*
* @return array
*
* @since 1.0.0
*/
public function getRoutedModules(Request $request) : array
{
$files = $this->getUriLoad($request);
$modules = [];
if (isset($files[4])) {
foreach ($files[4] as $module) {
$modules[] = $module['module_load_file'];
}
}
return $modules;
}
/**
* Get modules that run on this page.
*
* @param Request $request Request
*
* @return array
*
* @since 1.0.0
*/
public function getUriLoad(Request $request) : array
{
if (!isset($this->uriLoad)) {
switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL:
$uriHash = $request->getHash();
$uriPdo = '';
$i = 1;
$c = count($uriHash);
for ($k = 0; $k < $c; $k++) {
$uriPdo .= ':pid' . $i . ',';
$i++;
}
$uriPdo = rtrim($uriPdo, ',');
/* TODO: make join in order to see if they are active */
$sth = $this->app->dbPool->get('core')->con->prepare(
'SELECT
`' . $this->app->dbPool->get('core')->prefix . 'module_load`.`module_load_type`, `' . $this->app->dbPool->get('core')->prefix . 'module_load`.*
FROM
`' . $this->app->dbPool->get('core')->prefix . 'module_load`
WHERE
`module_load_pid` IN(' . $uriPdo . ')'
);
$i = 1;
foreach ($uriHash as $hash) {
$sth->bindValue(':pid' . $i, $hash, \PDO::PARAM_STR);
$i++;
}
$sth->execute();
$this->uriLoad = $sth->fetchAll(\PDO::FETCH_GROUP);
}
}
return $this->uriLoad;
}
/**
* Get language files.
*
@ -202,6 +129,58 @@ class ModuleManager
return $lang;
}
/**
* Get modules that run on this page.
*
* @param Request $request Request
*
* @return array
*
* @since 1.0.0
*/
public function getUriLoad(Request $request) : array
{
if (!isset($this->uriLoad)) {
switch ($this->app->dbPool->get('select')->getType()) {
case DatabaseType::MYSQL:
$uriHash = $request->getHash();
$uriPdo = '';
$i = 1;
$c = count($uriHash);
for ($k = 0; $k < $c; $k++) {
$uriPdo .= ':pid' . $i . ',';
$i++;
}
$uriPdo = rtrim($uriPdo, ',');
/* TODO: make join in order to see if they are active */
$sth = $this->app->dbPool->get('select')->con->prepare(
'SELECT
`' . $this->app->dbPool->get('select')->prefix . 'module_load`.`module_load_type`, `' . $this->app->dbPool->get('select')->prefix . 'module_load`.*
FROM
`' . $this->app->dbPool->get('select')->prefix . 'module_load`
WHERE
`module_load_pid` IN(' . $uriPdo . ')'
);
$i = 1;
foreach ($uriHash as $hash) {
$sth->bindValue(':pid' . $i, $hash, \PDO::PARAM_STR);
$i++;
}
$sth->execute();
$this->uriLoad = $sth->fetchAll(\PDO::FETCH_GROUP);
}
}
return $this->uriLoad;
}
/**
* Get all installed modules that are active (not just on this uri).
*
@ -212,9 +191,9 @@ class ModuleManager
public function getActiveModules() : array
{
if ($this->active === null) {
switch ($this->app->dbPool->get('core')->getType()) {
switch ($this->app->dbPool->get('select')->getType()) {
case DatabaseType::MYSQL:
$sth = $this->app->dbPool->get('core')->con->prepare('SELECT `module_path` FROM `' . $this->app->dbPool->get('core')->prefix . 'module` WHERE `module_active` = 1');
$sth = $this->app->dbPool->get('select')->con->prepare('SELECT `module_path` FROM `' . $this->app->dbPool->get('select')->prefix . 'module` WHERE `module_active` = 1');
$sth->execute();
$this->active = $sth->fetchAll(\PDO::FETCH_COLUMN);
break;
@ -300,6 +279,74 @@ class ModuleManager
}
}
/**
* Get all installed modules.
*
* @return array
*
* @since 1.0.0
*/
public function getInstalledModules() : array
{
if ($this->installed === null) {
switch ($this->app->dbPool->get('select')->getType()) {
case DatabaseType::MYSQL:
$sth = $this->app->dbPool->get('select')->con->prepare('SELECT `module_id`,`module_theme`,`module_version` FROM `' . $this->app->dbPool->get('select')->prefix . 'module`');
$sth->execute();
$this->installed = $sth->fetchAll(\PDO::FETCH_GROUP);
break;
}
}
return $this->installed;
}
/**
* Load info of module.
*
* @param string $module Module name
*
* @return InfoManager
*
* @since 1.0.0
*/
private function loadInfo(string $module) : InfoManager
{
$path = realpath($oldPath = $this->modulePath . '/' . $module . '/' . 'info.json');
if ($path === false) {
throw new PathException($oldPath);
}
$info = new InfoManager($path);
$info->load();
return $info;
}
/**
* Deactivate module.
*
* @param InfoManager $info Module info
*
* @return void
*
* @throws InvalidModuleException Throws this exception in case the deactiviation doesn't exist
*
* @since 1.0.0
*/
private function deactivateModule(InfoManager $info) /* : void */
{
$class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Deactivate';
if (!Autoloader::exists($class)) {
throw new InvalidModuleException($info->getDirectory());
}
/** @var $class DeactivateAbstract */
$class::deactivate($this->app->dbPool, $info);
}
/**
* Deactivate module.
*
@ -335,6 +382,29 @@ class ModuleManager
}
}
/**
* Activate module.
*
* @param InfoManager $info Module info
*
* @return void
*
* @throws InvalidModuleException Throws this exception in case the activation doesn't exist
*
* @since 1.0.0
*/
private function activateModule(InfoManager $info) /* : void */
{
$class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Activate';
if (!Autoloader::exists($class)) {
throw new InvalidModuleException($info->getDirectory());
}
/** @var $class ActivateAbstract */
$class::activate($this->app->dbPool, $info);
}
/**
* Re-init module.
*
@ -451,97 +521,6 @@ class ModuleManager
$class::install($this->modulePath, $this->app->dbPool, $info);
}
/**
* Deactivate module.
*
* @param InfoManager $info Module info
*
* @return void
*
* @throws InvalidModuleException Throws this exception in case the deactiviation doesn't exist
*
* @since 1.0.0
*/
private function deactivateModule(InfoManager $info) /* : void */
{
$class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Deactivate';
if (!Autoloader::exists($class)) {
throw new InvalidModuleException($info->getDirectory());
}
/** @var $class DeactivateAbstract */
$class::deactivate($this->app->dbPool, $info);
}
/**
* Activate module.
*
* @param InfoManager $info Module info
*
* @return void
*
* @throws InvalidModuleException Throws this exception in case the activation doesn't exist
*
* @since 1.0.0
*/
private function activateModule(InfoManager $info) /* : void */
{
$class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Activate';
if (!Autoloader::exists($class)) {
throw new InvalidModuleException($info->getDirectory());
}
/** @var $class ActivateAbstract */
$class::activate($this->app->dbPool, $info);
}
/**
* Load info of module.
*
* @param string $module Module name
*
* @return InfoManager
*
* @since 1.0.0
*/
private function loadInfo(string $module) : InfoManager
{
$path = realpath($oldPath = $this->modulePath . '/' . $module . '/' . 'info.json');
if ($path === false) {
throw new PathException($oldPath);
}
$info = new InfoManager($path);
$info->load();
return $info;
}
/**
* Get all installed modules.
*
* @return array
*
* @since 1.0.0
*/
public function getInstalledModules() : array
{
if ($this->installed === null) {
switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL:
$sth = $this->app->dbPool->get('core')->con->prepare('SELECT `module_id`,`module_theme`,`module_version` FROM `' . $this->app->dbPool->get('core')->prefix . 'module`');
$sth->execute();
$this->installed = $sth->fetchAll(\PDO::FETCH_GROUP);
break;
}
}
return $this->installed;
}
/**
* Install providing.
*
@ -563,6 +542,30 @@ class ModuleManager
}
}
/**
* Get module instance.
*
* @param string $module Module name
*
* @return \phpOMS\Module\ModuleAbstract
*
* @throws \Exception
*
* @since 1.0.0
*/
public function get(string $module) : ModuleAbstract
{
try {
if (!isset($this->running[$module])) {
$this->initModule($module);
}
return $this->running[$module];
} catch (\Exception $e) {
throw $e;
}
}
/**
* Initialize module.
*
@ -610,30 +613,6 @@ class ModuleManager
}
}
/**
* Get module instance.
*
* @param string $module Module name
*
* @return \phpOMS\Module\ModuleAbstract
*
* @throws \Exception
*
* @since 1.0.0
*/
public function get(string $module) : ModuleAbstract
{
try {
if (!isset($this->running[$module])) {
$this->initModule($module);
}
return $this->running[$module];
} catch (\Exception $e) {
throw $e;
}
}
/**
* Initialize all modules for a request.
*
@ -651,4 +630,27 @@ class ModuleManager
$this->initModuleController($module);
}
}
/**
* Get modules that run on this page.
*
* @param Request $request Request
*
* @return array
*
* @since 1.0.0
*/
public function getRoutedModules(Request $request) : array
{
$files = $this->getUriLoad($request);
$modules = [];
if (isset($files[4])) {
foreach ($files[4] as $module) {
$modules[] = $module['module_load_file'];
}
}
return $modules;
}
}

273
Module/PackageManager.php Normal file
View File

@ -0,0 +1,273 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @category TBD
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\Module;
use phpOMS\System\File\PathException;
use phpOMS\Utils\ArrayUtils;
use phpOMS\System\File\Local\File;
use phpOMS\System\File\Local\Directory;
use phpOMS\System\File\Local\LocalStorage;
use phpOMS\Utils\IO\Zip\Zip;
/**
* Package Manager model.
*
* The package manager is responsible for handling installation and update packages for modules, frameworks and resources.
*
* @category Framework
* @package phpOMS\Account
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
class PackageManager
{
/**
* File path.
*
* @var string
* @since 1.0.0
*/
private $path = '';
/**
* Base path.
*
* @var string
* @since 1.0.0
*/
private $basePath = '';
/**
* Extract path.
*
* @var string
* @since 1.0.0
*/
private $extractPath = '';
/**
* Info data.
*
* @var array
* @since 1.0.0
*/
private $info = [];
/**
* Constructor.
*
* @param string $path Package source path e.g. path after download.
* @param string basePath Path of the application
*
* @since 1.0.0
*/
public function __construct(string $path, string $basePath)
{
$this->path = $path;
$this->basePath = $basePath;
}
/**
* Extract package to temporary destination
*
* @param string $path Temporary extract path
*
* @return bool
*
* @since 1.0.0
*/
public function extract(string $path) : bool
{
$this->extractPath = $path;
Zip::unpack($this->path, $this->extractPath);
}
/**
* Load info data from path.
*
* @return void
*
* @throws PathException This exception is thrown in case the info file path doesn't exist.
*
* @since 1.0.0
*/
public function load() /* : void */
{
if(!file_exists($this->extractPath)) {
throw new PathException($this->extractPath);
}
$this->info = json_decode(file_get_contents($this->extractPath . '/info.json'), true);
}
/**
* Validate package integrity
*
* @return bool Returns true if the package is authentic, false otherwise
*
* @since 1.0.0
*/
public function isValid() : bool
{
return $this->authenticate(file_get_contents($this->extractPath . '/package.cert'), $this->hashFiles());
}
/**
* Hash array of files
*
* @param array $files Files to hash
*
* @return string Hash value of files
*
* @since 1.0.0
*/
private function hashFiles(array $files) : string
{
$files = Directory::list($this->extractPath . '/package');
$state = \sodium_crypto_generichash_init();
foreach($files as $file) {
if($file === 'package.cert') {
continue;
}
\sodium_crypto_generichash_update($state, file_get_contents($this->extractPath . '/package/' . $file));
}
return \sodium_crypto_generichash_final();
}
/**
* Install package
*
* @return void
*
* @since 1.0.0
*/
public function install() /* : void */
{
if(!$this->isValid()) {
throw new \Exception();
}
foreach($this->info as $key => $components) {
if(function_exists($this->{$key})) {
$this->{$key}($components);
}
}
}
/**
* Move files
*
* @return void
*
* @since 1.0.0
*/
private function move($components)
{
foreach($components as $component) {
LocalStorage::move($this->basePath . '/' . $component['from'], $this->basePath . '/' . $component['to'], true);
}
}
/**
* Copy files
*
* @return void
*
* @since 1.0.0
*/
private function copy($components)
{
foreach($components as $component) {
if(StringUtils::startsWith($component['from'], 'Package/')) {
LocalStorage::copy($this->path . '/' . $component['from'], $this->basePath . '/' . $component['to'], true);
} else {
LocalStorage::copy($this->basePath . '/' . $component['from'], $this->basePath . '/' . $component['to'], true);
}
}
}
/**
* Delete files
*
* @return void
*
* @since 1.0.0
*/
private function delete($components)
{
foreach($components as $component) {
LocalStorage::delete($this->basePath . '/' . $component);
}
}
/**
* Execute commands
*
* @return void
*
* @since 1.0.0
*/
private function execute($components)
{
foreach($components as $component) {
include $this->basePath . '/' . $component;
}
}
/**
* Cleanup after installation
*
* @return void
*
* @since 1.0.0
*/
public function cleanup()
{
File::delete($this->path);
Directory::delete($this->extractPath);
}
/**
* Authenticate package
*
* @return bool
*
* @since 1.0.0
*/
private function authenticate(string $signedHash, string $rawHash) : bool
{
// https://3v4l.org/PN9Xl
$publicKey = 'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjr73rerPRq3ZwWmrUKsN
Bjg8Wy5lnyWu9HCRQz0fix6grz+NOOsr4m/jazB2knfdtn7fi5XifbIbmrNJY8e6
musCJ0FTgJPVBqVk7XAFVSRe2gUaCPZrTPtfZ00C3cynjwTlxSdjNtU9N0ZAo17s
VWghH8ki4T2d5Mg1erGOtMJzp5yw47UHUa+KbxUmUV25WMcRYyi7+itD2xANF2AE
+PQZT1dSEU8++NI+zT6tXD/Orv5ikk0whoVqvo6duWejx5n5cpJB4EiMo4Q7epbw
9uMo9uIKqgQ9y3KdT36GBQkBErFf1dhf8KYJBGYMhO1UJE11dY3XrA7Ij1+zK+ai
duQHOc5EMClUGZQzCJAIU5lj4WEHQ4Lo0gop+fx9hzuBTDxdyOjWSJzkqyuWMkq3
zEpRBay785iaglaue9XDLee58wY+toiGLBfXe73gsbDqDSOll+cQYNjrronVN7sU
Dc2WyTIVW1Z8KFwK10D3SW0oEylCaGLtClyyihuW7JPu/8Or1Zjf87W82XTm31Fp
YkRgoEMDtVHZq0N2eHpLz1L8zKyT0ogZYN5eH5VlGrPcpwbAludNKlgAJ0hrgED1
9YsCBLwJQpFa4VZP7A5a/Qcw8EFAvNkgaPpBbAAtWoDbyOQsez6Jsdan/enfZ18+
LL7qOB5oFFM/pKlTIeVS+UsCAwEAAQ==';
$unsignedHash = \sodium_crypto_sign_open($signedHash, $publicKey);
return $unsignedHash === $rawHash;
}
}

View File

@ -34,7 +34,6 @@ interface SocketInterface
* @param int $port Port
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function create(string $ip, int $port);
@ -42,7 +41,6 @@ interface SocketInterface
* Close socket.
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function close();
@ -50,7 +48,6 @@ interface SocketInterface
* Run socket.
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function run();
}

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -70,7 +70,7 @@ interface ContainerInterface
*
* @since 1.0.0
*/
public static function permission(string $path) : string;
public static function permission(string $path) : int;
/**
* Get the parent path of the resource.

View File

@ -30,8 +30,8 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class ContentPutMode extends Enum
{
/* public */ const APPEND = 1;
/* public */ const PREPEND = 2;
/* public */ const REPLACE = 4;
/* public */ const CREATE = 8;
/* public */ const APPEND = 1;
/* public */ const PREPEND = 2;
/* public */ const REPLACE = 4;
/* public */ const CREATE = 8;
}

View File

@ -30,14 +30,14 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class ExtensionType extends Enum
{
/* public */ const UNKNOWN = 1;
/* public */ const CODE = 2;
/* public */ const AUDIO = 4;
/* public */ const VIDEO = 8;
/* public */ const TEXT = 16;
/* public */ const SPREADSHEET = 32;
/* public */ const PDF = 64;
/* public */ const ARCHIVE = 128;
/* public */ const UNKNOWN = 1;
/* public */ const CODE = 2;
/* public */ const AUDIO = 4;
/* public */ const VIDEO = 8;
/* public */ const TEXT = 16;
/* public */ const SPREADSHEET = 32;
/* public */ const PDF = 64;
/* public */ const ARCHIVE = 128;
/* public */ const PRESENTATION = 256;
/* public */ const IMAGE = 512;
/* public */ const IMAGE = 512;
}

View File

@ -26,21 +26,36 @@ namespace phpOMS\System\File;
*/
class FileUtils
{
/* public */ const CODE_EXTENSION = ['cpp', 'c', 'h', 'hpp', 'cs', 'css', 'htm', 'html', 'php', 'rb'];
/* public */ const TEXT_EXTENSION = ['doc', 'docx', 'txt', 'md', 'csv'];
/* public */ const CODE_EXTENSION = ['cpp', 'c', 'h', 'hpp', 'cs', 'css', 'htm', 'html', 'php', 'rb'];
/* public */ const TEXT_EXTENSION = ['doc', 'docx', 'txt', 'md', 'csv'];
/* public */ const PRESENTATION_EXTENSION = ['ppt', 'pptx'];
/* public */ const PDF_EXTENSION = ['pdf'];
/* public */ const ARCHIVE_EXTENSION = ['zip', '7z', 'rar'];
/* public */ const AUDIO_EXTENSION = ['mp3', 'wav'];
/* public */ const VIDEO_EXTENSION = ['mp4'];
/* public */ const SPREADSHEET_EXTENSION = ['xls', 'xlsm'];
/* public */ const IMAGE_EXTENSION = ['png', 'gif', 'jpg', 'jpeg', 'tiff', 'bmp'];
/* public */ const PDF_EXTENSION = ['pdf'];
/* public */ const ARCHIVE_EXTENSION = ['zip', '7z', 'rar'];
/* public */ const AUDIO_EXTENSION = ['mp3', 'wav'];
/* public */ const VIDEO_EXTENSION = ['mp4'];
/* public */ const SPREADSHEET_EXTENSION = ['xls', 'xlsm'];
/* public */ const IMAGE_EXTENSION = ['png', 'gif', 'jpg', 'jpeg', 'tiff', 'bmp'];
/**
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
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);
@ -67,4 +82,41 @@ class FileUtils
return ExtensionType::UNKNOWN;
}
/**
* Make file path absolute
*
* @param string $origPath File path
*
* @return string
*
* @since 1.0.0
*/
public static function absolute(string $origPath) : string
{
if(!file_exists($origPath)) {
$startsWithSlash = strpos($origPath, '/') === 0 ? '/' : '';
$path = [];
$parts = explode('/', $origPath);
foreach($parts as $part) {
if (empty($part) || $part === '.') {
continue;
}
if ($part !== '..') {
$path[] = $part;
} elseif (!empty($path)) {
array_pop($path);
} else {
throw new PathException($origPath);
}
}
return $startsWithSlash . implode('/', $path);
}
return realpath($origPath);
}
}

View File

@ -96,7 +96,7 @@ class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public static function permission(string $path) : string
public static function permission(string $path) : int
{
// TODO: Implement permission() method.
}

View File

@ -192,9 +192,9 @@ class File extends FileAbstract implements FileInterface
/**
* {@inheritdoc}
*/
public static function permission(string $path) : string
public static function permission(string $path) : int
{
return self::parseFtpFileData($path)['permission'] ?? '';
return (int) self::parseFtpFileData($path)['permission'] ?? 0;
}
private static function parseFtpFileData(string $path) : array

View File

@ -32,9 +32,19 @@ class FtpStorage extends StorageAbstract
{
private $con = null;
public function __construct(string $uri, int $port = 21, bool $mode = true, string $login = null, string $pass = null, bool $ssl = false)
private static $instance = null;
public function __construct() {
}
public static function getInstance() : StorageAbstract
{
$this->connect($uri, $port = 21, $mode, $login = null, $pass = null, $ssl = false);
if(!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function connect(string $uri, int $port = 21, bool $mode = true, string $login = null, string $pass = null, bool $ssl = false) : bool
@ -87,7 +97,7 @@ class FtpStorage extends StorageAbstract
/**
* {@inheritdoc}
*/
public static function permission(string $path) : string
public static function permission(string $path) : int
{
// TODO: Implement permission() method.
}
@ -164,6 +174,30 @@ class FtpStorage extends StorageAbstract
// TODO: Implement basename() method.
}
/**
* {@inheritdoc}
*/
public static function dirname(string $path) : string
{
// TODO: Implement basename() method.
}
/**
* {@inheritdoc}
*/
public static function dirpath(string $path) : string
{
// TODO: Implement basename() method.
}
/**
* {@inheritdoc}
*/
public static function list(string $path, string $filter = '*') : array
{
// TODO: Implement basename() method.
}
/**
* {@inheritdoc}
*/

View File

@ -68,7 +68,7 @@ class Directory extends FileAbstract implements DirectoryInterface
}
/**
* List all files in directorz.
* List all files in directory.
*
* @param string $path Path
* @param string $filter Filter
@ -79,10 +79,45 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function list(string $path, string $filter = '*') : array
{
$list = [];
if (!file_exists($path)) {
throw new PathException($path);
}
foreach (glob($path . DIRECTORY_SEPARATOR . $filter) as $filename) {
$list[] = $filename;
$list = [];
$path = rtrim($path, '\\/');
foreach ($iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST) as $item
) {
$list[] = str_replace('\\', '/', $iterator->getSubPathName());
}
return $list;
}
/**
* List all files by extension directory.
*
* @param string $path Path
* @param string $extension Extension
*
* @return array
*
* @since 1.0.0
*/
public static function listByExtension(string $path, string $extension) : array
{
$list = [];
$path = rtrim($path, '\\/');
foreach ($iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST) as $item
) {
if($item->getExtension() === $extension) {
$list[] = str_replace('\\', '/', $iterator->getSubPathName());
}
}
return $list;
@ -121,6 +156,10 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function size(string $dir, bool $recursive = true) : int
{
if (!file_exists($dir)) {
throw new PathException($dir);
}
$countSize = 0;
$count = 0;
@ -147,11 +186,16 @@ class Directory extends FileAbstract implements DirectoryInterface
/**
* {@inheritdoc}
*/
public static function count(string $path, bool $recursive = true, array $ignore = ['.', '..', 'cgi-bin',
'.DS_Store']) : int
public static function count(string $path, bool $recursive = true, array $ignore = []) : int
{
if (!file_exists($path)) {
throw new PathException($path);
}
$size = 0;
$files = scandir($path);
$ignore[] = '.';
$ignore[] = '..';
foreach ($files as $t) {
if (in_array($t, $ignore)) {
@ -174,10 +218,6 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function delete(string $path) : bool
{
if (!file_exists($path) || !is_dir($path)) {
throw new PathException($path);
}
$files = scandir($path);
/* Removing . and .. */
@ -185,10 +225,10 @@ class Directory extends FileAbstract implements DirectoryInterface
unset($files[0]);
foreach ($files as $file) {
if (is_dir($file)) {
self::delete($file);
if (is_dir($path . '/' . $file)) {
self::delete($path . '/' . $file);
} else {
unlink($file);
unlink($path . '/' . $file);
}
}
@ -215,10 +255,7 @@ class Directory extends FileAbstract implements DirectoryInterface
public static function created(string $path) : \DateTime
{
if(!file_exists($path)) {
$created = new \DateTime();
$created->setTimestamp(0);
return $created;
throw new PathException($path);
}
$created = new \DateTime('now');
@ -232,7 +269,14 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function changed(string $path) : \DateTime
{
// TODO: Implement changed() method.
if (!file_exists($path)) {
throw new PathException($path);
}
$changed = new \DateTime();
$changed->setTimestamp(filectime($path));
return $changed;
}
/**
@ -240,15 +284,23 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function owner(string $path) : int
{
// TODO: Implement owner() method.
if (!file_exists($path)) {
throw new PathException($path);
}
return fileowner($path);
}
/**
* {@inheritdoc}
*/
public static function permission(string $path) : string
public static function permission(string $path) : int
{
// TODO: Implement permission() method.
if (!file_exists($path)) {
throw new PathException($path);
}
return fileperms($path);
}
/**
@ -256,7 +308,32 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function copy(string $from, string $to, bool $overwrite = false) : bool
{
// TODO: Implement copy() method.
if (!is_dir($from)) {
throw new PathException($from);
}
if(!$overwrite && file_exists($to)) {
return false;
}
if (!file_exists($to)) {
self::create($to, 0644, true);
} elseif($overwrite && file_exists($to)) {
self::delete($to);
}
foreach ($iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($from, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST) as $item
) {
if ($item->isDir()) {
mkdir($to . '/' . $iterator->getSubPathName());
} else {
copy($from . '/' . $iterator->getSubPathName(), $to . '/' . $iterator->getSubPathName());
}
}
return true;
}
/**
@ -264,7 +341,23 @@ class Directory extends FileAbstract implements DirectoryInterface
*/
public static function move(string $from, string $to, bool $overwrite = false) : bool
{
// TODO: Implement move() method.
if (!is_dir($from)) {
throw new PathException($from);
}
if (!$overwrite && file_exists($to)) {
return false;
} elseif($overwrite && file_exists($to)) {
self::delete($to);
}
if (!self::exists(self::parent($to))) {
self::create(self::parent($to), 0644, true);
}
rename($from, $to);
return true;
}
/**
@ -307,6 +400,10 @@ class Directory extends FileAbstract implements DirectoryInterface
public static function create(string $path, int $permission = 0644, bool $recursive = false) : bool
{
if (!file_exists($path)) {
if(!$recursive && !file_exists(self::parent($path))) {
return false;
}
mkdir($path, $permission, $recursive);
return true;
@ -414,6 +511,22 @@ class Directory extends FileAbstract implements DirectoryInterface
return basename($path);
}
/**
* {@inheritdoc}
*/
public static function dirname(string $path) : string
{
return basename($path);
}
/**
* {@inheritdoc}
*/
public static function dirpath(string $path) : string
{
return $path;
}
/**
* {@inheritdoc}
*/

View File

@ -66,7 +66,6 @@ class File extends FileAbstract implements FileInterface
*/
public static function put(string $path, string $content, int $mode = ContentPutMode::REPLACE | ContentPutMode::CREATE) : bool
{
// todo: create all else cases, right now all getting handled the same way which is wrong
$exists = file_exists($path);
if (
@ -75,11 +74,17 @@ class File extends FileAbstract implements FileInterface
|| (($mode & ContentPutMode::REPLACE) === ContentPutMode::REPLACE && $exists)
|| (!$exists && ($mode & ContentPutMode::CREATE) === ContentPutMode::CREATE)
) {
if (!Directory::exists(dirname($path))) {
Directory::create(dirname($path), 0644, true);
}
if(($mode & ContentPutMode::APPEND) === ContentPutMode::APPEND && $exists) {
file_put_contents($path, file_get_contents($path) . $content);
} elseif(($mode & ContentPutMode::PREPEND) === ContentPutMode::PREPEND && $exists) {
file_put_contents($path, $content . file_get_contents($path));
} else {
if (!Directory::exists(dirname($path))) {
Directory::create(dirname($path), 0644, true);
}
file_put_contents($path, $content);
file_put_contents($path, $content);
}
return true;
}
@ -99,6 +104,14 @@ class File extends FileAbstract implements FileInterface
return file_get_contents($path);
}
/**
* {@inheritdoc}
*/
public static function count(string $path, bool $recursive = true, array $ignore = []) : int
{
return 1;
}
/**
* {@inheritdoc}
*/
@ -204,7 +217,7 @@ class File extends FileAbstract implements FileInterface
/**
* {@inheritdoc}
*/
public static function permission(string $path) : string
public static function permission(string $path) : int
{
if (!file_exists($path)) {
throw new PathException($path);
@ -246,7 +259,7 @@ class File extends FileAbstract implements FileInterface
*/
public static function copy(string $from, string $to, bool $overwrite = false) : bool
{
if (!file_exists($from)) {
if (!is_file($from)) {
throw new PathException($from);
}
@ -255,6 +268,10 @@ class File extends FileAbstract implements FileInterface
Directory::create(dirname($to), 0644, true);
}
if($overwrite && file_exists($to)) {
unlink($to);
}
copy($from, $to);
return true;
@ -268,7 +285,7 @@ class File extends FileAbstract implements FileInterface
*/
public static function move(string $from, string $to, bool $overwrite = false) : bool
{
if (!file_exists($from)) {
if (!is_file($from)) {
throw new PathException($from);
}
@ -277,6 +294,10 @@ class File extends FileAbstract implements FileInterface
Directory::create(dirname($to), 0644, true);
}
if($overwrite && file_exists($to)) {
unlink($to);
}
rename($from, $to);
return true;

View File

@ -16,6 +16,7 @@ declare(strict_types=1);
namespace phpOMS\System\File\Local;
use phpOMS\System\File\ContainerInterface;
use phpOMS\System\File\StorageAbstract;
use phpOMS\System\File\PathException;
/**
* Filesystem class.
@ -30,12 +31,32 @@ use phpOMS\System\File\StorageAbstract;
*/
class LocalStorage extends StorageAbstract
{
private static $instance = null;
public function __construct() {
}
public static function getInstance() : StorageAbstract
{
if(!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
private static function getClassType(string $path) : string
{
return is_dir($path) || (!is_file($path) && stripos($path, '.') === false) ? Directory::class : File::class;
}
/**
* {@inheritdoc}
*/
public static function created(string $path) : \DateTime
{
// TODO: Implement created() method.
return self::getClassType($path)::created($path);
}
/**
@ -43,7 +64,7 @@ class LocalStorage extends StorageAbstract
*/
public static function changed(string $path) : \DateTime
{
// TODO: Implement changed() method.
return self::getClassType($path)::changed($path);
}
/**
@ -51,15 +72,15 @@ class LocalStorage extends StorageAbstract
*/
public static function owner(string $path) : int
{
// TODO: Implement owner() method.
return self::getClassType($path)::owner($path);
}
/**
* {@inheritdoc}
*/
public static function permission(string $path) : string
public static function permission(string $path) : int
{
// TODO: Implement permission() method.
return self::getClassType($path)::permission($path);
}
/**
@ -67,7 +88,7 @@ class LocalStorage extends StorageAbstract
*/
public static function parent(string $path) : string
{
// TODO: Implement parent() method.
return self::getClassType($path)::parent($path);
}
/**
@ -75,7 +96,7 @@ class LocalStorage extends StorageAbstract
*/
public static function create(string $path) : bool
{
// TODO: Implement create() method.
return stripos($path, '.') === false ? Directory::create($path, 0644, true) : File::create($path);
}
/**
@ -83,7 +104,7 @@ class LocalStorage extends StorageAbstract
*/
public static function delete(string $path) : bool
{
// TODO: Implement delete() method.
return self::getClassType($path)::delete($path);
}
/**
@ -91,7 +112,7 @@ class LocalStorage extends StorageAbstract
*/
public static function copy(string $from, string $to, bool $overwrite = false) : bool
{
// TODO: Implement copy() method.
return self::getClassType($from)::copy($from, $to, $overwrite);
}
/**
@ -99,7 +120,7 @@ class LocalStorage extends StorageAbstract
*/
public static function move(string $from, string $to, bool $overwrite = false) : bool
{
// TODO: Implement move() method.
return self::getClassType($from)::move($from, $to, $overwrite);
}
/**
@ -107,7 +128,7 @@ class LocalStorage extends StorageAbstract
*/
public static function size(string $path, bool $recursive = true) : int
{
// TODO: Implement size() method.
return self::getClassType($path)::size($path, $recursive);
}
/**
@ -115,7 +136,7 @@ class LocalStorage extends StorageAbstract
*/
public static function exists(string $path) : bool
{
// TODO: Implement exists() method.
return self::getClassType($path)::exists($path);
}
/**
@ -123,7 +144,7 @@ class LocalStorage extends StorageAbstract
*/
public static function name(string $path) : string
{
// TODO: Implement name() method.
return self::getClassType($path)::name($path);
}
/**
@ -131,7 +152,23 @@ class LocalStorage extends StorageAbstract
*/
public static function basename(string $path) : string
{
// TODO: Implement basename() method.
return self::getClassType($path)::basename($path);
}
/**
* {@inheritdoc}
*/
public static function dirname(string $path) : string
{
return self::getClassType($path)::dirname($path);
}
/**
* {@inheritdoc}
*/
public static function dirpath(string $path) : string
{
return self::getClassType($path)::dirpath($path);
}
/**
@ -139,237 +176,7 @@ class LocalStorage extends StorageAbstract
*/
public static function count(string $path, bool $recursive = true, array $ignore = []) : int
{
// TODO: Implement count() method.
}
/**
* {@inheritdoc}
*/
public function getCount(bool $recursive = false) : int
{
// TODO: Implement getCount() method.
}
/**
* {@inheritdoc}
*/
public function getSize(bool $recursive = false) : int
{
// TODO: Implement getSize() method.
}
/**
* {@inheritdoc}
*/
public function getName() : string
{
// TODO: Implement getName() method.
}
/**
* {@inheritdoc}
*/
public function getPath() : string
{
// TODO: Implement getPath() method.
}
/**
* {@inheritdoc}
*/
public function getParent() : ContainerInterface
{
// TODO: Implement getParent() method.
}
/**
* {@inheritdoc}
*/
public function createNode() : bool
{
// TODO: Implement createNode() method.
}
/**
* {@inheritdoc}
*/
public function copyNode(string $to, bool $overwrite = false) : bool
{
// TODO: Implement copyNode() method.
}
/**
* {@inheritdoc}
*/
public function moveNode(string $to, bool $overwrite = false) : bool
{
// TODO: Implement moveNode() method.
}
/**
* {@inheritdoc}
*/
public function deleteNode() : bool
{
// TODO: Implement deleteNode() method.
}
/**
* {@inheritdoc}
*/
public function getCreatedAt() : \DateTime
{
// TODO: Implement getCreatedAt() method.
}
/**
* {@inheritdoc}
*/
public function getChangedAt() : \DateTime
{
// TODO: Implement getChangedAt() method.
}
/**
* {@inheritdoc}
*/
public function getOwner() : int
{
// TODO: Implement getOwner() method.
}
/**
* {@inheritdoc}
*/
public function getPermission() : string
{
// TODO: Implement getPermission() method.
}
/**
* {@inheritdoc}
*/
public function index()
{
// TODO: Implement index() method.
}
/**
* Return the current element
* @link http://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
* @since 5.0.0
*/
public function current()
{
// TODO: Implement current() method.
}
/**
* Move forward to next element
* @link http://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
* @since 5.0.0
*/
public function next()
{
// TODO: Implement next() method.
}
/**
* Return the key of the current element
* @link http://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
* @since 5.0.0
*/
public function key()
{
// TODO: Implement key() method.
}
/**
* Checks if current position is valid
* @link http://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
* @since 5.0.0
*/
public function valid()
{
// TODO: Implement valid() method.
}
/**
* Rewind the Iterator to the first element
* @link http://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
* @since 5.0.0
*/
public function rewind()
{
// TODO: Implement rewind() method.
}
/**
* Whether a offset exists
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
* @param mixed $offset <p>
* An offset to check for.
* </p>
* @return boolean true on success or false on failure.
* </p>
* <p>
* The return value will be casted to boolean if non-boolean was returned.
* @since 5.0.0
*/
public function offsetExists($offset)
{
// TODO: Implement offsetExists() method.
}
/**
* Offset to retrieve
* @link http://php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset <p>
* The offset to retrieve.
* </p>
* @return mixed Can return all value types.
* @since 5.0.0
*/
public function offsetGet($offset)
{
// TODO: Implement offsetGet() method.
}
/**
* Offset to set
* @link http://php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset <p>
* The offset to assign the value to.
* </p>
* @param mixed $value <p>
* The value to set.
* </p>
* @return void
* @since 5.0.0
*/
public function offsetSet($offset, $value)
{
// TODO: Implement offsetSet() method.
}
/**
* Offset to unset
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset <p>
* The offset to unset.
* </p>
* @return void
* @since 5.0.0
*/
public function offsetUnset($offset)
{
// TODO: Implement offsetUnset() method.
return self::getClassType($path)::count($path, $recursive, $ignore);
}
/**
@ -377,7 +184,11 @@ class LocalStorage extends StorageAbstract
*/
public static function put(string $path, string $content, int $mode = 0) : bool
{
// TODO: Implement put() method.
if(is_dir($path)) {
throw new PathException($path);
}
return File::put($path, $content, $mode);
}
/**
@ -385,23 +196,23 @@ class LocalStorage extends StorageAbstract
*/
public static function get(string $path) : string
{
// TODO: Implement get() method.
if(is_dir($path)) {
throw new PathException($path);
}
return File::get($path);
}
/**
* {@inheritdoc}
*/
public function putContent(string $content, int $mode = 0) : bool
public static function list(string $path, string $filter = '*') : array
{
// TODO: Implement putContent() method.
}
if(is_file($path)) {
throw new PathException($path);
}
/**
* {@inheritdoc}
*/
public function getContent() : string
{
// TODO: Implement getContent() method.
return Directory::list($path, $filter);
}
/**
@ -409,23 +220,7 @@ class LocalStorage extends StorageAbstract
*/
public static function sanitize(string $path, string $replace = '') : string
{
// TODO: Implement sanitize() method.
}
/**
* {@inheritdoc}
*/
public function getNode(string $name)
{
// TODO: Implement getNode() method.
}
/**
* {@inheritdoc}
*/
public function addNode($file) : bool
{
// TODO: Implement addNode() method.
return self::getClassType($path)::sanitize($path, $replace);
}
/**
@ -433,7 +228,11 @@ class LocalStorage extends StorageAbstract
*/
public static function set(string $path, string $content) : bool
{
// TODO: Implement set() method.
if(is_dir($path)) {
throw new PathException($path);
}
return File::set($path, $content);
}
/**
@ -441,7 +240,11 @@ class LocalStorage extends StorageAbstract
*/
public static function append(string $path, string $content) : bool
{
// TODO: Implement append() method.
if(is_dir($path)) {
throw new PathException($path);
}
return File::append($path, $content);
}
/**
@ -449,7 +252,11 @@ class LocalStorage extends StorageAbstract
*/
public static function prepend(string $path, string $content) : bool
{
// TODO: Implement prepend() method.
if(is_dir($path)) {
throw new PathException($path);
}
return File::prepend($path, $content);
}
/**
@ -457,38 +264,10 @@ class LocalStorage extends StorageAbstract
*/
public static function extension(string $path) : string
{
// TODO: Implement extension() method.
}
if(is_dir($path)) {
throw new PathException($path);
}
/**
* {@inheritdoc}
*/
public function setContent(string $content) : bool
{
// TODO: Implement setContent() method.
}
/**
* {@inheritdoc}
*/
public function appendContent(string $content) : bool
{
// TODO: Implement appendContent() method.
}
/**
* {@inheritdoc}
*/
public function prependContent(string $content) : bool
{
// TODO: Implement prependContent() method.
}
/**
* {@inheritdoc}
*/
public function getExtension() : string
{
// TODO: Implement getExtension() method.
return File::extension($path);
}
}

View File

@ -40,6 +40,7 @@ final class Storage
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
@ -73,6 +74,7 @@ final class Storage
$env = __NAMESPACE__ . '\\' . $env . '\\' . $env . 'Storage';
try {
/** @var StorageAbstract $env */
$env = $env::getInstance();
self::$registered[$stg] = $env;

View File

@ -26,16 +26,8 @@ namespace phpOMS\System\File;
* @link http://orange-management.com
* @since 1.0.0
*/
abstract class StorageAbstract implements DirectoryInterface, FileInterface
abstract class StorageAbstract
{
/**
* Singleton instance.
*
* @var StorageAbstract
* @since 1.0.0
*/
protected static $instance = null;
/**
* Storage type.
*
@ -48,6 +40,7 @@ abstract class StorageAbstract implements DirectoryInterface, FileInterface
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
@ -62,13 +55,8 @@ abstract class StorageAbstract implements DirectoryInterface, FileInterface
*/
public static function getInstance() : StorageAbstract
{
if(!isset(static::$instance)) {
static::$instance = new static();
}
return static::$instance;
return null;
}
/**
* Get storage type.
*
@ -80,4 +68,124 @@ abstract class StorageAbstract implements DirectoryInterface, FileInterface
{
return $this->type;
}
/**
* {@inheritdoc}
*/
public abstract static function created(string $path) : \DateTime;
/**
* {@inheritdoc}
*/
public abstract static function changed(string $path) : \DateTime;
/**
* {@inheritdoc}
*/
public abstract static function owner(string $path) : int;
/**
* {@inheritdoc}
*/
public abstract static function permission(string $path) : int;
/**
* {@inheritdoc}
*/
public abstract static function parent(string $path) : string;
/**
* {@inheritdoc}
*/
public abstract static function create(string $path) : bool;
/**
* {@inheritdoc}
*/
public abstract static function delete(string $path) : bool;
/**
* {@inheritdoc}
*/
public abstract static function copy(string $from, string $to, bool $overwrite = false) : bool;
/**
* {@inheritdoc}
*/
public abstract static function move(string $from, string $to, bool $overwrite = false) : bool;
/**
* {@inheritdoc}
*/
public abstract static function size(string $path, bool $recursive = true) : int;
/**
* {@inheritdoc}
*/
public abstract static function exists(string $path) : bool;
/**
* {@inheritdoc}
*/
public abstract static function name(string $path) : string;
/**
* {@inheritdoc}
*/
public abstract static function basename(string $path) : string;
/**
* {@inheritdoc}
*/
public abstract static function dirname(string $path) : string;
/**
* {@inheritdoc}
*/
public abstract static function dirpath(string $path) : string;
/**
* {@inheritdoc}
*/
public abstract static function list(string $path, string $filter = '*') : array;
/**
* {@inheritdoc}
*/
public abstract static function count(string $path, bool $recursive = true, array $ignore = []) : int;
/**
* {@inheritdoc}
*/
public abstract static function put(string $path, string $content, int $mode = 0) : bool;
/**
* {@inheritdoc}
*/
public abstract static function get(string $path) : string;
/**
* {@inheritdoc}
*/
public abstract static function sanitize(string $path, string $replace = '') : string;
/**
* {@inheritdoc}
*/
public abstract static function set(string $path, string $content) : bool;
/**
* {@inheritdoc}
*/
public abstract static function append(string $path, string $content) : bool;
/**
* {@inheritdoc}
*/
public abstract static function prepend(string $path, string $content) : bool;
/**
* {@inheritdoc}
*/
public abstract static function extension(string $path) : string;
}

View File

@ -30,8 +30,8 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class SystemType extends Enum
{
/* public */ const UNKNOWN = 1;
/* public */ const WIN = 2;
/* public */ const LINUX = 3;
/* public */ const OSX = 4;
/* public */ const UNKNOWN = 1;
/* public */ const WIN = 2;
/* public */ const LINUX = 3;
/* public */ const OSX = 4;
}

View File

@ -31,6 +31,7 @@ class SystemUtils
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{

View File

@ -35,6 +35,7 @@ final class UnhandledHandler
* @return void
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public static function exceptionHandler(\Throwable $e) /* : void */
{
@ -60,12 +61,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,
@ -83,6 +93,7 @@ final class UnhandledHandler
* @return void
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public static function shutdownHandler() /* : void */
{

View File

@ -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)) {
@ -278,19 +278,6 @@ class Http implements UriInterface
return $this->path . (!empty($query) ? '?' . $this->getQuery() : '');
}
/**
* {@inheritdoc}
*/
public function getPathElement(int $pos = null) : string
{
return explode('/', $this->path)[$pos];
}
public function getPathElements() : array
{
return explode('/', $this->path);
}
/**
* {@inheritdoc}
*/
@ -305,6 +292,22 @@ class Http implements UriInterface
return $this->queryString;
}
/**
* {@inheritdoc}
*/
public function getPathElement(int $pos = null) : string
{
return explode('/', $this->path)[$pos] ?? '';
}
/**
* {@inheritdoc}
*/
public function getPathElements() : array
{
return explode('/', $this->path);
}
/**
* {@inheritdoc}
*/

View File

@ -41,6 +41,7 @@ class UriFactory
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{

View File

@ -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.
*

View File

@ -28,19 +28,19 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class UriScheme extends Enum
{
/* public */ const HTTP = 0; /* Http */
/* public */ const FILE = 1; /* File */
/* public */ const HTTP = 0; /* Http */
/* public */ const FILE = 1; /* File */
/* public */ const MAILTO = 2; /* Mail */
/* public */ const FTP = 3; /* FTP */
/* public */ const HTTPS = 4; /* Https */
/* public */ const IRC = 5; /* IRC */
/* public */ const TEL = 6; /* Telephone */
/* public */ const FTP = 3; /* FTP */
/* public */ const HTTPS = 4; /* Https */
/* public */ const IRC = 5; /* IRC */
/* public */ const TEL = 6; /* Telephone */
/* public */ const TELNET = 7; /* Telnet */
/* public */ const SSH = 8; /* SSH */
/* public */ const SKYPE = 9; /* Skype */
/* public */ const SSL = 10; /* SSL */
/* public */ const NFS = 11; /* Network File System */
/* public */ const GEO = 12; /* Geo location */
/* public */ const SSH = 8; /* SSH */
/* public */ const SKYPE = 9; /* Skype */
/* public */ const SSL = 10; /* SSL */
/* public */ const NFS = 11; /* Network File System */
/* public */ const GEO = 12; /* Geo location */
/* public */ const MARKET = 13; /* Android Market */
/* public */ const ITMS = 14; /* iTunes */
/* public */ const ITMS = 14; /* iTunes */
}

View File

@ -31,6 +31,7 @@ class ArrayUtils
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
@ -294,6 +295,7 @@ class ArrayUtils
// see collection collapse as alternative?!
$flat = [];
$stack = array_values($array);
while (!empty($stack)) {
$value = array_shift($stack);
@ -322,7 +324,6 @@ class ArrayUtils
{
$count = $count === 0 ? count($array) : $start + $count;
$sum = 0;
$array = array_values($array);
for ($i = $start; $i <= $count - 1; $i++) {

View File

@ -28,7 +28,7 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class AngleType extends Enum
{
/* public */ const DEGREE = 'º';
/* public */ const DEGREE = 'deg';
/* public */ const RADIAN = 'rad';
/* public */ const SECOND = 'arcsec';
/* public */ const MINUTE = 'arcmin';

View File

@ -46,6 +46,7 @@ class Currency
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
@ -97,7 +98,7 @@ class Currency
public static function getEcbEuroRates() : array
{
if (!isset(self::$ecbCurrencies)) {
$request = new Request(new Localization(), new Http('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'));
$request = new Request(new Http('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'));
$request->setMethod(RequestMethod::GET);
$xml = new \SimpleXMLElement(Rest::request($request));

View File

@ -31,6 +31,7 @@ class File
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{

View File

@ -28,6 +28,12 @@ class Ip
{
/* public */ const IP_TABLE_ITERATIONS = 100;
/**
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
}

View File

@ -26,6 +26,15 @@ namespace phpOMS\Utils\Converter;
*/
class Measurement
{
/**
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
}
/**
* Convert temperature.
@ -88,7 +97,7 @@ class Measurement
$value = ($value - 273.15) * 1.5 - 100;
break;
case TemperatureType::NEWTON:
$value = ($value - 273.15) / 0.33;
$value = ($value - 273.15) * 0.33;
break;
case TemperatureType::ROMER:
$value = ($value - 273.15) * 0.525 + 7.5;
@ -1221,7 +1230,7 @@ class Measurement
*
* @since 1.0.0
*/
public static function convertEnergie(float $value, string $from = EnergyPowerType::JOULS, string $to = EnergyPowerType::KILOWATT_HOUERS) : float
public static function convertEnergy(float $value, string $from = EnergyPowerType::JOULS, string $to = EnergyPowerType::KILOWATT_HOUERS) : float
{
switch ($from) {
case EnergyPowerType::JOULS:

View File

@ -39,6 +39,7 @@ class Numeric
* Constructor.
*
* @since 1.0.0
* @codeCoverageIgnore
*/
private function __construct()
{
@ -73,7 +74,7 @@ class Numeric
$newOutput = 0;
for ($i = 1; $i <= $numberLen; $i++) {
$newOutput = bcadd($newOutput, bcmul(array_search($number[$i - 1], $fromBase), bcpow($fromLen, $numberLen - $i)));
$newOutput = bcadd((string) $newOutput, bcmul((string) array_search($number[$i - 1], $fromBase), bcpow((string) $fromLen, (string) ($numberLen - $i))));
}
return $newOutput;
@ -86,8 +87,8 @@ class Numeric
}
while ($base10 !== '0') {
$newOutput = $toBase[bcmod($base10, $toLen)] . $newOutput;
$base10 = bcdiv($base10, $toLen, 0);
$newOutput = $toBase[bcmod($base10, (string) $toLen)] . $newOutput;
$base10 = bcdiv($base10, (string) $toLen, 0);
}
return $newOutput;

Some files were not shown because too many files have changed in this diff Show More