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-28055: As a v2 Editor I want to search for content items by entering a search keyword #33

Merged

Conversation

mikadamczyk
Copy link
Contributor

https://jira.ez.no/browse/EZP-28055

This PR implements a user search for content item in the content repository. He can initiate a search by entering a search keyword and the application will retrieve a list of all the content items that have the same keyword in any of their searchable fields. This search feature use a PHP API along with a dedicated Symfony controller. The results is sorted by modified. As paginator pagerfanta/pagerfanta was used.

@mikadamczyk mikadamczyk force-pushed the ezp-28055-search-for-content branch from 46daeee to 0f0bfcb Compare October 30, 2017 15:59
@ezsystems ezsystems deleted a comment from ezrobot Oct 30, 2017
*/
public function getBlockPrefix()
{
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you set it to null? Block prefix is crucial for form theming. We do not have any strong convention but I started using underscored class name with type replaced with form word: simple_search_form.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used it because I want simple parameters in the URL. I don't think so the block prefix is crucial for form theming, rather id or class added in twig template. I think form builder is not a good place for styling. What do you think?

Copy link
Contributor

@webhdx webhdx Oct 31, 2017

Choose a reason for hiding this comment

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

Hmm, I'm not sure if you understand my point. All forms should have unique block name, this allows you to do overrides in twig:

{% block simple_search_form_widget %}
    {% set attr = attr|merge({'class': 'custom-class'}) %}
    {{ block('form_widget') }}
{% endblock %}

Which is what we do in order to separate styling information (like class HTML attribute) from PHP code.

*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->setMethod('GET')
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if we should force method in form builder. This kills reusability. You can always change this on form creation.

{
$resolver->setDefaults([
'data_class' => SimpleSearchData::class,
'csrf_protection' => false,
Copy link
Contributor

Choose a reason for hiding this comment

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

See my comment above.

@@ -0,0 +1,9 @@
{{ form_start(form) }}
<div class="input-group">
{{ form_widget(form.query, {'attr': {'style': 'width: 200px', 'class': 'form-control'} }) }}
Copy link
Contributor

Choose a reason for hiding this comment

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

We have to move inline style to CSS. @dew326 can propose you best solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inline style is not needed anymore

{% block pageTitle %}{% endblock %}

{% block content %}
<div id="react-udw"></div>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should UDW be a part of search page?

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 something we should change I think. We load UDW module in every page (in layout.html.twig) but the container is added in some subpage. I think we should move this container to the layout.html.twig and remove it from every subpage.

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 good point @dew326 . We should make a follow-up task on this UDW load.

$pagerfanta->setMaxPerPage($limit);
$pagerfanta->setCurrentPage($page);

$urlGenerator = $this->get('router');
Copy link
Contributor

Choose a reason for hiding this comment

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

Please inject in the constructor. We tend to not use container directly in the controllers.


$pagination = (new TwitterBootstrap4View())->render($pagerfanta, $routeGenerator);

return $this->render('@EzPlatformAdminUi/admin/search/list.html.twig', [
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't we share the same template file for search? By looking at the twig files I can see there is a lot of code duplication going on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes we can, but the grid template will be added, so I prefer separate templates to avoid mixing. What do you think?


{% block javascripts %}
{% javascripts
'bundles/ezplatformadminui/js/scripts/udw/browse.js' %}
Copy link
Member

Choose a reason for hiding this comment

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

This JS is always needed with the sidebar, if we have sidebar in layout.html.twig this JS should be loaded in layout.html.twig

<svg class="ez-icon ez-icon-browse">
<use xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#browse"></use>
</svg>
Browse
Copy link
Member

Choose a reason for hiding this comment

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

Translation?

Copy link
Contributor

@webhdx webhdx Oct 31, 2017

Choose a reason for hiding this comment

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

It's going to be fixed in #28 , @mikadamczyk can leave this as-is since he only moved the code.

{{ form_widget(form.query, {'attr': {'style': 'width: 200px', 'class': 'form-control'} }) }}

<span class="input-group-btn">
<input type="submit" class="btn btn-primary" value="Search"/>
Copy link
Member

Choose a reason for hiding this comment

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

I think it should be <button>, and I think the icon is missing in this input.

@mikadamczyk mikadamczyk force-pushed the ezp-28055-search-for-content branch 2 times, most recently from 51286c8 to d4a3c53 Compare October 31, 2017 10:45
@ezsystems ezsystems deleted a comment from ezrobot Oct 31, 2017
@mikadamczyk mikadamczyk force-pushed the ezp-28055-search-for-content branch from d4a3c53 to d4f5933 Compare October 31, 2017 10:49
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.

🙃

$query->filter = new Criterion\LogicalAnd(
[
new Criterion\Visibility(Criterion\Visibility::VISIBLE),
new Criterion\FullText($data->getQuery()),
Copy link
Member

Choose a reason for hiding this comment

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

Please validate if query is string and if it's not empty (to avoid making unnecessary calls to external SE handler).

]
);
$query->sortClauses[] = new SortClause\DateModified(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.

Please actually use $limit for query ($query->limit). Otherwise it will return default number of records (AFAICS now it is 25).
Also there's a need for $query->offset.

I don't know if and how this works with Pagerfanta, but offset and limits are needed to avoid killing external SE handler (e.g. can be Solr on a separate server)

composer.json Outdated
@@ -24,9 +24,6 @@
"require-dev": {
"phpunit/phpunit": "^6.4"
},
"require-dev": {
"phpunit/phpunit": "^6.4"
},
Copy link
Member

Choose a reason for hiding this comment

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

Changes out of scope should be in separate commits (yeah, we usually squash, but sometimes we don't).

private $page;

/** @var string */
private $query;
Copy link
Member

Choose a reason for hiding this comment

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

I never quite understood the need of encapsulation of data structure properties just to write getters and setters getting and setting them directly. This make sense to me only if structure is supposed to be immutable.

But not requesting changes, just asking why this is better. The flame war about this started around 2003 and never ended :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Accessing properties directly looks kinda lame. $something->getProperty() looks sexier. 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the only reason is that other classes are the same :(

@mikadamczyk mikadamczyk force-pushed the ezp-28055-search-for-content branch from d4f5933 to 7d50235 Compare October 31, 2017 15:15
@lserwatka
Copy link
Member

@webhdx @alongosz are you OK now?

alongosz
alongosz previously approved these changes Oct 31, 2017
@alongosz
Copy link
Member

Nitpicks:

  • still would prefer change of composer.json which is out of scope to be in a separate commit, but if it's gonna be squashed, then there's no point :)
  • also commit message (after expanding) looks a little bit weird, but this can be handled on merge if squashed

composer.json Outdated
@@ -22,9 +22,6 @@
"ezsystems/ez-support-tools": "^0.1@dev",
"knplabs/knp-menu-bundle": "^2.1"
},
"require-dev": {
Copy link
Contributor

@webhdx webhdx Nov 2, 2017

Choose a reason for hiding this comment

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

@mikadamczyk Why does this PR remove phpunit? Seems unrelated/bad?

Copy link
Member

Choose a reason for hiding this comment

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

Weird, actually when I reviewed this first it seemed like cleanup of redundant block, but maybe I misread something

class SearchController extends Controller
{
/** @var SearchService */
private $searchService;
Copy link
Contributor

Choose a reason for hiding this comment

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

I would define all properties either private or protected. private seems to be a more popular choice with recent PRs in order to disallow relying someone's code on our controllers.

/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please override configureOptions() with default data_class set to your SearchData::class

@alongosz alongosz dismissed their stale review November 2, 2017 08:17

Unjustified removal of phpunit

);

$query->limit = $limit;
$query->offset = ($page - 1) * $limit;
Copy link
Member

Choose a reason for hiding this comment

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

You don't need to set limit and offset manually, pagerfanta should take care of this.

Copy link
Member

@alongosz alongosz Nov 3, 2017

Choose a reason for hiding this comment

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

Ok, so apparently this already works with ContentSearchAdapter from kernel (which I didn't know or even expect to be implemented there, sorry). Not 100% convinced this is clean, as being PAPI developer I got confused, but seems like a intended way to go.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, so I will remove limit and offset for query

Copy link
Member

Choose a reason for hiding this comment

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

yep, sorry for the mess.

@micszo micszo requested a review from barbaragr November 2, 2017 10:10
@webhdx webhdx force-pushed the ezp-28055-search-for-content branch 2 times, most recently from 6aaa572 to 439dbf4 Compare November 3, 2017 09:54
@dew326 dew326 force-pushed the ezp-28055-search-for-content branch from 439dbf4 to 4193e2a Compare November 3, 2017 10:15
@barbaragr
Copy link

Performing Search on the second page of search results.
Preconditions: perform search action to receive more than 10 results. I've got 12 elements on a list and 2 pages.

Steps:

  1. Go to the second page.
  2. Type a word in a search input.
  3. Perform search action - "Page 2 does not exist. The currentPage must be inferior to 1" alert appears and there are no search results. It should automatically go to the first page and show results.

@barbaragr
Copy link

barbaragr commented Nov 3, 2017

Searching with phrase containing '%' results with "The expression 'OR' expected at least 1 argument but none provided". Nothing is shown in search result.

The same for "?", "!", "-", "$"

@adamwojs
Copy link
Member

adamwojs commented Nov 3, 2017

Searching with phrase containing '%' results with "The expression 'OR' expected at least 1 argument but none provided". Nothing is shown in search result.

@barbaragr This is already known issue. See ezsystems/ezpublish-kernel#2029 for more details.

Copy link

@barbaragr barbaragr left a comment

Choose a reason for hiding this comment

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

I've found a bug so please my comment above.

Copy link

@barbaragr barbaragr left a comment

Choose a reason for hiding this comment

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

I've found a bug so please my comment above.

@mikadamczyk mikadamczyk force-pushed the ezp-28055-search-for-content branch from 4193e2a to c72ca58 Compare November 6, 2017 09:43
@mikadamczyk
Copy link
Contributor Author

I fixed PR, can you take a look at it? @barbaragr @adamwojs @webhdx

*/
public function searchAction(Request $request): Response
{
$limit = $request->query->getInt('limit', 10);
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be best to expose limit as a configuration option instead of hardcoded 10.

@Nattfarinn
Copy link
Contributor

@webhdx Please confirm if you're fine with changes to your code review.

{{ form_start(form) }}
<div class="input-group">
{{ form_widget(form.query, {'attr': {'class': 'form-control'} }) }}
{{ form_widget(form.page, {'attr': {'value': 1 }}) }}
Copy link
Contributor

@webhdx webhdx Nov 6, 2017

Choose a reason for hiding this comment

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

We shouldn't overwrite the value in the view. Value can be passed in the controller by changing corresponding data object.

Actually with current implementation we cannot avoid doing that. It will need some refactoring in the future.

@webhdx webhdx force-pushed the ezp-28055-search-for-content branch 2 times, most recently from 2d85fdc to dbb6f2a Compare November 6, 2017 14:30
@webhdx webhdx force-pushed the ezp-28055-search-for-content branch from 448e9c7 to 6fdcd3a Compare November 6, 2017 15:10
@ezsystems ezsystems deleted a comment from ezrobot Nov 6, 2017
@lserwatka lserwatka merged commit 4e5337a into ezsystems:master Nov 6, 2017
tischsoic pushed a commit that referenced this pull request Nov 8, 2021
…tintegration

Merge IBX-1070 added fix for contentintegration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

8 participants