This commit is contained in:
Dennis Eichhorn 2016-03-16 22:33:44 +01:00
parent 6781777cd4
commit 9dd230df36
11 changed files with 506 additions and 353 deletions

View File

@ -190,9 +190,9 @@ class Matrix implements ArrayAccess, Iterator
switch($algorithm) { switch($algorithm) {
case InversionType::GAUSS_JORDAN: case InversionType::GAUSS_JORDAN:
return $this->inverseGaussJordan(); return $this->inverseGaussJordan();
default: default:
throw new \Exception(''); throw new \Exception('');
} }
} }
@ -298,31 +298,31 @@ class Matrix implements ArrayAccess, Iterator
for ($i = 0; $i < $n; $i++) { for ($i = 0; $i < $n; $i++) {
$max = 0; $max = 0;
for ($j = $i; $j < $n; $j++) { for ($j = $i; $j < $n; $j++) {
if (abs($arr[$j][$i]) > abs($arr[$max][$i])) { if (abs($arr[$j][$i]) > abs($arr[$max][$i])) {
$max = $j; $max = $j;
} }
} }
if ($max) { if ($max) {
$sign = -$sign; $sign = -$sign;
$temp = $arr[$i]; $temp = $arr[$i];
$arr[$i] = $arr[$max]; $arr[$i] = $arr[$max];
$arr[$max] = $temp; $arr[$max] = $temp;
} }
if (!$arr[$i][$i]) { if (!$arr[$i][$i]) {
return 0; return 0;
} }
for ($j = $i + 1; $j < $n; $j++) { for ($j = $i + 1; $j < $n; $j++) {
$r = $arr[$j][$i] / $arr[$i][$i]; $r = $arr[$j][$i] / $arr[$i][$i];
if (!$r) { if (!$r) {
continue; continue;
} }
for ($c = $i; $c < $n; $c ++) { for ($c = $i; $c < $n; $c ++) {
$arr[$j][$c] -= $arr[$i][$c] * $r; $arr[$j][$c] -= $arr[$i][$c] * $r;
} }

View File

@ -106,7 +106,33 @@ class Request extends RequestAbstract
public function init($uri = null) public function init($uri = null)
{ {
if ($uri === null) { if ($uri === null) {
$this->data = $_GET ?? []; $this->initCurrentRequest();
} else {
$this->initPseudoRequest($uri);
}
$this->data = array_change_key_case($this->data, CASE_LOWER);
$this->cleanupGlobals();
$this->path = explode('/', $this->uri->getPath());
$this->l11n->setLanguage($this->path[0]);
$this->setupUriBuilder();
$this->createRequestHashs();
}
/**
* Init current request
*
* @return void
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private function initCurrentRequest()
{
$this->data = $_GET ?? [];
if (isset($_SERVER['CONTENT_TYPE'])) { if (isset($_SERVER['CONTENT_TYPE'])) {
if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
@ -124,26 +150,50 @@ class Request extends RequestAbstract
} }
$this->uri->set(Http::getCurrent()); $this->uri->set(Http::getCurrent());
} else { }
$this->setMethod($uri['type']);
$this->uri->set($uri['uri']);
}
$this->data = array_change_key_case($this->data, CASE_LOWER); /**
* Init pseudo request
unset($_FILES); *
unset($_GET); * @param mixed $uri Uri to handle as request
unset($_POST); *
unset($_REQUEST); * @return void
*
$this->path = explode('/', $this->uri->getPath()); * @since 1.0.0
$this->l11n->setLanguage($this->path[0]); * @author Dennis Eichhorn <d.eichhorn@oms.com>
$this->hash = []; */
private function initPseudoRequest($uri)
{
$this->setMethod($uri['type']);
$this->uri->set($uri['uri']);
}
/**
* Setup uri builder based on current request
*
* @return void
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private function setupUriBuilder()
{
UriFactory::setQuery('/scheme', $this->uri->getScheme()); UriFactory::setQuery('/scheme', $this->uri->getScheme());
UriFactory::setQuery('/host', $this->uri->getHost()); UriFactory::setQuery('/host', $this->uri->getHost());
UriFactory::setQuery('/lang', $this->l11n->getLanguage()); UriFactory::setQuery('/lang', $this->l11n->getLanguage());
}
/**
* Create request hashs of current request
*
* @return void
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private function createRequestHashs()
{
$this->hash = [];
foreach ($this->path as $key => $path) { foreach ($this->path as $key => $path) {
$paths = []; $paths = [];
for ($i = 1; $i < $key + 1; $i++) { for ($i = 1; $i < $key + 1; $i++) {
@ -154,6 +204,22 @@ class Request extends RequestAbstract
} }
} }
/**
* Clean up globals that musn't be used any longer
*
* @return void
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private function cleanupGlobals()
{
unset($_FILES);
unset($_GET);
unset($_POST);
unset($_REQUEST);
}
/** /**
* Is Mobile * Is Mobile
* *

View File

@ -32,7 +32,7 @@ use phpOMS\Uri\UriInterface;
* @link http://orange-management.com * @link http://orange-management.com
* @since 1.0.0 * @since 1.0.0
*/ */
abstract class RequestAbstract implements RequestInterface abstract class RequestAbstract implements MessageInterface
{ {
/** /**
@ -126,7 +126,12 @@ abstract class RequestAbstract implements RequestInterface
} }
/** /**
* {@inheritdoc} * Get request uri.
*
* @return UriInterface
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function getUri() : UriInterface public function getUri() : UriInterface
{ {
@ -134,7 +139,12 @@ abstract class RequestAbstract implements RequestInterface
} }
/** /**
* {@inheritdoc} * Set request uri.
*
* @param UriInterface $uri
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function setUri(UriInterface $uri) public function setUri(UriInterface $uri)
{ {
@ -142,7 +152,12 @@ abstract class RequestAbstract implements RequestInterface
} }
/** /**
* {@inheritdoc} * Get request hash.
*
* @return array
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function getHash() : array public function getHash() : array
{ {
@ -170,12 +185,22 @@ abstract class RequestAbstract implements RequestInterface
} }
/** /**
* {@inheritdoc} * Get request method.
*
* @return string
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
abstract public function getMethod() : string; abstract public function getMethod() : string;
/** /**
* {@inheritdoc} * Set request method.
*
* @param string $method
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function setMethod(string $method) { public function setMethod(string $method) {
$this->method = $method; $this->method = $method;
@ -273,4 +298,14 @@ abstract class RequestAbstract implements RequestInterface
{ {
return $this->uri->__toString(); return $this->uri->__toString();
} }
/**
* Get request target.
*
* @return string
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
abstract public function getRequestTarget() : string;
} }

View File

@ -1,93 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.0
*
* @category TBD
* @package TBD
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @copyright 2013 Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
namespace phpOMS\Message;
use phpOMS\Uri\UriInterface;
/**
* Http request interface.
*
* @category Framework
* @package phpOMS\Response
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
interface RequestInterface extends MessageInterface
{
/**
* Get request target.
*
* @return string
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function getRequestTarget() : string;
/**
* Get request method.
*
* @return string
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function getMethod() : string;
/**
* Set request method.
*
* @param string $method
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function setMethod(string $method);
/**
* Get request uri.
*
* @return UriInterface
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function getUri() : UriInterface;
/**
* Set request uri.
*
* @param UriInterface $uri
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function setUri(UriInterface $uri);
/**
* Get request hash.
*
* @return array
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function getHash() : array;
}

View File

@ -31,7 +31,7 @@ use phpOMS\Utils\ArrayUtils;
* @link http://orange-management.com * @link http://orange-management.com
* @since 1.0.0 * @since 1.0.0
*/ */
abstract class ResponseAbstract implements ResponseInterface, ArrayableInterface, JsonableInterface abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, JsonableInterface
{ {
/** /**
@ -159,4 +159,16 @@ abstract class ResponseAbstract implements ResponseInterface, ArrayableInterface
{ {
return json_encode($this->toArray()); return json_encode($this->toArray());
} }
/**
* Generate header automatically based on code.
*
* @param int $code HTTP status code
*
* @return void
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
abstract public function generateHeader(int $code);
} }

View File

@ -1,43 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.0
*
* @category TBD
* @package TBD
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @copyright 2013 Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
namespace phpOMS\Message;
/**
* Response interface.
*
* @category Framework
* @package phpOMS\Response
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @license OMS License 1.0
* @link http://orange-management.com
* @since 1.0.0
*/
interface ResponseInterface extends MessageInterface
{
/**
* Generate header automatically based on code.
*
* @param int $code HTTP status code
*
* @return void
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function generateHeader(int $code);
}

View File

@ -77,29 +77,10 @@ class ModuleFactory
if (!isset(self::$loaded[$module])) { if (!isset(self::$loaded[$module])) {
try { try {
$class = '\\Modules\\' . $module . '\\Controller'; $class = '\\Modules\\' . $module . '\\Controller';
/**
* @var ModuleAbstract $obj
*/
$obj = new $class($app); $obj = new $class($app);
self::$loaded[$module] = $obj; self::$loaded[$module] = $obj;
self::registerRequesting($obj);
/** Install providing for */ self::registerProvided($obj);
foreach ($obj->getProviding() as $providing) {
if (isset(self::$loaded[$providing])) {
self::$loaded[$providing]->addReceiving($obj->getName());
} else {
self::$providing[$providing][] = $obj->getName();
}
}
/** Check if I get provided with */
$name = $obj->getName();
if (isset(self::$providing[$name])) {
foreach (self::$providing[$name] as $providing) {
self::$loaded[$name]->addReceiving($providing);
}
}
} catch(\Exception $e) { } catch(\Exception $e) {
self::$loaded[$module] = new NullModule($app); self::$loaded[$module] = new NullModule($app);
} }
@ -107,4 +88,41 @@ class ModuleFactory
return self::$loaded[$module]; return self::$loaded[$module];
} }
/**
* Load modules this module is requesting from
*
* @param ModuleAbstract $obj Current module
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private static function registerRequesting(ModuleAbstract $obj)
{
foreach ($obj->getProviding() as $providing) {
if (isset(self::$loaded[$providing])) {
self::$loaded[$providing]->addReceiving($obj->getName());
} else {
self::$providing[$providing][] = $obj->getName();
}
}
}
/**
* Register modules this module is receiving from
*
* @param ModuleAbstract $obj Current module
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private static function registerProvided(ModuleAbstract $obj)
{
$name = $obj->getName();
if (isset(self::$providing[$name])) {
foreach (self::$providing[$name] as $providing) {
self::$loaded[$name]->addReceiving($providing);
}
}
}
} }

View File

@ -146,37 +146,37 @@ class ModuleManager
if (!isset($this->uriLoad)) { if (!isset($this->uriLoad)) {
switch ($this->app->dbPool->get('core')->getType()) { switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL: case DatabaseType::MYSQL:
$uriHash = $request->getHash(); $uriHash = $request->getHash();
$uriPdo = ''; $uriPdo = '';
$i = 1; $i = 1;
$c = count($uriHash); $c = count($uriHash);
for ($k = 0; $k < $c; $k++) { for ($k = 0; $k < $c; $k++) {
$uriPdo .= ':pid' . $i . ','; $uriPdo .= ':pid' . $i . ',';
$i++; $i++;
} }
$uriPdo = rtrim($uriPdo, ','); $uriPdo = rtrim($uriPdo, ',');
/* TODO: make join in order to see if they are active */ /* TODO: make join in order to see if they are active */
$sth = $this->app->dbPool->get('core')->con->prepare( $sth = $this->app->dbPool->get('core')->con->prepare(
'SELECT 'SELECT
`' . $this->app->dbPool->get('core')->prefix . 'module_load`.`module_load_type`, `' . $this->app->dbPool->get('core')->prefix . 'module_load`.* `' . $this->app->dbPool->get('core')->prefix . 'module_load`.`module_load_type`, `' . $this->app->dbPool->get('core')->prefix . 'module_load`.*
FROM FROM
`' . $this->app->dbPool->get('core')->prefix . 'module_load` `' . $this->app->dbPool->get('core')->prefix . 'module_load`
WHERE WHERE
`module_load_pid` IN(' . $uriPdo . ')' `module_load_pid` IN(' . $uriPdo . ')'
); );
$i = 1; $i = 1;
foreach ($uriHash as $hash) { foreach ($uriHash as $hash) {
$sth->bindValue(':pid' . $i, $hash, \PDO::PARAM_STR); $sth->bindValue(':pid' . $i, $hash, \PDO::PARAM_STR);
$i++; $i++;
} }
$sth->execute(); $sth->execute();
$this->uriLoad = $sth->fetchAll(\PDO::FETCH_GROUP); $this->uriLoad = $sth->fetchAll(\PDO::FETCH_GROUP);
} }
} }
@ -220,10 +220,10 @@ class ModuleManager
if ($this->active === null) { if ($this->active === null) {
switch ($this->app->dbPool->get('core')->getType()) { switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL: 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('core')->con->prepare('SELECT `module_path` FROM `' . $this->app->dbPool->get('core')->prefix . 'module` WHERE `module_active` = 1');
$sth->execute(); $sth->execute();
$this->active = $sth->fetchAll(\PDO::FETCH_COLUMN); $this->active = $sth->fetchAll(\PDO::FETCH_COLUMN);
break; break;
} }
} }
@ -298,75 +298,73 @@ class ModuleManager
$path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json'); $path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json');
if ($path !== false) { if($path === false || strpos($path, self::MODULE_PATH) === false) {
if (strpos($path, self::MODULE_PATH) === false) { throw new PathException($module);
throw new PathException($oldPath); }
}
$info = json_decode(file_get_contents($path), true); $info = json_decode(file_get_contents($path), true);
if (!isset($info)) { if (!isset($info)) {
throw new InvalidJsonException($path); throw new InvalidJsonException($path);
} }
switch ($this->app->dbPool->get('core')->getType()) { switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL: case DatabaseType::MYSQL:
$this->app->dbPool->get('core')->con->beginTransaction(); $this->app->dbPool->get('core')->con->beginTransaction();
$sth = $this->app->dbPool->get('core')->con->prepare( $sth = $this->app->dbPool->get('core')->con->prepare(
'INSERT INTO `' . $this->app->dbPool->get('core')->prefix . 'module` (`module_id`, `module_theme`, `module_path`, `module_active`, `module_version`) VALUES 'INSERT INTO `' . $this->app->dbPool->get('core')->prefix . 'module` (`module_id`, `module_theme`, `module_path`, `module_active`, `module_version`) VALUES
(:internal, :theme, :path, :active, :version);' (:internal, :theme, :path, :active, :version);'
); );
$sth->bindValue(':internal', $info['name']['internal'], \PDO::PARAM_INT); $sth->bindValue(':internal', $info['name']['internal'], \PDO::PARAM_INT);
$sth->bindValue(':theme', 'Default', \PDO::PARAM_STR); $sth->bindValue(':theme', 'Default', \PDO::PARAM_STR);
$sth->bindValue(':path', $info['directory'], \PDO::PARAM_STR); $sth->bindValue(':path', $info['directory'], \PDO::PARAM_STR);
$sth->bindValue(':active', 1, \PDO::PARAM_INT); $sth->bindValue(':active', 1, \PDO::PARAM_INT);
$sth->bindValue(':version', $info['version'], \PDO::PARAM_STR); $sth->bindValue(':version', $info['version'], \PDO::PARAM_STR);
$sth->execute();
$sth = $this->app->dbPool->get('core')->con->prepare(
'INSERT INTO `' . $this->app->dbPool->get('core')->prefix . 'module_load` (`module_load_pid`, `module_load_type`, `module_load_from`, `module_load_for`, `module_load_file`) VALUES
(:pid, :type, :from, :for, :file);'
);
foreach ($info['load'] as $val) {
foreach ($val['pid'] as $pid) {
$sth->bindValue(':pid', $pid, \PDO::PARAM_STR);
$sth->bindValue(':type', $val['type'], \PDO::PARAM_INT);
$sth->bindValue(':from', $val['from'], \PDO::PARAM_STR);
$sth->bindValue(':for', $val['for'], \PDO::PARAM_STR);
$sth->bindValue(':file', $val['file'], \PDO::PARAM_STR);
$sth->execute(); $sth->execute();
}
$sth = $this->app->dbPool->get('core')->con->prepare(
'INSERT INTO `' . $this->app->dbPool->get('core')->prefix . 'module_load` (`module_load_pid`, `module_load_type`, `module_load_from`, `module_load_for`, `module_load_file`) VALUES
(:pid, :type, :from, :for, :file);'
);
foreach ($info['load'] as $val) {
foreach ($val['pid'] as $pid) {
$sth->bindValue(':pid', $pid, \PDO::PARAM_STR);
$sth->bindValue(':type', $val['type'], \PDO::PARAM_INT);
$sth->bindValue(':from', $val['from'], \PDO::PARAM_STR);
$sth->bindValue(':for', $val['for'], \PDO::PARAM_STR);
$sth->bindValue(':file', $val['file'], \PDO::PARAM_STR);
$sth->execute();
}
}
$this->app->dbPool->get('core')->con->commit();
break;
} }
foreach ($info['dependencies'] as $key => $version) { $this->app->dbPool->get('core')->con->commit();
$this->install($key);
}
$class = '\\Modules\\' . $module . '\\Admin\\Installer'; break;
/** @var $class InstallerAbstract */ }
$class::install($this->app->dbPool, $info);
foreach ($info['dependencies'] as $key => $version) {
$this->install($key);
}
$class = '\\Modules\\' . $module . '\\Admin\\Installer';
/** @var $class InstallerAbstract */
$class::install($this->app->dbPool, $info);
// TODO: change this // TODO: change this
$this->installed[$module] = true; $this->installed[$module] = true;
foreach ($info['providing'] as $key => $version) { foreach ($info['providing'] as $key => $version) {
$this->installProviding($module, $key); $this->installProviding($module, $key);
} }
/* Install receiving */ /* Install receiving */
foreach ($installed as $key => $value) { foreach ($installed as $key => $value) {
$this->installProviding($key, $module); $this->installProviding($key, $module);
}
} }
} }
@ -383,10 +381,10 @@ class ModuleManager
if ($this->installed === null) { if ($this->installed === null) {
switch ($this->app->dbPool->get('core')->getType()) { switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL: case DatabaseType::MYSQL:
$sth = $this->app->dbPool->get('core')->con->prepare('SELECT `module_id`,`module_theme`,`module_version`,`module_id` FROM `' . $this->app->dbPool->get('core')->prefix . 'module`'); $sth = $this->app->dbPool->get('core')->con->prepare('SELECT `module_id`,`module_theme`,`module_version`,`module_id` FROM `' . $this->app->dbPool->get('core')->prefix . 'module`');
$sth->execute(); $sth->execute();
$this->installed = $sth->fetchAll(\PDO::FETCH_GROUP); $this->installed = $sth->fetchAll(\PDO::FETCH_GROUP);
break; break;
} }
} }
@ -436,7 +434,7 @@ class ModuleManager
'message' => 'Trying to initialize ' . $m . ' without controller.', 'message' => 'Trying to initialize ' . $m . ' without controller.',
'line' => $e->getLine(), 'line' => $e->getLine(),
'file' => $e->getFile(), 'file' => $e->getFile(),
]); ]);
} }
} }
} elseif (is_string($module) && realpath(self::MODULE_PATH . '/' . $module . '/Controller.php') !== false) { } elseif (is_string($module) && realpath(self::MODULE_PATH . '/' . $module . '/Controller.php') !== false) {

View File

@ -15,7 +15,6 @@
*/ */
namespace phpOMS\Module; namespace phpOMS\Module;
/** /**
* Module abstraction class. * Module abstraction class.
* *

View File

@ -121,12 +121,14 @@ class MultiMap implements \Countable
*/ */
private function garbageCollect() private function garbageCollect()
{ {
/* garbage collect keys */
foreach ($this->keys as $key => $keyValue) { foreach ($this->keys as $key => $keyValue) {
if (!isset($this->values[$keyValue])) { if (!isset($this->values[$keyValue])) {
unset($this->keys[$key]); unset($this->keys[$key]);
} }
} }
/* garbage collect values */
foreach ($this->values as $valueKey => $value) { foreach ($this->values as $valueKey => $value) {
if (!in_array($valueKey, $this->keys)) { if (!in_array($valueKey, $this->keys)) {
unset($this->values[$valueKey]); unset($this->values[$valueKey]);
@ -146,29 +148,59 @@ class MultiMap implements \Countable
*/ */
public function get($key) public function get($key)
{ {
if($this->keyType === KeyType::MULTIPLE) { if($this->keyType === KeyType::SINGLE) {
return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null; return $this->getSingle($key);
} else { } else {
if(is_array($key)) { return $this->getMultiple($key);
if($this->orderType === OrderType::LOOSE) {
$keys = Permutation::permut($key);
foreach($keys as $key => $value) {
$key = implode($value, ':');
if(isset($this->keys[$key])) {
return $this->values[$this->keys[$key]];
}
}
} else {
$key = implode($key, ':');
}
}
return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null;
} }
} }
/**
* Get data.
*
* @param mixed $key Key used to identify value
*
* @return mixed
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function getSingle($key)
{
return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null;
}
/**
* Get data.
*
* @param mixed $key Key used to identify value
*
* @return mixed
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function getMultiple($key)
{
if(is_array($key)) {
if($this->orderType === OrderType::LOOSE) {
$keys = Permutation::permut($key);
foreach($keys as $key => $value) {
$key = implode($value, ':');
if(isset($this->keys[$key])) {
return $this->values[$this->keys[$key]];
}
}
} else {
$key = implode($key, ':');
}
}
return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null;
}
/** /**
* Set existing key with data. * Set existing key with data.
* *
@ -183,23 +215,59 @@ class MultiMap implements \Countable
public function set($key, $value) : bool public function set($key, $value) : bool
{ {
if($this->keyType === KeyType::MULTIPLE && is_array($key)) { if($this->keyType === KeyType::MULTIPLE && is_array($key)) {
if($this->orderType !== OrderType::LOOSE) { return $this->setMultiple($key, $value);
$permutation = Permutation::permut($key); } else {
return $this->setSingle($key, $value);
}
foreach($permuation as $permut) { return false;
if($this->set(implode($permut, ':'), $value)) { }
return true;
} /**
* Set existing key with data.
*
* @param mixed $key Key used to identify value
* @param mixed $value Value to store
*
* @return bool
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function setSingle($key, $value) : bool
{
if (isset($this->keys[$key])) {
$this->values[$this->keys[$key]] = $value;
return true;
}
return false;
}
/**
* Set existing key with data.
*
* @param mixed $key Key used to identify value
* @param mixed $value Value to store
*
* @return bool
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function setMultiple($key, $value) : bool
{
if($this->orderType !== OrderType::LOOSE) {
$permutation = Permutation::permut($key);
foreach($permuation as $permut) {
if($this->set(implode($permut, ':'), $value)) {
return true;
} }
} else {
return $this->set(implode($key, ':'));
} }
} else { } else {
if (isset($this->keys[$key])) { return $this->set(implode($key, ':'));
$this->values[$this->keys[$key]] = $value;
return true;
}
} }
return false; return false;
@ -218,34 +286,64 @@ class MultiMap implements \Countable
public function remove($key) : bool public function remove($key) : bool
{ {
if($this->keyType === KeyType::MULTIPLE && is_array($key)) { if($this->keyType === KeyType::MULTIPLE && is_array($key)) {
if($this->orderType === OrderType::LOOSE) { return $this->removeMultiple($key);
$keys = Permutation::permut($key);
$removed = false;
foreach($keys as $key => $value) {
$removed |= $this->remove(implode($value, ':'));
}
return $removed;
} else {
return $this->remove(implode($key, ':'));
}
} else { } else {
if (isset($this->keys[$key])) { return $this->removeSingle($key);
$id = $this->keys[$key]; }
}
unset($this->values[$id]); /**
* Remove value and all sibling keys based on key.
*
* @param mixed $key Key used to identify value
*
* @return bool
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function removeSingle($key) : bool
{
if (isset($this->keys[$key])) {
$id = $this->keys[$key];
$this->garbageCollect(); unset($this->values[$id]);
return true; $this->garbageCollect();
}
return true;
} }
return false; return false;
} }
/**
* Remove value and all sibling keys based on key.
*
* @param mixed $key Key used to identify value
*
* @return bool
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function removeMultiple($key) : bool
{
if($this->orderType === OrderType::LOOSE) {
$keys = Permutation::permut($key);
$removed = false;
foreach($keys as $key => $value) {
$removed |= $this->remove(implode($value, ':'));
}
return $removed;
} else {
return $this->remove(implode($key, ':'));
}
}
/** /**
* Remap key to a different value. * Remap key to a different value.
* *
@ -291,32 +389,66 @@ class MultiMap implements \Countable
public function removeKey($key) : bool public function removeKey($key) : bool
{ {
if($this->keyType === KeyType::MULTIPLE && is_array($key)) { if($this->keyType === KeyType::MULTIPLE && is_array($key)) {
if($this->orderType === OrderType::LOOSE) { return $this->removeKeyMultiple($key);
$keys = Permutation::permut($key);
$removed = false;
foreach($keys as $key => $value) {
$removed |= $this->removeKey(implode($value, ':'));
}
return $removed;
} else {
return $this->removeKey(implode($key, ':'));
}
} else { } else {
if (isset($this->keys[$key])) { return $this->removeKeySingle($key);
unset($this->keys[$key]); }
}
$this->garbageCollect(); /**
* Remove key.
*
* This only removes the value if no other key exists for this value.
*
* @param mixed $key Key used to identify value
*
* @return bool
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function removeKeySingle($key) : bool
{
if (isset($this->keys[$key])) {
unset($this->keys[$key]);
return true; $this->garbageCollect();
}
return true;
} }
return false; return false;
} }
/**
* Remove key.
*
* This only removes the value if no other key exists for this value.
*
* @param mixed $key Key used to identify value
*
* @return bool
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function removeKeyMultiple($key) : bool
{
if($this->orderType === OrderType::LOOSE) {
$keys = Permutation::permut($key);
$removed = false;
foreach($keys as $key => $value) {
$removed |= $this->removeKey(implode($value, ':'));
}
return $removed;
} else {
return $this->removeKey(implode($key, ':'));
}
}
/** /**
* Get all sibling keys. * Get all sibling keys.
* *
@ -329,16 +461,28 @@ class MultiMap implements \Countable
*/ */
public function getSiblings($key) : array public function getSiblings($key) : array
{ {
$siblings = [];
if($this->keyType === KeyType::MULTIPLE) { if($this->keyType === KeyType::MULTIPLE) {
if($this->orderType === OrderType::LOOSE) { return $this->getSiblingsMultiple($key);
return Permutation::permut($key);
} else {
return $siblings;
}
} }
return $this->getSiblingsSingle($key);
}
/**
* Get all sibling keys.
*
* @param mixed $key Key to find siblings for
*
* @return array
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
private function getSiblingsSingle($key) : array
{
$siblings = [];
if (isset($this->keys[$key])) { if (isset($this->keys[$key])) {
$id = $this->keys[$key]; $id = $this->keys[$key];
@ -348,8 +492,25 @@ class MultiMap implements \Countable
} }
} }
} }
}
return $siblings; /**
* Get all sibling keys.
*
* @param mixed $key Key to find siblings for
*
* @return array
*
* @since 1.0.0
* @author Dennis Eichhorn
*/
public function getSiblingsMultiple($key) : array
{
if($this->orderType === OrderType::LOOSE) {
return Permutation::permut($key);
} else {
return [];
}
} }
/** /**

View File

@ -10,7 +10,7 @@ class Permutation
$permutations = []; $permutations = [];
if(empty($toPermute)){ if(empty($toPermute)){
$permutations[] = implode("", $result); $permutations[] = implode('', $result);
}else{ }else{
foreach($toPermute as $key => $val){ foreach($toPermute as $key => $val){
$newArr = $toPermute; $newArr = $toPermute;