Compare commits

...

17 commits

Author SHA1 Message Date
Marc Alexander
5212659a1c
Merge 3eaf4829bb into f94423d491 2025-05-07 20:16:34 +02:00
Marc Alexander
f94423d491 Merge branch '3.3.x' 2025-05-07 18:16:11 +00:00
Marc Alexander
b6200d6690
Merge pull request #6800 from rxu/ticket/17491-master
[ticket/17491] Fix caching search results - master
2025-05-07 20:15:57 +02:00
Marc Alexander
04f2141a7d
Merge pull request #6799 from rxu/ticket/17491
[ticket/17491] Fix caching search results - 3.3.x
2025-05-07 20:15:53 +02:00
rxu
4b7d7c2fc7
Merge branch 'ticket/17491' into ticket/17491-master 2025-05-07 00:40:32 +07:00
rxu
3d76a8bd09
[ticket/17491] Fix rows duplication in search results
PHPBB-17491
2025-05-07 00:31:21 +07:00
rxu
1c399dcab7
[ticket/17491] Consistently apply array_unique to search results
PHPBB-17491
2025-05-06 00:11:45 +07:00
rxu
e91c7d42a9
[ticket/17491] Add test
PHPBB-17491
2025-05-05 23:46:09 +07:00
Marc Alexander
3eaf4829bb
[ticket/17501] Adjust notification dropdown color and spacing
PHPBB-17501
2025-04-24 21:03:44 +02:00
Marc Alexander
3b233d9c28
[ticket/17501] Update events docs
PHPBB-17501
2025-04-21 21:44:22 +02:00
Marc Alexander
3801eb0946
[ticket/17501] Remove not needed parentheses
PHPBB-17501
2025-04-21 20:38:59 +02:00
Marc Alexander
3a553f07bc
[ticket/17501] Remove unused CSS properties
PHPBB-17501
2025-04-21 20:36:04 +02:00
Marc Alexander
b666bc9e0a
[ticket/17501] Add to top button to viewtopic and add missing title in FAQ
PHPBB-17501
2025-04-21 20:33:36 +02:00
Marc Alexander
81c49aa6a5
[ticket/17501] Remove max width from subforums
PHPBB-17501
2025-04-21 20:18:40 +02:00
Marc Alexander
6fd9a78872
[ticket/17501] Adjust CSS for moved navbar & breadcrumbs
PHPBB-17501
2025-04-21 17:37:53 +02:00
Marc Alexander
7f3b37560e
[ticket/17501] Move navbar above header and breadcrumbs below
PHPBB-17501
2025-04-21 17:37:38 +02:00
rxu
8d0d6c012c
[ticket/17491] Fix caching search results
PHPBB-17491
2025-04-12 14:35:40 +07:00
15 changed files with 305 additions and 110 deletions

View file

@ -1746,29 +1746,33 @@ overall_header_body_before
overall_header_breadcrumb_append
===
* Locations:
+ styles/prosilver/template/navbar_header.html
+ styles/prosilver/template/breadcrumbs.html
* Since: 3.1.0-a1
* Changed: 4.0.0-a1 Moved to breadcrumbs.html
* Purpose: Add links to the list of breadcrumbs in the header
overall_header_breadcrumb_prepend
===
* Locations:
+ styles/prosilver/template/navbar_header.html
+ styles/prosilver/template/breadcrumbs.html
* Since: 3.1.0-RC3
* Changed: 4.0.0-a1 Moved to breadcrumbs.html
* Purpose: Add links to the list of breadcrumbs in the header (after site-home, but before board-index)
overall_header_breadcrumbs_after
===
* Locations:
+ styles/prosilver/template/navbar_header.html
+ styles/prosilver/template/breadcrumbs.html
* Since: 3.1.0-RC3
* Changed: 4.0.0-a1 Moved to breadcrumbs.html
* Purpose: Add content after the breadcrumbs (outside of the breadcrumbs container)
overall_header_breadcrumbs_before
===
* Locations:
+ styles/prosilver/template/navbar_header.html
+ styles/prosilver/template/breadcrumbs.html
* Since: 3.1.0-RC3
* Changed: 4.0.0-a1 Moved to breadcrumbs.html
* Purpose: Add content before the breadcrumbs (outside of the breadcrumbs container)
overall_header_content_before
@ -1830,15 +1834,17 @@ overall_header_navigation_prepend
overall_header_navlink_append
===
* Locations:
+ styles/prosilver/template/navbar_header.html
+ styles/prosilver/template/breadcrumbs.html
* Since: 3.1.0-b3
* Changed: 4.0.0-a1 Moved to breadcrumbs.html
* Purpose: Add content after each individual navlink (breadcrumb)
overall_header_navlink_prepend
===
* Locations:
+ styles/prosilver/template/navbar_header.html
+ styles/prosilver/template/breadcrumbs.html
* Since: 3.1.0-b3
* Changed: 4.0.0-a1 Moved to breadcrumbs.html
* Purpose: Add content before each individual navlink (breadcrumb)
overall_header_page_body_before

