Bonjour,

Voila je cherche un moyen simple d'accéder tous les mois à une action de mon site pour générer une facture automatiquement ou envoyer des mails. Le problème , c'est que je n'y parviens pas car j'ai besoin de m'authentifier sur mon site.

J'ai tenter ceci:

authentification:
wget --save-cookies cookies.txt --keep-session-cookies --post-data="[User][username]=xxxx&[User][password]=yy"

Accés url:
wget --load-cookies cookies.txt -p ww.monsite.com/Users/doFacture/true

Mais ça ne fonctionne pas car mon planificateur d'execution de tâche m'envoie le status suivant:
Le planificateur de tâches à terminé une tâche planifiée.aroundaroundTâche : EMAILaroundHeure de début : Sun, 26 Mar 2017 23:49:23 GMTaroundHeure d’arrêt : Sun, 26 Mar 2017 23:49:25 GMTaroundÉtat actuel : 8aroundSortie standard/erreur :around--2017-03-26 23:49:23-- www.monsite.com/identificationaroundResolving www.monsite.com... xx.xx.xxx.169aroundConnecting to [http://www.monsite.com|xx.xx.xxx.169...xx.xxx.169|:80... connected.aroundHTTP request sent, awaiting response... 200 OKaroundLength: unspecified [text/html]aroundSaving to: 'identification.6'aroundaround0K ......... 16.2M=0.001saroundaround2017-03-26 23:49:24 (16.2 MB/s) - 'identification.6' saved [9376]aroundaround--2017-03-26 23:49:24-- hwww.monsite.com/Users/doFacture/truearoundResolvingwww.monsite.com... xx.xx.xxx.169aroundConnecting to [http://www.monsite.com|xx.xx.xxx.169...xx.xxx.169|:80... connected.aroundHTTP request sent, awaiting response... 302 FoundaroundLocation: www.monsite.com/identification [following]around--2017-03-26 23:49:24-- www.monsite.com/identificationaroundReusing existing connection to www.monsite.com:80.aroundHTTP request sent, awaiting response... 200 OKaroundLength: 3044 (3.0K) [text/html]aroundSaving to: 'www.monsite.com/Users/doFacture/true'aroundaround0K .. 100% 60.3M=0s

Mais je n'ai jamais recu le résultat qui doit normalement être généré quand je vais sur la page suivate: ww.monsite.com/Users/doFacture/true

Avoue une idée de comment je pourrais faire?
Merci par avance, je suis vraiment bloqué.

26 réponses


jey1985
Auteur
Réponse acceptée

Salut, Youpi tout fonctionne !
Voici un petit topo pour ceux qui voudraient faire la même chose.

Besoin:
Exécuter une tâche planifiée sur un serveur OVH mutualisé qui doit exécuter des requêtes sur un site cakePHP avec authentification.

Solution:
1) Créer une commande cakePHP pour réaliser le traitement attendu (merci Kareylo), en effet en Shell on peut accéder à tout le modèle de données sans nécessiter d'authentification.
2) tester la commande en local en se positionnant dans le répertoire app du projet et en exécutant: Console/cake macommande mafonction
3) si tout fonctionne, créer un fichier cron.sh qu'on va déposer sur notre serveur OVH mutualisé et qui devra exécuter la commande que l'on vient de tester.
(Dans le .sh il faut mettre les chemins en absolu)
Voici le contenu de mon cron.sh:

  #!/bin/bash
  exec /usr/local/php5.6/bin/php www/monsite/app/Console/command/cake.php cronjob generate_facture

(J’ai bien sûr créé la commande shell: CronjobShell.php et la fonction generate_facture())
(je donne le chemin complet vers php, car sinon il n'utilise pas la bonne version de php si on met juste "php ...cake.php ..." car l'environnement d’exécution des tâches planifiées n'est pas le même que lorsqu’on exécute directement cron.sh à partir de la console distante SSH )
4) uploadé le .sh sur le serveur (je l'ai mis dans www/monsite/app/console/command)
-> ne pas oublier de rendre son .sh executable (chmod +x monscript.sh)
-> l'idéal est de se connecter en SSH (ce n'est possible qu'en mutualisé "pro") afin de tester sa commande (en SSH les niveaux de sécurités sont différents donc il est tout à fait normal que l’envoie de mail cakeEMAIL ne fonctionne pas avec un message d’erreur « Network is unreachable », mais ça fonctionnera lorsque le .sh sera exécuté par la tache planifiées.)
5) une fois que notre cron.sh est exécutable et se lance bien en SSH (malgré les petits aléas limités aux restrictions de sécurités) on peut créer la tache planifié dans OVH faire pointer vers notre script www/monsite/app/Console/command/cron.sh , choisir « Autre » dans le mode d’exécution.

Voila et encore merci Kareylo :)

Créé tout simplement des commandes consoles, c'est le mieux à faire niveau sécurité.

Pour les email, il y a déjà un plugin tout fait pour le faire :
Cakephp-email-queue

jey1985
Auteur

