diff --git a/ChillMainBundle.php b/ChillMainBundle.php
index f634c436b..ba3afd7af 100644
--- a/ChillMainBundle.php
+++ b/ChillMainBundle.php
@@ -3,7 +3,14 @@
namespace Chill\MainBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Chill\MainBundle\DependencyInjection\SearchableServicesCompilerPass;
class ChillMainBundle extends Bundle
{
+ public function build(ContainerBuilder $container)
+ {
+ parent::build($container);
+ $container->addCompilerPass(new SearchableServicesCompilerPass());
+ }
}
diff --git a/Controller/SearchController.php b/Controller/SearchController.php
new file mode 100644
index 000000000..280292082
--- /dev/null
+++ b/Controller/SearchController.php
@@ -0,0 +1,48 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\MainBundle\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ *
+ *
+ * @author julien.fastre@champs-libres.coop
+ * @author marc@champs-libres.coop
+ */
+
+class SearchController extends Controller
+{
+ public function searchAction(Request $request)
+ {
+ $searches = $this->get('chill.main.search_provider')->getByOrder();
+ $results = array();
+
+ foreach ($searches as $search ) {
+ $results[] = $search->renderResult($request->get('q'));
+ }
+
+ return $this->render('ChillMainBundle:Search:list.html.twig', array('results' => $results) );
+ }
+}
\ No newline at end of file
diff --git a/DependencyInjection/SearchableServicesCompilerPass.php b/DependencyInjection/SearchableServicesCompilerPass.php
new file mode 100644
index 000000000..ed2903cc5
--- /dev/null
+++ b/DependencyInjection/SearchableServicesCompilerPass.php
@@ -0,0 +1,73 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+namespace Chill\MainBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Reference;
+
+class SearchableServicesCompilerPass implements CompilerPassInterface
+{
+
+ /*
+ * (non-PHPdoc)
+ * @see \Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface::process()
+ */
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition('chill.main.search_provider')) {
+ throw new \LogicException('service chill.main.search_provider '
+ . 'is not defined.');
+ }
+
+ $definition = $container->getDefinition(
+ 'chill.main.search_provider'
+ );
+
+ $taggedServices = $container->findTaggedServiceIds(
+ 'chill.search'
+ );
+
+ $knownAliases = array();
+
+ foreach ($taggedServices as $id => $tagAttributes) {
+
+ foreach ($tagAttributes as $attributes) {
+
+ if (!isset($attributes["alias"])) {
+ throw new \LogicException("the 'name' attribute is missing in your ".
+ "service '$id' definition");
+ }
+
+ if (array_search($attributes["alias"], $knownAliases)) {
+ throw new \LogicException("There is already a chill.search service with alias "
+ .$attributes["alias"].". Choose another alias.");
+ }
+ $knownAliases[] = $attributes["alias"];
+
+ $definition->addMethodCall(
+ 'addSearchService',
+ array(new Reference($id), $attributes["alias"])
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml
index eb9979aa5..331f4ae21 100644
--- a/Resources/config/routing.yml
+++ b/Resources/config/routing.yml
@@ -28,6 +28,10 @@ chill_main_admin_central:
order: 20
label: Admin Menu
icons: [gears]
+
+chill_main_search:
+ pattern: /{_locale}/person/search
+ defaults: { _controller: ChillMainBundle:Search:search }
login:
path: /login
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index e6035a508..93cd62958 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -54,3 +54,7 @@ services:
- "@request_stack"
tags:
- { name: form.type, alias: select2_chill_country }
+
+ chill.main.search_provider:
+ class: Chill\MainBundle\Search\SearchProvider
+
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 3a016743d..915538c9f 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -1,4 +1,4 @@
-Search a person: Rechercher une personne
+Search: Rechercher
Person name: Nom / Prénom de la personne
Login: Connexion
Logout: Se déconnecter
diff --git a/Resources/views/Search/list.html.twig b/Resources/views/Search/list.html.twig
new file mode 100644
index 000000000..0f633263f
--- /dev/null
+++ b/Resources/views/Search/list.html.twig
@@ -0,0 +1,25 @@
+{#
+ * Copyright (C) 2014, Champs Libres Cooperative SCRLFS,
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+#}
+{% extends "ChillMainBundle::layout.html.twig" %}
+
+{% block content %}
+
+{% for result in results %}
+{{ result|raw }}
+{% endfor %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/Resources/views/layout.html.twig b/Resources/views/layout.html.twig
index f0fd78dba..66c6c41a7 100644
--- a/Resources/views/layout.html.twig
+++ b/Resources/views/layout.html.twig
@@ -32,8 +32,8 @@
-
diff --git a/Search/AbstractSearch.php b/Search/AbstractSearch.php
new file mode 100644
index 000000000..b39b20dc8
--- /dev/null
+++ b/Search/AbstractSearch.php
@@ -0,0 +1,38 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\MainBundle\Search;
+
+use Chill\MainBundle\Search\SearchInterface;
+
+/**
+ * This class implements abstract search with most common responses.
+ *
+ * you should use this abstract class instead of SearchInterface : if the signature of
+ * search interface change, the generic method will be implemented here.
+ *
+ * @author Julien Fastré
+ *
+ */
+abstract class AbstractSearch implements SearchInterface
+{
+
+}
\ No newline at end of file
diff --git a/Search/SearchInterface.php b/Search/SearchInterface.php
new file mode 100644
index 000000000..c102f229e
--- /dev/null
+++ b/Search/SearchInterface.php
@@ -0,0 +1,76 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\MainBundle\Search;
+
+/**
+ * This interface must be implemented on services which provide search results.
+ *
+ * @todo : write doc and add a link to documentation
+ *
+ * @author Julien Fastré
+ *
+ */
+interface SearchInterface #-> good name ?
+{
+ /*
+ * return the result in a html string. The string will be inclued (as raw)
+ * into a global view.
+ *
+ * The global view may be :
+ * {% for result as resultsFromDifferentSearchInterface %}
+ * {{ result|raw }}
+ * {% endfor %}
+ *
+ * @param string $pattern the string to search
+ * @param int $start the first result (for pagination)
+ * @param int $limit the number of result (for pagination)
+ * @param array $option the options, specific for each search
+ * @return string, an HTML string
+ */
+ public function renderResult($pattern, $start=0, $limit=50, array $options = array());
+
+ /*
+ * we may desactive the search interface by default. in this case,
+ * the search will be launch and rendered only with "advanced search"
+ *
+ * this may be activated/desactived from bundle definition in config.yml
+ *
+ * @return boolean
+ */
+ public function isActiveByDefault();
+
+ /*
+ * a string used in advanced search to activate the search
+ *
+ * @return string a string which will be translated by twig
+ */
+ public function getLabel();
+
+ /*
+ * the order in which the results will appears in the global view
+ *
+ * (this may be eventually defined in config.yml)
+ *
+ * @return int
+ */
+ public function getOrder();
+}
diff --git a/Search/SearchProvider.php b/Search/SearchProvider.php
new file mode 100644
index 000000000..fcf24dd06
--- /dev/null
+++ b/Search/SearchProvider.php
@@ -0,0 +1,58 @@
+get('chill.main.search_provider')
+ */
+class SearchProvider
+{
+ /**
+ *
+ * @var SearchInterface[]
+ */
+ private $searchServices = array();
+
+ /*
+ * return search services in an array, ordered by
+ * the order key (defined in service definition)
+ * the conflicts in keys (twice the same order) are resolved
+ * within the compiler : the function will preserve all services
+ * defined (if two services have the same order, the will increment
+ * the order of the second one.
+ *
+ * @return SearchInterface[], with an int as array key
+ */
+ public function getByOrder()
+ {
+ //sort the array
+ uasort($this->searchServices, function(SearchInterface $a, SearchInterface $b) {
+ if ($a->getOrder() == $b->getOrder()) {
+ return 0;
+ }
+ return ($a->getOrder() < $b->getOrder()) ? -1 : 1;
+ });
+
+ return $this->searchServices;
+ }
+
+ /*
+ * return search services with a specific name, defined in service
+ * definition.
+ *
+ * @return SearchInterface
+ */
+ public function getByName($name)
+ {
+ return $this->searchServices[$name];
+ }
+
+ public function addSearchService(SearchInterface $service, $name)
+ {
+ $this->searchServices[$name] = $service;
+ }
+}
\ No newline at end of file