diff --git a/Math/Matrix/Matrix.php b/Math/Matrix/Matrix.php index 8c638c11d..e8fda0bde 100644 --- a/Math/Matrix/Matrix.php +++ b/Math/Matrix/Matrix.php @@ -190,9 +190,9 @@ class Matrix implements ArrayAccess, Iterator switch($algorithm) { case InversionType::GAUSS_JORDAN: - return $this->inverseGaussJordan(); + return $this->inverseGaussJordan(); default: - throw new \Exception(''); + throw new \Exception(''); } } @@ -298,31 +298,31 @@ class Matrix implements ArrayAccess, Iterator for ($i = 0; $i < $n; $i++) { $max = 0; - + for ($j = $i; $j < $n; $j++) { if (abs($arr[$j][$i]) > abs($arr[$max][$i])) { $max = $j; } } - + if ($max) { $sign = -$sign; $temp = $arr[$i]; $arr[$i] = $arr[$max]; $arr[$max] = $temp; } - + if (!$arr[$i][$i]) { return 0; } - + for ($j = $i + 1; $j < $n; $j++) { $r = $arr[$j][$i] / $arr[$i][$i]; if (!$r) { continue; } - + for ($c = $i; $c < $n; $c ++) { $arr[$j][$c] -= $arr[$i][$c] * $r; } diff --git a/Message/Http/Request.php b/Message/Http/Request.php index 88c75e9e7..0dacfc7aa 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -106,7 +106,33 @@ class Request extends RequestAbstract public function init($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 + */ + private function initCurrentRequest() + { + $this->data = $_GET ?? []; if (isset($_SERVER['CONTENT_TYPE'])) { if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { @@ -124,26 +150,50 @@ class Request extends RequestAbstract } $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); - - unset($_FILES); - unset($_GET); - unset($_POST); - unset($_REQUEST); - - $this->path = explode('/', $this->uri->getPath()); - $this->l11n->setLanguage($this->path[0]); - $this->hash = []; + /** + * Init pseudo request + * + * @param mixed $uri Uri to handle as request + * + * @return void + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + 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 + */ + private function setupUriBuilder() + { UriFactory::setQuery('/scheme', $this->uri->getScheme()); UriFactory::setQuery('/host', $this->uri->getHost()); UriFactory::setQuery('/lang', $this->l11n->getLanguage()); + } + /** + * Create request hashs of current request + * + * @return void + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + private function createRequestHashs() + { + $this->hash = []; foreach ($this->path as $key => $path) { $paths = []; 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 + */ + private function cleanupGlobals() + { + unset($_FILES); + unset($_GET); + unset($_POST); + unset($_REQUEST); + } + /** * Is Mobile * diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index 0911edb7d..d719132a2 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -32,7 +32,7 @@ use phpOMS\Uri\UriInterface; * @link http://orange-management.com * @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 */ 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 */ 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 */ 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 */ abstract public function getMethod() : string; /** - * {@inheritdoc} + * Set request method. + * + * @param string $method + * + * @since 1.0.0 + * @author Dennis Eichhorn */ public function setMethod(string $method) { $this->method = $method; @@ -273,4 +298,14 @@ abstract class RequestAbstract implements RequestInterface { return $this->uri->__toString(); } + + /** + * Get request target. + * + * @return string + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + abstract public function getRequestTarget() : string; } diff --git a/Message/RequestInterface.php b/Message/RequestInterface.php deleted file mode 100644 index ab9ceda65..000000000 --- a/Message/RequestInterface.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @author Dennis Eichhorn - * @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 - * @author Dennis Eichhorn - * @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 - */ - public function getRequestTarget() : string; - - /** - * Get request method. - * - * @return string - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getMethod() : string; - - /** - * Set request method. - * - * @param string $method - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function setMethod(string $method); - - /** - * Get request uri. - * - * @return UriInterface - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getUri() : UriInterface; - - /** - * Set request uri. - * - * @param UriInterface $uri - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function setUri(UriInterface $uri); - - /** - * Get request hash. - * - * @return array - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getHash() : array; -} diff --git a/Message/ResponseAbstract.php b/Message/ResponseAbstract.php index 4da687024..fe4b834d0 100644 --- a/Message/ResponseAbstract.php +++ b/Message/ResponseAbstract.php @@ -31,7 +31,7 @@ use phpOMS\Utils\ArrayUtils; * @link http://orange-management.com * @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()); } + + /** + * Generate header automatically based on code. + * + * @param int $code HTTP status code + * + * @return void + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + abstract public function generateHeader(int $code); } diff --git a/Message/ResponseInterface.php b/Message/ResponseInterface.php deleted file mode 100644 index 407d57d29..000000000 --- a/Message/ResponseInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @author Dennis Eichhorn - * @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 - * @author Dennis Eichhorn - * @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 - */ - public function generateHeader(int $code); -} diff --git a/Module/ModuleFactory.php b/Module/ModuleFactory.php index 44355e08b..41b0a8153 100644 --- a/Module/ModuleFactory.php +++ b/Module/ModuleFactory.php @@ -77,29 +77,10 @@ class ModuleFactory if (!isset(self::$loaded[$module])) { try { $class = '\\Modules\\' . $module . '\\Controller'; - - /** - * @var ModuleAbstract $obj - */ $obj = new $class($app); self::$loaded[$module] = $obj; - - /** Install providing for */ - 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); - } - } + self::registerRequesting($obj); + self::registerProvided($obj); } catch(\Exception $e) { self::$loaded[$module] = new NullModule($app); } @@ -107,4 +88,41 @@ class ModuleFactory return self::$loaded[$module]; } + + /** + * Load modules this module is requesting from + * + * @param ModuleAbstract $obj Current module + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + 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 + */ + 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); + } + } +} } diff --git a/Module/ModuleManager.php b/Module/ModuleManager.php index a64f5473a..105f91a24 100644 --- a/Module/ModuleManager.php +++ b/Module/ModuleManager.php @@ -146,37 +146,37 @@ class ModuleManager if (!isset($this->uriLoad)) { switch ($this->app->dbPool->get('core')->getType()) { case DatabaseType::MYSQL: - $uriHash = $request->getHash(); - $uriPdo = ''; + $uriHash = $request->getHash(); + $uriPdo = ''; - $i = 1; - $c = count($uriHash); - for ($k = 0; $k < $c; $k++) { - $uriPdo .= ':pid' . $i . ','; - $i++; - } + $i = 1; + $c = count($uriHash); + for ($k = 0; $k < $c; $k++) { + $uriPdo .= ':pid' . $i . ','; + $i++; + } - $uriPdo = rtrim($uriPdo, ','); + $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 . ')' + /* 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++; - } + $i = 1; + foreach ($uriHash as $hash) { + $sth->bindValue(':pid' . $i, $hash, \PDO::PARAM_STR); + $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) { switch ($this->app->dbPool->get('core')->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->execute(); - $this->active = $sth->fetchAll(\PDO::FETCH_COLUMN); - break; + $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(); + $this->active = $sth->fetchAll(\PDO::FETCH_COLUMN); + break; } } @@ -298,75 +298,73 @@ class ModuleManager $path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json'); - if ($path !== false) { - if (strpos($path, self::MODULE_PATH) === false) { - throw new PathException($oldPath); - } + if($path === false || strpos($path, self::MODULE_PATH) === false) { + throw new PathException($module); + } - $info = json_decode(file_get_contents($path), true); + $info = json_decode(file_get_contents($path), true); - if (!isset($info)) { - throw new InvalidJsonException($path); - } + if (!isset($info)) { + throw new InvalidJsonException($path); + } - switch ($this->app->dbPool->get('core')->getType()) { - case DatabaseType::MYSQL: - $this->app->dbPool->get('core')->con->beginTransaction(); + switch ($this->app->dbPool->get('core')->getType()) { + case DatabaseType::MYSQL: + $this->app->dbPool->get('core')->con->beginTransaction(); - $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 - (:internal, :theme, :path, :active, :version);' - ); + $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 + (:internal, :theme, :path, :active, :version);' + ); - $sth->bindValue(':internal', $info['name']['internal'], \PDO::PARAM_INT); - $sth->bindValue(':theme', 'Default', \PDO::PARAM_STR); - $sth->bindValue(':path', $info['directory'], \PDO::PARAM_STR); - $sth->bindValue(':active', 1, \PDO::PARAM_INT); - $sth->bindValue(':version', $info['version'], \PDO::PARAM_STR); + $sth->bindValue(':internal', $info['name']['internal'], \PDO::PARAM_INT); + $sth->bindValue(':theme', 'Default', \PDO::PARAM_STR); + $sth->bindValue(':path', $info['directory'], \PDO::PARAM_STR); + $sth->bindValue(':active', 1, \PDO::PARAM_INT); + $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 = $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->install($key); - } + $this->app->dbPool->get('core')->con->commit(); - $class = '\\Modules\\' . $module . '\\Admin\\Installer'; - /** @var $class InstallerAbstract */ - $class::install($this->app->dbPool, $info); + break; + } + + 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 - $this->installed[$module] = true; + $this->installed[$module] = true; - foreach ($info['providing'] as $key => $version) { - $this->installProviding($module, $key); - } + foreach ($info['providing'] as $key => $version) { + $this->installProviding($module, $key); + } - /* Install receiving */ - foreach ($installed as $key => $value) { - $this->installProviding($key, $module); - } + /* Install receiving */ + foreach ($installed as $key => $value) { + $this->installProviding($key, $module); } } @@ -383,10 +381,10 @@ class ModuleManager 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`,`module_id` FROM `' . $this->app->dbPool->get('core')->prefix . 'module`'); - $sth->execute(); - $this->installed = $sth->fetchAll(\PDO::FETCH_GROUP); - break; + $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(); + $this->installed = $sth->fetchAll(\PDO::FETCH_GROUP); + break; } } @@ -436,7 +434,7 @@ class ModuleManager 'message' => 'Trying to initialize ' . $m . ' without controller.', 'line' => $e->getLine(), 'file' => $e->getFile(), - ]); + ]); } } } elseif (is_string($module) && realpath(self::MODULE_PATH . '/' . $module . '/Controller.php') !== false) { diff --git a/Module/NullModule.php b/Module/NullModule.php index b98c416a4..263237ec2 100644 --- a/Module/NullModule.php +++ b/Module/NullModule.php @@ -15,7 +15,6 @@ */ namespace phpOMS\Module; - /** * Module abstraction class. * diff --git a/Utils/MultiMap.php b/Utils/MultiMap.php index 58b6f8869..5f3303169 100644 --- a/Utils/MultiMap.php +++ b/Utils/MultiMap.php @@ -121,12 +121,14 @@ class MultiMap implements \Countable */ private function garbageCollect() { + /* garbage collect keys */ foreach ($this->keys as $key => $keyValue) { if (!isset($this->values[$keyValue])) { unset($this->keys[$key]); } } + /* garbage collect values */ foreach ($this->values as $valueKey => $value) { if (!in_array($valueKey, $this->keys)) { unset($this->values[$valueKey]); @@ -146,29 +148,59 @@ class MultiMap implements \Countable */ public function get($key) { - if($this->keyType === KeyType::MULTIPLE) { - return isset($this->keys[$key]) ? $this->values[$this->keys[$key]] ?? null : null; + if($this->keyType === KeyType::SINGLE) { + return $this->getSingle($key); } else { - 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; + return $this->getMultiple($key); } } + /** + * 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. * @@ -183,23 +215,59 @@ class MultiMap implements \Countable public function set($key, $value) : bool { if($this->keyType === KeyType::MULTIPLE && is_array($key)) { - if($this->orderType !== OrderType::LOOSE) { - $permutation = Permutation::permut($key); + return $this->setMultiple($key, $value); + } else { + return $this->setSingle($key, $value); + } - foreach($permuation as $permut) { - if($this->set(implode($permut, ':'), $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 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 { - if (isset($this->keys[$key])) { - $this->values[$this->keys[$key]] = $value; - - return true; - } + return $this->set(implode($key, ':')); } return false; @@ -218,34 +286,64 @@ class MultiMap implements \Countable public function remove($key) : bool { if($this->keyType === KeyType::MULTIPLE && is_array($key)) { - 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, ':')); - } + return $this->removeMultiple($key); } else { - if (isset($this->keys[$key])) { - $id = $this->keys[$key]; + return $this->removeSingle($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; } + /** + * 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. * @@ -291,32 +389,66 @@ class MultiMap implements \Countable public function removeKey($key) : bool { if($this->keyType === KeyType::MULTIPLE && is_array($key)) { - 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, ':')); - } + return $this->removeKeyMultiple($key); } else { - if (isset($this->keys[$key])) { - unset($this->keys[$key]); + return $this->removeKeySingle($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; } + /** + * 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. * @@ -329,16 +461,28 @@ class MultiMap implements \Countable */ public function getSiblings($key) : array { - $siblings = []; - if($this->keyType === KeyType::MULTIPLE) { - if($this->orderType === OrderType::LOOSE) { - return Permutation::permut($key); - } else { - return $siblings; - } + return $this->getSiblingsMultiple($key); } + 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])) { $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 []; + } } /** diff --git a/Utils/Permutation.php b/Utils/Permutation.php index f8a160f29..e505badcd 100644 --- a/Utils/Permutation.php +++ b/Utils/Permutation.php @@ -10,7 +10,7 @@ class Permutation $permutations = []; if(empty($toPermute)){ - $permutations[] = implode("", $result); + $permutations[] = implode('', $result); }else{ foreach($toPermute as $key => $val){ $newArr = $toPermute;