Skip to content

Commit

Permalink
Add native types to SQLFilter (doctrine#9524)
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus authored Feb 24, 2022
1 parent 1712e3c commit 5ebe984
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 170 deletions.
59 changes: 17 additions & 42 deletions lib/Doctrine/ORM/Query/Filter/SQLFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,28 @@
*/
abstract class SQLFilter
{
/**
* The entity manager.
*
* @var EntityManagerInterface
*/
private $em;

/**
* Parameters for the filter.
*
* @psalm-var array<string,array{type: string, value: mixed, is_list: bool}>
*/
private $parameters = [];
private array $parameters = [];

/**
* @param EntityManagerInterface $em The entity manager.
*/
final public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
final public function __construct(
private EntityManagerInterface $em
) {
}

/**
* Sets a parameter list that can be used by the filter.
*
* @param string $name Name of the parameter.
* @param array<mixed> $values List of parameter values.
* @param string $type The parameter type. If specified, the given value will be run through
* the type conversion of this type.
*
* @return $this
*/
final public function setParameterList(string $name, array $values, string $type = Types::STRING): self
final public function setParameterList(string $name, array $values, string $type = Types::STRING): static
{
$this->parameters[$name] = ['value' => $values, 'type' => $type, 'is_list' => true];

Expand All @@ -73,15 +62,13 @@ final public function setParameterList(string $name, array $values, string $type
/**
* Sets a parameter that can be used by the filter.
*
* @param string $name Name of the parameter.
* @param mixed $value Value of the parameter.
* @param string|null $type The parameter type. If specified, the given value will be run through
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
* @param string|null $type The parameter type. If specified, the given value will be run through
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
*
* @return $this
*/
final public function setParameter($name, $value, $type = null): self
final public function setParameter(string $name, mixed $value, ?string $type = null): static
{
if ($type === null) {
$type = ParameterTypeInferer::inferType($value);
Expand All @@ -104,13 +91,11 @@ final public function setParameter($name, $value, $type = null): self
* The function is responsible for the right output escaping to use the
* value in a query.
*
* @param string $name Name of the parameter.
*
* @return string The SQL escaped parameter to use in a query.
*
* @throws InvalidArgumentException
*/
final public function getParameter($name)
final public function getParameter(string $name): string
{
if (! isset($this->parameters[$name])) {
throw new InvalidArgumentException("Parameter '" . $name . "' does not exist.");
Expand All @@ -132,10 +117,6 @@ final public function getParameter($name)
* value in a query, separating each entry by comma to inline it into
* an IN() query part.
*
* @param string $name Name of the parameter.
*
* @return string The SQL escaped parameter to use in a query.
*
* @throws InvalidArgumentException
*/
final public function getParameterList(string $name): string
Expand All @@ -151,31 +132,26 @@ final public function getParameterList(string $name): string
$param = $this->parameters[$name];
$connection = $this->em->getConnection();

$quoted = array_map(static function ($value) use ($connection, $param) {
return $connection->quote($value, $param['type']);
}, $param['value']);
$quoted = array_map(
static fn (mixed $value): string => (string) $connection->quote($value, $param['type']),
$param['value']
);

return implode(',', $quoted);
}

/**
* Checks if a parameter was set for the filter.
*
* @param string $name Name of the parameter.
*
* @return bool
*/
final public function hasParameter($name)
final public function hasParameter(string $name): bool
{
return isset($this->parameters[$name]);
}

/**
* Returns as string representation of the SQLFilter parameters (the state).
*
* @return string String representation of the SQLFilter.
*/
final public function __toString()
final public function __toString(): string
{
return serialize($this->parameters);
}
Expand All @@ -191,10 +167,9 @@ final protected function getConnection(): Connection
/**
* Gets the SQL query part to add to a query.
*
* @param string $targetTableAlias
* @psalm-param ClassMetadata<object> $targetEntity
*
* @return string The constraint SQL if there is available, empty string otherwise.
*/
abstract public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias);
abstract public function addFilterConstraint(ClassMetadata $targetEntity, string $targetTableAlias): string;
}
83 changes: 19 additions & 64 deletions lib/Doctrine/ORM/Query/FilterCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,70 +29,47 @@ class FilterCollection
*/
public const FILTERS_STATE_DIRTY = 2;

/**
* The used Configuration.
*
* @var Configuration
*/
private $config;

/**
* The EntityManager that "owns" this FilterCollection instance.
*
* @var EntityManagerInterface
*/
private $em;
private Configuration $config;

/**
* Instances of enabled filters.
*
* @var SQLFilter[]
* @psalm-var array<string, SQLFilter>
* @var array<string, SQLFilter>
*/
private $enabledFilters = [];
private array $enabledFilters = [];

/**
* The filter hash from the last time the query was parsed.
*
* @var string
*/
private $filterHash = '';
/** The filter hash from the last time the query was parsed. */
private string $filterHash = '';

/**
* The current state of this filter.
*
* @var int
* @psalm-var self::FILTERS_STATE_*
*/
private $filtersState = self::FILTERS_STATE_CLEAN;
private int $filtersState = self::FILTERS_STATE_CLEAN;

public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
public function __construct(
private EntityManagerInterface $em
) {
$this->config = $em->getConfiguration();
}

/**
* Gets all the enabled filters.
*
* @return SQLFilter[] The enabled filters.
* @psalm-return array<string, SQLFilter>
* @return array<string, SQLFilter> The enabled filters.
*/
public function getEnabledFilters()
public function getEnabledFilters(): array
{
return $this->enabledFilters;
}

/**
* Enables a filter from the collection.
*
* @param string $name Name of the filter.
*
* @return SQLFilter The enabled filter.
*
* @throws InvalidArgumentException If the filter does not exist.
*/
public function enable($name)
public function enable(string $name): SQLFilter
{
if (! $this->has($name)) {
throw new InvalidArgumentException("Filter '" . $name . "' does not exist.");
Expand All @@ -117,13 +94,9 @@ public function enable($name)
/**
* Disables a filter.
*
* @param string $name Name of the filter.
*
* @return SQLFilter The disabled filter.
*
* @throws InvalidArgumentException If the filter does not exist.
*/
public function disable($name)
public function disable(string $name): SQLFilter
{
// Get the filter to return it
$filter = $this->getFilter($name);
Expand All @@ -138,13 +111,9 @@ public function disable($name)
/**
* Gets an enabled filter from the collection.
*
* @param string $name Name of the filter.
*
* @return SQLFilter The filter.
*
* @throws InvalidArgumentException If the filter is not enabled.
*/
public function getFilter($name)
public function getFilter(string $name): SQLFilter
{
if (! $this->isEnabled($name)) {
throw new InvalidArgumentException("Filter '" . $name . "' is not enabled.");
Expand All @@ -155,44 +124,32 @@ public function getFilter($name)

/**
* Checks whether filter with given name is defined.
*
* @param string $name Name of the filter.
*
* @return bool true if the filter exists, false if not.
*/
public function has($name)
public function has(string $name): bool
{
return $this->config->getFilterClassName($name) !== null;
}

/**
* Checks if a filter is enabled.
*
* @param string $name Name of the filter.
*
* @return bool True if the filter is enabled, false otherwise.
*/
public function isEnabled($name)
public function isEnabled(string $name): bool
{
return isset($this->enabledFilters[$name]);
}

/**
* Checks if the filter collection is clean.
*
* @return bool
*/
public function isClean()
public function isClean(): bool
{
return $this->filtersState === self::FILTERS_STATE_CLEAN;
}

/**
* Generates a string of currently enabled filters to use for the cache id.
*
* @return string
*/
public function getHash()
public function getHash(): string
{
// If there are only clean filters, the previous hash can be returned
if ($this->filtersState === self::FILTERS_STATE_CLEAN) {
Expand All @@ -213,10 +170,8 @@ public function getHash()

/**
* Sets the filter state to dirty.
*
* @return void
*/
public function setFiltersStateDirty()
public function setFiltersStateDirty(): void
{
$this->filtersState = self::FILTERS_STATE_DIRTY;
}
Expand Down
6 changes: 0 additions & 6 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1837,12 +1837,6 @@
</NonInvariantDocblockPropertyType>
</file>
<file src="lib/Doctrine/ORM/Query/Filter/SQLFilter.php">
<MissingClosureParamType occurrences="1">
<code>$value</code>
</MissingClosureParamType>
<MissingClosureReturnType occurrences="1">
<code>static function ($value) use ($connection, $param) {</code>
</MissingClosureReturnType>
<PropertyTypeCoercion occurrences="1">
<code>$this-&gt;parameters</code>
</PropertyTypeCoercion>
Expand Down
Loading

0 comments on commit 5ebe984

Please sign in to comment.