Animation d’un site web : créer un plugin

Animation d’un site web : créer un plugin

Pour donner un peu de vie à un site, on peut souhaiter que certains éléments soient animés. Ils peuvent par exemple arriver lorsqu’on déroule l’écran jusqu’à leur position, ou s’animer lorsqu’on fait glisser la souris dessus. La solution, très simple, a été créée par Matthieu Aussaguel pour wow.js et Daniel Eden pour animate.css. On peut voir sur cette page de démonstration ce qu’il est possible de faire.  (suite…)

Cron Job sur un hébergement mutualisé OVH

Dans un projet personnel, j’ai eu besoin de lancer un script régulièrement sur mon hébergement mutualisé OVH. Et j’ai constaté que ce n’est pas simple ! Je décris ici un script test, qui fonctionne après de multiples essais.

Le principe

Je veux que OVH exécute un script PHP à fréquence régulière. Le script PHP présenté ici réalise différentes activités qui permettent de vérifier que mes réglages sont bons. Il s’agit en effet de répondre aux questions suivantes :

  • comment faire pour que OVH exécute régulièrement un script (PHP ici) ?
  • Si le script doit accéder à d’autres fichiers, comment lui « dire » où les trouver ?
  • Si le script doit envoyer un mail, quelles sont les spécifications pour que ça fonctionne ?
  • Comment faire pour deboguer et afficher ce qui se passe durant le script « croné » ?

Ecriture du script PHP

Le fichier « cron-test.php »final, qui fonctionne, contient les éléments suivants :

#!/usr/local/bin/php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>Test de Cron</title>
	</head>
	<body>
		<h2> Le test commence </h2>
		<?php
		/**
		* test script
		**/

		$path = dirname( __FILE__ );
		
		// https://forum.ovh.com/showthread.php/101095-taches-planifi%C3%A9s-ne-s-executent-plus/page2

		define('ROOT',dirname( __FILE__ ));

		
		include_once ROOT . '/al-pi-cron-test.php';

		$line1 = $path ;
		$line2 = "ligne 2" ;
		$line3 = "ligne 3" ;

		date_default_timezone_set('CEST');
		$today = date("F j, Y, g:i a"); 


		$to      = 'adresse@gmail.com, autreadresse@hotmail.fr'; 
		$subject = 'cront-test.php  !!!';
		$message = $line1 . "\r\n" . $line2 . "\r\n" . $line3 . "\r\n" ;
	
		$send_mail = al_send_email( $to, $subject, $message) ;
			
		
		
		
		$fp = fopen( ROOT . '/My-pi/cron-pi.log', 'a' );  
		fwrite( $fp, "\r\n -----------------TEST----------------------------------- \r\n" );
		fwrite( $fp, $today . "\r\n" );
		fwrite( $fp, $line1 . "\r\n" );
		fwrite( $fp, $line2 . "\r\n" );
		fwrite( $fp, $line3 . "\r\n" );
		fwrite( $fp, "Résultat envoi Mail : " . $send_mail . "\r\n" );		
		fwrite( $fp, "\r\n -------------------------------------------------------- \r\n" );
		fclose($fp);
		?>
  
		<h2> Le test est terminé </h2> 

  
	</body>
	</html>

La partie html permet de visualiser (et lancer) le script à partir d’internet, en tapant l’adresse http://mon-site.com/cron-test.php, comme ci-dessous.
Affichage sur navigateur internet

Ce qui est réellement important, c’est le code php.

Pour que OVH puisse exécuter ce script en cron

Il vaut mieux (c’est optionnel pour du PHP), indiquer en toute première ligne du fichier comment il doit se décoder :

#!/usr/local/bin/php

Mais surtout, il faut comprendre que l’environnement dans lequel s’exécute un cron n’est pas celui dans lequel on exécute à la main (ou dans le navigateur comme ci-dessus). Le script ne sait pas où il est et il faut lui donner l’information ! On définit ainsi une variable ROOT avec la fonction define() puis on l’indique à chaque fois qu’il faut aller chercher un fichier, ici lorsqu’on veut utiliser un autre fichier pour définir les fonctions utilisées ou pour indiquer le chemin vers un fichier cron-pi.log que l’on veut ouvrir pour y ajouter du texte à la fin.

