Merge branch 'master' of github.com:Chill-project/Documentation

This commit is contained in:
Marc Ducobu
2015-01-27 16:44:44 +01:00
19 changed files with 1137 additions and 139 deletions

View File

@@ -1,119 +0,0 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Custom fields bundle
====================
This bundle provide the ability to add custom fields to existing entities.
Those custom fields contains extra data and will be stored in the DB, along with other data's entities. It may be string, text, date, ... or a link to an existing or to-be-created other entities.
In the database, custom fields are stored in json format.
.. seealso::
The full specification discussed `here. <https://redmine.champs-libres.coop/issues/239>`_
`JSON Type on postgresql documentation <http://www.postgresql.org/docs/9.3/static/datatype-json.html>`_
Custom Fields concepts
----------------------
.. warning::
This section is incomplete
Allow custom fields on a entity
--------------------------------
As a developer, you may allow your users to add custom fields on your entities.
Create a json field on your entity
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Declare a json field in your database :
.. code-block:: yaml
Chill\CustomFieldsBundle\Entity\BlopEntity:
type: entity
# ...
fields:
customField:
type: json_array
Create the field accordingly :
.. code-block:: php
namespace Chill\CustomFieldsBundle\Entity;
/**
* BlopEntity
*/
class BlopEntity
{
/**
* @var array
*/
private $customField = array();
/**
* This method will be required for the Form component to record the
* custom fields into the class
*
* @param array $customField
* @return BlopEntity
*/
public function setCustomField(array $customField)
{
$this->customField = $customField;
return $this;
}
/**
* Required by Forms to retrieve informations
*
* @return array
*/
public function getCustomField()
{
return $this->customField;
}
Declare your customizable class in configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Two methods are available :
* In your app/config.yml file. This is the easiest method, but discouraged because it will reduce the ease for installation.
* In your Configuration class
In app/config.yml file
""""""""""""""""""""""
Add those file under `chill_custom_fields` section :
.. code-block:: yaml
chill_custom_fields:
customizables_class:
- { class: Chill\CustomFieldsBundle\Entity\BlopEntity, name: blop_entity }
* The `name` allow you to define a string which is translatable. This string will appears when chill's admin will add/retrieve new customFieldsGroup.
* The class, which is a full FQDN class path
.. glossary::
customFieldsGroup
TODO

View File

@@ -1,16 +0,0 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Official bundles documentation
###############################
.. toctree::
:maxdepth: 2
Main Bundle <main.rst>
Custom Fields <custom-fields.rst>

View File

@@ -1,22 +0,0 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Main bundle
###########
This bundle is **required** for running Chill.
This bundle provide :
* Access control model (users, groups, and all concepts)
* ...
.. warning::
this section is incomplete.

View File

@@ -0,0 +1,35 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
.. _flashbags :
Flashbags: message to users
****************************
The four following levels are defined :
+-----------+----------------------------------------------------------------------------------------------+
|Key |Intent |
+===========+==============================================================================================+
|alert |A message not linked with the user action, but which should require an action or a |
| |correction. |
+-----------+----------------------------------------------------------------------------------------------+
|success |The user action succeeds. |
+-----------+----------------------------------------------------------------------------------------------+
|notice |A simple message to give information to the user. The message may be linked or not linked with|
| |the user action. |
+-----------+----------------------------------------------------------------------------------------------+
|warning |A message linked with an action, the user should correct. |
+-----------+----------------------------------------------------------------------------------------------+
|error |The user's action failed: he must correct something to process the action. |
+-----------+----------------------------------------------------------------------------------------------+
.. seealso::
`Flash Messages on Symfony documentation <http://symfony.com/doc/current/book/controller.html#flash-messages>`_
Learn how to use flash messages in controller.

View File

@@ -16,9 +16,14 @@ As Chill rely on the `symfony <http://symfony.com>`_ framework, reading the fram
Install Chill for development <installation.rst>
Instructions to create a new bundle <create-a-new-bundle.rst>
Routing <routing.rst>
Menus <menus.rst>
Message to users <flashbags.rst>
Localisation <localisation.rst>
Database migrations <migrations.rst>
Searching <searching.rst>
Testing <make-test-working.rst>
manual/index.rst
Official bundle's documentation <bundles/index.rst>
Help, I am lost !

View File

@@ -46,13 +46,40 @@ This will install a project. All downloaded modules will be stored in the `/vend
origin git://github.com/Chill-project/Standard.git (fetch)
origin git@github.com:Chill-project/Standard.git (push)
Deleted and added files after installation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Composer will deleted unrequired files, and add some of them. This perfectly normal and will appears in your git index. But you should NOT delete those files.
This should appears :
.. code-block:: bash
$git status
#(...)
Modifications qui ne seront pas validées :
(utilisez "git add/rm <fichier>..." pour mettre à jour ce qui sera validé)
(utilisez "git checkout -- <fichier>..." pour annuler les modifications dans la copie de travail)
modifié: app/SymfonyRequirements.php
supprimé: app/SymfonyStandard/Composer.php
supprimé: app/SymfonyStandard/RootPackageInstallSubscriber.php
modifié: app/check.php
You can ignore the locally using the `git update-index --assume-unchanged` command.
.. code-block:: bash
$ git update-index --assume-unchanged app/check.php
$ git update-index --assume-unchanged app/SymfonyRequirements.php
$ git update-index --assume-unchanged app/SymfonyStandard/Composer.php
$ git update-index --assume-unchanged app/SymfonyStandard/RootPackageInstallSuscriber.php
Working with your own fork
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. warning::
This section has not been tested yet. Feedback wanted.
Ideally, you will work on a fork of the main github repository. To ensure that composer will download the code from **your** repository, you will have to adapt the `composer.json` file accordingly, using your own repository.
Add the following lines to your composer.json file if you want to force composer to download from your own repository. This will force to use your own repository for the ChillMain bundle, insert in `composer.json` the following lines :

View File

@@ -0,0 +1,49 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Localisation
*************
Language in url
===============
Language should be present in URL, conventionnaly as first argument.
.. code-block:: none
/fr/your/url/here
This allow users to change from one language to another one on each page, which may be useful in multilanguages teams. If the installation is single-language, the language switcher will not appears.
This is an example of routing defined in yaml :
.. code-block:: yaml
chill_person_general_edit:
pattern: /{_locale}/person/{person_id}/general/edit
defaults: {_controller: ChillPersonBundle:Person:edit }
Date and time
==============
The `Intl extension <http://twig.sensiolabs.org/doc/extensions/intl.html>`_ is enabled on the Chill application.
You may format date and time using the `localizeddate` function :
.. code-block:: jinja
date|localizeddate('long', 'none')
By default, we prefer using the `long` format for date formatting.
.. seealso::
`Documentation for Intl Extension <http://twig.sensiolabs.org/doc/extensions/intl.html>`_
Read the complete doc for the Intl extension.

View File

@@ -0,0 +1,123 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
.. _menus :
Menus
*****
Chill has created his own menu system
.. seealso::
`Routes dans Chill [specification] <https://redmine.champs-libres.coop/issues/179>`_
The issue wich discussed the implementation of routes.
Concepts
========
.. warning::
to be written
Add a menu in a template
========================
In your twig template, use the `chill_menu` function :
.. code-block:: html+jinja
{{ chill_menu('person', {
'layout': 'ChillPersonBundle::menu.html.twig',
'args' : {'id': person.id },
'activeRouteKey': 'chill_person_view'
}) }}
The available arguments are:
* `layout` : a custom layout. Default to `ChillMainBundle:Menu:defaultMenu.html.twig`
* `args` : those arguments will be passed through the url generator.
* `activeRouteKey` must be the route key name.
.. note::
The argument `activeRouteKey` may be a twig variable, defined elsewhere in your template, even in child templates.
Create an entry in an existing menu
===================================
If a route belongs to a menu, you simply add this to his definition in routing.yml :
.. code-block:: yaml
chill_person_history_list:
pattern: /person/{person_id}/history
defaults: { _controller: ChillPersonBundle:History:list }
options:
#declare menus
menus:
# the route should be in 'person' menu :
person:
#and have those arguments :
order: 100
label: menu.person.history
* `order` (mandatory) : the order in the menu. It is preferrable to increment by far more than 1.
* `label` (mandatory) : a translatable string.
* `helper` (optional) : a text to help people to understand what does the menu do. Not used in default implementation.
* `condition` (optional) : an `Expression Language <http://symfony.com/doc/current/components/expression_language/index.html> `_ which will make the menu appears or not. Typically, it may be used to say "show this menu only if the person concerned is more than 18". **Not implemented yet**.
* `access` (optional) : an Expression Language to evalute the possibility, for the user, to show this menu according to Access Control Model. **Not implemented yet.**
You may add additional keys, but should not use the keys described above.
You may add the same route to multiple menus :
.. code-block:: yaml
chill_person_history_list:
pattern: /person/{person_id}/history
defaults: { _controller: ChillPersonBundle:History:list }
options:
menus:
menu1:
order: 100
label: menu.person.history
menu2:
order: 100
label: another.label
Customize menu rendering
========================
You may customize menu rendering by using the `layout` option.
.. warning ::
TODO : this part should be written.
.. _caveats :
Caveats
=======
Currently, you may pass arguments globally to each menu, and they will be all passed to route url. This means that :
* the argument name in the route entry must match the argument key in menu declaration in twig template
* if an argument is missing to generate an url, the url generator will throw a `Symfony\Component\Routing\Exception\MissingMandatoryParametersException`
* if the argument name is not declared in route entry, it will be added to the url, (example: `/my/route?additional=foo`)

View File

@@ -0,0 +1,100 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Database Migrations
********************
Every bundle potentially brings his own database operations : to persist entities, developers have to create database schema, creating indexes,...
Those schema might be changed (the less is the better) from time to time.
Consequence: each bundle should bring his own migration files, which will bring the database consistent with the operation you will run in your code. They will be gathered into the app installation, ready to be executed by the chill's installer.
Currently, we use `doctrine migration`_ to manage those migration files. A `composer`_ script located in the **chill standard** component will copy the migrations from your bundle to the doctrne migration's excepted directory after each install and/or update operation.
.. seealso::
The `doctrine migration`_ documentation
Learn concepts about migrations files and scripts and the doctrine ORM
The `doctrine migration bundle`_ documentation
Learn about doctrine migration integration with Symfony framework
Shipping migration files
========================
Migrations files should be shipped under the Resource/migrations directory. You could customize the migration directory by adding extra information in your composer.json:
.. code-block:: json
"extra": {
"migration-source": "path/to/my/dir"
}
The class namespace should be `Application\Migrations`, as expected by doctrine migration. Only the files which will be executed by doctrine migration will be moved: they must have the pattern `VersionYYYYMMDDHHMMSS.php` where YYYY is the year, MM the month, DD the day, HH the hour, MM the month and SS the second of creation.
They will be moved automatically by composer when you install or update a bundle.
Executing migration files
==========================
The installers will have to execute migrations files manually, running
.. code-block:: bash
php app/console doctrine:migrations:status #will give the current status of the database
php app/console doctrine:migrations:migrate #process the update
Updating migration files
=========================
.. warning::
After an installation, migration files will be executed and registered as executed in the database (the version timestamp is recorded into the :title:`migrations_versions` table). If you update your migration file code, the file will still be considered as "executed" by doctrine migration, which will not offers the possibility to run the migration again.
Consequently, updating migration file should only be considered during development phase, and not published on public git branches. If you want to edit your database schema, you should create a new migration file, with a new timestamp, which will proceed to your schema adaptations.
Every time a migration file is discovered, the composer'script will check if the migration exists in the local migration directory. If yes, the script will compare two file for changes (using a md5 hash). If migrations are discovered, the script will ask the installer to know if he must replace the file or ignore it.
.. note::
You can manually run composer script by launching `composer run-script post-update-cmd` from your root chill installation's directory.
.. _doctrine migration: http://www.doctrine-project.org/projects/migrations.html
.. _doctrine migration bundle : http://symfony.com/doc/master/bundles/DoctrineMigrationsBundle/index.html
.. _composer : https://getcomposer.org
Tips for development
====================
Migration and data
------------------
Each time you create a migration script, you should ensure that it will not lead to data losing. Eventually, feel free to use intermediate steps.
Generation
----------
You can generate migration file from the command line, using those commands:
* `php app/console doctrine:migrations:diff` to generate a migration file by comparing your current database to your mapping information
* `php app/console doctrine:migrations:generate` to generate a blank migration file.
Those files will be located into `app/DoctrineMigrations` directory. You will have to copy those file to your the directory `Resource/migrations` into your bundle directory.
Comments and documentation
--------------------------
As files are copied from your bundle to the `app/DoctrineMigrations` directory, the link between your bundle and the copied file will be unclear. Please add all relevant documentation which will allow future developers to make a link between your file and your bundle.
Inside the script
-----------------
The script which move the migrations files to app directory `might be found here <https://redmine.champs-libres.coop/projects/chill-standard/repository/changes/app/Composer/Migrations.php?rev=master>`_.

View File

@@ -0,0 +1,68 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Routing
#######
Our goal is to ease the installation of the different bundle. Users should not have to dive into complicated config files to install bundles.
A routing loader available for all bundles
===========================================
A Chill bundle may rely on the Routing Loader defined in ChillMain.
The loader will load `yml` or `xml` files. You simply have to add them into `chill_main` config
.. code-block:: yaml
chill_main:
# ... other stuff here
routing:
resources:
- @ChillMyBundle/Resources/config/routing.yml
Load routes automatically
-------------------------
But this force users to modify config files. To avoid this, you may prepend config implementing the `PrependExtensionInterface` in the `YourBundleExtension` class. This is an example from **chill main** bundle :
.. code-block:: php
namespace Chill\MainBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
class ChillMainExtension extends Extension implements PrependExtensionInterface
{
public function load(array $configs, ContainerBuilder $container)
{
// ...
}
public function prepend(ContainerBuilder $container)
{
//add current route to chill main
//this is where the resource is added automatically in the config
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillMainBundle/Resources/config/routing.yml'
)
)
));
}
}

View File

@@ -0,0 +1,250 @@
.. Copyright (C) 2014 Champs Libres Cooperative SCRLFS
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
Searching
*********
Chill should provide information needed by users when they need it. Searching within bundle, entities,... is an important feature to achieve this goal.
The Main Bundle provide interfaces to ease the developer work. It will also attempt that search will work in the same way accross bundles.
.. contents:: Table of content
:local:
.. seealso::
`Our blog post about searching (in French) <http://blog.champs-libres.coop/vie-des-champs/2015/01/06/va-chercher-chill-la-recherche-dans-chill-logiciel-libre-service-social.html>`_
This blog post give some information for end-users about searching.
`The issue about search behaviour <https://redmine.champs-libres.coop/issues/377>`_
Where the search behaviour is defined.
Searching in a glance for developers
====================================
Chill suggests to use an easy-to-learn language search.
.. note::
We are planning to provide a form to create automatically search pattern according to this language. Watch the `issue regarding this feature <https://redmine.champs-libres.coop/issues/389>`_.
The language is an association of search terms. Search terms may contains :
- **a domain**: this is "the domain you want to search" : it may some entities like people, reports, ... Example : `@person` to search accross people, `@report` to browse reports, ... The search pattern may have **a maximum of one** domain by search, providing more should throw an error, and trigger a warning for users.
- **arguments and their values** : This is "what you search". Arguments narrow the search to specific fields : username, date of birth, nationality, ... The syntax is `argument:value`. I.e.: ` birthdate:2014-12-15`, `firstname:Depardieu`, ... **Arguments are optional**. If the value of an argument contains spaces or characters like punctuation, quotes ("), the value should be provided between parenthesis : `firstname:(Van de snoeck)`, `firstname:(M'bola)`, ...
- **default value** : this the "rest" of the search, not linked with any arguments or domain. Example : `@person dep` (`dep` is the "default value"), or simply `dep` if any domain is provided (which is perfectly acceptable). If a string is not idenfied as argument or domain, it will be present in the "default" term.
If a search pattern (provided by the user) does not contains any domain, the search must be run across default domain/search modules.
A domain may be supported by different search modules. For instance, if you provide the domain `@person`, the end-user may receive results of exact firstname/lastname, but also result with spelling suggestion, ... **But** if results do not fit into the first page (if you have 75 results and the screen show only 50 results), the next page should contains only the results from the required module.
For instance : a user search across people by firstname/lastname, the exact spelling contains 10 results, the "spelling suggestion" results contains 75 names, but show only the first 50. If the user want to see the last 25, the next screen should not contains the results by firstname/lastname.
Allowed characters as arguments
===============================
In order to execute regular expression, the allowed chararcters in arguments are a-z characters, numbers, and the sign '-'. Spaces and special characters like accents are note allowed (the accents are removed during parsing).
Special characters and uppercase
================================
The search should not care about lowercase/uppercase and accentued characters. Currently, they are removed automatically by the `chill.main.search_provider`.
Implementing search module for dev
===================================
To implement a search module, you should :
- create a class which implements the `Chill\MainBundle\Search\SearchInterface` class. An abstract class `Chill\MainBundle\Search\AbstractSearch` will provide useful assertions for parsing date string to `DateTime` objects, ...
- register the class as a service, and tag the service with `chill.search` and an appropriate alias
The search logic is provided under the `/search` route.
.. seealso::
`The implementation of a search module in Person bundle <https://github.com/Chill-project/Person/blob/master/Search/PersonSearch.php>`_
An example of implementationhttps://github.com/Chill-project/Main/blob/master/DependencyInjection/SearchableServicesCompilerPass.php
.. note::
**Internals explained** : the services tagged with `chill.search` are gathered into the `chill.main.search_provider` service during compilation (`see the compiler pass <https://github.com/Chill-project/Main/blob/master/DependencyInjection/SearchableServicesCompilerPass.php>`_).
The `chill.main.search_provider` service allow to :
- retrieve all results (as html string) for all search module concerned by the search (according to the domain provided or modules marked as default)
- retrieve result for one search module
The SearchInterface class
-------------------------
.. code-block:: php
namespace Chill\PersonBundle\Search;
use Chill\MainBundle\Search\AbstractSearch;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Chill\MainBundle\Search\ParsingException;
class PersonSearch extends AbstractSearch
{
// indicate which domain you support
// you may respond TRUE to multiple domain, according to your logic
public function supports($domain)
{
return 'person' === $domain;
}
// if your domain must be called when no domain is provided, should return true
public function isActiveByDefault()
{
return true;
}
// if multiple module respond to the same domain, indicate an order for your search.
public function getOrder()
{
return 100;
}
// This is where your search logic should be executed.
// This method must return an HTML string (a string with HTML tags)
// see below about the structure of the $term array
public function renderResult(array $terms, $start = 0, $limit = 50, array $options = array())
{
return $this->container->get('templating')->render('ChillPersonBundle:Person:list.html.twig',
array(
// you should implements the `search` function somewhere :-)
'persons' => $this->search($terms, $start, $limit, $options),
// recomposePattern is available in AbstractSearch class
'pattern' => $this->recomposePattern($terms, array('nationality',
'firstname', 'lastname', 'birthdate', 'gender'), $terms['_domain']),
// you should implement the `count` function somewhere :-)
'total' => $this->count($terms)
));
}
}
Structure of array `$term`
^^^^^^^^^^^^^^^^^^^^^^^^^^
The array term is parsed automatically by the `main.chill.search_provider` service.
.. note::
If you need to parse a search pattern, you may use the function `parse($pattern)` provided by the service.
The array `$term` have the following structure after parsing :
.. code-block:: php
array(
'_domain' => 'person', //the domain, without the '@'
'argument1' => 'value', //the argument1, with his value
'argument2' => 'my value with spaces', //the argument2
'_default' => 'abcde ef' // the default term
);
The original search would have been : `@person argument1:value argument2:(my value with spaces) abcde ef`
.. warning::
The search values are always unaccented.
Register the service
--------------------
You should add your service in the configuration, and add a `chill.search` tag and an alias.
Example :
.. code-block:: yaml
services:
chill.person.search_person:
class: Chill\PersonBundle\Search\PersonSearch
#your logic here
tags:
- { name: chill.search, alias: 'person_regular' }
The alias will be used to get the results narrowed to this search module, in case of pagination (see above).
Parsing date
============
The class `Chill\MainBundle\Search\AbstractSearch` provides a method to parse date :
.. code-block:: php
//from subclasses
$date = $this->parseDate($string);
`$date` will be an instance of `DateTime <http://php.net/manual/en/class.datetime.php>`_.
.. seealso::
`The possibility to add periods instead of date <https://redmine.champs-libres.coop/issues/390>`_
Which may be a future improvement for search with date.
Exceptions
==========
The logic of the search is handled by the controller for the `/search` path.
You should throw those Exception from your instance of `SearchInterface` if needed :
Chill\MainBundle\Search\ParsingException
If the terms does not fit your search logic (for instance, conflicting terms)
Expected behaviour
==================
Operators between multiple terms
--------------------------------
Multiple terms should be considered are "AND" instructions :
@person nationality:RU firstname:dep
the people having the Russian nationality AND having DEP in their name
@person birthdate:2015-12-12 charles
the people having 'charles' in their name or firstname AND born on December 12 2015
Spaces in default
-----------------
Spaces in default terms should be considered as "AND" instruction
@person charle dep
people having "dep" AND "charles" in their firstname or lastname. Match "Charles Depardieu" but not "Gérard Depardieu" ('charle' is not present)
Rendering
---------
The rendering should contains :
- the total number of results ;
- the search pattern in the search language. The aim of this is to let users learn the search language easily.
- a title
Frequently Asked Questions (FAQ)
================================
Why renderResults returns an HTML string and not structured array ?
It seems that the form of results may vary (according to access-right logic, ...) and is not easily structurable