{"id":33974003,"url":"https://github.com/lampager/lampager-doctrine2","last_synced_at":"2025-12-13T01:37:46.789Z","repository":{"id":46111099,"uuid":"378180430","full_name":"lampager/lampager-doctrine2","owner":"lampager","description":"Rapid pagination for Doctrine 2","archived":false,"fork":false,"pushed_at":"2025-04-12T06:58:54.000Z","size":38,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-24T15:51:25.778Z","etag":null,"topics":["doctrine","fast","pagination","paginator","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lampager.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-06-18T14:43:12.000Z","updated_at":"2025-04-12T06:58:26.000Z","dependencies_parsed_at":"2025-04-12T07:29:03.142Z","dependency_job_id":"4b8fad7b-86fa-49a4-b591-8c31a7f431a3","html_url":"https://github.com/lampager/lampager-doctrine2","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/lampager/lampager-doctrine2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lampager%2Flampager-doctrine2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lampager%2Flampager-doctrine2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lampager%2Flampager-doctrine2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lampager%2Flampager-doctrine2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lampager","download_url":"https://codeload.github.com/lampager/lampager-doctrine2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lampager%2Flampager-doctrine2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27697860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-12T02:00:06.775Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["doctrine","fast","pagination","paginator","php"],"created_at":"2025-12-13T01:37:46.233Z","updated_at":"2025-12-13T01:37:46.783Z","avatar_url":"https://github.com/lampager.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg width=\"320\" alt=\"lampager-doctrine2\" src=\"https://user-images.githubusercontent.com/1351893/31839014-3e74b952-b61a-11e7-8d75-adba77a935ae.png\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/lampager/lampager-doctrine2/actions\"\u003e\u003cimg src=\"https://github.com/lampager/lampager-doctrine2/actions/workflows/test.yml/badge.svg?branch=master\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://coveralls.io/github/lampager/lampager-doctrine2?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/lampager/lampager-doctrine2/badge.svg?branch=master\" alt=\"Coverage Status\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Lampager for Doctrine 2\n\nRapid pagination for Doctrine 2\n\n## Requirements\n\n- PHP: `^8.2`\n- [doctrine/orm](https://github.com/doctrine/orm): `^2.20`\n- [lampager/lampager](https://github.com/lampager/lampager): `^0.5`\n\n\u003e [!NOTE]\n\u003e Older versions have outdated dependency requirements. If you cannot prepare the latest environment, please refer to past releases.\n\n## Installing\n\n```bash\ncomposer require lampager/lampager-doctrine2\n```\n\n## Usage\n\n### Basic\n\nInstantiate your QueryBuilder to create the Paginator.\n\n```php\n$cursor = [\n    'p.id' =\u003e 3,\n    'p.createdAt' =\u003e '2017-01-10 00:00:00',\n    'p.updatedAt' =\u003e '2017-01-20 00:00:00',\n];\n\n$result = Paginator::create(\n    $entityManager\n        -\u003egetRepository(Post::class)\n        -\u003ecreateQueryBuilder('p')\n        -\u003ewhere('p.userId = :userId')\n        -\u003esetParameter('userId', 1)\n)\n    -\u003eforward()\n    -\u003esetMaxResults(5) // Or -\u003elimit(5)\n    -\u003eorderByDesc('p.updatedAt') // ORDER BY p.updatedAt DESC, p.createdAt DESC, p.id DESC\n    -\u003eorderByDesc('p.createdAt')\n    -\u003eorderByDesc('p.id')\n    -\u003epaginate($cursor);\n```\n\nIt will run the optimized DQL.\n\n```sql\nSELECT * FROM App\\Entities\\Post p\nWHERE p.userId = 1\nAND (\n    p.updatedAt = '2017-01-20 00:00:00' AND p.createdAt = '2017-01-10 00:00:00' AND p.id \u003c= 3\n    OR\n    p.updatedAt = '2017-01-20 00:00:00' AND p.createdAt \u003c '2017-01-10 00:00:00'\n    OR\n    p.updatedAt \u003c '2017-01-20 00:00:00'\n)\nORDER BY p.updatedAt DESC, p.createdAt DESC, p.id DESC\nLIMIT 6\n```\n\nAnd you'll get\n\n```php\nobject(Lampager\\PaginationResult)#X (5) {\n  [\"records\"]=\u003e\n  array(5) {\n    [0]=\u003e\n    object(App\\Entities\\Post)#X (5) {\n      [\"id\"]=\u003e\n      int(3)\n      [\"userId\"]=\u003e\n      int(1)\n      [\"text\"]=\u003e\n      string(3) \"foo\"\n      [\"createdAt\"]=\u003e\n      object(DateTimeImmutable)#X (3) {\n        [\"date\"]=\u003e\n        string(26) \"2017-01-10 00:00:00.000000\"\n        [\"timezone_type\"]=\u003e\n        int(3)\n        [\"timezone\"]=\u003e\n        string(3) \"UTC\"\n      }\n      [\"updatedAt\"]=\u003e\n      object(DateTimeImmutable)#X (3) {\n        [\"date\"]=\u003e\n        string(26) \"2017-01-20 00:00:00.000000\"\n        [\"timezone_type\"]=\u003e\n        int(3)\n        [\"timezone\"]=\u003e\n        string(3) \"UTC\"\n      }\n    }\n    [1]=\u003e ...\n    [2]=\u003e ...\n    [3]=\u003e ...\n    [4]=\u003e ...\n  }\n  [\"hasPrevious\"]=\u003e\n  bool(false)\n  [\"previousCursor\"]=\u003e\n  NULL\n  [\"hasNext\"]=\u003e\n  bool(true)\n  [\"nextCursor\"]=\u003e\n  array(2) {\n    [\"p.updatedAt\"]=\u003e\n    object(DateTimeImmutable)#X (3) {\n      [\"date\"]=\u003e\n      string(26) \"2017-01-18 00:00:00.000000\"\n      [\"timezone_type\"]=\u003e\n      int(3)\n      [\"timezone\"]=\u003e\n      string(3) \"UTC\"\n    }\n    [\"p.createdAt\"]=\u003e\n    object(DateTimeImmutable)#X (3) {\n      [\"date\"]=\u003e\n      string(26) \"2017-01-14 00:00:00.000000\"\n      [\"timezone_type\"]=\u003e\n      int(3)\n      [\"timezone\"]=\u003e\n      string(3) \"UTC\"\n    }\n    [\"id\"]=\u003e\n    int(6)\n  }\n}\n```\n\n### Advanced: Provide mapping for aliased columns and switch to different Hydration Mode\n\n```php\n$result = Paginator::create(\n    $entityManager\n        -\u003egetRepository(Post::class)\n        -\u003ecreateQueryBuilder('p')\n        -\u003eselect('p.id as postId, p.userId as authorUserId, p.createdAt, p.updatedAt') // Aliasing\n        -\u003ewhere('p.userId = :userId')\n        -\u003esetParameter('userId', 1)\n)\n    -\u003eforward()\n    -\u003esetMaxResults(5)\n    -\u003eorderByDesc('p.updatedAt')\n    -\u003eorderByDesc('p.createdAt')\n    -\u003eorderByDesc('p.id')\n    -\u003esetMapping([\n        'p.id' =\u003e 'postId',\n        'p.userId' =\u003e 'authorUserId',\n    ]) // Mapping\n    -\u003epaginate($cursor, Query::HYDRATE_ARRAY); // Hydration Mode\n```\n\n## Questions\n\n### Seekable(Bidirectional) Query?\n\nSorry you can't use seekable mode since Doctrine DQL does not support `UNION ALL` syntax. :cry:\n\n### How about [Tuple Comparison](https://www.sql-workbench.eu/comparison/tuple_comparison.html)?\n\nDoctrine DQL does not support Tuple Comparison syntax! :cry:\n\n## Classes\n\nNote: See also [lampager/lampager](https://github.com/lampager/lampager).\n\n| Name | Type | Parent Class | Description |\n|:---|:---|:---|:---|\n| Lampager\\\\Doctrine2\\\\`Paginator` | Class | Lampager\\\\`Paginator` | Fluent factory implementation for Doctrine 2 |\n| Lampager\\\\Doctrine2\\\\`Processor` | Class | Lampager\\\\`AbstractProcessor` | Processor implementation for Doctrine 2 |\n| Lampager\\\\Doctrine2\\\\`Compiler` | Class | | Compile Lampager Query into Doctrine QueryBuilder |\n\n## API\n\nNote: See also [lampager/lampager](https://github.com/lampager/lampager).\n\n### Paginator::__construct()\u003cbr\u003ePaginator::create()\n\nCreate a new paginator instance.\n\n```php\nstatic Paginator create(\\Doctrine\\ORM\\QueryBuilder $builder): static\nPaginator::__construct(\\Doctrine\\ORM\\QueryBuilder $builder)\n```\n\n### Paginator::setMapping()\n\n```php\nPaginator::setMapping(string[] $mapping): $this\n```\n\n#### Arguments\n\n- **`(string[])`** __*$mapping*__\u003cbr\u003e An associative array that contains `$columnNameOrCursorKey =\u003e $fetchedFieldName`.\n\n### Paginator::aggregated()\n\n```php\nPaginator::aggregated(bool $aggregated = true): $this\n```\n\nDeclare that `HAVING` should be used instead of `WHERE` for aggregation.\n\n### Paginator::setMaxResults()\n\nAlias for `\\Lampager\\Paginator::limit()`.\n\n```php\nPaginator::setMaxResults(int $limit): $this\n```\n\n### Paginator::transform()\n\nTransform Lampager Query into Doctrine Query.\n\n```php\nPaginator::transform(\\Lampager\\Query $query): \\Doctrine\\ORM\\Query\n```\n\n### Paginator::build()\n\nPerform configure + transform.\n\n```php\nPaginator::build(\\Lampager\\Contracts\\Cursor|array $cursor = []): \\Doctrine\\ORM\\Query\n```\n\n### Paginator::paginate()\n\nPerform configure + transform + process.\n\n```php\nPaginator::paginate(\\Lampager\\Contracts\\Cursor|array $cursor = []): \\Lampager\\PaginationResult\n```\n\n#### Arguments\n\n- **`(mixed)`** __*$cursor*__\u003cbr\u003e An associative array that contains `$column =\u003e $value` or an object that implements `\\Lampager\\Contracts\\Cursor`. It must be **all-or-nothing**.\n    - For initial page, omit this parameter or pass empty array.\n    - For subsequent pages, pass all parameters. Partial parameters are not allowd.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flampager%2Flampager-doctrine2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flampager%2Flampager-doctrine2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flampager%2Flampager-doctrine2/lists"}