mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-10 11:33:17 +00:00
[SearchEngine] Add support for queries by date
This commit is contained in:
@@ -23,6 +23,7 @@ use Alchemy\Phrasea\Core\Provider\GeonamesServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ORMServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TaskManagerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\UnicodeServiceProvider;
|
||||
use FFMpeg\FFMpegServiceProvider;
|
||||
use Grom\Silex\ImagineServiceProvider;
|
||||
use MediaVorus\MediaVorusServiceProvider;
|
||||
@@ -135,6 +136,7 @@ class Application extends SilexApplication
|
||||
$this->register(new TaskManagerServiceProvider());
|
||||
$this->register(new UnoconvServiceProvider());
|
||||
$this->register(new UrlGeneratorServiceProvider());
|
||||
$this->register(new UnicodeServiceProvider());
|
||||
$this->register(new ValidatorServiceProvider());
|
||||
$this->register(new XPDFServiceProvider());
|
||||
|
||||
|
@@ -24,7 +24,7 @@ use Alchemy\Phrasea\Controller\Admin\Fields;
|
||||
use Alchemy\Phrasea\Controller\Admin\Publications;
|
||||
use Alchemy\Phrasea\Controller\Admin\Root;
|
||||
use Alchemy\Phrasea\Controller\Admin\Setup;
|
||||
use Alchemy\Phrasea\Controller\Admin\Sphinx;
|
||||
use Alchemy\Phrasea\Controller\Admin\SearchEngine;
|
||||
use Alchemy\Phrasea\Controller\Admin\Subdefs;
|
||||
use Alchemy\Phrasea\Controller\Admin\TaskManager;
|
||||
use Alchemy\Phrasea\Controller\Admin\Users;
|
||||
@@ -123,7 +123,7 @@ return call_user_func(function($environment = null) {
|
||||
$app->mount('/admin/databox', new Databox());
|
||||
$app->mount('/admin/databoxes', new Databoxes());
|
||||
$app->mount('/admin/setup', new Setup());
|
||||
$app->mount('/admin/sphinx', new Sphinx());
|
||||
$app->mount('/admin/search-engine', new SearchEngine());
|
||||
$app->mount('/admin/connected-users', new ConnectedUsers());
|
||||
$app->mount('/admin/publications', new Publications());
|
||||
$app->mount('/admin/users', new Users());
|
||||
|
@@ -83,7 +83,7 @@ class Setup implements ControllerProviderInterface
|
||||
*/
|
||||
public function getGlobals(Application $app, Request $request)
|
||||
{
|
||||
require_once __DIR__ . "/../../../../conf.d/_GV_template.inc";
|
||||
$GV = require_once __DIR__ . "/../../../../conf.d/_GV_template.inc";
|
||||
|
||||
if (null !== $update = $request->query->get('update')) {
|
||||
if (!!$update) {
|
||||
@@ -110,10 +110,14 @@ class Setup implements ControllerProviderInterface
|
||||
public function postGlobals(Application $app, Request $request)
|
||||
{
|
||||
if (\setup::create_global_values($app, $request->request->all())) {
|
||||
return $app->redirect('/admin/globals/?success=1');
|
||||
return $app->redirect($app['url_generator']->generate('setup_display_globals', array(
|
||||
'success' => 1
|
||||
)));
|
||||
}
|
||||
|
||||
return $app->redirect('/admin/globals/?success=0');
|
||||
return $app->redirect($app['url_generator']->generate('setup_display_globals', array(
|
||||
'success' => 0
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -11,7 +11,8 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Controller\Prod;
|
||||
|
||||
use Silex\Application;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Silex\Application as SilexApplication;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
@@ -25,7 +26,7 @@ use Alchemy\Phrasea\Helper;
|
||||
class Root implements ControllerProviderInterface
|
||||
{
|
||||
|
||||
public function connect(Application $app)
|
||||
public function connect(SilexApplication $app)
|
||||
{
|
||||
$controllers = $app['controllers_factory'];
|
||||
|
||||
@@ -122,7 +123,7 @@ class Root implements ControllerProviderInterface
|
||||
'thesau_js_list' => $thjslist,
|
||||
'thesau_json_sbas' => json_encode($sbas),
|
||||
'thesau_json_bas2sbas' => json_encode($bas2sbas),
|
||||
'thesau_languages' => \User_Adapter::avLanguages(),
|
||||
'thesau_languages' => $app->getAvailableLanguages(),
|
||||
));
|
||||
});
|
||||
|
||||
|
29
lib/Alchemy/Phrasea/Core/Provider/UnicodeServiceProvider.php
Normal file
29
lib/Alchemy/Phrasea/Core/Provider/UnicodeServiceProvider.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2012 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class UnicodeServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['unicode'] = $app->share(function($app) {
|
||||
return new \unicode();
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine;
|
||||
|
||||
abstract class AbstractConfigurationPanel implements ConfigurationPanelInterface
|
||||
{
|
||||
abstract public function getName();
|
||||
|
||||
public function getConfigPathFile()
|
||||
{
|
||||
return __DIR__ . '/../../../../config/'.$this->getName().'.json';
|
||||
}
|
||||
|
||||
public function getAvailableDateFields($databoxes)
|
||||
{
|
||||
$date_fields = array();
|
||||
|
||||
foreach ($databoxes as $databox) {
|
||||
foreach($databox->get_meta_structure() as $field) {
|
||||
if ($field->get_type() !== \databox_field::TYPE_DATE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$date_fields[] = $field->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return $date_fields;
|
||||
}
|
||||
}
|
@@ -3,10 +3,10 @@
|
||||
namespace Alchemy\Phrasea\SearchEngine\Phrasea;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\SearchEngine\ConfigurationPanelInterface;
|
||||
use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
class ConfigurationPanel extends AbstractConfigurationPanel
|
||||
{
|
||||
protected $charsets;
|
||||
protected $searchEngine;
|
||||
@@ -16,13 +16,57 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
$this->searchEngine = $engine;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'phrasea-engine';
|
||||
}
|
||||
|
||||
public function get(Application $app, Request $request)
|
||||
{
|
||||
return $app['twig']->render('admin/search-engine/phrasea.html.twig', array());
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
$params = array(
|
||||
'configuration' => $configuration,
|
||||
'date_fields' => $this->getAvailableDateFields($app['phraseanet.appbox']->get_databoxes()),
|
||||
'available_sort'=> $this->searchEngine->getAvailableSort(),
|
||||
);
|
||||
|
||||
return $app['twig']->render('admin/search-engine/phrasea.html.twig', $params);
|
||||
}
|
||||
|
||||
public function post(Application $app, Request $request)
|
||||
{
|
||||
$configuration = $this->getConfiguration();
|
||||
$configuration['date_fields'] = array();
|
||||
|
||||
foreach ($request->request->get('date_fields', array()) as $field) {
|
||||
$configuration['date_fields'][] = $field;
|
||||
}
|
||||
|
||||
$configuration['default_sort'] = $request->request->get('default_sort');
|
||||
|
||||
file_put_contents($this->getConfigPathFile(), json_encode($configuration));
|
||||
|
||||
return $app->redirect($app['url_generator']->generate('admin_searchengine_get'));
|
||||
}
|
||||
|
||||
public function getConfiguration()
|
||||
{
|
||||
$configuration = @json_decode(file_get_contents(__DIR__ . '/../../../../../config/phrasea-engine.json'), true);
|
||||
|
||||
if (!is_array($configuration)) {
|
||||
$configuration = array();
|
||||
}
|
||||
|
||||
if (!isset($configuration['date_fields'])) {
|
||||
$configuration['date_fields'] = array();
|
||||
}
|
||||
|
||||
if (!isset($configuration['default_sort'])) {
|
||||
$configuration['default_sort'] = null;
|
||||
}
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -21,12 +21,15 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
class PhraseaEngine implements SearchEngineInterface
|
||||
{
|
||||
private $initialized;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var SearchEngineOptions
|
||||
*/
|
||||
private $options;
|
||||
private $app;
|
||||
private $dateFields;
|
||||
private $configuration;
|
||||
private $queries = array();
|
||||
private $arrayq = array();
|
||||
private $colls = array();
|
||||
@@ -44,6 +47,67 @@ class PhraseaEngine implements SearchEngineInterface
|
||||
$this->options = new SearchEngineOptions();
|
||||
}
|
||||
|
||||
public function getAvailableDateFields()
|
||||
{
|
||||
if (!$this->dateFields) {
|
||||
foreach ($this->app['phraseanet.appbox']->get_databoxes() as $databox) {
|
||||
foreach ($databox->get_meta_structure() as $databox_field) {
|
||||
if ($databox_field->get_type() != \databox_field::TYPE_DATE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->dateFields[] = $databox_field->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
$this->dateFields = array_unique($this->dateFields);
|
||||
}
|
||||
|
||||
return $this->dateFields;
|
||||
}
|
||||
|
||||
public function getConfiguration()
|
||||
{
|
||||
if (!$this->configuration) {
|
||||
$this->configuration = $this->configurationPanel()->getConfiguration();
|
||||
}
|
||||
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
public function getDefaultSort()
|
||||
{
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
return $configuration['default_sort'];
|
||||
}
|
||||
|
||||
public function getAvailableSort()
|
||||
{
|
||||
$date_fields = $this->getAvailableDateFields();
|
||||
|
||||
$sort = array('' => _('No sort'));
|
||||
|
||||
foreach ($date_fields as $field) {
|
||||
$sort[$field] = $field;
|
||||
}
|
||||
|
||||
return $sort;
|
||||
}
|
||||
|
||||
public function getAvailableOrder()
|
||||
{
|
||||
return array(
|
||||
'desc' => _('descendant'),
|
||||
'asc' => _('ascendant'),
|
||||
);
|
||||
}
|
||||
|
||||
public function hasStemming()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
if ($this->initialized) {
|
||||
@@ -621,4 +685,5 @@ class PhraseaEngine implements SearchEngineInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -32,6 +32,16 @@ interface SearchEngineInterface
|
||||
|
||||
public function configurationPanel();
|
||||
|
||||
public function getAvailableDateFields();
|
||||
|
||||
public function getAvailableSort();
|
||||
|
||||
public function getDefaultSort();
|
||||
|
||||
public function getAvailableOrder();
|
||||
|
||||
public function hasStemming();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return an array of self::GEM_TYPE_* indexed types
|
||||
|
@@ -2,13 +2,14 @@
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\SphinxSearch;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\ConfigurationPanelInterface;
|
||||
use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
class ConfigurationPanel extends AbstractConfigurationPanel
|
||||
{
|
||||
const DATE_FIELD_PREFIX = 'date_field_';
|
||||
|
||||
protected $charsets;
|
||||
protected $searchEngine;
|
||||
|
||||
@@ -17,6 +18,11 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
$this->searchEngine = $engine;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'sphinx-search';
|
||||
}
|
||||
|
||||
public function get(Application $app, Request $request)
|
||||
{
|
||||
$configuration = $this->getConfiguration();
|
||||
@@ -25,40 +31,77 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
'configuration' => $configuration,
|
||||
'configfile' => $this->generateSphinxConf($app['phraseanet.appbox']->get_databoxes(), $configuration),
|
||||
'charsets' => $this->get_available_charsets(),
|
||||
'date_fields' => $this->getAvailableDateFields($app['phraseanet.appbox']->get_databoxes()),
|
||||
);
|
||||
|
||||
return $app['twig']->render('admin/search-engine/sphinx-search.html.twig', $params);
|
||||
}
|
||||
|
||||
public function getConfiguration()
|
||||
{
|
||||
$configuration = @json_decode(file_get_contents(__DIR__ . '/../../../../../config/sphinx-search.json'), true);
|
||||
|
||||
if ( ! is_array($configuration)) {
|
||||
$configuration = array();
|
||||
}
|
||||
|
||||
if ( ! isset($configuration['charset_tables'])) {
|
||||
$configuration['charset_tables'] = array("common","latin");
|
||||
}
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
public function post(Application $app, Request $request)
|
||||
{
|
||||
$configuration = $this->getConfiguration();
|
||||
$configuration['charset_tables'] = array();
|
||||
$configuration['date_fields'] = array();
|
||||
|
||||
foreach ($request->request->get('charset_tables', array()) as $table) {
|
||||
$configuration['charset_tables'][] = $table;
|
||||
}
|
||||
foreach ($request->request->get('date_fields', array()) as $field) {
|
||||
$configuration['date_fields'][] = $field;
|
||||
}
|
||||
|
||||
file_put_contents(__DIR__ . '/../../../../../config/sphinx-search.json', json_encode($configuration));
|
||||
$configuration['host'] = $request->request->get('host');
|
||||
$configuration['host'] = $request->request->get('port');
|
||||
$configuration['rt_host'] = $request->request->get('rt_host');
|
||||
$configuration['rt_port'] = $request->request->get('rt_port');
|
||||
|
||||
$this->saveConfiguration($configuration);
|
||||
|
||||
return $app->redirect($app['url_generator']->generate('admin_searchengine_get'));
|
||||
}
|
||||
|
||||
public function getConfiguration()
|
||||
{
|
||||
$configuration = @json_decode(file_get_contents($this->getConfigPathFile()), true);
|
||||
|
||||
if (!is_array($configuration)) {
|
||||
$configuration = array();
|
||||
}
|
||||
|
||||
if (!isset($configuration['charset_tables'])) {
|
||||
$configuration['charset_tables'] = array("common", "latin");
|
||||
}
|
||||
|
||||
if (!isset($configuration['date_fields'])) {
|
||||
$configuration['date_fields'] = array();
|
||||
}
|
||||
|
||||
if (!isset($configuration['host'])) {
|
||||
$configuration['host'] = '127.0.0.1';
|
||||
}
|
||||
|
||||
if (!isset($configuration['port'])) {
|
||||
$configuration['port'] = 9306;
|
||||
}
|
||||
|
||||
if (!isset($configuration['rt_host'])) {
|
||||
$configuration['rt_host'] = '127.0.0.1';
|
||||
}
|
||||
|
||||
if (!isset($configuration['rt_port'])) {
|
||||
$configuration['rt_port'] = 9308;
|
||||
}
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
public function saveConfiguration($configuration)
|
||||
{
|
||||
file_put_contents($this->getConfigPathFile(), json_encode($configuration));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get_available_charsets()
|
||||
{
|
||||
if (null !== $this->charsets) {
|
||||
@@ -107,7 +150,7 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
$charsets = explode("\n", $charsets);
|
||||
$last_detect = false;
|
||||
|
||||
for ($i = (count($charsets) - 1); $i >= 0; $i -- ) {
|
||||
for ($i = (count($charsets) - 1); $i >= 0; $i--) {
|
||||
if (trim($charsets[$i]) === '') {
|
||||
unset($charsets[$i]);
|
||||
continue;
|
||||
@@ -156,6 +199,20 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
|
||||
$index_crc = $this->searchEngine->CRCdatabox($databox);
|
||||
|
||||
$date_selects = $date_left_joins = $date_fields = array();
|
||||
foreach ($configuration['date_fields'] as $name) {
|
||||
$field = $databox->get_meta_structure()->get_element_by_name($name);
|
||||
|
||||
$date_fields[] = self::DATE_FIELD_PREFIX . $name;
|
||||
|
||||
if ($field instanceof \databox_field) {
|
||||
$date_selects[] = ", UNIX_TIMESTAMP(d" . $field->get_id() . ".value) as " . self::DATE_FIELD_PREFIX . $name;
|
||||
$date_left_joins[] = " LEFT JOIN metadatas d" . $field->get_id() . " ON (d" . $field->get_id() . ".record_id = r.record_id AND d" . $field->get_id() . ".meta_struct_id = " . $field->get_id() . ")";
|
||||
} else {
|
||||
$date_selects[] = ", null as " . $name;
|
||||
}
|
||||
}
|
||||
|
||||
$conf .= '
|
||||
|
||||
|
||||
@@ -219,7 +276,9 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
UNIX_TIMESTAMP(credate) as created_on, 0 as deleted, \
|
||||
CRC32(CONCAT_WS("_", r.coll_id, s.business)) as crc_coll_business, \
|
||||
s.business \
|
||||
FROM metadatas m, metadatas_structure s, record r \
|
||||
' . implode(" \\\n", $date_selects) . ' \
|
||||
FROM (metadatas m, metadatas_structure s, record r) \
|
||||
' . implode(" \\\n", $date_left_joins) . ' \
|
||||
WHERE m.record_id = r.record_id AND m.meta_struct_id = s.id \
|
||||
AND s.indexable = "1"
|
||||
|
||||
@@ -236,6 +295,12 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
sql_attr_uint = business
|
||||
sql_attr_uint = crc_coll_business
|
||||
sql_attr_timestamp = created_on
|
||||
';
|
||||
foreach ($date_fields as $date_field) {
|
||||
$conf.= " sql_attr_timestamp = $date_field\n";
|
||||
}
|
||||
|
||||
$conf .= '
|
||||
|
||||
sql_attr_multi = uint status from query; SELECT m.id as id, \
|
||||
CRC32(CONCAT_WS("_", ' . $databox->get_sbas_id() . ', s.name)) as name \
|
||||
@@ -329,7 +394,13 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
rt_attr_uint = business
|
||||
rt_attr_uint = crc_coll_business
|
||||
rt_attr_timestamp = created_on
|
||||
rt_attr_multi = status
|
||||
';
|
||||
|
||||
foreach ($date_fields as $date_field) {
|
||||
$conf.= " rt_attr_timestamp = $date_field\n";
|
||||
}
|
||||
|
||||
$conf .= ' rt_attr_multi = status
|
||||
}
|
||||
|
||||
#--------------------------------------
|
||||
@@ -338,13 +409,16 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
source src_documents' . $index_crc . ' : database_cfg' . $index_crc . '
|
||||
{
|
||||
sql_query = \
|
||||
SELECT r.record_id as id, record_id, r.parent_record_id, ' . $databox->get_sbas_id() . ' as sbas_id, \
|
||||
SELECT r.record_id as id, r.record_id, r.parent_record_id, ' . $databox->get_sbas_id() . ' as sbas_id, \
|
||||
CRC32(CONCAT_WS("_", ' . $databox->get_sbas_id() . ', r.coll_id)) as crc_sbas_coll, \
|
||||
CRC32(CONCAT_WS("_", ' . $databox->get_sbas_id() . ', r.record_id)) as crc_sbas_record, \
|
||||
CONCAT_WS("_", ' . $databox->get_sbas_id() . ' , r.coll_id) as sbas_coll, \
|
||||
CRC32(r.type) as crc_type, r.coll_id, \
|
||||
UNIX_TIMESTAMP(credate) as created_on, 0 as deleted \
|
||||
FROM record r
|
||||
UNIX_TIMESTAMP(r.credate) as created_on, 0 as deleted \
|
||||
' . implode(" \\\n", $date_selects) . ' \
|
||||
FROM (record r) \
|
||||
' . implode(" \\\n", $date_left_joins) . ' \
|
||||
WHERE 1
|
||||
|
||||
# documents can be filtered / sorted on each sql_attr
|
||||
sql_attr_uint = record_id
|
||||
@@ -356,6 +430,12 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
sql_attr_uint = crc_type
|
||||
sql_attr_uint = deleted
|
||||
sql_attr_timestamp = created_on
|
||||
';
|
||||
foreach ($date_fields as $date_field) {
|
||||
$conf.= " sql_attr_timestamp = $date_field\n";
|
||||
}
|
||||
|
||||
$conf .= '
|
||||
|
||||
sql_attr_multi = uint status from query; SELECT r.record_id as id, \
|
||||
CRC32(CONCAT_WS("_", ' . $databox->get_sbas_id() . ', s.name)) as name \
|
||||
@@ -443,7 +523,13 @@ class ConfigurationPanel implements ConfigurationPanelInterface
|
||||
rt_attr_uint = crc_type
|
||||
rt_attr_uint = deleted
|
||||
rt_attr_timestamp = created_on
|
||||
rt_attr_multi = status
|
||||
';
|
||||
|
||||
foreach ($date_fields as $date_field) {
|
||||
$conf.= " rt_attr_timestamp = $date_field\n";
|
||||
}
|
||||
|
||||
$conf .= ' rt_attr_multi = status
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
@@ -40,6 +40,8 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $rt_conn;
|
||||
private $dateFields;
|
||||
protected $configuration;
|
||||
protected $configurationPanel;
|
||||
protected $options;
|
||||
protected $app;
|
||||
@@ -69,6 +71,52 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAvailableDateFields()
|
||||
{
|
||||
if (!$this->dateFields) {
|
||||
foreach ($this->app['phraseanet.appbox']->get_databoxes() as $databox) {
|
||||
foreach ($databox->get_meta_structure() as $databox_field) {
|
||||
if ($databox_field->get_type() != \databox_field::TYPE_DATE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->dateFields[] = $databox_field->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
$this->dateFields = array_unique($this->dateFields);
|
||||
}
|
||||
|
||||
return $this->dateFields;
|
||||
}
|
||||
|
||||
public function getDefaultSort()
|
||||
{
|
||||
return 'relevance';
|
||||
}
|
||||
|
||||
public function getAvailableSort()
|
||||
{
|
||||
return array(
|
||||
'relevance' => _('pertinence'),
|
||||
'created_on' => _('date dajout'),
|
||||
'random' => _('aleatoire'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getAvailableOrder()
|
||||
{
|
||||
return array(
|
||||
'desc' => _('descendant'),
|
||||
'asc' => _('ascendant'),
|
||||
);
|
||||
}
|
||||
|
||||
public function hasStemming()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
if (false === $this->sphinx->Status()) {
|
||||
@@ -99,6 +147,15 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
return $this->configurationPanel;
|
||||
}
|
||||
|
||||
public function getConfiguration()
|
||||
{
|
||||
if (!$this->configuration) {
|
||||
$this->configuration = $this->configurationPanel()->getConfiguration();
|
||||
}
|
||||
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
public function availableTypes()
|
||||
{
|
||||
return array(self::GEM_TYPE_RECORD, self::GEM_TYPE_STORY);
|
||||
@@ -121,6 +178,8 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
}
|
||||
}
|
||||
|
||||
$sql_date_fields = $this->getSqlDateFields($record);
|
||||
|
||||
foreach ($record->get_caption()->get_fields(null, true) as $field) {
|
||||
if (!$field->is_indexable()) {
|
||||
continue;
|
||||
@@ -148,7 +207,9 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
," . (int) $value->getDatabox_field()->isBusiness() . "
|
||||
," . sprintf("%u", crc32($record->get_collection()->get_coll_id() . '_' . (int) $value->getDatabox_field()->isBusiness())) . "
|
||||
," . $record->get_creation_date()->format('U') . "
|
||||
,(" . implode(',', $status) . ") )");
|
||||
" . $sql_date_fields . "
|
||||
,(" . implode(',', $status) . ")
|
||||
)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,13 +226,40 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
," . sprintf("%u", crc32($record->get_type())) . "
|
||||
,0
|
||||
," . $record->get_creation_date()->format('U') . "
|
||||
,(" . implode(',', $status) . ") )";
|
||||
" . $sql_date_fields . "
|
||||
,(" . implode(',', $status) . ")
|
||||
)";
|
||||
|
||||
$this->rt_conn->exec($sql);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getSqlDateFields(\record_adapter $record)
|
||||
{
|
||||
$configuration = $this->getConfiguration();
|
||||
|
||||
$sql_fields = array();
|
||||
|
||||
foreach ($configuration['date_fields'] as $field_name) {
|
||||
|
||||
try {
|
||||
$value = $record->get_caption()->get_field($field_name)->get_serialized_values();
|
||||
} catch (\Exception $e) {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if ($value) {
|
||||
$date = \DateTime::createFromFormat('Y/m/d H:i:s', $this->app['unicode']->parseDate($value));
|
||||
$value = $date->format('U');
|
||||
}
|
||||
|
||||
$sql_fields[] = $value ? : '-1';
|
||||
}
|
||||
|
||||
return ($sql_fields ? ', ' : '') . implode(',', $sql_fields);
|
||||
}
|
||||
|
||||
public function removeRecord(\record_adapter $record)
|
||||
{
|
||||
if (!$this->rt_conn) {
|
||||
@@ -419,6 +507,17 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
$this->sphinx->SetFilter('deleted', array(0));
|
||||
$this->sphinx->SetFilter('parent_record_id', array($options->searchType()));
|
||||
|
||||
if ($options->getDateFields() && ($options->getMaxDate() || $options->getMinDate())) {
|
||||
foreach (array_unique(array_map(function(\databox_field $field) {
|
||||
return $field->get_name();
|
||||
}, $options->getDateFields())) as $field) {
|
||||
|
||||
$min = $options->getMinDate() ? $options->getMinDate()->format('U') : 0;
|
||||
$max = $options->getMaxDate() ? $options->getMaxDate()->format('U') : pow(2, 32);
|
||||
$this->sphinx->SetFilterRange(ConfigurationPanel::DATE_FIELD_PREFIX . $field, $min, $max);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($options->fields()) {
|
||||
|
||||
@@ -829,5 +928,6 @@ class SphinxSearchEngine implements SearchEngineInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -79,8 +79,9 @@ class Installer
|
||||
$this->app['phraseanet.registry']->set($key, $value, \registry::TYPE_STRING);
|
||||
}
|
||||
|
||||
// required to load GV template
|
||||
$app = $this->app;
|
||||
require __DIR__ . '/../../../../lib/conf.d/_GV_template.inc';
|
||||
$GV = require __DIR__ . '/../../../../lib/conf.d/_GV_template.inc';
|
||||
|
||||
foreach ($GV as $section) {
|
||||
foreach ($section['vars'] as $var) {
|
||||
|
@@ -29,13 +29,11 @@ class Migration31 implements MigrationInterface
|
||||
throw new \LogicException('Required config files not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Required for GV :/
|
||||
*/
|
||||
// required to load GV template
|
||||
$app = $this->app;
|
||||
|
||||
require __DIR__ . '/../../../../../../config/_GV.php';
|
||||
require __DIR__ . '/../../../../../../lib/conf.d/_GV_template.inc';
|
||||
$GV = require __DIR__ . '/../../../../../../lib/conf.d/_GV_template.inc';
|
||||
|
||||
$retrieve_old_credentials = function() {
|
||||
require __DIR__ . '/../../../../../../config/connexion.inc';
|
||||
@@ -61,11 +59,6 @@ class Migration31 implements MigrationInterface
|
||||
character_set_server = 'utf8'");
|
||||
|
||||
define('GV_STATIC_URL', '');
|
||||
define('GV_sphinx', false);
|
||||
define('GV_sphinx_host', '');
|
||||
define('GV_sphinx_port', '');
|
||||
define('GV_sphinx_rt_host', '');
|
||||
define('GV_sphinx_rt_port', '');
|
||||
|
||||
$connection->exec("CREATE TABLE IF NOT EXISTS `registry` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
|
@@ -406,6 +406,9 @@ class API_V1_adapter extends API_V1_Abstract
|
||||
'defaultQuery' => $app['phraseanet.registry']->get('GV_defaultQuery'),
|
||||
'defaultQueryType' => $app['phraseanet.registry']->get('GV_defaultQuery_type'),
|
||||
),
|
||||
/**
|
||||
* @todo neutron update this
|
||||
*/
|
||||
'sphinx' => array(
|
||||
'active' => $app['phraseanet.registry']->get('GV_sphinx'),
|
||||
'host' => $app['phraseanet.registry']->get('GV_sphinx_host'),
|
||||
|
@@ -1380,29 +1380,6 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function avLanguages()
|
||||
{
|
||||
$lngs = array();
|
||||
|
||||
$path = __DIR__ . "/../../../locale";
|
||||
if ($hdir = opendir($path)) {
|
||||
while (false !== ($file = readdir($hdir))) {
|
||||
if (substr($file, 0, 1) == "." || strtolower($file) == "cvs")
|
||||
continue;
|
||||
if (is_dir($path . "/" . $file) && strpos($file, '_') == 2 && strlen($file) == 5) {
|
||||
if (!array_key_exists($file, self::$locales))
|
||||
continue;
|
||||
$supFile = explode('_', $file);
|
||||
if (!isset($lngs[$supFile[0]]))
|
||||
$lngs[$supFile[0]] = array();
|
||||
$lngs[$supFile[0]][$file] = array('name' => self::$locales[$file], 'selected' => false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $lngs;
|
||||
}
|
||||
|
||||
public static function get_wrong_email_users(Application $app)
|
||||
{
|
||||
|
||||
|
@@ -146,8 +146,6 @@ interface User_Interface
|
||||
|
||||
public function get_nonce();
|
||||
|
||||
public static function avLanguages();
|
||||
|
||||
public function setPrefs($prop, $value);
|
||||
|
||||
public function getPrefs($prop);
|
||||
|
@@ -1294,11 +1294,12 @@ class databox extends base
|
||||
|
||||
$missing_locale = array();
|
||||
|
||||
$avLanguages = User_Adapter::avLanguages();
|
||||
foreach ($avLanguages as $lang)
|
||||
foreach ($lang as $k => $v)
|
||||
if ( ! isset($TOU[$k]))
|
||||
$missing_locale[] = $k;
|
||||
$avLanguages = $this->app->getAvailableLanguages();
|
||||
foreach ($avLanguages as $code=>$language) {
|
||||
if ( ! isset($TOU[$code])) {
|
||||
$missing_locale[] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
$date_obj = new DateTime();
|
||||
$date = $this->app['date-formatter']->format_mysql($date_obj);
|
||||
|
111
lib/classes/patch/3803.class.php
Normal file
111
lib/classes/patch/3803.class.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2012 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
|
||||
/**
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
class patch_3803 implements patchInterface
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $release = '3.8.0.a3';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
private $concern = array(base::APPLICATION_BOX);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_release()
|
||||
{
|
||||
return $this->release;
|
||||
}
|
||||
|
||||
public function require_all_upgrades()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
public function concern()
|
||||
{
|
||||
return $this->concern;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param base $appbox
|
||||
*/
|
||||
public function apply(base $appbox, Application $app)
|
||||
{
|
||||
$searchEngine = $app['phraseanet.registry']->get('GV_sphinx') ? 'sphinx-search' : 'phrasea';
|
||||
|
||||
$app['phraseanet.registry']->set('GV_search_engine', $searchEngine, \registry::TYPE_ENUM);
|
||||
|
||||
$phraseaConfiguration = null;
|
||||
$phraseaConfigFile = __DIR__ . '/../../../config/phrasea-engine.json';
|
||||
|
||||
if (file_exists($phraseaConfigFile)) {
|
||||
$phraseaConfiguration = json_decode(file_get_contents($phraseaConfigFile), true);
|
||||
}
|
||||
if (!is_array($phraseaConfiguration)) {
|
||||
$phraseaConfiguration = array();
|
||||
}
|
||||
|
||||
if ($app['phraseanet.registry']->get('GV_phrasea_sort')) {
|
||||
$phraseaConfiguration['default_sort'] = $app['phraseanet.registry']->get('GV_phrasea_sort');
|
||||
}
|
||||
|
||||
file_put_contents($phraseaConfigFile, $phraseaConfiguration);
|
||||
|
||||
$sphinxConfiguration = null;
|
||||
$sphinxConfigFile = __DIR__ . '/../../../config/sphinx-search.json';
|
||||
|
||||
if (file_exists($sphinxConfigFile)) {
|
||||
$sphinxConfiguration = json_decode(file_get_contents($sphinxConfigFile), true);
|
||||
}
|
||||
if (!is_array($sphinxConfiguration)) {
|
||||
$sphinxConfiguration = array();
|
||||
}
|
||||
|
||||
if ($app['phraseanet.registry']->get('GV_sphinx_rt_port')) {
|
||||
$sphinxConfiguration['rt_port'] = $app['phraseanet.registry']->get('GV_sphinx_rt_port');
|
||||
}
|
||||
if ($app['phraseanet.registry']->get('GV_sphinx_rt_host')) {
|
||||
$sphinxConfiguration['rt_host'] = $app['phraseanet.registry']->get('GV_sphinx_rt_host');
|
||||
}
|
||||
if ($app['phraseanet.registry']->get('GV_sphinx_port')) {
|
||||
$sphinxConfiguration['port'] = $app['phraseanet.registry']->get('GV_sphinx_port');
|
||||
}
|
||||
if ($app['phraseanet.registry']->get('GV_sphinx_host')) {
|
||||
$sphinxConfiguration['host'] = $app['phraseanet.registry']->get('GV_sphinx_host');
|
||||
}
|
||||
|
||||
file_put_contents($sphinxConfigFile, $sphinxConfiguration);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -75,7 +75,7 @@ class setup
|
||||
|
||||
public static function create_global_values(Application $app, $datas = array())
|
||||
{
|
||||
require(__DIR__ . "/../../lib/conf.d/_GV_template.inc");
|
||||
$GV = require(__DIR__ . "/../../lib/conf.d/_GV_template.inc");
|
||||
|
||||
$debug = $log_errors = false;
|
||||
$vars = array();
|
||||
|
@@ -119,7 +119,6 @@
|
||||
|
||||
if(dest && dest.indexOf('#') !== 0) {
|
||||
$('#right-ajax').empty().addClass('loading').parent().show();
|
||||
$('#right').hide();
|
||||
|
||||
$.get(dest, function(data) {
|
||||
$('#right-ajax').removeClass('loading').html(data);
|
||||
@@ -145,10 +144,7 @@
|
||||
var dest = $(this).attr('href');
|
||||
|
||||
$(this).bind('click',function(){
|
||||
if($(this).hasClass('ajax'))
|
||||
{
|
||||
$('#right-ajax').empty().addClass('loading').parent().show();
|
||||
$('#right').hide();
|
||||
|
||||
$.get(dest, function(data) {
|
||||
$('#right-ajax').removeClass('loading').html(data);
|
||||
@@ -158,12 +154,6 @@
|
||||
enableLink($(el));
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#right-ajax').empty().parent().hide();
|
||||
$('#right').show().addClass('loading').attr('src',dest);
|
||||
}
|
||||
$('#tree .selected').removeClass('selected');
|
||||
$(this).parent().addClass('selected');
|
||||
|
||||
@@ -191,8 +181,6 @@
|
||||
|
||||
function resize()
|
||||
{
|
||||
$('#right').height($(this).height()-$('#mainMenu').height()-20);
|
||||
$('#right').width($('#mainContent').width()-$('#left').width()-20);
|
||||
bodySize.y = $(window).height() - $('#mainMenu').outerHeight();
|
||||
bodySize.x = $(window).width();
|
||||
}
|
||||
@@ -236,7 +224,6 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<iframe class="right PNB10" src="about:blank;" name="right" id="right" frameborder="1" border="0" framespacing="0" style="left:260px;border:none;right:0;{{ notice ? "top:30px" : "top:0" }}"></iframe>
|
||||
<div class="right PNB" style="left:250px;overflow:auto;">
|
||||
<div id="right-ajax" class="PNB10"></div>
|
||||
</div>
|
||||
|
@@ -0,0 +1,16 @@
|
||||
<h1>{% trans 'Phrasea search-engine configuration' %}</h1>
|
||||
|
||||
<form method="post" action="{{ path('admin_searchengine_post') }}">
|
||||
|
||||
<div>{% trans 'Date fields available for search' %}</div>
|
||||
{% for field in date_fields %}
|
||||
<input type="checkbox" name="date_fields[]" value="{{ field }}" {% if field in configuration['date_fields'] %}checked="checked"{% endif %} > {{ field }}
|
||||
{% endfor %}
|
||||
<div>{% trans 'Default sort' %}</div>
|
||||
<select name="default_sort">
|
||||
{% for sort, sort_name in available_sort %}
|
||||
<option value="{{ sort }}" {%if configuration['default_sort'] == sort %}selected="selected"{% endif %}>{{ sort_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit">{% trans 'boutton::valider' %}</button>
|
||||
</form>
|
||||
|
@@ -1,9 +1,26 @@
|
||||
<form method="post">
|
||||
<h1>{% trans 'SphinxSearch search-engine configuration' %}</h1>
|
||||
|
||||
<form method="post" action="{{ path('admin_searchengine_post') }}">
|
||||
<div>{% trans 'Sphinx Search connection configuration' %}</div>
|
||||
|
||||
<div>{% trans 'Sphinx Search server' %}</div>
|
||||
<input type="text" name="host" value="{{ configuration['host'] | default('127.0.0.1') }}"/>
|
||||
<input type="text" name="port" value="{{ configuration['port'] | default('93') }}"/>
|
||||
<div>{% trans 'Sphinx Search RealTime server' %}</div>
|
||||
<input type="text" name="rt_host" value="{{ configuration['rt_host'] }}"/>
|
||||
<input type="text" name="rt_port" value="{{ configuration['rt_port'] }}"/>
|
||||
|
||||
<div>{% trans 'Charset to use for indexation' %}</div>
|
||||
{% for charset, charsetObject in charsets %}
|
||||
<input type="checkbox" name="charset_tables[]" value="{{ charset }}" {% if charset in configuration['charset_tables'] %}checked="checked"{% endif %} > {{ charsetObject.get_name() }}
|
||||
{% endfor %}
|
||||
<br/><br/>
|
||||
<div>{% trans 'Date fields available for search' %}</div>
|
||||
{% for field in date_fields %}
|
||||
<input type="checkbox" name="date_fields[]" value="{{ field }}" {% if field in configuration['date_fields'] %}checked="checked"{% endif %} > {{ field }}
|
||||
{% endfor %}
|
||||
|
||||
<button type="submit">{% trans 'boutton::valider' %}</button>
|
||||
</form>
|
||||
|
||||
<textarea style="width:100%;height:70%">{{ configfile }}</textarea>
|
||||
<textarea style="font-family: monospace;width:90%;height:70%">{{ configfile }}</textarea>
|
@@ -340,32 +340,20 @@
|
||||
<div class="btn-toolbar">
|
||||
<input class="btn btn-inverse" type="button" value="{% trans 'Re-initialiser' %}" onclick="reset_adv_search();" />
|
||||
</div>
|
||||
{% if app['phraseanet.registry'].get('GV_sphinx') %}
|
||||
|
||||
<span>{% trans 'Trier par ' %}</span>
|
||||
<select name="sort" class="input-mini">
|
||||
<option value="relevance">{% trans 'pertinence'%}</option>
|
||||
<option value="created_on">{% trans 'date dajout'%}</option>
|
||||
<option value="random">{% trans 'aleatoire'%}</option>
|
||||
</select>
|
||||
<select name="ord" class="span2">
|
||||
<option value="desc">{% trans 'descendant'%}</option>
|
||||
<option value="asc">{% trans 'ascendant'%}</option>
|
||||
</select>
|
||||
<input type="checkbox" checked="checked" name="stemme" /> {% trans 'rechercher par stemme' %}
|
||||
{% else %}
|
||||
<span>{% trans 'Trier par ' %}</span>
|
||||
<select name="sort" class="input-mini">
|
||||
<option value=""></option>
|
||||
{% for field_id, field in search_datas['fields'] %}
|
||||
{% if field['type'] == 'date' %}
|
||||
<option class="field_switch field_{{field['sbas']|join(' field_')}}" value="{{field_id}}" {% if app['phraseanet.registry'].get('GV_phrasea_sort') == field['fieldname'] %}selected="selected"{% endif %}>{{ field['fieldname'] }}</option>
|
||||
{% endif %}
|
||||
{% for sort, sort_name in app['phraseanet.SE'].getAvailableSort() %}
|
||||
<option value="{{ sort }}" {% if sort == app['phraseanet.SE'].getDefaultSort() %}selected="selected"{% endif %}>{{ sort_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="ord" class="span2">
|
||||
<option value="desc">{% trans 'descendant'%}</option>
|
||||
<option value="asc">{% trans 'ascendant'%}</option>
|
||||
{% for ord, ord_name in app['phraseanet.SE'].getAvailableOrder() %}
|
||||
<option value="{{ ord }}">{{ ord_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if app['phraseanet.SE'].hasStemming() %}
|
||||
<input type="checkbox" checked="checked" name="stemme" /> {% trans 'rechercher par stemme' %}
|
||||
{% endif %}
|
||||
<div class="field_filter">
|
||||
<span>{% trans 'Les termes apparaissent dans le(s) champs' %}</span>
|
||||
@@ -417,8 +405,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% set dates_length = search_datas['dates']|length %}
|
||||
{% if dates_length > 0 %}
|
||||
{% if app['phraseanet.SE'].getAvailableDateFields() | length > 0 %}
|
||||
<hr />
|
||||
<div class="date_filter">
|
||||
<span>{% trans 'Rechercher dans un champ date' %}</span>
|
||||
@@ -426,11 +413,11 @@
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<select name="datefield" class="input-medium">
|
||||
{% for field_id, field in search_datas['dates'] %}
|
||||
{% for field in app['phraseanet.SE'].getAvailableDateFields() %}
|
||||
<option onchange="checkFilters(true);"
|
||||
class="field_switch field_{{field['sbas']|join(' field_')}}" value="{{ field['fieldname'] }}">{{field['fieldname']}}</option>
|
||||
class="" value="{{ field }}">{{ field }}</option>
|
||||
{% endfor %}
|
||||
<option value="{{search_datas['dates']|keys|join('|')}}" selected="selected">
|
||||
<option value="{{configuration['date_fields']|keys|join('|')}}" selected="selected">
|
||||
{% trans 'rechercher dans tous les champs' %}
|
||||
</option>
|
||||
</select>
|
||||
|
@@ -8,6 +8,8 @@ require_once __DIR__ . '/../../../PhraseanetPHPUnitAuthenticatedAbstract.class.i
|
||||
|
||||
abstract class SearchEngineAbstractTest extends \PhraseanetPHPUnitAuthenticatedAbstract
|
||||
{
|
||||
|
||||
protected $options;
|
||||
protected static $searchEngine;
|
||||
protected static $initialized = false;
|
||||
|
||||
@@ -66,9 +68,19 @@ abstract class SearchEngineAbstractTest extends \PhraseanetPHPUnitAuthenticatedA
|
||||
$options = new SearchEngineOptions();
|
||||
$options->onCollections($databox->get_collections());
|
||||
|
||||
$this->options = $options;
|
||||
|
||||
self::$searchEngine->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SearchEngineOptions
|
||||
*/
|
||||
private function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
abstract public function initialize();
|
||||
|
||||
protected function updateIndex()
|
||||
@@ -114,22 +126,141 @@ abstract class SearchEngineAbstractTest extends \PhraseanetPHPUnitAuthenticatedA
|
||||
|
||||
public function testQueryByDateMin()
|
||||
{
|
||||
$this->markTestSkipped('No yet implemented');
|
||||
$record = self::$DI['record_24'];
|
||||
$query_string = 'boomboklot' . $record->get_record_id() . 'dateMin';
|
||||
|
||||
$this->editRecord($query_string, $record);
|
||||
|
||||
$date_field = $this->editDateRecord('2012-12-21 12:12:00', $record);
|
||||
|
||||
if (!$date_field) {
|
||||
$this->markTestSkipped('unable to add a date to record');
|
||||
}
|
||||
|
||||
self::$searchEngine->addRecord($record);
|
||||
$this->updateIndex();
|
||||
|
||||
$options = $this->getOptions();
|
||||
$options->setDateFields(array($date_field));
|
||||
$options->setMinDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-23 01:01:00'));
|
||||
self::$searchEngine->setOptions($options);
|
||||
|
||||
self::$searchEngine->resetCache();
|
||||
$results = self::$searchEngine->query($query_string, 0, 1);
|
||||
$this->assertEquals(0, $results->total());
|
||||
|
||||
$options->setMinDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-20 01:01:00'));
|
||||
self::$searchEngine->setOptions($options);
|
||||
|
||||
self::$searchEngine->resetCache();
|
||||
$results = self::$searchEngine->query($query_string, 0, 1);
|
||||
$this->assertEquals(1, $results->total());
|
||||
}
|
||||
|
||||
private function editDateRecord($date, \record_adapter $record)
|
||||
{
|
||||
$date_field = null;
|
||||
|
||||
foreach ($record->get_databox()->get_meta_structure() as $databox_field) {
|
||||
if ($databox_field->get_type() != \databox_field::TYPE_DATE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$date_field = $databox_field;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($date_field) {
|
||||
|
||||
$toupdate = array();
|
||||
|
||||
try {
|
||||
$values = $record->get_caption()->get_field($databox_field->get_name())->get_values();
|
||||
$value = array_pop($values);
|
||||
$meta_id = $value->getId();
|
||||
} catch (\Exception $e) {
|
||||
$meta_id = null;
|
||||
}
|
||||
|
||||
$toupdate[$databox_field->get_id()] = array(
|
||||
'meta_id' => $meta_id
|
||||
, 'meta_struct_id' => $databox_field->get_id()
|
||||
, 'value' => $date
|
||||
);
|
||||
|
||||
$record->set_metadatas($toupdate);
|
||||
}
|
||||
|
||||
|
||||
return $date_field;
|
||||
}
|
||||
|
||||
public function testQueryByDateMax()
|
||||
{
|
||||
$this->markTestSkipped('No yet implemented');
|
||||
$record = self::$DI['record_24'];
|
||||
$query_string = 'boomboklot' . $record->get_record_id() . 'dateMax';
|
||||
|
||||
$this->editRecord($query_string, $record);
|
||||
|
||||
$date_field = $this->editDateRecord('2012-12-21 12:12:00', $record);
|
||||
|
||||
if (!$date_field) {
|
||||
$this->markTestSkipped('unable to add a date to record');
|
||||
}
|
||||
|
||||
self::$searchEngine->addRecord($record);
|
||||
$this->updateIndex();
|
||||
|
||||
$options = $this->getOptions();
|
||||
$options->setDateFields(array($date_field));
|
||||
$options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-20 01:01:00'));
|
||||
self::$searchEngine->setOptions($options);
|
||||
|
||||
self::$searchEngine->resetCache();
|
||||
$results = self::$searchEngine->query($query_string, 0, 1);
|
||||
$this->assertEquals(0, $results->total());
|
||||
|
||||
$options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-23 01:01:00'));
|
||||
self::$searchEngine->setOptions($options);
|
||||
|
||||
self::$searchEngine->resetCache();
|
||||
$results = self::$searchEngine->query($query_string, 0, 1);
|
||||
$this->assertEquals(1, $results->total());
|
||||
}
|
||||
|
||||
public function testQueryByDateRange()
|
||||
{
|
||||
$this->markTestSkipped('No yet implemented');
|
||||
$record = self::$DI['record_24'];
|
||||
$query_string = 'boomboklot' . $record->get_record_id() . 'dateRange';
|
||||
|
||||
$this->editRecord($query_string, $record);
|
||||
|
||||
$date_field = $this->editDateRecord('2012-12-21 12:12:00', $record);
|
||||
|
||||
if (!$date_field) {
|
||||
$this->markTestSkipped('unable to add a date to record');
|
||||
}
|
||||
|
||||
public function testQueryInField()
|
||||
{
|
||||
$this->markTestSkipped('No yet implemented');
|
||||
self::$searchEngine->addRecord($record);
|
||||
$this->updateIndex();
|
||||
|
||||
$options = $this->getOptions();
|
||||
$options->setDateFields(array($date_field));
|
||||
$options->setMinDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-18 01:01:00'));
|
||||
$options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-20 01:01:00'));
|
||||
self::$searchEngine->setOptions($options);
|
||||
|
||||
self::$searchEngine->resetCache();
|
||||
$results = self::$searchEngine->query($query_string, 0, 1);
|
||||
$this->assertEquals(0, $results->total());
|
||||
|
||||
$options->setMaxDate(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-12-22 01:01:00'));
|
||||
self::$searchEngine->setOptions($options);
|
||||
|
||||
self::$searchEngine->resetCache();
|
||||
$results = self::$searchEngine->query($query_string, 0, 1);
|
||||
$this->assertEquals(1, $results->total());
|
||||
}
|
||||
|
||||
protected function editRecord($string2add, \record_adapter &$record, $indexable = true, $business = false)
|
||||
|
@@ -23,7 +23,23 @@ class SphinxSearchEngineTest extends SearchEngineAbstractTest
|
||||
self::$searchEngine = new SphinxSearchEngine($app, '127.0.0.1', 19306, '127.0.0.1', 19308);
|
||||
|
||||
self::$config = tempnam(sys_get_temp_dir(), 'tmp_sphinx.conf');
|
||||
$configFile = self::$searchEngine->configurationPanel()->generateSphinxConf($appbox->get_databoxes(), self::$searchEngine->configurationPanel()->getConfiguration());
|
||||
$configuration = self::$searchEngine->configurationPanel()->getConfiguration();
|
||||
$configuration['date_fields'] = array();
|
||||
|
||||
foreach($appbox->get_databoxes() as $databox) {
|
||||
foreach ($databox->get_meta_structure() as $databox_field) {
|
||||
if ($databox_field->get_type() != \databox_field::TYPE_DATE) {
|
||||
continue;
|
||||
}
|
||||
$configuration['date_fields'][] = $databox_field->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
$configuration['date_fields'] = array_unique($configuration['date_fields']);
|
||||
|
||||
self::$searchEngine->configurationPanel()->saveConfiguration($configuration);
|
||||
|
||||
$configFile = self::$searchEngine->configurationPanel()->generateSphinxConf($appbox->get_databoxes(), $configuration);
|
||||
|
||||
file_put_contents(self::$config, $configFile);
|
||||
|
||||
|
@@ -53,9 +53,11 @@ $obr = explode(';', $parm['obr']);
|
||||
$t_lng = array();
|
||||
|
||||
if ($parm['ofm'] == 'tofiles') {
|
||||
$t = User_Adapter::avLanguages();
|
||||
foreach ($t as $lng_code => $lng)
|
||||
foreach (Application::getAvailableLanguages() as $lng_code => $lng) {
|
||||
$lng_code = explode('_', $lng_code);
|
||||
$lng_code = $lng_code[0];
|
||||
$t_lng[] = $lng_code;
|
||||
}
|
||||
} else {
|
||||
$t_lng[] = $parm['piv'];
|
||||
}
|
||||
|
@@ -129,8 +129,9 @@ if ($nbases > 0) {
|
||||
}
|
||||
|
||||
$nf = 0;
|
||||
$tlng = User_Adapter::avLanguages();
|
||||
foreach ($tlng as $lng_code => $lng) {
|
||||
foreach (Application::getAvailableLanguages() as $lng_code => $lng) {
|
||||
$lng_code = explode('_', $lng_code);
|
||||
$lng_code = $lng_code[0];
|
||||
printf("<tr><td>%s</td>", $nf == 0 ? p4string::MakeString(_('thesaurus:: langue pivot')) /* Langue pivot : */ : "");
|
||||
print("<td style=\"text-align:left\"><input type='radio' onclick=\"ckok();return(true);\" value='$lng_code' name='piv'><img src='/skins/lng/" . $lng_code . "_flag_18.gif' /> (" . $lng_code . ")</td></tr>\n");
|
||||
$nf ++;
|
||||
|
@@ -97,8 +97,9 @@ switch ($parm["typ"]) {
|
||||
<td></td>
|
||||
<td valign="bottom">
|
||||
<?php
|
||||
$tlng = User_Adapter::avLanguages();
|
||||
foreach ($tlng as $lng_code => $lng) {
|
||||
foreach (Application::getAvailableLanguages() as $lng_code => $lng) {
|
||||
$lng_code = explode('_', $lng_code);
|
||||
$lng_code = $lng_code[0];
|
||||
$ck = $lng_code == $parm["piv"] ? " checked" : "";
|
||||
?>
|
||||
<span style="display:inline-block">
|
||||
|
@@ -78,8 +78,9 @@ if ($parm["dlg"]) {
|
||||
<div class="menu" id="flagsMenu" style="z-index:50">
|
||||
<?php
|
||||
// on liste tous les drapeaux
|
||||
$tlng = User_Adapter::avLanguages();
|
||||
foreach ($tlng as $lng_code => $lng) {
|
||||
foreach ($app->getAvailableLanguages() as $lng_code => $lng) {
|
||||
$lng_code = explode('_', $lng_code);
|
||||
$lng_code = $lng_code[0];
|
||||
print("<a id='flagMenu_$lng_code' href='javascript:void(0)' class=''><img src='/skins/lng/" . $lng_code . "_flag_18.gif' />$lng_code</a>");
|
||||
}
|
||||
?>
|
||||
|
@@ -190,8 +190,9 @@ User_Adapter::updateClientInfos($app, 5);
|
||||
<?php
|
||||
// on liste tous les drapeaux
|
||||
$jsFlags = "";
|
||||
$tlng = User_Adapter::avLanguages();
|
||||
foreach ($tlng as $lng_code => $lng) {
|
||||
foreach (Application::getAvailableLanguages() as $lng_code => $lng) {
|
||||
$lng_code = explode('_', $lng_code);
|
||||
$lng_code = $lng_code[0];
|
||||
if (file_exists("/skins/lng/" . $lng_code . "_flag_18.gif") && ($s = getimagesize("/skins/lng/" . $lng_code . "_flag_18.gif") )) {
|
||||
printf("\t<img id='flagMenu_%s' src='/skins/lng/%s_flag_18.gif' />\n", $lng_code, $lng_code);
|
||||
|
||||
|
Reference in New Issue
Block a user