add search possibility throught all bundles, and remove deps between mainbundle and person bundle.

refs #223
This commit is contained in:
Julien Fastré 2014-11-25 14:49:15 +01:00
parent 27903423da
commit 51d6bed43d
11 changed files with 336 additions and 3 deletions

View File

@ -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());
}
}

View File

@ -0,0 +1,48 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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) );
}
}

View File

@ -0,0 +1,73 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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"])
);
}
}
}
}

View File

@ -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

View File

@ -54,3 +54,7 @@ services:
- "@request_stack"
tags:
- { name: form.type, alias: select2_chill_country }
chill.main.search_provider:
class: Chill\MainBundle\Search\SearchProvider

View File

@ -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

View File

@ -0,0 +1,25 @@
{#
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
#}
{% extends "ChillMainBundle::layout.html.twig" %}
{% block content %}
{% for result in results %}
{{ result|raw }}
{% endfor %}
{% endblock %}

View File

@ -32,8 +32,8 @@
</ul>
</div>
<div class="grid-4 navigation-search">
<form action="{{ path('chill_person_search') }}" method="get">
<input name="q" type="search" placeholder="{{ 'Search a person'|trans }}" />
<form action="{{ path('chill_main_search') }}" method="get">
<input name="q" type="search" placeholder="{{ 'Search'|trans }}" />
<button type="submit" class="sc-button white border"><i class="fa fa-search"></i></button>
</form>
</div>

38
Search/AbstractSearch.php Normal file
View File

@ -0,0 +1,38 @@
<?php
/*
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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é <julien.fastre@champs-libres.coop>
*
*/
abstract class AbstractSearch implements SearchInterface
{
}

View File

@ -0,0 +1,76 @@
<?php
/*
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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é <julien.fastre@champs-libres.coop>
*
*/
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();
}

58
Search/SearchProvider.php Normal file
View File

@ -0,0 +1,58 @@
<?php
namespace Chill\MainBundle\Search;
use Chill\MainBundle\Search\SearchInterface;
/**
* a service which gather all search services defined into the bundles
* installed into the app.
* the service is callable from the container with
* $container->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;
}
}