Amélioration #5421
ferméDoc::Affect et nettoyage des valeurs
100%
Deux hook : Doc::preAffect() et Doc::postAffect()
sont ajoutés en début et fin de la méthode Doc::affect()
qui est utilisé par SearchDoc notamment.
La méthode
bool Doc::preAffect(&$data, &$more = false, &$reset=false)
Si elle retourne "false", l'affectation est annulée.
Le donnée peut être modifiée avant l'affectaion effective
La méthode
void Doc::postAffect($data, $more = false, $reset=false)
ne retourne pas d'information. Permet de réaliser un post-traitement
comme par exemple reinitialiser des données privées.
Description
la méthode Doc::affect est utilisée pour recycler un objet. à cette fin, elle nettoie les propriétés de l'objet. la liste de propriétés nettoyées est figée, et non surchargeable (en effet, la méthode ets finale).
En conséquence, l'utilisation de searchDoc sur une famille dont les méthodes utilisent du cache sous forme de propriétés de classe corromp les documents.
Exemple d'une telle méthode :
function getCachedValue()
{
if( null === $this->_myCachedValue ) {
$this->myCachedValue = $this->initid;
}
return $this->_myCachedValue;
}
Lors de l'utilisation de cette méthode au sein d'un appel à un searchDoc, cette méthode retournera l'initid du premier document pour tous les documents.
Mis à jour par Éric Brison il y a environ 11 ans
La méthode existe déjà c'est "DbObj::complete()'.
Mis à jour par Matthieu Codron il y a environ 11 ans
- Statut changé de Analysé à Assigné
- Assigné à
Éric Brisonsupprimé
on se serait plutt attendu à 2 méthodes
- une de nettoyage
- une de completion (
Doc::completesemble un bon candidat)
Dans tous les cas, il est important de documenter cette méthode, ainsi que d'enrichir la doc de searchdoc pour expliciter ce cas. En effet, dans le pire des cas, le cache ainsi propagé peut mélanger les données entre les documents (recopiant les données du premier document dans les suivants) de manière irréversible.
Mis à jour par Matthieu Codron il y a environ 11 ans
Le problème est que Doc::affect est appelé depuis Doc::postInsert (via postInsert → Select → Affect). cela vide le cache (appel de complete), alors qu'on ne change pas de document.
Dans notre cas, il est important que ce cahe ne soit pas vidé avant que le document ne soit enregistré.
Il faut donc une méthode permettant de réinitialiser le document entre 2 affectations successives sur le SearchDoc.
Mis à jour par Éric Brison il y a environ 11 ans
Sur la méthode Doc::Affect() le paramètre "reset" permet de différencier ces 2 cas.
Il peut suffire de propager cet attribut à la méthode complete.
Mis à jour par Marc Claverie il y a plus de 10 ans
- Statut changé de Assigné à À analyser
- Assigné à mis à Éric Brison
- Version cible mis à 3.2.20
Mis à jour par Éric Brison il y a plus de 10 ans
- Statut changé de À analyser à Analysé
- Solution proposée mis à jour (diff)
Mis à jour par Éric Brison il y a plus de 10 ans
- Solution proposée mis à jour (diff)
Pour résoudre, le cas présenté : ne pas reset le cache si même document
function preAffect(&$data, &$mode, &$reset) {
if ($reset) {
// no use reset if same document
$reset = (!$this->initid) || ($data["initid"] != $this->initid);
}
return true;
}
Mis à jour par Éric Brison il y a plus de 10 ans
- Statut changé de Assigné à Intégré
- % réalisé changé de 0 à 100
Appliqué par commit dynacase-core|commit:b4edde0c7ff76882473452f4ddb6982ad42d8dbc.