E-mail en PHP – Accents dans les sujets

Problème : Transmettre les accents dans les sujets d’e-mail via la fonction mail() de PHP.

Une solution apparemment efficace ici : http://pilgrim.maleo.net/2008/02/fonction-mail-envoyer-un-sujet-avec-des-accents

Extrait :

[…]

// Message
$recipient = 'you@example.com';
$subject = '=?UTF-8?B?'.base64_encode('Sujet : éèàïî').'?=';
$sender = '"=?UTF-8?B?'.base64_encode('Nom : éèàïî').'?=" <me@example.com>';
$body = 'Corps du message avec des accents aussi : éèàïî';

// Entêtes du message
$headers = array();
$headers[] = 'From: '.$sender;
$headers[] = 'Content-Type: text/plain; charset=UTF-8; format=flowed;';
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-Transfer-Encoding: 8bit';
$headers = join("\n", $headers);

// Envoi du mail
mail($recipient, $subject, $body, $headers);

« Ce code utilise l’UTF-8, c’est l’encodage par défaut de tout mon code en général que ca soit pour les fichiers, la base de données ou le « Content-Type » envoyé au navigateur. L’UTF-8 permet de faire des applications qui acceptent et utilisent n’importe quel caractère de n’importe quelle langue et sera en plus l’encodage par défaut pour le PHP6 à venir ce qui est une bonne chose.

Bien sûr, il faut mettre dans dans une fonction pour une meilleure factorisation, si je laisse ce code tel quel, c’est pour mieux en comprendre le mécanisme. Une visite de la documentation de la fonction mail() et des commentaires associés apportent de meilleures solutions. On y voit par exemple l’utilisation d’un code tel que celui-ci :

$subject= mb_encode_mimeheader($subject,"UTF-8", "B", "\n");

Je n’ai pas poussé mes investigations plus loin à ce niveau mais la lecture de la documentation de la fonction mb_encode_mimeheader() ne pourrait être que bénéfique. […] »

Importer WordPress sur des pages externes

Source : http://vogsphere.fr/importer-wordpress-sur-des-pages-externes/

Pour utiliser une installation WordPress sur une page externe, il faut importer les fichiers suivants :

wp-config.php, wp-load.php, wp-db.php (voir détails sur page source en référence).

Par exemple, pour récuprérer l’url du site WordPress dans une page test.php à la racine du site et ne faisant pas partie de l’installation WordPress, on écrira en tête du fichier :

<?php
define('WP_USE_THEMES', false);
include_once('wp-config.php');
include_once('wp-load.php');
include_once('wp-includes/wp-db.php');

$accueil =  home_url( '/' );
?>

jQuery et WordPress

Pour utiliser jQuery dans un thème WordPress, on peut :

– Soit activer la bibliothèque jQuery intégrée à WordPress, si elle n’est pas déjà activée dans le thème utilisé, avec la commande suivante :
wp_enqueue_script('jquery');
puis utiliser le sélecteur jQuery au lieu de $ (du fait de l’activation du mode « noConflict » dans la bibliothèque jQuery de WordPress) (v. un exemple ici).

– Soit appeler jQuery depuis une autre source en ligne ou sur une installation personnelle (p. ex. dans le thème personnalisé – v. cet article d’Alsacréations).

Ajouter le nom de la page (identifiant) dans les valeurs de la classe de la balise <body>

D’après http://www.geekpress.fr/wordpress/astuce/slug-page-body-class-1894/ <archivé>

Pour ajouter dans l’attribut class de la balise body l’identifiant texte (« slug ») de la page courante, il faut créer un script dans le fichier functions.php du thème qui ajoutera automatiquement l’identifiant via body_class(); dans le fichier header.php du thème.

Script à inscrire dans functions.php :

add_filter( 'body_class', 'add_slug_body_class' );
function add_slug_body_class( $classes )
{
  if ( is_page() )
  {
    global $post;
    $classes[] = $post->post_type . '-' . $post->post_name;
  }
  return $classes;
}

Code pour la balise body dans header.php :

<body <?php body_class(); ?>>

