-
Notifications
You must be signed in to change notification settings - Fork 16
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
Enhanced location handling (EZP-32182) #90
Conversation
2243a88
to
6342d46
Compare
6342d46
to
5f919be
Compare
return array_map( | ||
function ($contentId) use ($contentItems) { | ||
return $contentItems[array_search($contentId, array_column($contentItems, 'id'))]; | ||
}, | ||
$destinationContentIds | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment whole expression could be reduced to return $contentItems
Did you mean
return array_map(
function (Content $content): Item {
return $this->itemFactory->fromContent($content);
},
$contentItems
);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I recall correctly (I wrote that a while ago) the goal was to return the items in the order they are defined in the relation field. And if I recall correctly (again), the search result doesn't respect the order the id are passed in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the search result doesn't respect the order the id are passed in.
True, especially in multi node setup.
private function containsRootPath(array $path, array $rootPath): bool | ||
{ | ||
return array_slice($path, 0, count($rootPath)) === $rootPath; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have Path VO into PAPI to avoid re-implementing path operation at-hoc...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine by me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could even go further, and have an official API for getting the URL alias for a location for a given siteaccess.
src/GraphQL/Resolver/LocationGuesser/TreeRootLocationFilter.php
Outdated
Show resolved
Hide resolved
src/GraphQL/Value/Item.php
Outdated
if ($location === null && $content === null) { | ||
// @todo find a better exception | ||
throw new \Exception('Constructing an item requires one of location or content'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... or mark constructor as private/protected and force class instantiation using named constructors:
public static fromContent(LocationGuesser $locationGuesser, Content $content): self;
public static fromLocation(LocationGuesser $locationGuesser, Content $location): self;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why not. Do we agree that I still keep the ItemFactory
, but it uses the static methods instead of the constructor ?
f349e72
to
eebf539
Compare
We should be green. There are still todo items above, but they may also be taken care of in a follow-up. I'll work on them anyway, but if we could consider this PR for merging, it would be nice. |
6eb2633
to
0102724
Compare
To reviewers, I'd like to merge this as soon as possible and iterate further. There are remaining tasks, but it's a large refactoring, and doing it all in one pull-requests will make it difficult. |
0f5b618
to
5892ade
Compare
Two ItemFactory instances are exposed, depending on the need: - $siteItemFactory: locations and aliases are within the current site root only - $relatedItemFactory: locations and aliases can be in other public siteaccesses / site roots
53f2e4e
to
085a6dd
Compare
Summary of the plan for this:
If the plan doesn't work, please let me know. But releasing a BC break of that package in the LTS doesn't sound correct. |
A major refactoring of the GraphQL API that bumps it to v3.0.
*Content
as well as the wholeDomainContent
terminology is replaced with a concept ofItem
, where anItem
is the combination of a content and a location. Example: "ArticleContent" becomes "ArticleItem".The goal is to add a concept of "current location" so that from any retrieved item, we can get a location (and its URL). It uses a Location Guesser API that given a Content item will guess a Location for it. It allows to keep the API content centric while allowing to work with locations in a smart way.
Features
Illustration of the changes below:
site1
andsite2
site1
.folderBlog
135 has two locations, one insite1
, one insite2
.folderBlog.posts
is a query field that returns the blog posts that are children of the blog's current location.blog.relatedBlogPosts
contains relations to both both thesite1
andsite2
subtreesResult:
site1
(no/site-1
prefix)site2
is an absolute one, since it is on another siteaccessTree root support
Tree root settings are now taken into account automatically:
Item objects
When working with content, and Item value object is used. It references either a location or a content, and guesses the other:
A generic resource,
item
, with the same arguments thanarticle
orfolder
, is also available. It returns the item object, and its type can be tested in the query. It is meant to limit the usage of the_repository { location
resource.Location guesser API
Given a Content item, the LocationGuesser will return the "best" location for it. It uses a set of filters on the content item's locations:
More of those filters could be added:
Siteaccess guesser API
A specific ItemFactory,
$relatedItemFactory
, will accept locations from other siteaccesses. When an URL for such an item is requested, it will be generated for the Item's siteaccess, using an absolute URL if necessary.Other minor changes
id
argument for loading an item is replaced withcontentId
.locationRemoteId
andurlAlias
have also been added as argumentsTODO
createArticleContent
->createArticleItem
etc)Item { _locations }
so that it returns the locations that are valid for the itemItem { _locations { _url } }
item
resource that returns an item independently of its type (use-case: search for any item with an URL alias)