Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to doctrine/persistence 3 #860

Merged
merged 1 commit into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.3'
extensions: "curl,dom,json,xml,dom"
coverage: none

Expand Down
12 changes: 2 additions & 10 deletions .github/workflows/test-application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,16 @@ jobs:

matrix:
php-version:
- '8.0'
- '8.1'
- '8.2'
- '8.3'
dependencies: [highest]
symfony-version: ['*']
jackalope-version: ['1.*']
include:
- php-version: '8.0'
- php-version: '8.1'
dependencies: lowest
symfony-version: '*'
- php-version: '8.0'
dependencies: highest
symfony-version: '6.*'
- php-version: '8.1'
dependencies: highest
symfony-version: '5.4.*'
Expand Down Expand Up @@ -109,20 +105,16 @@ jobs:

matrix:
php-version:
- '8.0'
- '8.1'
- '8.2'
- '8.3'
dependencies: [highest]
symfony-version: ['*']
jackalope-version: ['1.*']
include:
- php-version: '8.0'
- php-version: '8.1'
dependencies: lowest
symfony-version: '*'
- php-version: '8.0'
dependencies: highest
symfony-version: '6.*'
- php-version: '8.1'
dependencies: highest
symfony-version: 5.4.*
Expand Down
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ Changelog

* Removed annotation mappings. Use attributes (or XML or YAML) instead.

* `ChildrenCollection::slice` no longer accepts a node name as offset. If you
want a slice starting from a node name, use `ChildrenCollection::sliceByChildName`
instead.

* Removed `DocumentManager::merge()`

* Removed support for short namespace aliases. ``ClassMetadataFactory::getFqcnFromAlias`` and the namespace registering
on `Configuration` are removed. `ClassMetadataFactory` methods now require their `$className` argument to be an
actual FQCN.

### New Features

* `DocumentManager::getDocumentId()` to get the id of a managed document
Expand All @@ -25,7 +35,7 @@ Changelog

* Allow using `doctrine/persistence`

* Added support for Symfony 7. Dropped support for PHP < 8.0 and Symfony < 5.4.
* Added support for Symfony 7. Dropped support for PHP < 8.1 and Symfony < 5.4.

