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

EZP-31650: Added Criterions handling for search in trash #80

Merged
merged 2 commits into from
Jun 29, 2020

Conversation

michal-myszka
Copy link
Contributor

@michal-myszka michal-myszka commented Jun 23, 2020

Question Answer
JIRA issue EZP-31650
Type feature
Target eZ Platform version v3.1
BC breaks no
Tests pass yes
Doc needed no

Added handling criterias for trash list

Checklist:

  • PR description is updated.
  • Old tests update
  • Tests are implemented.
  • Added code follows Coding Standards (use $ composer fix-cs).
  • PR is ready for a review.

@michal-myszka michal-myszka self-assigned this Jun 23, 2020
@michal-myszka michal-myszka changed the title WIP: EZP-31650 - Search in trash EZP-31650: Search in trash Jun 23, 2020
@michal-myszka michal-myszka changed the title EZP-31650: Search in trash EZP-31650: Added Criterions handling for search in trash Jun 23, 2020
@michal-myszka michal-myszka force-pushed the EZP-31650-search-in-trash branch from f147337 to eb276ba Compare June 23, 2020 10:54
@michal-myszka michal-myszka marked this pull request as ready for review June 23, 2020 10:54
@michal-myszka michal-myszka force-pushed the EZP-31650-search-in-trash branch from eb276ba to eb1e35c Compare June 23, 2020 11:02
@michal-myszka michal-myszka requested review from alongosz, adamwojs, ViniTou and a team June 23, 2020 11:02
@adamwojs
Copy link
Member

Would be great to have some integration tests 😉

@michal-myszka michal-myszka force-pushed the EZP-31650-search-in-trash branch from 2358978 to ea66cb8 Compare June 26, 2020 10:23
Copy link
Member