define('ROOT',dirname( __FILE__ ));

include_once ROOT . '/al-pi-cron-test.php';

$fp = fopen( ROOT . '/My-pi/cron-pi.log', 'a' );

Et voilà, les éléments indispensables pour qu’un script PHP puisse être exécuté en CRON sont identifiés !

Notez que la ligne ci-dessous fait appel à une fonction qui est écrite dans le fichier al-pi-cron-test.php appelé avec la fonction include_once.

$send_mail = al_send_email( $to, $subject, $message) ;

Réglage du Cron sur OVH mutualisé

Aller sur l’espace client OVH et sélectionner l’hébergement du nom de domaine correspondant. Cliquer sur l’onglet Cron puis choisir « ajouter une planification ».

Dans mon cas, le script est placé dans le répertoire pi-suivi/ .

cron job sur OVH (mutualisé) : étape 1

Après avoir cliqué sur suivant, il faut que je choisisses la fréquence de réalisation du script. Ici j’ai utilisé le mode simple et je n’ai rien modifié : je veux une exécution toutes les heures. Noter qu’on ne peut pas régler les minutes, même en mode expert. Sur un hébergement mutualisé OVH, ce n’est pas possible.

cron job sur OVH (mutualisé) : étape 2

Après avoir cliqué sur « suivant », voici la synthèse de ce que j’ai choisi. Notez le « ? » pour les minutes. C’est OVH qui va en décider la valeur.

cron job sur OVH (mutualisé) : étape 3

Je valide et j’attends 1 à 2 minutes. Je rafraichis la page de mon espace client OVH et la tâche Cron apparaît. J’avais déjà créé une autre tâche Cron. On voit que OVH a décidé qu’elle s’exécuterait à chaque fois qu’il est xh51. La deuxième tâche sera elle réalisée à chaque fois qu’il est xh40.

cron job sur OVH (mutualisé) : étape 4

J’attends qu’il soit xh40 et quelques, puis je vois que mon script s’est exécuté : j’ai reçu le mail généré par la fonction

Déboguage

Pour en arriver là, j’ai bien galéré et j’ai dû apprendre comment déboguer sur OVH.

En particulier, j’ai finalement trouvé où se trouvent les logs des hébergements mutualisés ! Il suffit de taper « https://logs.ovh.net/mon-site.com/ puis d’indiquer son identifiant OVH et son mot de passe (ceux qu’on utilise pour accéder à l’espace client). Par exemple, mes logs sont sur https://logs.ovh.net/parcours-performance.com/.

On trouve alors une ligne contenant « Cliquez ici pour voir les logs bruts en temps réel : web – ftp – error – cgi – out – ssh – cron ». On clique sur « cron » et on accède au dernier log des cron.

Les logs commencent par, et se terminent par ce qui suit. Entre les deux lignes, il y a le HTML. Ici j’ai remplacé le chemin vers mon répertoire par *** pour des raisons de sécurité.

Un cron s’est exécuté correctement s’il se termine par exitcode:0.

[2015-10-05 12:51:02] ## OVH ## START - 2015-10-05 11:23:02.575704 executing: /usr/local/php5.5/bin/php ***/pi-suivi/cron-test.php 
[2015-10-05 12:51:02] ## OVH ## END - 2015-10-05 12:51:03.454292 exitcode: 0

Mais évidemment, du point de vue du serveur un cron se termine correctement s’il n’y a pas d’erreur. De mon point de vue, il est terminé correctement s’il a réalisé ce que j’attendais….

Ecrire dans un fichier permet de vérifier ce qui se passe durant l’exécution du code. Ainsi j’ai défini $line1 puis je l’écris dans le fichier log défini. Ca me permet de savoir dans quel répertoire se déroule le travail.

