Mysql
 sql >> Base de données >  >> RDS >> Mysql

Modèle CakePHP avec entre les dates

Si je vous suis bien :

  • L'utilisateur doit spécifier les dates de début/fin des requêtes de recherche générées à partir d'un formulaire
  • Vous devez valider ces dates afin que, par exemple :
    • date de fin après la date de début
    • la date de fin n'est pas éloignée de plusieurs siècles de la date de début
  • Vous voulez que les erreurs de validation apparaissent en ligne dans le formulaire (même s'il ne s'agit pas d'une sauvegarde)

Puisque vous souhaitez valider ces dates, elles seront plus difficiles à saisir lorsqu'elles seront cachées dans votre tableau de conditions. Je suggère d'essayer de les transmettre séparément, puis de les traiter plus tard :

$this->Model->find('all', array(
    'conditions' => array(/* normal conditions here */),
    'dateRange' => array(
        'start' => /* start_date value */,
        'end'   => /* end_date value */,
    ),
));

Vous devriez, espérons-le, être capable de gérer tout le reste dans le beforeFind filtre :

public function beforeFind() {
    // perform query validation
    if ($queryData['dateRange']['end'] < $queryData['dateRange']['start']) {
        $this->invalidate(
            /* end_date field name */,
            "End date must be after start date"
        );
        return false;
    }
    /* repeat for other validation */
    // add between condition to query
    $queryData['conditions'][] = array(
        'Model.dateField BETWEEN ? AND ?' => array(
            $queryData['dateRange']['start'],
            $queryData['dateRange']['end'],
        ),
    );
    unset($queryData['dateRange']);
    // proceed with find
    return true;
}

Je n'ai pas essayé d'utiliser Model::invalidate() lors d'une opération de recherche, cela peut donc ne pas fonctionner. L'idée est que si le formulaire est créé à l'aide de FormHelper ces messages devraient revenir à côté des champs du formulaire.

A défaut, vous devrez peut-être effectuer cette validation dans le contrôleur et utiliser Session::setFlash() . si c'est le cas, vous pouvez également vous débarrasser du beforeFind et mettez le BETWEEN tableau de conditions avec vos autres conditions.