Restriction d’accès simple en PHP

d’après la source : forum.pluxml.org/viewtopic.php?id=1873

<?php
if ( !isset($_SERVER['PHP_AUTH_USER'])
	|| !isset($_SERVER['PHP_AUTH_PW'])
	|| ($_SERVER['PHP_AUTH_USER'] !== 'toto' )
	|| ($_SERVER['PHP_AUTH_PW'] !== 'passe') )
{
	header('WWW-Authenticate: Basic realm="Identification :"');
	header('HTTP/1.0 401 Unauthorized');
	echo '<html><head>';
	echo '<title>Acc&egrave;s Refus&eacute</title></head><body>';
	echo '<h1>Acc&egrave;s Refus&eacute</h1>';
	echo '</body>';
	exit;
}
?>

voir aussi : php.net/manual/fr/features.http-auth.php

Protéger les fichiers d’un répertoire par redirection

Empêche l’accès direct par l’url à un fichier d’un répertoire protégé par ce script htaccess.

Il reste possible de télécharger un fichier du répertoire via un fichier PHP utilisant un script spécifique (agissant au niveau HTTP) forçant le téléchargement d’un fichier (demandé via un formulaire distant par exemple).

Contenu du htaccess :

  • Première ligne : Active le moteur de réécriture
  • Deuxième ligne : Indique une condition = « Si la requête concerne un fichier… »
  • Troisième ligne : Indique une règle de réécriture. Dans l’exemple, on affiche le fichier index.php du répertoire.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.+$ index.php [L]

 

Notes :

  • Sur la deuxième ligne, pour indiquer que la requête ne concerne par un fichier, il faut terminer par !-f
  • On peut indiquer une condition de requête portant sur un répertoire en terminant par -d.
    Exemple : RewriteCond %{REQUEST_FILENAME} -d
  • [L] (troisième ligne) permet de terminer le processus de réécriture en cours

 

Rechercher – remplacer dans une base MySQL

La syntaxe est de la forme :

UPDATE table SET colonne_de_la_table = replace(colonne_de_la_table,'texte_à_remplacer','texte_de_remplacement');

Exemple :

UPDATE wp_links SET link_name = replace(link_name,'Documentation','Références');

Note : c’est un « rechercher-remplacer » systématique (i.e. toutes les occurrences du terme à remplacer seront traitées dans la table visée, pour toutes les entrées de la table).

PNG transparent – problèmes avec Internet Explorer

Les PNG transparents sont normalement reconnus par IE7 et IE8. Si un problème d’affichage survient (la couche Alpha étant couverte par un aplat noir ou gris, comme avec IE6) il faut vérifier si un attribut CSS d’opacité n’est pas appliqué à l’image. Tout attibut/filtre d’opacité (filter: alpha(opacity = 100)) doit être supprimé.

Attention : l’attribut d’opacité peut provenir d’un script JavaScript.

Il existe une méthode pour corriger ce problème : www.jacklmoore.com/notes/ie-transparency-problems

 

Lancement d’un script à la fin du chargement de la page

Pour qu’un script soit exécuté après le chargement complet d’une page HTML, il faut utiliser window.onload plutôt que <body onload="….

Exemple de script :

window.onload = function() {
function foo() {
alert("test");
}
setInterval(foo, 500);
}

Source (utile !) : http://stackoverflow.com/questions/2162267/setinterval-and-window-onload-problem

Remarque : window.onload ne peut être appelé qu’un seule fois, mais des solutions (JQuery…) permettent de lancer plusieurs scripts.

Des exemples (non testés) :

REGEXP – Expression régulière pour les requêtes SQL

Avec REGEXP, il est possible de rechercher un terme ou une chaîne particulière à l’intérieur d’un champ d’une base MySQL, selon les méthodes des expressions régulières.

Exemple :

mysql_query("SELECT * FROM table WHERE champ1 REGEXP 'bout'");

La chaîne de caractères « bout » est recherchée à l’intérieur du champ « champ1 ».

Voir aussi cette page : http://blogs.developpeur.org/poppyto/archive/2005/11/15/14581.aspx