Salut,
merci pour ta réponse,
Tu entends quoi par "creer des commandes consoles" ? aurais-tu un exemple ?

Un example ? Le plugin email-queue.
En gros, l'idée est de créer des commandes pour générer tes factures et une autre pour envoyer le mail. A partir de là, tu crées un controller côté web qui va lancer les commandes que tu as au préalablement créer.

L'avantage de cette technique, c'est que si tu as accès au CronJob, tu n'as pas besoin du controller web, tu as juste à lancer tes commandes directement.

jey1985
Auteur

C'est une action d'un controller web qui doit lancer les commandes 1)génération facture , 2) envoie mail ?

Les commandes générations facture/envoie mail, ont accés à tous mes modèles ?
Et donc avec ce système ça se passe comment niveau authentification ?

Réellement, tu peux le faire de plusieurs manières :

  • Tout côté web via un controller qui va lancer tes génération de la facture et l'envoie du mail, pour accéder à tes modèles, tu as $this->loadModel('Model'); => Sécurité : tu fais en sorte de ne pouvoir générer que les factures pas encore crées, pareil pour les mails, et tu laisses un accès total à ce controller.
  • Créer une commande que tu lanceras via bin/cake command, chose que tu peux faire via un bouton dans ton application que tu peux faire en background Documentation PHP. Tu devras donc lancer la commande que tu auras créé au préalable : Documentation CakePHP => Sécurité : Pareil que le précédent.
  • Créer une commande que tu lances en CronTab (voir point précédent). => Seul la machine où est le code peut lancer la commande.
jey1985
Auteur

Voila c'est le dernier point qui m'interesse. Je veux executer tous les 28 du mois par exemple l'url www.monsite.com/Users/doFacture.
Donc si je résume
Soit je déplace toutes les actions que je veux executer via l'extérieur dans un controller spécifique accéssible par tous (n'importe qui peut accéder aux actions ? )
Soit je creer une commande shell qui aura accés aux modèles et donc je code directement mes actions dans mes commandes shell puis j'execute un .sh dans ma crontab qui fait appel à "bin/cake macommande"

Sachant que mon site est hébergé sur un OVH mutualisé, je pourrais executer bin/cake selon toi ?

Je te redirige vers la doc de OVH pour ça car je n'ai jamais eu d'hébergement mutualisé chez OVH : OVH CronJob

jey1985
Auteur

Ok merci.
Juste une dernière question, tu me confirmes, qu'une commande Shell accède à tout le mdd sans necessité d'authentification ?

A partir du moment où tu load tes modèles dans ta commande, tu peux les utiliser comme bon te semble. Donc, non, tu n'as pas besoin d'authentification.
Donc, lis bien la doc concernant les commandes sur la documentation de CakePHP que je t'ai déjà donné : Shells, Tasks & Outils de Console

jey1985
Auteur

Ok merci, je vais essayer tout ça rapidement et je mettrai à jour le post :)

Très bien ! Bonne chance, dans ce cas !
Hésite pas à revenir par ici si tu as d'autres questions

jey1985
Auteur

Re,
Alors j'ai creer mon action dans le shell. Mais je suis confronnté à un nouveau problème, en effet je souhaite envoyer un PDF par email (de la même manière que je faisais dans mon controller)

Donc j'utilise ma view:

$this->autoRender = false;
$this->layout = false;            
$view = new View();          
$view->set('infos',$infos);
$view->set('month',$mois);
ob_start();
$html = $view->render('Users/do_facture');

$htmlcontent="<page backtop='45px'>";
$htmlcontent.= $html;
$htmlcontent.="</page>";

Le problème c'est que ma view() est toujours renvoyée avec le layout par défault malgré le fait que je mette layout=False, ce qui me provoque une erreur du genre :

 Fatal error: Class 'AuthComponent' not found in D:\DEV_WEB\i2\app\View\Elemen
ts\left_menu.ctp on line 2

quelqu'un à une idée ?
Merci

Bonsoir.
Qu'est-ce que tu fais là exactement ?
Ne me dis pas que tu fais ce code dans le shell quand même, si ?

jey1985
Auteur

Bonsoir Lartak,
lol oui je fais ce code dans un shell... en fait j´ai deplacé le code de l´action de mon controller ici.. je devrais peut etre faire un component ... mais le component aura accés à tout ? pour générer et envoyer une facture au format pdf ? ( necessite le model USER, l´import HTML2PDF et le composant CakeEMAIL)

Le shell n'est pas fait pour remplacer ce que tu ferais dans un controller ou une vue.

jey1985
Auteur

Quelle solution proposes tu?

@Lartak Vu ce qu'il veut faire, ça reste la meilleure solution.
Par contre, utilise plutôt un element à la place de ta vue directement:

    $view = new View();
    echo $view->element('do_facture');

Si tu veux vraiment utiliser le render, le layout = false, tu dois le faire sur $view, pas $this
Et le soucis du AuthComponent qui n'est pas chargé, c'est surtout qu'il doit être utilisé ou dans ta vue ou dans ton layout par défaut.