Mais un des rôles les plus importants d’un tel fichier log est de nous dire si les choses se sont bien passées :

exemple 1 : écrire dans un log le résultat d’une interaction

Dans le script ci-dessus, j’appelle une fonction, al_send_email, par la commande :

$send_mail = al_send_email( $to, $subject, $message) ;

Cette fonction (non présentée ici ) gènère un mail à destination de $to, avec $subject comme objet et $message dans le corps du mail.  C’est bien beau de lancer une fonction. Mais ce qui est essentiel, c’est de savoir si le mail a effectivement été expédié.

Et bien $send_mail contient cette information maintenant que la fonction a été exécutée. En effet la fonction contient la ligne ‘return $result ; » et $result est réglé à   » ###  » . $send_Mail .  » – Erreur envoi mail <br> \n » si le serveur de messagerie n’a pas répondu « true » lors de l’envoi. Je peux donc indiquer dans mon log si tout s’est bien passé.

exemple 2 : écrire dans un log le contenu d’un tableau (array)

Un autre exemple où la constitution d’un log est essentielle pour déboguer un script, c’est lorsqu’on manipule des tableaux (array).

Dans un autre script php j’utilise cette fonctionnalité en définissant $line1 comme contenant toutes les valeurs d’un array $list_pi :

$line1 = var_export( $list_pi, true ) ;

Le log correspondant va ainsi contenir le texte suivant pour $line1 :

array (
  0 => 'val1',
  1 => 'val2',
  2 => 'val3',
)

D’un coup d’oeil dans le log, je vois si le script tel que réalisé dans l’environnement cron s’est déroulé comme prévu.

Maintenant, il ne reste plus qu’à trouver d’autres actions à réaliser fréquemment. Il peut s’agir d’une sauvegarde de la base de données ou d’autres constructions plus sophistiquées.

paramétrer wp-config.php

paramétrer wp-config.php

Le fichier wp-config.php dit à WordPress quels sont ses principaux réglages lorsqu’il démarre. Les éléments minimaux sont : la manière d’accéder à la base de données et le chemin d’accès au répertoire contenant WordPress. Mais d’autres éléments sont utiles ou indispensables.  (suite…)

Modifier le theme customizer

Ceci est une liste des liens (tous en anglais) qui me semblent intéressants à ce stade :

Maintenant que c’est noté, j’expérimente un peu et je ferai ensuite un article pour faire part de ce que j’ai appris !

La suite de cet article correspond à des notes prises pour mon propre usage. Je ne pense pas que ça puisse aider qui que ce soit d’autre…

 Où sont rangées les informations saisies ?

