/**
  * Determines the type of which filter class to instantiate, based on
  * the structured array received and the given entity class.
  *
  * @param FilterOptions $filterOptions
  * @param string        $entity
  *
  * @return null|FilterInterface
  */
 public function guessFilterTypeFromArray($filterOptions, $entity)
 {
     $filterType = null;
     /* in case the attribute to filter by is situated in another entity,
        parse the connected entities until you reach its entity */
     if ($path = $filterOptions->getPathArray()) {
         while ($path) {
             $entity = $this->em->getClassMetadata($entity)->getAssociationMapping(array_shift($path))['targetEntity'];
         }
     }
     if ($filter = $this->filterFieldReader->getFilter($entity, $attribute = $filterOptions->getName())) {
         /* get the type of the attribute that corresponds to the filter */
         $attributeType = isset($filter[$attribute]['options']['type']) ? $filter[$attribute]['options']['type'] : $this->em->getClassMetadata($entity)->getTypeOfField($filter[$attribute]['property']);
         $filterOptions->setAttribute($filter[$attribute]['property']);
         if (sizeof($filterOptions->getValues()) == 1) {
             switch ($attributeType) {
                 case 'integer':
                     $filterType = FilterInterface::NUMERIC_FILTER;
                     break;
                 case 'text':
                 case 'string':
                     $filterType = FilterInterface::STRING_FILTER;
                     break;
                 case 'date':
                     $filterType = FilterInterface::DATE_FILTER;
                     break;
                 case 'checker':
                     $filterType = FilterInterface::CHECK_FILTER;
                     break;
             }
         } else {
             switch ($attributeType) {
                 case 'integer':
                     $filterType = FilterInterface::NUMERIC_INTERVAL_FILTER;
                     break;
                 case 'date':
                     $filterType = FilterInterface::DATE_INTERVAL_FILTER;
                     break;
                 case 'string':
                     $filterType = FilterInterface::OR_STRING_FILTER;
                     break;
                 case 'date_check':
                     $filterType = FilterInterface::DATE_CHECK_FILTER;
                     break;
             }
         }
     }
     return $filterType;
 }
 /**
  * Transforms the filters' string into an array of FilterOptions objects.
  *
  * @param string $filtersString
  * @param string $filtersDelimiter
  * @param string $expressionDelimiter
  * @param string $intervalDelimiter
  *
  * @return array $filtersOptions
  *
  * @throws \InvalidArgumentException
  */
 public function stripFilterQueryToFilterOptions($filtersString, $filtersDelimiter, $filtersOrDelimiter, $expressionDelimiter, $intervalDelimiter)
 {
     /* explode the filters string received into an array of individual strings
        representing a single filter */
     $filtersStringArray = explode($filtersDelimiter, substr($filtersString, 1, -1));
     foreach ($filtersStringArray as $key => $filterString) {
         if (sizeof(explode('=', $filterString)) > 1) {
             $filterOptions = new FilterOptions();
             $filterAttributeValue[] = explode('=', $filterString);
             /* we have to deal with an expression if $exprWithValues has
                more than 1 element, separated by the $expressionDelimiter
                so we set the expression and the values to the $filterOptions object */
             if (sizeof($exprWithValues = explode($expressionDelimiter, $filterAttributeValue[$key][1])) > 1) {
                 $filterOptions->setExpression(array_shift($exprWithValues));
                 /* if the OR delimiter is found in the $exprWithValues string,
                    explode by the said delimiter */
                 if (strpos($exprWithValues[0], $filtersOrDelimiter)) {
                     $exprWithValues = explode($filtersOrDelimiter, $exprWithValues[0]);
                 }
                 /* if the interval delimiter is found in the $exprWithValues string,
                    explode by the said delimiter */
                 if (strpos($exprWithValues[0], $intervalDelimiter)) {
                     $exprWithValues = explode($intervalDelimiter, $exprWithValues[0]);
                 }
                 $filterOptions->setValues($exprWithValues);
                 /* we have to deal with the default expression so we set only the
                  * value to the $filterOptions
                  */
             } else {
                 /* if the OR delimiter is found in the filterValues string,
                  * explode by the said delimiter
                  */
                 if (strpos($filterAttributeValue[$key][1], $filtersOrDelimiter)) {
                     $filterOrValues = explode($filtersOrDelimiter, $filterAttributeValue[$key][1]);
                 }
                 $filterOptions->setValues(isset($filterOrValues) ? $filterOrValues : $filterAttributeValue[$key][1]);
             }
             /* explode string before '=' to determine if the filter is in related entity */
             $filterPath = explode('.', $filterAttributeValue[$key][0]);
             $filterOptions->setName(array_pop($filterPath));
             if (sizeof($filterPath) > 0) {
                 $filterOptions->setPathArray($filterPath);
             }
             $filtersOptions[] = $filterOptions;
         } else {
             /* TODO: refactor this when implementing logs all over the project */
             $this->logger->error('Invalid arguments in filter usage.', array('path' => '\\Pitech\\FiltersBundle\\Helper\\FilterHelper', 'function' => 'stripFilterQueryToFilterOptions', 'filter_string' => $filtersString));
             throw new \InvalidArgumentException();
         }
     }
     return $filtersOptions;
 }