View file

@ -112,10 +112,16 @@ abstract class base implements search_backend_interface
}
}
// If the sort direction differs from the direction in the cache, then reverse the ids array
// If the sort direction differs from the direction in the cache, then recalculate array keys
if ($reverse_ids)
{
$stored_ids = array_reverse($stored_ids);
$keys = array_keys($stored_ids);
array_walk($keys, function (&$value, $key) use ($result_count)
{
$value = ($value >= 0) ? $result_count - $value - 1 : $value;
}
);
$stored_ids = array_combine($keys, $stored_ids);
}
for ($i = $start, $n = $start + $per_page; ($i < $n) && ($i < $result_count); $i++)
@ -166,6 +172,8 @@ abstract class base implements search_backend_interface
}
$store_ids = array_slice($id_ary, 0, $length);
$id_range = range($start, $start + $length - 1);
$store_ids = array_combine($id_range, $store_ids);
// create a new resultset if there is none for this search_key yet
// or add the ids to the existing resultset
@ -200,29 +208,26 @@ abstract class base implements search_backend_interface
$this->db->sql_query($sql);
$store = array(-1 => $result_count, -2 => $sort_dir);
$id_range = range($start, $start + $length - 1);
}
else
{
// we use one set of results for both sort directions so we have to calculate the indizes
// for the reversed array and we also have to reverse the ids themselves
// for the reversed array
if ($store[-2] != $sort_dir)
{
$store_ids = array_reverse($store_ids);
$id_range = range($store[-1] - $start - $length, $store[-1] - $start - 1);
}
else
{
$id_range = range($start, $start + $length - 1);
$keys = array_keys($store_ids);
array_walk($keys, function (&$value, $key) use ($store) {
$value = $store[-1] - $value - 1;
});
$store_ids = array_combine($keys, $store_ids);
}
}
$store_ids = array_combine($id_range, $store_ids);
// append the ids
if (is_array($store_ids))
{
$store += $store_ids;
ksort($store);
// if the cache is too big
if (count($store) - 2 > 20 * $this->config['search_block_size'])

View file

@ -550,7 +550,6 @@ class fulltext_mysql extends base implements search_backend_interface
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
// if the total result count is not cached yet, retrieve it from the db
if (!$result_count && count($id_ary))
{
@ -576,10 +575,10 @@ class fulltext_mysql extends base implements search_backend_interface
$id_ary[] = (int) $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
$this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
$id_ary = array_slice($id_ary, 0, (int) $per_page);
@ -758,6 +757,8 @@ class fulltext_mysql extends base implements search_backend_interface
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
// For sorting by non-unique columns, add unique sort key to avoid duplicated rows in results
$sql_sort .= ', p.post_id' . (($sort_dir == 'a') ? ' ASC' : ' DESC');
$sql = "SELECT $sql_select
FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t ' : ' ') . "
WHERE $sql_author
@ -821,10 +822,10 @@ class fulltext_mysql extends base implements search_backend_interface
$id_ary[] = (int) $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
if (count($id_ary))
{
$this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);

View file

@ -1004,6 +1004,8 @@ class fulltext_native extends base implements search_backend_interface
$this->db->sql_freeresult($result);
}
$id_ary = array_unique($id_ary);
// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
$this->save_ids($search_key, $this->search_query, $author_ary, $total_results, $id_ary, $start, $sort_dir);
$id_ary = array_slice($id_ary, 0, (int) $per_page);
@ -1225,6 +1227,8 @@ class fulltext_native extends base implements search_backend_interface
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
// For sorting by non-unique columns, add unique sort key to avoid duplicated rows in results
$sql_sort .= ', p.post_id' . (($sort_dir == 'a') ? ' ASC' : ' DESC');
$sql = "SELECT $select
FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t' : '') . "
WHERE $sql_author
@ -1289,6 +1293,8 @@ class fulltext_native extends base implements search_backend_interface
$this->db->sql_freeresult($result);
}
$id_ary = array_unique($id_ary);
if (count($id_ary))
{
$this->save_ids($search_key, '', $author_ary, $total_results, $id_ary, $start, $sort_dir);

View file

@ -478,8 +478,6 @@ class fulltext_postgres extends base implements search_backend_interface
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
// if the total result count is not cached yet, retrieve it from the db
if (!$result_count)
{
@ -509,10 +507,10 @@ class fulltext_postgres extends base implements search_backend_interface
$id_ary[] = $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
$this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
$id_ary = array_slice($id_ary, 0, (int) $per_page);
@ -683,6 +681,8 @@ class fulltext_postgres extends base implements search_backend_interface
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
// For sorting by non-unique columns, add unique sort key to avoid duplicated rows in results
$sql_sort .= ', p.post_id' . (($sort_dir == 'a') ? ' ASC' : ' DESC');
$sql = "SELECT p.post_id
FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t ' : ' ') . "
WHERE $sql_author
@ -775,10 +775,10 @@ class fulltext_postgres extends base implements search_backend_interface
$id_ary[] = (int) $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
if (count($id_ary))
{
$this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);

View file

@ -0,0 +1,53 @@
<ul id="nav-breadcrumbs" class="nav-breadcrumbs linklist navlinks" role="menubar">
{% set MICRODATA = 'itemtype="https://schema.org/ListItem" itemprop="itemListElement" itemscope' %}
{% set navlink_position = 1 %}
{% EVENT overall_header_breadcrumbs_before %}
<li class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
{% if U_SITE_HOME %}
<span class="crumb" {{ MICRODATA }}>
{% apply spaceless %}
<a itemprop="item" href="{{ U_SITE_HOME }}" data-navbar-reference="home">
{{ Icon('font', 'home', '', true, 'fas o-icon-baseline') }}
<span itemprop="name">{{ L_SITE_HOME }}</span>
</a>
{% endapply %}
<meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}">
</span>
{% endif %}
{% EVENT overall_header_breadcrumb_prepend %}
<span class="crumb" {{ MICRODATA }}>
{% apply spaceless %}
<a itemprop="item" href="{{ U_INDEX }}" accesskey="h" data-navbar-reference="index">
{% if not U_SITE_HOME %}{{ Icon('font', 'home', '', true, 'fas o-icon-baseline') }}{% endif %}
<span itemprop="name">{{ L_INDEX }}</span>
</a>
{% endapply %}
<meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}">
</span>
{% for navlink in navlinks %}
{% set NAVLINK_NAME = navlink.BREADCRUMB_NAME | default(navlink.FORUM_NAME) %}
{% set NAVLINK_LINK = navlink.U_BREADCRUMB | default(navlink.U_VIEW_FORUM) %}
{% EVENT overall_header_navlink_prepend %}
<span class="crumb" {{ MICRODATA }}{% if navlink.MICRODATA %} {{ navlink.MICRODATA }}{% endif %}>
{% apply spaceless %}
<a itemprop="item" href="{{ NAVLINK_LINK }}">
<span itemprop="name">{{ NAVLINK_NAME }}</span>
</a>
{% endapply %}
<meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}">
</span>
{% EVENT overall_header_navlink_append %}
{% endfor %}
{% EVENT overall_header_breadcrumb_append %}
</li>
{% EVENT overall_header_breadcrumbs_after %}
</ul>