Dans la table « PRE_options » (lorsque le prefixe de la base de données est PRE, wp_options si aucun réglage n’a été effectué). Il y a

  • une ligne dont le nom est « theme_mods_nom-du-theme » (noter les ‘-‘ et pas ‘_’ pour la partie qui correspond au nom du thème utilisé). L’option_value contient une chaine de caractères parmi laquelle on trouve : « s:21: »unique_theme_settings »;a:2:{s:10: »logo_width »;s:2: »48″;s:11: »logo_height »;s:3: »145″;}} » qui contient donc les deux textes saisis. Attention, c’est rangé sous la forme d’un array dont les deux éléments sont unique_theme_settings[logo_width] et unique_theme_settings[logo_height] !!!
  • Egalement une ligne dont le nom est « unique_theme_settings » (mon thème parent est unique) qui contient les autres données : a:3:{s:19: »test_ald_1_textarea« ;s:18: »je change ce texte »;s:11: »logo_upload« ;s:60: »http://dev.prosiad.fr/wp-content/uploads/2014/10/Prosiad.png »;s:14: »favicon_upload« ;s:60: »http://dev.prosiad.fr/wp-content/uploads/2014/10/favicon.png »;}

Mon problème est que j’arrive à afficher le contenu de tout ce qui est stocké dans la ligne « unique_theme_settings » avec

echo '<p>logo_upload : ' . esc_attr( hybrid_get_setting( 'logo_upload' ) ) . '</p>';

Mais la même commande ne fonctionne pas pour logo_width et logo_height qui pour une raison que je ne comprends pas ne sont pas traités de la même manière.

Pour des gens qui n’utilisent pas un thème avec le framework hybrid de Justin Tadlock, la commande serait :

$options = get_option( 'unique' . '_theme_settings', false );
if ( isset ($options[logo_upload])) {
        echo '<p>logo_upload : ' .  $options[logo_upload] . '</p>'; 	
}

 Pourquoi est-ce que [logo-height] et [logo-width] ne sont pas récupérés ?

Quelles sont les différences de réglage entre deux champs qui devraient être similaires

settings logo_width test_ald_1_textarea
‘type’ non spécifié  ‘option’
‘transport’ non spécifié ‘postMessage’

Le Codex pour la fonction ‘$wp_customize->add_setting($id, $args);’ indique que l’argument ‘type’ par défaut est ‘theme_mod’. Le type de ‘logo_width’ est donc ‘theme_mod’. C’est pour ça qu’il est rangé dans une autre ligne de la table ‘PRE_options’….

note : Selon cet article sur stackexchange, ‘theme_mod’ est plus lent et peut même ralentir significativement un site (!).  On appelle l’un ou l’autre des deux types en tapant get_theme_mod() calls to get_option()

Quant à « transport », selon le codex :

The ‘transport‘ argument is optional, and defaults to ‘refresh‘. If left to default, then the theme customizer’s preview window will update by completely reloading itself when this setting is changed. If you would prefer to avoid refreshes and improve responsiveness, you can set this to ‘postMessage‘ instead, then handle any styling updates manually with a bit of JavaScript

Je pense que la différence provient de « type »

Avant de modifier le type pour qu’il soit option dans tous mes settings, je teste l’affichage des options avec get_theme_mod :

J’ai défini logo_width comme suit ($prefix = ‘unique’) :

<?php
$wp_customize->add_setting( 
	"{$prefix}_theme_settings[logo_width]", 
	array(
		'default' => __('Largeur du logo (en px)', 'unique-impact1'),
		'sanitize_callback' => 'unique_impact_1_logo_sanitize',
	)
);
?>

Pour réussir à le lire, il faut que je cherche d’abord l’array ‘ unique_theme_settings’ puis je visualise l’élément [logo_width] de cet array…

$options = get_theme_mod( 'unique_theme_settings', false );
echo '<p>5. logo_width : ' . $options[logo_width] . '</p>';

Et ça fonctionne ! Mais c’est affreusement compliqué. Je modifie donc la définition des settings logo_width et logo_height comme suit :

$wp_customize->add_setting( 
	"{$prefix}_theme_settings[logo_width]", 
	array(
		'type'  	=> 'option',
		'default' => __('Largeur du logo (en px)', 'unique-impact1'),
		'sanitize_callback' => 'unique_impact_1_logo_sanitize',
	)
);

Pour voir un changement, il faut que j’aille enregistrer une valeur dans ces options.

Et les deux façons suivantes d’afficher logo_width fonctionnent maintenant !

// needs hybrid framework
echo '<p>logo_width : ' .  esc_attr( hybrid_get_setting( 'logo_width' ) ) . '</p>';

// works in any wordpress theme but 'unique' has to be changed into 'your-theme-prefix'
$options = get_option( 'unique' . '_theme_settings', false );
if ( isset ($options[logo_upload])) {
	echo '<p>logo_upload : ' .  $options[logo_upload] . '</p>'; 			
} else {
	echo '<p>logo_upload : pas trouvé ! </p>';
}
if ( isset ( $options[logo_width] )) {
	echo '<p>logo_width : ' .  $options[logo_width] . '</p>'; 			
} else {
	echo '<p>logo_width : pas trouvé ! </p>';
}

Je crois bien que j’ai compris l’essentiel. Il me reste maintenant à exploiter ces settings dans mon thème.