-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[PropertyAccess] Allow custom methods on property accesses #18016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
af3a824
5b82237
00a26eb
e4aaac9
e46df98
5f206e6
94e6157
09707ad
d02d93a
748b894
688cbda
003efdb
dc5cacb
1a35d45
1e29523
7c6a79c
d0bd777
6b7eeff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,5 +41,6 @@ | |
<framework:validation enabled="true" cache="validator.mapping.cache.doctrine.apc" /> | ||
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" /> | ||
<framework:serializer enabled="true" enable-annotations="true" name-converter="serializer.name_converter.camel_case_to_snake_case" /> | ||
<framework:property-access cache="property_access.mapping.cache.doctrine.apc" enable-annotations="true" magic-call="false" throw-exception-on-invalid-index="false" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be removed and use the new cache component instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. |
||
</framework:config> | ||
</container> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Exception; | ||
|
||
/** | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class NoSuchMetadataException extends AccessException | ||
{ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Mapping\Cache; | ||
|
||
use Symfony\Component\PropertyAccess\Mapping\ClassMetadata; | ||
|
||
/** | ||
* Persists ClassMetadata instances in a cache. | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
interface CacheInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a need for another CacheInterface? Why not just stick to PSR-6 without the need for another layer of indirection? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Metadata caching is still WIP. I just migrated the Validator component cache into PropertyAccess. As you say, the next logical step is integrate with the new Cache component |
||
{ | ||
/** | ||
* Returns whether metadata for the given class exists in the cache. | ||
* | ||
* @param string $class | ||
*/ | ||
public function has($class); | ||
|
||
/** | ||
* Returns the metadata for the given class from the cache. | ||
* | ||
* @param string $class Class Name | ||
* | ||
* @return ClassMetadata|false A ClassMetadata instance or false on miss | ||
*/ | ||
public function read($class); | ||
|
||
/** | ||
* Stores a class metadata in the cache. | ||
* | ||
* @param ClassMetadata $metadata A Class Metadata | ||
*/ | ||
public function write(ClassMetadata $metadata); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Mapping\Cache; | ||
|
||
use Doctrine\Common\Cache\Cache; | ||
use Symfony\Component\PropertyAccess\Mapping\ClassMetadata; | ||
|
||
/** | ||
* Adapts a Doctrine cache to a CacheInterface. | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
final class DoctrineCache implements CacheInterface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new Symfony Cache component (a PSR-6 implementation) has a Doctrine Cache adapter. |
||
{ | ||
private $cache; | ||
|
||
/** | ||
* Creates a new Doctrine cache. | ||
* | ||
* @param Cache $cache The cache to adapt | ||
*/ | ||
public function __construct(Cache $cache) | ||
{ | ||
$this->cache = $cache; | ||
} | ||
|
||
/** | ||
* Sets the cache to adapt. | ||
* | ||
* @param Cache $cache The cache to adapt | ||
*/ | ||
public function setCache(Cache $cache) | ||
{ | ||
$this->cache = $cache; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function has($class) | ||
{ | ||
return $this->cache->contains($class); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function read($class) | ||
{ | ||
return $this->cache->fetch($class); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function write(ClassMetadata $metadata) | ||
{ | ||
$this->cache->save($metadata->getName(), $metadata); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Mapping\Cache; | ||
|
||
use Psr\Cache\CacheItemPoolInterface; | ||
use Symfony\Component\PropertyAccess\Mapping\ClassMetadata; | ||
|
||
/** | ||
* PSR-6 adapter. | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class Psr6Cache implements CacheInterface | ||
{ | ||
/** | ||
* @var CacheItemPoolInterface | ||
*/ | ||
private $cacheItemPool; | ||
|
||
public function __construct(CacheItemPoolInterface $cacheItemPool) | ||
{ | ||
$this->cacheItemPool = $cacheItemPool; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function has($class) | ||
{ | ||
return $this->cacheItemPool->hasItem($this->escapeClassName($class)); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function read($class) | ||
{ | ||
$item = $this->cacheItemPool->getItem($this->escapeClassName($class)); | ||
|
||
if (!$item->isHit()) { | ||
return false; | ||
} | ||
|
||
return $item->get(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function write(ClassMetadata $metadata) | ||
{ | ||
$item = $this->cacheItemPool->getItem($this->escapeClassName($metadata->getName())); | ||
$item->set($metadata); | ||
|
||
$this->cacheItemPool->save($item); | ||
} | ||
|
||
/** | ||
* Replaces backslashes by dots in a class name. | ||
* | ||
* @param string $class | ||
* | ||
* @return string | ||
*/ | ||
private function escapeClassName($class) | ||
{ | ||
return str_replace('\\', '.', $class); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\PropertyAccess\Mapping\Factory; | ||
|
||
/** | ||
* Metadata factory that does not store metadata. | ||
* | ||
* This implementation is useful if you want to validate values against | ||
* constraints only and you don't need to add constraints to classes and | ||
* properties. | ||
* | ||
* @author Luis Ramón López <lrlopez@gmail.com> | ||
*/ | ||
class BlackHoleMetadataFactory implements MetadataFactoryInterface | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getMetadataFor($value) | ||
{ | ||
throw new \LogicException('This class does not support metadata.'); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function hasMetadataFor($value) | ||
{ | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for this docblock imo