J'ai une longue charge pour la boucle dans une fonction de l'un de mes modèles dans mon composant Joomla. Afin de jauger les progrès, je voulais faire une barre de progression en utilisant ajax et javascript pendant le traitement de la demande.
Pour commencer, j'ai fait un simple appel ajax à une fonction de l'un des contrôleurs qui contient le code suivant:
$mainframe =JFactory::getSession();
$i=$mainframe->get('component.progress', 0);
$echo($i);
Ici, j'utilise getSession, mais pour autant que je sache, session et état utilisateur ou presque, à l'exception de celui-ci autorisant d'autres opérations et sauvegardant les variables dans le registre. J'ai essayé les deux et les résultats sont les mêmes.
Le get vient de l'intérieur de la boucle de sol de ma fonction dans le modèle, qui effectue le calcul lourd, et qui ressemble à ceci:
for ($i = 1; $i < min(600, count($this->dati)); $i++) {
$mainframe = JFactory::getSession();
$mainframe->set('component.progress', $i);
heavy computation...
}
ensuite, lorsque j'exécute le script php, j'appelle simplement cette fonction javascript avec set_interval qui vide périodiquement le contenu du site, indiquant ainsi l'appel de la fonction sur le site existant:
function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function ()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "index.php?option=com_contentimporter&task=contentimporter.test", true);
xmlhttp.send();
}
Jusqu'ici tout va bien, le problème est que l'état de l'utilisateur n'est pas mis à jour lors de l'exécution du script. Il semble que cela ne soit mis à jour qu'une fois que c'est fait. Maintenant, ce que je soupçonne, c’est que joomla mette ces valeurs dans un tampon qu’elle ne définit que lorsqu’une demande en attente est effectuée.
Ce n'est malheureusement pas bon pour ce que j'essaie de faire.
Quelqu'un a-t-il une suggestion quant à ce que je pourrais faire à la place? Ce serait mieux si je pouvais le faire sans modifier aucun paramètre par défaut dans Joomla.
edit : Ok, j'ai remarqué quelque chose de nouveau, lorsque la fonction php est terminée, je produis quelques commentaires que je obtenez de l'état utilisateur que j'ai défini à la fin de la méthode dans mon modèle qui effectue le calcul lourd. J'ai remarqué que ces commentaires sont affichés correctement, mais seulement parfois.
En d'autres termes, il affiche parfois le retour du traitement précédent, parfois le retour du traitement actuel. Parfois, je peux actualiser la fenêtre après quelques secondes et les commentaires corrects s'affichent (à chaque fois que j'effectue une actualisation, getUserstate est appelé). D'autres fois, je dois réexécuter le script n fois avant que les commentaires corrects ne s'affichent.
Il semble se comporter de manière erratique et aléatoire. J'ai peut-être accidentellement supprimé certaines valeurs de table ou modifié certains paramètres de Joomla qui pourraient en être la cause? est-ce que quelqu'un a une idée?
En outre, j'ai lu que si le registre pour une raison quelconque n'était pas défini (setUserstat ne fera rien dans ce cas), je pourrais faire:
$session = JFactory::getSession();
$registry=$session->get('registry',null);
if(is_null($registry)) {
$session->set('registry', new JRegistry('session'));
}
J'ai essayé cela mais cela ne semble pas résoudre le problème.
Aussi, je ne devrais pas utiliser J! Dump de temps en temps pour afficher des informations sur certaines variables, et j'ai également le même problème avec ce composant, la fenêtre avec le vidage ne s'affiche que de temps en temps.
Eh bien, je crois que j’ai eu un problème similaire une fois où j’ai eu des résultats aléatoires. Pour moi, la solution utilisait une requête synchrone (au lieu de la requête asynchrone, que vous utilisez aussi, si je ne me trompe pas). Cela réduit quelque peu les performances, mais obligera la requête à être exécutée de manière ordonnée.
Je viens de trouver ceci page qui explique et donne quelques exemples. Essayez juste de changer
xmlhttp.open("GET", "index.php?option=com_contentimporter&task=contentimporter.test", true);
à
xmlhttp.open("GET", "index.php?option=com_contentimporter&task=contentimporter.test", false);
Le "faux" doit rendre la demande synchrone.