1.x
===
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
"minimum-stability": "beta",
"prefer-stable": true,
"require": {
"php": "^8.0",
"doctrine/collections": "^1.0 || ^2.0",
"php": "^8.1",
"doctrine/collections": "^2.0",
"doctrine/common": "^2.4 || ^3.0",
"doctrine/annotations": "^1.14.3 || ^2.0",
"doctrine/data-fixtures": "^1.0",
"doctrine/event-manager": "^1.0 || ^2.0",
"doctrine/persistence": "^2.4",
"doctrine/persistence": "^3.0",
"phpcr/phpcr": "^2.1.1",
"phpcr/phpcr-implementation": "^2.1",
"phpcr/phpcr-utils": "^1.3.0 || ^2.0",
Expand Down
3 changes: 2 additions & 1 deletion docs/en/reference/association-mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -518,14 +518,15 @@ collection of related documents. Say we have a User document that
contains a collection of groups::

use Doctrine\ODM\PHPCR\Mapping\Attributes as PHPCR;
use Doctrine\ODM\PHPCR\ReferenceManyCollection;

#[PHPCR\Document]
class User
{
#[PHPCR\ReferenceMany]
private $groups;

public function getGroups()
public function getGroups(): ReferenceManyCollection
{
return $this->groups;
}
Expand Down
9 changes: 8 additions & 1 deletion docs/en/reference/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ we can traverse them::
Children can be of any class. Be careful when looping over children
to be sure they are of the expected class.

The children collection supports iterating over the children and also direct
access by index or child name. To get a segment of the collection, you have the
normal ``slice()`` that works on indexes. Additionally, the
``ChildrenCollection`` offers the ``sliceByChildName()`` method, where you can
specify the child name from which to start the slice.

Even if children are not mapped, you can use the document manager to get all
flushed children of a document::

Expand Down Expand Up @@ -367,6 +373,7 @@ Lets look at an example of document ``A`` referencing ``B``::
namespace Demo;

use Doctrine\ODM\PHPCR\Mapping\Attributes as PHPCR;
use Doctrine\ODM\PHPCR\ReferrersCollection;

#[PHPCR\Document]
class A
Expand All @@ -381,7 +388,7 @@ Lets look at an example of document ``A`` referencing ``B``::
class B
{
#[PHPCR\Referrers(referringDocument: A::class, referencedBy: 'ref')]
private $referrers;
private ReferrersCollection $referrers;
}

We can now create a reference with the following code::
Expand Down
49 changes: 26 additions & 23 deletions lib/Doctrine/ODM/PHPCR/ChildrenCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ class ChildrenCollection extends PersistentCollection
{
private object $document;

/**
* @var array|string|null
*/
private $filter;
private string|array|null $filter;

private int $fetchDepth;

Expand All @@ -34,14 +31,14 @@ class ChildrenCollection extends PersistentCollection
/**
* Creates a new persistent collection.
*
* @param object $document The parent document instance
* @param string|array $filter Filter string or array of filter string
* @param int $fetchDepth Optional fetch depth, -1 to not override
* @param string|null $locale The locale to use during the loading of this collection
* @param object $document The parent document instance
* @param array|string|null $filter Filter string for child names or array of filter strings
* @param int $fetchDepth Optional fetch depth, -1 to not override
* @param string|null $locale The locale to use during the loading of this collection
*/
public function __construct(DocumentManagerInterface $dm, object $document, $filter = null, int $fetchDepth = -1, string $locale = null)
public function __construct(DocumentManagerInterface $dm, object $document, array|string $filter = null, int $fetchDepth = -1, string $locale = null)
{
$this->dm = $dm;
parent::__construct($dm);
$this->document = $document;
$this->filter = $filter;
$this->fetchDepth = $fetchDepth;
Expand Down Expand Up @@ -159,20 +156,13 @@ public function isEmpty(): bool
return parent::isEmpty();
}

public function slice($offset, $length = null)
public function slice(int $offset, $length = null): array
{
if (!$this->isInitialized()) {
$nodeNames = $this->getOriginalNodeNames();
if (!is_numeric($offset)) {
$offset = array_search($offset, $nodeNames, true);
if (false === $offset) {
return new ArrayCollection();
}
}

$nodeNames = array_slice($nodeNames, $offset, $length);
$parentPath = $this->getNode($this->fetchDepth)->getPath();
array_walk($nodeNames, function (&$nodeName) use ($parentPath) {
array_walk($nodeNames, static function (&$nodeName) use ($parentPath) {
$nodeName = "$parentPath/$nodeName";
});

Expand All @@ -181,12 +171,25 @@ public function slice($offset, $length = null)
return $this->getChildren($childNodes);
}

if (!is_numeric($offset)) {
$nodeNames = $this->collection->getKeys();
$offset = array_search($offset, $nodeNames, true);
return parent::slice($offset, $length);
}

public function sliceByChildName(string $firstChild, $length = null): array
{
if (!$this->isInitialized()) {
$nodeNames = $this->getOriginalNodeNames();
$offset = array_search($firstChild, $nodeNames, true);
if (false === $offset) {
return new ArrayCollection();
return [];
}

return $this->slice($offset, $length);
}

$nodeNames = $this->collection->getKeys();
$offset = array_search($firstChild, $nodeNames, true);
if (false === $offset) {
return [];
}

return parent::slice($offset, $length);
Expand Down
33 changes: 0 additions & 33 deletions lib/Doctrine/ODM/PHPCR/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class Configuration
'metadataDriverImpl' => null,
'metadataCacheImpl' => null,
'documentClassMapper' => null,
'documentNamespaces' => [],
'proxyNamespace' => 'MyPHPCRProxyNS',
'autoGenerateProxyClasses' => true,
];
Expand Down Expand Up @@ -62,38 +61,6 @@ public function getWriteDoctrineMetadata(): bool
return $this->attributes['writeDoctrineMetadata'];
}

/**
* Adds a namespace with the specified alias.
*/
public function addDocumentNamespace(string $alias, string $namespace): void
{
$this->attributes['documentNamespaces'][$alias] = $namespace;
}

/**
* Resolves a registered namespace alias to the full namespace.
*
* @throws PHPCRException
*/
public function getDocumentNamespace(string $documentNamespaceAlias): string
{
if (!array_key_exists($documentNamespaceAlias, $this->attributes['documentNamespaces'])) {
throw PHPCRException::unknownDocumentNamespace($documentNamespaceAlias);
}

return trim($this->attributes['documentNamespaces'][$documentNamespaceAlias], '\\');
}

/**
* Set the document alias map.
*
* @param array<string, string> $documentNamespaces
*/
public function setDocumentNamespaces(array $documentNamespaces): void
{
$this->attributes['documentNamespaces'] = $documentNamespaces;
}

/**
* Sets the driver implementation that is used to retrieve mapping metadata.
*/
Expand Down
6 changes: 3 additions & 3 deletions lib/Doctrine/ODM/PHPCR/Decorator/DocumentManagerDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public function reorder(object $document, string $srcName, string $targetName, b
$this->wrapped->reorder($document, $srcName, $targetName, $before);
}

public function getChildren(object $document, $filter = null, int $fetchDepth = -1, string $locale = null): ChildrenCollection
public function getChildren(object $document, array|string $filter = null, int $fetchDepth = -1, string $locale = null): ChildrenCollection
{
return $this->wrapped->getChildren($document, $filter, $fetchDepth, $locale);
}
Expand All @@ -173,12 +173,12 @@ public function getReferrers(object $document, string $type = null, string $name
return $this->wrapped->getReferrers($document, $type, $name, $locale, $refClass);
}

public function flush($document = null): void
public function flush(object|array $document = null): void
{
$this->wrapped->flush($document);
}

public function getReference(string $documentName, $id)
public function getReference(string $documentName, object|string $id): mixed
{
return $this->wrapped->getReference($documentName, $id);
}
Expand Down
37 changes: 3 additions & 34 deletions lib/Doctrine/ODM/PHPCR/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -478,37 +478,6 @@ public function remove($document): void
$this->unitOfWork->scheduleRemove($document);
}

/**
* {@inheritdoc}
*
* Merge the state of the detached object into the persistence context of
* this ObjectManager and returns the managed copy of the object.
*
* This will copy all fields of $document over the fields of the managed
* document and then cascade the merge to relations as configured.
*
* The object passed to merge will *not* become associated/managed with
* this ObjectManager.
*
* @param object $document the document to merge over a persisted document
* with the same id
*
* @return object The managed document where $document has been merged
* into. This is *not* the same instance as the parameter.
*
* @throws InvalidArgumentException if $document is not an object
*/
public function merge($document): object
{
if (!is_object($document)) {
throw new InvalidArgumentException('Parameter $document needs to be an object, '.gettype($document).' given');
}

$this->errorIfClosed();

return $this->unitOfWork->merge($document);
}

/**
* {@inheritdoc}
*
Expand Down Expand Up @@ -552,7 +521,7 @@ public function refresh($document): void
$this->unitOfWork->refresh($document);
}

public function getChildren(object $document, $filter = null, int $fetchDepth = -1, string $locale = null): ChildrenCollection
public function getChildren(object $document, array|string $filter = null, int $fetchDepth = -1, string $locale = null): ChildrenCollection
{
$this->errorIfClosed();

Expand All @@ -578,7 +547,7 @@ public function getReferrers(object $document, string $type = null, string $name
* @throws InvalidArgumentException if $document is neither null nor a
* document or an array of documents
*/
public function flush($document = null): void
public function flush(object|array $document = null): void
{
if (null !== $document && !is_object($document) && !is_array($document)) {
throw new InvalidArgumentException('Parameter $document needs to be an object, '.gettype($document).' given');
Expand All @@ -588,7 +557,7 @@ public function flush($document = null): void
$this->unitOfWork->commit($document);
}

public function getReference(string $documentName, $id)
public function getReference(string $documentName, object|string $id): mixed
{
return $this->unitOfWork->getOrCreateProxy($id, $documentName);
}
Expand Down
Loading