{"id":17226903,"url":"https://github.com/dantleech/doctrine-cr","last_synced_at":"2026-01-30T13:03:38.340Z","repository":{"id":66290671,"uuid":"57901706","full_name":"dantleech/doctrine-cr","owner":"dantleech","description":"Doctrine Content Repository","archived":false,"fork":false,"pushed_at":"2016-05-14T16:41:27.000Z","size":68,"stargazers_count":1,"open_issues_count":9,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-11T16:50:49.266Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/dantleech.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}},"created_at":"2016-05-02T15:55:24.000Z","updated_at":"2016-05-10T11:16:26.000Z","dependencies_parsed_at":"2023-02-22T13:00:37.024Z","dependency_job_id":null,"html_url":"https://github.com/dantleech/doctrine-cr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dantleech/doctrine-cr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantleech%2Fdoctrine-cr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantleech%2Fdoctrine-cr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantleech%2Fdoctrine-cr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantleech%2Fdoctrine-cr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dantleech","download_url":"https://codeload.github.com/dantleech/doctrine-cr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantleech%2Fdoctrine-cr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28913313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T12:13:43.263Z","status":"ssl_error","status_checked_at":"2026-01-30T12:13:22.389Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-10-15T04:17:31.339Z","updated_at":"2026-01-30T13:03:38.321Z","avatar_url":"https://github.com/dantleech.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Doctrine Content Repository\n===========================\n\n[![Build Status](https://travis-ci.org/dantleech/doctrine-content-repository.svg?branch=master)](https://travis-ci.org/dantleech/doctrine-content-repository)\n[![StyleCI](https://styleci.io/repos/\u003crepo-id\u003e/shield)](https://styleci.io/repos/\u003crepo-id\u003e)\n\nWhat is this?\n-------------\n\nThis allows you to organize Doctrine Entities in a tree hierarchy and identify\nthem with a UUID (universally unique identifier), for example:\n\n```bash\n/\n    page-1/          [Acme\\Entity\\Page]\n    page-2/          [Acme\\Entity\\Page]\n        block-1/     [Acme\\Entity\\Block]\n        block-2/     [Acme\\Entity\\Block]\n        comment-1/   [Acme\\Entity\\Comment]\n    foo/             [Acme\\Entity\\Foobar]\n```\n\nIt is similar in concept to the\n[PHPCR-ODM](https://github.com/doctrine/phpcr-odm) but uses the standard\nDoctrine ORM.\n\nYou can access entities by path:\n\n```php\n$page1 = $entityManager-\u003efind(null, '/page-1');\n$comment = $entityManager-\u003efind(null, '/page-1/comment1');\n```\n\nYou can also access by UUID:\n\n```php\n$page1 = $entityManager-\u003efind(null, '6cb68641-f995-43d4-b698-5d61ae78fa90');\n```\n\nand traverse the tree:\n\n```\n$page1 = $entityManager-\u003efind(null, '/page-1');\n\nforeach ($page1-\u003egetChildren() as $child) {\n    $parent = $child-\u003egetParent();\n}\n```\n\nNote that the above methods are not part of an interface, but are using mapped\nproperties - the DoctrineCR, like Doctrine itself, does not impose any\nrestrictions upon your domain model.\n\nAnother tree extension?\n-----------------------\n\nThis extension is different in that enables each node to be of a different\nobject class and allows nodes to be referenced by a single UUID regardless of\nwhich table they reside in.\n\nConfiguration\n-------------\n\n```php\nuse Metadata\\MetadataFactory;\nuse DTL\\DoctrineCR\\Metadata\\Driver\\XmlDriver;\nuse DTL\\DoctrineCR\\Metadata\\Locator\\DoctrineLocator;\nuse DTL\\DoctrineCR\\Path\\Storage\\DbalStorage;\nuse DTL\\DoctrineCR\\Path\\PathManager;\n\n$metadataFactory = new MetadataFactory(\n    new XmlDriver(\n        new DoctrineLocator($container['orm.file_locator'])\n    )\n);\n        };\n\n$pathStorage =  new DbalStorage($container['dbal.connection']);\n$pathManager = new PathManager($pathStorage);\n\n$dcrSubscriber =  new DcrSubscriber(\n    $pathManager,\n    $metadataFactory,\n    $ormEntityManager, // should do a minor refactor to remove this dep\n);\n\n$ormEntityManager-\u003egetEventManager()-\u003eaddEventSubscriber($dcrSubscriber);\n\n// create our new hierarchically aware entity manager\n$wrappedEntityManager = new ObjectManager($pathManager, $ormEntityManager);\n\n$wrappedEntityManager-\u003efind(null, '/foo/bar');\n$wrappedEntityManager-\u003emove('/foobar', '/barfoo');\n$wrappedEntityManager-\u003epersist($document);\n$wrappedEntityManager-\u003eremove('/foobar');\n// etc.\n```\n\nHow does it work?\n-----------------\n\nBasically we store all the paths and UUIDs in a lookup table. Mapping is\napplied to your domain models (Entities) indicating which fields should be\nmapped with the Doctrine CR fields such as \"children\", \"parent\", \"path\",\n\"uuid\", etc.  (UUID is mandatory).\n\nDoctrineCR then includes an event subscriber which will listen to load and\npersist events sent from the standard Doctrine `EntityManager` in addition to\ndecorating that same `EventManager` - adding the possiblity to lookup any\n(managed) Entity by UUID and perform tree specific operations such as moving.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdantleech%2Fdoctrine-cr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdantleech%2Fdoctrine-cr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdantleech%2Fdoctrine-cr/lists"}