jey1985
Auteur

Tout à fait le AuthComponent est chargé dans un autre élement du layout par défaut, c'est pour ça que je veux le désactiver. Je test ce soir ce que tu me proposes.
Merci

jey1985
Auteur

Rien n'y fait... il cherche tjrs le AuthComponent du default layout alors que je ne veux pas de default layout:

    $view = new View();    
    $view->autoRender = False;
    $view->layout = False;            
    $view->render(False);        
    $view->set('infos',$infos);
    $view->set('month',$mois);
    ob_start();
    $html = $view->element('do_facture');

J'ai meme déplacé do_facture.ctp dans les Elements

Fatal error: Class 'AuthComponent' not found in D:\DEV_WEB\i2\app\View\Elements\left_menu.ctp on line 2
jey1985
Auteur

Autant pour moi, ça fonctionne je mettais pas à jour le bon fichier...meaculpa.. pour info ça fonctionne avec les 2 manières suivantes:
$view->render('Users/do_facture")
ou
$view->element("do_facture")

En revanche ça plante un peu plus loin dans HTML2PDF

Notice Error: Undefined variable: kPathUrl in [D:\DEV_WEB\lmdi2\app\Vendor\html2pdf\_class\tcpdfConfig.php, line 80]

En regardant de plus prés ce tcpdfConfig:

// Automatic calculation for the following K_PATH_URL constant
if (isset($_SERVER['HTTP_HOST']) AND (!empty($_SERVER['HTTP_HOST']))) {
    if (isset($_SERVER['HTTPS']) AND (!empty($_SERVER['HTTPS'])) AND strtolower($_SERVER['HTTPS'])!='off') {
        $kPathUrl = 'https://';
    } else {
        $kPathUrl = 'http://';
    }
    $kPathUrl .= $_SERVER['HTTP_HOST'];
    $kPathUrl .= str_replace('\\', '/', substr(K_PATH_MAIN, (strlen($_SERVER['DOCUMENT_ROOT']) - 1)));
}

Le problème je pense vient du fait qu'on ne soit pas sur un browser ...donc pas de $_SERVER de définit..

jey1985
Auteur

Ok ma commande shell est fonctionnelle, génération et envoie du PDF.
Il a fallu au passage prendre la dernière version de Html2pdf (bug du kPathUrl corrigé)

Je me lance maintenant l'execution de cette commande sur ovh... je vous tiens au courant

C'est génial si tout est fonctionnel !
C'est sûr que gérer la vue directement dans une commande n'est pas top, mais à partir du moment où ça fonctionne correctement :)

jey1985
Auteur

En fait disons que la vue je l'utilise pour générer mon PDF que je joint au mail, ça m'évite justement de manipuler des balises html dans ma commande shell..c'est vrais que j'aurais pu tout remonter dans un "Components" pour faire plus propre....mais je ferais éventuellement de la propreté quand tout fonctionnera :)

En tout cas merci pour le conseil de la commande shell, que je n'avais jamais utilisé.
Là je galère pour executer mon script cron.sh que j'ai déposé sur OVH, sachant que les tâches s'executent au maximum 1 fois par heure.. donc c'est galère pour tester...

Je vais essayer de me connecter en ssh pour lancer la commande que j'ai mise dans mon .sh:

exec /usr/local/php5.6/bin/php cake.php cronjob generate_facture    
jey1985
Auteur

Je viens de tester en ligne de commande mon script...j'ai réglé quelques bricoles, mais là maintenant je suis confronté au pb qu'on ne peut pas utiliser CakeEmail en console sur ovh mutualisé apparemment..

Error: Network is unreachable
#0 /home/uuuu/www/site1/lib/Cake/Network/Email/SmtpTransport.php(154): CakeSocket->connect()
#1 /home/uuuu/www/site1/lib/Cake/Network/Email/SmtpTransport.php(95): SmtpTransport->_connect()
#2 /home/uuuu/www/site1/lib/Cake/Network/Email/CakeEmail.php(1150): SmtpTransport->send(Object(CakeEmail))
#3 /home/uuuu/www/site1/app/Console/Command/CronjobShell.php(82): CakeEmail->send('Bonjour<br><br>...')
#4 /home/uuuu/www/site1/lib/Cake/Console/Shell.php(437): CronjobShell->generate_facture()
#5 /home/uuuu/www/site1/lib/Cake/Console/ShellDispatcher.php(209): Shell->runCommand('generate_factur...', Array)
#6 /home/uuuu/www/site1/lib/Cake/Console/ShellDispatcher.php(66): ShellDispatcher->dispatch()
#7 /home/uuuu/www/site1/app/Console/cake.php(47): ShellDispatcher::run(Array)

J'ai contacté le support... mais je ne me fais pas trop d'illusion...

Je n'avais même pas remarqué que tu étais sous Cake 2 et je t'ai donné que de la doc Cake 3... comme quoi, on arrive à chercher assez facilement d'une version à l'autre...