Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Specification Laravel Package

happyr/doctrine-specification

Reusable Doctrine query Specifications for PHP. Replace messy repositories and huge QueryBuilder methods with small, composable, testable spec classes. Reduce duplication, avoid methods with many arguments, and extend queries cleanly as your app grows.

View on GitHub
Deep Wiki
Context7
v2.0.2

Changelog (since 2.0.1...2.0.2)

v2.0.1

Changelog (since 2.0.0...2.0.1)

  • bug #303 Allow always use a unique DQL alias in DQLContextResolver (@peter-gribanov)
  • bug #301 Fix problems with PHP-CS-Fixer (@peter-gribanov)
  • bug #298 Prefer to use default_repository_class instead of repository_factory (@peter-gribanov)
  • bug #296 Not use BaseSpecification::getNestedContext() method (@peter-gribanov)
v2.0.0

Changelog (since 1.1.3...2.0.0)

Upgrade from 1.1 to 2.0

  • The AbstractJoin::getJoinType() method was removed. Use AbstractJoin::modifyJoin() method inside.

  • The Comparison class marked as abstract.

  • The LogicX class marked as abstract.

  • The protected properties in Comparison class marked as private.

  • The protected properties in In class marked as private.

  • The protected properties in GroupBy class marked as private.

  • The protected properties in OrderBy class marked as private.

  • The protected properties in Limit class marked as private.

  • The protected properties in Offset class marked as private.

  • The Bitwise operands was removed.

  • The Happyr\DoctrineSpecification\Specification\Having class was removed, use Happyr\DoctrineSpecification\Query\Having instead.

  • The Happyr\DoctrineSpecification\EntitySpecificationRepository class was removed, use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository instead.

  • The Happyr\DoctrineSpecification\EntitySpecificationRepositoryInterface class was removed, use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface instead.

  • The Happyr\DoctrineSpecification\EntitySpecificationRepositoryTrait class was removed, use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryTrait instead.

  • The Happyr\DoctrineSpecification\RepositoryFactory class was removed, use Happyr\DoctrineSpecification\Repository\RepositoryFactory instead.

  • The Happyr\DoctrineSpecification\BaseSpecification class was removed, use Happyr\DoctrineSpecification\Specification\BaseSpecification instead.

  • Removes the ability to use array as argument for the PlatformFunction 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 the Select 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 the AddSelect 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 as abstract.

  • The InvalidArgumentException class marked as final.

  • The LogicException class marked as final.

  • The NonUniqueResultException class marked as final.

  • The NoResultException class marked as final.

  • The UnexpectedResultException class marked as abstract.

  • 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 as final.

  • The DBALTypesResolver class marked as final.

  • The ValueConverter class marked as final.

  • 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('contestant.user.state', State::active()->value()),
        Spec::eq('contestant.contest.enabled', true)
    );
    
  • 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](https://github.com/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](https://github.com/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](https://github.com/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](https://github.com/return) Filter|QueryModifier
         */
        protected function getSpec()
        {
            return new ContestantPublished('contestant');
        }
    }
    
    final class ContestantPublished extends BaseSpecification
    {
        /**
         * [@return](https://github.com/return) Filter|QueryModifier
         */
        protected function getSpec()
        {
            return Spec::andX(
                new JoinedContestant(),
                new ContestantApproved()
            );
        }
    }
    
    final class ContestantApproved extends BaseSpecification implements Satisfiable
    {
        /**
         * [@return](https://github.com/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 extends Satisfiable interface.

  • The BaseSpecification class implement Satisfiable interface.

  • The Happyr\DoctrineSpecification\Operand\CountDistinct class was removed, use Happyr\DoctrineSpecification\Operand\PlatformFunction\Count instead.

  • The Spec::countDistinct() method was removed, use Spec::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 to Spec::fun() is not longer supported, use Spec::COUNT() instead.

  • The COUNT function as argument to Happyr\DoctrineSpecification\Operand\PlatformFunction is not longer supported, use Happyr\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 to Spec::fun() is not longer supported, use Spec::AVG() instead.

  • The AVG function as argument to Happyr\DoctrineSpecification\Operand\PlatformFunction is not longer supported, use Happyr\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 to Spec::fun() is not longer supported, use Spec::MIN() instead.

  • The MIN function as argument to Happyr\DoctrineSpecification\Operand\PlatformFunction is not longer supported, use Happyr\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 to Spec::fun() is not longer supported, use Spec::MAX() instead.

  • The MAX function as argument to Happyr\DoctrineSpecification\Operand\PlatformFunction is not longer supported, use Happyr\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 to Spec::fun() is not longer supported, use Spec::SUM() instead.

  • The SUM function as argument to Happyr\DoctrineSpecification\Operand\PlatformFunction is not longer supported, use Happyr\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() and Spec::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'))
    );
    
v1.1.3

Changelog (since 1.1.2...1.1.3)

v1.1.2

Changelog (since 1.1.1...1.1.2)

  • bug #241 MemberOfX::getFilter() and LogicX::getFilter() should return a string (@peter-gribanov)
  • bug #243 Disable no_superfluous_phpdoc_tags_symfony in Style CI config (@peter-gribanov)
  • bug #242 Remove short_array_syntax CS fixer (@peter-gribanov)
v1.1.1

Changelog (since 1.1.0...1.1.1)

  • bug #239 Convert all arguments to operands (@peter-gribanov)
  • bug #240 Remove build badge of SensioLabsInsight linked to different project (@peter-gribanov)
v1.1.0

Changelog (since 1.0.6...1.1.0)

v1.0.6

Changelog (since 1.0.5...1.0.6)

  • bug #234 Empty filter (@peter-gribanov)
  • feature #231 Add a note on the repository trait (@kix)
v1.0.5

Changelog (since 1.0.4...1.0.5)

  • feature #209 Add Distinct query modifier and CountDistinct operand (@peter-gribanov)
v1.0.4

Changelog (since 1.0.3...1.0.4)

0.2.0

Changelog (since 0.1.0...0.2.0)

  • bug #50 run down minor docblock fixes and other cs (@cordoval)
  • feature #49 add alias branch (@cordoval)
  • bug #48 fix typos only on documentation and README.md (@cordoval)
  • bug #31 Added contributing file (@Nyholm)
  • bug #46 Pass hydration mode to getResult method (#44). (@timroberson)
  • feature #34 Renaming namespace (@Nyholm)
  • bug #36 Run Coverage only on Travis (@cakper)
  • bug #32 Cleanup (@Nyholm)
  • feature #29 A LIKE specification (@AP-Hunt)
  • bug #27 Add missing join specification (@cakper)
  • bug #28 Repository specification (@cakper)
  • feature #25 Added OrderBy and Limit. Fixed #24 (@Nyholm)
  • feature #26 Make sure that you may specify a default repository class (@Nyholm)
  • bug #21 Avoid accessing method on a null variable (@Nyholm)
  • feature #19 Use phpspec's coverage (@Nyholm)
  • bug #18 Removed unused operator (@Nyholm)
  • bug #17 Fixed #16 (@Nyholm)
  • feature #11 Added more spec tests (@Nyholm)
  • feature #12 Code coverage (@Nyholm)
  • feature #10 Added In spec. (@Nyholm)
  • feature #7 Refactor comparison expression (@cakper)
  • feature #6 Refactor Logic Spec's (@cakper)
  • bug #3 Minor fixes and follow up on Kacper's refactoring. (@Nyholm)
  • feature #2 Idea of refactoring (@cakper)
0.3.0

Changelog (since 0.2.0...0.3.0)

  • bug #76 Scrutinizer fixes (@Nyholm)
  • feature #74 Renamed getWrapped* functions (@Nyholm)
  • feature #75 Rename Expression to Filter (@cakper)
  • bug #73 Renamed Modifiers to QueryModifier and ResultModifier #59 (@Nyholm)
  • feature #61 Make sure logicX takes an Expression (@Nyholm)
  • bug #60 IsNull and IsNotNull should not have a value (@Nyholm)
  • bug #72 plug minor fixes (@cordoval)
  • bug #70 move to psr4, phpspec is complaining (@cordoval)
  • bug #67 minor fix (@cordoval)
  • bug #63 update name of ModifierCollection (@cordoval)
  • feature #56 Refactoring (@cakper)
0.3.1

Changelog (since 0.3.0...0.3.1)

0.4.0

Changelog (since 0.3.1...0.4.0)

  • feature #95 Added Cache ResultModifier (@cakper, @Nyholm)
  • feature #93 The modify function should not return anything (@Nyholm)
  • bug #88 Updated docs to reflect the lastest version of the code (@Nyholm)
  • feature #94 Added factory methods (@Nyholm)
  • bug #96 Better to check it modifier is null. (@Nyholm)
  • feature #91 Added AsSingle ResultModifier (@Nyholm)
  • bug #98 Updated doc. The value parameter should be "mixed" not "string" (@Nyholm)
  • feature #97 Removed coveralls and updated travis conf (@Nyholm)
  • feature #89 Added Offset Query Spec (@drewclauson)
  • feature #86 Make the api simpler (@Nyholm)
  • feature #87 Added Trait for EntitySpecificationRepository (@Nyholm)
  • feature #69 Added a first attempt to document changes (@Nyholm)
0.5.0

Changelog (since 0.4.0...0.5.0)

  • bug #101 Moved Specification interface to Specification folder (@Nyholm)
  • bug #107 Removed abstract signature to be compliant with doctrine/orm 2.5 (@Nyholm)
  • feature #106 added notIn filter (@drewclauson)
  • feature #103 Created AbstractJoin and added innerJoin (@Nyholm)
  • bug #100 Check for QueryModifier instead of Specification (@Nyholm)
  • feature #102 Add Left Join Spec (@drewclauson)
  • feature #99 Making the API more fluent (@Nyholm)
0.6.0

Changelog (since 0.5.0...0.6.0)

  • #108 Added prepare function to return a Query (@Nyholm)
  • Added GroupBy and Having (@Nyholm)
0.6.1

Changelog (since 0.6.0...0.6.1)

  • bug #121 Fixed issue #120 (@Nyholm)
  • feature #119 Filter: INSTANCE OF (@Strontium-90)
  • feature #118 Allow repository math Filter and QueryModifier. (@Strontium-90)
  • bug #114 Make EntitySpecificationRepository accept specs not creating a filter (@kgilden)
  • feature #113 Fixed Spec::asSingle, matchSingleResult, matchOneOrNullResult (@adamquaile)
  • bug #112 Make sure we return an instance of AndX/OrX (@Nyholm)
  • feature #109 Added GroupBy and Having (@Nyholm)
0.6.2

Changelog (since 0.6.1...0.6.2)

  • We need to consider BC, dont remove AsSingle (@Nyholm)
0.7.0

Changelog (since 0.6.2..0.7.0)

0.7.1

Changelog (since 0.7.0..0.7.1)

  • feature #124 Allow multiple order and group by (@Nyholm)
  • feature #123 Specification Interface for Happyr/Doctrine-Specification (@thundo)
v1.0.3

Changelog (since 1.0.2...1.0.3)

v1.0.2

Changelog (since 1.0.1...1.0.2)

v1.0.1

Changelog (since 1.0.0...1.0.1)

  • feature #193 Allow use a Field operand in IndexBy spec (@peter-gribanov)
  • feature #192 Support for indexing results by arbitrary field (@edefimov)
  • bug #191 Update branch alias (@XWB)
  • bug #190 Correct MemberOfX spec (@peter-gribanov)
  • bug #189 Сorrect get function arguments in Spec::fun() (@peter-gribanov)
  • feature #186 Create MemberOfX filter (@peter-gribanov)
  • feature #185 Allow use aliases in GroupBy and OrderBy specs (@peter-gribanov)
v1.0.0

Changelog (since 0.8.1...1.0.0)

  • feature #180 Use ::class const for optimization (@peter-gribanov)
  • bug #179 Not catch never throw exception (@peter-gribanov)
  • feature #177 Add scalar shortcut methods to repository (@XWB)
  • feature #175 Implementation of Function operand (@peter-gribanov)
  • feature #174 Implementation of Bitwise operands (@peter-gribanov)
  • feature #173 Implementation of Arithmetic operands (@peter-gribanov)
  • feature #172 Implementation of Selection concept (@peter-gribanov)
  • feature #171 Base implementation of Operands concept (@peter-gribanov)
  • feature #166 Add feature for iterate the results match with a Specification (@peter-gribanov)

[PR] #184

v0.8.1

Changelog (since 0.8.0...0.8.1)

  • feature #176 Add scalar result modifier (@XWB)
  • feature #170 Test with PHP 7.2 and 7.3 (@peter-gribanov)
v0.8.0

Changelog (since 0.7.2...0.8.0)

[PR] #168

0.7.2

Changelog (since 0.7.1...0.7.2)

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme