8000 [Form] Added support for caching choice lists based on options · symfony/symfony@81ce543 · GitHub
[go: up one dir, main page]

Skip to content

Commit 81ce543

Browse files
committed
[Form] Added support for caching choice lists based on options
1 parent c68ef46 commit 81ce543

19 files changed

+509
-30
lines changed

src/Symfony/Bridge/Doctrine/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* changed guessing of DECIMAL to set the `input` option of `NumberType` to string
88
* deprecated not passing an `IdReader` to the `DoctrineChoiceLoader` when query can be optimized with a single id field
99
* deprecated passing an `IdReader` to the `DoctrineChoiceLoader` when entities have a composite id
10+
* added a `ChoiceList` facade to explicit choice lists caching based on callback options or loader when configured by specific form types
1011

1112
4.2.0
1213
-----
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList;
13+
14+
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceFilter;
15+
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceFieldName;
16+
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLabel;
17+
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLoader;
18+
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceValue;
19+
use Symfony\Component\Form\ChoiceList\Factory\Cache\GroupBy;
20+
use Symfony\Component\Form\ChoiceList\Factory\Cache\PreferredChoice;
21+
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
22+
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
23+
use Symfony\Component\Form\FormTypeInterface;
24+
25+
/**
26+
* A set of convenient static methods to create choice list callbacks or loaders.
27+
*
28+
* @author Jules Pietri <jules@heahprod.com>
29+
*/
30+
class ChoiceList
31+
{
32+
/**
33+
* @param FormTypeInterface $formType A form type configuring a list
34+
* @param ChoiceLoaderInterface $loader Any pseudo callable to create a unique value from a choice
35+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the loader
36+
*/
37+
public static function lazy(FormTypeInterface $formType, callable $choices, $vary = null): ChoiceLoader
38+
{
39+
return self::loader($formType, new CallbackChoiceLoader($choices), $vary);
40+
}
41+
42+
/**
43+
* @param FormTypeInterface $formType A form type configuring a list
44+
* @param ChoiceLoaderInterface $loader Any pseudo callable to create a unique value from a choice
45+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the loader
46+
*/
47+
public static function loader(FormTypeInterface $formType, ChoiceLoaderInterface $loader, $vary = null): ChoiceLoader
48+
{
49+
return new ChoiceLoader($formType, $loader, $vary);
50+
}
51+
52+
/**
53+
* @param FormTypeInterface $formType A form type configuring a list
54+
* @param callable $value Any pseudo callable to create a unique value from a choice
55+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the callback
56+
*/
57+
public static function value(FormTypeInterface $formType, $value, $vary = null): ChoiceValue
58+
{
59+
return new ChoiceValue($formType, $value);
60+
}
61+
62+
/**
63+
* @param FormTypeInterface $formType A form type configuring a list
64+
* @param callable $label Any pseudo callable to create a label from a choice
65+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the callback
66< 10000 /code>+
*/
67+
public static function label(FormTypeInterface $formType, $label, $vary = null): ChoiceLabel
68+
{
69+
return new ChoiceLabel($formType, $label);
70+
}
71+
72+
/**
73+
* @param FormTypeInterface $formType A form type configuring a list
74+
* @param callable $fieldName Any pseudo callable to create a form name from a choice
75+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the callback
76+
*/
77+
public static function fieldName(FormTypeInterface $formType, $fieldName, $vary = null): ChoiceFieldName
78+
{
79+
return new ChoiceFieldName($formType, $fieldName);
80+
}
81+
82+
/**
83+
* @param FormTypeInterface $formType A form type configuring a list
84+
* @param callable $groupBy Any pseudo callable to return a group name from a choice
85+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the callback
86+
*/
87+
public static function groupBy(FormTypeInterface $formType, $groupBy, $vary = null): GroupBy
88+
{
89+
return new GroupBy($formType, $groupBy);
90+
}
91+
92+
/**
93+
* @param FormTypeInterface $formType A form type configuring a list
94+
* @param callable $preferred Any pseudo callable to return a group name from a choice
95+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the callback
96+
*/
97+
public static function preferred(FormTypeInterface $formType, $preferred, $vary = null): PreferredChoice
98+
{
99+
return new PreferredChoice($formType, $preferred);
100+
}
101+
}

