From 3bf54a2efcc2741c6b45a324f3e4f9b5ffd5063f Mon Sep 17 00:00:00 2001 From: Stefan Hecken Date: Tue, 2 Jul 2019 15:15:58 +0200 Subject: [PATCH 1/6] PHP7 Typehints and Codeformat --- .gitignore | 1 + src/CachedProvider.php | 85 +++++----- src/CachedRepository.php | 90 +++++----- src/Component.php | 17 +- src/Entity.php | 21 +-- src/ILIAS/Cache.php | 23 ++- src/ILIAS/Entity.php | 43 ++--- src/ILIAS/Provider.php | 226 +++++++++++++------------ src/ILIAS/ProviderDB.php | 125 +++++++------- src/ILIAS/Repository.php | 41 +++-- src/ILIAS/SeparatedUnboundProvider.php | 129 +++++++------- src/ILIAS/SharedUnboundProvider.php | 126 +++++++------- src/ILIAS/UnboundProvider.php | 75 ++++---- src/Provider.php | 61 +++---- src/ProviderHelper.php | 37 ++-- src/Repository.php | 23 ++- src/RepositoryHelper.php | 29 ++-- src/Simple/AttachInt.php | 17 +- src/Simple/AttachIntMemory.php | 65 +++---- src/Simple/AttachString.php | 17 +- src/Simple/AttachStringMemory.php | 65 +++---- src/Simple/Entity.php | 34 ++-- src/Simple/Provider.php | 124 +++++++------- src/Simple/Repository.php | 101 ++++++----- 24 files changed, 830 insertions(+), 745 deletions(-) diff --git a/.gitignore b/.gitignore index f37225b..1317f99 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp *.swo vendor +.idea/ diff --git a/src/CachedProvider.php b/src/CachedProvider.php index 3b121c6..9acd84a 100644 --- a/src/CachedProvider.php +++ b/src/CachedProvider.php @@ -8,49 +8,56 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** * A chaching wrapper around a provider that caches components per type * and passes through the other methods. */ -class CachedProvider implements Provider { - /** - * @var Provider - */ - protected $provider; - - /** - * @var array - */ - protected $cache; - - public function __construct(Provider $provider) { - $this->provider = $provider; - $this->cache = []; - } - - /** - * @inheritdocs - */ - public function componentsOfType($component_type) { - if (!isset($this->cache[$component_type])) { - $this->cache[$component_type] = $this->provider->componentsOfType($component_type); - } - return $this->cache[$component_type]; - } - - /** - * @inheritdocs - */ - public function componentTypes() { - return $this->provider->componentTypes(); - } - - /** - * @inheritdocs - */ - public function entity() { - return $this->provider->entity(); - } +class CachedProvider implements Provider +{ + /** + * @var Provider + */ + protected $provider; + + /** + * @var array + */ + protected $cache; + + public function __construct(Provider $provider) + { + $this->provider = $provider; + $this->cache = []; + } + + /** + * @inheritdocs + */ + public function componentsOfType(string $component_type) : array + { + if (!isset($this->cache[$component_type])) { + $this->cache[$component_type] = $this->provider->componentsOfType($component_type); + } + return $this->cache[$component_type]; + } + + /** + * @inheritdocs + */ + public function componentTypes() : string + { + return $this->provider->componentTypes(); + } + + /** + * @inheritdocs + */ + public function entity() : Entity + { + return $this->provider->entity(); + } } diff --git a/src/CachedRepository.php b/src/CachedRepository.php index 9bf0ef4..9a60feb 100644 --- a/src/CachedRepository.php +++ b/src/CachedRepository.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** @@ -16,45 +18,51 @@ * providers are wrapped in CachedProviders to enable caching for * components as well. */ -class CachedRepository implements Repository { - use RepositoryHelper; - - /** - * @var Repository - */ - protected $repository; - - /** - * @var array - */ - protected $cache; - - public function __construct(Repository $repository) { - $this->repository = $repository; - $this->cache = []; - } - - /** - * @inheritdocs - */ - public function providersForEntity(Entity $entity, $component_type = null) { - $id = $entity->id(); - if (!isset($this->cache[$id])) { - $this->cache[$id] = array_map(function(Provider $p) { - return new CachedProvider($p); - }, $this->repository->providersForEntity($entity)); - } - - if ($component_type === null) { - return $this->cache[$id]; - } - - $providers = []; - foreach ($this->cache[$id] as $provider) { - if (in_array($component_type, $provider->componentTypes())) { - $providers[] = $provider; - } - } - return $providers; - } +class CachedRepository implements Repository +{ + use RepositoryHelper; + + /** + * @var Repository + */ + protected $repository; + + /** + * @var array + */ + protected $cache; + + public function __construct(Repository $repository) + { + $this->repository = $repository; + $this->cache = []; + } + + /** + * @inheritdocs + */ + public function providersForEntity(Entity $entity, string $component_type = null) : array + { + $id = $entity->id(); + if (!isset($this->cache[$id])) { + $this->cache[$id] = array_map( + function(Provider $p) { + return new CachedProvider($p); + }, + $this->repository->providersForEntity($entity) + ); + } + + if ($component_type === null) { + return $this->cache[$id]; + } + + $providers = []; + foreach ($this->cache[$id] as $provider) { + if (in_array($component_type, $provider->componentTypes())) { + $providers[] = $provider; + } + } + return $providers; + } } diff --git a/src/Component.php b/src/Component.php index 80086c6..36cbae9 100644 --- a/src/Component.php +++ b/src/Component.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** @@ -20,11 +22,12 @@ * Concrete Components must be abstracted as another interface for this * machinery to work correctly. */ -interface Component { - /** - * Get the entity this component is attached to. - * - * @return Entity - */ - public function entity(); +interface Component +{ + /** + * Get the entity this component is attached to. + * + * @return Entity + */ + public function entity() : Entity; } diff --git a/src/Entity.php b/src/Entity.php index 2edef21..3fe0b06 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** @@ -19,14 +21,13 @@ * are known, thus couple the entity to all existing components. This dependency * should not be introduced to have an extensible system. */ -interface Entity { - /** - * Some ID for this entity. - * - * It needs to be guaranteed that every entity has exactly one unique id. - * It needs to be guaranteed that the id can be serialised. - * - * @return mixed - */ - public function id(); +interface Entity +{ + /** + * Some ID for this entity. + * + * It needs to be guaranteed that every entity has exactly one unique id. + * It needs to be guaranteed that the id can be serialised. + */ + public function id() : int; } diff --git a/src/ILIAS/Cache.php b/src/ILIAS/Cache.php index 4679d1c..d448e24 100644 --- a/src/ILIAS/Cache.php +++ b/src/ILIAS/Cache.php @@ -8,24 +8,21 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; /** * Contract for a cache. */ -interface Cache { - /** - * @return void - */ - public function set(string $key, array $value); +interface Cache +{ + public function set(string $key, array $value); - /** - * @return array|null - */ - public function get(string $key); + /** + * @return array|null + */ + public function get(string $key); - /** - * @return void - */ - public function delete(string $key); + public function delete(string $key); } diff --git a/src/ILIAS/Entity.php b/src/ILIAS/Entity.php index 34e70ac..890124e 100644 --- a/src/ILIAS/Entity.php +++ b/src/ILIAS/Entity.php @@ -8,32 +8,35 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; /** * An entity over an ILIAS object. */ -class Entity implements \CaT\Ente\Entity { - /** - * @var \ilObject - */ - private $object; +class Entity implements \CaT\Ente\Entity +{ + /** + * @var \ilObject + */ + private $object; - public function __construct(\ilObject $object) { - $this->object = $object; - } + public function __construct(\ilObject $object) + { + $this->object = $object; + } - /** - * @inheritdocs - */ - public function id() { - return $this->object->getId(); - } + /** + * @inheritdocs + */ + public function id() : int + { + return (int)$this->object->getId(); + } - /** - * @return \ilObject - */ - public function object() { - return $this->object; - } + public function object() : \ilObject + { + return $this->object; + } } diff --git a/src/ILIAS/Provider.php b/src/ILIAS/Provider.php index 7d35b4a..4d64125 100644 --- a/src/ILIAS/Provider.php +++ b/src/ILIAS/Provider.php @@ -8,119 +8,129 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; use CaT\Ente\Component; +use CaT\Ente\Entity AS IEntity; /** * Implementation of a provider for ILIAS. */ -final class Provider implements \CaT\Ente\Provider { - /** - * @var \ilObject - */ - private $object; - - /** - * @var Entity - */ - private $entity; - - /** - * @var UnboundProvider - */ - private $unbound_provider; - - /** - * @var array - */ - private $components; - - final public function __construct(\ilObject $object, UnboundProvider $unbound_provider) { - $this->object = $object; - $this->entity = new Entity($object); - $this->unbound_provider = $unbound_provider; - $this->components = []; - } - - /** - * @inheritdocs - */ - final public function componentTypes() { - return $this->unbound_provider->componentTypes(); - } - - /** - * @inheritdocs - */ - final public function componentsOfType($component_type) { - if (isset($this->components[$component_type])) { - return $this->components[$component_type]; - } - - $components = $this->unbound_provider->buildComponentsOf($component_type, $this->entity()); - $this->checkComponentArray($components, $component_type); - $this->components[$component_type] = $components; - return $components; - } - - /** - * @inheritdocs - */ - final public function entity() { - return $this->entity; - } - - /** - * Get the entity object of the component. - * - * @return \ilObject - */ - final public function object() { - return $this->object; - } - - /** - * Get the owner object of the component. - * - * @return \ilObject[] - */ - final public function owners() { - return $this->unbound_provider->owners(); - } - - /** - * Get the unbound provider underlying this. - * - * @return \UnboundProvider - */ - final public function unboundProvider() { - return $this->unbound_provider; - } - - /** - * Checks if the $var is a valid component array for the given type. - * - * @param mixed $var - * @param string $component_type - * @return bool - */ - private function checkComponentArray($var, $component_type) { - if (!is_array($var)) { - throw new \UnexpectedValueException( - "Expected buildComponentsOf to return an array, got ".gettype($var)); - } - - foreach($var as $component) { - if (!($component instanceof $component_type)) { - throw new \UnexpectedValueException( - "Expected build components to have the type $component_type, got ".get_class($component)); - } - if (!$component->entity() === $this->entity()) { - throw new \UnexpectedValueException( - 'Expected build components to have the same entity as $this.'); - } - } - - } +final class Provider implements \CaT\Ente\Provider +{ + /** + * @var \ilObject + */ + private $object; + + /** + * @var Entity + */ + private $entity; + + /** + * @var UnboundProvider + */ + private $unbound_provider; + + /** + * @var array + */ + private $components; + + final public function __construct(\ilObject $object, UnboundProvider $unbound_provider) + { + $this->object = $object; + $this->entity = new Entity($object); + $this->unbound_provider = $unbound_provider; + $this->components = []; + } + + /** + * @inheritdocs + */ + final public function componentTypes() : array + { + return $this->unbound_provider->componentTypes(); + } + + /** + * @inheritdocs + */ + final public function componentsOfType(string $component_type) : array + { + if (isset($this->components[$component_type])) { + return $this->components[$component_type]; + } + + $components = $this->unbound_provider->buildComponentsOf($component_type, $this->entity()); + $this->checkComponentArray($components, $component_type); + $this->components[$component_type] = $components; + return $components; + } + + /** + * @inheritdocs + */ + final public function entity() : IEntity + { + return $this->entity; + } + + /** + * Get the entity object of the component. + * + * @return \ilObject + */ + final public function object() : \ilObject + { + return $this->object; + } + + /** + * Get the owner object of the component. + * + * @return \ilObject[] + */ + final public function owners() : array + { + return $this->unbound_provider->owners(); + } + + /** + * Get the unbound provider underlying this. + * + * @return UnboundProvider + */ + final public function unboundProvider() : UnboundProvider + { + return $this->unbound_provider; + } + + /** + * Checks if the $var is a valid component array for the given type. + * @param mixed $var + */ + private function checkComponentArray($var, string $component_type) + { + if (!is_array($var)) { + throw new \UnexpectedValueException( + "Expected buildComponentsOf to return an array, got ".gettype($var)); + } + + foreach($var as $component) { + if (!($component instanceof $component_type)) { + throw new \UnexpectedValueException( + "Expected build components to have the type $component_type, got " + .get_class($component) + ); + } + if (!$component->entity() === $this->entity()) { + throw new \UnexpectedValueException( + 'Expected build components to have the same entity as $this.'); + } + } + } } diff --git a/src/ILIAS/ProviderDB.php b/src/ILIAS/ProviderDB.php index d59886f..6156ec2 100644 --- a/src/ILIAS/ProviderDB.php +++ b/src/ILIAS/ProviderDB.php @@ -8,82 +8,75 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; /** * A database that stores ILIAS providers. */ -interface ProviderDB { - /** - * Create a new separated unbound provider for the given owner. - * - * The provider will belong to objects above the $owner in the tree that also - * have the type $obj_type. - * - * @param \ilObject $owner - * @param string $obj_type - * @param string $class_name - * @param string $include_path - * @return SeparatedUnboundProvider - */ - public function createSeparatedUnboundProvider(\ilObject $owner, $obj_type, $class_name, $include_path); +interface ProviderDB +{ + /** + * Create a new separated unbound provider for the given owner. + * + * The provider will belong to objects above the $owner in the tree that also + * have the type $obj_type. + */ + public function createSeparatedUnboundProvider( + \ilObject $owner, + string $obj_type, + string $class_name, + string $include_path + ) : SeparatedUnboundProvider; - /** - * Create a new shared unbound provider for the given owner. - * - * The provider will be belong to objects above the $owner in the tree that also - * have the type $obj_type. + /** + * Create a new shared unbound provider for the given owner. * - * @param \ilObject $owner - * @param string $obj_type - * @param string $class_name - * @param string $include_path - * @return SharedUnboundProvider - */ - public function createSharedUnboundProvider(\ilObject $owner, $obj_type, $class_name, $include_path); + * The provider will be belong to objects above the $owner in the tree that also + * have the type $obj_type. + */ + public function createSharedUnboundProvider( + \ilObject $owner, + string $obj_type, + string $class_name, + string $include_path + ) : SharedUnboundProvider; - /** - * Load the unbound provider with the given id. - * - * @param int $id - * @throws \InvalidArgumentException if the provider with the supplied id does not exist. - * @return UnboundProvider - */ - public function load($id); + /** + * Load the unbound provider with the given id. + * @throws \InvalidArgumentException if the provider with the supplied id does not exist. + */ + public function load(int $id) : UnboundProvider; - /** - * Delete a given unbound provider. - * - * @param UnboundProvider $provider - * @param UnboundProvider $provider - * @return null - */ - public function delete(UnboundProvider $provider, \ilObject $owner); + /** + * Delete a given unbound provider. + * @param UnboundProvider $provider + * @param UnboundProvider $provider + * @return null + */ + public function delete(UnboundProvider $provider, \ilObject $owner); - /** - * Update the given unbound provider. - * - * The only thing that may be updated are the components that are provided. - * - * @param UnboundProvider $provider - * @return null - */ - public function update(UnboundProvider $provider); + /** + * Update the given unbound provider. + * + * The only thing that may be updated are the components that are provided. + * @param UnboundProvider $provider + */ + public function update(UnboundProvider $provider); - /** - * Get all unbound providers of a given owner. - * - * @param \ilObject $owner - * @return UnboundProvider[] - */ - public function unboundProvidersOf(\ilObject $owner); + /** + * Get all unbound providers of a given owner. + * @return UnboundProvider[] + */ + public function unboundProvidersOf(\ilObject $owner) : array; - /** - * Get all providers for the given object. - * - * @param \ilObject $object - * @param string|null $component_type - * @return Provider[] - */ - public function providersFor(\ilObject $object, $component_type = null); + /** + * Get all providers for the given object. + * @return Provider[] + */ + public function providersFor( + \ilObject $object, + string $component_type = null + ) : array; } diff --git a/src/ILIAS/Repository.php b/src/ILIAS/Repository.php index f7e988e..04566d0 100644 --- a/src/ILIAS/Repository.php +++ b/src/ILIAS/Repository.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; use CaT\Ente; @@ -15,26 +17,29 @@ /** * An repository over ILIAS objects. */ -class Repository implements Ente\Repository { +class Repository implements Ente\Repository +{ use Ente\RepositoryHelper; - /** - * @var ProviderDB - */ - private $provider_db; + /** + * @var ProviderDB + */ + private $provider_db; - public function __construct(ProviderDB $provider_db) { - $this->provider_db = $provider_db; - } + public function __construct(ProviderDB $provider_db) + { + $this->provider_db = $provider_db; + } - /** - * @inheritdocs - */ - public function providersForEntity(\CaT\Ente\Entity $entity, $component_type = null) { - // This can only return entities for ILIAS - if (!($entity instanceof Entity)) { - return []; - } - return $this->provider_db->providersFor($entity->object(), $component_type); - } + /** + * @inheritdocs + */ + public function providersForEntity(Ente\Entity $entity, string $component_type = null) : array + { + // This can only return entities for ILIAS + if (!($entity instanceof Entity)) { + return []; + } + return $this->provider_db->providersFor($entity->object(), $component_type); + } } diff --git a/src/ILIAS/SeparatedUnboundProvider.php b/src/ILIAS/SeparatedUnboundProvider.php index 59bfac9..7859237 100644 --- a/src/ILIAS/SeparatedUnboundProvider.php +++ b/src/ILIAS/SeparatedUnboundProvider.php @@ -8,78 +8,87 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; +use CaT\Ente\Component; +use CaT\Ente\Entity AS IEntity; + /** * An separated unbound provider is a unbound provider that has a single owner. */ -abstract class SeparatedUnboundProvider implements UnboundProvider { - /** - * @var int - */ - private $id; +abstract class SeparatedUnboundProvider implements UnboundProvider +{ + /** + * @var int + */ + private $id; - /** - * @var \ilObject - */ - private $owner; + /** + * @var \ilObject + */ + private $owner; - /** - * @var string - */ - private $object_type; + /** + * @var string + */ + private $object_type; - final public function __construct($id, \ilObject $owner, $object_type) { - assert('is_int($id)'); - $this->id = $id; - $this->owner = $owner; - assert('is_string($object_type)'); - $this->object_type = $object_type; - } + final public function __construct(int $id, \ilObject $owner, string $object_type) + { + $this->id = $id; + $this->owner = $owner; + $this->object_type = $object_type; + } - /** - * @inheritdocs - */ - abstract public function componentTypes(); + /** + * @inheritdocs + */ + abstract public function componentTypes(); - /** - * Build the component(s) of the given type for the given object. - * - * @param string $component_type - * @param Entity $provider - * @return Component[] - */ - abstract public function buildComponentsOf($component_type, Entity $entity); + /** + * Build the component(s) of the given type for the given object. + * @return Component[] + */ + abstract public function buildComponentsOf(string $component_type, IEntity $entity) : array; - /** - * @inheritdocs - */ - final public function idFor(\ilObject $owner) { - if ($owner->getId() !== $this->owner->getId()) { - throw new \InvalidArgumentException( - "Object with id ".$owner->getId()." is not the owner with id ".$this->owner->getId()); - } - return $this->id; - } + /** + * @inheritdocs + */ + final public function idFor(\ilObject $owner) : int + { + if ($owner->getId() !== $this->owner->getId()) { + throw new \InvalidArgumentException( + "Object with id " + .$owner->getId() + ." is not the owner with id ".$this->owner->getId() + ); + } + return $this->id; + } - /** - * @inheritdocs - */ - final public function owners() { - return [$this->owner]; - } + /** + * @inheritdocs + */ + final public function owners() : array + { + return [$this->owner]; + } - /** - * @inheritdocs - */ - final public function owner() { - return $this->owner; - } + /** + * @inheritdocs + */ + final public function owner() : \ilObject + { + return $this->owner; + } - /** - * @inheritdocs - */ - final public function objectType() { - return $this->object_type; - } + /** + * @inheritdocs + */ + final public function objectType() : string + { + return $this->object_type; + } } diff --git a/src/ILIAS/SharedUnboundProvider.php b/src/ILIAS/SharedUnboundProvider.php index a4e2ac1..0f101dd 100644 --- a/src/ILIAS/SharedUnboundProvider.php +++ b/src/ILIAS/SharedUnboundProvider.php @@ -8,78 +8,84 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; +use CaT\Ente\Component; +use CaT\Ente\Entity AS IEntity; + /** * An shared unbound provider is an unbound provider that has a multiple owners * and may provide components based on a combination of owners properties. */ -abstract class SharedUnboundProvider implements UnboundProvider { - /** - * @var \ilObject[] - */ - private $owners; +abstract class SharedUnboundProvider implements UnboundProvider +{ + /** + * @var \ilObject[] + */ + private $owners; - /** - * @var array - */ - private $ids; + /** + * @var array + */ + private $ids; - /** - * @var string - */ - private $object_type; + /** + * @var string + */ + private $object_type; - final public function __construct(array $owners, $object_type) { - $this->owners = []; - $this->ids = []; - foreach($owners as $id => $owner) { - assert('is_int($id)'); - assert('$owner instanceof \ilObject'); - $this->owners[] = $owner; - $this->ids[$owner->getId()] = $id; - } - assert('is_string($object_type)'); - $this->object_type = $object_type; - } + final public function __construct(array $owners, string $object_type) + { + $this->owners = []; + $this->ids = []; + foreach($owners as $id => $owner) { + assert('is_int($id)'); + assert('$owner instanceof \ilObject'); + $this->owners[] = $owner; + $this->ids[$owner->getId()] = $id; + } + $this->object_type = $object_type; + } - /** - * @inheritdocs - */ - abstract public function componentTypes(); + /** + * @inheritdocs + */ + abstract public function componentTypes(); - /** - * Build the component(s) of the given type for the given object. - * - * @param string $component_type - * @param Entity $provider - * @return Component[] - */ - abstract public function buildComponentsOf($component_type, Entity $entity); + /** + * Build the component(s) of the given type for the given object. + * @return Component[] + */ + abstract public function buildComponentsOf(string $component_type, IEntity $entity) : array; - /** - * @inheritdocs - */ - final public function idFor(\ilObject $owner) { - $id = $owner->getId(); - if (!isset($this->ids[$id])) { - throw new \InvalidArgumentException( - "Object with id ".$owner->getId()." is not an owner"); - } - return $this->ids[$id]; - } + /** + * @inheritdocs + */ + final public function idFor(\ilObject $owner) : int + { + $id = $owner->getId(); + if (!isset($this->ids[$id])) { + throw new \InvalidArgumentException( + "Object with id ".$owner->getId()." is not an owner"); + } + return (int)$this->ids[$id]; + } - /** - * @inheritdocs - */ - final public function owners() { - return $this->owners; - } + /** + * @inheritdocs + */ + final public function owners() : array + { + return $this->owners; + } - /** - * @inheritdocs - */ - final public function objectType() { - return $this->object_type; - } + /** + * @inheritdocs + */ + final public function objectType() :string + { + return $this->object_type; + } } diff --git a/src/ILIAS/UnboundProvider.php b/src/ILIAS/UnboundProvider.php index e2e543d..c2ad25b 100644 --- a/src/ILIAS/UnboundProvider.php +++ b/src/ILIAS/UnboundProvider.php @@ -8,47 +8,48 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; +use CaT\Ente\Component; +use CaT\Ente\Entity AS IEntity; + /** * An unbound provider is a provider that currently is not bound to an * entity and can thus not produce components. */ -interface UnboundProvider { - /** - * @inheritdocs - */ - public function componentTypes(); - - /** - * Build the component(s) of the given type for the given object. - * - * @param string $component_type - * @param Entity $provider - * @return Component[] - */ - public function buildComponentsOf($component_type, Entity $entity); - - /** - * Get the id of this provider for the given owner. - * - * @param \ilObject $owner - * @throws \InvalidArgumentException if $owner is not an owner of this provider - * @return int - */ - public function idFor(\ilObject $owner); - - /** - * Get the owner object of the component. - * - * @return \ilObject[] - */ - public function owners(); - - /** - * Get the object type this binds to. - * - * @return string - */ - public function objectType(); +interface UnboundProvider +{ + /** + * @inheritdocs + */ + public function componentTypes(); + + /** + * Build the component(s) of the given type for the given object. + * @return Component[] + */ + public function buildComponentsOf(string $component_type, IEntity $entity) : array; + + /** + * Get the id of this provider for the given owner. + * + * @throws \InvalidArgumentException if $owner is not an owner of this provider + */ + public function idFor(\ilObject $owner) : int; + + /** + * Get the owner object of the component. + * + * @return \ilObject[] + */ + public function owners() : array; + + /** + * Get the object type this binds to. + * + * @return string + */ + public function objectType() : string; } diff --git a/src/Provider.php b/src/Provider.php index d2e77f4..b5347d9 100644 --- a/src/Provider.php +++ b/src/Provider.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** @@ -19,35 +21,36 @@ * components for one entity. The use cases for the framework will be mostly * entity centric, thus it makes more sense to have according providers. */ -interface Provider { - /** - * Get the components of a given type. - * - * `$component_type` must be a class or interface name. The returned - * components must implement that class or interface. - * - * For every `$component_type` not included in `providedComponentTypes` - * this must return an empty array. - * - * For every `$entity` not included in `providesForEntities` this must - * return an empty array. - * - * @param string $component_type - * @return Component[] - */ - public function componentsOfType($component_type); +interface Provider +{ + /** + * Get the components of a given type. + * + * `$component_type` must be a class or interface name. The returned + * components must implement that class or interface. + * + * For every `$component_type` not included in `providedComponentTypes` + * this must return an empty array. + * + * For every `$entity` not included in `providesForEntities` this must + * return an empty array. + * + * @param string $component_type + * @return Component[] + */ + public function componentsOfType(string $component_type) : array; - /** - * Get the component types this provider provides. - * - * @return string[] - */ - public function componentTypes(); + /** + * Get the component types this provider provides. + * + * @return string[] + */ + public function componentTypes() : array; - /** - * Get the entity this provider provides components for. - * - * @return Entity - */ - public function entity(); + /** + * Get the entity this provider provides components for. + * + * @return Entity + */ + public function entity() : Entity; } diff --git a/src/ProviderHelper.php b/src/ProviderHelper.php index d32a0bd..c8cf11c 100644 --- a/src/ProviderHelper.php +++ b/src/ProviderHelper.php @@ -8,27 +8,28 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** * Helpers to implement providers. */ -trait ProviderHelper { - /** - * Get the component types implemented by the given component. - * - * Traverses all implemented interfaces and checks if they extend `Component`. - * - * @param Component $component - * @return string[] - */ - public function componentTypesOf(Component $component) { - $ret = []; - foreach (class_implements(get_class($component)) as $interface) { - if (is_subclass_of($interface, Component::class)) { - $ret[] = $interface; - } - } - return $ret; - } +trait ProviderHelper +{ + /** + * Get the component types implemented by the given component. + * Traverses all implemented interfaces and checks if they extend `Component`. + * @return string[] + */ + public function componentTypesOf(Component $component) : array + { + $ret = []; + foreach (class_implements(get_class($component)) as $interface) { + if (is_subclass_of($interface, Component::class)) { + $ret[] = $interface; + } + } + return $ret; + } } diff --git a/src/Repository.php b/src/Repository.php index 5536254..6231138 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** @@ -18,22 +20,17 @@ * doesn't have a provider. The provider was introduced to render a central * storage mechanism for all components unnecessary. */ -interface Repository { - /** - * Get providers for an entity, possibly filtered by a component type. - * - * @param Entity $entity - * @param string|null $component_type - * @return Provider[] - */ - public function providersForEntity(Entity $entity, $component_type = null); +interface Repository +{ + /** + * Get providers for an entity, possibly filtered by a component type. + * @return Provider[] + */ + public function providersForEntity(Entity $entity, string $component_type = null) : array; /** * Get components for the entity, possibly filtered by component type. - * - * @param Entity $entity - * @param string|null $component_type * @return Component[] */ - public function componentsForEntity(Entity $entity, $component_type = null); + public function componentsForEntity(Entity $entity, string $component_type = null) : array; } diff --git a/src/RepositoryHelper.php b/src/RepositoryHelper.php index 825da7d..a3a6029 100644 --- a/src/RepositoryHelper.php +++ b/src/RepositoryHelper.php @@ -8,30 +8,31 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente; /** * Helper for all repositories. Repos only need to implement a minimal amount * of methods then. */ -trait RepositoryHelper { - /** - * Get providers for an entity, possibly filtered by a component type. - * - * @param Entity $entity - * @param string|null $component_type - * @return Provider[] - */ - abstract public function providersForEntity(Entity $entity, $component_type = null); +trait RepositoryHelper +{ + /** + * Get providers for an entity, possibly filtered by a component type. + * @return Provider[] + */ + abstract public function providersForEntity( + Entity $entity, + string $component_type = null + ) : array; /** * Get components for the entity, possibly filtered by component type. - * - * @param Entity $entity - * @param string|null $component_type - * @return Component[] + * @return Component[] */ - public function componentsForEntity(Entity $entity, $component_type = null) { + public function componentsForEntity(Entity $entity, string $component_type = null) : array + { $providers = $this->providersForEntity($entity, $component_type); $components = []; foreach ($providers as $provider) { diff --git a/src/Simple/AttachInt.php b/src/Simple/AttachInt.php index c0d5eb5..4f9d2fe 100644 --- a/src/Simple/AttachInt.php +++ b/src/Simple/AttachInt.php @@ -8,18 +8,21 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; +use \CaT\Ente\Component; + /** * Attaches an integer to an entity. * * Intended to be used for testing. */ -interface AttachInt extends \CaT\Ente\Component { - /** - * Get the attached integer. - * - * @return int - */ - public function attachedInt(); +interface AttachInt extends Component +{ + /** + * Get the attached integer. + */ + public function attachedInt() : int; } diff --git a/src/Simple/AttachIntMemory.php b/src/Simple/AttachIntMemory.php index 7b2dcc5..b9a1624 100644 --- a/src/Simple/AttachIntMemory.php +++ b/src/Simple/AttachIntMemory.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; use CaT\Ente\Entity as IEntity; @@ -15,34 +17,37 @@ /** * In memory implementation of AttachInt. */ -class AttachIntMemory implements AttachInt { - /** - * @var IEntity - */ - private $entity; - - /** - * @var int - */ - private $attached_int; - - public function __construct(IEntity $entity, $attached_int) { - assert('is_int($attached_int)'); - $this->entity = $entity; - $this->attached_int = $attached_int; - } - - /** - * @inheritdocs - */ - public function entity() { - return $this->entity; - } - - /** - * @inheritdocs - */ - public function attachedInt() { - return $this->attached_int; - } +class AttachIntMemory implements AttachInt +{ + /** + * @var IEntity + */ + private $entity; + + /** + * @var int + */ + private $attached_int; + + public function __construct(IEntity $entity, int $attached_int) + { + $this->entity = $entity; + $this->attached_int = $attached_int; + } + + /** + * @inheritdocs + */ + public function entity() : IEntity + { + return $this->entity; + } + + /** + * @inheritdocs + */ + public function attachedInt() : int + { + return $this->attached_int; + } } diff --git a/src/Simple/AttachString.php b/src/Simple/AttachString.php index bc06aec..2592a7c 100644 --- a/src/Simple/AttachString.php +++ b/src/Simple/AttachString.php @@ -8,18 +8,21 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; +use \CaT\Ente\Component; + /** * Attaches a string to an entity. * * Intended to be used for testing. */ -interface AttachString extends \CaT\Ente\Component { - /** - * Get the attached string. - * - * @return string - */ - public function attachedString(); +interface AttachString extends Component +{ + /** + * Get the attached string. + */ + public function attachedString() : string; } diff --git a/src/Simple/AttachStringMemory.php b/src/Simple/AttachStringMemory.php index d5829ea..14f56f1 100644 --- a/src/Simple/AttachStringMemory.php +++ b/src/Simple/AttachStringMemory.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; use CaT\Ente\Entity as IEntity; @@ -15,34 +17,37 @@ /** * In memory implementation of AttachString. */ -class AttachStringMemory implements AttachString { - /** - * @var IEntity - */ - private $entity; - - /** - * @var string - */ - private $attached_string; - - public function __construct(IEntity $entity, $attached_string) { - assert('is_string($attached_string)'); - $this->entity = $entity; - $this->attached_string = $attached_string; - } - - /** - * @inheritdocs - */ - public function entity() { - return $this->entity; - } - - /** - * @inheritdocs - */ - public function attachedString() { - return $this->attached_string; - } +class AttachStringMemory implements AttachString +{ + /** + * @var IEntity + */ + private $entity; + + /** + * @var string + */ + private $attached_string; + + public function __construct(IEntity $entity, string $attached_string) + { + $this->entity = $entity; + $this->attached_string = $attached_string; + } + + /** + * @inheritdocs + */ + public function entity() : IEntity + { + return $this->entity; + } + + /** + * @inheritdocs + */ + public function attachedString() : string + { + return $this->attached_string; + } } diff --git a/src/Simple/Entity.php b/src/Simple/Entity.php index 5f73aeb..b8ce885 100644 --- a/src/Simple/Entity.php +++ b/src/Simple/Entity.php @@ -8,26 +8,30 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; /** * Simple implementation for an entity. */ -class Entity implements \CaT\Ente\Entity { - /** - * @var integer - */ - private $id; +class Entity implements \CaT\Ente\Entity +{ + /** + * @var integer + */ + private $id; - public function __construct($id) { - assert('is_integer($id)'); - $this->id = $id; - } + public function __construct(int $id) + { + $this->id = $id; + } - /** - * @inheritdocs - */ - public function id() { - return $this->id; - } + /** + * @inheritdocs + */ + public function id() : int + { + return $this->id; + } } diff --git a/src/Simple/Provider.php b/src/Simple/Provider.php index 7940500..2e0a71d 100644 --- a/src/Simple/Provider.php +++ b/src/Simple/Provider.php @@ -8,74 +8,84 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; +use CaT\Ente; + /** * Simple implementation for a provider, works in memory. */ -class Provider implements \CaT\Ente\Provider { - use \CaT\Ente\ProviderHelper; +class Provider implements \CaT\Ente\Provider +{ + use Ente\ProviderHelper; - /** - * @var Entity - */ - private $entity; + /** + * @var Entity + */ + private $entity; - /** - * @var array - */ - private $components; + /** + * @var array + */ + private $components; - public function __construct(Entity $entity) { - $this->entity = $entity; - $this->components = []; - } + public function __construct(Entity $entity) + { + $this->entity = $entity; + $this->components = []; + } - /** - * @inheritdocs - */ - public function componentsOfType($component_type) { - if (isset($this->components[$component_type])) { - return $this->components[$component_type]; - } - return []; - } + /** + * @inheritdocs + */ + public function componentsOfType(string $component_type) : array + { + if (isset($this->components[$component_type])) { + return $this->components[$component_type]; + } + return []; + } - /** - * @inheritdocs - */ - public function componentTypes() { - return array_keys($this->components); - } + /** + * @inheritdocs + */ + public function componentTypes() : array + { + return array_keys($this->components); + } - /** - * @inheritdocs - */ - public function entity() { - return $this->entity; - } + /** + * @inheritdocs + */ + public function entity() : Ente\Entity + { + return $this->entity; + } - /** - * Add a component to the provider. - * - * @param \CaT\Ente\Component $component - * @throws InvalidArgumentException if $component belongs to another entity - * @return self - */ - public function addComponent(\CaT\Ente\Component $component) { - if ($component->entity()->id() !== $this->entity()->id()) { - $my_id = serialize($this->entity()->id()); - $other_id = serialize($component->entity()->id()); - throw new \InvalidArgumentException( - "Cannot add component of entity '$other_id' to provider for '$my_id'."); - } + /** + * Add a component to the provider. + * + * @param \CaT\Ente\Component $component + * @throws InvalidArgumentException if $component belongs to another entity + * @return self + */ + public function addComponent(Ente\Component $component) : Provider + { + if ($component->entity()->id() !== $this->entity()->id()) { + $my_id = serialize($this->entity()->id()); + $other_id = serialize($component->entity()->id()); + throw new \InvalidArgumentException( + "Cannot add component of entity '$other_id' to provider for '$my_id'."); + } - foreach ($this->componentTypesOf($component) as $type) { - if (!isset($this->components[$type])) { - $this->components[$type] = []; - } - $this->components[$type][] = $component; - } - return $this; - } + foreach ($this->componentTypesOf($component) as $type) { + if (!isset($this->components[$type])) { + $this->components[$type] = []; + } + $this->components[$type][] = $component; + } + return $this; + } } diff --git a/src/Simple/Repository.php b/src/Simple/Repository.php index 9c05464..871f0cf 100644 --- a/src/Simple/Repository.php +++ b/src/Simple/Repository.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\Simple; use CaT\Ente; @@ -18,55 +20,62 @@ class Repository implements Ente\Repository { use Ente\RepositoryHelper; - /** - * @var array - */ - protected $providers; + /** + * @var array + */ + protected $providers; - /** - * @var array - */ - protected $entities; + /** + * @var array + */ + protected $entities; - public function __construct() { - $this->providers = []; - $this->entities = []; - } + public function __construct() + { + $this->providers = []; + $this->entities = []; + } - /** - * @inheritdocs - */ - public function providersForEntity(Ente\Entity $entity, $component_type = null) { - $id = serialize($entity->id()); - if (!isset($this->providers[$id])) { - return []; - } + /** + * @inheritdocs + */ + public function providersForEntity( + Ente\Entity $entity, + string $component_type = null + ) : array { + $id = serialize($entity->id()); + if (!isset($this->providers[$id])) { + return []; + } - $ret = []; - foreach ($this->providers[$id] as $provider) { - if ($component_type === null - || in_array($component_type, $provider->componentTypes())) { - $ret[] = $provider; - } - } - return $ret; - } + $ret = []; + foreach ($this->providers[$id] as $provider) { + if ( + $component_type === null || + in_array($component_type, $provider->componentTypes()) + ) { + $ret[] = $provider; + } + } + return $ret; + } - /** - * Add a provider to this repository. - * - * @param Provider $provider - * @return self - */ - public function addProvider(Provider $provider) { - $id = serialize($provider->entity()->id()); - if (!isset($this->entities[$id])) { - $this->entities[$id] = $provider->entity(); - } - if (!isset($this->providers[$id])) { - $this->providers[$id] = []; - } - $this->providers[$id][] = $provider; - return $this; - } + /** + * Add a provider to this repository. + * + * @param Provider $provider + * @return self + */ + public function addProvider(Provider $provider) : Repository + { + $id = serialize($provider->entity()->id()); + if (!isset($this->entities[$id])) { + $this->entities[$id] = $provider->entity(); + } + if (!isset($this->providers[$id])) { + $this->providers[$id] = []; + } + $this->providers[$id][] = $provider; + return $this; + } } From 6ee75539cd153cb8aa3b490ab68e25c953e62588 Mon Sep 17 00:00:00 2001 From: Stefan Hecken Date: Wed, 3 Jul 2019 14:12:20 +0200 Subject: [PATCH 2/6] Last steps in php7 refactoring and Fixing ILIAS tests --- composer.json | 8 +- src/CachedProvider.php | 2 +- src/ILIAS/Entity.php | 4 +- src/ILIAS/ProviderDB.php | 6 +- src/ILIAS/ilCachesOwnerRangeProviderDB.php | 434 ++-- src/ILIAS/ilGlobalCache.php | 83 +- src/ILIAS/ilHandlerObjectHelper.php | 111 +- src/ILIAS/ilObjectHelper.php | 47 +- src/ILIAS/ilProviderDB.php | 1184 ++++++----- src/ILIAS/ilProviderObjectHelper.php | 9 +- tests/ILIAS/SeparatedUnboundProviderTest.php | 10 +- tests/ILIAS/SharedUnboundProviderTest.php | 6 +- .../ILIAS/ilCachesOwnerRangeProviderTest.php | 52 +- tests/ILIAS/ilHandlerObjectHelperTest.php | 4 +- tests/ILIAS/ilProviderDBTest.php | 1781 +++++++++-------- tests/ILIAS/ilProviderObjectHelperTest.php | 11 +- tests/ProviderHelperTest.php | 3 +- 17 files changed, 1965 insertions(+), 1790 deletions(-) diff --git a/composer.json b/composer.json index 05c7405..215e893 100644 --- a/composer.json +++ b/composer.json @@ -11,10 +11,10 @@ } ], "autoload" : { - "psr-4" : { "CaT\\Ente\\" : "src" } + "psr-4" : { "CaT\\Ente\\" : ["src", "tests"] } }, "require": {}, - "require-dev" : { - "phpunit/phpunit" : "^5.6" - } + "require-dev" : { + "phpunit/phpunit" : "^5.6" + } } diff --git a/src/CachedProvider.php b/src/CachedProvider.php index 9acd84a..91b1eb1 100644 --- a/src/CachedProvider.php +++ b/src/CachedProvider.php @@ -48,7 +48,7 @@ public function componentsOfType(string $component_type) : array /** * @inheritdocs */ - public function componentTypes() : string + public function componentTypes() : array { return $this->provider->componentTypes(); } diff --git a/src/ILIAS/Entity.php b/src/ILIAS/Entity.php index 890124e..58df176 100644 --- a/src/ILIAS/Entity.php +++ b/src/ILIAS/Entity.php @@ -12,10 +12,12 @@ namespace CaT\Ente\ILIAS; +use \CaT\Ente\Entity AS IEntity; + /** * An entity over an ILIAS object. */ -class Entity implements \CaT\Ente\Entity +class Entity implements IEntity { /** * @var \ilObject diff --git a/src/ILIAS/ProviderDB.php b/src/ILIAS/ProviderDB.php index 6156ec2..dd7bfe9 100644 --- a/src/ILIAS/ProviderDB.php +++ b/src/ILIAS/ProviderDB.php @@ -47,13 +47,10 @@ public function createSharedUnboundProvider( * Load the unbound provider with the given id. * @throws \InvalidArgumentException if the provider with the supplied id does not exist. */ - public function load(int $id) : UnboundProvider; + public function load(int $id) : UnboundProvider; /** * Delete a given unbound provider. - * @param UnboundProvider $provider - * @param UnboundProvider $provider - * @return null */ public function delete(UnboundProvider $provider, \ilObject $owner); @@ -61,7 +58,6 @@ public function delete(UnboundProvider $provider, \ilObject $owner); * Update the given unbound provider. * * The only thing that may be updated are the components that are provided. - * @param UnboundProvider $provider */ public function update(UnboundProvider $provider); diff --git a/src/ILIAS/ilCachesOwnerRangeProviderDB.php b/src/ILIAS/ilCachesOwnerRangeProviderDB.php index db9b1eb..ca92ea7 100644 --- a/src/ILIAS/ilCachesOwnerRangeProviderDB.php +++ b/src/ILIAS/ilCachesOwnerRangeProviderDB.php @@ -8,238 +8,214 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; /** * A database that stores ILIAS providers and uses a cache. */ -class ilCachesOwnerRangeProviderDB extends ilProviderDB { - /** - * @var Cache - */ - protected $cache; - - /** - * @var int - */ - protected $shard_size; - - /** - * @var array - */ - protected $shards; - - /** - * @var \ilDBInterface - */ - private $ilDB; - - /** - * @param int $shard_size how many owners are stored in one cache entry? - */ - public function __construct(\ilDBInterface $ilDB, \ilTree $tree, \ilObjectDataCache $obj_cache, Cache $cache, int $shard_size = 1000) { - parent::__construct($ilDB, $tree, $obj_cache); - $this->ilDB = $ilDB; - $this->cache = $cache; - $this->shard_size = $shard_size; - $this->shards = []; - } - - /** - * @inheritdocs - */ - public function createSeparatedUnboundProvider(\ilObject $owner, $object_type, $class_name, $include_path) { - $res = parent::createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); - $this->refreshShardOf($owner->getId()); - return $res; - } - - /** - * @inheritdocs - */ - public function createSharedUnboundProvider(\ilObject $owner, $object_type, $class_name, $include_path) { - $res = parent::createSharedUnboundProvider($owner, $object_type, $class_name, $include_path); - $this->refreshShardOf($owner->getId()); - return $res; - } - - /** - * @inheritdocs - */ - public function delete(UnboundProvider $provider, \ilObject $owner) { - parent::delete($provider, $owner); - $this->refreshShardOf($owner->getId()); - } - - /** - * Get the data of the separated unbound providers of the given nodes. - * - * @param int[] $node_ids - * @param string $object_type - * @param string|null $component_type - * @return array - */ - protected function getSeperatedUnboundProviderDataOf($node_ids, string $object_type, string $component_type = null) { - if ($component_type !== null) { - return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); - } - - $ret = []; - foreach($node_ids as $node_id) { - $ret[] = $this->getDataOf($node_id, $object_type, "separated", $component_type); - } - return call_user_func_array("array_merge", $ret); - } - - /** - * Get the data of the shared unbound providers of the given nodes. - * - * @param int[] $node_ids - * @param string $object_type - * @param string|null $component_type - * @return array - */ - protected function getSharedUnboundProviderDataOf($node_ids, string $object_type, string $component_type = null) { - if ($component_type !== null) { - return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); - } - - $data = []; - foreach($node_ids as $node_id) { - $ds = $this->getDataOf($node_id, $object_type, "shared"); - foreach ($ds as $d) { - $key = $d["class_name"]." ".$d["include_path"]; - if(!isset($data[$key])) { - $data[$key] = [ - "owners" => [], - "ids" => [], - "class_name" => $d["class_name"], - "include_path" => $d["include_path"] - ]; - } - $data[$key]["owners"][] = $d["owner"]; - $data[$key]["ids"][] = $d["id"]; - } - } - return array_values($data); - } - - /** - * Refreshes a shard in the cache from the database. - */ - protected function refreshShardOf(int $node_id) { - $shard_id = $this->getShardIdOf($node_id); - return $this->refreshShard($shard_id); - } - - /** - * Refreshes a shard in the cache from the database. - */ - protected function refreshShard(int $shard_id) { - unset($this->shards[$shard_id]); - $data = $this->loadShardDataFromDB($shard_id); - // For some reason we get a null in maybeLoadShardDataFromCache if the array - // is completely empty. This produces (wrong) cache misses. To prevent them - // we set this key. - $data["i am"] = "here"; - $this->shards[$shard_id] = $data; - $this->cache->set("$shard_id", $data); - } - - /** - * Get the data for a specific node. - */ - protected function getDataOf(int $node_id, string $object_type, string $which) { - $shard_id = $this->getShardIdOf($node_id); - $this->maybeLoadShardDataFromCache($shard_id); - if (!isset($this->shards[$shard_id][$node_id][$object_type])) { - return []; - } - return $this->shards[$shard_id][$node_id][$object_type][$which]; - } - - /** - * Get the id of the shard the node is in. - */ - protected function getShardIdOf(int $node_id) { - return (int)floor($node_id/$this->shard_size); - } - - /** - * Load shard data from cache if not already loaded. - */ - protected function maybeLoadShardDataFromCache(int $shard_id) { - if (isset($this->shards[$shard_id])) { - return; - } - $data = $this->cache->get("$shard_id"); - if ($data !== null) { - $this->shards[$shard_id] = $data; - return; - } - $this->refreshShard($shard_id); - } - - /** - * Load the data for a shard from the db. - */ - protected function loadShardDataFromDB($shard_id) { - $data = []; - $l = $shard_id * $this->shard_size; - $r = ($shard_id + 1) * $this->shard_size; - foreach ($this->getUnboundProviderDataOf($l, $r) as $d) { - $owner = $d["owner"]; - $object_type = $d["object_type"]; - if (!isset($data[$owner])) { - $data[$owner] = []; - } - if (!isset($data[$owner][$object_type])) { - $data[$owner][$object_type] = [ "separated" => [], "shared" => []]; - } - $data[$owner][$object_type][$d["which"]][] = $d; - } - return $data; - } - - /** - * Get the data of the seperated unbound providers of the given range of owners. - * - * @param int $left first owner to be used - * @param int $right first owner not to be used - * @return \Iterator - */ - protected function getUnboundProviderDataOf(int $left, int $right) { - assert($left < $right); - assert($right - $left > 0); - $query = $this->buildUnboundProviderQueryForObjects($left, $right); - $res = $this->ilDB->query($query); - while ($row = $this->ilDB->fetchAssoc($res)) { - yield [ - "id" => (int)$row["id"], - "owner" => (int)$row["owner"], - "class_name" => $row["class_name"], - "include_path" => $row["include_path"], - "object_type" => $row["object_type"], - "which" => $row["shared"] == 0 ? "separated" : "shared" - ]; - } - } - - /** - * Get a query for all SeparatedUnboundProviders that are owned by the given nodes - * providing for a given object type. - * - * @param int $left first owner to be used - * @param int $right first owner not to be used - * @return string - */ - protected function buildUnboundProviderQueryForObjects(int $left, int $right) { - assert($left < $right); - assert($right - $left > 0); - return - "SELECT id, owner, class_name, include_path, object_type, shared ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE owner >= ".$this->ilDB->quote($left, "integer"). - " AND owner < ".$this->ilDB->quote($right, "integer"); - } +class ilCachesOwnerRangeProviderDB extends ilProviderDB +{ + /** + * @var Cache + */ + protected $cache; + + /** + * @var int + */ + protected $shard_size; + + /** + * @var array + */ + protected $shards; + + /** + * @var \ilDBInterface + */ + private $ilDB; + + public function __construct( + \ilDBInterface $ilDB, + \ilTree $tree, + \ilObjectDataCache $obj_cache, + Cache $cache, + int $shard_size = 1000 + ) { + parent::__construct($ilDB, $tree, $obj_cache); + $this->ilDB = $ilDB; + $this->cache = $cache; + $this->shard_size = $shard_size; + $this->shards = []; + } + + /** + * @inheritdocs + */ + public function createSeparatedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ) : SeparatedUnboundProvider { + $res = parent::createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); + $this->refreshShardOf($owner->getId()); + return $res; + } + + /** + * @inheritdocs + */ + public function createSharedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ) : SharedUnboundProvider { + $res = parent::createSharedUnboundProvider($owner, $object_type, $class_name, $include_path); + $this->refreshShardOf($owner->getId()); + return $res; + } + + /** + * @inheritdocs + */ + public function delete(UnboundProvider $provider, \ilObject $owner) { + parent::delete($provider, $owner); + $this->refreshShardOf($owner->getId()); + } + + protected function getSeperatedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ) : iterable { + if ($component_type !== null) { + return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); + } + + $ret = []; + foreach($node_ids as $node_id) { + $ret[] = $this->getDataOf($node_id, $object_type, "separated", $component_type); + } + return call_user_func_array("array_merge", $ret); + } + + protected function getSharedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ) : iterable { + if ($component_type !== null) { + return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); + } + + $data = []; + foreach($node_ids as $node_id) { + $ds = $this->getDataOf($node_id, $object_type, "shared"); + foreach ($ds as $d) { + $key = $d["class_name"]." ".$d["include_path"]; + if(!isset($data[$key])) { + $data[$key] = [ + "owners" => [], + "ids" => [], + "class_name" => $d["class_name"], + "include_path" => $d["include_path"] + ]; + } + $data[$key]["owners"][] = $d["owner"]; + $data[$key]["ids"][] = $d["id"]; + } + } + return array_values($data); + } + + protected function refreshShardOf(int $node_id) { + $shard_id = $this->getShardIdOf($node_id); + return $this->refreshShard($shard_id); + } + + protected function refreshShard(int $shard_id) { + unset($this->shards[$shard_id]); + $data = $this->loadShardDataFromDB($shard_id); + // For some reason we get a null in maybeLoadShardDataFromCache if the array + // is completely empty. This produces (wrong) cache misses. To prevent them + // we set this key. + $data["i am"] = "here"; + $this->shards[$shard_id] = $data; + $this->cache->set("$shard_id", $data); + } + + protected function getDataOf(int $node_id, string $object_type, string $which) { + $shard_id = $this->getShardIdOf($node_id); + $this->maybeLoadShardDataFromCache($shard_id); + if (!isset($this->shards[$shard_id][$node_id][$object_type])) { + return []; + } + return $this->shards[$shard_id][$node_id][$object_type][$which]; + } + + protected function getShardIdOf(int $node_id) { + return (int)floor($node_id/$this->shard_size); + } + + protected function maybeLoadShardDataFromCache(int $shard_id) { + if (isset($this->shards[$shard_id])) { + return; + } + $data = $this->cache->get("$shard_id"); + if ($data !== null) { + $this->shards[$shard_id] = $data; + return; + } + $this->refreshShard($shard_id); + } + + protected function loadShardDataFromDB($shard_id) { + $data = []; + $l = $shard_id * $this->shard_size; + $r = ($shard_id + 1) * $this->shard_size; + foreach ($this->getUnboundProviderDataOf($l, $r) as $d) { + $owner = $d["owner"]; + $object_type = $d["object_type"]; + if (!isset($data[$owner])) { + $data[$owner] = []; + } + if (!isset($data[$owner][$object_type])) { + $data[$owner][$object_type] = [ "separated" => [], "shared" => []]; + } + $data[$owner][$object_type][$d["which"]][] = $d; + } + return $data; + } + + protected function getUnboundProviderDataOf(int $left, int $right) : \Iterator + { + assert($left < $right); + assert($right - $left > 0); + $query = $this->buildUnboundProviderQueryForObjects($left, $right); + $res = $this->ilDB->query($query); + while ($row = $this->ilDB->fetchAssoc($res)) { + yield [ + "id" => (int)$row["id"], + "owner" => (int)$row["owner"], + "class_name" => $row["class_name"], + "include_path" => $row["include_path"], + "object_type" => $row["object_type"], + "which" => $row["shared"] == 0 ? "separated" : "shared" + ]; + } + } + + protected function buildUnboundProviderQueryForObjects(int $left, int $right) : string { + assert($left < $right); + assert($right - $left > 0); + return + "SELECT id, owner, class_name, include_path, object_type, shared ". + "FROM ".ilProviderDB::PROVIDER_TABLE." ". + "WHERE owner >= ".$this->ilDB->quote($left, "integer"). + " AND owner < ".$this->ilDB->quote($right, "integer"); + } } diff --git a/src/ILIAS/ilGlobalCache.php b/src/ILIAS/ilGlobalCache.php index bc764be..fa38905 100644 --- a/src/ILIAS/ilGlobalCache.php +++ b/src/ILIAS/ilGlobalCache.php @@ -8,47 +8,54 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; /** * Contract for a cache. */ -class ilGlobalCache implements Cache { - /** - * @var \ilGlobalCache - */ - protected $il_global_cache; - - /** - * @var int|null - */ - protected $ttl_in_seconds; - - const PREFIX = "tms_ente_"; - - public function __construct(\ilGlobalCache $cache, int $ttl_in_seconds = null) { - $this->il_global_cache = $cache; - $this->ttl_in_seconds = $ttl_in_seconds; - } - - /** - * @return void - */ - public function set(string $key, array $value) { - return $this->il_global_cache->set(self::PREFIX.$key, $value); - } - - /** - * @return array|null - */ - public function get(string $key) { - return $this->il_global_cache->get(self::PREFIX.$key); - } - - /** - * @return void - */ - public function delete(string $key) { - $this->il_global_cache->delete(self::PREFIX.$key); - } +class ilGlobalCache implements Cache +{ + /** + * @var \ilGlobalCache + */ + protected $il_global_cache; + + /** + * @var int|null + */ + protected $ttl_in_seconds; + + const PREFIX = "tms_ente_"; + + public function __construct(\ilGlobalCache $cache, int $ttl_in_seconds = null) + { + $this->il_global_cache = $cache; + $this->ttl_in_seconds = $ttl_in_seconds; + } + + /** + * @inheritDoc + */ + public function set(string $key, array $value) + { + return $this->il_global_cache->set(self::PREFIX.$key, $value); + } + + /** + * @inheritDoc + */ + public function get(string $key) + { + return $this->il_global_cache->get(self::PREFIX.$key); + } + + /** + * @inheritDoc + */ + public function delete(string $key) + { + $this->il_global_cache->delete(self::PREFIX.$key); + } } diff --git a/src/ILIAS/ilHandlerObjectHelper.php b/src/ILIAS/ilHandlerObjectHelper.php index 2784cdb..314482b 100644 --- a/src/ILIAS/ilHandlerObjectHelper.php +++ b/src/ILIAS/ilHandlerObjectHelper.php @@ -8,72 +8,71 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; -use CaT\Ente; +use \CaT\Ente\Component AS IComponent; +use \CaT\Ente\Entity AS IEntity; +use \CaT\Ente\CachedRepository; /** * Helper for repository objects that want to handle components. */ -trait ilHandlerObjectHelper { - use ilObjectHelper; +trait ilHandlerObjectHelper +{ + use ilObjectHelper; - /** - * Get a repository for providers and components. - * - * @return \CaT\Ente\Repository - */ - protected function getRepository() { - $DIC = $this->getDIC(); - if (!isset($DIC["ente.repository"])) { - $DIC["ente.repository"] = function ($c) { - return new Ente\CachedRepository( - new \CaT\Ente\ILIAS\Repository($c["ente.provider_db"]) - ); + /** + * Get a repository for providers and components. + * + * @return \CaT\Ente\Repository + */ + protected function getRepository() { + $DIC = $this->getDIC(); + if (!isset($DIC["ente.repository"])) { + $DIC["ente.repository"] = function ($c) { + return new CachedRepository( + new Repository($c["ente.provider_db"]) + ); }; - } - return $DIC["ente.repository"]; - } + } + return $DIC["ente.repository"]; + } - /** - * Get components for the entity. - * - * @return Component[] - */ - protected function getComponents() { - $repository = $this->getRepository(); - return $repository->componentsForEntity($this->getEntity()); - } + /** + * Get components for the entity. + * + * @return IComponent[] + */ + protected function getComponents() { + $repository = $this->getRepository(); + return $repository->componentsForEntity($this->getEntity()); + } - /** - * Get components for the entity. - * - * @param string $component_type - * @return Component[] - */ - protected function getComponentsOfType($component_type) { - assert('is_string($component_type)'); - $repository = $this->getRepository(); - return $repository->componentsForEntity($this->getEntity(), $component_type); - } + /** + * @return IComponent[] + */ + protected function getComponentsOfType(string $component_type) : array + { + $repository = $this->getRepository(); + return $repository->componentsForEntity($this->getEntity(), $component_type); + } - /** - * Get the entity this object handles components for. - * - * @return Ente\Entity - */ - protected function getEntity() { - return new \CaT\Ente\ILIAS\Entity - ( \ilObjectFactory::getInstanceByRefId - ( $this->getEntityRefId() - ) - ); - } + /** + * Get the entity this object handles components for. + */ + protected function getEntity() : IEntity + { + return new Entity( + \ilObjectFactory::getInstanceByRefId( + $this->getEntityRefId() + ) + ); + } - /** - * Get the ref_id of the object this object handles components for. - * - * @return int - */ - abstract protected function getEntityRefId(); + /** + * Get the ref_id of the object this object handles components for. + */ + abstract protected function getEntityRefId() : int; } diff --git a/src/ILIAS/ilObjectHelper.php b/src/ILIAS/ilObjectHelper.php index b3b8478..aaa59f5 100644 --- a/src/ILIAS/ilObjectHelper.php +++ b/src/ILIAS/ilObjectHelper.php @@ -8,6 +8,8 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; use CaT\Ente; @@ -17,27 +19,28 @@ * use this directly, use ilHandlerObjectHelper or * ilProviderObjectHelper. */ -trait ilObjectHelper { - /** - * @return \CaT\Ente\ILIAS\ProviderDB - */ - protected function getProviderDB() { - $DIC = $this->getDIC(); - if (!isset($DIC["ente.provider_db"])) { - $DIC["ente.provider_db"] = new \CaT\Ente\ILIAS\ilProviderDB - ( $DIC["ilDB"] - , $DIC["tree"] - , $DIC["ilObjDataCache"] - , $DIC - ); - } - return $DIC["ente.provider_db"]; - } +trait ilObjectHelper +{ + /** + * @return Ente\ILIAS\ProviderDB + */ + protected function getProviderDB() : Ente\ILIAS\ProviderDB + { + $DIC = $this->getDIC(); + if (!isset($DIC["ente.provider_db"])) { + $DIC["ente.provider_db"] = new Ente\ILIAS\ilProviderDB( + $DIC["ilDB"], + $DIC["tree"], + $DIC["ilObjDataCache"] + ); + } + return $DIC["ente.provider_db"]; + } - /** - * Get the ILIAS DIC. - * - * @return \ArrayAccess - */ - abstract protected function getDIC(); + /** + * Get the ILIAS DIC. + * + * @return \ArrayAccess + */ + abstract protected function getDIC(); } diff --git a/src/ILIAS/ilProviderDB.php b/src/ILIAS/ilProviderDB.php index ff8a7fc..0c119be 100644 --- a/src/ILIAS/ilProviderDB.php +++ b/src/ILIAS/ilProviderDB.php @@ -8,545 +8,657 @@ * the license along with the code. */ +declare(strict_types=1); + namespace CaT\Ente\ILIAS; /** * A database that stores ILIAS providers. */ -class ilProviderDB implements ProviderDB { - const PROVIDER_TABLE = "ente_prvs"; - const COMPONENT_TABLE = "ente_prv_cmps"; - - const CLASS_NAME_LENGTH = 128; - const PATH_LENGTH = 1024; - - /** - * @var \ilDBInterface - */ - private $ilDB; - - /** - * @var \ilTree - */ - private $ilTree; - - /** - * @var \ilObjectDataCache - */ - private $ilObjectDataCache; - - public function __construct(\ilDBInterface $ilDB, \ilTree $tree, \ilObjectDataCache $cache) { - $this->ilDB = $ilDB; - $this->ilTree = $tree; - $this->ilObjectDataCache = $cache; - } - - /** - * @inheritdocs - */ - public function createSeparatedUnboundProvider(\ilObject $owner, $object_type, $class_name, $include_path) { - $this->validateCreationParams($object_type, $class_name, $include_path); - $shared = false; - list($unbound_provider, $id) = $this->createUnboundProvider($owner, $object_type, $class_name, $include_path, $shared); - $this->createComponentsForUnboundProvider($unbound_provider, $id); - return $unbound_provider; - } - - /** - * @inheritdocs - */ - public function createSharedUnboundProvider(\ilObject $owner, $object_type, $class_name, $include_path) { - $this->validateCreationParams($object_type, $class_name, $include_path); - $shared = true; - list($unbound_provider, $id) = $this->createUnboundProvider($owner, $object_type, $class_name, $include_path, $shared); - $this->createComponentsForUnboundProvider($unbound_provider, $id); - return $unbound_provider; - } - - /** - * @param \ilObject $owner - * @param string $obj_type - * @param string $class_name - * @param string $include_path - * @param bool $shared - * @return array(UnboundProvider, int) - */ - private function createUnboundProvider(\ilObject $owner, $object_type, $class_name, $include_path, $shared) { - // TODO: check if class exist first - $id = (int)$this->ilDB->nextId(ilProviderDB::PROVIDER_TABLE); - $this->ilDB->insert(ilProviderDB::PROVIDER_TABLE, - [ "id" => ["integer", $id] - , "owner" => ["integer", $owner->getId()] - , "object_type" => ["string", $object_type] - , "class_name" => ["string", $class_name] - , "include_path" => ["string", $include_path] - , "shared" => ["integer", $shared] - ]); - - if($shared===true) { - $unbound_provider = $this->buildSharedUnboundProvider(array($id=>$owner), $class_name, $class_name, $include_path); - } else { - $unbound_provider = $this->buildSeparatedUnboundProvider($id, $owner, $class_name, $class_name, $include_path); - } - return array($unbound_provider, $id); - } - - - /** - * - * @param string $obj_type - * @param string $class_name - * @param string $include_path - * @throws \LogicException if any parameter is out of bounds - * @return void - */ - private function validateCreationParams($object_type, $class_name, $include_path) { - assert('is_string($object_type)'); - assert('is_string($class_name)'); - assert('is_string($include_path)'); - if (strlen($object_type) > 4) { - throw new \LogicException("Expected object type '$object_type' to have four or less chars."); - } - if (strlen($class_name) > ilProviderDB::CLASS_NAME_LENGTH) { - throw new \LogicException( - "Expected class name '$class_name' to have at most " - .ilProviderDB::CLASS_NAME_LENGTH." chars."); - } - if (strlen($include_path) > ilProviderDB::PATH_LENGTH) { - throw new \LogicException( - "Expected include path '$include_path' to have at most " - .ilProviderDB::PATH_LENGTH." chars."); - } - } - - /** - * - * @param UnboundProvider $unbound_provider - * @param int $id - * @throws \LogicException if class_name of component is out of bounds - * @return void - */ - private function createComponentsForUnboundProvider(UnboundProvider $unbound_provider, $id) { - foreach ($unbound_provider->componentTypes() as $component_type) { - if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { - throw new \LogicException( - "Expected component type '$class_name' to have at most " - .ilProviderDB::CLASS_NAME_LENGTH." chars."); - } - $this->ilDB->insert(ilProviderDB::COMPONENT_TABLE, - [ "id" => ["integer", $id] - , "component_type" => ["string", $component_type] - ]); - } - } - - /** - * @inheritdocs - */ - public function load($id) { - assert('is_int($id)'); - - $query = - "SELECT owner, object_type, class_name, include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE id = ".$this->ilDB->quote($id, "integer"); - $res = $this->ilDB->query($query); - - if($row = $this->ilDB->fetchAssoc($res)) { - $owner = $this->buildObjectByObjId($row["owner"]); - return $this->buildSeparatedUnboundProvider($id, $owner, $row["object_type"], $row["class_name"], $row["include_path"]); - } - else { - throw new \InvalidArgumentException("Unbound provider with id '$id' does not exist."); - } - } - - /** - * @inheritdocs - */ - public function delete(UnboundProvider $provider, \ilObject $owner) { - $id = $provider->idFor($owner); - $this->ilDB->manipulate("DELETE FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ".$this->ilDB->quote($id, "integer")); - $this->ilDB->manipulate("DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ".$this->ilDB->quote($id, "integer")); - } - - /** - * @inheritdocs - */ - public function update(UnboundProvider $provider) { - $component_types = $provider->componentTypes(); - foreach ($provider->owners() as $owner) { - $id = $provider->idFor($owner); - $this->ilDB->manipulate("DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ".$this->ilDB->quote($id, "integer")); - - foreach ($component_types as $component_type) { - if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { - throw new \LogicException( - "Expected component type '$class_name' to have at most " - .ilProviderDB::CLASS_NAME_LENGTH." chars."); - } - $this->ilDB->insert(ilProviderDB::COMPONENT_TABLE, - [ "id" => ["integer", $id] - , "component_type" => ["string", $component_type] - ]); - } - } - } - - /** - * @inheritdocs - */ - public function unboundProvidersOf(\ilObject $owner) { - $ret = []; - - $query = - "SELECT id, object_type, class_name, include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE owner = ".$this->ilDB->quote($owner->getId(), "integer"); - $res = $this->ilDB->query($query); - - while($row = $this->ilDB->fetchAssoc($res)) { - if(is_subclass_of($row["class_name"], 'CaT\Ente\ILIAS\SeparatedUnboundProvider')) { - $ret[] = $this->buildSeparatedUnboundProvider((int)$row["id"], $owner, $row["object_type"], $row["class_name"], $row["include_path"]); - } - if(is_subclass_of($row["class_name"], 'CaT\Ente\ILIAS\SharedUnboundProvider')) { - $ret[] = $this->buildSharedUnboundProvider(array($row["id"]=>$owner), $row["object_type"], $row["class_name"], $row["include_path"]); - } - } - - return $ret; - } - - /** - * @inheritdocs - */ - public function providersFor(\ilObject $object, $component_type = null) { - assert('is_null($component_type) || is_string($component_type)'); - - list($nodes_ids, $nodes_id_mapping) = $this->getSubtreeObjectIdsAndRefIdMapping((int)$object->getRefId()); - $object_type = $object->getType(); - - $ret = []; - - $provider_data = $this->getSeperatedUnboundProviderDataOf($nodes_ids, $object_type, $component_type); - foreach ($provider_data as $data) { - $obj_id = $data["owner"]; - $ref_id = $nodes_id_mapping[$obj_id]; - try { - $owner = $this->buildObjectByRefId($ref_id); - } - catch (\InvalidArgumentException $e) { - continue; - } - $ret[] = new Provider - ( $object - , $this->buildSeparatedUnboundProvider - ( $data["id"] - , $owner - , $object_type - , $data["class_name"] - , $data["include_path"] - ) - ); - } - - $provider_data = $this->getSharedUnboundProviderDataOf($nodes_ids, $object_type, $component_type); - foreach ($provider_data as $data) { - $owners = []; - foreach ($data["owners"] as $obj_id) { - $ref_id = $nodes_id_mapping[$obj_id]; - $prv_id = array_shift($data["ids"]); - try { - $owners[$prv_id] = $this->buildObjectByRefId($ref_id); - } - catch (\InvalidArgumentException $e) { - continue; - } - } - if (count($owners) > 0) { - $ret[] = new Provider - ( $object - , $this->buildSharedUnboundProvider - ( $owners - , $object_type - , $data["class_name"] - , $data["include_path"] - ) - ); - } - } - - return $ret; - } - - /** - * Get the object ids of the subtree starting at and including $ref_id with - * a mapping from $obj_id to $ref_id. - * - * @param int $ref_id - * @return array [int[], array] - */ - protected function getSubtreeObjectIdsAndRefIdMapping($ref_id) { - $sub_nodes_refs = $this->ilTree->getSubTreeIds($ref_id); - $all_nodes_refs = array_merge([$ref_id], $sub_nodes_refs); - $this->ilObjectDataCache->preloadReferenceCache($all_nodes_refs); - - $nodes_id_mapping = []; - $nodes_ids = []; - foreach ($all_nodes_refs as $ref_id) { - $id = $this->ilObjectDataCache->lookupObjId($ref_id); - $nodes_id_mapping[$id] = $ref_id; - $nodes_ids[] = $id; - } - return [$nodes_ids, $nodes_id_mapping]; - } - - /** - * Get the data of the seperated unbound providers of the given nodes. - * - * @param int[] $node_ids - * @param string $object_type - * @param string|null $component_type - * @return array - */ - protected function getSeperatedUnboundProviderDataOf($node_ids, string $object_type, string $component_type = null) { - $query = $this->buildSeparatedUnboundProviderQueryForObjects($node_ids, $object_type, $component_type); - $res = $this->ilDB->query($query); - while ($row = $this->ilDB->fetchAssoc($res)) { - yield [ - "id" => (int)$row["id"], - "owner" => (int)$row["owner"], - "class_name" => $row["class_name"], - "include_path" => $row["include_path"] - ]; - } - } - - /** - * Get the data of the shared unbound providers of the given nodes. - * - * @param int[] $node_ids - * @param string $object_type - * @param string|null $component_type - * @return array - */ - protected function getSharedUnboundProviderDataOf($node_ids, string $object_type, string $component_type = null) { - $to_int_list = function ($r) { - return array_map(function($v) { return (int)$v; }, explode(",", $r)); - }; - $query = $this->buildSharedUnboundProviderQueryForObjects($node_ids, $object_type, $component_type); - $res = $this->ilDB->query($query); - while ($row = $this->ilDB->fetchAssoc($res)) { - yield [ - "owners" => $to_int_list($row["owners"]), - "ids" => $to_int_list($row["ids"]), - "class_name" => $row["class_name"], - "include_path" => $row["include_path"] - ]; - } - } - - /** - * Get a query for all SeparatedUnboundProviders that are owned by the given nodes - * providing for a given object type. - * - * @param int[] $node_ids - * @param string $object_type - * @param string|null $component_type - * @return string - */ - protected function buildSeparatedUnboundProviderQueryForObjects(array $node_ids, $object_type, $component_type) { - assert('is_string($object_type)'); - assert('is_null($component_type) || is_string($component_type)'); - if ($component_type === null) { - return - "SELECT id, owner, class_name, include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE shared = 0". - " AND ".$this->ilDB->in("owner", $node_ids, false, "integer"). - " AND object_type = ".$this->ilDB->quote($object_type, "string"); - } - else { - return - "SELECT prv.id, prv.owner, prv.class_name, prv.include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." prv ". - "JOIN ".ilProviderDB::COMPONENT_TABLE." cmp ". - "ON prv.id = cmp.id ". - "WHERE shared = 0". - " AND ".$this->ilDB->in("owner", $node_ids, false, "integer"). - " AND object_type = ".$this->ilDB->quote($object_type, "string"). - " AND component_type = ".$this->ilDB->quote($component_type, "string"); - } - } - - /** - * Get a query for all SharedUnboundProviders that are owned by the given nodes - * providing for a given object type. - * - * @param int[] $node_ids - * @param string $object_type - * @param string|null $component_type - * @return string - */ - protected function buildSharedUnboundProviderQueryForObjects(array $node_ids, $object_type, $component_type) { - assert('is_string($object_type)'); - assert('is_null($component_type) || is_string($component_type)'); - if ($component_type === null) { - return - "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids, GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE shared = 1". - " AND ".$this->ilDB->in("owner", $node_ids, false, "integer"). - " AND object_type = ".$this->ilDB->quote($object_type, "string"). - " GROUP BY class_name, include_path"; - } - else { - return - "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids, GROUP_CONCAT(prv.owner SEPARATOR \",\") owners, prv.class_name, prv.include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." prv ". - "JOIN ".ilProviderDB::COMPONENT_TABLE." cmp ". - "ON prv.id = cmp.id ". - "WHERE shared = 1". - " AND ".$this->ilDB->in("owner", $node_ids, false, "integer"). - " AND object_type = ".$this->ilDB->quote($object_type, "string"). - " AND component_type = ".$this->ilDB->quote($component_type, "string"). - " GROUP BY prv.class_name, prv.include_path"; - } - } - - /** - * Create the tables for the providers in the ILIAS db. - * - * @return null - */ - public function createTables() { - if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { - $this->ilDB->createTable(ilProviderDB::PROVIDER_TABLE, - [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "owner" => ["type" => "integer", "length" => 4, "notnull" => true] - , "object_type" => ["type" => "text", "length" => 4, "notnull" => true] - , "class_name" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] - , "include_path" => ["type" => "text", "length" => ilProviderDB::PATH_LENGTH, "notnull" => true] - ]); - $this->ilDB->addPrimaryKey(ilProviderDB::PROVIDER_TABLE, ["id"]); - $this->ilDB->createSequence(ilProviderDB::PROVIDER_TABLE); - } - if (!$this->ilDB->tableExists(ilProviderDB::COMPONENT_TABLE)) { - $this->ilDB->createTable(ilProviderDB::COMPONENT_TABLE, - [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "component_type" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] - ]); - $this->ilDB->addPrimaryKey(ilProviderDB::COMPONENT_TABLE, ["id", "component_type"]); - } - if (!$this->ilDB->tableColumnExists(ilProviderDB::PROVIDER_TABLE, "shared")) { - $this->ilDB->addTableColumn(ilProviderDB::PROVIDER_TABLE, "shared", ["type" => "integer", "length" => 1, "notnull" => true, "default" => 0]); - $this->ilDB->addIndex(ilProviderDB::PROVIDER_TABLE, ["shared"], "ids"); - } - } - - public function addIndizes() { - if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { - return; - } - $this->ilDB->addIndex(ilProviderDB::PROVIDER_TABLE, ["owner"], "ido", false); - } - - /** - * Create a separated unbound provider. - * - * @param int $id - * @param \ilObject $owner - * @param string $object_type - * @param string $class_name - * @param string $include_path - * @return UnboundProvider - */ - protected function buildSeparatedUnboundProvider($id, \ilObject $owner, $object_type, $class_name, $include_path) { - assert('is_int($id)'); - assert('is_string($object_type)'); - assert('is_string($class_name)'); - assert('is_string($include_path)'); - assert('file_exists($include_path)'); - - require_once($include_path); - - assert('class_exists($class_name)'); - - if (!is_subclass_of($class_name, SeparatedUnboundProvider::class)) { - throw new \UnexpectedValueException( - "Class '$class_name' does not extend UnboundProvider."); - } - - return new $class_name($id, $owner, $object_type); - } - - /** - * Create a shared unbound provider. - * - * @param array $owners with a minimum 1 entries - * @param string $object_type - * @param string $class_name - * @param string $include_path - * @return UnboundProvider - */ - protected function buildSharedUnboundProvider(array $owners, $object_type, $class_name, $include_path) { - assert('is_string($object_type)'); - assert('is_string($class_name)'); - assert('is_string($include_path)'); - assert('file_exists($include_path)'); - assert('count($owners) > 0'); - - require_once($include_path); - - assert('class_exists($class_name)'); - - if (!is_subclass_of($class_name, SharedUnboundProvider::class)) { - throw new \UnexpectedValueException( - "Class '$class_name' does not extend UnboundProvider."); - } - - return new $class_name($owners, $object_type); - } - - /** - * Build an object by its reference id. - * - * @param int $ref_id - * @throws \InvalidArgumentException if object could not be build - * @return \ilObject - */ - protected function buildObjectByRefId($ref_id) { - $obj = \ilObjectFactory::getInstanceByRefId($ref_id, false); - if ($obj === false) { - throw new \InvalidArgumentException("Cannot build object with obj_id='$ref_id'"); - } - assert($obj instanceof \ilObject); - return $obj; - } - - /** - * Build an object by its object id. - * - * @param int $obj_id - * @throws \InvalidArgumentException if object could not be build - * @return \ilObject - */ - protected function buildObjectByObjId($obj_id) { - $obj = \ilObjectFactory::getInstanceByObjId($ref_id, false); - if ($obj === false) { - throw new \InvalidArgumentException("Cannot build object with obj_id='$obj_id'"); - } - assert($obj instanceof \ilObject); - return $obj; - } - - /** - * Get all reference ids for an object id. - * - * @param int $obj_id - * @return int[] - */ - protected function getAllReferenceIdsFor($obj_id) { - return \ilObject::_getAllReferences($obj_id); - } +class ilProviderDB implements ProviderDB +{ + const PROVIDER_TABLE = "ente_prvs"; + const COMPONENT_TABLE = "ente_prv_cmps"; + + const CLASS_NAME_LENGTH = 128; + const PATH_LENGTH = 1024; + + /** + * @var \ilDBInterface + */ + private $ilDB; + + /** + * @var \ilTree + */ + private $ilTree; + + /** + * @var \ilObjectDataCache + */ + private $ilObjectDataCache; + + public function __construct(\ilDBInterface $ilDB, \ilTree $tree, \ilObjectDataCache $cache) + { + $this->ilDB = $ilDB; + $this->ilTree = $tree; + $this->ilObjectDataCache = $cache; + } + + /** + * @inheritdocs + */ + public function createSeparatedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ) : SeparatedUnboundProvider { + $this->validateCreationParams($object_type, $class_name, $include_path); + $shared = false; + list($unbound_provider, $id) = $this->createUnboundProvider( + $owner, + $object_type, + $class_name, + $include_path, + $shared + ); + $this->createComponentsForUnboundProvider($unbound_provider, $id); + return $unbound_provider; + } + + /** + * @inheritdocs + */ + public function createSharedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ) : SharedUnboundProvider { + $this->validateCreationParams($object_type, $class_name, $include_path); + $shared = true; + list($unbound_provider, $id) = $this->createUnboundProvider( + $owner, + $object_type, + $class_name, + $include_path, + $shared + ); + $this->createComponentsForUnboundProvider($unbound_provider, $id); + return $unbound_provider; + } + + /** + * @return array(UnboundProvider, int) + */ + private function createUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path, + bool $shared + ) : array { + // TODO: check if class exist first + $id = (int)$this->ilDB->nextId(ilProviderDB::PROVIDER_TABLE); + $this->ilDB->insert( + ilProviderDB::PROVIDER_TABLE, + [ + "id" => ["integer", $id], + "owner" => ["integer", $owner->getId()], + "object_type" => ["string", $object_type], + "class_name" => ["string", $class_name], + "include_path" => ["string", $include_path], + "shared" => ["integer", $shared] + ] + ); + + if($shared===true) { + $unbound_provider = $this->buildSharedUnboundProvider( + array($id=>$owner), + $class_name, + $class_name, + $include_path + ); + } else { + $unbound_provider = $this->buildSeparatedUnboundProvider( + $id, + $owner, + $class_name, + $class_name, + $include_path + ); + } + return array($unbound_provider, $id); + } + + + /** + * @throws \LogicException if any parameter is out of bounds + */ + private function validateCreationParams( + string $object_type, + string $class_name, + string $include_path + ) { + if (strlen($object_type) > 4) { + throw new \LogicException( + "Expected object type '$object_type' to have four or less chars." + ); + } + if (strlen($class_name) > ilProviderDB::CLASS_NAME_LENGTH) { + throw new \LogicException( + "Expected class name '$class_name' to have at most " + .ilProviderDB::CLASS_NAME_LENGTH." chars."); + } + if (strlen($include_path) > ilProviderDB::PATH_LENGTH) { + throw new \LogicException( + "Expected include path '$include_path' to have at most " + .ilProviderDB::PATH_LENGTH." chars."); + } + } + + /** + * @throws \LogicException if class_name of component is out of bounds + */ + private function createComponentsForUnboundProvider(UnboundProvider $unbound_provider, int $id) + { + foreach ($unbound_provider->componentTypes() as $component_type) { + if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { + throw new \LogicException( + "Expected component type '$component_type' to have at most " + .ilProviderDB::CLASS_NAME_LENGTH." chars." + ); + } + $this->ilDB->insert( + ilProviderDB::COMPONENT_TABLE, + [ + "id" => ["integer", $id], + "component_type" => ["string", $component_type] + ] + ); + } + } + + /** + * @inheritdocs + */ + public function load(int $id) : UnboundProvider + { + assert('is_int($id)'); + + $query = + "SELECT owner, object_type, class_name, include_path ". + "FROM ".ilProviderDB::PROVIDER_TABLE." ". + "WHERE id = ".$this->ilDB->quote($id, "integer"); + $res = $this->ilDB->query($query); + + if($row = $this->ilDB->fetchAssoc($res)) { + $owner = $this->buildObjectByObjId($row["owner"]); + return $this->buildSeparatedUnboundProvider( + $id, $owner, $row["object_type"], + $row["class_name"], + $row["include_path"] + ); + } + else { + throw new \InvalidArgumentException( + "Unbound provider with id '$id' does not exist." + ); + } + } + + /** + * @inheritdocs + */ + public function delete(UnboundProvider $provider, \ilObject $owner) + { + $id = $provider->idFor($owner); + $this->ilDB->manipulate( + "DELETE FROM ".ilProviderDB::PROVIDER_TABLE + ." WHERE id = ".$this->ilDB->quote($id, "integer") + ); + $this->ilDB->manipulate( + "DELETE FROM ".ilProviderDB::COMPONENT_TABLE + ." WHERE id = ".$this->ilDB->quote($id, "integer") + ); + } + + /** + * @inheritdocs + */ + public function update(UnboundProvider $provider) + { + $component_types = $provider->componentTypes(); + foreach ($provider->owners() as $owner) { + $id = $provider->idFor($owner); + $this->ilDB->manipulate( + "DELETE FROM ".ilProviderDB::COMPONENT_TABLE + ." WHERE id = ".$this->ilDB->quote($id, "integer") + ); + + foreach ($component_types as $component_type) { + if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { + throw new \LogicException( + "Expected component type '" + .$component_type."'' to have at most " + .ilProviderDB::CLASS_NAME_LENGTH." chars." + ); + } + $this->ilDB->insert( + ilProviderDB::COMPONENT_TABLE, + [ + "id" => ["integer", $id], + "component_type" => ["string", $component_type] + ] + ); + } + } + } + + /** + * @inheritdocs + */ + public function unboundProvidersOf(\ilObject $owner) : array + { + $ret = []; + + $query = + "SELECT id, object_type, class_name, include_path ". + "FROM ".ilProviderDB::PROVIDER_TABLE." ". + "WHERE owner = ".$this->ilDB->quote($owner->getId(), "integer"); + $res = $this->ilDB->query($query); + + while($row = $this->ilDB->fetchAssoc($res)) { + if( + is_subclass_of( + $row["class_name"], + 'CaT\Ente\ILIAS\SeparatedUnboundProvider' + ) + ) { + $ret[] = $this->buildSeparatedUnboundProvider( + (int)$row["id"], $owner, + $row["object_type"], + $row["class_name"], + $row["include_path"] + ); + } + if( + is_subclass_of( + $row["class_name"], + 'CaT\Ente\ILIAS\SharedUnboundProvider' + ) + ) { + $ret[] = $this->buildSharedUnboundProvider( + array($row["id"]=>$owner), + $row["object_type"], + $row["class_name"], + $row["include_path"] + ); + } + } + + return $ret; + } + + /** + * @inheritdocs + */ + public function providersFor( + \ilObject $object, + string $component_type = null + ) : array { + list($nodes_ids, $nodes_id_mapping) = $this->getSubtreeObjectIdsAndRefIdMapping( + (int)$object->getRefId() + ); + $object_type = $object->getType(); + + $ret = []; + + $provider_data = $this->getSeperatedUnboundProviderDataOf( + $nodes_ids, + $object_type, + $component_type + ); + foreach ($provider_data as $data) { + $obj_id = $data["owner"]; + $ref_id = $nodes_id_mapping[$obj_id]; + try { + $owner = $this->buildObjectByRefId($ref_id); + } + catch (\InvalidArgumentException $e) { + continue; + } + $ret[] = new Provider( + $object, + $this->buildSeparatedUnboundProvider( + $data["id"], + $owner, + $object_type, + $data["class_name"], + $data["include_path"] + ) + ); + } + + $provider_data = $this->getSharedUnboundProviderDataOf( + $nodes_ids, + $object_type, + $component_type + ); + foreach ($provider_data as $data) { + $owners = []; + foreach ($data["owners"] as $obj_id) { + $ref_id = $nodes_id_mapping[$obj_id]; + $prv_id = array_shift($data["ids"]); + try { + $owners[$prv_id] = $this->buildObjectByRefId($ref_id); + } + catch (\InvalidArgumentException $e) { + continue; + } + } + if (count($owners) > 0) { + $ret[] = new Provider( + $object, + $this->buildSharedUnboundProvider( + $owners, + $object_type, + $data["class_name"], + $data["include_path"] + ) + ); + } + } + + return $ret; + } + + /** + * Get the object ids of the subtree starting at and including $ref_id with + * a mapping from $obj_id to $ref_id. + * + * @return array [int[], array] + */ + protected function getSubtreeObjectIdsAndRefIdMapping(int $ref_id) : array + { + $sub_nodes_refs = $this->ilTree->getSubTreeIds($ref_id); + $all_nodes_refs = array_merge([$ref_id], $sub_nodes_refs); + $this->ilObjectDataCache->preloadReferenceCache($all_nodes_refs); + + $nodes_id_mapping = []; + $nodes_ids = []; + foreach ($all_nodes_refs as $ref_id) { + $id = $this->ilObjectDataCache->lookupObjId($ref_id); + $nodes_id_mapping[$id] = $ref_id; + $nodes_ids[] = $id; + } + return [$nodes_ids, $nodes_id_mapping]; + } + + protected function getSeperatedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ) : iterable { + $query = $this->buildSeparatedUnboundProviderQueryForObjects( + $node_ids, + $object_type, + $component_type + ); + $res = $this->ilDB->query($query); + while ($row = $this->ilDB->fetchAssoc($res)) { + yield [ + "id" => (int)$row["id"], + "owner" => (int)$row["owner"], + "class_name" => $row["class_name"], + "include_path" => $row["include_path"] + ]; + } + } + + protected function getSharedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ) : iterable { + $to_int_list = function ($r) { + return array_map(function($v) { return (int)$v; }, explode(",", $r)); + }; + $query = $this->buildSharedUnboundProviderQueryForObjects( + $node_ids, + $object_type, + $component_type + ); + $res = $this->ilDB->query($query); + while ($row = $this->ilDB->fetchAssoc($res)) { + yield [ + "owners" => $to_int_list($row["owners"]), + "ids" => $to_int_list($row["ids"]), + "class_name" => $row["class_name"], + "include_path" => $row["include_path"] + ]; + } + } + + protected function buildSeparatedUnboundProviderQueryForObjects( + array $node_ids, + string $object_type, + string $component_type = null + ) : string { + if ($component_type === null) { + return + "SELECT id, owner, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ".$this->ilDB->in("owner", $node_ids, false, "integer").PHP_EOL + ." AND object_type = ".$this->ilDB->quote($object_type,"string"); + } + else { + return + "SELECT prv.id, prv.owner, prv.class_name, prv.include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE." prv".PHP_EOL + ."JOIN ".ilProviderDB::COMPONENT_TABLE." cmp".PHP_EOL + ." ON prv.id = cmp.id".PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ".$this->ilDB->in("owner", $node_ids, false, "integer").PHP_EOL + ." AND object_type = ".$this->ilDB->quote($object_type, "string").PHP_EOL + ." AND component_type = ".$this->ilDB->quote($component_type, "string"); + } + } + + protected function buildSharedUnboundProviderQueryForObjects( + array $node_ids, + string $object_type, + string $component_type = null + ) : string { + if ($component_type === null) { + return + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ".$this->ilDB->in("owner", $node_ids,false,"integer").PHP_EOL + ." AND object_type = ".$this->ilDB->quote($object_type, "string").PHP_EOL + ."GROUP BY class_name, include_path"; + } + else { + return + "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(prv.owner SEPARATOR \",\") owners,".PHP_EOL + ."prv.class_name, prv.include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE." prv".PHP_EOL + ."JOIN ".ilProviderDB::COMPONENT_TABLE." cmp".PHP_EOL + ." ON prv.id = cmp.id".PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ".$this->ilDB->in("owner", $node_ids,false,"integer").PHP_EOL + ." AND object_type = ".$this->ilDB->quote($object_type, "string").PHP_EOL + ." AND component_type = ".$this->ilDB->quote($component_type, "string").PHP_EOL + ."GROUP BY prv.class_name, prv.include_path"; + } + } + + public function createTables() { + if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { + $this->ilDB->createTable( + ilProviderDB::PROVIDER_TABLE, + [ + "id" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "owner" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "object_type" => [ + "type" => "text", + "length" => 4, + "notnull" => true + ], + "class_name" => [ + "type" => "text", + "length" => ilProviderDB::CLASS_NAME_LENGTH, + "notnull" => true + ], + "include_path" => [ + "type" => "text", + "length" => ilProviderDB::PATH_LENGTH, + "notnull" => true + ] + ] + ); + $this->ilDB->addPrimaryKey(ilProviderDB::PROVIDER_TABLE, ["id"]); + $this->ilDB->createSequence(ilProviderDB::PROVIDER_TABLE); + } + if (!$this->ilDB->tableExists(ilProviderDB::COMPONENT_TABLE)) { + $this->ilDB->createTable( + ilProviderDB::COMPONENT_TABLE, + [ + "id" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "component_type" => [ + "type" => "text", + "length" => ilProviderDB::CLASS_NAME_LENGTH, + "notnull" => true + ] + ] + ); + $this->ilDB->addPrimaryKey( + ilProviderDB::COMPONENT_TABLE, + ["id", "component_type"] + ); + } + if (!$this->ilDB->tableColumnExists( + ilProviderDB::PROVIDER_TABLE, + "shared") + ) { + $this->ilDB->addTableColumn( + ilProviderDB::PROVIDER_TABLE, + "shared", + [ + "type" => "integer", + "length" => 1, + "notnull" => true, + "default" => 0 + ] + ); + $this->ilDB->addIndex( + ilProviderDB::PROVIDER_TABLE, + ["shared"], + "ids" + ); + } + } + + public function addIndizes() { + if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { + return; + } + $this->ilDB->addIndex( + ilProviderDB::PROVIDER_TABLE, + ["owner"], + "ido", + false + ); + } + + protected function buildSeparatedUnboundProvider( + int $id, + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ) : UnboundProvider { + require_once($include_path); + + assert('class_exists($class_name)'); + if (!is_subclass_of($class_name, SeparatedUnboundProvider::class)) { + throw new \UnexpectedValueException( + "Class '$class_name' does not extend UnboundProvider." + ); + } + + return new $class_name($id, $owner, $object_type); + } + + protected function buildSharedUnboundProvider( + array $owners, + string $object_type, + string $class_name, + string $include_path + ) : UnboundProvider { + assert('count($owners) > 0'); + + require_once($include_path); + + assert('class_exists($class_name)'); + if (!is_subclass_of($class_name, SharedUnboundProvider::class)) { + throw new \UnexpectedValueException( + "Class '$class_name' does not extend UnboundProvider." + ); + } + + return new $class_name($owners, $object_type); + } + + /** + * Build an object by its reference id. + * + * @throws \InvalidArgumentException if object could not be build + */ + protected function buildObjectByRefId(int $ref_id) : \ilObject + { + $obj = \ilObjectFactory::getInstanceByRefId($ref_id, false); + if ($obj === false) { + throw new \InvalidArgumentException("Cannot build object with obj_id='$ref_id'"); + } + assert($obj instanceof \ilObject); + return $obj; + } + + /** + * Build an object by its object id. + * + * @throws \InvalidArgumentException if object could not be build + */ + protected function buildObjectByObjId(int $obj_id) : \ilObject + { + $obj = \ilObjectFactory::getInstanceByObjId($obj_id, false); + if ($obj === false) { + throw new \InvalidArgumentException("Cannot build object with obj_id='$obj_id'"); + } + assert($obj instanceof \ilObject); + return $obj; + } + + protected function getAllReferenceIdsFor(int $obj_id) : array + { + return \ilObject::_getAllReferences($obj_id); + } } diff --git a/src/ILIAS/ilProviderObjectHelper.php b/src/ILIAS/ilProviderObjectHelper.php index 507a5f1..12e48cf 100644 --- a/src/ILIAS/ilProviderObjectHelper.php +++ b/src/ILIAS/ilProviderObjectHelper.php @@ -8,14 +8,15 @@ * the license along with the code. */ -namespace CaT\Ente\ILIAS; +declare(strict_types=1); -use CaT\Ente; +namespace CaT\Ente\ILIAS; /** * Helper for repository objects that want to provide components. */ -trait ilProviderObjectHelper { +trait ilProviderObjectHelper +{ use ilObjectHelper; /** @@ -41,7 +42,7 @@ protected function deleteUnboundProviders() { * @param string $object_type for which the object provides * @param string $class_name of the unbound provider * @param string $path of the include file for the unbound provider class - * @return void + * @return void */ protected function createUnboundProvider($object_type, $class_name, $path) { if (!($this instanceof \ilObject)) { diff --git a/tests/ILIAS/SeparatedUnboundProviderTest.php b/tests/ILIAS/SeparatedUnboundProviderTest.php index d50ac2e..42566e9 100644 --- a/tests/ILIAS/SeparatedUnboundProviderTest.php +++ b/tests/ILIAS/SeparatedUnboundProviderTest.php @@ -8,15 +8,14 @@ * the license along with the code. */ -use CaT\Ente\ILIAS\Entity; -use CaT\Ente\ILIAS\Provider; use CaT\Ente\ILIAS\SeparatedUnboundProvider; -use CaT\Ente\Simple; use CaT\Ente\Simple\AttachString; use CaT\Ente\Simple\AttachStringMemory; use CaT\Ente\Simple\AttachInt; use CaT\Ente\Simple\AttachIntMemory; +use CaT\Ente\Entity AS IEntity; + if (!class_exists("ilObject")) { require_once(__DIR__."/ilObject.php"); } @@ -26,11 +25,10 @@ public function componentTypes() { return [AttachString::class, AttachInt::class]; } - public function buildComponentsOf($component_type, Entity $entity) { - assert(is_string($component_type)); + public function buildComponentsOf(string $component_type, IEntity $entity) : array + { $this->callsTo_buildComponentsOf[] = $component_type; $object = $entity->object(); - $entity = $entity; if ($component_type == AttachString::class) { return [new AttachStringMemory($entity, "id: {$object->getId()}")]; } diff --git a/tests/ILIAS/SharedUnboundProviderTest.php b/tests/ILIAS/SharedUnboundProviderTest.php index 4ae20d5..2061681 100644 --- a/tests/ILIAS/SharedUnboundProviderTest.php +++ b/tests/ILIAS/SharedUnboundProviderTest.php @@ -9,14 +9,14 @@ */ use CaT\Ente\ILIAS\Entity; -use CaT\Ente\ILIAS\Provider; use CaT\Ente\ILIAS\SharedUnboundProvider; -use CaT\Ente\Simple; use CaT\Ente\Simple\AttachString; use CaT\Ente\Simple\AttachStringMemory; use CaT\Ente\Simple\AttachInt; use CaT\Ente\Simple\AttachIntMemory; +use CaT\Ente\Entity AS IEntity; + if (!class_exists("ilObject")) { require_once(__DIR__."/ilObject.php"); } @@ -26,7 +26,7 @@ public function componentTypes() { return [AttachString::class, AttachInt::class]; } - public function buildComponentsOf($component_type, Entity $entity) { + public function buildComponentsOf(string $component_type, IEntity $entity) : array { assert(is_string($component_type)); $this->callsTo_buildComponentsOf[] = $component_type; $object = $entity->object(); diff --git a/tests/ILIAS/ilCachesOwnerRangeProviderTest.php b/tests/ILIAS/ilCachesOwnerRangeProviderTest.php index 5003222..d15a4cc 100644 --- a/tests/ILIAS/ilCachesOwnerRangeProviderTest.php +++ b/tests/ILIAS/ilCachesOwnerRangeProviderTest.php @@ -33,10 +33,12 @@ require_once(__DIR__."/ilObjectDataCache.php"); } -class Test_ilCachesOwnerRangeProviderDB extends ilCachesOwnerRangeProviderDB { +class Test_ilCachesOwnerRangeProviderDB extends ilCachesOwnerRangeProviderDB +{ public $object_ref = []; public $throws = false; - protected function buildObjectByRefId($ref_id) { + protected function buildObjectByRefId(int $ref_id) : \ilObject + { if ($this->throws) { throw new \InvalidArgumentException(); } @@ -44,7 +46,8 @@ protected function buildObjectByRefId($ref_id) { return $this->object_ref[$ref_id]; } public $object_obj = []; - protected function buildObjectByObjId($obj_id) { + protected function buildObjectByObjId(int $obj_id) : \ilObject + { if ($this->throws) { throw new \InvalidArgumentException(); } @@ -52,13 +55,15 @@ protected function buildObjectByObjId($obj_id) { return $this->object_obj[$obj_id]; } public $reference_ids = []; - protected function getAllReferenceIdsFor($obj_id) { + protected function getAllReferenceIdsFor(int $obj_id) : array + { assert(isset($this->reference_ids[$obj_id])); return $this->reference_ids[$obj_id]; } } -class ILIAS_ilCachesOwnerRangeProviderDBTest extends PHPUnit_Framework_TestCase { +class ILIAS_ilCachesOwnerRangeProviderDBTest extends PHPUnit_Framework_TestCase +{ protected function il_db_mock() { return $this->createMock(\ilDBInterface::class); } @@ -101,7 +106,7 @@ public function test_providersFor_no_cache() { $sub_tree_id1 = 3; $sub_tree_id2 = 14; - $sub_tree_ids = ["$sub_tree_id1", "$sub_tree_id2"]; + $sub_tree_ids = [$sub_tree_id1, $sub_tree_id2]; $il_tree ->expects($this->once()) ->method("getSubTreeIds") @@ -163,6 +168,7 @@ public function test_providersFor_no_cache() { ] ] ]], + "i am" => "here" ] ); @@ -217,7 +223,8 @@ public function test_providersFor_no_cache() { $this->assertEquals([$owner_2], $provider2->owners()); } - public function test_providersFor_with_cache() { + public function test_providersFor_with_cache() + { $il_db = $this->il_db_mock(); $il_tree = $this->il_tree_mock(); $il_cache = $this->il_object_data_cache_mock(); @@ -241,7 +248,7 @@ public function test_providersFor_with_cache() { $sub_tree_id1 = 3; $sub_tree_id2 = 14; - $sub_tree_ids = ["$sub_tree_id1", "$sub_tree_id2"]; + $sub_tree_ids = [$sub_tree_id1, $sub_tree_id2]; $il_tree ->expects($this->once()) ->method("getSubTreeIds") @@ -272,10 +279,15 @@ public function test_providersFor_with_cache() { ->with("0") ->willReturn( [ - $object_ref_id => [ $object_type => [ "separated" => [], "shared" => []]], - $sub_tree_id1 => [ $object_type => [ - "separated" => - [ + $object_ref_id => [ + $object_type => [ + "separated" => [], + "shared" => [] + ] + ], + $sub_tree_id1 => [ + $object_type => [ + "separated" => [ [ "id" => 1, "owner" => $sub_tree_id1, @@ -283,11 +295,12 @@ public function test_providersFor_with_cache() { "include_path" => $include_path ] ], - "shared" => [] - ]], - $sub_tree_id2 => [ $object_type => [ - "separated" => - [ + "shared" => [] + ] + ], + $sub_tree_id2 => [ + $object_type => [ + "separated" => [ [ "id" => 2, "owner" => $sub_tree_id2, @@ -295,8 +308,9 @@ public function test_providersFor_with_cache() { "include_path" => $include_path ] ], - "shared" => [] - ]], + "shared" => [] + ] + ], ] ); diff --git a/tests/ILIAS/ilHandlerObjectHelperTest.php b/tests/ILIAS/ilHandlerObjectHelperTest.php index f41afb7..d545dcb 100644 --- a/tests/ILIAS/ilHandlerObjectHelperTest.php +++ b/tests/ILIAS/ilHandlerObjectHelperTest.php @@ -66,7 +66,7 @@ public function test_getComponents() { ->method("getEntity") ->willReturn($entity); - $array = new \StdClass(); + $array = [new \StdClass()]; $repository ->expects($this->once()) @@ -99,7 +99,7 @@ public function test_getComponentsOfType() { ->method("getEntity") ->willReturn($entity); - $array = new \StdClass(); + $array = [new \StdClass()]; $type = "TYPE"; $repository diff --git a/tests/ILIAS/ilProviderDBTest.php b/tests/ILIAS/ilProviderDBTest.php index e427499..58b5d82 100644 --- a/tests/ILIAS/ilProviderDBTest.php +++ b/tests/ILIAS/ilProviderDBTest.php @@ -1,883 +1,944 @@ - - * - * This software is licensed under GPLv3. You should have received a copy of - * the license along with the code. - */ - -use CaT\Ente\ILIAS\SeparatedUnboundProvider; -use CaT\Ente\ILIAS\UnboundProvider; -use CaT\Ente\Provider; -use CaT\Ente\ILIAS\ilProviderDB; -use CaT\Ente\Simple\AttachString; -use CaT\Ente\Simple\AttachInt; - -if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); -} - -if (!interface_exists("ilDBInterface")) { - require_once(__DIR__."/ilDBInterface.php"); -} - -if (!interface_exists("ilTree")) { - require_once(__DIR__."/ilTree.php"); -} - -if (!interface_exists("ilObjectDataCache")) { - require_once(__DIR__."/ilObjectDataCache.php"); -} - -class Test_ilProviderDB extends ilProviderDB { - public $object_ref = []; + + * + * This software is licensed under GPLv3. You should have received a copy of + * the license along with the code. + */ + + use CaT\Ente\ILIAS\SeparatedUnboundProvider; + use CaT\Ente\ILIAS\UnboundProvider; + use CaT\Ente\Provider; + use CaT\Ente\ILIAS\ilProviderDB; + use CaT\Ente\Simple\AttachString; + use CaT\Ente\Simple\AttachInt; + + if (!class_exists("ilObject")) { + require_once(__DIR__."/ilObject.php"); + } + + if (!interface_exists("ilDBInterface")) { + require_once(__DIR__."/ilDBInterface.php"); + } + + if (!interface_exists("ilTree")) { + require_once(__DIR__."/ilTree.php"); + } + + if (!interface_exists("ilObjectDataCache")) { + require_once(__DIR__."/ilObjectDataCache.php"); + } + + class Test_ilProviderDB extends ilProviderDB { + public $object_ref = []; public $throws = false; - protected function buildObjectByRefId($ref_id) { + protected function buildObjectByRefId(int $ref_id) : \ilObject + { if ($this->throws) { throw new \InvalidArgumentException(); } - assert(isset($this->object_ref[$ref_id])); - return $this->object_ref[$ref_id]; - } - public $object_obj = []; - protected function buildObjectByObjId($obj_id) { + assert(isset($this->object_ref[$ref_id])); + return $this->object_ref[$ref_id]; + } + public $object_obj = []; + protected function buildObjectByObjId(int $obj_id) : \ilObject + { if ($this->throws) { throw new \InvalidArgumentException(); } - assert(isset($this->object_obj[$obj_id])); - return $this->object_obj[$obj_id]; - } - public $reference_ids = []; - protected function getAllReferenceIdsFor($obj_id) { - assert(isset($this->reference_ids[$obj_id])); - return $this->reference_ids[$obj_id]; - } -} - -class ILIAS_ilProviderDBTest extends PHPUnit_Framework_TestCase { - protected function il_db_mock() { - return $this->createMock(\ilDBInterface::class); - } - - public function il_tree_mock() { - return $this - ->getMockBuilder(\ilTree::class) - ->setMethods(["getSubTreeIds", "getNodePath"]) - ->getMock(); - } - - public function il_object_data_cache_mock() { - return $this - ->getMockBuilder(\ilObjectDataCache::class) - ->setMethods(["preloadReferenceCache", "lookupObjId"]) - ->getMock(); - } - - public function test_createTables() { - $il_db = $this->il_db_mock(); - - $provider_table = - [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "owner" => ["type" => "integer", "length" => 4, "notnull" => true] - , "object_type" => ["type" => "text", "length" => 4, "notnull" => true] - , "class_name" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] - , "include_path" => ["type" => "text", "length" => ilProviderDB::PATH_LENGTH, "notnull" => true] - ]; - $component_table = - [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "component_type" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] - ]; - - $il_db - ->expects($this->exactly(2)) - ->method("createTable") - ->withConsecutive( - [ilProviderDB::PROVIDER_TABLE, $provider_table], - [ilProviderDB::COMPONENT_TABLE, $component_table]); - - $il_db - ->expects($this->exactly(2)) - ->method("tableExists") - ->withConsecutive([ilProviderDB::PROVIDER_TABLE], [ilProviderDB::COMPONENT_TABLE]) - ->will($this->onConsecutiveCalls(false, false)); - - $il_db - ->expects($this->exactly(2)) - ->method("addPrimaryKey") - ->withConsecutive( - [ilProviderDB::PROVIDER_TABLE, ["id"]], - [ilProviderDB::COMPONENT_TABLE, ["id", "component_type"]]); - - $il_db - ->expects($this->once()) - ->method("createSequence") - ->with(ilProviderDB::PROVIDER_TABLE); - - $il_db - ->expects($this->once()) - ->method("tableColumnExists") - ->with(ilProviderDB::PROVIDER_TABLE, "shared") - ->willReturn(false); - - $il_db - ->expects($this->once()) - ->method("addTableColumn") - ->with(ilProviderDB::PROVIDER_TABLE, "shared", ["type" => "integer", "length" => 1, "notnull" => true, "default" => 0]); - - $il_db - ->expects($this->once()) - ->method("addIndex") - ->with(ilProviderDB::PROVIDER_TABLE, ["shared"], "ids"); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $db->createTables(); - } - - public function test_create() { - $il_db = $this->il_db_mock(); - - $owner = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - $owner_id = 42; - $owner - ->method("getId") - ->willReturn($owner_id); - - $new_provider_id = 23; - $object_type = "crs"; - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $insert_provider = - [ "id" => ["integer", $new_provider_id] - , "owner" => ["integer", $owner_id] - , "object_type" => ["string", $object_type] - , "class_name" => ["string", $class_name] - , "include_path" => ["string", $include_path] + assert(isset($this->object_obj[$obj_id])); + return $this->object_obj[$obj_id]; + } + public $reference_ids = []; + protected function getAllReferenceIdsFor(int $obj_id) :array + { + assert(isset($this->reference_ids[$obj_id])); + return $this->reference_ids[$obj_id]; + } + } + + class ILIAS_ilProviderDBTest extends PHPUnit_Framework_TestCase { + protected function il_db_mock() { + return $this->createMock(\ilDBInterface::class); + } + + public function il_tree_mock() { + return $this + ->getMockBuilder(\ilTree::class) + ->setMethods(["getSubTreeIds", "getNodePath"]) + ->getMock(); + } + + public function il_object_data_cache_mock() { + return $this + ->getMockBuilder(\ilObjectDataCache::class) + ->setMethods(["preloadReferenceCache", "lookupObjId"]) + ->getMock(); + } + + public function test_createTables() { + $il_db = $this->il_db_mock(); + + $provider_table = + [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] + , "owner" => ["type" => "integer", "length" => 4, "notnull" => true] + , "object_type" => ["type" => "text", "length" => 4, "notnull" => true] + , "class_name" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] + , "include_path" => ["type" => "text", "length" => ilProviderDB::PATH_LENGTH, "notnull" => true] + ]; + $component_table = + [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] + , "component_type" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] + ]; + + $il_db + ->expects($this->exactly(2)) + ->method("createTable") + ->withConsecutive( + [ilProviderDB::PROVIDER_TABLE, $provider_table], + [ilProviderDB::COMPONENT_TABLE, $component_table]); + + $il_db + ->expects($this->exactly(2)) + ->method("tableExists") + ->withConsecutive([ilProviderDB::PROVIDER_TABLE], [ilProviderDB::COMPONENT_TABLE]) + ->will($this->onConsecutiveCalls(false, false)); + + $il_db + ->expects($this->exactly(2)) + ->method("addPrimaryKey") + ->withConsecutive( + [ilProviderDB::PROVIDER_TABLE, ["id"]], + [ilProviderDB::COMPONENT_TABLE, ["id", "component_type"]]); + + $il_db + ->expects($this->once()) + ->method("createSequence") + ->with(ilProviderDB::PROVIDER_TABLE); + + $il_db + ->expects($this->once()) + ->method("tableColumnExists") + ->with(ilProviderDB::PROVIDER_TABLE, "shared") + ->willReturn(false); + + $il_db + ->expects($this->once()) + ->method("addTableColumn") + ->with(ilProviderDB::PROVIDER_TABLE, "shared", ["type" => "integer", "length" => 1, "notnull" => true, "default" => 0]); + + $il_db + ->expects($this->once()) + ->method("addIndex") + ->with(ilProviderDB::PROVIDER_TABLE, ["shared"], "ids"); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $db->createTables(); + } + + public function test_create() { + $il_db = $this->il_db_mock(); + + $owner = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + $owner_id = 42; + $owner + ->method("getId") + ->willReturn($owner_id); + + $new_provider_id = 23; + $object_type = "crs"; + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + + $insert_provider = + [ "id" => ["integer", $new_provider_id] + , "owner" => ["integer", $owner_id] + , "object_type" => ["string", $object_type] + , "class_name" => ["string", $class_name] + , "include_path" => ["string", $include_path] , "shared" => ["integer", 0] - ]; - - $insert_component_1 = - [ "id" => ["integer", $new_provider_id] - , "component_type" => ["string", AttachString::class] - ]; - - $insert_component_2 = - [ "id" => ["integer", $new_provider_id] - , "component_type" => ["string", AttachInt::class] - ]; - - $il_db - ->expects($this->exactly(3)) - ->method("insert") - ->withConsecutive( - [ilProviderDB::PROVIDER_TABLE, $insert_provider], - [ilProviderDB::COMPONENT_TABLE, $insert_component_1], - [ilProviderDB::COMPONENT_TABLE, $insert_component_2]); - - $il_db - ->expects($this->once()) - ->method("nextId") - ->with(ilProviderDB::PROVIDER_TABLE) - ->willReturn($new_provider_id); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $unbound_provider = $db->createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); - - $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $unbound_provider); - } - - public function test_delete() { - $il_db = $this->il_db_mock(); - - $owner = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - - $unbound_provider = $this->createMock(UnboundProvider::class); - - $unbound_provider_id = 23; - $unbound_provider - ->expects($this->once()) - ->method("idFor") - ->with($owner) - ->willReturn($unbound_provider_id); - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->with($unbound_provider_id, "integer") - ->willReturn("~$unbound_provider_id~"); - - $il_db - ->expects($this->exactly(2)) - ->method("manipulate") - ->withConsecutive( - ["DELETE FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ~$unbound_provider_id~"], - ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~$unbound_provider_id~"]); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $db->delete($unbound_provider, $owner); - } - - public function test_update() { - $il_db = $this->il_db_mock(); - - $owner1 = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - $owner2 = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - $unbound_provider = $this->createMock(UnboundProvider::class); - - $unbound_provider - ->expects($this->once()) - ->method("owners") - ->willReturn([$owner1, $owner2]); - - $unbound_provider - ->expects($this->exactly(2)) - ->method("idFor") - ->withConsecutive([$owner1],[$owner2]) - ->will($this->onConsecutiveCalls(1,2)); - - $unbound_provider - ->expects($this->once()) - ->method("componentTypes") - ->willReturn([AttachString::class, AttachInt::class]); - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->withConsecutive([1, "integer"],[2, "integer"]) - ->will($this->returnCallback(function($int) { return "~$int~"; })); - - $il_db - ->expects($this->exactly(2)) - ->method("manipulate") - ->withConsecutive( - ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~1~"], - ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~2~"]); - - $insert_component_1 = - [ "id" => ["integer", 1] - , "component_type" => ["string", AttachString::class] - ]; - - $insert_component_2 = - [ "id" => ["integer", 1] - , "component_type" => ["string", AttachInt::class] - ]; - - $insert_component_3 = - [ "id" => ["integer", 2] - , "component_type" => ["string", AttachString::class] - ]; - - $insert_component_4 = - [ "id" => ["integer", 2] - , "component_type" => ["string", AttachInt::class] - ]; - - $il_db - ->expects($this->exactly(4)) - ->method("insert") - ->withConsecutive( - [ilProviderDB::COMPONENT_TABLE, $insert_component_1], - [ilProviderDB::COMPONENT_TABLE, $insert_component_2], - [ilProviderDB::COMPONENT_TABLE, $insert_component_3], - [ilProviderDB::COMPONENT_TABLE, $insert_component_4]); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $db->update($unbound_provider); - } - - public function test_unboundProvidersOf() { - $il_db = $this->il_db_mock(); - - $owner = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - $owner_id = 42; - $owner - ->expects($this->atLeastOnce()) - ->method("getId") - ->willReturn(42); - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->with($owner_id, "integer") - ->willReturn("~$owner_id~"); - - $result = "RESULT"; - $il_db - ->expects($this->once()) - ->method("query") - ->with("SELECT id, object_type, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE owner = ~$owner_id~") - ->willReturn($result); - - $object_type = "type"; - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(3)) - ->method("fetchAssoc") - ->with("RESULT") - ->will($this->onConsecutiveCalls( - ["id" => 1, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], - ["id" => 2, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], - null)); - - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $providers = $db->unboundProvidersOf($owner); - - $this->assertCount(2, $providers); - - foreach ($providers as $provider) { - $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); - $this->assertEquals($object_type, $provider->objectType()); - $this->assertEquals([$owner], $provider->owners()); - } - - list($provider1, $provider2) = $providers; - $this->assertEquals(1, $provider1->idFor($owner)); - $this->assertEquals(2, $provider2->idFor($owner)); - } - - public function test_load() { - $il_db = $this->il_db_mock(); - - $provider_id = 23; - $owner_id = 42; - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->with($provider_id, "integer") - ->willReturn("~$provider_id~"); - $result = "RESULT"; - $il_db - ->expects($this->once()) - ->method("query") - ->with("SELECT owner, object_type, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ~$provider_id~") - ->willReturn($result); - - $object_type = "type"; - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->once()) - ->method("fetchAssoc") - ->with("RESULT") - ->willReturn( - ["owner" => $owner_id, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path] - ); - - $db = new Test_ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock(), []); - $owner = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $db->object_obj[$owner_id] = $owner; - $provider = $db->load($provider_id); - - $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); - $this->assertEquals($object_type, $provider->objectType()); - $this->assertEquals([$owner], $provider->owners()); - $this->assertEquals($provider_id, $provider->idFor($owner)); - } - - public function test_providersFor() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = ["3", "14"]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); + ]; + + $insert_component_1 = + [ "id" => ["integer", $new_provider_id] + , "component_type" => ["string", AttachString::class] + ]; + + $insert_component_2 = + [ "id" => ["integer", $new_provider_id] + , "component_type" => ["string", AttachInt::class] + ]; + + $il_db + ->expects($this->exactly(3)) + ->method("insert") + ->withConsecutive( + [ilProviderDB::PROVIDER_TABLE, $insert_provider], + [ilProviderDB::COMPONENT_TABLE, $insert_component_1], + [ilProviderDB::COMPONENT_TABLE, $insert_component_2]); + + $il_db + ->expects($this->once()) + ->method("nextId") + ->with(ilProviderDB::PROVIDER_TABLE) + ->willReturn($new_provider_id); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $unbound_provider = $db->createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); + + $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $unbound_provider); + } + + public function test_delete() { + $il_db = $this->il_db_mock(); + + $owner = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + + $unbound_provider = $this->createMock(UnboundProvider::class); + + $unbound_provider_id = 23; + $unbound_provider + ->expects($this->once()) + ->method("idFor") + ->with($owner) + ->willReturn($unbound_provider_id); + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->with($unbound_provider_id, "integer") + ->willReturn("~$unbound_provider_id~"); + + $il_db + ->expects($this->exactly(2)) + ->method("manipulate") + ->withConsecutive( + ["DELETE FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ~$unbound_provider_id~"], + ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~$unbound_provider_id~"]); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $db->delete($unbound_provider, $owner); + } + + public function test_update() { + $il_db = $this->il_db_mock(); + + $owner1 = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + $owner2 = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + $unbound_provider = $this->createMock(UnboundProvider::class); + + $unbound_provider + ->expects($this->once()) + ->method("owners") + ->willReturn([$owner1, $owner2]); + + $unbound_provider + ->expects($this->exactly(2)) + ->method("idFor") + ->withConsecutive([$owner1],[$owner2]) + ->will($this->onConsecutiveCalls(1,2)); + + $unbound_provider + ->expects($this->once()) + ->method("componentTypes") + ->willReturn([AttachString::class, AttachInt::class]); + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->withConsecutive([1, "integer"],[2, "integer"]) + ->will($this->returnCallback(function($int) { return "~$int~"; })); + + $il_db + ->expects($this->exactly(2)) + ->method("manipulate") + ->withConsecutive( + ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~1~"], + ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~2~"]); + + $insert_component_1 = + [ "id" => ["integer", 1] + , "component_type" => ["string", AttachString::class] + ]; + + $insert_component_2 = + [ "id" => ["integer", 1] + , "component_type" => ["string", AttachInt::class] + ]; + + $insert_component_3 = + [ "id" => ["integer", 2] + , "component_type" => ["string", AttachString::class] + ]; + + $insert_component_4 = + [ "id" => ["integer", 2] + , "component_type" => ["string", AttachInt::class] + ]; + + $il_db + ->expects($this->exactly(4)) + ->method("insert") + ->withConsecutive( + [ilProviderDB::COMPONENT_TABLE, $insert_component_1], + [ilProviderDB::COMPONENT_TABLE, $insert_component_2], + [ilProviderDB::COMPONENT_TABLE, $insert_component_3], + [ilProviderDB::COMPONENT_TABLE, $insert_component_4]); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $db->update($unbound_provider); + } + + public function test_unboundProvidersOf() { + $il_db = $this->il_db_mock(); + + $owner = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + $owner_id = 42; + $owner + ->expects($this->atLeastOnce()) + ->method("getId") + ->willReturn(42); + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->with($owner_id, "integer") + ->willReturn("~$owner_id~"); + + $result = "RESULT"; + $il_db + ->expects($this->once()) + ->method("query") + ->with("SELECT id, object_type, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE owner = ~$owner_id~") + ->willReturn($result); + + $object_type = "type"; + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(3)) + ->method("fetchAssoc") + ->with("RESULT") + ->will($this->onConsecutiveCalls( + ["id" => 1, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], + ["id" => 2, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], + null)); + + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $providers = $db->unboundProvidersOf($owner); + + $this->assertCount(2, $providers); + + foreach ($providers as $provider) { + $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); + $this->assertEquals($object_type, $provider->objectType()); + $this->assertEquals([$owner], $provider->owners()); + } + + list($provider1, $provider2) = $providers; + $this->assertEquals(1, $provider1->idFor($owner)); + $this->assertEquals(2, $provider2->idFor($owner)); + } + + public function test_load() { + $il_db = $this->il_db_mock(); + + $provider_id = 23; + $owner_id = 42; + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->with($provider_id, "integer") + ->willReturn("~$provider_id~"); + $result = "RESULT"; + $il_db + ->expects($this->once()) + ->method("query") + ->with("SELECT owner, object_type, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ~$provider_id~") + ->willReturn($result); + + $object_type = "type"; + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->once()) + ->method("fetchAssoc") + ->with("RESULT") + ->willReturn( + ["owner" => $owner_id, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path] + ); + + $db = new Test_ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock(), []); + $owner = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $db->object_obj[$owner_id] = $owner; + $provider = $db->load($provider_id); + + $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); + $this->assertEquals($object_type, $provider->objectType()); + $this->assertEquals([$owner], $provider->owners()); + $this->assertEquals($provider_id, $provider->idFor($owner)); + } + + public function test_providersFor() { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive - ( ["SELECT id, owner, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 0 AND ~IN~ AND object_type = ~TYPE~"] - - , ["SELECT GROUP_CONCAT(id SEPARATOR \",\") ids, GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 1 AND ~IN~ AND object_type = ~TYPE~ GROUP BY class_name, include_path"] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(4)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result1],[$result1],[$result2]) - ->will($this->onConsecutiveCalls( - ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], - ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null, - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - - $owner_1 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $db->object_ref[$sub_tree_ids[0]] = $owner_1; - - $owner_2 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $db->object_ref[$sub_tree_ids[1]] = $owner_2; - - $providers = $db->providersFor($object); - $this->assertCount(2, $providers); - - foreach ($providers as $provider) { - $this->assertInstanceOf(Provider::class, $provider); - $this->assertEquals($object, $provider->object()); - $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); - } - - list($provider1, $provider2) = $providers; - $this->assertEquals(1, $provider1->unboundProvider()->idFor($owner_1)); - $this->assertEquals([$owner_1], $provider1->owners()); - - $this->assertEquals(2, $provider2->unboundProvider()->idFor($owner_2)); - $this->assertEquals([$owner_2], $provider2->owners()); - - } - - public function test_providersFor_filtered() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = ["3", "14"]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path".PHP_EOL + ."FROM ente_prvs".PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~".PHP_EOL + ."GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(4)) + ->method("fetchAssoc") + ->withConsecutive([$result1],[$result1],[$result1],[$result2]) + ->will($this->onConsecutiveCalls( + ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], + ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null, + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + + $owner_1 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $db->object_ref[$sub_tree_ids[0]] = $owner_1; + + $owner_2 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $db->object_ref[$sub_tree_ids[1]] = $owner_2; + + $providers = $db->providersFor($object); + $this->assertCount(2, $providers); + + foreach ($providers as $provider) { + $this->assertInstanceOf(Provider::class, $provider); + $this->assertEquals($object, $provider->object()); + $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); + } + + list($provider1, $provider2) = $providers; + $this->assertEquals(1, $provider1->unboundProvider()->idFor($owner_1)); + $this->assertEquals([$owner_1], $provider1->owners()); + + $this->assertEquals(2, $provider2->unboundProvider()->idFor($owner_2)); + $this->assertEquals([$owner_2], $provider2->owners()); + + } + + public function test_providersFor_filtered() { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $component_type = "COMPONENT_TYPE"; - $il_db - ->expects($this->exactly(4)) - ->method("quote") - ->withConsecutive([$object_type], [$component_type], [$object_type], [$component_type]) - ->will($this->onConsecutiveCalls("~TYPE~", "~COMPONENT_TYPE~", "~TYPE~", "~COMPONENT_TYPE~")); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive( - ["SELECT prv.id, prv.owner, prv.class_name, prv.include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." prv ". - "JOIN ".ilProviderDB::COMPONENT_TABLE." cmp ". - "ON prv.id = cmp.id ". - "WHERE shared = 0 ". - "AND ~IN~ ". - "AND object_type = ~TYPE~ ". - "AND component_type = ~COMPONENT_TYPE~"], - ["SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids, GROUP_CONCAT(prv.owner SEPARATOR \",\") owners, prv.class_name, prv.include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." prv ". - "JOIN ".ilProviderDB::COMPONENT_TABLE." cmp ". - "ON prv.id = cmp.id ". - "WHERE shared = 1 ". - "AND ~IN~ ". - "AND object_type = ~TYPE~ ". - "AND component_type = ~COMPONENT_TYPE~ ". - "GROUP BY prv.class_name, prv.include_path"] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $il_db - ->expects($this->exactly(2)) - ->method("fetchAssoc") - ->withConsecutive([$result1], [$result2]) - ->willReturn(null); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - - $providers = $db->providersFor($object, "COMPONENT_TYPE"); - $this->assertCount(0, $providers); - } - - public function test_providersFor_shared() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = ["3", "14"]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $component_type = "COMPONENT_TYPE"; + $il_db + ->expects($this->exactly(4)) + ->method("quote") + ->withConsecutive([$object_type], [$component_type], [$object_type], [$component_type]) + ->will($this->onConsecutiveCalls("~TYPE~", "~COMPONENT_TYPE~", "~TYPE~", "~COMPONENT_TYPE~")); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT prv.id, prv.owner, prv.class_name, prv.include_path".PHP_EOL + ."FROM ente_prvs prv".PHP_EOL + ."JOIN ente_prv_cmps cmp".PHP_EOL + ." ON prv.id = cmp.id".PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~".PHP_EOL + ." AND component_type = ~COMPONENT_TYPE~" + ], + [ + "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(prv.owner SEPARATOR \",\") owners,".PHP_EOL + ."prv.class_name, prv.include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE." prv".PHP_EOL + ."JOIN ".ilProviderDB::COMPONENT_TABLE." cmp".PHP_EOL + ." ON prv.id = cmp.id".PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~".PHP_EOL + ." AND component_type = ~COMPONENT_TYPE~".PHP_EOL + ."GROUP BY prv.class_name, prv.include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $il_db + ->expects($this->exactly(2)) + ->method("fetchAssoc") + ->withConsecutive([$result1], [$result2]) + ->willReturn(null); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + + $providers = $db->providersFor($object, "COMPONENT_TYPE"); + $this->assertCount(0, $providers); + } + + public function test_providersFor_shared() { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive - ( ["SELECT id, owner, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 0 AND ~IN~ AND object_type = ~TYPE~"] - - , ["SELECT GROUP_CONCAT(id SEPARATOR \",\") ids, GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 1 AND ~IN~ AND object_type = ~TYPE~ GROUP BY class_name, include_path"] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = "Test_SharedUnboundProvider"; - $include_path = __DIR__."/SharedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(3)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result2],[$result2]) - ->will($this->onConsecutiveCalls( - null, - ["ids" => "1,2", "owners" => $sub_tree_ids[0].",".$sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - - $owner_1 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $owner_1 - ->method("getId") - ->willReturn("23"); - $db->object_ref[$sub_tree_ids[0]] = $owner_1; - - $owner_2 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $owner_2 - ->method("getId") - ->willReturn("24"); - $db->object_ref[$sub_tree_ids[1]] = $owner_2; - - $providers = $db->providersFor($object); - $this->assertCount(1, $providers); - $provider = array_shift($providers); - - $this->assertInstanceOf(Provider::class, $provider); - $this->assertEquals($object, $provider->object()); - $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); - $this->assertEquals([$owner_1, $owner_2], $provider->unboundProvider()->owners()); - - $this->assertEquals(1, $provider->unboundProvider()->idFor($owner_1)); - $this->assertEquals(2, $provider->unboundProvider()->idFor($owner_2)); - } - - public function test_providersFor_for_unbuildable_object() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = ["3", "14"]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~".PHP_EOL + ."GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = "Test_SharedUnboundProvider"; + $include_path = __DIR__."/SharedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(3)) + ->method("fetchAssoc") + ->withConsecutive([$result1],[$result2],[$result2]) + ->will($this->onConsecutiveCalls( + null, + ["ids" => "1,2", "owners" => $sub_tree_ids[0].",".$sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + + $owner_1 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $owner_1 + ->method("getId") + ->willReturn("23"); + $db->object_ref[$sub_tree_ids[0]] = $owner_1; + + $owner_2 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $owner_2 + ->method("getId") + ->willReturn("24"); + $db->object_ref[$sub_tree_ids[1]] = $owner_2; + + $providers = $db->providersFor($object); + $this->assertCount(1, $providers); + $provider = array_shift($providers); + + $this->assertInstanceOf(Provider::class, $provider); + $this->assertEquals($object, $provider->object()); + $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); + $this->assertEquals([$owner_1, $owner_2], $provider->unboundProvider()->owners()); + + $this->assertEquals(1, $provider->unboundProvider()->idFor($owner_1)); + $this->assertEquals(2, $provider->unboundProvider()->idFor($owner_2)); + } + + public function test_providersFor_for_unbuildable_object() { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive - ( ["SELECT id, owner, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 0 AND ~IN~ AND object_type = ~TYPE~"] - - , ["SELECT GROUP_CONCAT(id SEPARATOR \",\") ids, GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 1 AND ~IN~ AND object_type = ~TYPE~ GROUP BY class_name, include_path"] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(4)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result1],[$result1],[$result2]) - ->will($this->onConsecutiveCalls( - ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], - ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null, - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~".PHP_EOL + ."GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(4)) + ->method("fetchAssoc") + ->withConsecutive([$result1],[$result1],[$result1],[$result2]) + ->will($this->onConsecutiveCalls( + ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], + ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null, + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); $db->throws = true; - $providers = $db->providersFor($object); - $this->assertCount(0, $providers); - } - - public function test_providersFor_shared_for_unbuildable_objects() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = ["3", "14"]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); + $providers = $db->providersFor($object); + $this->assertCount(0, $providers); + } + + public function test_providersFor_shared_for_unbuildable_objects() { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive - ( ["SELECT id, owner, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 0 AND ~IN~ AND object_type = ~TYPE~"] - - , ["SELECT GROUP_CONCAT(id SEPARATOR \",\") ids, GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE shared = 1 AND ~IN~ AND object_type = ~TYPE~ GROUP BY class_name, include_path"] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = "Test_SharedUnboundProvider"; - $include_path = __DIR__."/SharedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(3)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result2],[$result2]) - ->will($this->onConsecutiveCalls( - null, - ["ids" => "1,2", "owners" => $sub_tree_ids[0].",".$sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 0".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL + ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL + ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL + ."WHERE shared = 1".PHP_EOL + ." AND ~IN~".PHP_EOL + ." AND object_type = ~TYPE~".PHP_EOL + ."GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = "Test_SharedUnboundProvider"; + $include_path = __DIR__."/SharedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(3)) + ->method("fetchAssoc") + ->withConsecutive([$result1],[$result2],[$result2]) + ->will($this->onConsecutiveCalls( + null, + ["ids" => "1,2", "owners" => $sub_tree_ids[0].",".$sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); $db->throws = true; - $providers = $db->providersFor($object); - $this->assertCount(0, $providers); - } + $providers = $db->providersFor($object); + $this->assertCount(0, $providers); + } -} + } diff --git a/tests/ILIAS/ilProviderObjectHelperTest.php b/tests/ILIAS/ilProviderObjectHelperTest.php index 77e6fca..3800737 100644 --- a/tests/ILIAS/ilProviderObjectHelperTest.php +++ b/tests/ILIAS/ilProviderObjectHelperTest.php @@ -39,12 +39,12 @@ public function _createUnboundProvider($object_type, $class_name, $path) { class _SeparatedUnboundProvider extends Ente\ILIAS\SeparatedUnboundProvider { public function componentTypes() {} - public function buildComponentsOf($c, Ente\ILIAS\Entity $e) {} + public function buildComponentsOf(string $c, Ente\Entity $e) : array {} } class _SharedUnboundProvider extends Ente\ILIAS\SharedUnboundProvider { public function componentTypes() {} - public function buildComponentsOf($c, Ente\ILIAS\Entity $e) {} + public function buildComponentsOf(string $c, Ente\Entity $e) : array {} } class ilProviderObjectHelperTest extends PHPUnit_Framework_TestCase { @@ -132,12 +132,17 @@ public function test_createUnboundProvider_with_non_provider_class() { $class_name = "CLASS"; $path = "PATH"; + $mock = $this + ->getMockBuilder(ilProviderObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC"]) + ->getMock(); + $thrown = true; try { $mock->_createUnboundProvider($object_type, $class_name, $path); $this->assertFalse("This should not happen."); } - catch (\Exception $e) { + catch (\LogicException $e) { $thrown = true; } $this->assertTrue($thrown); diff --git a/tests/ProviderHelperTest.php b/tests/ProviderHelperTest.php index f60d68a..090a1de 100644 --- a/tests/ProviderHelperTest.php +++ b/tests/ProviderHelperTest.php @@ -8,6 +8,7 @@ * the license along with the code. */ +use CaT\Ente\Entity; use CaT\Ente\Component; use CaT\Ente\ProviderHelper; @@ -21,7 +22,7 @@ interface Unrelated { } class SomeComponentImplementation implements SomeComponent, SomeOtherComponent, Unrelated { - public function entity() { throw new \RuntimeException(); } + public function entity() : Entity { throw new \RuntimeException(); } } class ProviderHelperTest extends PHPUnit_Framework_TestCase { From 0e0aef36607a9bd04e630cdd63233b944b43fbfd Mon Sep 17 00:00:00 2001 From: Stefan Hecken Date: Thu, 4 Jul 2019 09:29:30 +0200 Subject: [PATCH 3/6] Change intendation to spaces --- .../class.ilComponentHandlerExamplePlugin.php | 31 +- .../class.ilObjComponentHandlerExample.php | 41 +- ...ass.ilObjComponentHandlerExampleAccess.php | 86 +- .../class.ilObjComponentHandlerExampleGUI.php | 75 +- ...ss.ilObjComponentHandlerExampleListGUI.php | 74 +- example/ComponentHandlerExample/composer.json | 22 +- example/ComponentHandlerExample/composer.lock | 90 +- .../Settings/ComponentProviderExample.php | 21 +- .../classes/Settings/DB.php | 45 +- .../classes/Settings/ilDB.php | 56 +- .../classes/UnboundProvider.php | 21 +- ...class.ilComponentProviderExamplePlugin.php | 39 +- .../class.ilObjComponentProviderExample.php | 78 +- ...ss.ilObjComponentProviderExampleAccess.php | 86 +- ...class.ilObjComponentProviderExampleGUI.php | 82 +- ...s.ilObjComponentProviderExampleListGUI.php | 74 +- .../ComponentProviderExample/composer.json | 22 +- .../ComponentProviderExample/composer.lock | 90 +- .../tests/SettingsTest.php | 12 +- src/CachedProvider.php | 84 +- src/CachedRepository.php | 78 +- src/Component.php | 12 +- src/Entity.php | 16 +- src/ILIAS/Cache.php | 12 +- src/ILIAS/Entity.php | 38 +- src/ILIAS/Provider.php | 226 +- src/ILIAS/ProviderDB.php | 104 +- src/ILIAS/Repository.php | 40 +- src/ILIAS/SeparatedUnboundProvider.php | 124 +- src/ILIAS/SharedUnboundProvider.php | 118 +- src/ILIAS/UnboundProvider.php | 62 +- src/ILIAS/ilCachesOwnerRangeProviderDB.php | 415 ++-- src/ILIAS/ilGlobalCache.php | 82 +- src/ILIAS/ilHandlerObjectHelper.php | 100 +- src/ILIAS/ilObjectHelper.php | 42 +- src/ILIAS/ilProviderDB.php | 1298 +++++------ src/ILIAS/ilProviderObjectHelper.php | 80 +- src/Provider.php | 56 +- src/ProviderHelper.php | 30 +- src/Repository.php | 20 +- src/RepositoryHelper.php | 63 +- src/Simple/AttachInt.php | 8 +- src/Simple/AttachIntMemory.php | 62 +- src/Simple/AttachString.php | 8 +- src/Simple/AttachStringMemory.php | 62 +- src/Simple/Entity.php | 30 +- src/Simple/Provider.php | 122 +- src/Simple/Repository.php | 112 +- tests/CachedProviderTest.php | 26 +- tests/CachedRepositoryTest.php | 15 +- tests/ILIAS/EntityTest.php | 13 +- tests/ILIAS/ProviderTest.php | 121 +- tests/ILIAS/RepositoryTest.php | 48 +- tests/ILIAS/SeparatedUnboundProviderTest.php | 39 +- tests/ILIAS/SharedUnboundProviderTest.php | 39 +- .../ILIAS/ilCachesOwnerRangeProviderTest.php | 197 +- tests/ILIAS/ilDBInterface.php | 181 +- tests/ILIAS/ilHandlerObjectHelperTest.php | 211 +- tests/ILIAS/ilObject.php | 44 +- tests/ILIAS/ilObjectDataCache.php | 9 +- tests/ILIAS/ilObjectHelperTest.php | 63 +- tests/ILIAS/ilProviderDBTest.php | 1911 +++++++++-------- tests/ILIAS/ilProviderObjectHelperTest.php | 257 ++- tests/ILIAS/ilTree.php | 43 +- tests/ProviderHelperTest.php | 27 +- tests/ProviderTest.php | 19 +- tests/RepositoryHelperTest.php | 100 +- tests/RepositoryTest.php | 18 +- tests/Simple/AttachIntMemoryTest.php | 19 +- tests/Simple/AttachStringMemoryTest.php | 17 +- tests/Simple/ProviderTest.php | 25 +- tests/Simple/RepositoryTest.php | 36 +- 72 files changed, 4154 insertions(+), 3873 deletions(-) diff --git a/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php b/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php index 415f90c..74f14e0 100644 --- a/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php +++ b/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php @@ -1,28 +1,31 @@ setType("xleh"); - } + /** + * Init the type of the plugin. Same value as choosen in plugin.php + */ + public function initType() + { + $this->setType("xleh"); + } /** * Returns an array with title => string[] entries containing the strings @@ -26,11 +29,12 @@ public function initType() { * * @return array */ - public function getProvidedStrings() { - $components = $this->getComponentsOfType(\CaT\Ente\Simple\AttachString::class); + public function getProvidedStrings() + { + $components = $this->getComponentsOfType(\CaT\Ente\Simple\AttachString::class); $provided_strings = []; - foreach ($components as $component) { + foreach ($components as $component) { $provided_strings[] = $component->attachedString(); } @@ -38,11 +42,12 @@ public function getProvidedStrings() { } /** - * Get the ref_id of the object this object handles components for. - * - * @return int + * Get the ref_id of the object this object handles components for. + * + * @return int */ - protected function getEntityRefId() { + protected function getEntityRefId() + { global $DIC; return $DIC->repositoryTree()->getParentId($this->getRefId()); } diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php index 31631f6..2dc4af2 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php @@ -4,50 +4,52 @@ /** * Access checker for each plugin object. */ -class ilObjComponentHandlerExampleAccess extends ilObjectPluginAccess { - /** - * Checks wether a user may invoke a command or not - * (this method is called by ilAccessHandler::checkAccess) - * - * Please do not check any preconditions handled by - * ilConditionHandler here. Also don't do usual RBAC checks. - * - * @param string $a_cmd command (not permission!) - * @param string $a_permission permission - * @param int $a_ref_id reference id - * @param int $a_obj_id object id - * @param int $a_user_id user id (default is current user) - * - * @return boolean true, if everything is ok - */ - public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "") { - global $ilUser, $ilAccess; +class ilObjComponentHandlerExampleAccess extends ilObjectPluginAccess +{ + /** + * Checks wether a user may invoke a command or not + * (this method is called by ilAccessHandler::checkAccess) + * + * Please do not check any preconditions handled by + * ilConditionHandler here. Also don't do usual RBAC checks. + * + * @param string $a_cmd command (not permission!) + * @param string $a_permission permission + * @param int $a_ref_id reference id + * @param int $a_obj_id object id + * @param int $a_user_id user id (default is current user) + * + * @return boolean true, if everything is ok + */ + public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "") + { + global $ilUser, $ilAccess; - /* - * This Routine is called within ilAccess::checkAccessOfUser::doStatusCheck. - * We rely on standart ilAccess::checkAccessOfUser procedure, i.e. return true here, except when the object is offline, - * then redirect to read-permission check. - */ - if ($a_user_id == "") { - $a_user_id = $ilUser->getId(); - } + /* + * This Routine is called within ilAccess::checkAccessOfUser::doStatusCheck. + * We rely on standart ilAccess::checkAccessOfUser procedure, i.e. return true here, except when the object is offline, + * then redirect to read-permission check. + */ + if ($a_user_id == "") { + $a_user_id = $ilUser->getId(); + } - switch ($a_permission) { - case "read": - if (!self::checkOnline($a_obj_id) - && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) - { - return false; - } - } + switch ($a_permission) { + case "read": + if (!self::checkOnline($a_obj_id) + && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) { + return false; + } + } - return true; - } + return true; + } - /** - * Check online status of object - */ - static public function checkOnline($a_id) { - return true; - } + /** + * Check online status of object + */ + static public function checkOnline($a_id) + { + return true; + } } diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php index 46d1a28..0a9a42e 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php @@ -11,7 +11,8 @@ * @ilCtrl_isCalledBy ilObjComponentHandlerExampleGUI: ilRepositoryGUI, ilAdministrationGUI, ilObjPluginDispatchGUI * @ilCtrl_Calls ilObjComponentHandlerExampleGUI: ilPermissionGUI, ilInfoScreenGUI, ilObjectCopyGUI, ilCommonActionDispatcherGUI */ -class ilObjComponentHandlerExampleGUI extends ilObjectPluginGUI { +class ilObjComponentHandlerExampleGUI extends ilObjectPluginGUI +{ /** * @var \ilTemplate */ @@ -27,58 +28,64 @@ class ilObjComponentHandlerExampleGUI extends ilObjectPluginGUI { */ protected $ui_renderer; - /** - * Called after parent constructor. It's possible to define some plugin special values - */ - protected function afterConstructor() { + /** + * Called after parent constructor. It's possible to define some plugin special values + */ + protected function afterConstructor() + { global $DIC; $this->ilTemplate = $DIC->ui()->mainTemplate(); $this->ui_factory = $DIC->ui()->factory(); - $this->ui_renderer= $DIC->ui()->renderer(); - } + $this->ui_renderer = $DIC->ui()->renderer(); + } - /** - * Get type. Same value as choosen in plugin.php - */ - final function getType() { - return "xleh"; - } + /** + * Get type. Same value as choosen in plugin.php + */ + final function getType() + { + return "xleh"; + } - /** - * Handles all commmands of this class, centralizes permission checks - */ - function performCommand($cmd) { - switch ($cmd) { + /** + * Handles all commmands of this class, centralizes permission checks + */ + function performCommand($cmd) + { + switch ($cmd) { case "showContent": $this->ilTemplate->setContent($this->showContent()); break; - default: + default: throw new \InvalidArgumentException("Unknown Command: '$cmd'"); - } - } + } + } /** * Show the edit form. * * @return string */ - public function showContent() { + public function showContent() + { $items = $this->object->getProvidedStrings(); $listing = $this->ui_factory->listing()->ordered($items); return $this->ui_renderer->render($listing); } - /** - * After object has been created -> jump to this command - */ - function getAfterCreationCmd() { - return "showContent"; - } + /** + * After object has been created -> jump to this command + */ + function getAfterCreationCmd() + { + return "showContent"; + } - /** - * Get standard command - */ - function getStandardCmd() { - return "showContent"; - } + /** + * Get standard command + */ + function getStandardCmd() + { + return "showContent"; + } } diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php index feab240..bb23ed9 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php @@ -4,42 +4,46 @@ /** * List gui class for plugin object in repository */ -class ilObjComponentHandlerExampleListGUI extends ilObjectPluginListGUI { - /** - * Init the type of the plugin. Same value as choosen in plugin.php - */ - public function initType() { - $this->setType("xleh"); - } +class ilObjComponentHandlerExampleListGUI extends ilObjectPluginListGUI +{ + /** + * Init the type of the plugin. Same value as choosen in plugin.php + */ + public function initType() + { + $this->setType("xleh"); + } - /** - * Get name of gui class handling the commands - */ - function getGuiClass() { - return "ilObjComponentHandlerExampleGUI"; - } + /** + * Get name of gui class handling the commands + */ + function getGuiClass() + { + return "ilObjComponentHandlerExampleGUI"; + } - /** - * Get commands - */ - function initCommands() { - $this->info_screen_enabled = true; - $this->copy_enabled = true; - $this->cut_enabled = true; - $this->subscribe_enabled = true; - $this->link_enabled = false; - $this->payment_enabled = false; - $this->timings_enabled = false; + /** + * Get commands + */ + function initCommands() + { + $this->info_screen_enabled = true; + $this->copy_enabled = true; + $this->cut_enabled = true; + $this->subscribe_enabled = true; + $this->link_enabled = false; + $this->payment_enabled = false; + $this->timings_enabled = false; - return array(array("permission" => "read", - "cmd" => "showContent", - "default" => true - ), - array("permission" => "write", - "cmd" => "editProperties", - "txt" => $this->txt("edit"), - "default" => false - ) - ); - } + return array(array("permission" => "read", + "cmd" => "showContent", + "default" => true + ), + array("permission" => "write", + "cmd" => "editProperties", + "txt" => $this->txt("edit"), + "default" => false + ) + ); + } } diff --git a/example/ComponentHandlerExample/composer.json b/example/ComponentHandlerExample/composer.json index a1b67f8..a9afc6a 100644 --- a/example/ComponentHandlerExample/composer.json +++ b/example/ComponentHandlerExample/composer.json @@ -1,14 +1,16 @@ { - "require" : { - "cat/ente" : "@dev" - }, - "repositories" : [{ - "type" : "vcs", - "url": "git@github.com:/conceptsandtraining/lib-ente.git" - }], - "autoload" : { - "psr-4" : { - "CaT\\Plugins\\ComponentHandlerExample\\" : "./classes" + "require": { + "cat/ente": "@dev" + }, + "repositories": [ + { + "type": "vcs", + "url": "git@github.com:/conceptsandtraining/lib-ente.git" + } + ], + "autoload": { + "psr-4": { + "CaT\\Plugins\\ComponentHandlerExample\\": "./classes" } } } diff --git a/example/ComponentHandlerExample/composer.lock b/example/ComponentHandlerExample/composer.lock index 460b429..7b0aa26 100644 --- a/example/ComponentHandlerExample/composer.lock +++ b/example/ComponentHandlerExample/composer.lock @@ -1,47 +1,47 @@ { - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "9c0e2452fa8cca6d217b99382a0306aa", - "content-hash": "272e30e103e1ef82a667b67c718bb48c", - "packages": [ - { - "name": "cat/ente", - "version": "0.1.0", - "dist": { - "type": "path", - "url": "../../lib/", - "reference": "66f0059afe55352a187b7293f0c83658869f2452", - "shasum": null - }, - "type": "library", - "autoload": { - "psr-4": { - "CaT\\Ente\\": "src" - } - }, - "license": [ - "GPLv3" - ], - "authors": [ - { - "name": "Richard Klees", - "email": "richard.klees@concepts-and-training.de" - } - ], - "description": "An entity component framework for PHP." - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "cat/ente": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "9c0e2452fa8cca6d217b99382a0306aa", + "content-hash": "272e30e103e1ef82a667b67c718bb48c", + "packages": [ + { + "name": "cat/ente", + "version": "0.1.0", + "dist": { + "type": "path", + "url": "../../lib/", + "reference": "66f0059afe55352a187b7293f0c83658869f2452", + "shasum": null + }, + "type": "library", + "autoload": { + "psr-4": { + "CaT\\Ente\\": "src" + } + }, + "license": [ + "GPLv3" + ], + "authors": [ + { + "name": "Richard Klees", + "email": "richard.klees@concepts-and-training.de" + } + ], + "description": "An entity component framework for PHP." + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "cat/ente": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] } diff --git a/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php b/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php index e68304b..5de585e 100644 --- a/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php +++ b/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php @@ -1,11 +1,12 @@ obj_id = $obj_id; @@ -28,7 +30,8 @@ public function __construct($obj_id, array $provided_strings) { * * @return int */ - public function objId() { + public function objId() + { return $this->obj_id; } @@ -37,17 +40,19 @@ public function objId() { * * @return string[] */ - public function providedStrings() { - return $this->provided_strings; + public function providedStrings() + { + return $this->provided_strings; } /** * Change the provided strings. * - * @param string[] $provided_strings + * @param string[] $provided_strings * @return ComponentProviderExample */ - public function withProvidedStrings(array $provided_strings) { + public function withProvidedStrings(array $provided_strings) + { assert('array_sum(array_map("is_string", $provided_strings)) == count($provided_strings)'); $clone = clone $this; $clone->provided_strings = $provided_strings; diff --git a/example/ComponentProviderExample/classes/Settings/DB.php b/example/ComponentProviderExample/classes/Settings/DB.php index fc3a97c..11f8d63 100644 --- a/example/ComponentProviderExample/classes/Settings/DB.php +++ b/example/ComponentProviderExample/classes/Settings/DB.php @@ -1,32 +1,33 @@ ilDB = $ilDB; } - /** + /** * @inheritdoc - */ - public function update(ComponentProviderExample $settings) { + */ + public function update(ComponentProviderExample $settings) + { $obj_id = $settings->objId(); $this->deleteFor($obj_id); foreach ($settings->providedStrings() as $value) { $this->ilDB->insert(self::TABLE_NAME, - [ "obj_id" => ["integer", $obj_id] - , "value" => ["string", $value] - ]); - } + ["obj_id" => ["integer", $obj_id] + , "value" => ["string", $value] + ]); + } } - /** + /** * @inheritdoc - */ - public function getFor($obj_id) { + */ + public function getFor($obj_id) + { assert('is_int($obj_id)'); $query = - "SELECT value FROM ".self::TABLE_NAME. - " WHERE obj_id = ".$this->ilDB->quote($obj_id, "integer"); + "SELECT value FROM " . self::TABLE_NAME . + " WHERE obj_id = " . $this->ilDB->quote($obj_id, "integer"); $res = $this->ilDB->query($query); $values = []; - while($row = $this->ilDB->fetchAssoc($res)) { + while ($row = $this->ilDB->fetchAssoc($res)) { $values[] = $row["value"]; } return new ComponentProviderExample($obj_id, $values); } - /** + /** * @inheritdoc - */ - public function deleteFor($obj_id) { + */ + public function deleteFor($obj_id) + { $statement = - "DELETE FROM ".self::TABLE_NAME. - " WHERE obj_id = ".$this->ilDB->quote($obj_id, "integer"); + "DELETE FROM " . self::TABLE_NAME . + " WHERE obj_id = " . $this->ilDB->quote($obj_id, "integer"); $this->ilDB->manipulate($statement); } - public function install() { - if(!$this->ilDB->tableExists(self::TABLE_NAME)) { + public function install() + { + if (!$this->ilDB->tableExists(self::TABLE_NAME)) { $this->ilDB->createTable(self::TABLE_NAME, - [ "obj_id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "value" => ["type" => "text", "length" => 64, "notnull" => true] + ["obj_id" => ["type" => "integer", "length" => 4, "notnull" => true] + , "value" => ["type" => "text", "length" => 64, "notnull" => true] ]); $this->ilDB->addPrimaryKey(self::TABLE_NAME, ["obj_id", "value"]); diff --git a/example/ComponentProviderExample/classes/UnboundProvider.php b/example/ComponentProviderExample/classes/UnboundProvider.php index 2664e80..c431145 100644 --- a/example/ComponentProviderExample/classes/UnboundProvider.php +++ b/example/ComponentProviderExample/classes/UnboundProvider.php @@ -2,34 +2,37 @@ namespace CaT\Plugins\ComponentProviderExample; -require_once(__DIR__."/../vendor/autoload.php"); +require_once(__DIR__ . "/../vendor/autoload.php"); use \CaT\Ente\ILIAS\SeparatedUnboundProvider as Base; use \CaT\Ente\Simple\AttachString; use \CaT\Ente\Simple\AttachStringMemory; use \CaT\Ente\ILIAS\Entity; -class UnboundProvider extends Base { +class UnboundProvider extends Base +{ /** * @inheritdocs */ - public function componentTypes() { + public function componentTypes() + { return [AttachString::class]; } /** * Build the component(s) of the given type for the given object. * - * @param string $component_type - * @param Entity $provider + * @param string $component_type + * @param Entity $provider * @return Component[] */ - public function buildComponentsOf($component_type, Entity $entity) { + public function buildComponentsOf($component_type, Entity $entity) + { if ($component_type === AttachString::class) { $returns = []; - foreach ($this->owner()->getProvidedStrings() as $s) { - $returns[] = new AttachStringMemory($entity, $s); - } + foreach ($this->owner()->getProvidedStrings() as $s) { + $returns[] = new AttachStringMemory($entity, $s); + } return $returns; } throw new \InvalidArgumentException("Unexpected component type '$component_type'"); diff --git a/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php b/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php index f941ac2..1fbaf75 100644 --- a/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php +++ b/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php @@ -1,11 +1,12 @@ ilDB = $DIC->database(); } - /** - * Get the name of the Plugin - * - * @return string - */ - function getPluginName() { - return "ComponentProviderExample"; - } + /** + * Get the name of the Plugin + * + * @return string + */ + function getPluginName() + { + return "ComponentProviderExample"; + } - /** - * Defines custom uninstall action like delete table or something else - */ - protected function uninstallCustom() { - } + /** + * Defines custom uninstall action like delete table or something else + */ + protected function uninstallCustom() + { + } /** * Get the database for settings. * * @return \CaT\Plugins\ComponentProviderExample\Settings\DB */ - public function settingsDB() { + public function settingsDB() + { if ($this->settings_db === null) { $this->settings_db = new \CaT\Plugins\ComponentProviderExample\Settings\ilDB($this->ilDB); } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php index 1514c0b..5d8176f 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php @@ -7,48 +7,54 @@ /** * Object of the plugin */ -class ilObjComponentProviderExample extends ilObjectPlugin { - use ilProviderObjectHelper; +class ilObjComponentProviderExample extends ilObjectPlugin +{ + use ilProviderObjectHelper; - protected function getDIC() { - return $GLOBALS["DIC"]; - } + protected function getDIC() + { + return $GLOBALS["DIC"]; + } - /** - * Init the type of the plugin. Same value as choosen in plugin.php - */ - public function initType() { - $this->setType("xlep"); - } + /** + * Init the type of the plugin. Same value as choosen in plugin.php + */ + public function initType() + { + $this->setType("xlep"); + } - /** - * Creates ente-provider. - */ - public function doCreate() { - $this->createUnboundProvider("crs", UnboundProvider::class, __DIR__."/UnboundProvider.php"); - } + /** + * Creates ente-provider. + */ + public function doCreate() + { + $this->createUnboundProvider("crs", UnboundProvider::class, __DIR__ . "/UnboundProvider.php"); + } - /** - * Get called if the object should be deleted. - * Delete additional settings - */ - public function doDelete() { + /** + * Get called if the object should be deleted. + * Delete additional settings + */ + public function doDelete() + { $db = $this->plugin->settingsDB(); $db->deleteFor($this->getId()); $this->deleteUnboundProviders(); - } + } - /** - * Get the strings provided by this object. - * - * @return string[] - */ - public function getProvidedStrings() { - $settings = $this->plugin->settingsDB()->getFor((int)$this->getId()); - $returns = []; - foreach($settings->providedStrings() as $s) { - $returns[] = $s; - } - return $returns; - } + /** + * Get the strings provided by this object. + * + * @return string[] + */ + public function getProvidedStrings() + { + $settings = $this->plugin->settingsDB()->getFor((int)$this->getId()); + $returns = []; + foreach ($settings->providedStrings() as $s) { + $returns[] = $s; + } + return $returns; + } } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php index cd0ddf7..61fa51d 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php @@ -4,50 +4,52 @@ /** * Access checker for each plugin object. */ -class ilObjComponentProviderExampleAccess extends ilObjectPluginAccess { - /** - * Checks wether a user may invoke a command or not - * (this method is called by ilAccessHandler::checkAccess) - * - * Please do not check any preconditions handled by - * ilConditionHandler here. Also don't do usual RBAC checks. - * - * @param string $a_cmd command (not permission!) - * @param string $a_permission permission - * @param int $a_ref_id reference id - * @param int $a_obj_id object id - * @param int $a_user_id user id (default is current user) - * - * @return boolean true, if everything is ok - */ - public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "") { - global $ilUser, $ilAccess; +class ilObjComponentProviderExampleAccess extends ilObjectPluginAccess +{ + /** + * Checks wether a user may invoke a command or not + * (this method is called by ilAccessHandler::checkAccess) + * + * Please do not check any preconditions handled by + * ilConditionHandler here. Also don't do usual RBAC checks. + * + * @param string $a_cmd command (not permission!) + * @param string $a_permission permission + * @param int $a_ref_id reference id + * @param int $a_obj_id object id + * @param int $a_user_id user id (default is current user) + * + * @return boolean true, if everything is ok + */ + public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "") + { + global $ilUser, $ilAccess; - /* - * This Routine is called within ilAccess::checkAccessOfUser::doStatusCheck. - * We rely on standart ilAccess::checkAccessOfUser procedure, i.e. return true here, except when the object is offline, - * then redirect to read-permission check. - */ - if ($a_user_id == "") { - $a_user_id = $ilUser->getId(); - } + /* + * This Routine is called within ilAccess::checkAccessOfUser::doStatusCheck. + * We rely on standart ilAccess::checkAccessOfUser procedure, i.e. return true here, except when the object is offline, + * then redirect to read-permission check. + */ + if ($a_user_id == "") { + $a_user_id = $ilUser->getId(); + } - switch ($a_permission) { - case "read": - if (!self::checkOnline($a_obj_id) - && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) - { - return false; - } - } + switch ($a_permission) { + case "read": + if (!self::checkOnline($a_obj_id) + && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) { + return false; + } + } - return true; - } + return true; + } - /** - * Check online status of object - */ - static public function checkOnline($a_id) { - return true; - } + /** + * Check online status of object + */ + static public function checkOnline($a_id) + { + return true; + } } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php index 73b99f0..f38c47b 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php @@ -11,7 +11,8 @@ * @ilCtrl_isCalledBy ilObjComponentProviderExampleGUI: ilRepositoryGUI, ilAdministrationGUI, ilObjPluginDispatchGUI * @ilCtrl_Calls ilObjComponentProviderExampleGUI: ilPermissionGUI, ilInfoScreenGUI, ilObjectCopyGUI, ilCommonActionDispatcherGUI */ -class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI { +class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI +{ const VALUES_FIELD_NAME = "values"; const SAVE_CMD = "saveForm"; @@ -25,41 +26,45 @@ class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI { */ protected $ilCtrl; - /** - * Called after parent constructor. It's possible to define some plugin special values - */ - protected function afterConstructor() { + /** + * Called after parent constructor. It's possible to define some plugin special values + */ + protected function afterConstructor() + { global $DIC; $this->ilTemplate = $DIC->ui()->mainTemplate(); $this->ilCtrl = $DIC->ctrl(); - } - - /** - * Get type. Same value as choosen in plugin.php - */ - final function getType() { - return "xlep"; - } - - /** - * Handles all commmands of this class, centralizes permission checks - */ - function performCommand($cmd) { - switch ($cmd) { + } + + /** + * Get type. Same value as choosen in plugin.php + */ + final function getType() + { + return "xlep"; + } + + /** + * Handles all commmands of this class, centralizes permission checks + */ + function performCommand($cmd) + { + switch ($cmd) { case self::SAVE_CMD: $this->saveForm(); case "showContent": $this->ilTemplate->setContent($this->showContent()); break; - default: + default: throw new \InvalidArgumentException("Unknown Command: '$cmd'"); - } - } + } + } /** * Save values provided from form. */ - protected function saveForm() { + protected function saveForm() + { $db = $this->plugin->settingsDB(); $settings = $db->getFor((int)$this->object->getId()); $settings = $settings->withProvidedStrings($_POST[self::VALUES_FIELD_NAME]); @@ -72,7 +77,8 @@ protected function saveForm() { * * @return string */ - public function showContent() { + public function showContent() + { $db = $this->plugin->settingsDB(); $settings = $db->getFor((int)$this->object->getId()); @@ -91,17 +97,19 @@ public function showContent() { return $form->getHTML(); } - /** - * After object has been created -> jump to this command - */ - function getAfterCreationCmd() { - return "showContent"; - } - - /** - * Get standard command - */ - function getStandardCmd() { - return "showContent"; - } + /** + * After object has been created -> jump to this command + */ + function getAfterCreationCmd() + { + return "showContent"; + } + + /** + * Get standard command + */ + function getStandardCmd() + { + return "showContent"; + } } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php index daec286..0dad242 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php @@ -4,42 +4,46 @@ /** * List gui class for plugin object in repository */ -class ilObjComponentProviderExampleListGUI extends ilObjectPluginListGUI { - /** - * Init the type of the plugin. Same value as choosen in plugin.php - */ - public function initType() { - $this->setType("xlep"); - } +class ilObjComponentProviderExampleListGUI extends ilObjectPluginListGUI +{ + /** + * Init the type of the plugin. Same value as choosen in plugin.php + */ + public function initType() + { + $this->setType("xlep"); + } - /** - * Get name of gui class handling the commands - */ - function getGuiClass() { - return "ilObjComponentProviderExampleGUI"; - } + /** + * Get name of gui class handling the commands + */ + function getGuiClass() + { + return "ilObjComponentProviderExampleGUI"; + } - /** - * Get commands - */ - function initCommands() { - $this->info_screen_enabled = true; - $this->copy_enabled = true; - $this->cut_enabled = true; - $this->subscribe_enabled = true; - $this->link_enabled = false; - $this->payment_enabled = false; - $this->timings_enabled = false; + /** + * Get commands + */ + function initCommands() + { + $this->info_screen_enabled = true; + $this->copy_enabled = true; + $this->cut_enabled = true; + $this->subscribe_enabled = true; + $this->link_enabled = false; + $this->payment_enabled = false; + $this->timings_enabled = false; - return array(array("permission" => "read", - "cmd" => "showContent", - "default" => true - ), - array("permission" => "write", - "cmd" => "editProperties", - "txt" => $this->txt("edit"), - "default" => false - ) - ); - } + return array(array("permission" => "read", + "cmd" => "showContent", + "default" => true + ), + array("permission" => "write", + "cmd" => "editProperties", + "txt" => $this->txt("edit"), + "default" => false + ) + ); + } } diff --git a/example/ComponentProviderExample/composer.json b/example/ComponentProviderExample/composer.json index 1019141..8ceb77c 100644 --- a/example/ComponentProviderExample/composer.json +++ b/example/ComponentProviderExample/composer.json @@ -1,14 +1,16 @@ { - "require" : { - "cat/ente" : "@dev" - }, - "repositories" : [{ - "type" : "vcs", - "url": "git@github.com:/conceptsandtraining/lib-ente.git" - }], - "autoload" : { - "psr-4" : { - "CaT\\Plugins\\ComponentProviderExample\\" : "./classes" + "require": { + "cat/ente": "@dev" + }, + "repositories": [ + { + "type": "vcs", + "url": "git@github.com:/conceptsandtraining/lib-ente.git" + } + ], + "autoload": { + "psr-4": { + "CaT\\Plugins\\ComponentProviderExample\\": "./classes" } } } diff --git a/example/ComponentProviderExample/composer.lock b/example/ComponentProviderExample/composer.lock index ab3d3d5..bddb1ae 100644 --- a/example/ComponentProviderExample/composer.lock +++ b/example/ComponentProviderExample/composer.lock @@ -1,47 +1,47 @@ { - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "3d742255057590cad00d70c503624e2c", - "content-hash": "272e30e103e1ef82a667b67c718bb48c", - "packages": [ - { - "name": "cat/ente", - "version": "0.1.0", - "dist": { - "type": "path", - "url": "../../lib/", - "reference": "66f0059afe55352a187b7293f0c83658869f2452", - "shasum": null - }, - "type": "library", - "autoload": { - "psr-4": { - "CaT\\Ente\\": "src" - } - }, - "license": [ - "GPLv3" - ], - "authors": [ - { - "name": "Richard Klees", - "email": "richard.klees@concepts-and-training.de" - } - ], - "description": "An entity component framework for PHP." - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "cat/ente": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "3d742255057590cad00d70c503624e2c", + "content-hash": "272e30e103e1ef82a667b67c718bb48c", + "packages": [ + { + "name": "cat/ente", + "version": "0.1.0", + "dist": { + "type": "path", + "url": "../../lib/", + "reference": "66f0059afe55352a187b7293f0c83658869f2452", + "shasum": null + }, + "type": "library", + "autoload": { + "psr-4": { + "CaT\\Ente\\": "src" + } + }, + "license": [ + "GPLv3" + ], + "authors": [ + { + "name": "Richard Klees", + "email": "richard.klees@concepts-and-training.de" + } + ], + "description": "An entity component framework for PHP." + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "cat/ente": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] } diff --git a/example/ComponentProviderExample/tests/SettingsTest.php b/example/ComponentProviderExample/tests/SettingsTest.php index 95c9bb0..dd52e7a 100644 --- a/example/ComponentProviderExample/tests/SettingsTest.php +++ b/example/ComponentProviderExample/tests/SettingsTest.php @@ -2,19 +2,23 @@ use \CaT\Plugins\ComponentProviderExample\Settings\ComponentProviderExample; -class SettingsTest extends PHPUnit_Framework_TestCase { - public function test_objId() { +class SettingsTest extends PHPUnit_Framework_TestCase +{ + public function test_objId() + { $cpe = new ComponentProviderExample(23, []); $this->assertEquals(23, $cpe->objId()); } - public function test_providedStrings() { + public function test_providedStrings() + { $some_strings = ["a", "b", "c"]; $cpe = new ComponentProviderExample(23, $some_strings); $this->assertEquals($some_strings, $cpe->providedStrings()); } - public function test_withProvidedStrings() { + public function test_withProvidedStrings() + { $cpe = new ComponentProviderExample(23, []); $this->assertEquals([], $cpe->providedStrings()); $some_strings = ["d", "e", "f"]; diff --git a/src/CachedProvider.php b/src/CachedProvider.php index 91b1eb1..ead420d 100644 --- a/src/CachedProvider.php +++ b/src/CachedProvider.php @@ -18,46 +18,46 @@ */ class CachedProvider implements Provider { - /** - * @var Provider - */ - protected $provider; - - /** - * @var array - */ - protected $cache; - - public function __construct(Provider $provider) - { - $this->provider = $provider; - $this->cache = []; - } - - /** - * @inheritdocs - */ - public function componentsOfType(string $component_type) : array - { - if (!isset($this->cache[$component_type])) { - $this->cache[$component_type] = $this->provider->componentsOfType($component_type); - } - return $this->cache[$component_type]; - } - - /** - * @inheritdocs - */ - public function componentTypes() : array - { - return $this->provider->componentTypes(); - } - - /** - * @inheritdocs - */ - public function entity() : Entity - { - return $this->provider->entity(); - } + /** + * @var Provider + */ + protected $provider; + + /** + * @var array + */ + protected $cache; + + public function __construct(Provider $provider) + { + $this->provider = $provider; + $this->cache = []; + } + + /** + * @inheritdocs + */ + public function componentsOfType(string $component_type): array + { + if (!isset($this->cache[$component_type])) { + $this->cache[$component_type] = $this->provider->componentsOfType($component_type); + } + return $this->cache[$component_type]; + } + + /** + * @inheritdocs + */ + public function componentTypes(): array + { + return $this->provider->componentTypes(); + } + + /** + * @inheritdocs + */ + public function entity(): Entity + { + return $this->provider->entity(); + } } diff --git a/src/CachedRepository.php b/src/CachedRepository.php index 9a60feb..e3947de 100644 --- a/src/CachedRepository.php +++ b/src/CachedRepository.php @@ -20,49 +20,49 @@ */ class CachedRepository implements Repository { - use RepositoryHelper; + use RepositoryHelper; - /** - * @var Repository - */ - protected $repository; + /** + * @var Repository + */ + protected $repository; - /** - * @var array - */ - protected $cache; + /** + * @var array + */ + protected $cache; - public function __construct(Repository $repository) - { - $this->repository = $repository; - $this->cache = []; - } + public function __construct(Repository $repository) + { + $this->repository = $repository; + $this->cache = []; + } - /** - * @inheritdocs - */ - public function providersForEntity(Entity $entity, string $component_type = null) : array - { - $id = $entity->id(); - if (!isset($this->cache[$id])) { - $this->cache[$id] = array_map( - function(Provider $p) { - return new CachedProvider($p); - }, - $this->repository->providersForEntity($entity) - ); - } + /** + * @inheritdocs + */ + public function providersForEntity(Entity $entity, string $component_type = null): array + { + $id = $entity->id(); + if (!isset($this->cache[$id])) { + $this->cache[$id] = array_map( + function (Provider $p) { + return new CachedProvider($p); + }, + $this->repository->providersForEntity($entity) + ); + } - if ($component_type === null) { - return $this->cache[$id]; - } + if ($component_type === null) { + return $this->cache[$id]; + } - $providers = []; - foreach ($this->cache[$id] as $provider) { - if (in_array($component_type, $provider->componentTypes())) { - $providers[] = $provider; - } - } - return $providers; - } + $providers = []; + foreach ($this->cache[$id] as $provider) { + if (in_array($component_type, $provider->componentTypes())) { + $providers[] = $provider; + } + } + return $providers; + } } diff --git a/src/Component.php b/src/Component.php index 36cbae9..5375e81 100644 --- a/src/Component.php +++ b/src/Component.php @@ -24,10 +24,10 @@ */ interface Component { - /** - * Get the entity this component is attached to. - * - * @return Entity - */ - public function entity() : Entity; + /** + * Get the entity this component is attached to. + * + * @return Entity + */ + public function entity(): Entity; } diff --git a/src/Entity.php b/src/Entity.php index 3fe0b06..4d2126c 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -13,7 +13,7 @@ namespace CaT\Ente; /** - * An entity is to be thought of as a naked object without any behaviour. + * An entity is to be thought of as a naked object without any behaviour. * * ARCH: * - The entity could have a method to provide components by itself. This would @@ -23,11 +23,11 @@ */ interface Entity { - /** - * Some ID for this entity. - * - * It needs to be guaranteed that every entity has exactly one unique id. - * It needs to be guaranteed that the id can be serialised. - */ - public function id() : int; + /** + * Some ID for this entity. + * + * It needs to be guaranteed that every entity has exactly one unique id. + * It needs to be guaranteed that the id can be serialised. + */ + public function id(): int; } diff --git a/src/ILIAS/Cache.php b/src/ILIAS/Cache.php index d448e24..9de28c4 100644 --- a/src/ILIAS/Cache.php +++ b/src/ILIAS/Cache.php @@ -17,12 +17,12 @@ */ interface Cache { - public function set(string $key, array $value); + public function set(string $key, array $value); - /** - * @return array|null - */ - public function get(string $key); + /** + * @return array|null + */ + public function get(string $key); - public function delete(string $key); + public function delete(string $key); } diff --git a/src/ILIAS/Entity.php b/src/ILIAS/Entity.php index 58df176..f5539d7 100644 --- a/src/ILIAS/Entity.php +++ b/src/ILIAS/Entity.php @@ -19,26 +19,26 @@ */ class Entity implements IEntity { - /** - * @var \ilObject - */ - private $object; + /** + * @var \ilObject + */ + private $object; - public function __construct(\ilObject $object) - { - $this->object = $object; - } + public function __construct(\ilObject $object) + { + $this->object = $object; + } - /** - * @inheritdocs - */ - public function id() : int - { - return (int)$this->object->getId(); - } + /** + * @inheritdocs + */ + public function id(): int + { + return (int)$this->object->getId(); + } - public function object() : \ilObject - { - return $this->object; - } + public function object(): \ilObject + { + return $this->object; + } } diff --git a/src/ILIAS/Provider.php b/src/ILIAS/Provider.php index 4d64125..2ddb12a 100644 --- a/src/ILIAS/Provider.php +++ b/src/ILIAS/Provider.php @@ -20,117 +20,117 @@ */ final class Provider implements \CaT\Ente\Provider { - /** - * @var \ilObject - */ - private $object; - - /** - * @var Entity - */ - private $entity; - - /** - * @var UnboundProvider - */ - private $unbound_provider; - - /** - * @var array - */ - private $components; - - final public function __construct(\ilObject $object, UnboundProvider $unbound_provider) - { - $this->object = $object; - $this->entity = new Entity($object); - $this->unbound_provider = $unbound_provider; - $this->components = []; - } - - /** - * @inheritdocs - */ - final public function componentTypes() : array - { - return $this->unbound_provider->componentTypes(); - } - - /** - * @inheritdocs - */ - final public function componentsOfType(string $component_type) : array - { - if (isset($this->components[$component_type])) { - return $this->components[$component_type]; - } - - $components = $this->unbound_provider->buildComponentsOf($component_type, $this->entity()); - $this->checkComponentArray($components, $component_type); - $this->components[$component_type] = $components; - return $components; - } - - /** - * @inheritdocs - */ - final public function entity() : IEntity - { - return $this->entity; - } - - /** - * Get the entity object of the component. - * - * @return \ilObject - */ - final public function object() : \ilObject - { - return $this->object; - } - - /** - * Get the owner object of the component. - * - * @return \ilObject[] - */ - final public function owners() : array - { - return $this->unbound_provider->owners(); - } - - /** - * Get the unbound provider underlying this. - * - * @return UnboundProvider - */ - final public function unboundProvider() : UnboundProvider - { - return $this->unbound_provider; - } - - /** - * Checks if the $var is a valid component array for the given type. - * @param mixed $var - */ - private function checkComponentArray($var, string $component_type) - { - if (!is_array($var)) { - throw new \UnexpectedValueException( - "Expected buildComponentsOf to return an array, got ".gettype($var)); - } - - foreach($var as $component) { - if (!($component instanceof $component_type)) { - throw new \UnexpectedValueException( - "Expected build components to have the type $component_type, got " - .get_class($component) - ); - } - if (!$component->entity() === $this->entity()) { - throw new \UnexpectedValueException( - 'Expected build components to have the same entity as $this.'); - } - } - } + /** + * @var \ilObject + */ + private $object; + + /** + * @var Entity + */ + private $entity; + + /** + * @var UnboundProvider + */ + private $unbound_provider; + + /** + * @var array + */ + private $components; + + final public function __construct(\ilObject $object, UnboundProvider $unbound_provider) + { + $this->object = $object; + $this->entity = new Entity($object); + $this->unbound_provider = $unbound_provider; + $this->components = []; + } + + /** + * @inheritdocs + */ + final public function componentTypes(): array + { + return $this->unbound_provider->componentTypes(); + } + + /** + * @inheritdocs + */ + final public function componentsOfType(string $component_type): array + { + if (isset($this->components[$component_type])) { + return $this->components[$component_type]; + } + + $components = $this->unbound_provider->buildComponentsOf($component_type, $this->entity()); + $this->checkComponentArray($components, $component_type); + $this->components[$component_type] = $components; + return $components; + } + + /** + * @inheritdocs + */ + final public function entity(): IEntity + { + return $this->entity; + } + + /** + * Get the entity object of the component. + * + * @return \ilObject + */ + final public function object(): \ilObject + { + return $this->object; + } + + /** + * Get the owner object of the component. + * + * @return \ilObject[] + */ + final public function owners(): array + { + return $this->unbound_provider->owners(); + } + + /** + * Get the unbound provider underlying this. + * + * @return UnboundProvider + */ + final public function unboundProvider(): UnboundProvider + { + return $this->unbound_provider; + } + + /** + * Checks if the $var is a valid component array for the given type. + * @param mixed $var + */ + private function checkComponentArray($var, string $component_type) + { + if (!is_array($var)) { + throw new \UnexpectedValueException( + "Expected buildComponentsOf to return an array, got " . gettype($var)); + } + + foreach ($var as $component) { + if (!($component instanceof $component_type)) { + throw new \UnexpectedValueException( + "Expected build components to have the type $component_type, got " + . get_class($component) + ); + } + if (!$component->entity() === $this->entity()) { + throw new \UnexpectedValueException( + 'Expected build components to have the same entity as $this.'); + } + } + } } diff --git a/src/ILIAS/ProviderDB.php b/src/ILIAS/ProviderDB.php index dd7bfe9..37f33c1 100644 --- a/src/ILIAS/ProviderDB.php +++ b/src/ILIAS/ProviderDB.php @@ -17,62 +17,62 @@ */ interface ProviderDB { - /** - * Create a new separated unbound provider for the given owner. - * - * The provider will belong to objects above the $owner in the tree that also - * have the type $obj_type. - */ - public function createSeparatedUnboundProvider( - \ilObject $owner, - string $obj_type, - string $class_name, - string $include_path - ) : SeparatedUnboundProvider; + /** + * Create a new separated unbound provider for the given owner. + * + * The provider will belong to objects above the $owner in the tree that also + * have the type $obj_type. + */ + public function createSeparatedUnboundProvider( + \ilObject $owner, + string $obj_type, + string $class_name, + string $include_path + ): SeparatedUnboundProvider; - /** - * Create a new shared unbound provider for the given owner. - * - * The provider will be belong to objects above the $owner in the tree that also - * have the type $obj_type. - */ - public function createSharedUnboundProvider( - \ilObject $owner, - string $obj_type, - string $class_name, - string $include_path - ) : SharedUnboundProvider; + /** + * Create a new shared unbound provider for the given owner. + * + * The provider will be belong to objects above the $owner in the tree that also + * have the type $obj_type. + */ + public function createSharedUnboundProvider( + \ilObject $owner, + string $obj_type, + string $class_name, + string $include_path + ): SharedUnboundProvider; - /** - * Load the unbound provider with the given id. - * @throws \InvalidArgumentException if the provider with the supplied id does not exist. - */ - public function load(int $id) : UnboundProvider; + /** + * Load the unbound provider with the given id. + * @throws \InvalidArgumentException if the provider with the supplied id does not exist. + */ + public function load(int $id): UnboundProvider; - /** - * Delete a given unbound provider. - */ - public function delete(UnboundProvider $provider, \ilObject $owner); + /** + * Delete a given unbound provider. + */ + public function delete(UnboundProvider $provider, \ilObject $owner); - /** - * Update the given unbound provider. - * - * The only thing that may be updated are the components that are provided. - */ - public function update(UnboundProvider $provider); + /** + * Update the given unbound provider. + * + * The only thing that may be updated are the components that are provided. + */ + public function update(UnboundProvider $provider); - /** - * Get all unbound providers of a given owner. - * @return UnboundProvider[] - */ - public function unboundProvidersOf(\ilObject $owner) : array; + /** + * Get all unbound providers of a given owner. + * @return UnboundProvider[] + */ + public function unboundProvidersOf(\ilObject $owner): array; - /** - * Get all providers for the given object. - * @return Provider[] - */ - public function providersFor( - \ilObject $object, - string $component_type = null - ) : array; + /** + * Get all providers for the given object. + * @return Provider[] + */ + public function providersFor( + \ilObject $object, + string $component_type = null + ): array; } diff --git a/src/ILIAS/Repository.php b/src/ILIAS/Repository.php index 04566d0..d0fd9ec 100644 --- a/src/ILIAS/Repository.php +++ b/src/ILIAS/Repository.php @@ -19,27 +19,27 @@ */ class Repository implements Ente\Repository { - use Ente\RepositoryHelper; + use Ente\RepositoryHelper; - /** - * @var ProviderDB - */ - private $provider_db; + /** + * @var ProviderDB + */ + private $provider_db; - public function __construct(ProviderDB $provider_db) - { - $this->provider_db = $provider_db; - } + public function __construct(ProviderDB $provider_db) + { + $this->provider_db = $provider_db; + } - /** - * @inheritdocs - */ - public function providersForEntity(Ente\Entity $entity, string $component_type = null) : array - { - // This can only return entities for ILIAS - if (!($entity instanceof Entity)) { - return []; - } - return $this->provider_db->providersFor($entity->object(), $component_type); - } + /** + * @inheritdocs + */ + public function providersForEntity(Ente\Entity $entity, string $component_type = null): array + { + // This can only return entities for ILIAS + if (!($entity instanceof Entity)) { + return []; + } + return $this->provider_db->providersFor($entity->object(), $component_type); + } } diff --git a/src/ILIAS/SeparatedUnboundProvider.php b/src/ILIAS/SeparatedUnboundProvider.php index 7859237..fb1ce49 100644 --- a/src/ILIAS/SeparatedUnboundProvider.php +++ b/src/ILIAS/SeparatedUnboundProvider.php @@ -20,75 +20,75 @@ */ abstract class SeparatedUnboundProvider implements UnboundProvider { - /** - * @var int - */ - private $id; + /** + * @var int + */ + private $id; - /** - * @var \ilObject - */ - private $owner; + /** + * @var \ilObject + */ + private $owner; - /** - * @var string - */ - private $object_type; + /** + * @var string + */ + private $object_type; - final public function __construct(int $id, \ilObject $owner, string $object_type) - { - $this->id = $id; - $this->owner = $owner; - $this->object_type = $object_type; - } + final public function __construct(int $id, \ilObject $owner, string $object_type) + { + $this->id = $id; + $this->owner = $owner; + $this->object_type = $object_type; + } - /** - * @inheritdocs - */ - abstract public function componentTypes(); + /** + * @inheritdocs + */ + abstract public function componentTypes(); - /** - * Build the component(s) of the given type for the given object. - * @return Component[] - */ - abstract public function buildComponentsOf(string $component_type, IEntity $entity) : array; + /** + * Build the component(s) of the given type for the given object. + * @return Component[] + */ + abstract public function buildComponentsOf(string $component_type, IEntity $entity): array; - /** - * @inheritdocs - */ - final public function idFor(\ilObject $owner) : int - { - if ($owner->getId() !== $this->owner->getId()) { - throw new \InvalidArgumentException( - "Object with id " - .$owner->getId() - ." is not the owner with id ".$this->owner->getId() - ); - } - return $this->id; - } + /** + * @inheritdocs + */ + final public function idFor(\ilObject $owner): int + { + if ($owner->getId() !== $this->owner->getId()) { + throw new \InvalidArgumentException( + "Object with id " + . $owner->getId() + . " is not the owner with id " . $this->owner->getId() + ); + } + return $this->id; + } - /** - * @inheritdocs - */ - final public function owners() : array - { - return [$this->owner]; - } + /** + * @inheritdocs + */ + final public function owners(): array + { + return [$this->owner]; + } - /** - * @inheritdocs - */ - final public function owner() : \ilObject - { - return $this->owner; - } + /** + * @inheritdocs + */ + final public function owner(): \ilObject + { + return $this->owner; + } - /** - * @inheritdocs - */ - final public function objectType() : string - { - return $this->object_type; - } + /** + * @inheritdocs + */ + final public function objectType(): string + { + return $this->object_type; + } } diff --git a/src/ILIAS/SharedUnboundProvider.php b/src/ILIAS/SharedUnboundProvider.php index 0f101dd..a2c763c 100644 --- a/src/ILIAS/SharedUnboundProvider.php +++ b/src/ILIAS/SharedUnboundProvider.php @@ -21,71 +21,71 @@ */ abstract class SharedUnboundProvider implements UnboundProvider { - /** - * @var \ilObject[] - */ - private $owners; + /** + * @var \ilObject[] + */ + private $owners; - /** - * @var array - */ - private $ids; + /** + * @var array + */ + private $ids; - /** - * @var string - */ - private $object_type; + /** + * @var string + */ + private $object_type; - final public function __construct(array $owners, string $object_type) - { - $this->owners = []; - $this->ids = []; - foreach($owners as $id => $owner) { - assert('is_int($id)'); - assert('$owner instanceof \ilObject'); - $this->owners[] = $owner; - $this->ids[$owner->getId()] = $id; - } - $this->object_type = $object_type; - } + final public function __construct(array $owners, string $object_type) + { + $this->owners = []; + $this->ids = []; + foreach ($owners as $id => $owner) { + assert('is_int($id)'); + assert('$owner instanceof \ilObject'); + $this->owners[] = $owner; + $this->ids[$owner->getId()] = $id; + } + $this->object_type = $object_type; + } - /** - * @inheritdocs - */ - abstract public function componentTypes(); + /** + * @inheritdocs + */ + abstract public function componentTypes(); - /** - * Build the component(s) of the given type for the given object. - * @return Component[] - */ - abstract public function buildComponentsOf(string $component_type, IEntity $entity) : array; + /** + * Build the component(s) of the given type for the given object. + * @return Component[] + */ + abstract public function buildComponentsOf(string $component_type, IEntity $entity): array; - /** - * @inheritdocs - */ - final public function idFor(\ilObject $owner) : int - { - $id = $owner->getId(); - if (!isset($this->ids[$id])) { - throw new \InvalidArgumentException( - "Object with id ".$owner->getId()." is not an owner"); - } - return (int)$this->ids[$id]; - } + /** + * @inheritdocs + */ + final public function idFor(\ilObject $owner): int + { + $id = $owner->getId(); + if (!isset($this->ids[$id])) { + throw new \InvalidArgumentException( + "Object with id " . $owner->getId() . " is not an owner"); + } + return (int)$this->ids[$id]; + } - /** - * @inheritdocs - */ - final public function owners() : array - { - return $this->owners; - } + /** + * @inheritdocs + */ + final public function owners(): array + { + return $this->owners; + } - /** - * @inheritdocs - */ - final public function objectType() :string - { - return $this->object_type; - } + /** + * @inheritdocs + */ + final public function objectType(): string + { + return $this->object_type; + } } diff --git a/src/ILIAS/UnboundProvider.php b/src/ILIAS/UnboundProvider.php index c2ad25b..fb42bda 100644 --- a/src/ILIAS/UnboundProvider.php +++ b/src/ILIAS/UnboundProvider.php @@ -21,35 +21,35 @@ */ interface UnboundProvider { - /** - * @inheritdocs - */ - public function componentTypes(); - - /** - * Build the component(s) of the given type for the given object. - * @return Component[] - */ - public function buildComponentsOf(string $component_type, IEntity $entity) : array; - - /** - * Get the id of this provider for the given owner. - * - * @throws \InvalidArgumentException if $owner is not an owner of this provider - */ - public function idFor(\ilObject $owner) : int; - - /** - * Get the owner object of the component. - * - * @return \ilObject[] - */ - public function owners() : array; - - /** - * Get the object type this binds to. - * - * @return string - */ - public function objectType() : string; + /** + * @inheritdocs + */ + public function componentTypes(); + + /** + * Build the component(s) of the given type for the given object. + * @return Component[] + */ + public function buildComponentsOf(string $component_type, IEntity $entity): array; + + /** + * Get the id of this provider for the given owner. + * + * @throws \InvalidArgumentException if $owner is not an owner of this provider + */ + public function idFor(\ilObject $owner): int; + + /** + * Get the owner object of the component. + * + * @return \ilObject[] + */ + public function owners(): array; + + /** + * Get the object type this binds to. + * + * @return string + */ + public function objectType(): string; } diff --git a/src/ILIAS/ilCachesOwnerRangeProviderDB.php b/src/ILIAS/ilCachesOwnerRangeProviderDB.php index ca92ea7..520aa77 100644 --- a/src/ILIAS/ilCachesOwnerRangeProviderDB.php +++ b/src/ILIAS/ilCachesOwnerRangeProviderDB.php @@ -17,205 +17,218 @@ */ class ilCachesOwnerRangeProviderDB extends ilProviderDB { - /** - * @var Cache - */ - protected $cache; - - /** - * @var int - */ - protected $shard_size; - - /** - * @var array - */ - protected $shards; - - /** - * @var \ilDBInterface - */ - private $ilDB; - - public function __construct( - \ilDBInterface $ilDB, - \ilTree $tree, - \ilObjectDataCache $obj_cache, - Cache $cache, - int $shard_size = 1000 - ) { - parent::__construct($ilDB, $tree, $obj_cache); - $this->ilDB = $ilDB; - $this->cache = $cache; - $this->shard_size = $shard_size; - $this->shards = []; - } - - /** - * @inheritdocs - */ - public function createSeparatedUnboundProvider( - \ilObject $owner, - string $object_type, - string $class_name, - string $include_path - ) : SeparatedUnboundProvider { - $res = parent::createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); - $this->refreshShardOf($owner->getId()); - return $res; - } - - /** - * @inheritdocs - */ - public function createSharedUnboundProvider( - \ilObject $owner, - string $object_type, - string $class_name, - string $include_path - ) : SharedUnboundProvider { - $res = parent::createSharedUnboundProvider($owner, $object_type, $class_name, $include_path); - $this->refreshShardOf($owner->getId()); - return $res; - } - - /** - * @inheritdocs - */ - public function delete(UnboundProvider $provider, \ilObject $owner) { - parent::delete($provider, $owner); - $this->refreshShardOf($owner->getId()); - } - - protected function getSeperatedUnboundProviderDataOf( - array $node_ids, - string $object_type, - string $component_type = null - ) : iterable { - if ($component_type !== null) { - return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); - } - - $ret = []; - foreach($node_ids as $node_id) { - $ret[] = $this->getDataOf($node_id, $object_type, "separated", $component_type); - } - return call_user_func_array("array_merge", $ret); - } - - protected function getSharedUnboundProviderDataOf( - array $node_ids, - string $object_type, - string $component_type = null - ) : iterable { - if ($component_type !== null) { - return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); - } - - $data = []; - foreach($node_ids as $node_id) { - $ds = $this->getDataOf($node_id, $object_type, "shared"); - foreach ($ds as $d) { - $key = $d["class_name"]." ".$d["include_path"]; - if(!isset($data[$key])) { - $data[$key] = [ - "owners" => [], - "ids" => [], - "class_name" => $d["class_name"], - "include_path" => $d["include_path"] - ]; - } - $data[$key]["owners"][] = $d["owner"]; - $data[$key]["ids"][] = $d["id"]; - } - } - return array_values($data); - } - - protected function refreshShardOf(int $node_id) { - $shard_id = $this->getShardIdOf($node_id); - return $this->refreshShard($shard_id); - } - - protected function refreshShard(int $shard_id) { - unset($this->shards[$shard_id]); - $data = $this->loadShardDataFromDB($shard_id); - // For some reason we get a null in maybeLoadShardDataFromCache if the array - // is completely empty. This produces (wrong) cache misses. To prevent them - // we set this key. - $data["i am"] = "here"; - $this->shards[$shard_id] = $data; - $this->cache->set("$shard_id", $data); - } - - protected function getDataOf(int $node_id, string $object_type, string $which) { - $shard_id = $this->getShardIdOf($node_id); - $this->maybeLoadShardDataFromCache($shard_id); - if (!isset($this->shards[$shard_id][$node_id][$object_type])) { - return []; - } - return $this->shards[$shard_id][$node_id][$object_type][$which]; - } - - protected function getShardIdOf(int $node_id) { - return (int)floor($node_id/$this->shard_size); - } - - protected function maybeLoadShardDataFromCache(int $shard_id) { - if (isset($this->shards[$shard_id])) { - return; - } - $data = $this->cache->get("$shard_id"); - if ($data !== null) { - $this->shards[$shard_id] = $data; - return; - } - $this->refreshShard($shard_id); - } - - protected function loadShardDataFromDB($shard_id) { - $data = []; - $l = $shard_id * $this->shard_size; - $r = ($shard_id + 1) * $this->shard_size; - foreach ($this->getUnboundProviderDataOf($l, $r) as $d) { - $owner = $d["owner"]; - $object_type = $d["object_type"]; - if (!isset($data[$owner])) { - $data[$owner] = []; - } - if (!isset($data[$owner][$object_type])) { - $data[$owner][$object_type] = [ "separated" => [], "shared" => []]; - } - $data[$owner][$object_type][$d["which"]][] = $d; - } - return $data; - } - - protected function getUnboundProviderDataOf(int $left, int $right) : \Iterator - { - assert($left < $right); - assert($right - $left > 0); - $query = $this->buildUnboundProviderQueryForObjects($left, $right); - $res = $this->ilDB->query($query); - while ($row = $this->ilDB->fetchAssoc($res)) { - yield [ - "id" => (int)$row["id"], - "owner" => (int)$row["owner"], - "class_name" => $row["class_name"], - "include_path" => $row["include_path"], - "object_type" => $row["object_type"], - "which" => $row["shared"] == 0 ? "separated" : "shared" - ]; - } - } - - protected function buildUnboundProviderQueryForObjects(int $left, int $right) : string { - assert($left < $right); - assert($right - $left > 0); - return - "SELECT id, owner, class_name, include_path, object_type, shared ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE owner >= ".$this->ilDB->quote($left, "integer"). - " AND owner < ".$this->ilDB->quote($right, "integer"); - } + /** + * @var Cache + */ + protected $cache; + + /** + * @var int + */ + protected $shard_size; + + /** + * @var array + */ + protected $shards; + + /** + * @var \ilDBInterface + */ + private $ilDB; + + public function __construct( + \ilDBInterface $ilDB, + \ilTree $tree, + \ilObjectDataCache $obj_cache, + Cache $cache, + int $shard_size = 1000 + ) + { + parent::__construct($ilDB, $tree, $obj_cache); + $this->ilDB = $ilDB; + $this->cache = $cache; + $this->shard_size = $shard_size; + $this->shards = []; + } + + /** + * @inheritdocs + */ + public function createSeparatedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ): SeparatedUnboundProvider + { + $res = parent::createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); + $this->refreshShardOf($owner->getId()); + return $res; + } + + /** + * @inheritdocs + */ + public function createSharedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ): SharedUnboundProvider + { + $res = parent::createSharedUnboundProvider($owner, $object_type, $class_name, $include_path); + $this->refreshShardOf($owner->getId()); + return $res; + } + + /** + * @inheritdocs + */ + public function delete(UnboundProvider $provider, \ilObject $owner) + { + parent::delete($provider, $owner); + $this->refreshShardOf($owner->getId()); + } + + protected function getSeperatedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ): iterable + { + if ($component_type !== null) { + return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); + } + + $ret = []; + foreach ($node_ids as $node_id) { + $ret[] = $this->getDataOf($node_id, $object_type, "separated", $component_type); + } + return call_user_func_array("array_merge", $ret); + } + + protected function getSharedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ): iterable + { + if ($component_type !== null) { + return parent::getSharedUnboundProviderDataOf($node_ids, $object_type, $component_type); + } + + $data = []; + foreach ($node_ids as $node_id) { + $ds = $this->getDataOf($node_id, $object_type, "shared"); + foreach ($ds as $d) { + $key = $d["class_name"] . " " . $d["include_path"]; + if (!isset($data[$key])) { + $data[$key] = [ + "owners" => [], + "ids" => [], + "class_name" => $d["class_name"], + "include_path" => $d["include_path"] + ]; + } + $data[$key]["owners"][] = $d["owner"]; + $data[$key]["ids"][] = $d["id"]; + } + } + return array_values($data); + } + + protected function refreshShardOf(int $node_id) + { + $shard_id = $this->getShardIdOf($node_id); + return $this->refreshShard($shard_id); + } + + protected function refreshShard(int $shard_id) + { + unset($this->shards[$shard_id]); + $data = $this->loadShardDataFromDB($shard_id); + // For some reason we get a null in maybeLoadShardDataFromCache if the array + // is completely empty. This produces (wrong) cache misses. To prevent them + // we set this key. + $data["i am"] = "here"; + $this->shards[$shard_id] = $data; + $this->cache->set("$shard_id", $data); + } + + protected function getDataOf(int $node_id, string $object_type, string $which) + { + $shard_id = $this->getShardIdOf($node_id); + $this->maybeLoadShardDataFromCache($shard_id); + if (!isset($this->shards[$shard_id][$node_id][$object_type])) { + return []; + } + return $this->shards[$shard_id][$node_id][$object_type][$which]; + } + + protected function getShardIdOf(int $node_id) + { + return (int)floor($node_id / $this->shard_size); + } + + protected function maybeLoadShardDataFromCache(int $shard_id) + { + if (isset($this->shards[$shard_id])) { + return; + } + $data = $this->cache->get("$shard_id"); + if ($data !== null) { + $this->shards[$shard_id] = $data; + return; + } + $this->refreshShard($shard_id); + } + + protected function loadShardDataFromDB($shard_id) + { + $data = []; + $l = $shard_id * $this->shard_size; + $r = ($shard_id + 1) * $this->shard_size; + foreach ($this->getUnboundProviderDataOf($l, $r) as $d) { + $owner = $d["owner"]; + $object_type = $d["object_type"]; + if (!isset($data[$owner])) { + $data[$owner] = []; + } + if (!isset($data[$owner][$object_type])) { + $data[$owner][$object_type] = ["separated" => [], "shared" => []]; + } + $data[$owner][$object_type][$d["which"]][] = $d; + } + return $data; + } + + protected function getUnboundProviderDataOf(int $left, int $right): \Iterator + { + assert($left < $right); + assert($right - $left > 0); + $query = $this->buildUnboundProviderQueryForObjects($left, $right); + $res = $this->ilDB->query($query); + while ($row = $this->ilDB->fetchAssoc($res)) { + yield [ + "id" => (int)$row["id"], + "owner" => (int)$row["owner"], + "class_name" => $row["class_name"], + "include_path" => $row["include_path"], + "object_type" => $row["object_type"], + "which" => $row["shared"] == 0 ? "separated" : "shared" + ]; + } + } + + protected function buildUnboundProviderQueryForObjects(int $left, int $right): string + { + assert($left < $right); + assert($right - $left > 0); + return + "SELECT id, owner, class_name, include_path, object_type, shared " . + "FROM " . ilProviderDB::PROVIDER_TABLE . " " . + "WHERE owner >= " . $this->ilDB->quote($left, "integer") . + " AND owner < " . $this->ilDB->quote($right, "integer"); + } } diff --git a/src/ILIAS/ilGlobalCache.php b/src/ILIAS/ilGlobalCache.php index fa38905..04cf7c2 100644 --- a/src/ILIAS/ilGlobalCache.php +++ b/src/ILIAS/ilGlobalCache.php @@ -17,45 +17,45 @@ */ class ilGlobalCache implements Cache { - /** - * @var \ilGlobalCache - */ - protected $il_global_cache; - - /** - * @var int|null - */ - protected $ttl_in_seconds; - - const PREFIX = "tms_ente_"; - - public function __construct(\ilGlobalCache $cache, int $ttl_in_seconds = null) - { - $this->il_global_cache = $cache; - $this->ttl_in_seconds = $ttl_in_seconds; - } - - /** - * @inheritDoc - */ - public function set(string $key, array $value) - { - return $this->il_global_cache->set(self::PREFIX.$key, $value); - } - - /** - * @inheritDoc - */ - public function get(string $key) - { - return $this->il_global_cache->get(self::PREFIX.$key); - } - - /** - * @inheritDoc - */ - public function delete(string $key) - { - $this->il_global_cache->delete(self::PREFIX.$key); - } + /** + * @var \ilGlobalCache + */ + protected $il_global_cache; + + /** + * @var int|null + */ + protected $ttl_in_seconds; + + const PREFIX = "tms_ente_"; + + public function __construct(\ilGlobalCache $cache, int $ttl_in_seconds = null) + { + $this->il_global_cache = $cache; + $this->ttl_in_seconds = $ttl_in_seconds; + } + + /** + * @inheritDoc + */ + public function set(string $key, array $value) + { + return $this->il_global_cache->set(self::PREFIX . $key, $value); + } + + /** + * @inheritDoc + */ + public function get(string $key) + { + return $this->il_global_cache->get(self::PREFIX . $key); + } + + /** + * @inheritDoc + */ + public function delete(string $key) + { + $this->il_global_cache->delete(self::PREFIX . $key); + } } diff --git a/src/ILIAS/ilHandlerObjectHelper.php b/src/ILIAS/ilHandlerObjectHelper.php index 314482b..f8470c3 100644 --- a/src/ILIAS/ilHandlerObjectHelper.php +++ b/src/ILIAS/ilHandlerObjectHelper.php @@ -21,58 +21,60 @@ */ trait ilHandlerObjectHelper { - use ilObjectHelper; + use ilObjectHelper; - /** - * Get a repository for providers and components. - * - * @return \CaT\Ente\Repository - */ - protected function getRepository() { - $DIC = $this->getDIC(); - if (!isset($DIC["ente.repository"])) { - $DIC["ente.repository"] = function ($c) { - return new CachedRepository( - new Repository($c["ente.provider_db"]) - ); - }; - } - return $DIC["ente.repository"]; - } + /** + * Get a repository for providers and components. + * + * @return \CaT\Ente\Repository + */ + protected function getRepository() + { + $DIC = $this->getDIC(); + if (!isset($DIC["ente.repository"])) { + $DIC["ente.repository"] = function ($c) { + return new CachedRepository( + new Repository($c["ente.provider_db"]) + ); + }; + } + return $DIC["ente.repository"]; + } - /** - * Get components for the entity. - * - * @return IComponent[] - */ - protected function getComponents() { - $repository = $this->getRepository(); - return $repository->componentsForEntity($this->getEntity()); - } + /** + * Get components for the entity. + * + * @return IComponent[] + */ + protected function getComponents() + { + $repository = $this->getRepository(); + return $repository->componentsForEntity($this->getEntity()); + } - /** - * @return IComponent[] - */ - protected function getComponentsOfType(string $component_type) : array - { - $repository = $this->getRepository(); - return $repository->componentsForEntity($this->getEntity(), $component_type); - } + /** + * @return IComponent[] + */ + protected function getComponentsOfType(string $component_type): array + { + $repository = $this->getRepository(); + return $repository->componentsForEntity($this->getEntity(), $component_type); + } - /** - * Get the entity this object handles components for. - */ - protected function getEntity() : IEntity - { - return new Entity( - \ilObjectFactory::getInstanceByRefId( - $this->getEntityRefId() - ) - ); - } + /** + * Get the entity this object handles components for. + */ + protected function getEntity(): IEntity + { + return new Entity( + \ilObjectFactory::getInstanceByRefId( + $this->getEntityRefId() + ) + ); + } - /** - * Get the ref_id of the object this object handles components for. - */ - abstract protected function getEntityRefId() : int; + /** + * Get the ref_id of the object this object handles components for. + */ + abstract protected function getEntityRefId(): int; } diff --git a/src/ILIAS/ilObjectHelper.php b/src/ILIAS/ilObjectHelper.php index aaa59f5..8003838 100644 --- a/src/ILIAS/ilObjectHelper.php +++ b/src/ILIAS/ilObjectHelper.php @@ -21,26 +21,26 @@ */ trait ilObjectHelper { - /** - * @return Ente\ILIAS\ProviderDB - */ - protected function getProviderDB() : Ente\ILIAS\ProviderDB - { - $DIC = $this->getDIC(); - if (!isset($DIC["ente.provider_db"])) { - $DIC["ente.provider_db"] = new Ente\ILIAS\ilProviderDB( - $DIC["ilDB"], - $DIC["tree"], - $DIC["ilObjDataCache"] - ); - } - return $DIC["ente.provider_db"]; - } + /** + * @return Ente\ILIAS\ProviderDB + */ + protected function getProviderDB(): Ente\ILIAS\ProviderDB + { + $DIC = $this->getDIC(); + if (!isset($DIC["ente.provider_db"])) { + $DIC["ente.provider_db"] = new Ente\ILIAS\ilProviderDB( + $DIC["ilDB"], + $DIC["tree"], + $DIC["ilObjDataCache"] + ); + } + return $DIC["ente.provider_db"]; + } - /** - * Get the ILIAS DIC. - * - * @return \ArrayAccess - */ - abstract protected function getDIC(); + /** + * Get the ILIAS DIC. + * + * @return \ArrayAccess + */ + abstract protected function getDIC(); } diff --git a/src/ILIAS/ilProviderDB.php b/src/ILIAS/ilProviderDB.php index 0c119be..4ad76ab 100644 --- a/src/ILIAS/ilProviderDB.php +++ b/src/ILIAS/ilProviderDB.php @@ -17,648 +17,658 @@ */ class ilProviderDB implements ProviderDB { - const PROVIDER_TABLE = "ente_prvs"; - const COMPONENT_TABLE = "ente_prv_cmps"; - - const CLASS_NAME_LENGTH = 128; - const PATH_LENGTH = 1024; - - /** - * @var \ilDBInterface - */ - private $ilDB; - - /** - * @var \ilTree - */ - private $ilTree; - - /** - * @var \ilObjectDataCache - */ - private $ilObjectDataCache; - - public function __construct(\ilDBInterface $ilDB, \ilTree $tree, \ilObjectDataCache $cache) - { - $this->ilDB = $ilDB; - $this->ilTree = $tree; - $this->ilObjectDataCache = $cache; - } - - /** - * @inheritdocs - */ - public function createSeparatedUnboundProvider( - \ilObject $owner, - string $object_type, - string $class_name, - string $include_path - ) : SeparatedUnboundProvider { - $this->validateCreationParams($object_type, $class_name, $include_path); - $shared = false; - list($unbound_provider, $id) = $this->createUnboundProvider( - $owner, - $object_type, - $class_name, - $include_path, - $shared - ); - $this->createComponentsForUnboundProvider($unbound_provider, $id); - return $unbound_provider; - } - - /** - * @inheritdocs - */ - public function createSharedUnboundProvider( - \ilObject $owner, - string $object_type, - string $class_name, - string $include_path - ) : SharedUnboundProvider { - $this->validateCreationParams($object_type, $class_name, $include_path); - $shared = true; - list($unbound_provider, $id) = $this->createUnboundProvider( - $owner, - $object_type, - $class_name, - $include_path, - $shared - ); - $this->createComponentsForUnboundProvider($unbound_provider, $id); - return $unbound_provider; - } - - /** - * @return array(UnboundProvider, int) - */ - private function createUnboundProvider( - \ilObject $owner, - string $object_type, - string $class_name, - string $include_path, - bool $shared - ) : array { - // TODO: check if class exist first - $id = (int)$this->ilDB->nextId(ilProviderDB::PROVIDER_TABLE); - $this->ilDB->insert( - ilProviderDB::PROVIDER_TABLE, - [ - "id" => ["integer", $id], - "owner" => ["integer", $owner->getId()], - "object_type" => ["string", $object_type], - "class_name" => ["string", $class_name], - "include_path" => ["string", $include_path], - "shared" => ["integer", $shared] - ] - ); - - if($shared===true) { - $unbound_provider = $this->buildSharedUnboundProvider( - array($id=>$owner), - $class_name, - $class_name, - $include_path - ); - } else { - $unbound_provider = $this->buildSeparatedUnboundProvider( - $id, - $owner, - $class_name, - $class_name, - $include_path - ); - } - return array($unbound_provider, $id); - } - - - /** - * @throws \LogicException if any parameter is out of bounds - */ - private function validateCreationParams( - string $object_type, - string $class_name, - string $include_path - ) { - if (strlen($object_type) > 4) { - throw new \LogicException( - "Expected object type '$object_type' to have four or less chars." - ); - } - if (strlen($class_name) > ilProviderDB::CLASS_NAME_LENGTH) { - throw new \LogicException( - "Expected class name '$class_name' to have at most " - .ilProviderDB::CLASS_NAME_LENGTH." chars."); - } - if (strlen($include_path) > ilProviderDB::PATH_LENGTH) { - throw new \LogicException( - "Expected include path '$include_path' to have at most " - .ilProviderDB::PATH_LENGTH." chars."); - } - } - - /** - * @throws \LogicException if class_name of component is out of bounds - */ - private function createComponentsForUnboundProvider(UnboundProvider $unbound_provider, int $id) - { - foreach ($unbound_provider->componentTypes() as $component_type) { - if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { - throw new \LogicException( - "Expected component type '$component_type' to have at most " - .ilProviderDB::CLASS_NAME_LENGTH." chars." - ); - } - $this->ilDB->insert( - ilProviderDB::COMPONENT_TABLE, - [ - "id" => ["integer", $id], - "component_type" => ["string", $component_type] - ] - ); - } - } - - /** - * @inheritdocs - */ - public function load(int $id) : UnboundProvider - { - assert('is_int($id)'); - - $query = - "SELECT owner, object_type, class_name, include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE id = ".$this->ilDB->quote($id, "integer"); - $res = $this->ilDB->query($query); - - if($row = $this->ilDB->fetchAssoc($res)) { - $owner = $this->buildObjectByObjId($row["owner"]); - return $this->buildSeparatedUnboundProvider( - $id, $owner, $row["object_type"], - $row["class_name"], - $row["include_path"] - ); - } - else { - throw new \InvalidArgumentException( - "Unbound provider with id '$id' does not exist." - ); - } - } - - /** - * @inheritdocs - */ - public function delete(UnboundProvider $provider, \ilObject $owner) - { - $id = $provider->idFor($owner); - $this->ilDB->manipulate( - "DELETE FROM ".ilProviderDB::PROVIDER_TABLE - ." WHERE id = ".$this->ilDB->quote($id, "integer") - ); - $this->ilDB->manipulate( - "DELETE FROM ".ilProviderDB::COMPONENT_TABLE - ." WHERE id = ".$this->ilDB->quote($id, "integer") - ); - } - - /** - * @inheritdocs - */ - public function update(UnboundProvider $provider) - { - $component_types = $provider->componentTypes(); - foreach ($provider->owners() as $owner) { - $id = $provider->idFor($owner); - $this->ilDB->manipulate( - "DELETE FROM ".ilProviderDB::COMPONENT_TABLE - ." WHERE id = ".$this->ilDB->quote($id, "integer") - ); - - foreach ($component_types as $component_type) { - if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { - throw new \LogicException( - "Expected component type '" - .$component_type."'' to have at most " - .ilProviderDB::CLASS_NAME_LENGTH." chars." - ); - } - $this->ilDB->insert( - ilProviderDB::COMPONENT_TABLE, - [ - "id" => ["integer", $id], - "component_type" => ["string", $component_type] - ] - ); - } - } - } - - /** - * @inheritdocs - */ - public function unboundProvidersOf(\ilObject $owner) : array - { - $ret = []; - - $query = - "SELECT id, object_type, class_name, include_path ". - "FROM ".ilProviderDB::PROVIDER_TABLE." ". - "WHERE owner = ".$this->ilDB->quote($owner->getId(), "integer"); - $res = $this->ilDB->query($query); - - while($row = $this->ilDB->fetchAssoc($res)) { - if( - is_subclass_of( - $row["class_name"], - 'CaT\Ente\ILIAS\SeparatedUnboundProvider' - ) - ) { - $ret[] = $this->buildSeparatedUnboundProvider( - (int)$row["id"], $owner, - $row["object_type"], - $row["class_name"], - $row["include_path"] - ); - } - if( - is_subclass_of( - $row["class_name"], - 'CaT\Ente\ILIAS\SharedUnboundProvider' - ) - ) { - $ret[] = $this->buildSharedUnboundProvider( - array($row["id"]=>$owner), - $row["object_type"], - $row["class_name"], - $row["include_path"] - ); - } - } - - return $ret; - } - - /** - * @inheritdocs - */ - public function providersFor( - \ilObject $object, - string $component_type = null - ) : array { - list($nodes_ids, $nodes_id_mapping) = $this->getSubtreeObjectIdsAndRefIdMapping( - (int)$object->getRefId() - ); - $object_type = $object->getType(); - - $ret = []; - - $provider_data = $this->getSeperatedUnboundProviderDataOf( - $nodes_ids, - $object_type, - $component_type - ); - foreach ($provider_data as $data) { - $obj_id = $data["owner"]; - $ref_id = $nodes_id_mapping[$obj_id]; - try { - $owner = $this->buildObjectByRefId($ref_id); - } - catch (\InvalidArgumentException $e) { - continue; - } - $ret[] = new Provider( - $object, - $this->buildSeparatedUnboundProvider( - $data["id"], - $owner, - $object_type, - $data["class_name"], - $data["include_path"] - ) - ); - } - - $provider_data = $this->getSharedUnboundProviderDataOf( - $nodes_ids, - $object_type, - $component_type - ); - foreach ($provider_data as $data) { - $owners = []; - foreach ($data["owners"] as $obj_id) { - $ref_id = $nodes_id_mapping[$obj_id]; - $prv_id = array_shift($data["ids"]); - try { - $owners[$prv_id] = $this->buildObjectByRefId($ref_id); - } - catch (\InvalidArgumentException $e) { - continue; - } - } - if (count($owners) > 0) { - $ret[] = new Provider( - $object, - $this->buildSharedUnboundProvider( - $owners, - $object_type, - $data["class_name"], - $data["include_path"] - ) - ); - } - } - - return $ret; - } - - /** - * Get the object ids of the subtree starting at and including $ref_id with - * a mapping from $obj_id to $ref_id. - * - * @return array [int[], array] - */ - protected function getSubtreeObjectIdsAndRefIdMapping(int $ref_id) : array - { - $sub_nodes_refs = $this->ilTree->getSubTreeIds($ref_id); - $all_nodes_refs = array_merge([$ref_id], $sub_nodes_refs); - $this->ilObjectDataCache->preloadReferenceCache($all_nodes_refs); - - $nodes_id_mapping = []; - $nodes_ids = []; - foreach ($all_nodes_refs as $ref_id) { - $id = $this->ilObjectDataCache->lookupObjId($ref_id); - $nodes_id_mapping[$id] = $ref_id; - $nodes_ids[] = $id; - } - return [$nodes_ids, $nodes_id_mapping]; - } - - protected function getSeperatedUnboundProviderDataOf( - array $node_ids, - string $object_type, - string $component_type = null - ) : iterable { - $query = $this->buildSeparatedUnboundProviderQueryForObjects( - $node_ids, - $object_type, - $component_type - ); - $res = $this->ilDB->query($query); - while ($row = $this->ilDB->fetchAssoc($res)) { - yield [ - "id" => (int)$row["id"], - "owner" => (int)$row["owner"], - "class_name" => $row["class_name"], - "include_path" => $row["include_path"] - ]; - } - } - - protected function getSharedUnboundProviderDataOf( - array $node_ids, - string $object_type, - string $component_type = null - ) : iterable { - $to_int_list = function ($r) { - return array_map(function($v) { return (int)$v; }, explode(",", $r)); - }; - $query = $this->buildSharedUnboundProviderQueryForObjects( - $node_ids, - $object_type, - $component_type - ); - $res = $this->ilDB->query($query); - while ($row = $this->ilDB->fetchAssoc($res)) { - yield [ - "owners" => $to_int_list($row["owners"]), - "ids" => $to_int_list($row["ids"]), - "class_name" => $row["class_name"], - "include_path" => $row["include_path"] - ]; - } - } - - protected function buildSeparatedUnboundProviderQueryForObjects( - array $node_ids, - string $object_type, - string $component_type = null - ) : string { - if ($component_type === null) { - return - "SELECT id, owner, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ".$this->ilDB->in("owner", $node_ids, false, "integer").PHP_EOL - ." AND object_type = ".$this->ilDB->quote($object_type,"string"); - } - else { - return - "SELECT prv.id, prv.owner, prv.class_name, prv.include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE." prv".PHP_EOL - ."JOIN ".ilProviderDB::COMPONENT_TABLE." cmp".PHP_EOL - ." ON prv.id = cmp.id".PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ".$this->ilDB->in("owner", $node_ids, false, "integer").PHP_EOL - ." AND object_type = ".$this->ilDB->quote($object_type, "string").PHP_EOL - ." AND component_type = ".$this->ilDB->quote($component_type, "string"); - } - } - - protected function buildSharedUnboundProviderQueryForObjects( - array $node_ids, - string $object_type, - string $component_type = null - ) : string { - if ($component_type === null) { - return - "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ".$this->ilDB->in("owner", $node_ids,false,"integer").PHP_EOL - ." AND object_type = ".$this->ilDB->quote($object_type, "string").PHP_EOL - ."GROUP BY class_name, include_path"; - } - else { - return - "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(prv.owner SEPARATOR \",\") owners,".PHP_EOL - ."prv.class_name, prv.include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE." prv".PHP_EOL - ."JOIN ".ilProviderDB::COMPONENT_TABLE." cmp".PHP_EOL - ." ON prv.id = cmp.id".PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ".$this->ilDB->in("owner", $node_ids,false,"integer").PHP_EOL - ." AND object_type = ".$this->ilDB->quote($object_type, "string").PHP_EOL - ." AND component_type = ".$this->ilDB->quote($component_type, "string").PHP_EOL - ."GROUP BY prv.class_name, prv.include_path"; - } - } - - public function createTables() { - if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { - $this->ilDB->createTable( - ilProviderDB::PROVIDER_TABLE, - [ - "id" => [ - "type" => "integer", - "length" => 4, - "notnull" => true - ], - "owner" => [ - "type" => "integer", - "length" => 4, - "notnull" => true - ], - "object_type" => [ - "type" => "text", - "length" => 4, - "notnull" => true - ], - "class_name" => [ - "type" => "text", - "length" => ilProviderDB::CLASS_NAME_LENGTH, - "notnull" => true - ], - "include_path" => [ - "type" => "text", - "length" => ilProviderDB::PATH_LENGTH, - "notnull" => true - ] - ] - ); - $this->ilDB->addPrimaryKey(ilProviderDB::PROVIDER_TABLE, ["id"]); - $this->ilDB->createSequence(ilProviderDB::PROVIDER_TABLE); - } - if (!$this->ilDB->tableExists(ilProviderDB::COMPONENT_TABLE)) { - $this->ilDB->createTable( - ilProviderDB::COMPONENT_TABLE, - [ - "id" => [ - "type" => "integer", - "length" => 4, - "notnull" => true - ], - "component_type" => [ - "type" => "text", - "length" => ilProviderDB::CLASS_NAME_LENGTH, - "notnull" => true - ] - ] - ); - $this->ilDB->addPrimaryKey( - ilProviderDB::COMPONENT_TABLE, - ["id", "component_type"] - ); - } - if (!$this->ilDB->tableColumnExists( - ilProviderDB::PROVIDER_TABLE, - "shared") - ) { - $this->ilDB->addTableColumn( - ilProviderDB::PROVIDER_TABLE, - "shared", - [ - "type" => "integer", - "length" => 1, - "notnull" => true, - "default" => 0 - ] - ); - $this->ilDB->addIndex( - ilProviderDB::PROVIDER_TABLE, - ["shared"], - "ids" - ); - } - } - - public function addIndizes() { - if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { - return; - } - $this->ilDB->addIndex( - ilProviderDB::PROVIDER_TABLE, - ["owner"], - "ido", - false - ); - } - - protected function buildSeparatedUnboundProvider( - int $id, - \ilObject $owner, - string $object_type, - string $class_name, - string $include_path - ) : UnboundProvider { - require_once($include_path); - - assert('class_exists($class_name)'); - if (!is_subclass_of($class_name, SeparatedUnboundProvider::class)) { - throw new \UnexpectedValueException( - "Class '$class_name' does not extend UnboundProvider." - ); - } - - return new $class_name($id, $owner, $object_type); - } - - protected function buildSharedUnboundProvider( - array $owners, - string $object_type, - string $class_name, - string $include_path - ) : UnboundProvider { - assert('count($owners) > 0'); - - require_once($include_path); - - assert('class_exists($class_name)'); - if (!is_subclass_of($class_name, SharedUnboundProvider::class)) { - throw new \UnexpectedValueException( - "Class '$class_name' does not extend UnboundProvider." - ); - } - - return new $class_name($owners, $object_type); - } - - /** - * Build an object by its reference id. - * - * @throws \InvalidArgumentException if object could not be build - */ - protected function buildObjectByRefId(int $ref_id) : \ilObject - { - $obj = \ilObjectFactory::getInstanceByRefId($ref_id, false); - if ($obj === false) { - throw new \InvalidArgumentException("Cannot build object with obj_id='$ref_id'"); - } - assert($obj instanceof \ilObject); - return $obj; - } - - /** - * Build an object by its object id. - * - * @throws \InvalidArgumentException if object could not be build - */ - protected function buildObjectByObjId(int $obj_id) : \ilObject - { - $obj = \ilObjectFactory::getInstanceByObjId($obj_id, false); - if ($obj === false) { - throw new \InvalidArgumentException("Cannot build object with obj_id='$obj_id'"); - } - assert($obj instanceof \ilObject); - return $obj; - } - - protected function getAllReferenceIdsFor(int $obj_id) : array - { - return \ilObject::_getAllReferences($obj_id); - } + const PROVIDER_TABLE = "ente_prvs"; + const COMPONENT_TABLE = "ente_prv_cmps"; + + const CLASS_NAME_LENGTH = 128; + const PATH_LENGTH = 1024; + + /** + * @var \ilDBInterface + */ + private $ilDB; + + /** + * @var \ilTree + */ + private $ilTree; + + /** + * @var \ilObjectDataCache + */ + private $ilObjectDataCache; + + public function __construct(\ilDBInterface $ilDB, \ilTree $tree, \ilObjectDataCache $cache) + { + $this->ilDB = $ilDB; + $this->ilTree = $tree; + $this->ilObjectDataCache = $cache; + } + + /** + * @inheritdocs + */ + public function createSeparatedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ): SeparatedUnboundProvider + { + $this->validateCreationParams($object_type, $class_name, $include_path); + $shared = false; + list($unbound_provider, $id) = $this->createUnboundProvider( + $owner, + $object_type, + $class_name, + $include_path, + $shared + ); + $this->createComponentsForUnboundProvider($unbound_provider, $id); + return $unbound_provider; + } + + /** + * @inheritdocs + */ + public function createSharedUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ): SharedUnboundProvider + { + $this->validateCreationParams($object_type, $class_name, $include_path); + $shared = true; + list($unbound_provider, $id) = $this->createUnboundProvider( + $owner, + $object_type, + $class_name, + $include_path, + $shared + ); + $this->createComponentsForUnboundProvider($unbound_provider, $id); + return $unbound_provider; + } + + /** + * @return array(UnboundProvider, int) + */ + private function createUnboundProvider( + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path, + bool $shared + ): array + { + // TODO: check if class exist first + $id = (int)$this->ilDB->nextId(ilProviderDB::PROVIDER_TABLE); + $this->ilDB->insert( + ilProviderDB::PROVIDER_TABLE, + [ + "id" => ["integer", $id], + "owner" => ["integer", $owner->getId()], + "object_type" => ["string", $object_type], + "class_name" => ["string", $class_name], + "include_path" => ["string", $include_path], + "shared" => ["integer", $shared] + ] + ); + + if ($shared === true) { + $unbound_provider = $this->buildSharedUnboundProvider( + array($id => $owner), + $class_name, + $class_name, + $include_path + ); + } else { + $unbound_provider = $this->buildSeparatedUnboundProvider( + $id, + $owner, + $class_name, + $class_name, + $include_path + ); + } + return array($unbound_provider, $id); + } + + + /** + * @throws \LogicException if any parameter is out of bounds + */ + private function validateCreationParams( + string $object_type, + string $class_name, + string $include_path + ) + { + if (strlen($object_type) > 4) { + throw new \LogicException( + "Expected object type '$object_type' to have four or less chars." + ); + } + if (strlen($class_name) > ilProviderDB::CLASS_NAME_LENGTH) { + throw new \LogicException( + "Expected class name '$class_name' to have at most " + . ilProviderDB::CLASS_NAME_LENGTH . " chars."); + } + if (strlen($include_path) > ilProviderDB::PATH_LENGTH) { + throw new \LogicException( + "Expected include path '$include_path' to have at most " + . ilProviderDB::PATH_LENGTH . " chars."); + } + } + + /** + * @throws \LogicException if class_name of component is out of bounds + */ + private function createComponentsForUnboundProvider(UnboundProvider $unbound_provider, int $id) + { + foreach ($unbound_provider->componentTypes() as $component_type) { + if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { + throw new \LogicException( + "Expected component type '$component_type' to have at most " + . ilProviderDB::CLASS_NAME_LENGTH . " chars." + ); + } + $this->ilDB->insert( + ilProviderDB::COMPONENT_TABLE, + [ + "id" => ["integer", $id], + "component_type" => ["string", $component_type] + ] + ); + } + } + + /** + * @inheritdocs + */ + public function load(int $id): UnboundProvider + { + assert('is_int($id)'); + + $query = + "SELECT owner, object_type, class_name, include_path " . + "FROM " . ilProviderDB::PROVIDER_TABLE . " " . + "WHERE id = " . $this->ilDB->quote($id, "integer"); + $res = $this->ilDB->query($query); + + if ($row = $this->ilDB->fetchAssoc($res)) { + $owner = $this->buildObjectByObjId($row["owner"]); + return $this->buildSeparatedUnboundProvider( + $id, $owner, $row["object_type"], + $row["class_name"], + $row["include_path"] + ); + } else { + throw new \InvalidArgumentException( + "Unbound provider with id '$id' does not exist." + ); + } + } + + /** + * @inheritdocs + */ + public function delete(UnboundProvider $provider, \ilObject $owner) + { + $id = $provider->idFor($owner); + $this->ilDB->manipulate( + "DELETE FROM " . ilProviderDB::PROVIDER_TABLE + . " WHERE id = " . $this->ilDB->quote($id, "integer") + ); + $this->ilDB->manipulate( + "DELETE FROM " . ilProviderDB::COMPONENT_TABLE + . " WHERE id = " . $this->ilDB->quote($id, "integer") + ); + } + + /** + * @inheritdocs + */ + public function update(UnboundProvider $provider) + { + $component_types = $provider->componentTypes(); + foreach ($provider->owners() as $owner) { + $id = $provider->idFor($owner); + $this->ilDB->manipulate( + "DELETE FROM " . ilProviderDB::COMPONENT_TABLE + . " WHERE id = " . $this->ilDB->quote($id, "integer") + ); + + foreach ($component_types as $component_type) { + if (strlen($component_type) > ilProviderDB::CLASS_NAME_LENGTH) { + throw new \LogicException( + "Expected component type '" + . $component_type . "'' to have at most " + . ilProviderDB::CLASS_NAME_LENGTH . " chars." + ); + } + $this->ilDB->insert( + ilProviderDB::COMPONENT_TABLE, + [ + "id" => ["integer", $id], + "component_type" => ["string", $component_type] + ] + ); + } + } + } + + /** + * @inheritdocs + */ + public function unboundProvidersOf(\ilObject $owner): array + { + $ret = []; + + $query = + "SELECT id, object_type, class_name, include_path " . + "FROM " . ilProviderDB::PROVIDER_TABLE . " " . + "WHERE owner = " . $this->ilDB->quote($owner->getId(), "integer"); + $res = $this->ilDB->query($query); + + while ($row = $this->ilDB->fetchAssoc($res)) { + if ( + is_subclass_of( + $row["class_name"], + 'CaT\Ente\ILIAS\SeparatedUnboundProvider' + ) + ) { + $ret[] = $this->buildSeparatedUnboundProvider( + (int)$row["id"], $owner, + $row["object_type"], + $row["class_name"], + $row["include_path"] + ); + } + if ( + is_subclass_of( + $row["class_name"], + 'CaT\Ente\ILIAS\SharedUnboundProvider' + ) + ) { + $ret[] = $this->buildSharedUnboundProvider( + array($row["id"] => $owner), + $row["object_type"], + $row["class_name"], + $row["include_path"] + ); + } + } + + return $ret; + } + + /** + * @inheritdocs + */ + public function providersFor( + \ilObject $object, + string $component_type = null + ): array + { + list($nodes_ids, $nodes_id_mapping) = $this->getSubtreeObjectIdsAndRefIdMapping( + (int)$object->getRefId() + ); + $object_type = $object->getType(); + + $ret = []; + + $provider_data = $this->getSeperatedUnboundProviderDataOf( + $nodes_ids, + $object_type, + $component_type + ); + foreach ($provider_data as $data) { + $obj_id = $data["owner"]; + $ref_id = $nodes_id_mapping[$obj_id]; + try { + $owner = $this->buildObjectByRefId($ref_id); + } catch (\InvalidArgumentException $e) { + continue; + } + $ret[] = new Provider( + $object, + $this->buildSeparatedUnboundProvider( + $data["id"], + $owner, + $object_type, + $data["class_name"], + $data["include_path"] + ) + ); + } + + $provider_data = $this->getSharedUnboundProviderDataOf( + $nodes_ids, + $object_type, + $component_type + ); + foreach ($provider_data as $data) { + $owners = []; + foreach ($data["owners"] as $obj_id) { + $ref_id = $nodes_id_mapping[$obj_id]; + $prv_id = array_shift($data["ids"]); + try { + $owners[$prv_id] = $this->buildObjectByRefId($ref_id); + } catch (\InvalidArgumentException $e) { + continue; + } + } + if (count($owners) > 0) { + $ret[] = new Provider( + $object, + $this->buildSharedUnboundProvider( + $owners, + $object_type, + $data["class_name"], + $data["include_path"] + ) + ); + } + } + + return $ret; + } + + /** + * Get the object ids of the subtree starting at and including $ref_id with + * a mapping from $obj_id to $ref_id. + * + * @return array [int[], array] + */ + protected function getSubtreeObjectIdsAndRefIdMapping(int $ref_id): array + { + $sub_nodes_refs = $this->ilTree->getSubTreeIds($ref_id); + $all_nodes_refs = array_merge([$ref_id], $sub_nodes_refs); + $this->ilObjectDataCache->preloadReferenceCache($all_nodes_refs); + + $nodes_id_mapping = []; + $nodes_ids = []; + foreach ($all_nodes_refs as $ref_id) { + $id = $this->ilObjectDataCache->lookupObjId($ref_id); + $nodes_id_mapping[$id] = $ref_id; + $nodes_ids[] = $id; + } + return [$nodes_ids, $nodes_id_mapping]; + } + + protected function getSeperatedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ): iterable + { + $query = $this->buildSeparatedUnboundProviderQueryForObjects( + $node_ids, + $object_type, + $component_type + ); + $res = $this->ilDB->query($query); + while ($row = $this->ilDB->fetchAssoc($res)) { + yield [ + "id" => (int)$row["id"], + "owner" => (int)$row["owner"], + "class_name" => $row["class_name"], + "include_path" => $row["include_path"] + ]; + } + } + + protected function getSharedUnboundProviderDataOf( + array $node_ids, + string $object_type, + string $component_type = null + ): iterable + { + $to_int_list = function ($r) { + return array_map(function ($v) { + return (int)$v; + }, explode(",", $r)); + }; + $query = $this->buildSharedUnboundProviderQueryForObjects( + $node_ids, + $object_type, + $component_type + ); + $res = $this->ilDB->query($query); + while ($row = $this->ilDB->fetchAssoc($res)) { + yield [ + "owners" => $to_int_list($row["owners"]), + "ids" => $to_int_list($row["ids"]), + "class_name" => $row["class_name"], + "include_path" => $row["include_path"] + ]; + } + } + + protected function buildSeparatedUnboundProviderQueryForObjects( + array $node_ids, + string $object_type, + string $component_type = null + ): string + { + if ($component_type === null) { + return + "SELECT id, owner, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND " . $this->ilDB->in("owner", $node_ids, false, "integer") . PHP_EOL + . " AND object_type = " . $this->ilDB->quote($object_type, "string"); + } else { + return + "SELECT prv.id, prv.owner, prv.class_name, prv.include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . " prv" . PHP_EOL + . "JOIN " . ilProviderDB::COMPONENT_TABLE . " cmp" . PHP_EOL + . " ON prv.id = cmp.id" . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND " . $this->ilDB->in("owner", $node_ids, false, "integer") . PHP_EOL + . " AND object_type = " . $this->ilDB->quote($object_type, "string") . PHP_EOL + . " AND component_type = " . $this->ilDB->quote($component_type, "string"); + } + } + + protected function buildSharedUnboundProviderQueryForObjects( + array $node_ids, + string $object_type, + string $component_type = null + ): string + { + if ($component_type === null) { + return + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND " . $this->ilDB->in("owner", $node_ids, false, "integer") . PHP_EOL + . " AND object_type = " . $this->ilDB->quote($object_type, "string") . PHP_EOL + . "GROUP BY class_name, include_path"; + } else { + return + "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(prv.owner SEPARATOR \",\") owners," . PHP_EOL + . "prv.class_name, prv.include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . " prv" . PHP_EOL + . "JOIN " . ilProviderDB::COMPONENT_TABLE . " cmp" . PHP_EOL + . " ON prv.id = cmp.id" . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND " . $this->ilDB->in("owner", $node_ids, false, "integer") . PHP_EOL + . " AND object_type = " . $this->ilDB->quote($object_type, "string") . PHP_EOL + . " AND component_type = " . $this->ilDB->quote($component_type, "string") . PHP_EOL + . "GROUP BY prv.class_name, prv.include_path"; + } + } + + public function createTables() + { + if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { + $this->ilDB->createTable( + ilProviderDB::PROVIDER_TABLE, + [ + "id" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "owner" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "object_type" => [ + "type" => "text", + "length" => 4, + "notnull" => true + ], + "class_name" => [ + "type" => "text", + "length" => ilProviderDB::CLASS_NAME_LENGTH, + "notnull" => true + ], + "include_path" => [ + "type" => "text", + "length" => ilProviderDB::PATH_LENGTH, + "notnull" => true + ] + ] + ); + $this->ilDB->addPrimaryKey(ilProviderDB::PROVIDER_TABLE, ["id"]); + $this->ilDB->createSequence(ilProviderDB::PROVIDER_TABLE); + } + if (!$this->ilDB->tableExists(ilProviderDB::COMPONENT_TABLE)) { + $this->ilDB->createTable( + ilProviderDB::COMPONENT_TABLE, + [ + "id" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "component_type" => [ + "type" => "text", + "length" => ilProviderDB::CLASS_NAME_LENGTH, + "notnull" => true + ] + ] + ); + $this->ilDB->addPrimaryKey( + ilProviderDB::COMPONENT_TABLE, + ["id", "component_type"] + ); + } + if (!$this->ilDB->tableColumnExists( + ilProviderDB::PROVIDER_TABLE, + "shared") + ) { + $this->ilDB->addTableColumn( + ilProviderDB::PROVIDER_TABLE, + "shared", + [ + "type" => "integer", + "length" => 1, + "notnull" => true, + "default" => 0 + ] + ); + $this->ilDB->addIndex( + ilProviderDB::PROVIDER_TABLE, + ["shared"], + "ids" + ); + } + } + + public function addIndizes() + { + if (!$this->ilDB->tableExists(ilProviderDB::PROVIDER_TABLE)) { + return; + } + $this->ilDB->addIndex( + ilProviderDB::PROVIDER_TABLE, + ["owner"], + "ido", + false + ); + } + + protected function buildSeparatedUnboundProvider( + int $id, + \ilObject $owner, + string $object_type, + string $class_name, + string $include_path + ): UnboundProvider + { + require_once($include_path); + + assert('class_exists($class_name)'); + if (!is_subclass_of($class_name, SeparatedUnboundProvider::class)) { + throw new \UnexpectedValueException( + "Class '$class_name' does not extend UnboundProvider." + ); + } + + return new $class_name($id, $owner, $object_type); + } + + protected function buildSharedUnboundProvider( + array $owners, + string $object_type, + string $class_name, + string $include_path + ): UnboundProvider + { + assert('count($owners) > 0'); + + require_once($include_path); + + assert('class_exists($class_name)'); + if (!is_subclass_of($class_name, SharedUnboundProvider::class)) { + throw new \UnexpectedValueException( + "Class '$class_name' does not extend UnboundProvider." + ); + } + + return new $class_name($owners, $object_type); + } + + /** + * Build an object by its reference id. + * + * @throws \InvalidArgumentException if object could not be build + */ + protected function buildObjectByRefId(int $ref_id): \ilObject + { + $obj = \ilObjectFactory::getInstanceByRefId($ref_id, false); + if ($obj === false) { + throw new \InvalidArgumentException("Cannot build object with obj_id='$ref_id'"); + } + assert($obj instanceof \ilObject); + return $obj; + } + + /** + * Build an object by its object id. + * + * @throws \InvalidArgumentException if object could not be build + */ + protected function buildObjectByObjId(int $obj_id): \ilObject + { + $obj = \ilObjectFactory::getInstanceByObjId($obj_id, false); + if ($obj === false) { + throw new \InvalidArgumentException("Cannot build object with obj_id='$obj_id'"); + } + assert($obj instanceof \ilObject); + return $obj; + } + + protected function getAllReferenceIdsFor(int $obj_id): array + { + return \ilObject::_getAllReferences($obj_id); + } } diff --git a/src/ILIAS/ilProviderObjectHelper.php b/src/ILIAS/ilProviderObjectHelper.php index 12e48cf..51328cd 100644 --- a/src/ILIAS/ilProviderObjectHelper.php +++ b/src/ILIAS/ilProviderObjectHelper.php @@ -17,47 +17,47 @@ */ trait ilProviderObjectHelper { - use ilObjectHelper; + use ilObjectHelper; - /** - * Delete all unbound providers of this object. - * - * @return void - */ - protected function deleteUnboundProviders() { - if (!($this instanceof \ilObject)) { - throw new \LogicException("ilProviderObjectHelper can only be used with ilObjects."); - } + /** + * Delete all unbound providers of this object. + * + * @return void + */ + protected function deleteUnboundProviders() + { + if (!($this instanceof \ilObject)) { + throw new \LogicException("ilProviderObjectHelper can only be used with ilObjects."); + } - $provider_db = $this->getProviderDB(); - $unbound_providers = $provider_db->unboundProvidersOf($this); - foreach ($unbound_providers as $unbound_provider) { - $provider_db->delete($unbound_provider, $this); - } - } + $provider_db = $this->getProviderDB(); + $unbound_providers = $provider_db->unboundProvidersOf($this); + foreach ($unbound_providers as $unbound_provider) { + $provider_db->delete($unbound_provider, $this); + } + } - /** - * Create an unbound provider for this object. - * - * @param string $object_type for which the object provides - * @param string $class_name of the unbound provider - * @param string $path of the include file for the unbound provider class - * @return void - */ - protected function createUnboundProvider($object_type, $class_name, $path) { - if (!($this instanceof \ilObject)) { - throw new \LogicException("ilProviderObjectHelper can only be used with ilObjects."); - } - if(is_subclass_of($class_name, SeparatedUnboundProvider::class)) { - $this->getProviderDB()->createSeparatedUnboundProvider($this, $object_type, $class_name, $path); - } - else if(is_subclass_of($class_name, SharedUnboundProvider::class)) { - $this->getProviderDB()->createSharedUnboundProvider($this, $object_type, $class_name, $path); - } - else { - throw new \LogicException( - "createUnboundProvider can only create providers ". - "derived from Shared- or SeperatedUnboundProvider."); - } - } + /** + * Create an unbound provider for this object. + * + * @param string $object_type for which the object provides + * @param string $class_name of the unbound provider + * @param string $path of the include file for the unbound provider class + * @return void + */ + protected function createUnboundProvider($object_type, $class_name, $path) + { + if (!($this instanceof \ilObject)) { + throw new \LogicException("ilProviderObjectHelper can only be used with ilObjects."); + } + if (is_subclass_of($class_name, SeparatedUnboundProvider::class)) { + $this->getProviderDB()->createSeparatedUnboundProvider($this, $object_type, $class_name, $path); + } else if (is_subclass_of($class_name, SharedUnboundProvider::class)) { + $this->getProviderDB()->createSharedUnboundProvider($this, $object_type, $class_name, $path); + } else { + throw new \LogicException( + "createUnboundProvider can only create providers " . + "derived from Shared- or SeperatedUnboundProvider."); + } + } } diff --git a/src/Provider.php b/src/Provider.php index b5347d9..84800a4 100644 --- a/src/Provider.php +++ b/src/Provider.php @@ -23,34 +23,34 @@ */ interface Provider { - /** - * Get the components of a given type. - * - * `$component_type` must be a class or interface name. The returned - * components must implement that class or interface. - * - * For every `$component_type` not included in `providedComponentTypes` - * this must return an empty array. - * - * For every `$entity` not included in `providesForEntities` this must - * return an empty array. - * - * @param string $component_type - * @return Component[] - */ - public function componentsOfType(string $component_type) : array; + /** + * Get the components of a given type. + * + * `$component_type` must be a class or interface name. The returned + * components must implement that class or interface. + * + * For every `$component_type` not included in `providedComponentTypes` + * this must return an empty array. + * + * For every `$entity` not included in `providesForEntities` this must + * return an empty array. + * + * @param string $component_type + * @return Component[] + */ + public function componentsOfType(string $component_type): array; - /** - * Get the component types this provider provides. - * - * @return string[] - */ - public function componentTypes() : array; + /** + * Get the component types this provider provides. + * + * @return string[] + */ + public function componentTypes(): array; - /** - * Get the entity this provider provides components for. - * - * @return Entity - */ - public function entity() : Entity; + /** + * Get the entity this provider provides components for. + * + * @return Entity + */ + public function entity(): Entity; } diff --git a/src/ProviderHelper.php b/src/ProviderHelper.php index c8cf11c..ec0be83 100644 --- a/src/ProviderHelper.php +++ b/src/ProviderHelper.php @@ -17,19 +17,19 @@ */ trait ProviderHelper { - /** - * Get the component types implemented by the given component. - * Traverses all implemented interfaces and checks if they extend `Component`. - * @return string[] - */ - public function componentTypesOf(Component $component) : array - { - $ret = []; - foreach (class_implements(get_class($component)) as $interface) { - if (is_subclass_of($interface, Component::class)) { - $ret[] = $interface; - } - } - return $ret; - } + /** + * Get the component types implemented by the given component. + * Traverses all implemented interfaces and checks if they extend `Component`. + * @return string[] + */ + public function componentTypesOf(Component $component): array + { + $ret = []; + foreach (class_implements(get_class($component)) as $interface) { + if (is_subclass_of($interface, Component::class)) { + $ret[] = $interface; + } + } + return $ret; + } } diff --git a/src/Repository.php b/src/Repository.php index 6231138..9d60708 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -22,15 +22,15 @@ */ interface Repository { - /** - * Get providers for an entity, possibly filtered by a component type. - * @return Provider[] - */ - public function providersForEntity(Entity $entity, string $component_type = null) : array; + /** + * Get providers for an entity, possibly filtered by a component type. + * @return Provider[] + */ + public function providersForEntity(Entity $entity, string $component_type = null): array; - /** - * Get components for the entity, possibly filtered by component type. - * @return Component[] - */ - public function componentsForEntity(Entity $entity, string $component_type = null) : array; + /** + * Get components for the entity, possibly filtered by component type. + * @return Component[] + */ + public function componentsForEntity(Entity $entity, string $component_type = null): array; } diff --git a/src/RepositoryHelper.php b/src/RepositoryHelper.php index a3a6029..a0ce3f3 100644 --- a/src/RepositoryHelper.php +++ b/src/RepositoryHelper.php @@ -18,37 +18,36 @@ */ trait RepositoryHelper { - /** - * Get providers for an entity, possibly filtered by a component type. - * @return Provider[] - */ - abstract public function providersForEntity( - Entity $entity, - string $component_type = null - ) : array; + /** + * Get providers for an entity, possibly filtered by a component type. + * @return Provider[] + */ + abstract public function providersForEntity( + Entity $entity, + string $component_type = null + ): array; - /** - * Get components for the entity, possibly filtered by component type. - * @return Component[] - */ - public function componentsForEntity(Entity $entity, string $component_type = null) : array - { - $providers = $this->providersForEntity($entity, $component_type); - $components = []; - foreach ($providers as $provider) { - if ($component_type !== null) { - $components[] = $provider->componentsOfType($component_type); - } - else { - foreach ($provider->componentTypes() as $type) { - $components[] = $provider->componentsOfType($type); - } - } - } - if(count($components) > 0) { - return call_user_func_array("array_merge", $components); - } else { - return $components; - } - } + /** + * Get components for the entity, possibly filtered by component type. + * @return Component[] + */ + public function componentsForEntity(Entity $entity, string $component_type = null): array + { + $providers = $this->providersForEntity($entity, $component_type); + $components = []; + foreach ($providers as $provider) { + if ($component_type !== null) { + $components[] = $provider->componentsOfType($component_type); + } else { + foreach ($provider->componentTypes() as $type) { + $components[] = $provider->componentsOfType($type); + } + } + } + if (count($components) > 0) { + return call_user_func_array("array_merge", $components); + } else { + return $components; + } + } } diff --git a/src/Simple/AttachInt.php b/src/Simple/AttachInt.php index 4f9d2fe..ff79b0d 100644 --- a/src/Simple/AttachInt.php +++ b/src/Simple/AttachInt.php @@ -21,8 +21,8 @@ */ interface AttachInt extends Component { - /** - * Get the attached integer. - */ - public function attachedInt() : int; + /** + * Get the attached integer. + */ + public function attachedInt(): int; } diff --git a/src/Simple/AttachIntMemory.php b/src/Simple/AttachIntMemory.php index b9a1624..7ebc8a4 100644 --- a/src/Simple/AttachIntMemory.php +++ b/src/Simple/AttachIntMemory.php @@ -19,35 +19,35 @@ */ class AttachIntMemory implements AttachInt { - /** - * @var IEntity - */ - private $entity; - - /** - * @var int - */ - private $attached_int; - - public function __construct(IEntity $entity, int $attached_int) - { - $this->entity = $entity; - $this->attached_int = $attached_int; - } - - /** - * @inheritdocs - */ - public function entity() : IEntity - { - return $this->entity; - } - - /** - * @inheritdocs - */ - public function attachedInt() : int - { - return $this->attached_int; - } + /** + * @var IEntity + */ + private $entity; + + /** + * @var int + */ + private $attached_int; + + public function __construct(IEntity $entity, int $attached_int) + { + $this->entity = $entity; + $this->attached_int = $attached_int; + } + + /** + * @inheritdocs + */ + public function entity(): IEntity + { + return $this->entity; + } + + /** + * @inheritdocs + */ + public function attachedInt(): int + { + return $this->attached_int; + } } diff --git a/src/Simple/AttachString.php b/src/Simple/AttachString.php index 2592a7c..27d548e 100644 --- a/src/Simple/AttachString.php +++ b/src/Simple/AttachString.php @@ -21,8 +21,8 @@ */ interface AttachString extends Component { - /** - * Get the attached string. - */ - public function attachedString() : string; + /** + * Get the attached string. + */ + public function attachedString(): string; } diff --git a/src/Simple/AttachStringMemory.php b/src/Simple/AttachStringMemory.php index 14f56f1..e14f565 100644 --- a/src/Simple/AttachStringMemory.php +++ b/src/Simple/AttachStringMemory.php @@ -19,35 +19,35 @@ */ class AttachStringMemory implements AttachString { - /** - * @var IEntity - */ - private $entity; - - /** - * @var string - */ - private $attached_string; - - public function __construct(IEntity $entity, string $attached_string) - { - $this->entity = $entity; - $this->attached_string = $attached_string; - } - - /** - * @inheritdocs - */ - public function entity() : IEntity - { - return $this->entity; - } - - /** - * @inheritdocs - */ - public function attachedString() : string - { - return $this->attached_string; - } + /** + * @var IEntity + */ + private $entity; + + /** + * @var string + */ + private $attached_string; + + public function __construct(IEntity $entity, string $attached_string) + { + $this->entity = $entity; + $this->attached_string = $attached_string; + } + + /** + * @inheritdocs + */ + public function entity(): IEntity + { + return $this->entity; + } + + /** + * @inheritdocs + */ + public function attachedString(): string + { + return $this->attached_string; + } } diff --git a/src/Simple/Entity.php b/src/Simple/Entity.php index b8ce885..c52fdb1 100644 --- a/src/Simple/Entity.php +++ b/src/Simple/Entity.php @@ -17,21 +17,21 @@ */ class Entity implements \CaT\Ente\Entity { - /** - * @var integer - */ - private $id; + /** + * @var integer + */ + private $id; - public function __construct(int $id) - { - $this->id = $id; - } + public function __construct(int $id) + { + $this->id = $id; + } - /** - * @inheritdocs - */ - public function id() : int - { - return $this->id; - } + /** + * @inheritdocs + */ + public function id(): int + { + return $this->id; + } } diff --git a/src/Simple/Provider.php b/src/Simple/Provider.php index 2e0a71d..62e65b8 100644 --- a/src/Simple/Provider.php +++ b/src/Simple/Provider.php @@ -19,73 +19,73 @@ */ class Provider implements \CaT\Ente\Provider { - use Ente\ProviderHelper; + use Ente\ProviderHelper; - /** - * @var Entity - */ - private $entity; + /** + * @var Entity + */ + private $entity; - /** - * @var array - */ - private $components; + /** + * @var array + */ + private $components; - public function __construct(Entity $entity) - { - $this->entity = $entity; - $this->components = []; - } + public function __construct(Entity $entity) + { + $this->entity = $entity; + $this->components = []; + } - /** - * @inheritdocs - */ - public function componentsOfType(string $component_type) : array - { - if (isset($this->components[$component_type])) { - return $this->components[$component_type]; - } - return []; - } + /** + * @inheritdocs + */ + public function componentsOfType(string $component_type): array + { + if (isset($this->components[$component_type])) { + return $this->components[$component_type]; + } + return []; + } - /** - * @inheritdocs - */ - public function componentTypes() : array - { - return array_keys($this->components); - } + /** + * @inheritdocs + */ + public function componentTypes(): array + { + return array_keys($this->components); + } - /** - * @inheritdocs - */ - public function entity() : Ente\Entity - { - return $this->entity; - } + /** + * @inheritdocs + */ + public function entity(): Ente\Entity + { + return $this->entity; + } - /** - * Add a component to the provider. - * - * @param \CaT\Ente\Component $component - * @throws InvalidArgumentException if $component belongs to another entity - * @return self - */ - public function addComponent(Ente\Component $component) : Provider - { - if ($component->entity()->id() !== $this->entity()->id()) { - $my_id = serialize($this->entity()->id()); - $other_id = serialize($component->entity()->id()); - throw new \InvalidArgumentException( - "Cannot add component of entity '$other_id' to provider for '$my_id'."); - } + /** + * Add a component to the provider. + * + * @param \CaT\Ente\Component $component + * @return self + * @throws InvalidArgumentException if $component belongs to another entity + */ + public function addComponent(Ente\Component $component): Provider + { + if ($component->entity()->id() !== $this->entity()->id()) { + $my_id = serialize($this->entity()->id()); + $other_id = serialize($component->entity()->id()); + throw new \InvalidArgumentException( + "Cannot add component of entity '$other_id' to provider for '$my_id'."); + } - foreach ($this->componentTypesOf($component) as $type) { - if (!isset($this->components[$type])) { - $this->components[$type] = []; - } - $this->components[$type][] = $component; - } - return $this; - } + foreach ($this->componentTypesOf($component) as $type) { + if (!isset($this->components[$type])) { + $this->components[$type] = []; + } + $this->components[$type][] = $component; + } + return $this; + } } diff --git a/src/Simple/Repository.php b/src/Simple/Repository.php index 871f0cf..3166ddc 100644 --- a/src/Simple/Repository.php +++ b/src/Simple/Repository.php @@ -17,65 +17,67 @@ /** * Simple implementation for a repository, works in memory. */ -class Repository implements Ente\Repository { - use Ente\RepositoryHelper; +class Repository implements Ente\Repository +{ + use Ente\RepositoryHelper; - /** - * @var array - */ - protected $providers; + /** + * @var array + */ + protected $providers; - /** - * @var array - */ - protected $entities; + /** + * @var array + */ + protected $entities; - public function __construct() - { - $this->providers = []; - $this->entities = []; - } + public function __construct() + { + $this->providers = []; + $this->entities = []; + } - /** - * @inheritdocs - */ - public function providersForEntity( - Ente\Entity $entity, - string $component_type = null - ) : array { - $id = serialize($entity->id()); - if (!isset($this->providers[$id])) { - return []; - } + /** + * @inheritdocs + */ + public function providersForEntity( + Ente\Entity $entity, + string $component_type = null + ): array + { + $id = serialize($entity->id()); + if (!isset($this->providers[$id])) { + return []; + } - $ret = []; - foreach ($this->providers[$id] as $provider) { - if ( - $component_type === null || - in_array($component_type, $provider->componentTypes()) - ) { - $ret[] = $provider; - } - } - return $ret; - } + $ret = []; + foreach ($this->providers[$id] as $provider) { + if ( + $component_type === null || + in_array($component_type, $provider->componentTypes()) + ) { + $ret[] = $provider; + } + } + return $ret; + } - /** - * Add a provider to this repository. - * - * @param Provider $provider - * @return self - */ - public function addProvider(Provider $provider) : Repository - { - $id = serialize($provider->entity()->id()); - if (!isset($this->entities[$id])) { - $this->entities[$id] = $provider->entity(); - } - if (!isset($this->providers[$id])) { - $this->providers[$id] = []; - } - $this->providers[$id][] = $provider; - return $this; - } + /** + * Add a provider to this repository. + * + * @param Provider $provider + * @return self + */ + public function addProvider(Provider $provider): Repository + { + $id = serialize($provider->entity()->id()); + if (!isset($this->entities[$id])) { + $this->entities[$id] = $provider->entity(); + } + if (!isset($this->providers[$id])) { + $this->providers[$id] = []; + } + $this->providers[$id][] = $provider; + return $this; + } } diff --git a/tests/CachedProviderTest.php b/tests/CachedProviderTest.php index dd9f16c..98a6519 100644 --- a/tests/CachedProviderTest.php +++ b/tests/CachedProviderTest.php @@ -10,13 +10,16 @@ use CaT\Ente; -class CachedProviderTest extends PHPUnit_Framework_TestCase { - public function setUp() { +class CachedProviderTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { $this->original_provider = $this->createMock(Ente\Provider::class); $this->cached_provider = new Ente\CachedProvider($this->original_provider); } - public function test_componentTypes_passthru() { + public function test_componentTypes_passthru() + { $component_types = ["A", "B"]; $this->original_provider @@ -31,7 +34,8 @@ public function test_componentTypes_passthru() { $this->assertEquals($component_types, $res2); } - public function test_entity_passthru() { + public function test_entity_passthru() + { $entity = $this->createMock(Ente\Entity::class); $this->original_provider @@ -46,7 +50,8 @@ public function test_entity_passthru() { $this->assertEquals($entity, $res2); } - public function test_componentsOfType_calls_once() { + public function test_componentsOfType_calls_once() + { $component_type = "CTYPE"; $c1 = $this->createMock(Ente\Component::class); $c2 = $this->createMock(Ente\Component::class); @@ -64,7 +69,8 @@ public function test_componentsOfType_calls_once() { $this->assertEquals([$c1, $c2], $res2); } - public function test_componentsOfType_calls_once_per_component_type() { + public function test_componentsOfType_calls_once_per_component_type() + { $component_type1 = "CT1"; $component_type2 = "CT2"; $c1 = $this->createMock(Ente\Component::class); @@ -74,13 +80,13 @@ public function test_componentsOfType_calls_once_per_component_type() { ->expects($this->exactly(2)) ->method("componentsOfType") ->withConsecutive - ( [$component_type1] + ([$component_type1] , [$component_type2] - ) + ) ->will($this->onConsecutiveCalls - ( [$c1] + ([$c1] , [$c2] - )); + )); $res1 = $this->cached_provider->componentsOfType($component_type1); $res2 = $this->cached_provider->componentsOfType($component_type1); diff --git a/tests/CachedRepositoryTest.php b/tests/CachedRepositoryTest.php index f5912ea..92b690c 100644 --- a/tests/CachedRepositoryTest.php +++ b/tests/CachedRepositoryTest.php @@ -10,13 +10,16 @@ use CaT\Ente; -class CachedRepositoryTest extends PHPUnit_Framework_TestCase { - public function setUp() { +class CachedRepositoryTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { $this->original_repo = $this->createMock(Ente\Repository::class); $this->cached_repo = new Ente\CachedRepository($this->original_repo); } - public function test_caches_provider_for_entity() { + public function test_caches_provider_for_entity() + { $entity = $this->createMock(Ente\Entity::class); $entity_id = 42; $entity @@ -38,7 +41,8 @@ public function test_caches_provider_for_entity() { $this->assertEquals([new Ente\CachedProvider($provider)], $res2); } - public function test_componentsForEntity_calls_providersForEntity() { + public function test_componentsForEntity_calls_providersForEntity() + { $entity = $this->createMock(Ente\Entity::class); $entity_id = 42; $entity @@ -71,7 +75,8 @@ public function test_componentsForEntity_calls_providersForEntity() { $this->assertEquals($components, $res); } - public function test_providersForEntities_evaluates_component_type_internally() { + public function test_providersForEntities_evaluates_component_type_internally() + { $entity = $this->createMock(Ente\Entity::class); $entity_id = 42; $entity diff --git a/tests/ILIAS/EntityTest.php b/tests/ILIAS/EntityTest.php index aa6ebbd..76b4e4c 100644 --- a/tests/ILIAS/EntityTest.php +++ b/tests/ILIAS/EntityTest.php @@ -11,11 +11,13 @@ use CaT\Ente\ILIAS\Entity; if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } -class ILIAS_EntityTest extends PHPUnit_Framework_TestCase { - public function test_callsGetObjId() { +class ILIAS_EntityTest extends PHPUnit_Framework_TestCase +{ + public function test_callsGetObjId() + { $mock = $this ->getMockBuilder(ilObject::class) ->setMethods(["getId"]) @@ -26,14 +28,15 @@ public function test_callsGetObjId() { $mock ->expects($this->once()) ->method("getId") - ->willReturn($id); + ->willReturn($id); $e = new Entity($mock); $this->assertEquals($id, $e->id()); } - public function test_object() { + public function test_object() + { $mock = $this ->getMockBuilder(ilObject::class) ->getMock(); diff --git a/tests/ILIAS/ProviderTest.php b/tests/ILIAS/ProviderTest.php index 5d8e1f7..1196cb0 100644 --- a/tests/ILIAS/ProviderTest.php +++ b/tests/ILIAS/ProviderTest.php @@ -18,19 +18,21 @@ use CaT\Ente\Simple\AttachIntMemory; if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } -require_once(__DIR__."/../ProviderTest.php"); +require_once(__DIR__ . "/../ProviderTest.php"); -class ILIAS_ProviderTest extends ProviderTest { +class ILIAS_ProviderTest extends ProviderTest +{ /** * @inheritdocs */ - protected function provider() { - if (isset($this->provider)) { - return $this->provider; - } + protected function provider() + { + if (isset($this->provider)) { + return $this->provider; + } $this->object = $this ->getMockBuilder(\ilObject::class) @@ -42,7 +44,7 @@ protected function provider() { ->method("getId") ->willReturn($this->object_id); - $this->entity = new Entity($this->object); + $this->entity = new Entity($this->object); $this->owner = $this ->getMockBuilder(\ilObject::class) @@ -54,7 +56,7 @@ protected function provider() { ->method("getId") ->willReturn($this->owner_id); - $this->unbound_provider = $this->createMock(UnboundProvider::class); + $this->unbound_provider = $this->createMock(UnboundProvider::class); $this->provider = new Provider($this->object, $this->unbound_provider); @@ -64,15 +66,17 @@ protected function provider() { /** * @inheritdocs */ - protected function doesNotProvideComponentType() { + protected function doesNotProvideComponentType() + { return [self::class]; } - protected function initUnboundProvider() { + protected function initUnboundProvider() + { $this->provider(); $this->unbound_provider ->method("buildComponentsOf") - ->will($this->returnCallback(function($c) { + ->will($this->returnCallback(function ($c) { if ($c === AttachString::class) { return [new AttachStringMemory($this->entity, "")]; } @@ -83,59 +87,66 @@ protected function initUnboundProvider() { })); } - public function test_only_provides_announced_component_types() { + public function test_only_provides_announced_component_types() + { $this->initUnboundProvider(); parent::test_only_provides_announced_component_types(); - } + } /** * @dataProvider component_types */ - public function test_provides_for_own_entity($component_type) { + public function test_provides_for_own_entity($component_type) + { $this->initUnboundProvider(); parent::test_provides_for_own_entity($component_type); - } + } /** * @dataProvider component_types */ - public function test_provides_expected_component_types($component_type) { + public function test_provides_expected_component_types($component_type) + { $this->initUnboundProvider(); parent::test_provides_expected_component_types($component_type); - } + } - public function component_types() { + public function component_types() + { return [[AttachString::class], [AttachInt::class]]; } - public function test_entity_id_is_object_id() { + public function test_entity_id_is_object_id() + { $provider = $this->provider(); $this->assertEquals($this->object_id, $provider->entity()->id()); } - public function test_componentTypes() { + public function test_componentTypes() + { $provider = $this->provider(); - $component_types = ["a", "b"]; - $this->unbound_provider - ->expects($this->once()) - ->method("componentTypes") - ->willReturn($component_types); + $component_types = ["a", "b"]; + $this->unbound_provider + ->expects($this->once()) + ->method("componentTypes") + ->willReturn($component_types); $this->assertEquals($component_types, $provider->componentTypes()); } - public function test_provided_components() { + public function test_provided_components() + { $provider = $this->provider(); - $string = "A STRING"; - $int = 1337; - $this->unbound_provider - ->expects($this->exactly(2)) - ->method("buildComponentsOf") - ->withConsecutive([AttachString::class],[AttachInt::class]) - ->will($this->onConsecutiveCalls - ( [new AttachStringMemory($this->entity, $string)] - , [new AttachIntMemory($this->entity, $int)] - )); + $string = "A STRING"; + $int = 1337; + $this->unbound_provider + ->expects($this->exactly(2)) + ->method("buildComponentsOf") + ->withConsecutive([AttachString::class], [AttachInt::class]) + ->will($this->onConsecutiveCalls + ([new AttachStringMemory($this->entity, $string)] + , [new AttachIntMemory($this->entity, $int)] + )); $attached_strings = $provider->componentsOfType(AttachString::class); $this->assertCount(1, $attached_strings); @@ -148,37 +159,41 @@ public function test_provided_components() { $this->assertEquals($int, $attached_int->attachedInt()); } - public function test_caching() { + public function test_caching() + { $provider = $this->provider(); - $string = "A STRING"; - $int = 1337; - $this->unbound_provider - ->expects($this->exactly(1)) - ->method("buildComponentsOf") - ->with(AttachString::class) - ->willReturn([new AttachStringMemory($this->entity, $string)]); + $string = "A STRING"; + $int = 1337; + $this->unbound_provider + ->expects($this->exactly(1)) + ->method("buildComponentsOf") + ->with(AttachString::class) + ->willReturn([new AttachStringMemory($this->entity, $string)]); $provider->componentsOfType(AttachString::class); $provider->componentsOfType(AttachString::class); } - public function test_object() { + public function test_object() + { $object = $this->provider()->object(); - $this->assertEquals($this->object, $object); + $this->assertEquals($this->object, $object); } - public function test_owners() { + public function test_owners() + { $provider = $this->provider(); - $this->unbound_provider - ->expects($this->once()) - ->method("owners") - ->willReturn([$this->owner]); + $this->unbound_provider + ->expects($this->once()) + ->method("owners") + ->willReturn([$this->owner]); $owners = $provider->owners(); $this->assertEquals([$this->owner], $owners); } - public function test_unboundProvider() { + public function test_unboundProvider() + { $provider = $this->provider(); $this->assertEquals($this->unbound_provider, $provider->unboundProvider()); } diff --git a/tests/ILIAS/RepositoryTest.php b/tests/ILIAS/RepositoryTest.php index bf12dd8..2d09a6e 100644 --- a/tests/ILIAS/RepositoryTest.php +++ b/tests/ILIAS/RepositoryTest.php @@ -17,35 +17,44 @@ use CaT\Ente\Simple\AttachInt; use CaT\Ente\Simple\AttachIntMemory; -require_once(__DIR__."/../RepositoryTest.php"); +require_once(__DIR__ . "/../RepositoryTest.php"); if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } -class ILIAS_RepositoryTest_Object extends ilObject { +class ILIAS_RepositoryTest_Object extends ilObject +{ protected $id; - public function __construct($id) { + + public function __construct($id) + { $this->id = $id; } - public function getId() { + + public function getId() + { return $this->id; } } -class ILIAS_RepositoryTest extends RepositoryTest { - protected function object($id) { +class ILIAS_RepositoryTest extends RepositoryTest +{ + protected function object($id) + { return new ILIAS_RepositoryTest_Object($id); } - protected function entity($id) { + protected function entity($id) + { return new Entity($this->object($id)); } /** * @inheritdocs */ - protected function repository() { + protected function repository() + { $this->provider_db = $this->createMock(ProviderDB::class); $this->provider_1 = $this @@ -76,14 +85,14 @@ protected function repository() { $this->provider_db ->method("providersFor") - ->will($this->returnCallback(function($o, $ct) { + ->will($this->returnCallback(function ($o, $ct) { if ($o == $this->object(1)) { - if ($ct === null || $ct === AttachInt::class) + if ($ct === null || $ct === AttachInt::class) return [$this->provider_1]; return []; } if ($o == $this->object(2)) { - if ($ct === null || $ct === AttachString::class) + if ($ct === null || $ct === AttachString::class) return [$this->provider_2]; return []; } @@ -96,31 +105,36 @@ protected function repository() { /** * @inheritdocs */ - protected function hasProvidersForEntities() { + protected function hasProvidersForEntities() + { return [$this->entity(1), $this->entity(2)]; } /** * @inheritdocs */ - protected function hasProvidersForComponentTypes() { + protected function hasProvidersForComponentTypes() + { return [AttachInt::class, AttachString::class]; } - public function test_provider_db() { + public function test_provider_db() + { $this->repository(); $this->assertEquals([$this->provider_1], $this->provider_db->providersFor($this->object(1))); $this->assertEquals([$this->provider_2], $this->provider_db->providersFor($this->object(2))); } - public function test_ILIAS_Entities_only() { + public function test_ILIAS_Entities_only() + { $repository = $this->repository(); $entity = new \CaT\Ente\Simple\Entity(1); $this->assertEquals([], $repository->providersForEntity($entity)); } - public function test_providersForEntity_calls_providersFor() { + public function test_providersForEntity_calls_providersFor() + { $repository = $this->repository(); $this->provider_db diff --git a/tests/ILIAS/SeparatedUnboundProviderTest.php b/tests/ILIAS/SeparatedUnboundProviderTest.php index 42566e9..4869069 100644 --- a/tests/ILIAS/SeparatedUnboundProviderTest.php +++ b/tests/ILIAS/SeparatedUnboundProviderTest.php @@ -17,16 +17,18 @@ use CaT\Ente\Entity AS IEntity; if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } -class Test_SeparatedUnboundProvider extends SeparatedUnboundProvider { - public function componentTypes() { +class Test_SeparatedUnboundProvider extends SeparatedUnboundProvider +{ + public function componentTypes() + { return [AttachString::class, AttachInt::class]; } - public function buildComponentsOf(string $component_type, IEntity $entity) : array - { + public function buildComponentsOf(string $component_type, IEntity $entity): array + { $this->callsTo_buildComponentsOf[] = $component_type; $object = $entity->object(); if ($component_type == AttachString::class) { @@ -39,11 +41,13 @@ public function buildComponentsOf(string $component_type, IEntity $entity) : arr } } -class ILIAS_SeparatedUnboundProviderTest extends PHPUnit_Framework_TestCase { +class ILIAS_SeparatedUnboundProviderTest extends PHPUnit_Framework_TestCase +{ /** * @inheritdocs */ - protected function unboundProvider() { + protected function unboundProvider() + { $this->owner = $this ->getMockBuilder(\ilObject::class) ->setMethods(["getId"]) @@ -72,19 +76,22 @@ protected function unboundProvider() { return $provider; } - public function test_componentTypes() { + public function test_componentTypes() + { $unbound_provider = $this->unboundProvider(); $this->assertEquals([AttachString::class, AttachInt::class], $unbound_provider->componentTypes()); } - public function test_owner() { + public function test_owner() + { $owner = $this->unboundProvider()->owner(); $this->assertInstanceOf(\ilObject::class, $owner); $this->assertEquals($this->owner_id, $owner->getId()); } - public function test_owners() { + public function test_owners() + { $owners = $this->unboundProvider()->owners(); $this->assertCount(1, $owners); @@ -93,25 +100,27 @@ public function test_owners() { $this->assertEquals($this->owner_id, $owner->getId()); } - public function test_idFor() { + public function test_idFor() + { $unbound_provider = $this->unboundProvider(); $this->assertEquals($this->unbound_provider_id, $unbound_provider->idFor($this->owner)); } - public function test_idFor_throws() { + public function test_idFor_throws() + { $unbound_provider = $this->unboundProvider(); try { $unbound_provider->idFor($this->no_owner); $raised = false; - } - catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException $e) { $raised = true; } $this->assertTrue($raised); } - public function test_object_type() { + public function test_object_type() + { $unbound_provider = $this->unboundProvider(); $this->assertEquals($this->object_type, $unbound_provider->objectType()); } diff --git a/tests/ILIAS/SharedUnboundProviderTest.php b/tests/ILIAS/SharedUnboundProviderTest.php index 2061681..8b33390 100644 --- a/tests/ILIAS/SharedUnboundProviderTest.php +++ b/tests/ILIAS/SharedUnboundProviderTest.php @@ -18,15 +18,18 @@ use CaT\Ente\Entity AS IEntity; if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } -class Test_SharedUnboundProvider extends SharedUnboundProvider { - public function componentTypes() { +class Test_SharedUnboundProvider extends SharedUnboundProvider +{ + public function componentTypes() + { return [AttachString::class, AttachInt::class]; } - public function buildComponentsOf(string $component_type, IEntity $entity) : array { + public function buildComponentsOf(string $component_type, IEntity $entity): array + { assert(is_string($component_type)); $this->callsTo_buildComponentsOf[] = $component_type; $object = $entity->object(); @@ -41,11 +44,13 @@ public function buildComponentsOf(string $component_type, IEntity $entity) : arr } } -class ILIAS_SharedUnboundProviderTest extends PHPUnit_Framework_TestCase { +class ILIAS_SharedUnboundProviderTest extends PHPUnit_Framework_TestCase +{ /** * @inheritdocs */ - protected function unboundProvider() { + protected function unboundProvider() + { $this->owner1 = $this ->getMockBuilder(\ilObject::class) ->setMethods(["getId"]) @@ -71,8 +76,8 @@ protected function unboundProvider() { $this->object_type = "object_type"; $owners = - [ $this->unbound_provider_id1 => $this->owner1 - , $this->unbound_provider_id2 => $this->owner2 + [$this->unbound_provider_id1 => $this->owner1 + , $this->unbound_provider_id2 => $this->owner2 ]; $provider = new Test_SharedUnboundProvider($owners, $this->object_type); @@ -80,12 +85,14 @@ protected function unboundProvider() { return $provider; } - public function test_componentTypes() { + public function test_componentTypes() + { $unbound_provider = $this->unboundProvider(); $this->assertEquals([AttachString::class, AttachInt::class], $unbound_provider->componentTypes()); } - public function test_owner() { + public function test_owner() + { $owners = $this->unboundProvider()->owners(); $this->assertCount(2, $owners); @@ -98,13 +105,15 @@ public function test_owner() { $this->assertEquals($this->owner2_id, $owner2->getId()); } - public function test_idFor() { + public function test_idFor() + { $unbound_provider = $this->unboundProvider(); $this->assertEquals($this->unbound_provider_id1, $unbound_provider->idFor($this->owner1)); $this->assertEquals($this->unbound_provider_id2, $unbound_provider->idFor($this->owner2)); } - public function test_idFor_throws() { + public function test_idFor_throws() + { $unbound_provider = $this->unboundProvider(); $other = $this ->getMockBuilder(\ilObject::class) @@ -119,14 +128,14 @@ public function test_idFor_throws() { try { $unbound_provider->idFor($other); $raised = false; - } - catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException $e) { $raised = true; } $this->assertTrue($raised); } - public function test_object_type() { + public function test_object_type() + { $unbound_provider = $this->unboundProvider(); $this->assertEquals($this->object_type, $unbound_provider->objectType()); } diff --git a/tests/ILIAS/ilCachesOwnerRangeProviderTest.php b/tests/ILIAS/ilCachesOwnerRangeProviderTest.php index d15a4cc..6c1c60e 100644 --- a/tests/ILIAS/ilCachesOwnerRangeProviderTest.php +++ b/tests/ILIAS/ilCachesOwnerRangeProviderTest.php @@ -18,45 +18,50 @@ use CaT\Ente\Simple\AttachInt; if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } if (!interface_exists("ilDBInterface")) { - require_once(__DIR__."/ilDBInterface.php"); + require_once(__DIR__ . "/ilDBInterface.php"); } if (!interface_exists("ilTree")) { - require_once(__DIR__."/ilTree.php"); + require_once(__DIR__ . "/ilTree.php"); } if (!interface_exists("ilObjectDataCache")) { - require_once(__DIR__."/ilObjectDataCache.php"); + require_once(__DIR__ . "/ilObjectDataCache.php"); } class Test_ilCachesOwnerRangeProviderDB extends ilCachesOwnerRangeProviderDB { public $object_ref = []; - public $throws = false; - protected function buildObjectByRefId(int $ref_id) : \ilObject - { - if ($this->throws) { - throw new \InvalidArgumentException(); - } + public $throws = false; + + protected function buildObjectByRefId(int $ref_id): \ilObject + { + if ($this->throws) { + throw new \InvalidArgumentException(); + } assert(isset($this->object_ref[$ref_id])); return $this->object_ref[$ref_id]; } + public $object_obj = []; - protected function buildObjectByObjId(int $obj_id) : \ilObject - { - if ($this->throws) { - throw new \InvalidArgumentException(); - } + + protected function buildObjectByObjId(int $obj_id): \ilObject + { + if ($this->throws) { + throw new \InvalidArgumentException(); + } assert(isset($this->object_obj[$obj_id])); return $this->object_obj[$obj_id]; } + public $reference_ids = []; - protected function getAllReferenceIdsFor(int $obj_id) : array - { + + protected function getAllReferenceIdsFor(int $obj_id): array + { assert(isset($this->reference_ids[$obj_id])); return $this->reference_ids[$obj_id]; } @@ -64,25 +69,29 @@ protected function getAllReferenceIdsFor(int $obj_id) : array class ILIAS_ilCachesOwnerRangeProviderDBTest extends PHPUnit_Framework_TestCase { - protected function il_db_mock() { + protected function il_db_mock() + { return $this->createMock(\ilDBInterface::class); } - public function il_tree_mock() { + public function il_tree_mock() + { return $this ->getMockBuilder(\ilTree::class) ->setMethods(["getSubTreeIds", "getNodePath"]) ->getMock(); } - public function il_object_data_cache_mock() { + public function il_object_data_cache_mock() + { return $this ->getMockBuilder(\ilObjectDataCache::class) ->setMethods(["preloadReferenceCache", "lookupObjId"]) ->getMock(); } - public function test_providersFor_no_cache() { + public function test_providersFor_no_cache() + { $il_db = $this->il_db_mock(); $il_tree = $this->il_tree_mock(); $il_cache = $this->il_object_data_cache_mock(); @@ -113,7 +122,7 @@ public function test_providersFor_no_cache() { ->with($object_ref_id) ->willReturn($sub_tree_ids); - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); $il_cache ->expects($this->once()) ->method("preloadReferenceCache") @@ -122,12 +131,12 @@ public function test_providersFor_no_cache() { $il_cache ->expects($this->exactly(3)) ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; $cache = $this->createMock(Cache::class); $cache @@ -139,56 +148,56 @@ public function test_providersFor_no_cache() { ->expects($this->once()) ->method("set") ->with("0", - [ - $sub_tree_id1 => [ $object_type => [ - "shared" => [], - "separated" => - [ - [ - "id" => 1, - "owner" => $sub_tree_id1, - "class_name" => $class_name, - "include_path" => $include_path, - "object_type" => $object_type, - "which" => "separated" - ] - ] - ]], - $sub_tree_id2 => [ $object_type => [ - "shared" => [], - "separated" => - [ - [ - "id" => 2, - "owner" => $sub_tree_id2, - "class_name" => $class_name, - "include_path" => $include_path, - "object_type" => $object_type, - "which" => "separated" - ] - ] - ]], - "i am" => "here" + [ + $sub_tree_id1 => [$object_type => [ + "shared" => [], + "separated" => + [ + [ + "id" => 1, + "owner" => $sub_tree_id1, + "class_name" => $class_name, + "include_path" => $include_path, + "object_type" => $object_type, + "which" => "separated" + ] + ] + ]], + $sub_tree_id2 => [$object_type => [ + "shared" => [], + "separated" => + [ + [ + "id" => 2, + "owner" => $sub_tree_id2, + "class_name" => $class_name, + "include_path" => $include_path, + "object_type" => $object_type, + "which" => "separated" + ] + ] + ]], + "i am" => "here" ] ); $il_db ->expects($this->exactly(2)) ->method("quote") - ->withConsecutive([0],[1000]) + ->withConsecutive([0], [1000]) ->willReturn("~RANGE~"); $il_db ->expects($this->once()) ->method("query") ->with - ("SELECT id, owner, class_name, include_path, object_type, shared FROM ".ilProviderDB::PROVIDER_TABLE." WHERE owner >= ~RANGE~ AND owner < ~RANGE~") + ("SELECT id, owner, class_name, include_path, object_type, shared FROM " . ilProviderDB::PROVIDER_TABLE . " WHERE owner >= ~RANGE~ AND owner < ~RANGE~") ->willReturn("R1"); $il_db ->expects($this->exactly(3)) ->method("fetchAssoc") - ->withConsecutive(["R1"],["R1"],["R1"]) + ->withConsecutive(["R1"], ["R1"], ["R1"]) ->will($this->onConsecutiveCalls( ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path, "object_type" => $object_type, "shared" => 0], ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path, "object_type" => $object_type, "shared" => 0], @@ -224,7 +233,7 @@ public function test_providersFor_no_cache() { } public function test_providersFor_with_cache() - { + { $il_db = $this->il_db_mock(); $il_tree = $this->il_tree_mock(); $il_cache = $this->il_object_data_cache_mock(); @@ -255,7 +264,7 @@ public function test_providersFor_with_cache() ->with($object_ref_id) ->willReturn($sub_tree_ids); - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); $il_cache ->expects($this->once()) ->method("preloadReferenceCache") @@ -264,12 +273,12 @@ public function test_providersFor_with_cache() $il_cache ->expects($this->exactly(3)) ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; $cache = $this->createMock(Cache::class); @@ -278,39 +287,39 @@ public function test_providersFor_with_cache() ->method("get") ->with("0") ->willReturn( - [ - $object_ref_id => [ - $object_type => [ - "separated" => [], - "shared" => [] - ] - ], - $sub_tree_id1 => [ - $object_type => [ - "separated" => [ - [ - "id" => 1, - "owner" => $sub_tree_id1, - "class_name" => $class_name, - "include_path" => $include_path - ] - ], - "shared" => [] - ] - ], - $sub_tree_id2 => [ - $object_type => [ - "separated" => [ - [ - "id" => 2, - "owner" => $sub_tree_id2, - "class_name" => $class_name, - "include_path" => $include_path - ] - ], - "shared" => [] - ] - ], + [ + $object_ref_id => [ + $object_type => [ + "separated" => [], + "shared" => [] + ] + ], + $sub_tree_id1 => [ + $object_type => [ + "separated" => [ + [ + "id" => 1, + "owner" => $sub_tree_id1, + "class_name" => $class_name, + "include_path" => $include_path + ] + ], + "shared" => [] + ] + ], + $sub_tree_id2 => [ + $object_type => [ + "separated" => [ + [ + "id" => 2, + "owner" => $sub_tree_id2, + "class_name" => $class_name, + "include_path" => $include_path + ] + ], + "shared" => [] + ] + ], ] ); diff --git a/tests/ILIAS/ilDBInterface.php b/tests/ILIAS/ilDBInterface.php index 1643aa4..39a879d 100644 --- a/tests/ILIAS/ilDBInterface.php +++ b/tests/ILIAS/ilDBInterface.php @@ -11,107 +11,108 @@ /** * Essentials of ILIAS database for this framework. */ -interface ilDBInterface { - /** - * @param $table_name string - * - * @return int - */ - public function nextId($table_name); +interface ilDBInterface +{ + /** + * @param $table_name string + * + * @return int + */ + public function nextId($table_name); - /** - * @param $table_name - * @param $fields - * @param bool $drop_table - * @param bool $ignore_erros - * @return mixed - */ - public function createTable($table_name, $fields, $drop_table = false, $ignore_erros = false); + /** + * @param $table_name + * @param $fields + * @param bool $drop_table + * @param bool $ignore_erros + * @return mixed + */ + public function createTable($table_name, $fields, $drop_table = false, $ignore_erros = false); - /** - * @param $table_name string - * @param $primary_keys array - */ - public function addPrimaryKey($table_name, $primary_keys); + /** + * @param $table_name string + * @param $primary_keys array + */ + public function addPrimaryKey($table_name, $primary_keys); - /** - * @param $table_name - * @param int $start - */ - public function createSequence($table_name, $start = 1); + /** + * @param $table_name + * @param int $start + */ + public function createSequence($table_name, $start = 1); - /** - * @param $table_name string - * - * @return bool - */ - public function tableExists($table_name); + /** + * @param $table_name string + * + * @return bool + */ + public function tableExists($table_name); - /** - * @param $table_name string - * @param $column_name string - * - * @return bool - */ - public function tableColumnExists($table_name, $column_name); + /** + * @param $table_name string + * @param $column_name string + * + * @return bool + */ + public function tableColumnExists($table_name, $column_name); - /** - * @param $table_name - * @param $fields - * @param string $index_name - * @param bool $fulltext - * @return bool - */ - public function addIndex($table_name, $fields, $index_name = '', $fulltext = false); + /** + * @param $table_name + * @param $fields + * @param string $index_name + * @param bool $fulltext + * @return bool + */ + public function addIndex($table_name, $fields, $index_name = '', $fulltext = false); - /** - * @param $table_name string - * @param $column_name string - * @param $attributes array - */ - public function addTableColumn($table_name, $column_name, $attributes); + /** + * @param $table_name string + * @param $column_name string + * @param $attributes array + */ + public function addTableColumn($table_name, $column_name, $attributes); - /** - * @param $query string - * - * @return \ilPDOStatement - */ - public function query($query); + /** + * @param $query string + * + * @return \ilPDOStatement + */ + public function query($query); - /** - * @param $table_name string - * @param $values - * @return int|void - */ - public function insert($table_name, $values); + /** + * @param $table_name string + * @param $values + * @return int|void + */ + public function insert($table_name, $values); - /** - * @param $query_result ilDBStatement - * - * @return mixed - */ - public function fetchAssoc($query_result); + /** + * @param $query_result ilDBStatement + * + * @return mixed + */ + public function fetchAssoc($query_result); - /** - * @param $value - * @param $type - * - * @return string - */ - public function quote($value, $type); + /** + * @param $value + * @param $type + * + * @return string + */ + public function quote($value, $type); - /** - * @param $query string - * @return int|void - */ - public function manipulate($query); + /** + * @param $query string + * @return int|void + */ + public function manipulate($query); - /** - * @param $field string - * @param $values array - * @param bool $negate - * @param string $type - * @return string - */ - public function in($field, $values, $negate = false, $type = ""); + /** + * @param $field string + * @param $values array + * @param bool $negate + * @param string $type + * @return string + */ + public function in($field, $values, $negate = false, $type = ""); } diff --git a/tests/ILIAS/ilHandlerObjectHelperTest.php b/tests/ILIAS/ilHandlerObjectHelperTest.php index d545dcb..87d1bd0 100644 --- a/tests/ILIAS/ilHandlerObjectHelperTest.php +++ b/tests/ILIAS/ilHandlerObjectHelperTest.php @@ -10,106 +10,117 @@ use CaT\Ente; -abstract class ilHandlerObjectHelperMock { - use Ente\ILIAS\ilHandlerObjectHelper; - public function _getRepository() { - return $this->getRepository(); - } - public function _getComponents() { - return $this->getComponents(); - } - public function _getComponentsOfType($t) { - return $this->getComponentsOfType($t); - } +abstract class ilHandlerObjectHelperMock +{ + use Ente\ILIAS\ilHandlerObjectHelper; + + public function _getRepository() + { + return $this->getRepository(); + } + + public function _getComponents() + { + return $this->getComponents(); + } + + public function _getComponentsOfType($t) + { + return $this->getComponentsOfType($t); + } } -class ilHandlerObjectHelperTest extends PHPUnit_Framework_TestCase { - public function test_getRepository() { - $provider_db = $this->createMock(Ente\ILIAS\ProviderDB::class); - - $mock = $this - ->getMockBuilder(ilHandlerObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC", "getEntityRefId"]) - ->getMock(); - - $dic = [ - "ente.provider_db" => $provider_db - ]; - $mock - ->expects($this->once()) - ->method("getDIC") - ->willReturn($dic); - - $repository = $mock->_getRepository(); - // unwrap creation closure - $repository = $repository($dic); - - $this->assertInstanceOf(Ente\Repository::class, $repository); - } - - public function test_getComponents() { - $repository = $this->createMock(Ente\Repository::class); - $entity = $this->createMock(Ente\Entity::class); - - $mock = $this - ->getMockBuilder(ilHandlerObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC", "getEntityRefId", "getEntity", "getRepository"]) - ->getMock(); - - $mock - ->expects($this->once()) - ->method("getRepository") - ->willReturn($repository); - - $mock - ->expects($this->once()) - ->method("getEntity") - ->willReturn($entity); - - $array = [new \StdClass()]; - - $repository - ->expects($this->once()) - ->method("componentsForEntity") - ->with($entity) - ->willReturn($array); - - $components = $mock->_getComponents(); - - $this->assertSame($array, $components); - } - - - public function test_getComponentsOfType() { - $repository = $this->createMock(Ente\Repository::class); - $entity = $this->createMock(Ente\Entity::class); - - $mock = $this - ->getMockBuilder(ilHandlerObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC", "getEntityRefId", "getEntity", "getRepository"]) - ->getMock(); - - $mock - ->expects($this->once()) - ->method("getRepository") - ->willReturn($repository); - - $mock - ->expects($this->once()) - ->method("getEntity") - ->willReturn($entity); - - $array = [new \StdClass()]; - $type = "TYPE"; - - $repository - ->expects($this->once()) - ->method("componentsForEntity") - ->with($entity, $type) - ->willReturn($array); - - $components = $mock->_getComponentsOfType($type); - - $this->assertSame($array, $components); - } +class ilHandlerObjectHelperTest extends PHPUnit_Framework_TestCase +{ + public function test_getRepository() + { + $provider_db = $this->createMock(Ente\ILIAS\ProviderDB::class); + + $mock = $this + ->getMockBuilder(ilHandlerObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC", "getEntityRefId"]) + ->getMock(); + + $dic = [ + "ente.provider_db" => $provider_db + ]; + $mock + ->expects($this->once()) + ->method("getDIC") + ->willReturn($dic); + + $repository = $mock->_getRepository(); + // unwrap creation closure + $repository = $repository($dic); + + $this->assertInstanceOf(Ente\Repository::class, $repository); + } + + public function test_getComponents() + { + $repository = $this->createMock(Ente\Repository::class); + $entity = $this->createMock(Ente\Entity::class); + + $mock = $this + ->getMockBuilder(ilHandlerObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC", "getEntityRefId", "getEntity", "getRepository"]) + ->getMock(); + + $mock + ->expects($this->once()) + ->method("getRepository") + ->willReturn($repository); + + $mock + ->expects($this->once()) + ->method("getEntity") + ->willReturn($entity); + + $array = [new \StdClass()]; + + $repository + ->expects($this->once()) + ->method("componentsForEntity") + ->with($entity) + ->willReturn($array); + + $components = $mock->_getComponents(); + + $this->assertSame($array, $components); + } + + + public function test_getComponentsOfType() + { + $repository = $this->createMock(Ente\Repository::class); + $entity = $this->createMock(Ente\Entity::class); + + $mock = $this + ->getMockBuilder(ilHandlerObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC", "getEntityRefId", "getEntity", "getRepository"]) + ->getMock(); + + $mock + ->expects($this->once()) + ->method("getRepository") + ->willReturn($repository); + + $mock + ->expects($this->once()) + ->method("getEntity") + ->willReturn($entity); + + $array = [new \StdClass()]; + $type = "TYPE"; + + $repository + ->expects($this->once()) + ->method("componentsForEntity") + ->with($entity, $type) + ->willReturn($array); + + $components = $mock->_getComponentsOfType($type); + + $this->assertSame($array, $components); + } } diff --git a/tests/ILIAS/ilObject.php b/tests/ILIAS/ilObject.php index bc83742..1f2595d 100644 --- a/tests/ILIAS/ilObject.php +++ b/tests/ILIAS/ilObject.php @@ -11,31 +11,35 @@ /** * Essentials of ILIAS object for this framework. */ -abstract class ilObject { - /** - * get object id - * @access public - * @return integer object id - */ - public function getId() { +abstract class ilObject +{ + /** + * get object id + * @access public + * @return integer object id + */ + public function getId() + { assert(false); } - /** - * get reference id - * @access public - * @return integer reference id - */ - public function getRefId() { + /** + * get reference id + * @access public + * @return integer reference id + */ + public function getRefId() + { assert(false); } - /** - * get object type - * @access public - * @return string object type - */ - public function getType() { + /** + * get object type + * @access public + * @return string object type + */ + public function getType() + { assert(false); - } + } } diff --git a/tests/ILIAS/ilObjectDataCache.php b/tests/ILIAS/ilObjectDataCache.php index d2ab505..fe96683 100644 --- a/tests/ILIAS/ilObjectDataCache.php +++ b/tests/ILIAS/ilObjectDataCache.php @@ -11,12 +11,15 @@ /** * Essentials of ILIAS object data cache for this framework. */ -abstract class ilObjectDataCache { - public function preloadReferenceCache($a_ref_ids, $a_incl_obj = true) { +abstract class ilObjectDataCache +{ + public function preloadReferenceCache($a_ref_ids, $a_incl_obj = true) + { assert(false); } - public function lookupObjId($a_ref_id) { + public function lookupObjId($a_ref_id) + { assert(false); } } diff --git a/tests/ILIAS/ilObjectHelperTest.php b/tests/ILIAS/ilObjectHelperTest.php index f1aeccd..225da3b 100644 --- a/tests/ILIAS/ilObjectHelperTest.php +++ b/tests/ILIAS/ilObjectHelperTest.php @@ -12,48 +12,53 @@ if (!interface_exists("ilDBInterface")) { - require_once(__DIR__."/ilDBInterface.php"); + require_once(__DIR__ . "/ilDBInterface.php"); } if (!interface_exists("ilTree")) { - require_once(__DIR__."/ilTree.php"); + require_once(__DIR__ . "/ilTree.php"); } if (!interface_exists("ilObjectDataCache")) { - require_once(__DIR__."/ilObjectDataCache.php"); + require_once(__DIR__ . "/ilObjectDataCache.php"); } -abstract class ilObjectHelperMock { - use Ente\ILIAS\ilObjectHelper; - public function _getProviderDB() { - return $this->getProviderDB(); - } +abstract class ilObjectHelperMock +{ + use Ente\ILIAS\ilObjectHelper; + + public function _getProviderDB() + { + return $this->getProviderDB(); + } } -class ilObjectHelperTest extends PHPUnit_Framework_TestCase { - public function test_getProviderDB() { - $db = $this->createMock(\ilDBInterface::class); - $tree = $this->createMock(\ilTree::class); - $objDataCache = $this->createMock(\ilObjectDataCache::class); +class ilObjectHelperTest extends PHPUnit_Framework_TestCase +{ + public function test_getProviderDB() + { + $db = $this->createMock(\ilDBInterface::class); + $tree = $this->createMock(\ilTree::class); + $objDataCache = $this->createMock(\ilObjectDataCache::class); + + $dic = []; + $dic["ilDB"] = $db; + $dic["tree"] = $tree; + $dic["ilObjDataCache"] = $objDataCache; - $dic = []; - $dic["ilDB"] = $db; - $dic["tree"] = $tree; - $dic["ilObjDataCache"] = $objDataCache; + $mock = $this + ->getMockBuilder(ilObjectHelperMock::class) + ->setMethods(["getDIC"]) + ->getMock(); - $mock = $this - ->getMockBuilder(ilObjectHelperMock::class) - ->setMethods(["getDIC"]) - ->getMock(); - - $mock - ->expects($this->once()) - ->method("getDIC") - ->willReturn($dic); + $mock + ->expects($this->once()) + ->method("getDIC") + ->willReturn($dic); - $provider_db = $mock->_getProviderDB(); + $provider_db = $mock->_getProviderDB(); - $this->assertInstanceOf(Ente\ILIAS\ProviderDB::class, $provider_db); - } + $this->assertInstanceOf(Ente\ILIAS\ProviderDB::class, $provider_db); + } } diff --git a/tests/ILIAS/ilProviderDBTest.php b/tests/ILIAS/ilProviderDBTest.php index 58b5d82..e8475ac 100644 --- a/tests/ILIAS/ilProviderDBTest.php +++ b/tests/ILIAS/ilProviderDBTest.php @@ -1,944 +1,967 @@ - - * - * This software is licensed under GPLv3. You should have received a copy of - * the license along with the code. - */ - - use CaT\Ente\ILIAS\SeparatedUnboundProvider; - use CaT\Ente\ILIAS\UnboundProvider; - use CaT\Ente\Provider; - use CaT\Ente\ILIAS\ilProviderDB; - use CaT\Ente\Simple\AttachString; - use CaT\Ente\Simple\AttachInt; - - if (!class_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); - } - - if (!interface_exists("ilDBInterface")) { - require_once(__DIR__."/ilDBInterface.php"); - } - - if (!interface_exists("ilTree")) { - require_once(__DIR__."/ilTree.php"); - } - - if (!interface_exists("ilObjectDataCache")) { - require_once(__DIR__."/ilObjectDataCache.php"); - } - - class Test_ilProviderDB extends ilProviderDB { - public $object_ref = []; - public $throws = false; - protected function buildObjectByRefId(int $ref_id) : \ilObject - { - if ($this->throws) { - throw new \InvalidArgumentException(); - } - assert(isset($this->object_ref[$ref_id])); - return $this->object_ref[$ref_id]; - } - public $object_obj = []; - protected function buildObjectByObjId(int $obj_id) : \ilObject - { - if ($this->throws) { - throw new \InvalidArgumentException(); - } - assert(isset($this->object_obj[$obj_id])); - return $this->object_obj[$obj_id]; - } - public $reference_ids = []; - protected function getAllReferenceIdsFor(int $obj_id) :array - { - assert(isset($this->reference_ids[$obj_id])); - return $this->reference_ids[$obj_id]; - } - } - - class ILIAS_ilProviderDBTest extends PHPUnit_Framework_TestCase { - protected function il_db_mock() { - return $this->createMock(\ilDBInterface::class); - } - - public function il_tree_mock() { - return $this - ->getMockBuilder(\ilTree::class) - ->setMethods(["getSubTreeIds", "getNodePath"]) - ->getMock(); - } - - public function il_object_data_cache_mock() { - return $this - ->getMockBuilder(\ilObjectDataCache::class) - ->setMethods(["preloadReferenceCache", "lookupObjId"]) - ->getMock(); - } - - public function test_createTables() { - $il_db = $this->il_db_mock(); - - $provider_table = - [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "owner" => ["type" => "integer", "length" => 4, "notnull" => true] - , "object_type" => ["type" => "text", "length" => 4, "notnull" => true] - , "class_name" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] - , "include_path" => ["type" => "text", "length" => ilProviderDB::PATH_LENGTH, "notnull" => true] - ]; - $component_table = - [ "id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "component_type" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] - ]; - - $il_db - ->expects($this->exactly(2)) - ->method("createTable") - ->withConsecutive( - [ilProviderDB::PROVIDER_TABLE, $provider_table], - [ilProviderDB::COMPONENT_TABLE, $component_table]); - - $il_db - ->expects($this->exactly(2)) - ->method("tableExists") - ->withConsecutive([ilProviderDB::PROVIDER_TABLE], [ilProviderDB::COMPONENT_TABLE]) - ->will($this->onConsecutiveCalls(false, false)); - - $il_db - ->expects($this->exactly(2)) - ->method("addPrimaryKey") - ->withConsecutive( - [ilProviderDB::PROVIDER_TABLE, ["id"]], - [ilProviderDB::COMPONENT_TABLE, ["id", "component_type"]]); - - $il_db - ->expects($this->once()) - ->method("createSequence") - ->with(ilProviderDB::PROVIDER_TABLE); - - $il_db - ->expects($this->once()) - ->method("tableColumnExists") - ->with(ilProviderDB::PROVIDER_TABLE, "shared") - ->willReturn(false); - - $il_db - ->expects($this->once()) - ->method("addTableColumn") - ->with(ilProviderDB::PROVIDER_TABLE, "shared", ["type" => "integer", "length" => 1, "notnull" => true, "default" => 0]); - - $il_db - ->expects($this->once()) - ->method("addIndex") - ->with(ilProviderDB::PROVIDER_TABLE, ["shared"], "ids"); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $db->createTables(); - } - - public function test_create() { - $il_db = $this->il_db_mock(); - - $owner = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - $owner_id = 42; - $owner - ->method("getId") - ->willReturn($owner_id); - - $new_provider_id = 23; - $object_type = "crs"; - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $insert_provider = - [ "id" => ["integer", $new_provider_id] - , "owner" => ["integer", $owner_id] - , "object_type" => ["string", $object_type] - , "class_name" => ["string", $class_name] - , "include_path" => ["string", $include_path] - , "shared" => ["integer", 0] - ]; - - $insert_component_1 = - [ "id" => ["integer", $new_provider_id] - , "component_type" => ["string", AttachString::class] - ]; - - $insert_component_2 = - [ "id" => ["integer", $new_provider_id] - , "component_type" => ["string", AttachInt::class] - ]; - - $il_db - ->expects($this->exactly(3)) - ->method("insert") - ->withConsecutive( - [ilProviderDB::PROVIDER_TABLE, $insert_provider], - [ilProviderDB::COMPONENT_TABLE, $insert_component_1], - [ilProviderDB::COMPONENT_TABLE, $insert_component_2]); - - $il_db - ->expects($this->once()) - ->method("nextId") - ->with(ilProviderDB::PROVIDER_TABLE) - ->willReturn($new_provider_id); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $unbound_provider = $db->createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); - - $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $unbound_provider); - } - - public function test_delete() { - $il_db = $this->il_db_mock(); - - $owner = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - - $unbound_provider = $this->createMock(UnboundProvider::class); - - $unbound_provider_id = 23; - $unbound_provider - ->expects($this->once()) - ->method("idFor") - ->with($owner) - ->willReturn($unbound_provider_id); - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->with($unbound_provider_id, "integer") - ->willReturn("~$unbound_provider_id~"); - - $il_db - ->expects($this->exactly(2)) - ->method("manipulate") - ->withConsecutive( - ["DELETE FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ~$unbound_provider_id~"], - ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~$unbound_provider_id~"]); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $db->delete($unbound_provider, $owner); - } - - public function test_update() { - $il_db = $this->il_db_mock(); - - $owner1 = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - $owner2 = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - - $unbound_provider = $this->createMock(UnboundProvider::class); - - $unbound_provider - ->expects($this->once()) - ->method("owners") - ->willReturn([$owner1, $owner2]); - - $unbound_provider - ->expects($this->exactly(2)) - ->method("idFor") - ->withConsecutive([$owner1],[$owner2]) - ->will($this->onConsecutiveCalls(1,2)); - - $unbound_provider - ->expects($this->once()) - ->method("componentTypes") - ->willReturn([AttachString::class, AttachInt::class]); - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->withConsecutive([1, "integer"],[2, "integer"]) - ->will($this->returnCallback(function($int) { return "~$int~"; })); - - $il_db - ->expects($this->exactly(2)) - ->method("manipulate") - ->withConsecutive( - ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~1~"], - ["DELETE FROM ".ilProviderDB::COMPONENT_TABLE." WHERE id = ~2~"]); - - $insert_component_1 = - [ "id" => ["integer", 1] - , "component_type" => ["string", AttachString::class] - ]; - - $insert_component_2 = - [ "id" => ["integer", 1] - , "component_type" => ["string", AttachInt::class] - ]; - - $insert_component_3 = - [ "id" => ["integer", 2] - , "component_type" => ["string", AttachString::class] - ]; - - $insert_component_4 = - [ "id" => ["integer", 2] - , "component_type" => ["string", AttachInt::class] - ]; - - $il_db - ->expects($this->exactly(4)) - ->method("insert") - ->withConsecutive( - [ilProviderDB::COMPONENT_TABLE, $insert_component_1], - [ilProviderDB::COMPONENT_TABLE, $insert_component_2], - [ilProviderDB::COMPONENT_TABLE, $insert_component_3], - [ilProviderDB::COMPONENT_TABLE, $insert_component_4]); - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $db->update($unbound_provider); - } - - public function test_unboundProvidersOf() { - $il_db = $this->il_db_mock(); - - $owner = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getId"]) - ->getMock(); - $owner_id = 42; - $owner - ->expects($this->atLeastOnce()) - ->method("getId") - ->willReturn(42); - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->with($owner_id, "integer") - ->willReturn("~$owner_id~"); - - $result = "RESULT"; - $il_db - ->expects($this->once()) - ->method("query") - ->with("SELECT id, object_type, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE owner = ~$owner_id~") - ->willReturn($result); - - $object_type = "type"; - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(3)) - ->method("fetchAssoc") - ->with("RESULT") - ->will($this->onConsecutiveCalls( - ["id" => 1, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], - ["id" => 2, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], - null)); - - - $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); - $providers = $db->unboundProvidersOf($owner); - - $this->assertCount(2, $providers); - - foreach ($providers as $provider) { - $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); - $this->assertEquals($object_type, $provider->objectType()); - $this->assertEquals([$owner], $provider->owners()); - } - - list($provider1, $provider2) = $providers; - $this->assertEquals(1, $provider1->idFor($owner)); - $this->assertEquals(2, $provider2->idFor($owner)); - } - - public function test_load() { - $il_db = $this->il_db_mock(); - - $provider_id = 23; - $owner_id = 42; - - $il_db - ->expects($this->atLeastOnce()) - ->method("quote") - ->with($provider_id, "integer") - ->willReturn("~$provider_id~"); - $result = "RESULT"; - $il_db - ->expects($this->once()) - ->method("query") - ->with("SELECT owner, object_type, class_name, include_path FROM ".ilProviderDB::PROVIDER_TABLE." WHERE id = ~$provider_id~") - ->willReturn($result); - - $object_type = "type"; - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->once()) - ->method("fetchAssoc") - ->with("RESULT") - ->willReturn( - ["owner" => $owner_id, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path] - ); - - $db = new Test_ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock(), []); - $owner = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $db->object_obj[$owner_id] = $owner; - $provider = $db->load($provider_id); - - $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); - $this->assertEquals($object_type, $provider->objectType()); - $this->assertEquals([$owner], $provider->owners()); - $this->assertEquals($provider_id, $provider->idFor($owner)); - } - - public function test_providersFor() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = [3, 14]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); - - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive( - [ - "SELECT id, owner, class_name, include_path".PHP_EOL - ."FROM ente_prvs".PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~" - ], - [ - "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~".PHP_EOL - ."GROUP BY class_name, include_path" - ] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(4)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result1],[$result1],[$result2]) - ->will($this->onConsecutiveCalls( - ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], - ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null, - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - - $owner_1 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $db->object_ref[$sub_tree_ids[0]] = $owner_1; - - $owner_2 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $db->object_ref[$sub_tree_ids[1]] = $owner_2; - - $providers = $db->providersFor($object); - $this->assertCount(2, $providers); - - foreach ($providers as $provider) { - $this->assertInstanceOf(Provider::class, $provider); - $this->assertEquals($object, $provider->object()); - $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); - } - - list($provider1, $provider2) = $providers; - $this->assertEquals(1, $provider1->unboundProvider()->idFor($owner_1)); - $this->assertEquals([$owner_1], $provider1->owners()); - - $this->assertEquals(2, $provider2->unboundProvider()->idFor($owner_2)); - $this->assertEquals([$owner_2], $provider2->owners()); - - } - - public function test_providersFor_filtered() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = [3, 14]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); - - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $component_type = "COMPONENT_TYPE"; - $il_db - ->expects($this->exactly(4)) - ->method("quote") - ->withConsecutive([$object_type], [$component_type], [$object_type], [$component_type]) - ->will($this->onConsecutiveCalls("~TYPE~", "~COMPONENT_TYPE~", "~TYPE~", "~COMPONENT_TYPE~")); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive( - [ - "SELECT prv.id, prv.owner, prv.class_name, prv.include_path".PHP_EOL - ."FROM ente_prvs prv".PHP_EOL - ."JOIN ente_prv_cmps cmp".PHP_EOL - ." ON prv.id = cmp.id".PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~".PHP_EOL - ." AND component_type = ~COMPONENT_TYPE~" - ], - [ - "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(prv.owner SEPARATOR \",\") owners,".PHP_EOL - ."prv.class_name, prv.include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE." prv".PHP_EOL - ."JOIN ".ilProviderDB::COMPONENT_TABLE." cmp".PHP_EOL - ." ON prv.id = cmp.id".PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~".PHP_EOL - ." AND component_type = ~COMPONENT_TYPE~".PHP_EOL - ."GROUP BY prv.class_name, prv.include_path" - ] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $il_db - ->expects($this->exactly(2)) - ->method("fetchAssoc") - ->withConsecutive([$result1], [$result2]) - ->willReturn(null); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - - $providers = $db->providersFor($object, "COMPONENT_TYPE"); - $this->assertCount(0, $providers); - } - - public function test_providersFor_shared() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = [3, 14]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); - - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive( - [ - "SELECT id, owner, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~" - ], - [ - "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~".PHP_EOL - ."GROUP BY class_name, include_path" - ] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = "Test_SharedUnboundProvider"; - $include_path = __DIR__."/SharedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(3)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result2],[$result2]) - ->will($this->onConsecutiveCalls( - null, - ["ids" => "1,2", "owners" => $sub_tree_ids[0].",".$sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - - $owner_1 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $owner_1 - ->method("getId") - ->willReturn("23"); - $db->object_ref[$sub_tree_ids[0]] = $owner_1; - - $owner_2 = $this - ->getMockBuilder(\ilObject::class) - ->getMock(); - $owner_2 - ->method("getId") - ->willReturn("24"); - $db->object_ref[$sub_tree_ids[1]] = $owner_2; - - $providers = $db->providersFor($object); - $this->assertCount(1, $providers); - $provider = array_shift($providers); - - $this->assertInstanceOf(Provider::class, $provider); - $this->assertEquals($object, $provider->object()); - $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); - $this->assertEquals([$owner_1, $owner_2], $provider->unboundProvider()->owners()); - - $this->assertEquals(1, $provider->unboundProvider()->idFor($owner_1)); - $this->assertEquals(2, $provider->unboundProvider()->idFor($owner_2)); - } - - public function test_providersFor_for_unbuildable_object() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = [3, 14]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); - - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive( - [ - "SELECT id, owner, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~" - ], - [ - "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~".PHP_EOL - ."GROUP BY class_name, include_path" - ] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = Test_SeparatedUnboundProvider::class; - $include_path = __DIR__."/SeparatedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(4)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result1],[$result1],[$result2]) - ->will($this->onConsecutiveCalls( - ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], - ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null, - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - $db->throws = true; - - $providers = $db->providersFor($object); - $this->assertCount(0, $providers); - } - - public function test_providersFor_shared_for_unbuildable_objects() { - $il_db = $this->il_db_mock(); - $il_tree = $this->il_tree_mock(); - $il_cache = $this->il_object_data_cache_mock(); - - $object_ref_id = 42; - $object_type = "crs"; - $object = $this - ->getMockBuilder(\ilObject::class) - ->setMethods(["getRefId", "getType"]) - ->getMock(); - - $object - ->expects($this->atLeastOnce()) - ->method("getRefId") - ->willReturn($object_ref_id); - - $object - ->expects($this->atLeastOnce()) - ->method("getType") - ->willReturn($object_type); - - $sub_tree_ids = [3, 14]; - $il_tree - ->expects($this->once()) - ->method("getSubTreeIds") - ->with($object_ref_id) - ->willReturn($sub_tree_ids); - - $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); - $il_cache - ->expects($this->once()) - ->method("preloadReferenceCache") - ->with($tree_ids); - - $il_cache - ->expects($this->exactly(3)) - ->method("lookupObjId") - ->withConsecutive([$tree_ids[0]],[$tree_ids[1]], [$tree_ids[2]]) - ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); - - $il_db - ->expects($this->exactly(2)) - ->method("in") - ->with("owner", $tree_ids, false, "integer") - ->willReturn("~IN~"); - - $il_db - ->expects($this->exactly(2)) - ->method("quote") - ->with($object_type) - ->willReturn("~TYPE~"); - - $result1 = "RESULT 1"; - $result2 = "RESULT 2"; - $il_db - ->expects($this->exactly(2)) - ->method("query") - ->withConsecutive( - [ - "SELECT id, owner, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 0".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~" - ], - [ - "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids,".PHP_EOL - ."GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path".PHP_EOL - ."FROM ".ilProviderDB::PROVIDER_TABLE.PHP_EOL - ."WHERE shared = 1".PHP_EOL - ." AND ~IN~".PHP_EOL - ." AND object_type = ~TYPE~".PHP_EOL - ."GROUP BY class_name, include_path" - ] - ) - ->will($this->onConsecutiveCalls($result1, $result2)); - - $class_name = "Test_SharedUnboundProvider"; - $include_path = __DIR__."/SharedUnboundProviderTest.php"; - - $il_db - ->expects($this->exactly(3)) - ->method("fetchAssoc") - ->withConsecutive([$result1],[$result2],[$result2]) - ->will($this->onConsecutiveCalls( - null, - ["ids" => "1,2", "owners" => $sub_tree_ids[0].",".$sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], - null)); - - $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); - $db->throws = true; - - $providers = $db->providersFor($object); - $this->assertCount(0, $providers); - } - - } + + * + * This software is licensed under GPLv3. You should have received a copy of + * the license along with the code. + */ + +use CaT\Ente\ILIAS\SeparatedUnboundProvider; +use CaT\Ente\ILIAS\UnboundProvider; +use CaT\Ente\Provider; +use CaT\Ente\ILIAS\ilProviderDB; +use CaT\Ente\Simple\AttachString; +use CaT\Ente\Simple\AttachInt; + +if (!class_exists("ilObject")) { + require_once(__DIR__ . "/ilObject.php"); +} + +if (!interface_exists("ilDBInterface")) { + require_once(__DIR__ . "/ilDBInterface.php"); +} + +if (!interface_exists("ilTree")) { + require_once(__DIR__ . "/ilTree.php"); +} + +if (!interface_exists("ilObjectDataCache")) { + require_once(__DIR__ . "/ilObjectDataCache.php"); +} + +class Test_ilProviderDB extends ilProviderDB +{ + public $object_ref = []; + public $throws = false; + + protected function buildObjectByRefId(int $ref_id): \ilObject + { + if ($this->throws) { + throw new \InvalidArgumentException(); + } + assert(isset($this->object_ref[$ref_id])); + return $this->object_ref[$ref_id]; + } + + public $object_obj = []; + + protected function buildObjectByObjId(int $obj_id): \ilObject + { + if ($this->throws) { + throw new \InvalidArgumentException(); + } + assert(isset($this->object_obj[$obj_id])); + return $this->object_obj[$obj_id]; + } + + public $reference_ids = []; + + protected function getAllReferenceIdsFor(int $obj_id): array + { + assert(isset($this->reference_ids[$obj_id])); + return $this->reference_ids[$obj_id]; + } +} + +class ILIAS_ilProviderDBTest extends PHPUnit_Framework_TestCase +{ + protected function il_db_mock() + { + return $this->createMock(\ilDBInterface::class); + } + + public function il_tree_mock() + { + return $this + ->getMockBuilder(\ilTree::class) + ->setMethods(["getSubTreeIds", "getNodePath"]) + ->getMock(); + } + + public function il_object_data_cache_mock() + { + return $this + ->getMockBuilder(\ilObjectDataCache::class) + ->setMethods(["preloadReferenceCache", "lookupObjId"]) + ->getMock(); + } + + public function test_createTables() + { + $il_db = $this->il_db_mock(); + + $provider_table = + ["id" => ["type" => "integer", "length" => 4, "notnull" => true] + , "owner" => ["type" => "integer", "length" => 4, "notnull" => true] + , "object_type" => ["type" => "text", "length" => 4, "notnull" => true] + , "class_name" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] + , "include_path" => ["type" => "text", "length" => ilProviderDB::PATH_LENGTH, "notnull" => true] + ]; + $component_table = + ["id" => ["type" => "integer", "length" => 4, "notnull" => true] + , "component_type" => ["type" => "text", "length" => ilProviderDB::CLASS_NAME_LENGTH, "notnull" => true] + ]; + + $il_db + ->expects($this->exactly(2)) + ->method("createTable") + ->withConsecutive( + [ilProviderDB::PROVIDER_TABLE, $provider_table], + [ilProviderDB::COMPONENT_TABLE, $component_table]); + + $il_db + ->expects($this->exactly(2)) + ->method("tableExists") + ->withConsecutive([ilProviderDB::PROVIDER_TABLE], [ilProviderDB::COMPONENT_TABLE]) + ->will($this->onConsecutiveCalls(false, false)); + + $il_db + ->expects($this->exactly(2)) + ->method("addPrimaryKey") + ->withConsecutive( + [ilProviderDB::PROVIDER_TABLE, ["id"]], + [ilProviderDB::COMPONENT_TABLE, ["id", "component_type"]]); + + $il_db + ->expects($this->once()) + ->method("createSequence") + ->with(ilProviderDB::PROVIDER_TABLE); + + $il_db + ->expects($this->once()) + ->method("tableColumnExists") + ->with(ilProviderDB::PROVIDER_TABLE, "shared") + ->willReturn(false); + + $il_db + ->expects($this->once()) + ->method("addTableColumn") + ->with(ilProviderDB::PROVIDER_TABLE, "shared", ["type" => "integer", "length" => 1, "notnull" => true, "default" => 0]); + + $il_db + ->expects($this->once()) + ->method("addIndex") + ->with(ilProviderDB::PROVIDER_TABLE, ["shared"], "ids"); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $db->createTables(); + } + + public function test_create() + { + $il_db = $this->il_db_mock(); + + $owner = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + $owner_id = 42; + $owner + ->method("getId") + ->willReturn($owner_id); + + $new_provider_id = 23; + $object_type = "crs"; + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; + + $insert_provider = + ["id" => ["integer", $new_provider_id] + , "owner" => ["integer", $owner_id] + , "object_type" => ["string", $object_type] + , "class_name" => ["string", $class_name] + , "include_path" => ["string", $include_path] + , "shared" => ["integer", 0] + ]; + + $insert_component_1 = + ["id" => ["integer", $new_provider_id] + , "component_type" => ["string", AttachString::class] + ]; + + $insert_component_2 = + ["id" => ["integer", $new_provider_id] + , "component_type" => ["string", AttachInt::class] + ]; + + $il_db + ->expects($this->exactly(3)) + ->method("insert") + ->withConsecutive( + [ilProviderDB::PROVIDER_TABLE, $insert_provider], + [ilProviderDB::COMPONENT_TABLE, $insert_component_1], + [ilProviderDB::COMPONENT_TABLE, $insert_component_2]); + + $il_db + ->expects($this->once()) + ->method("nextId") + ->with(ilProviderDB::PROVIDER_TABLE) + ->willReturn($new_provider_id); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $unbound_provider = $db->createSeparatedUnboundProvider($owner, $object_type, $class_name, $include_path); + + $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $unbound_provider); + } + + public function test_delete() + { + $il_db = $this->il_db_mock(); + + $owner = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + + $unbound_provider = $this->createMock(UnboundProvider::class); + + $unbound_provider_id = 23; + $unbound_provider + ->expects($this->once()) + ->method("idFor") + ->with($owner) + ->willReturn($unbound_provider_id); + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->with($unbound_provider_id, "integer") + ->willReturn("~$unbound_provider_id~"); + + $il_db + ->expects($this->exactly(2)) + ->method("manipulate") + ->withConsecutive( + ["DELETE FROM " . ilProviderDB::PROVIDER_TABLE . " WHERE id = ~$unbound_provider_id~"], + ["DELETE FROM " . ilProviderDB::COMPONENT_TABLE . " WHERE id = ~$unbound_provider_id~"]); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $db->delete($unbound_provider, $owner); + } + + public function test_update() + { + $il_db = $this->il_db_mock(); + + $owner1 = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + $owner2 = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + + $unbound_provider = $this->createMock(UnboundProvider::class); + + $unbound_provider + ->expects($this->once()) + ->method("owners") + ->willReturn([$owner1, $owner2]); + + $unbound_provider + ->expects($this->exactly(2)) + ->method("idFor") + ->withConsecutive([$owner1], [$owner2]) + ->will($this->onConsecutiveCalls(1, 2)); + + $unbound_provider + ->expects($this->once()) + ->method("componentTypes") + ->willReturn([AttachString::class, AttachInt::class]); + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->withConsecutive([1, "integer"], [2, "integer"]) + ->will($this->returnCallback(function ($int) { + return "~$int~"; + })); + + $il_db + ->expects($this->exactly(2)) + ->method("manipulate") + ->withConsecutive( + ["DELETE FROM " . ilProviderDB::COMPONENT_TABLE . " WHERE id = ~1~"], + ["DELETE FROM " . ilProviderDB::COMPONENT_TABLE . " WHERE id = ~2~"]); + + $insert_component_1 = + ["id" => ["integer", 1] + , "component_type" => ["string", AttachString::class] + ]; + + $insert_component_2 = + ["id" => ["integer", 1] + , "component_type" => ["string", AttachInt::class] + ]; + + $insert_component_3 = + ["id" => ["integer", 2] + , "component_type" => ["string", AttachString::class] + ]; + + $insert_component_4 = + ["id" => ["integer", 2] + , "component_type" => ["string", AttachInt::class] + ]; + + $il_db + ->expects($this->exactly(4)) + ->method("insert") + ->withConsecutive( + [ilProviderDB::COMPONENT_TABLE, $insert_component_1], + [ilProviderDB::COMPONENT_TABLE, $insert_component_2], + [ilProviderDB::COMPONENT_TABLE, $insert_component_3], + [ilProviderDB::COMPONENT_TABLE, $insert_component_4]); + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $db->update($unbound_provider); + } + + public function test_unboundProvidersOf() + { + $il_db = $this->il_db_mock(); + + $owner = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getId"]) + ->getMock(); + $owner_id = 42; + $owner + ->expects($this->atLeastOnce()) + ->method("getId") + ->willReturn(42); + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->with($owner_id, "integer") + ->willReturn("~$owner_id~"); + + $result = "RESULT"; + $il_db + ->expects($this->once()) + ->method("query") + ->with("SELECT id, object_type, class_name, include_path FROM " . ilProviderDB::PROVIDER_TABLE . " WHERE owner = ~$owner_id~") + ->willReturn($result); + + $object_type = "type"; + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(3)) + ->method("fetchAssoc") + ->with("RESULT") + ->will($this->onConsecutiveCalls( + ["id" => 1, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], + ["id" => 2, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path], + null)); + + + $db = new ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock()); + $providers = $db->unboundProvidersOf($owner); + + $this->assertCount(2, $providers); + + foreach ($providers as $provider) { + $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); + $this->assertEquals($object_type, $provider->objectType()); + $this->assertEquals([$owner], $provider->owners()); + } + + list($provider1, $provider2) = $providers; + $this->assertEquals(1, $provider1->idFor($owner)); + $this->assertEquals(2, $provider2->idFor($owner)); + } + + public function test_load() + { + $il_db = $this->il_db_mock(); + + $provider_id = 23; + $owner_id = 42; + + $il_db + ->expects($this->atLeastOnce()) + ->method("quote") + ->with($provider_id, "integer") + ->willReturn("~$provider_id~"); + $result = "RESULT"; + $il_db + ->expects($this->once()) + ->method("query") + ->with("SELECT owner, object_type, class_name, include_path FROM " . ilProviderDB::PROVIDER_TABLE . " WHERE id = ~$provider_id~") + ->willReturn($result); + + $object_type = "type"; + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->once()) + ->method("fetchAssoc") + ->with("RESULT") + ->willReturn( + ["owner" => $owner_id, "object_type" => $object_type, "class_name" => $class_name, "include_path" => $include_path] + ); + + $db = new Test_ilProviderDB($il_db, $this->il_tree_mock(), $this->il_object_data_cache_mock(), []); + $owner = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $db->object_obj[$owner_id] = $owner; + $provider = $db->load($provider_id); + + $this->assertInstanceOf(Test_SeparatedUnboundProvider::class, $provider); + $this->assertEquals($object_type, $provider->objectType()); + $this->assertEquals([$owner], $provider->owners()); + $this->assertEquals($provider_id, $provider->idFor($owner)); + } + + public function test_providersFor() + { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); + + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path" . PHP_EOL + . "FROM ente_prvs" . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" . PHP_EOL + . "GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(4)) + ->method("fetchAssoc") + ->withConsecutive([$result1], [$result1], [$result1], [$result2]) + ->will($this->onConsecutiveCalls( + ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], + ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null, + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + + $owner_1 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $db->object_ref[$sub_tree_ids[0]] = $owner_1; + + $owner_2 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $db->object_ref[$sub_tree_ids[1]] = $owner_2; + + $providers = $db->providersFor($object); + $this->assertCount(2, $providers); + + foreach ($providers as $provider) { + $this->assertInstanceOf(Provider::class, $provider); + $this->assertEquals($object, $provider->object()); + $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); + } + + list($provider1, $provider2) = $providers; + $this->assertEquals(1, $provider1->unboundProvider()->idFor($owner_1)); + $this->assertEquals([$owner_1], $provider1->owners()); + + $this->assertEquals(2, $provider2->unboundProvider()->idFor($owner_2)); + $this->assertEquals([$owner_2], $provider2->owners()); + + } + + public function test_providersFor_filtered() + { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); + + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $component_type = "COMPONENT_TYPE"; + $il_db + ->expects($this->exactly(4)) + ->method("quote") + ->withConsecutive([$object_type], [$component_type], [$object_type], [$component_type]) + ->will($this->onConsecutiveCalls("~TYPE~", "~COMPONENT_TYPE~", "~TYPE~", "~COMPONENT_TYPE~")); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT prv.id, prv.owner, prv.class_name, prv.include_path" . PHP_EOL + . "FROM ente_prvs prv" . PHP_EOL + . "JOIN ente_prv_cmps cmp" . PHP_EOL + . " ON prv.id = cmp.id" . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" . PHP_EOL + . " AND component_type = ~COMPONENT_TYPE~" + ], + [ + "SELECT GROUP_CONCAT(prv.id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(prv.owner SEPARATOR \",\") owners," . PHP_EOL + . "prv.class_name, prv.include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . " prv" . PHP_EOL + . "JOIN " . ilProviderDB::COMPONENT_TABLE . " cmp" . PHP_EOL + . " ON prv.id = cmp.id" . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" . PHP_EOL + . " AND component_type = ~COMPONENT_TYPE~" . PHP_EOL + . "GROUP BY prv.class_name, prv.include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $il_db + ->expects($this->exactly(2)) + ->method("fetchAssoc") + ->withConsecutive([$result1], [$result2]) + ->willReturn(null); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + + $providers = $db->providersFor($object, "COMPONENT_TYPE"); + $this->assertCount(0, $providers); + } + + public function test_providersFor_shared() + { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); + + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" . PHP_EOL + . "GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = "Test_SharedUnboundProvider"; + $include_path = __DIR__ . "/SharedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(3)) + ->method("fetchAssoc") + ->withConsecutive([$result1], [$result2], [$result2]) + ->will($this->onConsecutiveCalls( + null, + ["ids" => "1,2", "owners" => $sub_tree_ids[0] . "," . $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + + $owner_1 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $owner_1 + ->method("getId") + ->willReturn("23"); + $db->object_ref[$sub_tree_ids[0]] = $owner_1; + + $owner_2 = $this + ->getMockBuilder(\ilObject::class) + ->getMock(); + $owner_2 + ->method("getId") + ->willReturn("24"); + $db->object_ref[$sub_tree_ids[1]] = $owner_2; + + $providers = $db->providersFor($object); + $this->assertCount(1, $providers); + $provider = array_shift($providers); + + $this->assertInstanceOf(Provider::class, $provider); + $this->assertEquals($object, $provider->object()); + $this->assertEquals($object_type, $provider->unboundProvider()->objectType()); + $this->assertEquals([$owner_1, $owner_2], $provider->unboundProvider()->owners()); + + $this->assertEquals(1, $provider->unboundProvider()->idFor($owner_1)); + $this->assertEquals(2, $provider->unboundProvider()->idFor($owner_2)); + } + + public function test_providersFor_for_unbuildable_object() + { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); + + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" . PHP_EOL + . "GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = Test_SeparatedUnboundProvider::class; + $include_path = __DIR__ . "/SeparatedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(4)) + ->method("fetchAssoc") + ->withConsecutive([$result1], [$result1], [$result1], [$result2]) + ->will($this->onConsecutiveCalls( + ["id" => 1, "owner" => $sub_tree_ids[0], "class_name" => $class_name, "include_path" => $include_path], + ["id" => 2, "owner" => $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null, + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + $db->throws = true; + + $providers = $db->providersFor($object); + $this->assertCount(0, $providers); + } + + public function test_providersFor_shared_for_unbuildable_objects() + { + $il_db = $this->il_db_mock(); + $il_tree = $this->il_tree_mock(); + $il_cache = $this->il_object_data_cache_mock(); + + $object_ref_id = 42; + $object_type = "crs"; + $object = $this + ->getMockBuilder(\ilObject::class) + ->setMethods(["getRefId", "getType"]) + ->getMock(); + + $object + ->expects($this->atLeastOnce()) + ->method("getRefId") + ->willReturn($object_ref_id); + + $object + ->expects($this->atLeastOnce()) + ->method("getType") + ->willReturn($object_type); + + $sub_tree_ids = [3, 14]; + $il_tree + ->expects($this->once()) + ->method("getSubTreeIds") + ->with($object_ref_id) + ->willReturn($sub_tree_ids); + + $tree_ids = array_merge([$object_ref_id], $sub_tree_ids); + $il_cache + ->expects($this->once()) + ->method("preloadReferenceCache") + ->with($tree_ids); + + $il_cache + ->expects($this->exactly(3)) + ->method("lookupObjId") + ->withConsecutive([$tree_ids[0]], [$tree_ids[1]], [$tree_ids[2]]) + ->will($this->onConsecutiveCalls($tree_ids[0], $tree_ids[1], $tree_ids[2])); + + $il_db + ->expects($this->exactly(2)) + ->method("in") + ->with("owner", $tree_ids, false, "integer") + ->willReturn("~IN~"); + + $il_db + ->expects($this->exactly(2)) + ->method("quote") + ->with($object_type) + ->willReturn("~TYPE~"); + + $result1 = "RESULT 1"; + $result2 = "RESULT 2"; + $il_db + ->expects($this->exactly(2)) + ->method("query") + ->withConsecutive( + [ + "SELECT id, owner, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 0" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" + ], + [ + "SELECT GROUP_CONCAT(id SEPARATOR \",\") ids," . PHP_EOL + . "GROUP_CONCAT(owner SEPARATOR \",\") owners, class_name, include_path" . PHP_EOL + . "FROM " . ilProviderDB::PROVIDER_TABLE . PHP_EOL + . "WHERE shared = 1" . PHP_EOL + . " AND ~IN~" . PHP_EOL + . " AND object_type = ~TYPE~" . PHP_EOL + . "GROUP BY class_name, include_path" + ] + ) + ->will($this->onConsecutiveCalls($result1, $result2)); + + $class_name = "Test_SharedUnboundProvider"; + $include_path = __DIR__ . "/SharedUnboundProviderTest.php"; + + $il_db + ->expects($this->exactly(3)) + ->method("fetchAssoc") + ->withConsecutive([$result1], [$result2], [$result2]) + ->will($this->onConsecutiveCalls( + null, + ["ids" => "1,2", "owners" => $sub_tree_ids[0] . "," . $sub_tree_ids[1], "class_name" => $class_name, "include_path" => $include_path], + null)); + + $db = new Test_ilProviderDB($il_db, $il_tree, $il_cache, []); + $db->throws = true; + + $providers = $db->providersFor($object); + $this->assertCount(0, $providers); + } + +} diff --git a/tests/ILIAS/ilProviderObjectHelperTest.php b/tests/ILIAS/ilProviderObjectHelperTest.php index 3800737..79670ae 100644 --- a/tests/ILIAS/ilProviderObjectHelperTest.php +++ b/tests/ILIAS/ilProviderObjectHelperTest.php @@ -12,139 +12,160 @@ if (!interface_exists("ilDBInterface")) { - require_once(__DIR__."/ilDBInterface.php"); + require_once(__DIR__ . "/ilDBInterface.php"); } if (!interface_exists("ilTree")) { - require_once(__DIR__."/ilTree.php"); + require_once(__DIR__ . "/ilTree.php"); } if (!interface_exists("ilObjectDataCache")) { - require_once(__DIR__."/ilObjectDataCache.php"); + require_once(__DIR__ . "/ilObjectDataCache.php"); } if (!interface_exists("ilObject")) { - require_once(__DIR__."/ilObject.php"); + require_once(__DIR__ . "/ilObject.php"); } -abstract class ilProviderObjectHelperMock extends ilObject { - use Ente\ILIAS\ilProviderObjectHelper; - public function _deleteUnboundProviders() { - $this->deleteUnboundProviders(); - } - public function _createUnboundProvider($object_type, $class_name, $path) { - $this->createUnboundProvider($object_type, $class_name, $path); - } +abstract class ilProviderObjectHelperMock extends ilObject +{ + use Ente\ILIAS\ilProviderObjectHelper; + + public function _deleteUnboundProviders() + { + $this->deleteUnboundProviders(); + } + + public function _createUnboundProvider($object_type, $class_name, $path) + { + $this->createUnboundProvider($object_type, $class_name, $path); + } } -class _SeparatedUnboundProvider extends Ente\ILIAS\SeparatedUnboundProvider { - public function componentTypes() {} - public function buildComponentsOf(string $c, Ente\Entity $e) : array {} +class _SeparatedUnboundProvider extends Ente\ILIAS\SeparatedUnboundProvider +{ + public function componentTypes() + { + } + + public function buildComponentsOf(string $c, Ente\Entity $e): array + { + } } -class _SharedUnboundProvider extends Ente\ILIAS\SharedUnboundProvider { - public function componentTypes() {} - public function buildComponentsOf(string $c, Ente\Entity $e) : array {} +class _SharedUnboundProvider extends Ente\ILIAS\SharedUnboundProvider +{ + public function componentTypes() + { + } + + public function buildComponentsOf(string $c, Ente\Entity $e): array + { + } } -class ilProviderObjectHelperTest extends PHPUnit_Framework_TestCase { - public function test_deleteUnboundProviders() { - $provider_db = $this->createMock(Ente\ILIAS\ilProviderDB::class); - $up1 = $this->createMock(Ente\ILIAS\UnboundProvider::class); - $up2 = $this->createMock(Ente\ILIAS\UnboundProvider::class); - - $mock = $this - ->getMockBuilder(ilProviderObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC"]) - ->getMock(); - - $mock - ->expects($this->atLeast(1)) - ->method("getProviderDB") - ->willReturn($provider_db); - - $provider_db - ->expects($this->once()) - ->method("unboundProvidersOf") - ->with($mock) - ->willReturn([$up1, $up2]); - - $provider_db - ->expects($this->exactly(2)) - ->method("delete") - ->withConsecutive([$up1], [$up2]); - - $mock->_deleteUnboundProviders(); - } - - public function test_createSeperatedUnboundProvider() { - $provider_db = $this->createMock(Ente\ILIAS\ilProviderDB::class); - - $mock = $this - ->getMockBuilder(ilProviderObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC"]) - ->getMock(); - - $mock - ->expects($this->once()) - ->method("getProviderDB") - ->willReturn($provider_db); - - $object_type = "TYPE"; - $class_name = _SeparatedUnboundProvider::class; - $path = "PATH"; - - $provider_db - ->expects($this->once()) - ->method("createSeparatedUnboundProvider") - ->with($mock, $object_type, $class_name, $path); - - $mock->_createUnboundProvider($object_type, $class_name, $path); - } - - public function test_createSharedUnboundProvider() { - $provider_db = $this->createMock(Ente\ILIAS\ilProviderDB::class); - - $mock = $this - ->getMockBuilder(ilProviderObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC"]) - ->getMock(); - - $mock - ->expects($this->once()) - ->method("getProviderDB") - ->willReturn($provider_db); - - $object_type = "TYPE"; - $class_name = _SharedUnboundProvider::class; - $path = "PATH"; - - $provider_db - ->expects($this->once()) - ->method("createSharedUnboundProvider") - ->with($mock, $object_type, $class_name, $path); - - $mock->_createUnboundProvider($object_type, $class_name, $path); - } - - public function test_createUnboundProvider_with_non_provider_class() { - $object_type = "TYPE"; - $class_name = "CLASS"; - $path = "PATH"; - - $mock = $this - ->getMockBuilder(ilProviderObjectHelperMock::class) - ->setMethods(["getProviderDB", "getDIC"]) - ->getMock(); - - $thrown = true; - try { - $mock->_createUnboundProvider($object_type, $class_name, $path); - $this->assertFalse("This should not happen."); - } - catch (\LogicException $e) { - $thrown = true; - } - $this->assertTrue($thrown); - } +class ilProviderObjectHelperTest extends PHPUnit_Framework_TestCase +{ + public function test_deleteUnboundProviders() + { + $provider_db = $this->createMock(Ente\ILIAS\ilProviderDB::class); + $up1 = $this->createMock(Ente\ILIAS\UnboundProvider::class); + $up2 = $this->createMock(Ente\ILIAS\UnboundProvider::class); + + $mock = $this + ->getMockBuilder(ilProviderObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC"]) + ->getMock(); + + $mock + ->expects($this->atLeast(1)) + ->method("getProviderDB") + ->willReturn($provider_db); + + $provider_db + ->expects($this->once()) + ->method("unboundProvidersOf") + ->with($mock) + ->willReturn([$up1, $up2]); + + $provider_db + ->expects($this->exactly(2)) + ->method("delete") + ->withConsecutive([$up1], [$up2]); + + $mock->_deleteUnboundProviders(); + } + + public function test_createSeperatedUnboundProvider() + { + $provider_db = $this->createMock(Ente\ILIAS\ilProviderDB::class); + + $mock = $this + ->getMockBuilder(ilProviderObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC"]) + ->getMock(); + + $mock + ->expects($this->once()) + ->method("getProviderDB") + ->willReturn($provider_db); + + $object_type = "TYPE"; + $class_name = _SeparatedUnboundProvider::class; + $path = "PATH"; + + $provider_db + ->expects($this->once()) + ->method("createSeparatedUnboundProvider") + ->with($mock, $object_type, $class_name, $path); + + $mock->_createUnboundProvider($object_type, $class_name, $path); + } + + public function test_createSharedUnboundProvider() + { + $provider_db = $this->createMock(Ente\ILIAS\ilProviderDB::class); + + $mock = $this + ->getMockBuilder(ilProviderObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC"]) + ->getMock(); + + $mock + ->expects($this->once()) + ->method("getProviderDB") + ->willReturn($provider_db); + + $object_type = "TYPE"; + $class_name = _SharedUnboundProvider::class; + $path = "PATH"; + + $provider_db + ->expects($this->once()) + ->method("createSharedUnboundProvider") + ->with($mock, $object_type, $class_name, $path); + + $mock->_createUnboundProvider($object_type, $class_name, $path); + } + + public function test_createUnboundProvider_with_non_provider_class() + { + $object_type = "TYPE"; + $class_name = "CLASS"; + $path = "PATH"; + + $mock = $this + ->getMockBuilder(ilProviderObjectHelperMock::class) + ->setMethods(["getProviderDB", "getDIC"]) + ->getMock(); + + $thrown = true; + try { + $mock->_createUnboundProvider($object_type, $class_name, $path); + $this->assertFalse("This should not happen."); + } catch (\LogicException $e) { + $thrown = true; + } + $this->assertTrue($thrown); + } } diff --git a/tests/ILIAS/ilTree.php b/tests/ILIAS/ilTree.php index d172ee2..ea8cb68 100644 --- a/tests/ILIAS/ilTree.php +++ b/tests/ILIAS/ilTree.php @@ -11,33 +11,36 @@ /** * Essentials of ILIAS tree for this framework. */ -abstract class ilTree { +abstract class ilTree +{ /** * Get all ids of subnodes - * @return * @param object $a_ref_id + * @return */ - public function getSubTreeIds($a_ref_id) { + public function getSubTreeIds($a_ref_id) + { assert(false); } - /** - * Returns the node path for the specified object reference. - * - * Note: this function returns the same result as getNodePathForTitlePath, - * but takes ref-id's as parameters. - * - * This function differs from getPathFull, in the following aspects: - * - The title of an object is not translated into the language of the user - * - This function is significantly faster than getPathFull. - * - * @access public - * @param integer node_id of endnode - * @param integer node_id of startnode (optional) - * @return array ordered path info (depth,parent,child,obj_id,type,title) - * or null, if the node_id can not be converted into a node path. - */ - public function getNodePath($a_endnode_id, $a_startnode_id = 0) { + /** + * Returns the node path for the specified object reference. + * + * Note: this function returns the same result as getNodePathForTitlePath, + * but takes ref-id's as parameters. + * + * This function differs from getPathFull, in the following aspects: + * - The title of an object is not translated into the language of the user + * - This function is significantly faster than getPathFull. + * + * @access public + * @param integer node_id of endnode + * @param integer node_id of startnode (optional) + * @return array ordered path info (depth,parent,child,obj_id,type,title) + * or null, if the node_id can not be converted into a node path. + */ + public function getNodePath($a_endnode_id, $a_startnode_id = 0) + { assert(false); } } diff --git a/tests/ProviderHelperTest.php b/tests/ProviderHelperTest.php index 090a1de..bfd83bd 100644 --- a/tests/ProviderHelperTest.php +++ b/tests/ProviderHelperTest.php @@ -12,26 +12,35 @@ use CaT\Ente\Component; use CaT\Ente\ProviderHelper; -interface SomeComponent extends Component { +interface SomeComponent extends Component +{ } -interface SomeOtherComponent extends Component { +interface SomeOtherComponent extends Component +{ } -interface Unrelated { +interface Unrelated +{ } -class SomeComponentImplementation implements SomeComponent, SomeOtherComponent, Unrelated { - public function entity() : Entity { throw new \RuntimeException(); } +class SomeComponentImplementation implements SomeComponent, SomeOtherComponent, Unrelated +{ + public function entity(): Entity + { + throw new \RuntimeException(); + } } -class ProviderHelperTest extends PHPUnit_Framework_TestCase { - use ProviderHelper; +class ProviderHelperTest extends PHPUnit_Framework_TestCase +{ + use ProviderHelper; - public function test_componentTypesOf() { + public function test_componentTypesOf() + { $impl = new SomeComponentImplementation(); $expected = [SomeComponent::class, SomeOtherComponent::class]; $this->assertEquals($expected, $this->componentTypesOf($impl)); - } + } } diff --git a/tests/ProviderTest.php b/tests/ProviderTest.php index 2fa3163..4c2198e 100644 --- a/tests/ProviderTest.php +++ b/tests/ProviderTest.php @@ -13,7 +13,8 @@ /** * This testcases must be passed by a Provider. */ -abstract class ProviderTest extends PHPUnit_Framework_TestCase { +abstract class ProviderTest extends PHPUnit_Framework_TestCase +{ /** * To make this interesting, the provider should at least provide for one * entity. @@ -31,7 +32,8 @@ abstract protected function doesNotProvideComponentType(); // TEST - public function test_only_provides_announced_component_types() { + public function test_only_provides_announced_component_types() + { $provider = $this->provider(); foreach ($this->doesNotProvideComponentType() as $component_type) { $this->assertEmpty($provider->componentsOfType($component_type)); @@ -41,10 +43,11 @@ public function test_only_provides_announced_component_types() { /** * @dataProvider component_types */ - public function test_provides_for_own_entity($component_type) { + public function test_provides_for_own_entity($component_type) + { $provider = $this->provider(); $id = $provider->entity()->id(); - foreach($provider->componentsOfType($component_type) as $component) { + foreach ($provider->componentsOfType($component_type) as $component) { $this->assertEquals(serialize($id), serialize($component->entity()->id())); } } @@ -52,16 +55,18 @@ public function test_provides_for_own_entity($component_type) { /** * @dataProvider component_types */ - public function test_provides_expected_component_types($component_type) { + public function test_provides_expected_component_types($component_type) + { $provider = $this->provider(); - foreach($provider->componentsOfType($component_type) as $component) { + foreach ($provider->componentsOfType($component_type) as $component) { $this->assertInstanceOf($component_type, $component); } } // DATA PROVIDERS - public function component_types() { + public function component_types() + { $provider = $this->provider(); foreach ($provider->componentTypes() as $type) { yield [$type]; diff --git a/tests/RepositoryHelperTest.php b/tests/RepositoryHelperTest.php index a2c6bcd..a77e11d 100644 --- a/tests/RepositoryHelperTest.php +++ b/tests/RepositoryHelperTest.php @@ -10,53 +10,55 @@ use CaT\Ente; -class RepositoryHelperTest extends PHPUnit_Framework_TestCase { - public function test_componentsForEntity() { - $mock = $this->getMockForTrait(Ente\RepositoryHelper::class); - $entity = $this->createMock(Ente\Entity::class); - $component1 = $this->createMock(Ente\Component::class); - $component2 = $this->createMock(Ente\Component::class); - $provider1 = $this->createMock(Ente\Provider::class); - $provider2 = $this->createMock(Ente\Provider::class); - - $component_type1 = "COMPONENT_TYPE1"; - $component_type2 = "COMPONENT_TYPE2"; - - $mock - ->expects($this->once()) - ->method("providersForEntity") - ->with($entity) - ->willReturn([$provider1, $provider2]); - - $provider1 - ->expects($this->once()) - ->method("componentTypes") - ->willReturn([$component_type1, $component_type2]); - - $provider1 - ->expects($this->exactly(2)) - ->method("componentsOfType") - ->withConsecutive - ( [$component_type1] - , [$component_type2] - ) - ->will($this->onConsecutiveCalls([$component1, $component2], [])); - - $provider2 - ->expects($this->once()) - ->method("componentTypes") - ->willReturn([$component_type1, $component_type2]); - - $provider2 - ->expects($this->exactly(2)) - ->method("componentsOfType") - ->withConsecutive - ( [$component_type1] - , [$component_type2] - ) - ->will($this->onConsecutiveCalls([], [])); - - $components = $mock->componentsForEntity($entity); - $this->assertEquals([$component1, $component2], $components); - } +class RepositoryHelperTest extends PHPUnit_Framework_TestCase +{ + public function test_componentsForEntity() + { + $mock = $this->getMockForTrait(Ente\RepositoryHelper::class); + $entity = $this->createMock(Ente\Entity::class); + $component1 = $this->createMock(Ente\Component::class); + $component2 = $this->createMock(Ente\Component::class); + $provider1 = $this->createMock(Ente\Provider::class); + $provider2 = $this->createMock(Ente\Provider::class); + + $component_type1 = "COMPONENT_TYPE1"; + $component_type2 = "COMPONENT_TYPE2"; + + $mock + ->expects($this->once()) + ->method("providersForEntity") + ->with($entity) + ->willReturn([$provider1, $provider2]); + + $provider1 + ->expects($this->once()) + ->method("componentTypes") + ->willReturn([$component_type1, $component_type2]); + + $provider1 + ->expects($this->exactly(2)) + ->method("componentsOfType") + ->withConsecutive + ([$component_type1] + , [$component_type2] + ) + ->will($this->onConsecutiveCalls([$component1, $component2], [])); + + $provider2 + ->expects($this->once()) + ->method("componentTypes") + ->willReturn([$component_type1, $component_type2]); + + $provider2 + ->expects($this->exactly(2)) + ->method("componentsOfType") + ->withConsecutive + ([$component_type1] + , [$component_type2] + ) + ->will($this->onConsecutiveCalls([], [])); + + $components = $mock->componentsForEntity($entity); + $this->assertEquals([$component1, $component2], $components); + } } diff --git a/tests/RepositoryTest.php b/tests/RepositoryTest.php index d43fc4f..d820ab0 100644 --- a/tests/RepositoryTest.php +++ b/tests/RepositoryTest.php @@ -13,7 +13,8 @@ /** * This testcases must be passed by a Repository. */ -abstract class RepositoryTest extends PHPUnit_Framework_TestCase { +abstract class RepositoryTest extends PHPUnit_Framework_TestCase +{ /** * To make this interesting, the repository should at least contain one * provider that provides for some entity. @@ -41,7 +42,8 @@ abstract protected function hasProvidersForComponentTypes(); /** * @dataProvider has_providers_for_entities */ - public function test_providers_for_entity($entity) { + public function test_providers_for_entity($entity) + { $providers = $this->repository()->providersForEntity($entity); foreach ($providers as $provider) { $this->assertEquals($entity->id(), $provider->entity()->id()); @@ -51,7 +53,8 @@ public function test_providers_for_entity($entity) { /** * @dataProvider has_providers_for_entities_and_component_types */ - public function test_providers_for_entity_filtered($entity, $component_type) { + public function test_providers_for_entity_filtered($entity, $component_type) + { $providers = $this->repository()->providersForEntity($entity, $component_type); foreach ($providers as $provider) { $this->assertEquals($entity->id(), $provider->entity()->id()); @@ -61,19 +64,22 @@ public function test_providers_for_entity_filtered($entity, $component_type) { // DATA PROVIDERS - public function has_providers_for_entities() { + public function has_providers_for_entities() + { foreach ($this->hasProvidersForEntities() as $entity) { yield [$entity]; } } - public function has_providers_for_component_types() { + public function has_providers_for_component_types() + { foreach ($this->hasProvidersForComponentTypes() as $component_type) { yield [$component_type]; } } - public function has_providers_for_entities_and_component_types() { + public function has_providers_for_entities_and_component_types() + { foreach ($this->hasProvidersForEntities() as $entity) { foreach ($this->hasProvidersForComponentTypes() as $component_type) { yield [$entity, $component_type]; diff --git a/tests/Simple/AttachIntMemoryTest.php b/tests/Simple/AttachIntMemoryTest.php index 9b2ac46..4210883 100644 --- a/tests/Simple/AttachIntMemoryTest.php +++ b/tests/Simple/AttachIntMemoryTest.php @@ -13,24 +13,29 @@ use CaT\Ente\Simple\AttachInt; use CaT\Ente\Simple\AttachIntMemory; -class Simple_AttachIntMemoryTest extends PHPUnit_Framework_TestCase { - use ProviderHelper; +class Simple_AttachIntMemoryTest extends PHPUnit_Framework_TestCase +{ + use ProviderHelper; - public function setUp() { + public function setUp() + { $this->id = rand(); $this->entity = new Entity($this->id); - $this->component = new AttachIntMemory($this->entity, -1 * $this->id); + $this->component = new AttachIntMemory($this->entity, -1 * $this->id); } - public function test_entity() { + public function test_entity() + { $this->assertEquals($this->entity, $this->component->entity()); } - public function test_attachedInt() { + public function test_attachedInt() + { $this->assertEquals(-1 * $this->id, $this->component->attachedInt()); } - public function test_componentTypes() { + public function test_componentTypes() + { $this->assertEquals([AttachInt::class], $this->componentTypesOf($this->component)); } } diff --git a/tests/Simple/AttachStringMemoryTest.php b/tests/Simple/AttachStringMemoryTest.php index 4641831..03e5f18 100644 --- a/tests/Simple/AttachStringMemoryTest.php +++ b/tests/Simple/AttachStringMemoryTest.php @@ -13,24 +13,29 @@ use CaT\Ente\Simple\AttachString; use CaT\Ente\Simple\AttachStringMemory; -class Simple_AttachStringMemoryTest extends PHPUnit_Framework_TestCase { - use ProviderHelper; +class Simple_AttachStringMemoryTest extends PHPUnit_Framework_TestCase +{ + use ProviderHelper; - public function setUp() { + public function setUp() + { $this->id = rand(); $this->entity = new Entity($this->id); $this->component = new AttachStringMemory($this->entity, "id: {$this->id}"); } - public function test_entity() { + public function test_entity() + { $this->assertEquals($this->entity, $this->component->entity()); } - public function test_attachedString() { + public function test_attachedString() + { $this->assertEquals("id: {$this->id}", $this->component->attachedString()); } - public function test_componentTypes() { + public function test_componentTypes() + { $this->assertEquals([AttachString::class], $this->componentTypesOf($this->component)); } } diff --git a/tests/Simple/ProviderTest.php b/tests/Simple/ProviderTest.php index 689820b..cb3ad7e 100644 --- a/tests/Simple/ProviderTest.php +++ b/tests/Simple/ProviderTest.php @@ -15,13 +15,15 @@ use CaT\Ente\Simple\AttachInt; use CaT\Ente\Simple\AttachIntMemory; -require_once(__DIR__."/../ProviderTest.php"); +require_once(__DIR__ . "/../ProviderTest.php"); -class Simple_ProviderTest extends ProviderTest { +class Simple_ProviderTest extends ProviderTest +{ /** * @inheritdocs */ - protected function provider() { + protected function provider() + { $entity = new Entity(0); $provider = new Provider($entity); $component = new AttachStringMemory($entity, "id: {$entity->id()}"); @@ -34,11 +36,13 @@ protected function provider() { /** * @inheritdocs */ - protected function doesNotProvideComponentType() { + protected function doesNotProvideComponentType() + { return [self::class]; } - public function test_cannot_add_for_other_entity() { + public function test_cannot_add_for_other_entity() + { $provider = $this->provider(); $entity = new Entity(1); @@ -47,25 +51,26 @@ public function test_cannot_add_for_other_entity() { try { $provider->addComponent($component); $this->assertFalse("This should not happen."); - } - catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException $e) { $this->assertTrue(true); } } - public function test_componentTypes() { + public function test_componentTypes() + { $provider = $this->provider(); $this->assertEquals([AttachString::class, AttachInt::class], $provider->componentTypes()); } - public function test_add_two_components_of_same_type() { + public function test_add_two_components_of_same_type() + { $entity = new Entity(0); $provider = new Provider($entity); $component = new AttachStringMemory($entity, "1"); $provider->addComponent($component); $component = new AttachStringMemory($entity, "2"); $provider->addComponent($component); - + $this->assertCount(2, $provider->componentsOfType(AttachString::class)); } } diff --git a/tests/Simple/RepositoryTest.php b/tests/Simple/RepositoryTest.php index 5f45140..4da10ea 100644 --- a/tests/Simple/RepositoryTest.php +++ b/tests/Simple/RepositoryTest.php @@ -14,27 +14,32 @@ use CaT\Ente\Simple\AttachString; use CaT\Ente\Simple\AttachStringMemory; -require_once(__DIR__."/../RepositoryTest.php"); +require_once(__DIR__ . "/../RepositoryTest.php"); -class _Repository extends Repository { - public function _providers() { +class _Repository extends Repository +{ + public function _providers() + { return $this->providers; } } -class Simple_RepositoryTest extends RepositoryTest { - protected function entities() { - return +class Simple_RepositoryTest extends RepositoryTest +{ + protected function entities() + { + return [new Entity(0), - new Entity(1), - new Entity(2), - new Entity(3)]; + new Entity(1), + new Entity(2), + new Entity(3)]; } /** * @inheritdocs */ - protected function repository() { + protected function repository() + { $entities = $this->entities(); $repo = new _Repository(); @@ -50,7 +55,8 @@ protected function repository() { /** * @inheritdocs */ - protected function hasProvidersForEntities() { + protected function hasProvidersForEntities() + { return $this->entities(); } @@ -59,14 +65,16 @@ protected function hasProvidersForEntities() { * * @return string[] */ - protected function hasProvidersForComponentTypes() { + protected function hasProvidersForComponentTypes() + { return [AttachString::class]; } - public function test_providers() { + public function test_providers() + { $providers = $this->repository()->_providers(); $this->assertCount(4, $providers); - $this->assertEquals([serialize(0),serialize(1),serialize(2),serialize(3)], array_keys($providers)); + $this->assertEquals([serialize(0), serialize(1), serialize(2), serialize(3)], array_keys($providers)); $this->assertCount(1, $providers[serialize(0)]); $this->assertCount(1, $providers[serialize(1)]); $this->assertCount(1, $providers[serialize(2)]); From add2ab2785eb1a7df173c395d5fa55873eddc5dd Mon Sep 17 00:00:00 2001 From: Stefan Hecken Date: Thu, 4 Jul 2019 14:00:11 +0200 Subject: [PATCH 4/6] PHP7 coding and format for examples --- .../class.ilComponentHandlerExamplePlugin.php | 14 +-- .../class.ilObjComponentHandlerExample.php | 24 +++-- ...ass.ilObjComponentHandlerExampleAccess.php | 11 ++- .../class.ilObjComponentHandlerExampleGUI.php | 38 +++---- ...ss.ilObjComponentHandlerExampleListGUI.php | 35 ++++--- example/ComponentHandlerExample/composer.json | 8 +- .../Settings/ComponentProviderExample.php | 29 ++---- .../classes/Settings/DB.php | 28 ++---- .../classes/Settings/ilDB.php | 69 ++++++++----- .../classes/UnboundProvider.php | 19 ++-- ...class.ilComponentProviderExamplePlugin.php | 28 +++--- .../class.ilObjComponentProviderExample.php | 15 ++- ...ss.ilObjComponentProviderExampleAccess.php | 11 ++- ...class.ilObjComponentProviderExampleGUI.php | 53 +++++----- ...s.ilObjComponentProviderExampleListGUI.php | 38 ++++--- .../ComponentProviderExample/composer.json | 10 +- .../ComponentProviderExample/composer.lock | 98 ++++++++++--------- .../tests/Settings/SettingsTest.php | 35 +++++++ .../tests/SettingsTest.php | 29 ------ 19 files changed, 318 insertions(+), 274 deletions(-) create mode 100644 example/ComponentProviderExample/tests/Settings/SettingsTest.php delete mode 100644 example/ComponentProviderExample/tests/SettingsTest.php diff --git a/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php b/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php index 74f14e0..7f6be28 100644 --- a/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php +++ b/example/ComponentHandlerExample/classes/class.ilComponentHandlerExamplePlugin.php @@ -1,17 +1,17 @@ */ + +declare(strict_types=1); + +require_once "./Services/Repository/classes/class.ilRepositoryObjectPlugin.php"; +require_once __DIR__ . "/../vendor/autoload.php"; /** * Plugin base class. Keeps all information the plugin needs */ class ilComponentHandlerExamplePlugin extends ilRepositoryObjectPlugin { - /** - * @var \ilDBInterface - */ - protected $ilDB; - /** * Get the name of the Plugin * diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExample.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExample.php index ed56ea9..86ffeeb 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExample.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExample.php @@ -1,8 +1,14 @@ */ + +declare(strict_types=1); + +use CaT\Ente\Simple; use CaT\Ente\ILIAS; +require_once "Services/Repository/classes/class.ilObjectPlugin.php"; + /** * Object of the plugin */ @@ -26,12 +32,10 @@ public function initType() /** * Returns an array with title => string[] entries containing the strings * provided for the object this plugin object is contained in. - * - * @return array */ - public function getProvidedStrings() + public function getProvidedStrings() : array { - $components = $this->getComponentsOfType(\CaT\Ente\Simple\AttachString::class); + $components = $this->getComponentsOfType(Simple\AttachString::class); $provided_strings = []; foreach ($components as $component) { @@ -41,14 +45,8 @@ public function getProvidedStrings() return $provided_strings; } - /** - * Get the ref_id of the object this object handles components for. - * - * @return int - */ - protected function getEntityRefId() + protected function getEntityRefId() : int { - global $DIC; - return $DIC->repositoryTree()->getParentId($this->getRefId()); + return (int)$$this->getDIC()["tree"]->getParentId($this->getRefId()); } } diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php index 2dc4af2..3d728e8 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleAccess.php @@ -1,4 +1,9 @@ */ + +declare(strict_types=1); + require_once 'Services/Repository/classes/class.ilObjectPluginAccess.php'; /** @@ -36,7 +41,7 @@ public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_use switch ($a_permission) { case "read": - if (!self::checkOnline($a_obj_id) + if (self::_isOffline($a_obj_id) && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) { return false; } @@ -48,8 +53,8 @@ public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_use /** * Check online status of object */ - static public function checkOnline($a_id) + static public function _isOffline($a_obj_id) { - return true; + return false; } } diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php index 0a9a42e..a54dda0 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleGUI.php @@ -1,9 +1,10 @@ */ + +declare(strict_types=1); +require_once("./Services/Repository/classes/class.ilObjectPluginGUI.php"); /** * Plugin object GUI class. Baseclass for all GUI action in ILIAS @@ -13,10 +14,12 @@ */ class ilObjComponentHandlerExampleGUI extends ilObjectPluginGUI { + const CMD_SHOW_CONTENT = "showContent"; + /** * @var \ilTemplate */ - protected $ilTemplate; + protected $tpl; /** * @var \ILIAS\UI\Factory @@ -34,9 +37,9 @@ class ilObjComponentHandlerExampleGUI extends ilObjectPluginGUI protected function afterConstructor() { global $DIC; - $this->ilTemplate = $DIC->ui()->mainTemplate(); - $this->ui_factory = $DIC->ui()->factory(); - $this->ui_renderer = $DIC->ui()->renderer(); + $this->tpl = $DIC["tpl"]; + $this->ui_factory = $DIC["ui.factory"]; + $this->ui_renderer = $DIC["ui.renderer"]; } /** @@ -53,39 +56,36 @@ final function getType() function performCommand($cmd) { switch ($cmd) { - case "showContent": - $this->ilTemplate->setContent($this->showContent()); + case self::CMD_SHOW_CONTENT: + $this->showContent(); break; default: throw new \InvalidArgumentException("Unknown Command: '$cmd'"); } } - /** - * Show the edit form. - * - * @return string - */ public function showContent() { $items = $this->object->getProvidedStrings(); $listing = $this->ui_factory->listing()->ordered($items); - return $this->ui_renderer->render($listing); + $this->tpl->setContent( + $this->ui_renderer->render($listing) + ); } /** * After object has been created -> jump to this command */ - function getAfterCreationCmd() + public function getAfterCreationCmd() { - return "showContent"; + return self::CMD_SHOW_CONTENT; } /** * Get standard command */ - function getStandardCmd() + public function getStandardCmd() { - return "showContent"; + return self::CMD_SHOW_CONTENT; } } diff --git a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php index bb23ed9..48e7898 100644 --- a/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php +++ b/example/ComponentHandlerExample/classes/class.ilObjComponentHandlerExampleListGUI.php @@ -1,5 +1,10 @@ */ + +declare(strict_types=1); + +require_once "./Services/Repository/classes/class.ilObjectPluginListGUI.php"; /** * List gui class for plugin object in repository @@ -7,7 +12,7 @@ class ilObjComponentHandlerExampleListGUI extends ilObjectPluginListGUI { /** - * Init the type of the plugin. Same value as choosen in plugin.php + * @inheritDoc */ public function initType() { @@ -15,7 +20,7 @@ public function initType() } /** - * Get name of gui class handling the commands + * @inheritDoc */ function getGuiClass() { @@ -23,18 +28,10 @@ function getGuiClass() } /** - * Get commands + * @inheritDoc */ function initCommands() { - $this->info_screen_enabled = true; - $this->copy_enabled = true; - $this->cut_enabled = true; - $this->subscribe_enabled = true; - $this->link_enabled = false; - $this->payment_enabled = false; - $this->timings_enabled = false; - return array(array("permission" => "read", "cmd" => "showContent", "default" => true @@ -46,4 +43,18 @@ function initCommands() ) ); } + + /** + * @inheritDoc + */ + protected function initListActions() + { + $this->info_screen_enabled = true; + $this->copy_enabled = true; + $this->cut_enabled = true; + $this->subscribe_enabled = true; + $this->link_enabled = false; + $this->payment_enabled = false; + $this->timings_enabled = false; + } } diff --git a/example/ComponentHandlerExample/composer.json b/example/ComponentHandlerExample/composer.json index a9afc6a..3d12b82 100644 --- a/example/ComponentHandlerExample/composer.json +++ b/example/ComponentHandlerExample/composer.json @@ -1,13 +1,7 @@ { "require": { - "cat/ente": "@dev" + "conceptsandtraining/ente": "^4.0.0" }, - "repositories": [ - { - "type": "vcs", - "url": "git@github.com:/conceptsandtraining/lib-ente.git" - } - ], "autoload": { "psr-4": { "CaT\\Plugins\\ComponentHandlerExample\\": "./classes" diff --git a/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php b/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php index 5de585e..e1513a4 100644 --- a/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php +++ b/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php @@ -1,5 +1,9 @@ */ + +declare(strict_types=1); + namespace CaT\Plugins\ComponentProviderExample\Settings; /** @@ -17,41 +21,24 @@ class ComponentProviderExample */ protected $provided_strings; - public function __construct($obj_id, array $provided_strings) + public function __construct(int $obj_id, array $provided_strings) { - assert('is_int($obj_id)'); assert('array_sum(array_map("is_string", $provided_strings)) == count($provided_strings)'); $this->obj_id = $obj_id; $this->provided_strings = $provided_strings; } - /** - * Get the id of the object this is belonging to. - * - * @return int - */ - public function objId() + public function getObjId() : int { return $this->obj_id; } - /** - * Get the provided strings. - * - * @return string[] - */ - public function providedStrings() + public function getProvidedStrings() : array { return $this->provided_strings; } - /** - * Change the provided strings. - * - * @param string[] $provided_strings - * @return ComponentProviderExample - */ - public function withProvidedStrings(array $provided_strings) + public function withProvidedStrings(array $provided_strings) : ComponentProviderExample { assert('array_sum(array_map("is_string", $provided_strings)) == count($provided_strings)'); $clone = clone $this; diff --git a/example/ComponentProviderExample/classes/Settings/DB.php b/example/ComponentProviderExample/classes/Settings/DB.php index 11f8d63..de6907e 100644 --- a/example/ComponentProviderExample/classes/Settings/DB.php +++ b/example/ComponentProviderExample/classes/Settings/DB.php @@ -1,5 +1,9 @@ */ + +declare(strict_types=1); + namespace CaT\Plugins\ComponentProviderExample\Settings; /** @@ -7,27 +11,7 @@ */ interface DB { - /** - * Update settings of an existing repo object. - * - * @param ComponentProviderExample $settings - * @return null - */ public function update(ComponentProviderExample $settings); - - /** - * return ComponentProviderExample for $obj_id - * - * @param int $obj_id - * - * @return ComponentProviderExample - */ - public function getFor($obj_id); - - /** - * Delete all information of the given obj id - * - * @param int $obj_id - */ - public function deleteFor($obj_id); + public function getFor(int $obj_id) : ComponentProviderExample; + public function deleteFor(int $obj_id); } diff --git a/example/ComponentProviderExample/classes/Settings/ilDB.php b/example/ComponentProviderExample/classes/Settings/ilDB.php index aff7d21..dac3cf6 100644 --- a/example/ComponentProviderExample/classes/Settings/ilDB.php +++ b/example/ComponentProviderExample/classes/Settings/ilDB.php @@ -1,5 +1,9 @@ */ + +declare(strict_types=1); + namespace CaT\Plugins\ComponentProviderExample\Settings; /** @@ -12,11 +16,11 @@ class ilDB /** * @var \ilDBInterface */ - protected $ilDB; + protected $db; - public function __construct(\ilDBInterface $ilDB) + public function __construct(\ilDBInterface $db) { - $this->ilDB = $ilDB; + $this->db = $db; } /** @@ -27,26 +31,33 @@ public function update(ComponentProviderExample $settings) $obj_id = $settings->objId(); $this->deleteFor($obj_id); foreach ($settings->providedStrings() as $value) { - $this->ilDB->insert(self::TABLE_NAME, - ["obj_id" => ["integer", $obj_id] - , "value" => ["string", $value] - ]); + $this->db->insert( + self::TABLE_NAME, + [ + "obj_id" => [ + "integer", + $obj_id + ], + "value" => [ + "string", + $value + ] + ] + ); } } /** * @inheritdoc */ - public function getFor($obj_id) + public function getFor(int $obj_id) : ComponentProviderExample { - assert('is_int($obj_id)'); - $query = - "SELECT value FROM " . self::TABLE_NAME . - " WHERE obj_id = " . $this->ilDB->quote($obj_id, "integer"); - $res = $this->ilDB->query($query); + $query = "SELECT value FROM " . self::TABLE_NAME . PHP_EOL + ." WHERE obj_id = " . $this->db->quote($obj_id, "integer"); + $res = $this->db->query($query); $values = []; - while ($row = $this->ilDB->fetchAssoc($res)) { + while ($row = $this->db->fetchAssoc($res)) { $values[] = $row["value"]; } @@ -56,23 +67,33 @@ public function getFor($obj_id) /** * @inheritdoc */ - public function deleteFor($obj_id) + public function deleteFor(int $obj_id) { - $statement = - "DELETE FROM " . self::TABLE_NAME . - " WHERE obj_id = " . $this->ilDB->quote($obj_id, "integer"); + $statement = "DELETE FROM " . self::TABLE_NAME . PHP_EOL + ."WHERE obj_id = " . $this->db->quote($obj_id, "integer"); $this->ilDB->manipulate($statement); } public function install() { - if (!$this->ilDB->tableExists(self::TABLE_NAME)) { - $this->ilDB->createTable(self::TABLE_NAME, - ["obj_id" => ["type" => "integer", "length" => 4, "notnull" => true] - , "value" => ["type" => "text", "length" => 64, "notnull" => true] - ]); + if (!$this->db->tableExists(self::TABLE_NAME)) { + $this->db->createTable( + self::TABLE_NAME, + [ + "obj_id" => [ + "type" => "integer", + "length" => 4, + "notnull" => true + ], + "value" => [ + "type" => "text", + "length" => 64, + "notnull" => true + ] + ] + ); - $this->ilDB->addPrimaryKey(self::TABLE_NAME, ["obj_id", "value"]); + $this->db->addPrimaryKey(self::TABLE_NAME, ["obj_id", "value"]); } } } diff --git a/example/ComponentProviderExample/classes/UnboundProvider.php b/example/ComponentProviderExample/classes/UnboundProvider.php index c431145..7e5c0ef 100644 --- a/example/ComponentProviderExample/classes/UnboundProvider.php +++ b/example/ComponentProviderExample/classes/UnboundProvider.php @@ -1,13 +1,18 @@ */ + +declare(strict_types=1); -require_once(__DIR__ . "/../vendor/autoload.php"); +namespace CaT\Plugins\ComponentProviderExample; use \CaT\Ente\ILIAS\SeparatedUnboundProvider as Base; use \CaT\Ente\Simple\AttachString; use \CaT\Ente\Simple\AttachStringMemory; -use \CaT\Ente\ILIAS\Entity; +use \CaT\Ente\Entity as IEntity; +use \CaT\Ente\Component as IComponent; + +require_once __DIR__ . "/../vendor/autoload.php"; class UnboundProvider extends Base { @@ -20,13 +25,9 @@ public function componentTypes() } /** - * Build the component(s) of the given type for the given object. - * - * @param string $component_type - * @param Entity $provider - * @return Component[] + * @return IComponent[] */ - public function buildComponentsOf($component_type, Entity $entity) + public function buildComponentsOf(string $component_type, IEntity $entity) : array { if ($component_type === AttachString::class) { $returns = []; diff --git a/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php b/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php index 1fbaf75..e46b323 100644 --- a/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php +++ b/example/ComponentProviderExample/classes/class.ilComponentProviderExamplePlugin.php @@ -1,19 +1,26 @@ */ + +declare(strict_types=1); + +use \CaT\Plugins\ComponentProviderExample\Settings; + +require_once "./Services/Repository/classes/class.ilRepositoryObjectPlugin.php"; +require_once __DIR__ . "/../vendor/autoload.php"; /** * Plugin base class. Keeps all information the plugin needs */ -class ilComponentProviderExamplePlugin extends ilRepositoryObjectPlugin +class ilComponentProviderExamplePlugin extends \ilRepositoryObjectPlugin { /** * @var \ilDBInterface */ - protected $ilDB; + protected $db; /** - * @var \CaT\Plugins\ComponentProviderExamplePlugin\Settings\DB|null + * @var Settings\DB | null */ protected $settings_db = null; @@ -23,7 +30,7 @@ class ilComponentProviderExamplePlugin extends ilRepositoryObjectPlugin protected function init() { global $DIC; - $this->ilDB = $DIC->database(); + $this->db = $DIC["ilDB"]; } /** @@ -43,15 +50,10 @@ protected function uninstallCustom() { } - /** - * Get the database for settings. - * - * @return \CaT\Plugins\ComponentProviderExample\Settings\DB - */ - public function settingsDB() + public function settingsDB() : Settings\DB { if ($this->settings_db === null) { - $this->settings_db = new \CaT\Plugins\ComponentProviderExample\Settings\ilDB($this->ilDB); + $this->settings_db = new Settings\ilDB($this->db); } return $this->settings_db; } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php index 5d8176f..134c18c 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php @@ -1,13 +1,18 @@ */ + +declare(strict_types=1); use CaT\Plugins\ComponentProviderExample\UnboundProvider; use CaT\Ente\ILIAS\ilProviderObjectHelper; +require_once "Services/Repository/classes/class.ilObjectPlugin.php"; + /** * Object of the plugin */ -class ilObjComponentProviderExample extends ilObjectPlugin +class ilObjComponentProviderExample extends \ilObjectPlugin { use ilProviderObjectHelper; @@ -29,7 +34,11 @@ public function initType() */ public function doCreate() { - $this->createUnboundProvider("crs", UnboundProvider::class, __DIR__ . "/UnboundProvider.php"); + $this->createUnboundProvider( + "crs", + UnboundProvider::class, + __DIR__ . "/UnboundProvider.php" + ); } /** diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php index 61fa51d..abbaa11 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleAccess.php @@ -1,4 +1,9 @@ */ + +declare(strict_types=1); + require_once 'Services/Repository/classes/class.ilObjectPluginAccess.php'; /** @@ -36,7 +41,7 @@ public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_use switch ($a_permission) { case "read": - if (!self::checkOnline($a_obj_id) + if (self::_isOffline($a_obj_id) && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) { return false; } @@ -48,8 +53,8 @@ public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_use /** * Check online status of object */ - static public function checkOnline($a_id) + static public function _isOffline($a_obj_id) { - return true; + return false; } } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php index f38c47b..b21d846 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php @@ -1,9 +1,12 @@ */ +declare(strict_types=1); + +require_once "./Services/Repository/classes/class.ilObjectPluginGUI.php"; +require_once "./Services/Form/classes/class.ilPropertyFormGUI.php"; +require_once "./Services/Form/classes/class.ilTextInputGUI.php"; /** * Plugin object GUI class. Baseclass for all GUI action in ILIAS @@ -14,17 +17,18 @@ class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI { const VALUES_FIELD_NAME = "values"; - const SAVE_CMD = "saveForm"; + const CMD_SAVE = "saveForm"; + const CMD_SHOW_CONTENT = "showContent"; /** * @var \ilTemplate */ - protected $ilTemplate; + protected $tpl; /** * @var \ilCtrl */ - protected $ilCtrl; + protected $ctrl; /** * Called after parent constructor. It's possible to define some plugin special values @@ -32,8 +36,8 @@ class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI protected function afterConstructor() { global $DIC; - $this->ilTemplate = $DIC->ui()->mainTemplate(); - $this->ilCtrl = $DIC->ctrl(); + $this->tpl = $DIC["tpl"]; + $this->ctrl = $DIC["ilCtrl"]; } /** @@ -50,10 +54,11 @@ final function getType() function performCommand($cmd) { switch ($cmd) { - case self::SAVE_CMD: + case self::CMD_SAVE: $this->saveForm(); - case "showContent": - $this->ilTemplate->setContent($this->showContent()); + break; + case self::CMD_SHOW_CONTENT: + $this->showContent(); break; default: throw new \InvalidArgumentException("Unknown Command: '$cmd'"); @@ -69,7 +74,7 @@ protected function saveForm() $settings = $db->getFor((int)$this->object->getId()); $settings = $settings->withProvidedStrings($_POST[self::VALUES_FIELD_NAME]); $db->update($settings); - $this->ilCtrl->redirect($this, "showContent"); + $this->ctrl->redirect($this, self::CMD_SHOW_CONTENT); } /** @@ -83,33 +88,37 @@ public function showContent() $settings = $db->getFor((int)$this->object->getId()); $form = new \ilPropertyFormGUI(); - $form->setTitle($this->plugin->txt("settings_form_title")); - $form->setFormAction($this->ilCtrl->getFormAction($this)); - $form->addCommandButton(self::SAVE_CMD, $this->txt("save")); + $form->setTitle($this->txt("settings_form_title")); + $form->setFormAction($this->ctrl->getFormAction($this)); + $form->addCommandButton(self::CMD_SAVE, $this->txt("save")); - $input = new \ilTextInputGUI($this->plugin->txt("values"), self::VALUES_FIELD_NAME); + $input = new \ilTextInputGUI($this->txt("values"), self::VALUES_FIELD_NAME); $input->setMulti(true); $input->setMaxLength(64); $input->setValue($settings->providedStrings()); - $form->addItem($input); - return $form->getHTML(); + $this->tpl->setContent( $form->getHTML()); } /** * After object has been created -> jump to this command */ - function getAfterCreationCmd() + public function getAfterCreationCmd() { - return "showContent"; + return self::CMD_SHOW_CONTENT; } /** * Get standard command */ - function getStandardCmd() + public function getStandardCmd() + { + return self::CMD_SHOW_CONTENT; + } + + protected function txt(string $code) : string { - return "showContent"; + return $this->plugin->txt($code); } } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php index 0dad242..e272b25 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleListGUI.php @@ -1,5 +1,10 @@ */ + +declare(strict_types=1); + +require_once "./Services/Repository/classes/class.ilObjectPluginListGUI.php"; /** * List gui class for plugin object in repository @@ -7,7 +12,7 @@ class ilObjComponentProviderExampleListGUI extends ilObjectPluginListGUI { /** - * Init the type of the plugin. Same value as choosen in plugin.php + * @inheritDoc */ public function initType() { @@ -15,7 +20,7 @@ public function initType() } /** - * Get name of gui class handling the commands + * @inheritDoc */ function getGuiClass() { @@ -23,19 +28,10 @@ function getGuiClass() } /** - * Get commands + * @inheritDoc */ function initCommands() - { - $this->info_screen_enabled = true; - $this->copy_enabled = true; - $this->cut_enabled = true; - $this->subscribe_enabled = true; - $this->link_enabled = false; - $this->payment_enabled = false; - $this->timings_enabled = false; - - return array(array("permission" => "read", + { return array(array("permission" => "read", "cmd" => "showContent", "default" => true ), @@ -46,4 +42,18 @@ function initCommands() ) ); } + + /** + * @inheritDoc + */ + protected function initListActions() + { + $this->info_screen_enabled = true; + $this->copy_enabled = true; + $this->cut_enabled = true; + $this->subscribe_enabled = true; + $this->link_enabled = false; + $this->payment_enabled = false; + $this->timings_enabled = false; + } } diff --git a/example/ComponentProviderExample/composer.json b/example/ComponentProviderExample/composer.json index 8ceb77c..cb4bd44 100644 --- a/example/ComponentProviderExample/composer.json +++ b/example/ComponentProviderExample/composer.json @@ -1,16 +1,10 @@ { "require": { - "cat/ente": "@dev" + "conceptsandtraining/ente": "^4.0.0" }, - "repositories": [ - { - "type": "vcs", - "url": "git@github.com:/conceptsandtraining/lib-ente.git" - } - ], "autoload": { "psr-4": { - "CaT\\Plugins\\ComponentProviderExample\\": "./classes" + "CaT\\Plugins\\ComponentProviderExample\\": ["./classes", "./tests"] } } } diff --git a/example/ComponentProviderExample/composer.lock b/example/ComponentProviderExample/composer.lock index bddb1ae..c401437 100644 --- a/example/ComponentProviderExample/composer.lock +++ b/example/ComponentProviderExample/composer.lock @@ -1,47 +1,55 @@ { - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "3d742255057590cad00d70c503624e2c", - "content-hash": "272e30e103e1ef82a667b67c718bb48c", - "packages": [ - { - "name": "cat/ente", - "version": "0.1.0", - "dist": { - "type": "path", - "url": "../../lib/", - "reference": "66f0059afe55352a187b7293f0c83658869f2452", - "shasum": null - }, - "type": "library", - "autoload": { - "psr-4": { - "CaT\\Ente\\": "src" - } - }, - "license": [ - "GPLv3" - ], - "authors": [ - { - "name": "Richard Klees", - "email": "richard.klees@concepts-and-training.de" - } - ], - "description": "An entity component framework for PHP." - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "cat/ente": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "39df0d7b39836781192c2937f207efa9", + "content-hash": "53399f79ac9f1877c74993378b457019", + "packages": [ + { + "name": "conceptsandtraining/ente", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/conceptsandtraining/lib-ente.git", + "reference": "656b99073fa6e649550938e272eca051e2325a6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/conceptsandtraining/lib-ente/zipball/656b99073fa6e649550938e272eca051e2325a6d", + "reference": "656b99073fa6e649550938e272eca051e2325a6d", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^5.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "CaT\\Ente\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Richard Klees", + "email": "richard.klees@concepts-and-training.de" + } + ], + "description": "An entity component framework for ILIAS.", + "time": "2018-08-23 14:29:44" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] } diff --git a/example/ComponentProviderExample/tests/Settings/SettingsTest.php b/example/ComponentProviderExample/tests/Settings/SettingsTest.php new file mode 100644 index 0000000..faef166 --- /dev/null +++ b/example/ComponentProviderExample/tests/Settings/SettingsTest.php @@ -0,0 +1,35 @@ + */ + +declare(strict_types=1); + +namespace CaT\Plugins\ComponentProviderExample\Settings; + +use PHPUnit\Framework\TestCase; + +class SettingsTest extends TestCase +{ + public function test_objId() + { + $cpe = new ComponentProviderExample(23, []); + $this->assertEquals(23, $cpe->getObjId()); + } + + public function test_providedStrings() + { + $some_strings = ["a", "b", "c"]; + $cpe = new ComponentProviderExample(23, $some_strings); + $this->assertEquals($some_strings, $cpe->getProvidedStrings()); + } + + public function test_withProvidedStrings() + { + $cpe = new ComponentProviderExample(23, []); + $this->assertEquals([], $cpe->getProvidedStrings()); + $some_strings = ["d", "e", "f"]; + $cpe = $cpe->withProvidedStrings($some_strings); + $this->assertEquals(23, $cpe->getObjId()); + $this->assertEquals($some_strings, $cpe->getProvidedStrings()); + } +} diff --git a/example/ComponentProviderExample/tests/SettingsTest.php b/example/ComponentProviderExample/tests/SettingsTest.php deleted file mode 100644 index dd52e7a..0000000 --- a/example/ComponentProviderExample/tests/SettingsTest.php +++ /dev/null @@ -1,29 +0,0 @@ -assertEquals(23, $cpe->objId()); - } - - public function test_providedStrings() - { - $some_strings = ["a", "b", "c"]; - $cpe = new ComponentProviderExample(23, $some_strings); - $this->assertEquals($some_strings, $cpe->providedStrings()); - } - - public function test_withProvidedStrings() - { - $cpe = new ComponentProviderExample(23, []); - $this->assertEquals([], $cpe->providedStrings()); - $some_strings = ["d", "e", "f"]; - $cpe = $cpe->withProvidedStrings($some_strings); - $this->assertEquals(23, $cpe->objId()); - $this->assertEquals($some_strings, $cpe->providedStrings()); - } -} From ba5d5a1a412750c3cf5ee618e627622911aee23e Mon Sep 17 00:00:00 2001 From: Stefan Hecken Date: Thu, 4 Jul 2019 16:29:31 +0200 Subject: [PATCH 5/6] Restructuring of plugin settings and implementation of DIC --- .../ComponentProviderExample/classes/DI.php | 64 ++++++++++ ...ample.php => ProvidedStringComponents.php} | 2 +- .../class.ilProvidedComponentsGUI.php | 104 +++++++++++++++++ .../classes/UnboundProvider.php | 2 +- .../class.ilObjComponentProviderExample.php | 7 ++ ...class.ilObjComponentProviderExampleGUI.php | 109 ++++++++++-------- .../lang/ilias_en.lang | 1 + .../tests/Settings/SettingsTest.php | 6 +- 8 files changed, 245 insertions(+), 50 deletions(-) create mode 100644 example/ComponentProviderExample/classes/DI.php rename example/ComponentProviderExample/classes/Settings/{ComponentProviderExample.php => ProvidedStringComponents.php} (97%) create mode 100644 example/ComponentProviderExample/classes/Settings/class.ilProvidedComponentsGUI.php diff --git a/example/ComponentProviderExample/classes/DI.php b/example/ComponentProviderExample/classes/DI.php new file mode 100644 index 0000000..2268e15 --- /dev/null +++ b/example/ComponentProviderExample/classes/DI.php @@ -0,0 +1,64 @@ + */ + +declare(strict_types=1); + +namespace CaT\Plugins\ComponentProviderExample; + +use function foo\func; +use Pimple\Container; + +trait DI +{ + public function getObjectDIC( + \ilObjComponentProviderExample $object, + $dic + ): Container { + $container = new Container(); + + $container["ilDB"] = function ($c) use ($dic) { + return $dic["ilDB"]; + }; + $container["ilCtrl"] = function ($c) use ($dic) { + return $dic["ilCtrl"]; + }; + $container["tpl"] = function ($c) use ($dic) { + return $dic["tpl"]; + }; + $container["ilAccess"] = function ($c) use ($dic) { + return $dic["ilAccess"]; + }; + $container["ilTabs"] = function ($c) use ($dic) { + return $dic["ilTabs"]; + }; + $container["txtclosure"] = function ($c) use ($object) { + return $object->getTxtClosure(); + }; + + $container["settings.db"] = function ($c) { + return new Settings\ilDB($c["ilDB"]); + }; + $container["settings.gui"] = function ($c) { + require_once "Settings/class.ilProvidedComponentsGUI.php"; + return $c["ilCtrl"]->getLinkTargetByClass( + "ilProvidedComponentsGUI", + \ilProvidedComponentsGUI::CMD_SHOW_CONTENT, + "", + false, + false + ); + }; + $container["settings.gui.link"] = function ($c) { + require_once "Settings/class.ilProvidedComponentsGUI.php"; + return new \ilProvidedComponentsGUI( + $c["tpl"], + $c["ilCtrl"], + $c["txtclosure"], + $c["settings.db"] + ); + }; + + return $container; + } +} diff --git a/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php b/example/ComponentProviderExample/classes/Settings/ProvidedStringComponents.php similarity index 97% rename from example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php rename to example/ComponentProviderExample/classes/Settings/ProvidedStringComponents.php index e1513a4..0872f65 100644 --- a/example/ComponentProviderExample/classes/Settings/ComponentProviderExample.php +++ b/example/ComponentProviderExample/classes/Settings/ProvidedStringComponents.php @@ -9,7 +9,7 @@ /** * Settings for an ComponentProviderExample. */ -class ComponentProviderExample +class ProvidedStringComponents { /** * @var int diff --git a/example/ComponentProviderExample/classes/Settings/class.ilProvidedComponentsGUI.php b/example/ComponentProviderExample/classes/Settings/class.ilProvidedComponentsGUI.php new file mode 100644 index 0000000..0d95f75 --- /dev/null +++ b/example/ComponentProviderExample/classes/Settings/class.ilProvidedComponentsGUI.php @@ -0,0 +1,104 @@ + */ + +declare(strict_types=1); + +use CaT\Plugins\ComponentProviderExample\Settings\DB; + +class ilProvidedComponentsGUI +{ + const VALUES_FIELD_NAME = "values"; + const CMD_SAVE = "saveForm"; + const CMD_SHOW_CONTENT = "showContent"; + + /** + * @var ilTemplate + */ + protected $tpl; + + /** + * @var ilCtrl + */ + protected $ctrl; + + /** + * @var Closure + */ + protected $txt; + + /** + * @var DB + */ + protected $db; + + public function __construct( + ilTemplate $tpl, + ilCtrl $ctrl, + Closure $txt, + DB $db + ) { + $this->tpl = $tpl; + $this->ctrl = $ctrl; + $this->txt = $txt; + $this->db = $db; + } + + /** + * Handles all commmands of this class, centralizes permission checks + */ + public function executeCommand() + { + $cmd = $this->ctrl->getCmd(); + switch ($cmd) { + case self::CMD_SAVE: + $this->saveForm(); + break; + case self::CMD_SHOW_CONTENT: + $this->showContent(); + break; + default: + throw new \InvalidArgumentException("Unknown Command: '$cmd'"); + } + } + + /** + * Save values provided from form. + */ + protected function saveForm() + { + $settings = $this->db->getFor((int)$this->object->getId()); + $settings = $settings->withProvidedStrings($_POST[self::VALUES_FIELD_NAME]); + $this->db->update($settings); + $this->ctrl->redirect($this, self::CMD_SHOW_CONTENT); + } + + /** + * Show the edit form. + * + * @return string + */ + public function showContent() + { + $db = $this->plugin->settingsDB(); + $settings = $db->getFor((int)$this->object->getId()); + + $form = new \ilPropertyFormGUI(); + $form->setTitle($this->txt("settings_form_title")); + $form->setFormAction($this->ctrl->getFormAction($this)); + $form->addCommandButton(self::CMD_SAVE, $this->txt("save")); + + $input = new \ilTextInputGUI($this->txt("values"), self::VALUES_FIELD_NAME); + $input->setMulti(true); + $input->setMaxLength(64); + $input->setValue($settings->providedStrings()); + $form->addItem($input); + + $this->tpl->setContent( $form->getHTML()); + } + + protected function txt(string $code) : string + { + return call_user_func($this->txt, $code); + } +} diff --git a/example/ComponentProviderExample/classes/UnboundProvider.php b/example/ComponentProviderExample/classes/UnboundProvider.php index 7e5c0ef..415f506 100644 --- a/example/ComponentProviderExample/classes/UnboundProvider.php +++ b/example/ComponentProviderExample/classes/UnboundProvider.php @@ -25,7 +25,7 @@ public function componentTypes() } /** - * @return IComponent[] + * @return IComponent[] */ public function buildComponentsOf(string $component_type, IEntity $entity) : array { diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php index 134c18c..dbc229b 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExample.php @@ -66,4 +66,11 @@ public function getProvidedStrings() } return $returns; } + + public function getTxtClosure() + { + return function ($code) { + return $this->getPlugin()->txt($code); + }; + } } diff --git a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php index b21d846..f95ef1a 100644 --- a/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php +++ b/example/ComponentProviderExample/classes/class.ilObjComponentProviderExampleGUI.php @@ -8,18 +8,23 @@ require_once "./Services/Form/classes/class.ilPropertyFormGUI.php"; require_once "./Services/Form/classes/class.ilTextInputGUI.php"; +use CaT\Plugins\ComponentProviderExample\DI; + /** * Plugin object GUI class. Baseclass for all GUI action in ILIAS * * @ilCtrl_isCalledBy ilObjComponentProviderExampleGUI: ilRepositoryGUI, ilAdministrationGUI, ilObjPluginDispatchGUI * @ilCtrl_Calls ilObjComponentProviderExampleGUI: ilPermissionGUI, ilInfoScreenGUI, ilObjectCopyGUI, ilCommonActionDispatcherGUI + * @ilCtrl_Calls ilObjComponentProviderExampleGUI: ilProvidedComponentsGUI */ class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI { - const VALUES_FIELD_NAME = "values"; - const CMD_SAVE = "saveForm"; + use DI; + const CMD_SHOW_CONTENT = "showContent"; + const TAB_SETTINGS = "tab_settings"; + /** * @var \ilTemplate */ @@ -31,14 +36,19 @@ class ilObjComponentProviderExampleGUI extends ilObjectPluginGUI protected $ctrl; /** - * Called after parent constructor. It's possible to define some plugin special values + * @var ArrayAccess */ - protected function afterConstructor() - { - global $DIC; - $this->tpl = $DIC["tpl"]; - $this->ctrl = $DIC["ilCtrl"]; - } + protected $dic; + + /** + * @var ilAccess + */ + protected $access; + + /** + * @var ilTabsGUI + */ + protected $tabs; /** * Get type. Same value as choosen in plugin.php @@ -53,52 +63,55 @@ final function getType() */ function performCommand($cmd) { - switch ($cmd) { - case self::CMD_SAVE: - $this->saveForm(); - break; - case self::CMD_SHOW_CONTENT: - $this->showContent(); + $this->initClassProperties(); + + $next_class = $this->ctrl->getNextClass(); + switch($next_class) { + case "ilprovidedcomponentsgui": + $gui = $this->dic["settings.gui"]; + $this->ctrl->forwardCommand($gui); break; default: - throw new \InvalidArgumentException("Unknown Command: '$cmd'"); + switch ($cmd) { + case self::CMD_SHOW_CONTENT: + $this->redirectSettings(); + break; + default: + throw new \InvalidArgumentException("Unknown Command: '$cmd'"); + } } + } - /** - * Save values provided from form. - */ - protected function saveForm() + protected function initClassProperties() { - $db = $this->plugin->settingsDB(); - $settings = $db->getFor((int)$this->object->getId()); - $settings = $settings->withProvidedStrings($_POST[self::VALUES_FIELD_NAME]); - $db->update($settings); - $this->ctrl->redirect($this, self::CMD_SHOW_CONTENT); + $this->dic = $this->getObjDic(); + $this->tpl = $this->dic["tpl"]; + $this->ctrl = $this->dic["ilCtrl"]; + $this->access = $this->dic["ilAccess"]; + $this->tabs = $this->dic["ilTabs"]; } - /** - * Show the edit form. - * - * @return string - */ - public function showContent() + protected function redirectSettings() { - $db = $this->plugin->settingsDB(); - $settings = $db->getFor((int)$this->object->getId()); - - $form = new \ilPropertyFormGUI(); - $form->setTitle($this->txt("settings_form_title")); - $form->setFormAction($this->ctrl->getFormAction($this)); - $form->addCommandButton(self::CMD_SAVE, $this->txt("save")); + $link = $this->dic["settings.gui.link"]; + $this->ctrl->redirectToUrl($link); + } - $input = new \ilTextInputGUI($this->txt("values"), self::VALUES_FIELD_NAME); - $input->setMulti(true); - $input->setMaxLength(64); - $input->setValue($settings->providedStrings()); - $form->addItem($input); + protected function setTabs() + { + $this->addInfoTab(); + + if ($this->access->checkAccess("write", "", $this->object->getRefId())) { + $link = $this->dic["settings.gui.link"]; + $this->tabs->addTab( + self::TAB_SETTINGS, + $this->txt(self::TAB_SETTINGS), + $link + ); + } - $this->tpl->setContent( $form->getHTML()); + $this->addPermissionTab(); } /** @@ -119,6 +132,12 @@ public function getStandardCmd() protected function txt(string $code) : string { - return $this->plugin->txt($code); + return $this->txt($code); + } + + protected function getObjDic() : Pimple\Container + { + global $DIC; + return $this->getObjectDIC($this->object, $DIC); } } diff --git a/example/ComponentProviderExample/lang/ilias_en.lang b/example/ComponentProviderExample/lang/ilias_en.lang index b1a5c57..d1ff776 100644 --- a/example/ComponentProviderExample/lang/ilias_en.lang +++ b/example/ComponentProviderExample/lang/ilias_en.lang @@ -5,3 +5,4 @@ xlep_new#:#New Component Provider Example settings_form_title#:#Provided Strings save#:#Save values#:#Values +tab_settings#:#Einstellungen diff --git a/example/ComponentProviderExample/tests/Settings/SettingsTest.php b/example/ComponentProviderExample/tests/Settings/SettingsTest.php index faef166..147e303 100644 --- a/example/ComponentProviderExample/tests/Settings/SettingsTest.php +++ b/example/ComponentProviderExample/tests/Settings/SettingsTest.php @@ -12,20 +12,20 @@ class SettingsTest extends TestCase { public function test_objId() { - $cpe = new ComponentProviderExample(23, []); + $cpe = new ProvidedStringComponents(23, []); $this->assertEquals(23, $cpe->getObjId()); } public function test_providedStrings() { $some_strings = ["a", "b", "c"]; - $cpe = new ComponentProviderExample(23, $some_strings); + $cpe = new ProvidedStringComponents(23, $some_strings); $this->assertEquals($some_strings, $cpe->getProvidedStrings()); } public function test_withProvidedStrings() { - $cpe = new ComponentProviderExample(23, []); + $cpe = new ProvidedStringComponents(23, []); $this->assertEquals([], $cpe->getProvidedStrings()); $some_strings = ["d", "e", "f"]; $cpe = $cpe->withProvidedStrings($some_strings); From ce16b758d740c3aa1f4701dfd2ba20278a9d1850 Mon Sep 17 00:00:00 2001 From: Stefan Hecken Date: Thu, 4 Jul 2019 16:45:39 +0200 Subject: [PATCH 6/6] First try to an object implementation of provider helper --- .../ComponentProviderExample/classes/DI.php | 21 +++++++++++- src/ILIAS/ilProviderObjectHelper.php | 34 +++++++++++-------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/example/ComponentProviderExample/classes/DI.php b/example/ComponentProviderExample/classes/DI.php index 2268e15..1bd3d0f 100644 --- a/example/ComponentProviderExample/classes/DI.php +++ b/example/ComponentProviderExample/classes/DI.php @@ -6,7 +6,7 @@ namespace CaT\Plugins\ComponentProviderExample; -use function foo\func; +use CaT\Ente\ILIAS; use Pimple\Container; trait DI @@ -36,6 +36,10 @@ public function getObjectDIC( return $object->getTxtClosure(); }; + $container["ilObjDataCache"] = function ($c) use ($dic) { + return $dic["ilObjDataCache"]; + }; + $container["settings.db"] = function ($c) { return new Settings\ilDB($c["ilDB"]); }; @@ -59,6 +63,21 @@ public function getObjectDIC( ); }; + $container["provider.db"] = function ($c) { + new ILIAS\ilProviderDB( + $c["ilDB"], + $c["tree"], + $c["ilObjDataCache"] + ); + }; + + $container["object.help.provider"] = function ($c) use ($object) { + return new ILIAS\ilProviderObjectHelper( + $object, + $c["provider.db"] + ); + }; + return $container; } } diff --git a/src/ILIAS/ilProviderObjectHelper.php b/src/ILIAS/ilProviderObjectHelper.php index 51328cd..8ccc416 100644 --- a/src/ILIAS/ilProviderObjectHelper.php +++ b/src/ILIAS/ilProviderObjectHelper.php @@ -15,9 +15,23 @@ /** * Helper for repository objects that want to provide components. */ -trait ilProviderObjectHelper +class ilProviderObjectHelper { - use ilObjectHelper; + /** + * @var ProviderDB + */ + protected $provider_db; + + /** + * @var \ilObject + */ + protected $object; + + public function __construct(\ilObject $object, ProviderDB $provider_db) + { + $this->provider_db = $provider_db; + $this->object = $object; + } /** * Delete all unbound providers of this object. @@ -26,14 +40,9 @@ trait ilProviderObjectHelper */ protected function deleteUnboundProviders() { - if (!($this instanceof \ilObject)) { - throw new \LogicException("ilProviderObjectHelper can only be used with ilObjects."); - } - - $provider_db = $this->getProviderDB(); - $unbound_providers = $provider_db->unboundProvidersOf($this); + $unbound_providers = $this->provider_db->unboundProvidersOf($this->object); foreach ($unbound_providers as $unbound_provider) { - $provider_db->delete($unbound_provider, $this); + $this->provider_db->delete($unbound_provider, $this->object); } } @@ -47,13 +56,10 @@ protected function deleteUnboundProviders() */ protected function createUnboundProvider($object_type, $class_name, $path) { - if (!($this instanceof \ilObject)) { - throw new \LogicException("ilProviderObjectHelper can only be used with ilObjects."); - } if (is_subclass_of($class_name, SeparatedUnboundProvider::class)) { - $this->getProviderDB()->createSeparatedUnboundProvider($this, $object_type, $class_name, $path); + $this->provider_db->createSeparatedUnboundProvider($this->object, $object_type, $class_name, $path); } else if (is_subclass_of($class_name, SharedUnboundProvider::class)) { - $this->getProviderDB()->createSharedUnboundProvider($this, $object_type, $class_name, $path); + $this->provider_db->createSharedUnboundProvider($this->object, $object_type, $class_name, $path); } else { throw new \LogicException( "createUnboundProvider can only create providers " .