View file

@ -44,7 +44,7 @@
<!-- END faq_block -->
<div class="to-top-button">
<a href="#faqlinks">
<a href="#faqlinks" title="{{ lang('BACK_TO_TOP') }}">
{{ Icon('font', 'chevron-up', '', false) }}
</a>
</div>

View file

@ -203,68 +203,5 @@
{% endif %}
</ul>
<ul id="nav-breadcrumbs" class="nav-breadcrumbs linklist navlinks" role="menubar">
{% set MICRODATA = 'itemtype="https://schema.org/ListItem" itemprop="itemListElement" itemscope' %}
{% set navlink_position = 1 %}
{% EVENT overall_header_breadcrumbs_before %}
<li class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
{% if U_SITE_HOME %}
<span class="crumb" {{ MICRODATA }}>
{% apply spaceless %}
<a itemprop="item" href="{{ U_SITE_HOME }}" data-navbar-reference="home">
{{ Icon('font', 'home', '', true, 'fas o-icon-baseline') }}
<span itemprop="name">{{ L_SITE_HOME }}</span>
</a>
{% endapply %}
<meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}">
</span>
{% endif %}
{% EVENT overall_header_breadcrumb_prepend %}
<span class="crumb" {{ MICRODATA }}>
{% apply spaceless %}
<a itemprop="item" href="{{ U_INDEX }}" accesskey="h" data-navbar-reference="index">
{% if not U_SITE_HOME %}{{ Icon('font', 'home', '', true, 'fas o-icon-baseline') }}{% endif %}
<span itemprop="name">{{ L_INDEX }}</span>
</a>
{% endapply %}
<meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}">
</span>
{% for navlink in navlinks %}
{% set NAVLINK_NAME = navlink.BREADCRUMB_NAME | default(navlink.FORUM_NAME) %}
{% set NAVLINK_LINK = navlink.U_BREADCRUMB | default(navlink.U_VIEW_FORUM) %}
{% EVENT overall_header_navlink_prepend %}
<span class="crumb" {{ MICRODATA }}{% if navlink.MICRODATA %} {{ navlink.MICRODATA }}{% endif %}>
{% apply spaceless %}
<a itemprop="item" href="{{ NAVLINK_LINK }}">
<span itemprop="name">{{ NAVLINK_NAME }}</span>
</a>
{% endapply %}
<meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}">
</span>
{% EVENT overall_header_navlink_append %}
{% endfor %}
{% EVENT overall_header_breadcrumb_append %}
</li>
{% EVENT overall_header_breadcrumbs_after %}
{% if S_DISPLAY_SEARCH and not S_IN_SEARCH %}
<li class="rightside responsive-search">
<a href="{{ U_SEARCH }}" title="{{ lang('SEARCH_ADV_EXPLAIN') }}" role="menuitem">
{{ Icon('font', 'search', lang('SEARCH'), true) }}
</a>
</li>
{% endif %}
</ul>
</div>
</div>