@alongosz alongosz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several architecture-related, but naming-wise and DX issues:

  1. While PMs define this feature as "Search in trash", conceptually this is not LSE, nor any search engine. It's very misleading to declare it like that and use Search* namespace for Legacy Storage implementations (e.g. eZ/Publish/Core/Search/Legacy/Content/Common/Gateway/SortClauseHandler/Trash/*). The parts, e.g. Criteria, re-used from LSE could stay as-is. Not happy about mixing things, but better to keep it DRY probably.

  2. The set of supported Criteria and Sort Clauses is limited. It's going to be very difficult for Developers to understand which ones are supported. It's fine to refer them do the doc as long as they know they should. However since findTrashItems accepts Query, it gives an impression that all of them are supported. Not sure if anything can be done for the method signature due to BC[1], but each SortClause and Criterion should implement marker interface to indicate that it supports trash filtering (I'm really not fine with calling it search). E.g.: eZ\Publish\SPI\Repository\Values\Trash\Criterion and eZ\Publish\SPI\Repository\Values\Trash\SortClause respectively - the similar concept exists for EZP-31569: Implemented Repository filtering #54

  3. ezpublish from new container definitions/parameters needs to disappear regardless of 1. & 2.


[1] Maybe PHPDoc improvements only? Or maybe, since those criteria never worked anyway, it would be fine to make signature more strict? Or maybe to be implemented as a separate method.

* @param string $operator One of the Operator constants
* @param mixed $value The match value, either as an array of as a single value, depending on the operator
*/
public function __construct(string $target, string $operator, $value)
{
if ($target != self::MODIFIED && $target != self::CREATED) {
if (!in_array($target, [self::MODIFIED, self::CREATED, self::TRASHED])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you extract [self::MODIFIED, self::CREATED, self::TRASHED] as a private constant? e.g.:

Suggested change
if (!in_array($target, [self::MODIFIED, self::CREATED, self::TRASHED])) {
if (!in_array($target, self::TARGETS)) {

/**
* Creates a new DateMetadata criterion on $metadata.
*
* @throws \InvalidArgumentException If target is unknown
*
* @param string $target One of DateMetadata::CREATED or DateMetadata::MODIFIED
* @param string $target One of DateMetadata::CREATED, DateMetadata::MODIFIED or DateMetadata::TRASHED (works only with LSE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true, LSE does not cover searching in Trash at all as no Search engine does. Conceptually search in trash is not a part of LSE.
What could be safer is:

Suggested change
* @param string $target One of DateMetadata::CREATED, DateMetadata::MODIFIED or DateMetadata::TRASHED (works only with LSE)
* @param string $target One of DateMetadata::CREATED, DateMetadata::MODIFIED or DateMetadata::TRASHED (applies to TrashService::findTrashItems only).
*
* @see \eZ\Publish\API\Repository\TrashService::findTrashItems

@@ -36,6 +36,10 @@ parameters:
- "tab_search_normalize"

services:
ezplatform.search.legacy.gateway.criteria_converter.trash:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, this is not search in terms of our domain definition, though indeed feature is called search in trash (which should be trash filtering, but what can I do...).

Suggested change
ezplatform.search.legacy.gateway.criteria_converter.trash:
ezplatform.trash.search.legacy.gateway.criteria_converter:

@@ -86,6 +90,7 @@ services:
tags:
- {name: ezpublish.search.legacy.gateway.criterion_handler.content}
- {name: ezpublish.search.legacy.gateway.criterion_handler.location}
- {name: ezplatform.search.legacy.gateway.criterion_handler.trash}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- {name: ezplatform.search.legacy.gateway.criterion_handler.trash}
- {name: ezplatform.trash.search.legacy.gateway.criterion_handler.trash}

@@ -4,6 +4,10 @@ services:
arguments:
$connection: '@ezpublish.persistence.connection'

ezpublish.search.legacy.gateway.sort_clause_converter.trash:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ezpublish.search.legacy.gateway.sort_clause_converter.trash:
ezplatform.trash.search.legacy.gateway.sort_clause_converter:

array $languageSettings
): void {
$query->innerJoin(
'c', ContentTypeGateway::CONTENT_TYPE_TABLE, 'cc', 'c.contentclass_id = cc.id'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why cc for Content Type? ct, content_type, type I would understand

Suggested change
'c', ContentTypeGateway::CONTENT_TYPE_TABLE, 'cc', 'c.contentclass_id = cc.id'
'c', ContentTypeGateway::CONTENT_TYPE_TABLE, 'ct', 'c.contentclass_id = ct.id'

@@ -25,6 +25,8 @@
*/
final class DoctrineDatabase extends Gateway
{
public const USER_TABLE = 'ezuser';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those should be defined on the Gateway, not implementation because Gateway itself applies to Legacy Storage only. Past implementations are a bit inconsistent, but the most recent one, regarding switch from eZc Database Handler to Doctrine shows the correct path.

'location_path' => 'path_string',
'trashed' => 'trashed',
];
public const TRASH_TABLE = 'ezcontentobject_trash';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as before - belongs to Gateway.

@@ -669,7 +669,7 @@ public function testFindTrashItems()
$query = new Query();
$query->filter = new Criterion\LogicalAnd(
[
new Criterion\Field('title', Criterion\Operator::LIKE, '*'),
new Criterion\ContentTypeId(1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are more Criteria supported by Trash filtering, but the coverage is missing.

@michal-myszka
Copy link
Contributor Author

There are several architecture-related, but naming-wise and DX issues:

While PMs define this feature as "Search in trash", conceptually this is not LSE, nor any search engine. It's very misleading to declare it like that and use Search* namespace for Legacy Storage implementations (e.g. eZ/Publish/Core/Search/Legacy/Content/Common/Gateway/SortClauseHandler/Trash/*). The parts, e.g. Criteria, re-used from LSE could stay as-is. Not happy about mixing things, but better to keep it DRY probably.

The set of supported Criteria and Sort Clauses is limited. It's going to be very difficult for Developers to understand which ones are supported. It's fine to refer them do the doc as long as they know they should. However since findTrashItems accepts Query, it gives an impression that all of them are supported. Not sure if anything can be done for the method signature due to BC[1], but each SortClause and Criterion should implement marker interface to indicate that it supports trash filtering (I'm really not fine with calling it search). E.g.: eZ\Publish\SPI\Repository\Values\Trash\Criterion and eZ\Publish\SPI\Repository\Values\Trash\SortClause respectively - the similar concept exists for #54

ezpublish from new container definitions/parameters needs to disappear regardless of 1. & 2.

Yes, that's right, this is not strict "search" feature in our project mind. I tried to avoid the situations you are writing about, I even made two conceptual approaches, but finally without BC breaks they proved impossible. Let's talk on Zoom first.

@alongosz
Copy link
Member

Note: agreed on MVP during internal sync.

Copy link
Member

@alongosz alongosz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1
Some minor nitpicks:

@@ -1121,4 +1283,41 @@ private function getTrashItemDouble(int $trashId, int $contentId = 44, int $pare
'contentInfo' => new ContentInfo(['id' => $contentId]),
]);
}

private function trashDifferentContents(): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plural of a content is content Items ;)

Suggested change
private function trashDifferentContents(): void
private function trashDifferentContentItems(): void

use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\SortClauseHandler;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;

class UserName extends SortClauseHandler
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: all handlers should be final and @internal (I mean new ones).

Comment on lines +83 to +84
default:
return 'c.' . Criterion\DateMetadata::PUBLISHED;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda risky. What if Developer passes something completely different?
We tend to do throw new InvalidArgumentException or RuntimeException on default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's for save old logic (before refactor)


$ascQuery = new Query();
foreach ($sortClausesClasses as $sortClauseClass) {
$ascQuery->sortClauses[] = new $sortClauseClass(Query::SORT_ASC);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass \eZ\Publish\API\Repository\Values\Content\Query\SortClause instance instead of dynamically create instances from class string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's intended because I need to pass different arguments to sortClause instance

$ascResultsIds[] = $result->contentInfo->id;
}

$this->assertGreaterThanOrEqual(2, count($ascResultsIds));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert is not guarantee that trash find results are in correct order. 

$this->assertEquals([1, 2, 3], $ascResultsIds);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert doesn't check the order, but this is for requiring 2 items in result. Checking sort is in the next steps below

krsort($descResultsIds);
$descResultsIds = array_values($descResultsIds);

$this->assertSame($descResultsIds, $ascResultsIds);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert will fail in case of more the 1 page of results so make sure this assumption is fulfilled by specifying limit on query.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is expecting count = 2, and the limit is 25 (as default), but I can also add the fit query limit.

$query
->addSelect(
sprintf(
'ct.identifier AS %s',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation does not fit to class name: results will be sorted by content type identifier instead of content type name.

)
);

return (array)$column;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (array)$column;
return [$column];

use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\SortClauseHandler;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;

class UserName extends SortClauseHandler
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO `UserLogin` is better naming choice for this sort clause

Michał Myszka added 2 commits June 29, 2020 12:44
Delete unnecessary criterion converter

Handled Criterion on count trash items

Added sort clauses handling in trash search

Fixed tests

After CR

After CR

Fixes

Added tests for search in trash filtering

Added tests for search in trash sorting

Improved tests

CR suggestions

CR suggestions

CR suggestions
Copy link

@tomaszszopinski tomaszszopinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA approved on eZPlatform ee 3.1dev with diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

5 participants