src/Symfony/Component/Form/ChoiceList/ChoiceListInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public function getValues();
8686
* this method SHOULD be equivalent to {@link getValues()}.
8787
* The $groupBy callback parameter SHOULD be used instead.
8888
*
89-
* @return string[] The choice values
89+
* @return string[]|string[][] The choice values
9090
*/
9191
public function getStructuredValues();
9292

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/*
3+
* This file is part of the BlackfireBundle project.
4+
*
5+
* (c) Jules Pietri <jules@heahprod.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
12+
13+
use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator;
14+
use Symfony\Component\Form\FormTypeInterface;
15+
16+
/**
17+
* A template for static callbacks used by {@see CachingFactoryDecorator}.
18+
*
19+
* @internal
20+
*
21+
* @author Jules Pietri <jules@heahprod.com>
22+
*/
23+
abstract class AbstractStaticCallback
24+
{
25+
private static $callbacks = [];
26+
27+
/** @var callable|string|array|\Closure */
28+
private $callback;
29+
30+
/**
31+
* @param FormTypeInterface $formType A form type configuring a list
32+
* @param callable $callback Any pseudo callable to create choice list property
33+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the callback
34+
*/
35+
final public function __construct(FormTypeInterface $formType, $callback, $vary = null)
36+
{
37+
$uniquePrefix = $formType->getBlockPrefix();
38+
$hash = $vary ? CachingFactoryDecorator::generateHash($vary) : '';
39+
40+
if (empty(self::$callbacks[static::class][$uniquePrefix])) {
41+
self::$callbacks[static::class][$uniquePrefix][$hash] = $callback;
42+
}
43+
44+
$this->callback = self::$callbacks[static::class][$uniquePrefix][$hash];
45+
}
46+
47+
/**
48+
* @return mixed
49+
*/
50+
final public function getCallback()
51+
{
52+
return $this->callback;
53+
}
54+
55+
public static function reset()
56+
{
57+
self::$callbacks = [];
58+
}
59+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
13+
14+
use Symfony\Component\Form\FormTypeInterface;
15+
16+
/**
17+
* A static wrapper for any {@see FormTypeInterface} which configures a choice attributes callback.
18+
*
19+
* @internal
20+
*
21+
* @author Jules Pietri <jules@heahprod.com>
22+
*/
23+
final class ChoiceAttr extends AbstractStaticCallback
24+
{
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
13+
14+
use Symfony\Component\Form\FormTypeInterface;
15+
16+
/**
17+
* A static wrapper for any {@see FormTypeInterface} which configures a choice field name callback.
18+
*
19+
* @internal
20+
*
21+
* @author Jules Pietri <jules@heahprod.com>
22+
*/
23+
final class ChoiceFieldName extends AbstractStaticCallback
24+
{
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
13+
14+
use Symfony\Component\Form\FormTypeInterface;
15+
16+
/**
17+
* A static wrapper for any {@see FormTypeInterface} which configures a choice label callback.
18+
*
19+
* @internal
20+
*
21+
* @author Jules Pietri <jules@heahprod.com>
22+
*/
23+
final class ChoiceLabel extends AbstractStaticCallback
24+
{
25+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
13+
14+
use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator;
15+
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
16+
use Symfony\Component\Form\FormTypeInterface;
17+
18+
/**
19+
* A FlyWeight for types using static loaders, used by {@see CachingFactoryDecorator}.
20+
*
21+
* @internal
22+
*
23+
* @author Jules Pietri <jules@heahprod.com>
24+
*/
25+
class ChoiceLoader implements ChoiceLoaderInterface
26+
{
27+
private static $loaders = [];
28+
29+
/** @var ChoiceLoaderInterface */
30+
private $loader;
31+
32+
/**
33+
* @param FormTypeInterface $formType A form type configuring a list
34+
* @param ChoiceLoaderInterface $loader A static loader used by the type
35+
* @param mixed $vary Dynamic data used to compute a unique hash when caching the loader
36+
*/
37+
final public function __construct(FormTypeInterface $formType, ChoiceLoaderInterface $loader, $vary)
38+
{
39+
$uniquePrefix = $formType->getBlockPrefix();
40+
$hash = $vary ? CachingFactoryDecorator::generateHash($vary) : '';
41+
42+
if (empty(self::$loaders[static::class][$uniquePrefix])) {
43+
self::$loaders[static::class][$uniquePrefix][$hash] = $loader;
44+
}
45+
46+
$this->loader = self::$loaders[static::class][$uniquePrefix][$hash];
47+
}
48+
49+
final public function getLoader(): ChoiceLoaderInterface
50+
{
51+
return $this->loader;
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function loadChoiceList($value = null)
58+
{
59+
return $this->loader->loadChoiceList($value);
60+
}
61+
62+
/**
63+
* Not implemented.
64+
*/
65+
public function loadChoicesForValues(array $values, $value = null)
66+
{
67+
return $this->loader->loadChoicesForValues($value);
68+
}
69+
70+
/**
71+
* Not implemented.
72+
*/
73+
public function loadValuesForChoices(array $choices, $value = null)
74+
{
75+
return $this->loader->loadValuesForChoices($value);
76+
}
77+
78+
public static function reset()
79+
{
80+
self::$loaders = [];
81+
}
82+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
13+
14+
use Symfony\Component\Form\FormTypeInterface;
15+
16+
/**
17+
* A static wrapper for any {@see FormTypeInterface} which configures a choice value callback.
18+
*
19+
* @internal
20+
*
21+
* @author Jules Pietri <jules@heahprod.com>
22+
*/
23+
final class ChoiceValue extends AbstractStaticCallback
24+
{
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
13+
14+
use Symfony\Component\Form\FormTypeInterface;
15+
16+
/**
17+
* A static wrapper for any {@see FormTypeInterface} which configures a group by callback.
18+
*
19+
* @internal
20+
*
21+
* @author Jules Pietri <jules@heahprod.com>
22+
*/
23+
final class GroupBy extends AbstractStaticCallback
24+
{
25+
}

0 commit comments

Comments
 (0)
0