View file

@ -68,7 +68,7 @@
<!-- EVENT overall_header_stylesheets_after -->
{% if NOTIFICATIONS_WEBPUSH_ENABLE %}
{% include('ucp_notifications_webpush.html') %}
{% include 'ucp_notifications_webpush.html' %}
{% endif %}
</head>
@ -79,7 +79,11 @@
<div id="wrap" class="wrap">
<a id="top" class="top-anchor" accesskey="t"></a>
<div id="page-header">
<!-- EVENT overall_header_navbar_before -->
<div class="headerbar" role="banner">
{% include 'navbar_header.html' %}
<!-- EVENT overall_header_headerbar_before -->
<div class="inner">
@ -117,10 +121,10 @@
</div>
<!-- EVENT overall_header_headerbar_after -->
</div>
<!-- EVENT overall_header_navbar_before -->
<!-- INCLUDE navbar_header.html -->
</div>
{% include 'breadcrumbs.html' %}
<!-- EVENT overall_header_page_body_before -->
<a id="start_here" class="anchor"></a>

View file

@ -423,9 +423,6 @@
<!-- EVENT viewtopic_body_postrow_back2top_before -->
<div class="back2top">
<!-- EVENT viewtopic_body_postrow_back2top_prepend -->
<a href="#top" class="top" title="{L_BACK_TO_TOP}">
{{ Icon('font', 'circle-chevron-up', lang('BACK_TO_TOP'), false, 'fas c-top-icon') }}
</a>
<!-- EVENT viewtopic_body_postrow_back2top_append -->
</div>
<!-- EVENT viewtopic_body_postrow_back2top_after -->
@ -496,6 +493,12 @@
<!-- ENDIF -->
</div>
<div class="to-top-button">
<a href="#top" title="{{ lang('BACK_TO_TOP') }}">
{{ Icon('font', 'chevron-up', '', false) }}
</a>
</div>
<!-- EVENT viewtopic_body_footer_before -->
<!-- INCLUDE jumpbox.html -->