Voir aussi :

Guillemets simples ou doubles (' ou ")

Avec des guillemets simples pour echo, la chaîne de caractères est transcrite telle quelle, alors qu’avec des guillemets doubles, les variables ou des caractères spéciaux (ex. caractère d’échappement) peuvent être interprétés.

Exemple :

<?php
$a = 'test';
echo '<p>$a\n</p>'; // exemple 1
echo "<p>\n$a\n</p>"; // exemple 2
?>

« exemple 1 » écrira :
<p>$a\n</p>

« exemple 2 » écrira :
<p>
test
</p>

Définir le fichier index par défaut

Il est possible de définir le fichier index par défaut avec la commande DirectoryIndex, syntaxe de la forme :

DirectoryIndex index.php index.html accueil.php index.phtml /erreurs/403.php

Les fichiers sont indiqués dans l’ordre de priorité : dans l’exemple ci-dessus, le navigateur devra afficher le premier fichier cité (index.php), s’il ne le trouve pas, le fichier suivant etc.

Gestionnaires de newsletters gratuits

En ligne:

MailChimp :
En ligne, très pratique et efficace – adopté !

Systèmes à installer :

Pommo :
(+) gère le « multipart » (text + html) ; complet ; interface assez réussie, plutôt agréable et intuitive ; gestion de templates ; multilingue
(-) pour créer et utiliser un template html complet (header compris), le wysiwyg doit être désactivé ; des erreurs dans la traduction française (contre-sens, termes inappropriés)

PHP List (v. 2.10.12) :
(+) « multipart » ; succès de cet outil, très répandu (mais personnellement je ne l’apprécie pas) ; complet
(-) « bridé » (on ne peut pas personnaliser le <header> d’un template html)

phpMyNewsletter (v. 0.8b5) :
(+) « multipart »
(-) « bridé » (pas d’accès au <header> d’un message ou du template html) ; pas de wysiwyg

Plugin(s) WordPress : MailPress : Excellent
(+) « multipart » ; très complet
(-) trop complet ? (on peut s’y perdre un peu, tous les plugins Mailpress n’ont pas forcément besoin d’être tous activés, système complexe donc risque de bug non négligeable)

Autres gestionnaires :

Tellmatic
NewsletTux
Wanesletter

voir aussi sur opensourcescripts.com

Clients e-mails à tester :

Mac : Thunderbird, Apple Mail
Win : Thunderbird, Outlook, Outlook Express, Windows Live Mail
Webmails : GMail, Hotmail, Yahoo.fr, Laposte.net, gmx.fr, Roundcube, Squirrelmail, Horde, atmail, Hastymail, Ilohamail…

Divers

un forum sur les newsletters

Mention spéciale : selfhtml.org

Il y a des ouvrages comme ça qui deviennent incontournables, qui deviennent des références.

Il ne me semble pas que selfhtml.org soit aussi souvent cité qu’il le mériterait, et pourtant… Je tenais en tout cas à rédiger cette petite mention spéciale pour le site selfhtml.org.

Ce site est une mine, notamment  pour l’apprentissage de JavaScript et des CSS mais aussi du HTML et de quelques autres domaines techniques. Le travail de Stefan Münz et Serge François est colossal et d’autant plus remarquable que totalement bénévole. Un grand merci à eux (à titre posthume hélas pour Serge François).

Le site est en outre téléchargeable est consultable en local – très pratique – et c’est pour moi une documentation essentielle, toujours à portée de clic, depuis quelques années et qui le restera encore longtemps je pense. Je dirais que 90 % de ce que j’ai appris de JavaScript et des CSS provient de selfhtml.org.

Variables globales et locales

référence : http://fr.selfhtml.org/javascript/langage/variables.htm#definir

variables locales : ne sont disponibles que dans la fonction courante

variables globales : sont disponibles pour toute la page et pour toutes les fonctions

  • Une variable déclarée par var à l’intérieur d’une fonction est une variable locale ; elle ne sera disponible que dans la fonction dans laquelle elle a été déclarée.
  • Une variable non déclarée par var à l’intérieur d’une fonction sera globale.
  • Une variable déclarée (précédée ou non de var) à l’extérieur d’une fonction sera toujours globale.

remarque : une variable non déclarée par var peut perturber/bloquer un script si aucune valeur ne lui est assignée

exemple :

<script type="text/javascript">
var nord_est;
sud_est = "suret";

function question() {
var sud_ouest;
nord_ouest = "noroît";

reponse = prompt("Ça souffle du nord-est, c'est le… ?","");
if(reponse == "nordet") { alert("exact"); } else { alert("Êtes-vous bien sûr ?… Une autre réponse était attendue."); }
}
</script>
  • Les variables nord_est, sud_est, nord_ouest et reponse sont globales ; la variable sud_ouest est locale.
  • Les variables sud_est et nord_ouest ont une valeur pré-définie, sans quoi le script risque de ne pas fonctionner correctement.

E-mail « multi-part » (texte + html)

Le script ci-dessous envoie un e-mail « multi-part » (texte + html) : selon le logiciel de messagerie et/ou les réglages de l’utilisateur, le contenu de l’un ou l’autre format est affiché.
Pour la gestion de newsletter, voir aussi wanewsletter.

Une autre source pour les mails multipart en php : www.vulgarisation-informatique.com/mail.php.

<?php
$destinataire = "destinataire@exemple.com";
$sujet = "Le sujet";
$messtxt = "message format texte";
$messhtml = "<html>code source html... </html>";
$from = "moi@exemple.com";

$boundary = "_parties_".md5 (uniqid (rand())); // génération d'une limite (boundary)
$limite = "--" . $boundary; // les parties du message ne sont reconnues que si le délimiteur (boundary) est précédé de 2 tirets

$entete = "Reply-to: $from\n";
$entete .= "From:$from\n";
$entete .= "Date: ".date("l j F Y, G:i")."\n";
$entete .= "MIME-Version: 1.0\n";
$entete .= "Content-Type: multipart/alternative;\n";
$entete .= "    boundary=\"$boundary\"\n\n"; // une tabulation (ou une espace) est indispensable ici avant "boundary" !

$corps = "This is a multi-part message in MIME format.\n";
$corps .= "Ceci est un message \"multi-part\" au format MIME.\n\n";

//Le message en texte simple pour les navigateurs qui n'acceptent pas le HTML
$corps .= "$limite\n";
$corps .= "Content-Type: text/plain; charset=\"ISO-8859-1\"\n";
$corps .= "Content-Transfer-Encoding: 7bit\n\n";
$corps .= $messtxt;
$corps .= "\n\n";

//le message en html original
$corps .= "$limite\n";
$corps .= "Content-Type: text/html; charset=\"ISO-8859-1\"\n";
$corps .= "Content-Transfer-Encoding: 7bit\n\n";
$corps .= $messhtml;
$corps .= "\n\n$limite\n";

if(mail($destinataire,$sujet,$corps,$entete))
{
echo 'Le mail a été envoyé';
}
else
{
echo 'Le mail n\'a pu être envoyé';
}
?>

vidéo en boucle

source : www.wisibility.com/blog/?2007/01/30/244-tutorial-flash-flv-en-boucle

script ActionScript à appliquer à la vidéo dans le flv :

// tutoriel flash sur wisibility.com
// script de lecture video en boucle

monLecteurVideo.addEventListener("complete", boucle);

function boucle(evtObj) {
	//avance la tete de lecture d'une valeur aleatoire entre 0 et 4 secondes
	//supprimer les 3 lignes suivantes pour une lecture en boucle normale
	var avance=Math.random()*4;

	trace(avance);
	evtObj.target.seek(avance);

	evtObj.target.play();
}

« monLecteurVideo » est dans ce script le nom donné à la vidéo dans le flv (c’est à dire le .mov importé par exemple, quot;FLVPlayBackquot; dans la bibliothèque)… voir tutoriel vidéo sur la source.

Pour upload de fichier par le web

La taille maximum autorisée pour uploader un fichier par le web varie en fonction de l’offre d’hébergement (ex. 2, 8 à 16 Mo chez OVH).
Pour connaître cette limite, créer un fichier php avec le code suivant :

<?php phpinfo(); ?>

Ouvrir le fichier avec le navigateur, et chercher la ligne : upload_max_filesize pour connaître la taille maximum.

Sélection d’entrées dans une table (requête SQL avec SELECT, FROM, WHERE…)

réf MySQL :
http://dev.mysql.com/doc/refman/5.0/fr/ix01.html

mysql_query("SELECT * FROM images WHERE type=’photo’ AND (ext=’jpg’ OR ext=’png’) OR type=’dessin’ ORDER BY date DESC LIMIT 0,10")

L’astérisque après SELECT indique « tous les champs ».

FROM précise la table dans la base sélectionnée au préalable (par « mysql_select_db »).

WHERE précise les valeurs à sélectionner dans un champ donné (valeur « photo » dans le champ « type »).

Opérateur logique AND : idem WHERE – ajoute un critère de recherche.

Opérateur logique OR : idem WHERE – critère de recherche alternatif.

Les parenthèses sont utiles pour grouper les valeurs recherchées en évitant des incohérences entres AND et OR

ORDER BY propose un classement selon un champ donnée (ex. ici par le champ « date »).

LIMIT suivi de 2 valeurs : première valeur indique la première entrée à sélectionner ; seconde valeur indique le nombre d’entrées à sélectionner.

Forcer le téléchargement

Forcer le téléchargement d’un fichier au clic, plutôt que son ouverture automatique dans le navigateur.

Exemple 1 :

référence : fr.openclassrooms.com/informatique/cours/…

Dans cet exemple, le fichier demandé est indiqué par un formulaire (transmission de la requête par méthode « post »).

Contenu du fichier de téléchargement que l’on nommera « telecharger.php » :

<?php
$erreur = "Votre requ&ecirc;te n'a pu aboutir ; veuillez v&eacute;rifier vos informations.";

if ($_POST) {
	if ($_POST['codeSecret']=="toto") {
		$chemin = realpath('toto.pdf');
	}
	else goto message;

	// Les données reçues sont un fichier à télécharger :
	header('Content-Description: File Transfer');
	header('Content-Type: application/octet-stream');
	// Trouve le nom du fichier à télécharger afin de nommer le fichier téléchargé :
	header('Content-Disposition: attachment; filename=' . basename($chemin));
	// Transfert en mode binaire - les données ne seront tansférées telles quelles (non interprétées) :
	header('Content-Transfer-Encoding: binary');
	// 3 lignes suivantes : pas de mise en cache
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	// Trouve la taille du fichier : permet au navigateur de calculer le taux de chargement :
	header('Content-Length: ' . filesize($chemin));
	// Lit enfin le fichier :
	readfile($chemin);
	// On quitte afin d'éviter tout ajout de donnée risquant de corrompre le fichier :
	exit;
}
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>What Wonderful Wine</title>
</head>
<body>
<p><?php message: echo $erreur; ?></p>
</body>
</html>

Exemple de formulaire appelant le téléchargement de toto.pdf via le fichier « telecharger.php » :

<form action="telecharger.php" method="post">
<input type="hidden" name="codeSecret" value="toto" />
<button type="submit">Envoi Toto</button>
</form>

 

 

Exemple 2 : Par « QUERY_STRING »

Le lien d’appel du fichier (depuis n’importe quelle page du site autre que la page « appel.php ») doit être du type () :

<a href="appel.php?file=exemple.mp3">exemple.mp3</a>

En tête de la page « appel.php », avant le Doctype :

<?php
$file=$_GET['file'];

$taille=filesize("fichiers/$file");
header("Content-Type: application/force-download; name=\"$file\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: $taille");
header("Content-Disposition: attachment; filename=\"$file\"");
header("Expires: 0");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
readfile("fichiers/$file");
exit();
?>

Remarques :
– le chemin au fichier est ici précisé dans le script PHP (« exemple.mp3 » est dans le sous-dossier « fichiers »)