Skip to content
This repository has been archived by the owner on Mar 31, 2022. It is now read-only.

Commit

Permalink
'customProperties update'
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinDev committed Dec 19, 2020
1 parent d331c5f commit 8f230f4
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 18 deletions.
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -111,9 +111,6 @@ List of existing extension wich are not in the **core** :

## TODO before v1

- [ ] Gérer un système d'extension viable pour l'admin : à l'install, créer les fichiers Admin qui étendent l'admin de base
L'ajout d'un plugin modifie automatiquement ce nouveau fichier en ajoutant le code nécessaire (ajout d'une trait + édition d'une fonction)
Retro-compatibilité : créer le fichier admin + le services (autowire) si il n'existe pas
- [ ] Refactor default theme (and add Default bootstrap 5, default Tailwind in core ?!)
- [ ] Better management for social network from backend (plugin ?!) (for now, just use customProperty)
- [ ] Move facultative extensin in an other bundle (PageUpdateNotification)
Expand All @@ -133,6 +130,9 @@ List of existing extension wich are not in the **core** :

### To plan

- [ ] Gérer un système d'extension viable pour l'admin : à l'install, créer les fichiers Admin qui étendent l'admin de base
L'ajout d'un plugin modifie automatiquement ce nouveau fichier en ajoutant le code nécessaire (ajout d'une trait + édition d'une fonction)
Retro-compatibilité : créer le fichier admin + le services (autowire) si il n'existe pas
- [ ] Scan : scanner une page en direct + scanner plus de choses (liens externes, texte alternative manquant, etc.)
- [ ] Multi upload
- [ ] Test the code, search for all "todo" in the code,
Expand Down
2 changes: 1 addition & 1 deletion src/Entity/Page.php
Expand Up @@ -26,14 +26,14 @@
*/
class Page implements PageInterface
{
use CustomPropertiesTrait;
use IdTrait;
use PageExtendedTrait;
use PageI18nTrait;
use PageImageTrait;
use PageMultiHostTrait;
use PageRedirectionTrait;
use PageTrait;
use CustomPropertiesTrait;

public function __construct()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Entity/PageInterface.php
Expand Up @@ -32,7 +32,7 @@ public function getTemplate();

public function setMainContent(?string $mainContent);

public function getCustomProperty($name);
public function getCustomProperty(string $name);

public function getH1();

Expand Down
15 changes: 15 additions & 0 deletions src/Entity/SharedTrait/CustomPropertiesException.php
@@ -0,0 +1,15 @@
<?php

namespace PiedWeb\CMSBundle\Entity\SharedTrait;

use Exception;

class CustomPropertiesException extends Exception
{
public function __construct(string $name)
{
$message = 'use `setStandAloneCustomProperties` for an index custom property (`'.$name.'`)';

parent::__construct($message);
}
}
144 changes: 131 additions & 13 deletions src/Entity/SharedTrait/CustomPropertiesTrait.php
Expand Up @@ -18,43 +18,161 @@ trait CustomPropertiesTrait

protected $customPropertiesParsed;

public function getCustomProperties()
/**
* Stand Alone for Not Indexed.
*
* @var array
*/
protected $StandAloneCustomPropertiesParsed;

protected $StandAloneCustomProperties;

public function getCustomProperties(): ?string
{
return $this->customProperties;
}

public function setCustomProperties($customProperties)
public function setCustomProperties($customProperties): self
{
$this->customProperties = $customProperties;
$this->customPropertiesParsed = null;

return $customProperties;
return $this;
}

/**
* @Assert\Callback
*/
public function validateCustomProperties(ExecutionContextInterface $context)
public function validateCustomProperties(ExecutionContextInterface $context, $path = 'customProperties'): void
{
if (! empty($this->customProperties)) {
// ou utiliser yaml_parse
try {
Yaml::parse($this->customProperties);
} catch (ParseException $exception) {
$context->buildViolation('page.customProperties.malformed') //'$exception->getMessage())
->atPath('customProperties')
if (empty($this->customProperties)) {
return;
}

try {
$parsed = Yaml::parse($this->customProperties);
if (isset($parsed['customProperties']) || $parsed['CustomProperties']) {
$context->buildViolation('page.customProperties.cantUseCustomPropertiesInside')
->atPath($path)
->addViolation();
}
} catch (ParseException $exception) {
$context->buildViolation('page.customProperties.malformed') //'$exception->getMessage())
->atPath($path)
->addViolation();
}
}

/**
* Return custom properties without the ones wich have a get method.
*/
public function getStandAloneCustomProperties(): string
{
$customPropertiesParsed = $this->getCustomPropertiesParsed();
if (! $customPropertiesParsed) {
return '';
}
$standStandAloneCustomPropertiesParsed = array_filter(
$customPropertiesParsed,
[$this, 'isStandAloneCustomProperty'],
ARRAY_FILTER_USE_KEY
);

return Yaml::dump($standStandAloneCustomPropertiesParsed);
}

public function setStandAloneCustomProperties(?string $standStandAloneCustomProperties, $merge = false)
{
$this->standAloneCustomProperties = $standStandAloneCustomProperties;

if ($merge) {
$this->mergeStandAloneCustomProperties();
}

$this->customProperties = Yaml::dump(Yaml::parse($this->customProperties));
// check them :
// 1. Can We parse them ?
// Yes - Remove duplicate (done )
$this->customPropertiesParsed = null;

return $this;
}

protected function mergeStandAloneCustomProperties()
{
$standStandAloneParsed = Yaml::parse($this->standAloneCustomProperties);
$this->standAloneCustomProperties = null;

if (! $standStandAloneParsed) {
return;
}

foreach ($standStandAloneParsed as $name => $value) {
if (! $this->isStandAloneCustomProperty($name)) {
throw new CustomPropertiesException($name);
}

$this->setCustomProperty($name, $value);
}
}

public function getCustomProperty($name)
/**
* @Assert\Callback
*/
public function validateStandAloneCustomProperties(ExecutionContextInterface $context, $path = 'standAloneCustomProperties'): void
{
if (empty($this->standStandAloneCustomProperties)) {
return;
}

try {
$this->mergeStandAloneCustomProperties();
} catch (ParseException $exception) {
$context->buildViolation('page.customProperties.malformed') //'$exception->getMessage())
->atPath($path)
->addViolation();
} catch (CustomPropertiesException $exception) {
$context->buildViolation('page.customProperties.notStandAlone') //'$exception->getMessage())
->atPath($path)
->addViolation();
}

$this->validateCustomProperties($context, $path); // too much
}

protected function isStandAloneCustomProperty($name): bool
{
return ! method_exists($this, 'get'.ucfirst($name)) && ! method_exists($this, 'get'.$name);
}

public function setCustomProperty($name, $value): self
{
$customPropertiesParsed = $this->getCustomPropertiesParsed();

$customPropertiesParsed[$name] = $value;

$this->customProperties = Yaml::dump($customPropertiesParsed);

return $this;
}

protected function getCustomPropertiesParsed(): array
{
if (null === $this->customPropertiesParsed) {
$this->customPropertiesParsed = $this->customProperties ? Yaml::parse($this->customProperties) : [];
}

return $this->customPropertiesParsed[$name] ?? null;
return $this->customPropertiesParsed;
}

/**
* @return mixed
*/
public function getCustomProperty(string $name)
{
$customPropertiesParsed = $this->getCustomPropertiesParsed();

return $customPropertiesParsed[$name] ?? null;
}

/**
Expand Down
73 changes: 73 additions & 0 deletions tests/Entity/SharedTrait/CustomPropertiesTraitTest.php
@@ -0,0 +1,73 @@
<?php

namespace PiedWeb\CMSBundle\Tests\Entity\SharedTrait;

use PHPUnit\Framework\TestCase;
use PiedWeb\CMSBundle\Entity\SharedTrait\CustomPropertiesTrait;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
use Symfony\Component\Yaml\Yaml;

class CustomPropertiesTraitTest extends TestCase
{
protected static function customPorperties($firstValue = 'test', $secondValue = 'test 2')
{
return Yaml::dump([
'newCustomPropertyNotIndexed' => $firstValue,
'customProperties' => $secondValue,
]);
}

protected static function standStandAloneCustomProperties($firstValue = 'test')
{
return Yaml::dump(['newCustomPropertyNotIndexed' => $firstValue]);
}

public function testStandAloneCustomProperties()
{
$customProperties = $this->getCustomPropertiesTrait();

$this->assertNull($customProperties->getCustomProperties());

$customProperties->setCustomProperties(static::customPorperties());

$this->assertNull($customProperties->validateCustomProperties($this->getExceptionContextInterface()));
$this->assertSame($customProperties->getCustomProperties(), static::customPorperties());
$this->assertSame($customProperties->getStandAloneCustomProperties(), static::standStandAloneCustomProperties());

$customProperties->setStandAloneCustomProperties(static::standStandAloneCustomProperties('test 1234'), true);
$this->assertSame(static::customPorperties('test 1234'), $customProperties->getCustomProperties());
}

/**
* @return CustomPropertiesTrait
*/
protected function getCustomPropertiesTrait()
{
$mock = $this->getMockForTrait(CustomPropertiesTrait::class);
//$mock->method('getTitle')->willReturn(true);

return $mock;
}

/**
* @return ExecutionContextInterface
*/
protected function getExceptionContextInterface()
{
$mockConstraintViolationBuilder = $this->createMock(ConstraintViolationBuilderInterface::class);
$mockConstraintViolationBuilder->method('atPath')->willReturnSelf();
$mockConstraintViolationBuilder->method('addViolation')->willReturnSelf();

$mock = $this->createMock(ExecutionContextInterface::class);
$mock->method('buildViolation')->willReturnCallback(function ($arg) use ($mockConstraintViolationBuilder) {
if (\in_array($arg, ['page.customProperties.malformed', 'page.customProperties.notStandAlone'])) {
new \Error();
} else {
return $mockConstraintViolationBuilder;
}
});

return $mock;
}
}

0 comments on commit 8f230f4

Please sign in to comment.