diff --git a/src/Colibri/Core/Entity.php b/src/Colibri/Core/Entity.php index 7f6999b..2ed1cda 100644 --- a/src/Colibri/Core/Entity.php +++ b/src/Colibri/Core/Entity.php @@ -141,7 +141,7 @@ public function setVirtual($offset, $value = null) */ public function hashCode() { - + return sha1(json_encode($this->toArray())); } /** diff --git a/src/Colibri/Extension/AbstractExtension.php b/src/Colibri/Extension/AbstractExtension.php new file mode 100644 index 0000000..2f15206 --- /dev/null +++ b/src/Colibri/Extension/AbstractExtension.php @@ -0,0 +1,87 @@ +path(sprintf('extensions.%s', $this->getNameNS())); + + if (null === $extensionConfiguration) { + throw new NotFoundException(sprintf('Extension could not be loaded because configuration for "%s" does not exist', + $this->getNameNS())); + } + + $this->setConfiguration($extensionConfiguration); + } + + /** + * @inheritDoc + */ + public function setConfiguration(ParametersCollection $collection) + { + $this->configuration = $collection; + + return $this; + } + + /** + * @inheritDoc + */ + public function getConfiguration() + { + return $this->configuration; + } + + /** + * @param EntityLifecycleEvent $event + * @param callable $callback + */ + protected function resolveEntities(EntityLifecycleEvent $event, callable $callback) + { + $callback = new Callback($callback); + + foreach ($this->getConfiguration() as $entityClassName => $extensionConfiguration) { + if ($event->getEntity() instanceof $entityClassName) { + $entity = $event->getEntity(); + $callback->call(...[$entity, $extensionConfiguration]); + } + } + } + + /** + * @param $variable + * @return bool + */ + protected static function isIterable($variable) + { + if (version_compare(PHP_VERSION, 7.1) === -1) { + return is_array($variable) || ($variable instanceof \Traversable); + } else { + return is_iterable($variable); + } + } + +} \ No newline at end of file diff --git a/src/Colibri/Extension/EventSubscriber/AbstractDataFilter.php b/src/Colibri/Extension/EventSubscriber/AbstractDataFilter.php new file mode 100644 index 0000000..69231ce --- /dev/null +++ b/src/Colibri/Extension/EventSubscriber/AbstractDataFilter.php @@ -0,0 +1,23 @@ +resolveEntities($event, function (EntityInterface $entity, ParametersCollection $parameters) { + /** @var ParametersCollection $configuration */ + foreach ($parameters as $propertyName => $configuration) { + if ($entity->hasProperty($propertyName) && $configuration->offsetExists('filters')) { + $propertyData = $entity->getByProperty($propertyName); + $propertyData = $this->applyFilters($propertyData, $configuration->offsetGet('filters')->toArray()); + $entity->setByProperty($propertyName, $propertyData); + } + } + }); + } + + /** + * @param $propertyData + * @param array $filterClasses + * @return array|int|string + */ + protected function applyFilters(&$propertyData, array $filterClasses) + { + /** @var FilterInterface $filter */ + foreach ($filterClasses as $filterClass => $filterClassArguments) { + $filter = new $filterClass(...$filterClassArguments); + $propertyData = $filter->apply($propertyData); + } + + return $propertyData; + } + +} \ No newline at end of file diff --git a/src/Colibri/Extension/EventSubscriber/ResourceLogger.php b/src/Colibri/Extension/EventSubscriber/ResourceLogger.php new file mode 100644 index 0000000..d93e99a --- /dev/null +++ b/src/Colibri/Extension/EventSubscriber/ResourceLogger.php @@ -0,0 +1,78 @@ +entitiesStates = new Collection(); + } + + /** + * @inheritdoc + */ + public function getEvents() + { + return [ORMEvents::beforePersist, ORMEvents::afterPersist]; + } + + /** + * @inheritdoc + */ + public function getNameNS() + { + return 'resourceLogger'; + } + + /** + * @param EntityLifecycleEvent $event + */ + public function beforePersist(EntityLifecycleEvent $event) + { + $entity = $event->getEntity(); + $states = $this->getEntitiesStates(); + + $states->set($entity->hashCode(), $entity); + } + + /** + * @param EntityLifecycleEvent $event + */ + public function afterPersist(EntityLifecycleEvent $event) + { + $entity = $event->getEntity(); + $states = $this->getEntitiesStates(); + + if (!$states->has($entity->hashCode())) { + + } + } + + /** + * @return Collection + */ + public function getEntitiesStates() + { + return $this->entitiesStates; + } + +} \ No newline at end of file diff --git a/src/Colibri/Extension/EventSubscriber/ResourceLogger/ResourceModelInterface.php b/src/Colibri/Extension/EventSubscriber/ResourceLogger/ResourceModelInterface.php new file mode 100644 index 0000000..0d83f71 --- /dev/null +++ b/src/Colibri/Extension/EventSubscriber/ResourceLogger/ResourceModelInterface.php @@ -0,0 +1,12 @@ +offsetGet('properties') as $property) { + if ($entity->hasProperty($property)) { + $parts[] = Transliterator::urlize(Transliterator::transliterate($entity->getByProperty($property))); + } + } + + $string = implode($configuration->offsetGet('separator'), $parts); + + return sprintf('%s%s%s', $configuration->get('prefix'), $string, $configuration->get('suffix')); + } + + /** + * @param EntityLifecycleEvent $event + */ + public function beforePersist(EntityLifecycleEvent $event) + { + foreach ($this->getConfiguration() as $entityClassName => $propertyConfiguration) { + if ($event->getEntity() instanceof $entityClassName) { + $entity = $event->getEntity(); + foreach ($propertyConfiguration as $propertyName => $configuration) { + $entity->setByProperty($propertyName, $this->getSlugForEntity($entity, $configuration)); + } + } + } + } + +} \ No newline at end of file diff --git a/src/Colibri/Extension/EventSubscriber/Timestampable.php b/src/Colibri/Extension/EventSubscriber/Timestampable.php new file mode 100644 index 0000000..9fbeffd --- /dev/null +++ b/src/Colibri/Extension/EventSubscriber/Timestampable.php @@ -0,0 +1,84 @@ +getConfiguration() as $entityClassName => $propertyConfiguration) { + if ($event->getEntity() instanceof $entityClassName) { + /** @var Repository $repository */ + $entity = $event->getEntity(); + $repository = $event->getRepository(); + foreach ($propertyConfiguration as $propertyName => $configuration) { + $this->updateEntity($propertyName, $entity, $repository, $configuration); + } + } + } + } + + /** + * @param $property + * @param EntityInterface $entity + * @param Repository $repository + * @param ParametersCollection $configuration + * @return null + * @throws ExtensionException + */ + private function updateEntity($property, EntityInterface $entity, Repository $repository, ParametersCollection $configuration) + { + if ($configuration->offsetExists('on') && $onEvent = $configuration->offsetGet('on')) { + + $onEvent = !static::isIterable($onEvent) ? [$onEvent] : $onEvent; + + foreach ($onEvent as $onEventName) { + if (($onEventName === Timestampable::ON_CREATE && $repository->isNewEntity($entity)) || $onEventName === Timestampable::ON_UPDATE) { + $entity->setByProperty($property, new DateTime()); + } + } + + return null; + } + + throw new ExtensionException('Wrong configuration passed to Timestampable extension'); + } + +} \ No newline at end of file diff --git a/src/Colibri/Extension/EventSubscriber/Versionable.php b/src/Colibri/Extension/EventSubscriber/Versionable.php new file mode 100644 index 0000000..abcaa05 --- /dev/null +++ b/src/Colibri/Extension/EventSubscriber/Versionable.php @@ -0,0 +1,47 @@ +resolveEntities($event, function (EntityInterface $entity, ParametersCollection $parameters) { + foreach ($parameters->get('properties') as $propertyName) { + $version = $entity->getByProperty($propertyName); + $entity->setByProperty($propertyName, $version + 1); + } + }); + } + +} \ No newline at end of file diff --git a/src/Colibri/Extension/ExtensionException.php b/src/Colibri/Extension/ExtensionException.php new file mode 100644 index 0000000..db5becc --- /dev/null +++ b/src/Colibri/Extension/ExtensionException.php @@ -0,0 +1,12 @@ + [ + + 'sluggable' => [ + \stdClass::class => [ + 'slug' => [ + 'properties' => ['name',], + 'prefix' => null, + 'suffix' => null, + 'separator' => '-', + ], + ], + ], + 'timestampable' => [ + \stdClass::class => [ + 'created' => [ + 'on' => [ + 'create', + ], + ], + 'modified' => [ + 'on' => [ + 'update', + 'create', + ], + ], + ], + ], + 'versionable' => [ + \stdClass::class => [ + 'properties' => [ + 'version', + ], + ], + ], + 'dataFilter' => [ + \stdClass::class => [ + 'name' => [ + 'filters' => [ + \Colibri\Filters\ClearHtmlFilter::class => [[],], // clear all + ], + ], + ], + ], + 'resourceLogger' => [ + // not implemented yet... + ], + ] +]; \ No newline at end of file diff --git a/src/Colibri/Filters/AbstractFilter.php b/src/Colibri/Filters/AbstractFilter.php new file mode 100644 index 0000000..6d6754e --- /dev/null +++ b/src/Colibri/Filters/AbstractFilter.php @@ -0,0 +1,10 @@ +setAllowedTags($allowedTags); + } + } + + /** + * @inheritDoc + */ + public function apply($input) + { + $allowedTags = array_map(function ($allowedTag) { + return sprintf('<%s>', $allowedTag); + }, $this->getAllowedTags()); + + return strip_tags($input, implode($allowedTags)); + } + + /** + * @return array + */ + public function getAllowedTags(): array + { + return $this->allowedTags; + } + + /** + * @param array $allowedTags + * @return $this + */ + public function setAllowedTags(array $allowedTags) + { + $this->allowedTags = $allowedTags; + + return $this; + } + +} \ No newline at end of file diff --git a/src/Colibri/Filters/FilterInterface.php b/src/Colibri/Filters/FilterInterface.php new file mode 100644 index 0000000..61f965a --- /dev/null +++ b/src/Colibri/Filters/FilterInterface.php @@ -0,0 +1,18 @@ +