View file

@ -99,18 +99,19 @@ th a:hover {
}
/* round cornered boxes and backgrounds */
.headerbar {
color: #ffffff;
.headerbar,
.headerbar h1 {
color: #eaf8ff;
}
.headerbar,
.forumbg {
background-color: #13a4ec;
background-color: #4688ce;
background-repeat: repeat-x;
}
.forabg {
background-color: #13a4ec;
background-color: #4688ce;
background-repeat: repeat-x;
}
@ -118,6 +119,18 @@ th a:hover {
background-color: #c9dee8;
}
.headerbar .navbar a {
color: #eaf8ff;
}
.headerbar .navbar .dropdown a {
color: #0f4d8a;
}
.header-profile {
text-shadow: 0 0 1.75rem #eaf8ff;
}
.panel {
background-color: #f0f3f5;
color: #29303d;
@ -814,6 +827,10 @@ dd.profile-warnings {
/* icon images */
.site_logo { background-image: url("./images/site_logo.svg"); }
.c-hero-logo-img g {
fill: #eaf8ff;
}
/* colours and backgrounds for cp.css */
/* main cp box */
@ -1109,6 +1126,7 @@ input.disabled {
.dropdown-extended .dropdown-extended-item {
border-top-color: #bdbdbd;
color: #47536b;
}
.dropdown-extended .dropdown-extended-item:hover {

View file

@ -17,7 +17,7 @@ body {
line-height: normal;
word-wrap: break-word;
margin: 0;
padding: 12px 0;
padding: 0 0 12px;
-webkit-print-color-adjust: exact;
}
@ -151,12 +151,13 @@ a:hover {
/* Main blocks
---------------------------------------- */
.wrap {
border: 1px solid transparent;
border-radius: 8px;
border: solid transparent;
border-width: 0 1px 1px;
border-radius: 0 0 8px 8px;
min-width: 625px;
max-width: 1152px;
margin: 0 auto;
padding: 15px;
padding: 0 15px 15px;
}
.page-body {
@ -200,7 +201,7 @@ a:hover {
/* Round cornered boxes and backgrounds
---------------------------------------- */
.headerbar {
border-radius: 7px;
border-radius: 0 0 7px 7px;
display: flex;
flex-direction: column;
margin-bottom: 0.5rem;
@ -212,6 +213,11 @@ a:hover {
padding: 3px 10px;
}
.headerbar .navbar {
background: none;
padding: calc(var(--ps-line-height) * 0.25) 5px calc(var(--ps-line-height) * 0.5);
}
.forabg {
border-radius: 7px;
clear: both;
@ -340,6 +346,10 @@ ul.linklist .dropdown-up .dropdown {
bottom: 18px;
}
ul.nav-breadcrumbs {
margin: calc(var(--ps-line-height) * 0.75) 0;
}
/* Bulletin icons for list items
---------------------------------------- */
ul.linklist.bulletin > li:before {

View file

@ -465,7 +465,7 @@ p.author {
clear: left;
overflow: hidden;
width: 100%;
margin-top: calc(var(--ps-font-small) * 1.4);
margin: calc(var(--ps-font-small) * 1.4) 0;
padding-top: 2px;
}

View file

@ -328,7 +328,6 @@
vertical-align: bottom;
text-overflow: ellipsis;
overflow: hidden;
max-width: 100px;
}
/* Pagination

View file

@ -229,6 +229,159 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
$this->delete_topic($topic_multiple_results_count2['topic_id']);
}
public function test_caching_search_results()
{
global $phpbb_root_path;
// Sphinx search doesn't use phpBB search results caching
if (strpos($this->search_backend, 'fulltext_sphinx'))
{
$this->markTestSkipped("Sphinx search doesn't use phpBB search results caching");
}
$this->purge_cache();
$this->login();
$this->admin_login();
$crawler = self::request('GET', 'search.php?author_id=2&sr=posts');
$posts_found_text = $crawler->filter('.searchresults-title')->text();
// Get total user's post count
preg_match('!(\d+)!', $posts_found_text, $matches);
$posts_count = (int) $matches[1];
$this->assertStringContainsString("Search found $posts_count matches", $posts_found_text, $this->search_backend);
// Set this value to cache less results than total count
$sql = 'UPDATE ' . CONFIG_TABLE . '
SET config_value = ' . floor($posts_count / 3) . "
WHERE config_name = '" . $this->db->sql_escape('search_block_size') . "'";
$this->db->sql_query($sql);
// Temporarily set posts_per_page to the value allowing to get several pages (4+)
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post');
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$current_posts_per_page = $values['config[posts_per_page]'];
$values['config[posts_per_page]'] = floor($posts_count / 10);
$form->setValues($values);
$crawler = self::submit($form);
$this->assertEquals(1, $crawler->filter('.successbox')->count(), $this->search_backend);
// Now actually test caching search results
$this->purge_cache();
// Default sort direction is 'd' (descending), browse the 1st page
$crawler = self::request('GET', 'search.php?author_id=2&sr=posts');
$pagination = $crawler->filter('.pagination')->eq(0);
$posts_found_text = $pagination->text();
$this->assertStringContainsString("Search found $posts_count matches", $posts_found_text, $this->search_backend);
// Filter all search result page links on the 1st page
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
// Get last page number
$last_page = (int) $pagination->last()->text();
// Browse the last search page
$crawler = self::$client->click($pagination->selectLink($last_page)->link());
$pagination = $crawler->filter('.pagination')->eq(0);
// Filter all search result page links on the last page
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
// Now change sort direction to ascending
$form = $crawler->selectButton('sort')->form();
$values = $form->getValues();
$values['sd'] = 'a';
$form->setValues($values);
$crawler = self::submit($form);
$pagination = $crawler->filter('.pagination')->eq(0);
// Filter all search result page links on the 1st page with new sort direction
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
// Browse the rest of search results pages with new sort direction
$pages = range(2, $last_page);
foreach ($pages as $page_number)
{
$crawler = self::$client->click($pagination->selectLink($page_number)->link());
$pagination = $crawler->filter('.pagination')->eq(0);
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
}
// Get search results cache varname
$finder = new \Symfony\Component\Finder\Finder();
$finder
->name('data_search_results_*.php')
->files()
->in($phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT);
$iterator = $finder->getIterator();
$iterator->rewind();
$cache_filename = $iterator->current();
$cache_varname = substr($cache_filename->getBasename('.php'), 4);
// Get cached post ids data
$cache = $this->get_cache_driver();
$post_ids_cached = $cache->get($cache_varname);
$cached_results_count = count($post_ids_cached) - 2; // Don't count '-1' and '-2' indexes
$post_ids_cached_backup = $post_ids_cached;
// Cached data still should have initial 'd' sort direction
$this->assertTrue($post_ids_cached[-2] === 'd', $this->search_backend);
// Cached search results count should be equal to displayed on search results page
$this->assertEquals($posts_count, $post_ids_cached[-1], $this->search_backend);
// Actual cached data array count should be equal to displayed on search results page too
$this->assertEquals($posts_count, $cached_results_count, $this->search_backend);
// Cached data array shouldn't change after removing duplicates. That is, it shouldn't have any duplicates.
unset($post_ids_cached[-2], $post_ids_cached[-1]);
unset($post_ids_cached_backup[-2], $post_ids_cached_backup[-1]);
$post_ids_cached = array_unique($post_ids_cached);
$this->assertEquals($post_ids_cached_backup, $post_ids_cached, $this->search_backend);
// Restore this value to default
$sql = 'UPDATE ' . CONFIG_TABLE . "
SET config_value = 250
WHERE config_name = '" . $this->db->sql_escape('search_block_size') . "'";
$this->db->sql_query($sql);
// Restore posts_per_page value
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post');
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$values['config[posts_per_page]'] = $current_posts_per_page;
$form->setValues($values);
$crawler = self::submit($form);
$this->assertEquals(1, $crawler->filter('.successbox')->count(), $this->search_backend);
}
protected function create_search_index($backend = null)
{
$this->add_lang('acp/search');