-
The
AbstractJoin::getJoinType()
method was removed. UseAbstractJoin::modifyJoin()
method inside. -
The
Comparison
class marked asabstract
. -
The
LogicX
class marked asabstract
. -
The
protected
properties inComparison
class marked asprivate
. -
The
protected
properties inIn
class marked asprivate
. -
The
protected
properties inGroupBy
class marked asprivate
. -
The
protected
properties inOrderBy
class marked asprivate
. -
The
protected
properties inLimit
class marked asprivate
. -
The
protected
properties inOffset
class marked asprivate
. -
The
Bitwise
operands was removed. -
The
Happyr\DoctrineSpecification\Specification\Having
class was removed, useHappyr\DoctrineSpecification\Query\Having
instead. -
The
Happyr\DoctrineSpecification\EntitySpecificationRepository
class was removed, useHappyr\DoctrineSpecification\Repository\EntitySpecificationRepository
instead. -
The
Happyr\DoctrineSpecification\EntitySpecificationRepositoryInterface
class was removed, useHappyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface
instead. -
The
Happyr\DoctrineSpecification\EntitySpecificationRepositoryTrait
class was removed, useHappyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryTrait
instead. -
The
Happyr\DoctrineSpecification\RepositoryFactory
class was removed, useHappyr\DoctrineSpecification\Repository\RepositoryFactory
instead. -
The
Happyr\DoctrineSpecification\BaseSpecification
class was removed, useHappyr\DoctrineSpecification\Specification\BaseSpecification
instead. -
Removes the ability to use
array
as argument for thePlatformFunction
operand.Before:
$arguments = ['create_at', new \DateTimeImmutable()]; Spec::DATE_DIFF($arguments); Spec::fun('DATE_DIFF', $arguments); new PlatformFunction('DATE_DIFF', $arguments);
After:
$arguments = ['create_at', new \DateTimeImmutable()]; Spec::DATE_DIFF(...$arguments); Spec::fun('DATE_DIFF', ...$arguments); new PlatformFunction('DATE_DIFF', ...$arguments);
-
Removes the ability to use
array
as argument for theSelect
query modifier.Before:
$fields = ['title', 'cover']; Spec::select($fields); new Select($fields);
After:
$fields = ['title', 'cover']; Spec::select(...$fields); new Select(...$fields);
-
Removes the ability to use
array
as argument for theAddSelect
query modifier.Before:
$fields = ['title', 'cover']; Spec::addSelect($fields); new AddSelect($fields);
After:
$fields = ['title', 'cover']; Spec::addSelect(...$fields); new AddSelect(...$fields);
-
The
BaseSpecification::getSpec()
method marked asabstract
. -
The
InvalidArgumentException
class marked asfinal
. -
The
LogicException
class marked asfinal
. -
The
NonUniqueResultException
class marked asfinal
. -
The
NoResultException
class marked asfinal
. -
The
UnexpectedResultException
class marked asabstract
. -
All the filter classes marked as
final
. -
All the logic classes marked as
final
. -
All the operand classes marked as
final
. -
All the query modifier classes marked as
final
. -
All the result modifier classes marked as
final
. -
The
CountOf
class marked asfinal
. -
The
DBALTypesResolver
class marked asfinal
. -
The
ValueConverter
class marked asfinal
. -
The
EntitySpecificationRepositoryTrait::getAlias()
method returns nothing else. -
The
Operand::execute()
method was added. This method performs the necessary actions on the operand and returns the result. It is desirable to return a scalar value so that it is compatible with other operands. -
The custom platform functions also need to be made executable and register the executor in the registry.
PlatformFunction::getExecutorRegistry()->register('POW', fn ($base, $exp) => pow($base, $exp));
-
The use of DQL aliases has been replaced with descriptions of contexts.
Before:
Spec::andX( Spec::innerJoin('contestant', 'ct'), Spec::innerJoin('contest', 'c', 'ct'), Spec::innerJoin('user', 'u', 'ct'), Spec::eq('state', State::active()->value(), 'u'), Spec::eq('enabled', true, 'c') );
After:
Spec::andX( Spec::eq('state', State::active()->value(), 'contestant.user'), Spec::eq('enabled', true, 'contestant.contest') );
-
Changed behavior of DQL aliases to use context.
Before:
final class PublishedQuestionnaires extends BaseSpecification { private string $contest_alias; private string $contestant_alias; private string $user_alias; public function __construct( string $contest_alias = 'c', string $contestant_alias = 'ct', string $user_alias = 'u', ?string $dql_alias = null ) { $this->contest_alias = $contest_alias; $this->contestant_alias = $contestant_alias; $this->user_alias = $user_alias; parent::__construct($dql_alias); } /** * @return Filter|QueryModifier */ protected function getSpec() { return Spec::andX( Spec::innerJoin('contestant', $this->contestant_alias), new ContestantPublished($this->contest_alias, $this->user_alias, $this->contestant_alias) ); } } final class ContestantPublished extends BaseSpecification { private string $contest_alias; private string $user_alias; public function __construct(string $contest_alias = 'c', string $user_alias = 'u', ?string $dql_alias = null) { $this->contest_alias = $contest_alias; $this->user_alias = $user_alias; parent::__construct($dql_alias); } /** * @return Filter|QueryModifier */ protected function getSpec() { return Spec::andX( new JoinedContestant($this->contest_alias, $this->user_alias), new ContestantApproved($this->contest_alias) ); } } final class ContestantApproved extends BaseSpecification implements Satisfiable { private string $contest_alias; public function __construct(string $contest_alias = 'c', ?string $dql_alias = null) { $this->contest_alias = $contest_alias; parent::__construct($dql_alias); } /** * @return Filter|QueryModifier */ protected function getSpec() { return Spec::orX( Spec::eq('permission', Permission::approved()->value()), Spec::not(new ContestRequireModeration($this->contest_alias)) ); } }
After:
final class PublishedQuestionnaires extends BaseSpecification { /** * @return Filter|QueryModifier */ protected function getSpec() { return new ContestantPublished('contestant'); } } final class ContestantPublished extends BaseSpecification { /** * @return Filter|QueryModifier */ protected function getSpec() { return Spec::andX( new JoinedContestant(), new ContestantApproved() ); } } final class ContestantApproved extends BaseSpecification implements Satisfiable { /** * @return Filter|QueryModifier */ protected function getSpec() { return Spec::orX( Spec::eq('permission', Permission::approved()->value()), Spec::not(new ContestRequireModeration('contest')) ); } }
-
The
Satisfiable
interface was added. -
The
Specification
interface was extendsSatisfiable
interface. -
The
BaseSpecification
class implementSatisfiable
interface. -
The
Happyr\DoctrineSpecification\Operand\CountDistinct
class was removed, useHappyr\DoctrineSpecification\Operand\PlatformFunction\Count
instead. -
The
Spec::countDistinct()
method was removed, useSpec::COUNT()
instead.Before:
new CountDistinct('field_name'); Spec::countDistinct('field_name');
After:
new Count('field_name', true); Spec::COUNT('field_name', true);
-
The
COUNT
function as argument toSpec::fun()
is not longer supported, useSpec::COUNT()
instead. -
The
COUNT
function as argument toHappyr\DoctrineSpecification\Operand\PlatformFunction
is not longer supported, useHappyr\DoctrineSpecification\Operand\PlatformFunction\Count
instead.Before:
new PlatformFunction('COUNT', 'field_name'); Spec::fun('COUNT', 'field_name');
After:
new Count('field_name'); Spec::COUNT('field_name');
-
The
AVG
function as argument toSpec::fun()
is not longer supported, useSpec::AVG()
instead. -
The
AVG
function as argument toHappyr\DoctrineSpecification\Operand\PlatformFunction
is not longer supported, useHappyr\DoctrineSpecification\Operand\PlatformFunction\Avg
instead.Before:
new PlatformFunction('AVG', 'field_name'); Spec::fun('AVG', 'field_name');
After:
new Avg('field_name'); Spec::AVG('field_name');
-
The
MIN
function as argument toSpec::fun()
is not longer supported, useSpec::MIN()
instead. -
The
MIN
function as argument toHappyr\DoctrineSpecification\Operand\PlatformFunction
is not longer supported, useHappyr\DoctrineSpecification\Operand\PlatformFunction\Min
instead.Before:
new PlatformFunction('MIN', 'field_name'); Spec::fun('MIN', 'field_name');
After:
new Min('field_name'); Spec::MIN('field_name');
-
The
MAX
function as argument toSpec::fun()
is not longer supported, useSpec::MAX()
instead. -
The
MAX
function as argument toHappyr\DoctrineSpecification\Operand\PlatformFunction
is not longer supported, useHappyr\DoctrineSpecification\Operand\PlatformFunction\Max
instead.Before:
new PlatformFunction('MAX', 'field_name'); Spec::fun('MAX', 'field_name');
After:
new Max('field_name'); Spec::MAX('field_name');
-
The
SUM
function as argument toSpec::fun()
is not longer supported, useSpec::SUM()
instead. -
The
SUM
function as argument toHappyr\DoctrineSpecification\Operand\PlatformFunction
is not longer supported, useHappyr\DoctrineSpecification\Operand\PlatformFunction\Sum
instead.Before:
new PlatformFunction('SUM', 'field_name'); Spec::fun('SUM', 'field_name');
After:
new Sum('field_name'); Spec::SUM('field_name');
-
Define
Spec::leftJoin()
,Spec::innerJoin()
andSpec::join()
before using the new alias from it.Before:
$spec = Spec::andX( Spec::select(Spec::selectEntity('person')), Spec::leftJoin('person', 'person') );
After:
$spec = Spec::andX( Spec::leftJoin('person', 'person'), Spec::select(Spec::selectEntity('person')) );
- No BC breaks
- The
Comparison
no longer supports the operatorLIKE
. Use theLike
filter. - The
Like
filter no longer expands theComparison
base filter. - The
IsNotNull
filter no longer expands theIsNull
base filter.
- The
CountOf
specification not expect aSpecification
as argument. - The
ResultModifier
inEntitySpecificationRepositoryInterface
method arguments now is nullable. - Added new method
EntitySpecificationRepositoryInterface::getQueryBuilder()
andEntitySpecificationRepositoryTrait::getQueryBuilder()
for get Doctrine QueryBuilder with specification.
- Removed
AsSingle
result modifier. Consider usingAsSingleScalar
.
- No BC breaks
- Moved
Happyr\DoctrineSpecification\Specification
toHappyr\DoctrineSpecification\Specification\Specification
.
- Merged
getFilterInstance
andgetQueryModifierInstance
intogetSpec
. The new function should return aFilter
and/or aQueryBuilder
. We did this to make the API easier.
- You can now do
Spec::andx(new MyFilter(), new MyQueryModifier);
with bothFilter
s andQueryBuilder
s.
- It has been many changes since 0.2 and we refactored quite a lot. These are the biggest changes.
- The old
Specification
interface has been split up to two parts. We got aFilter
with will modify theSELECT
clause of the SQL query. We also got theQueryModifier
interface the modifies the query (Limit, Order, Join etc). - The new
Specification
interface extendsFilter
andQueryModifier
. - You have to update your specifications to comply with
QueryModifier
and/orExpression
- There are two new methods
getFilter
andmodify
. You don't need to override these. You may use BaseSpecfication as normal. - The
supports
function has been removed.
- The
match
method has changed to take a second optional parameter of aResultModifier
. You may modify the result by changing the hydration mode or to add a cache. We decided that it would not be a part of aSpecification
.