Skip to content

Commit

Permalink
Issue mozfr#320: multi-repository search
Browse files Browse the repository at this point in the history
* New search class with a fluent interface
* Removed "wildcard" search option from main view
  • Loading branch information
pascalchevrel authored and TheoChevalier committed Jan 4, 2016
1 parent 5620048 commit 4ead132
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 99 deletions.
52 changes: 37 additions & 15 deletions app/classes/Transvision/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,28 @@ public static function getSupportedRepositories()
$repositories[$repository['id']] = $repository['name'];
}

// 'global' is a virtual repository
$repositories['global'] = 'All repositories';

return $repositories;
}

/**
* Get the list of repositories.
*
* @return array list of local repositories values
* @param boolean $include_virtual Include virtual repositories, default to false
* @return array List of local repositories values
*/
public static function getRepositories()
public static function getRepositories($include_virtual = false)
{
return array_keys(self::getSupportedRepositories());
$supported_repositories = array_keys(self::getSupportedRepositories());

if (! $include_virtual) {
$supported_repositories = array_diff($supported_repositories, ['global']);
$supported_repositories = array_values($supported_repositories);
}

return $supported_repositories;
}

/**
Expand Down Expand Up @@ -140,33 +151,44 @@ public static function getDesktopRepositories()
{
return array_diff(
self::getRepositories(),
['mozilla_org', 'firefox_ios'],
['mozilla_org', 'firefox_ios', 'global'],
self::getGaiaRepositories()
);
}

/**
* Get the list of locales available for a repository
* Get the list of locales available for a repository.
* If the repository queried is 'global', then we return the locales
* for all the repositories we support.
*
* @param string $repository ID of the repository
* @return array A sorted list of locales
*/
public static function getRepositoryLocales($repository)
{
$file_name = APP_SOURCES . "{$repository}.txt";
$repositories = ($repository == 'global')
? self::getRepositories()
: [$repository];

$supported_locales = [];
if (file_exists($file_name)) {
$supported_locales = file($file_name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($repositories as $repository) {
$file_name = APP_SOURCES . "{$repository}.txt";
if (file_exists($file_name)) {
$supported_locales = array_merge(
$supported_locales,
file($file_name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
);
}
// Make sure that the reference locale is included
$reference_locale = self::getReferenceLocale($repository);
if (! in_array($reference_locale, $supported_locales)) {
$supported_locales[] = $reference_locale;
}
}

// Make sure that the reference locale is included
$reference_locale = self::getReferenceLocale($repository);
if (! in_array($reference_locale, $supported_locales)) {
$supported_locales[] = $reference_locale;
}
sort($supported_locales);

return $supported_locales;
return array_unique($supported_locales);
}

/**
Expand Down Expand Up @@ -210,7 +232,7 @@ public static function getReferenceLocale($repository)
*/
public static function isValidRepository($repository)
{
return in_array($repository, self::getRepositories());
return in_array($repository, self::getRepositories(true));
}

/**
Expand Down
5 changes: 0 additions & 5 deletions app/controllers/mainsearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
. "{$type}/{$repo}/{$source}/{$target}/{$terms}/{$regex}");
exit;
}

// Bootstrap l10n
require_once INC . 'l10n-init.php';

Expand Down Expand Up @@ -78,10 +77,6 @@
return;
}

// Valid search, we load all the strings
$tmx_source = Utils::getRepoStrings($source_locale, $check['repo']);
$tmx_target = Utils::getRepoStrings($locale, $check['repo']);

if ($check['search_type'] == 'entities') {
require_once MODELS . 'mainsearch_entities.php';
require_once VIEWS . 'results_entities.php';
Expand Down
15 changes: 6 additions & 9 deletions app/inc/search_options.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@
$check = [];

foreach ($form_checkboxes as $val) {
$check[$val] = (isset($_GET[$val])) ? true : false;
$check[$val] = isset($_GET[$val]);
}

// Check for default_repository cookie, if not set default repo to 'central'
if (isset($_COOKIE['default_repository'])) {
$check['repo'] = $_COOKIE['default_repository'];
} else {
$check['repo'] = 'aurora';
}
// Check for default_repository cookie, if not set default repo to 'aurora'
$check['repo'] = isset($_COOKIE['default_repository'])
? $_COOKIE['default_repository']
: 'aurora';

if (isset($_GET['repo']) && in_array($_GET['repo'], $repos)) {
$check['repo'] = $_GET['repo'];
Expand Down Expand Up @@ -54,8 +52,7 @@
$loc_list = [];
$source_locales_list = [];
$target_locales_list = [];
$repositories = Project::getRepositories();
foreach ($repositories as $repository) {
foreach (Project::getRepositories(true) as $repository) {
$loc_list[$repository] = Project::getRepositoryLocales($repository);

// build the source locale switcher
Expand Down
2 changes: 1 addition & 1 deletion app/inc/variables.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/* Global variables used across the project */

// Repositories
$repos = Project::getRepositories();
$repos = Project::getRepositories(true);
$repos_nice_names = Project::getRepositoriesNames();
$gaia_repos = Project::getGaiaRepositories();
$desktop_repos = Project::getDesktopRepositories();
Expand Down
3 changes: 3 additions & 0 deletions app/models/mainsearch_entities.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?php
namespace Transvision;

$tmx_source = Utils::getRepoStrings($source_locale, $check['repo']);
$tmx_target = Utils::getRepoStrings($locale, $check['repo']);

// rtl support
$direction1 = RTLSupport::getDirection($source_locale);
$direction2 = RTLSupport::getDirection($locale);
Expand Down
129 changes: 62 additions & 67 deletions app/models/mainsearch_strings.php
Original file line number Diff line number Diff line change
@@ -1,76 +1,67 @@
<?php
namespace Transvision;

if ($search->isPerfectMatch()) {
$locale1_strings = preg_grep($search->getRegex(), $tmx_source);
$locale2_strings = preg_grep($search->getRegex(), $tmx_target);
} else {
$locale1_strings = $tmx_source;
$locale2_strings = $tmx_target;
foreach (Utils::uniqueWords($initial_search) as $word) {
$locale1_strings = preg_grep($search->getRegex(), $locale1_strings);
$locale2_strings = preg_grep($search->getRegex(), $locale2_strings);
}
// Define our source and target locales
$locales = [$source_locale, $locale];
if ($page == '3locales') {
$locales[] = $locale2;
}

if ($check['search_type'] == 'strings_entities') {
$entities = ShowResults::searchEntities($tmx_source, $search->getRegex());
foreach ($entities as $entity) {
$locale1_strings[$entity] = $tmx_source[$entity];
}
}

$real_search_results = count($locale1_strings);
$limit_results = 200;
// Limit results to 200 per locale
array_splice($locale1_strings, $limit_results);
array_splice($locale2_strings, $limit_results);

$searches = [
$source_locale => $locale1_strings,
$locale => $locale2_strings,
];
// Define our regex and our locales
$search = (new Search)
->setSearchTerms(Utils::cleanString($_GET['recherche']))
->setRegexWholeWords($check['whole_word'])
->setRegexCase($check['case_sensitive'])
->setRegexPerfectMatch($check['perfect_match'])
->setLocales($locales)
->setResultsLimit(200)
;

$data = [$tmx_source, $tmx_target];

// 3locales view
if ($url['path'] == '3locales') {
$check['extra_locale'] = $locale2;
$searches[$locale2] = $locale3_strings;
$data[] = $tmx_target2;
}
$repo_loop = ($repo == 'global')
? Project::getRepositories()
: [$repo];

$search_yields_results = false;

// This will hold the components names for the search filters
$components = [];

foreach ($searches as $key => $value) {
$search_results = ShowResults::getTMXResults(array_keys($value), $data);
$components += Project::getComponents($search_results);

if (count($value) > 0) {
// We have results, we won't display search suggestions but search results
$search_yields_results = true;

$search_id = strtolower(str_replace('-', '', $key));
$message_count = $real_search_results > $limit_results
? "<span class=\"results_count_{$search_id}\">{$limit_results} results</span> out of {$real_search_results}"
: "<span class=\"results_count_{$search_id}\">" . Utils::pluralize(count($search_results), 'result') . '</span>';

$output[$key] = "<h2>Displaying {$message_count} for the string "
. "<span class=\"searchedTerm\">{$initial_search_decoded}</span> in {$key}:</h2>";
$output[$key] .= ShowResults::resultsTable($search_id, $search_results, $initial_search, $source_locale, $locale, $check);
} else {
$output[$key] = "<h2>No matching results for the string "
. "<span class=\"searchedTerm\">{$initial_search_decoded}</span>"
. " for the locale {$key}</h2>";
$search_results = [];

// We loop through all repositories searched and merge results
foreach ($repo_loop as $repository) {
$search->setRepository($repository);
// This is the reference data
$data =[
Utils::getRepoStrings($source_locale, $repository),
Utils::getRepoStrings($locale, $repository)
];

foreach ($search->getResults() as $key => $value) {
$search_results = array_merge($search_results, ShowResults::getTMXResults(array_keys($value), $data));
$components += Project::getComponents($search_results);
if (count($value) > 0) {
// We have results, we won't display search suggestions but search results
$search_yields_results = true;
$search_id = strtolower(str_replace('-', '', $key));
$real_search_results = count($search->getResults()[$key]);

$message_count = $real_search_results > $search->limit
? "<span>{$search->limit} results</span> out of {$real_search_results}"
: "<span>" . Utils::pluralize(count($search_results), 'result') . '</span>';

$output[$key] = "<h2>Displaying {$message_count} for the string "
. "<span class=\"searchedTerm\">{$initial_search_decoded}</span> in {$key}:</h2>";
$output[$key] .= ShowResults::resultsTable($search_id, $search_results, $initial_search, $source_locale, $locale, $check);
} else {
$output[$key] = "<h2>No matching results for the string "
. "<span class=\"searchedTerm\">{$initial_search_decoded}</span>"
. " for the locale {$key}</h2>";
}
}
unset($data);
}

// Remove duplicated components
$components = array_unique($components);

// Display a search hint for the closest string we have if we have no search results
if (! $search_yields_results) {
$merged_strings = [];
Expand All @@ -84,13 +75,17 @@
include VIEWS . 'results_similar.php';

return;
} else {
if (in_array($check['repo'], $desktop_repos)) {
// Build logic to filter components
$javascript_include[] = '/js/component_filter.js';
$filter_block = '';
foreach ($components as $value) {
$filter_block .= " <a href='#{$value}' id='{$value}' class='filter'>{$value}</a>";
}
}
}

// Build logic to filter components
$javascript_include[] = 'component_filter.js';
$filter_block = '';

// Remove duplicated components
$components = array_unique($components);

foreach ($components as $value) {
$filter_block .= " <a href='#{$value}' id='{$value}' class='filter'>{$value}</a>";
}

skipped:
12 changes: 10 additions & 2 deletions tests/units/Transvision/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ public function testGetRepositories()
{
$obj = new _Project();
$repos = ['release', 'beta', 'aurora', 'central', 'gaia_2_0',
'gaia_2_1', 'gaia', 'mozilla_org', ];
'gaia_2_1', 'gaia', 'mozilla_org'];
$this
->array($obj->getRepositories())
->isEqualTo($repos);
$repos[] = 'global';
$this
->array($obj->getRepositories(true))
->isEqualTo($repos);
}

public function testGetRepositoriesNames()
Expand All @@ -51,6 +55,7 @@ public function testGetRepositoriesNames()
'gaia_2_1' => 'Gaia 2.1',
'gaia' => 'Gaia Master',
'mozilla_org' => 'mozilla.org',
'global' => 'All repositories',
];
$this
->array($obj->getRepositoriesNames())
Expand Down Expand Up @@ -97,7 +102,7 @@ public function testGetRepositoryLocales($a, $b)
public function getLocaleRepositoriesDP()
{
return [
['fr', ['central', 'mozilla_org']],
['fr', ['central', 'mozilla_org',]],
['foobar', []],
];
}
Expand Down Expand Up @@ -130,6 +135,9 @@ public function testIsValidRepository()
$this
->boolean($obj->isValidRepository('central'))
->isEqualTo(true);
$this
->boolean($obj->isValidRepository('global'))
->isEqualTo(true);
$this
->boolean($obj->isValidRepository('foo'))
->isEqualTo(false);
Expand Down

0 comments on commit 4ead132

Please sign in to comment.