web-dev-qa-db-fra.com

JForm avec des instructions SQL personnalisées

J'ai un formulaire JForm, qui insère des enregistrements dans la base de données et s'appuie sur ses propres contrôleurs, modèles, vues et tables, dérivés de JTable.

Cependant, la table de base de données contient un champ spécial représentant le numéro de facture, qui doit être incrémenté à chaque nouvel enregistrement et réinitialisé à la fin de l'année. Par conséquent, sa valeur ne peut pas être prise en compte par le formulaire, mais doit être calculée uniquement. avant de sauvegarder l'enregistrement. La requête elle-même est un peu plus complexe, mais pour donner une idée, elle pourrait être simplifiée comme suit:

INSERT INTO `table` (`number`, `year`, `data`)
VALUES (
    (SELECT MAX(`number`) + 1 FROM `table` WHERE `year` = YEAR(CURDATE())),
    YEAR(CURDATE()),
    'some data...'
)

Maintenant la question, puisque JTable :: store () utilise JDatabaseDriver :: insertObject () pour sauvegarder ses données, et je suppose que je ne peux pas demander à JTable d'exécuter des instructions SQL personnalisées, Quel est le meilleur moyen d'y parvenir?

5
Demis Palma ツ

Vous pouvez remplacer la méthode store() dans votre classe de table; quelque chose comme ça:

public function store($updateNulls = true) { // or false but you can't nullify a value if needed
    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query->select('MAX(`number`) + 1');
    $query->from('`#__table`');
    $query->where('`year` = YEAR(CURDATE())');
    $db->setQuery($query);
    $db->execute();
    $number = $db->loadResult();

    $date = JFactory::getDate();
    $year = $date->format('Y');

    $this->number = $number;
    $this->year = $year; // or get it by another db query but not recommended
    $this->data = 'some data...';

    return parent::store($updateNulls);
}
2
Farahmand

Vous pouvez ajouter une méthode check à votre classe de table. Ceci est exécuté après bind mais avant store par défaut. C'est une excellente méthode pour vérifier que l'enregistrement est valide et gérer toutes les exigences de lignes spécifiques.

public function check() {
    // Only set the number if this is a new record (id = 0)
    if (property_exists($this, 'number') && $this->id == 0) {
         $db = JFactory::getDbo();
         $query = $db->getQuery(true);
         $query->select('MAX(`number`) + 1');
         $query->from('`#__table`');
         $query->where('`year` = YEAR(CURDATE())');
         $db->setQuery($query);
         $this->number = $db->loadResult();
    }

    return parent::check();
}
1
David Fritsch