-
Notifications
You must be signed in to change notification settings - Fork 57
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
EZP-28055: As a v2 Editor I want to search for content items by entering a search keyword #33
Conversation
46daeee
to
0f0bfcb
Compare
*/ | ||
public function getBlockPrefix() | ||
{ | ||
return null; |
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.
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
.
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.
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?
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, 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') |
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.
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, |
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.
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'} }) }} |
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 have to move inline style
to CSS. @dew326 can propose you best solution.
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.
Inline style is not needed anymore
{% block pageTitle %}{% endblock %} | ||
|
||
{% block content %} | ||
<div id="react-udw"></div> |
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.
Should UDW be a part of search page?
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.
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.
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.
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'); |
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.
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', [ |
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.
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.
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.
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' %} |
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.
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 |
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.
Translation?
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.
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"/> |
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.
I think it should be <button>
, and I think the icon is missing in this input.
51286c8
to
d4a3c53
Compare
d4a3c53
to
d4f5933
Compare
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.
🙃
$query->filter = new Criterion\LogicalAnd( | ||
[ | ||
new Criterion\Visibility(Criterion\Visibility::VISIBLE), | ||
new Criterion\FullText($data->getQuery()), |
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.
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); | ||
|
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.
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" | |||
}, |
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.
Changes out of scope should be in separate commits (yeah, we usually squash, but sometimes we don't).
private $page; | ||
|
||
/** @var string */ | ||
private $query; |
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.
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 :)
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.
Accessing properties directly looks kinda lame. $something->getProperty()
looks sexier. 😂
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.
I think the only reason is that other classes are the same :(
d4f5933
to
7d50235
Compare
Nitpicks:
|
composer.json
Outdated
@@ -22,9 +22,6 @@ | |||
"ezsystems/ez-support-tools": "^0.1@dev", | |||
"knplabs/knp-menu-bundle": "^2.1" | |||
}, | |||
"require-dev": { |
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.
@mikadamczyk Why does this PR remove phpunit? Seems unrelated/bad?
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.
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; |
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.
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) |
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.
Please override configureOptions()
with default data_class
set to your SearchData::class
); | ||
|
||
$query->limit = $limit; | ||
$query->offset = ($page - 1) * $limit; |
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.
You don't need to set limit
and offset
manually, pagerfanta should take care of this.
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.
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.
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.
Ok, so I will remove limit
and offset
for query
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.
yep, sorry for the mess.
6aaa572
to
439dbf4
Compare
439dbf4
to
4193e2a
Compare
Performing Search on the second page of search results. Steps:
|
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 "?", "!", "-", "$" |
@barbaragr This is already known issue. See ezsystems/ezpublish-kernel#2029 for more details. |
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.
I've found a bug so please my comment above.
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.
I've found a bug so please my comment above.
4193e2a
to
c72ca58
Compare
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); |
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.
It would be best to expose limit
as a configuration option instead of hardcoded 10
.
@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 }}) }} |
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 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.
2d85fdc
to
dbb6f2a
Compare
…ing a search keyword
448e9c7
to
6fdcd3a
Compare
…tintegration Merge IBX-1070 added fix for contentintegration
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.