Archive for the php Category

Logo

L’atelier sur XSLT proposait une découverte rapide du langage avant de passer directement aux exemples.

Un même fichier XML a été utilisé pour les différents cas d’utilisation de XSLT pour produire du HTML : côté client avec le navigateur qui effectue la transformation, sur la machine avec xsltproc et côté serveur avec PHP.

Click to continue reading

Un effort communautaire pour aider une ONG à avoir une présence web dernier cri — 4 et 5 octobre 2008 — Paris, La Cantine Numérique.

Durant le premier week-end d’octobre 2008, en seulement 2 jours, la communauté française Drupal construira un site web complet et actif pour une ONG. Gratuitement, et pour un résultat libre et open source.
Qu’y gagnera l’ONG choisie ?

Vous n’avez pas de présence internet, une présence internet médiocre, ou vous voulez faire un truc incroyablement cool sur le web ? Inscrivez-vous sur le site Drupal n’Go : http://www.drupalngo.org/user/register. Puis visitez http://www.drupalngo.org/fr/node/add/application pour remplir le formulaire de proposition de projets.

La communauté choisira une seule ONG pour ce premier évènement. Petites et grandes ONGs peuvent se porter candidates.

Click to continue reading

La gestion des dates sous PHP a toujours été compliquée (pour ne pas dire pénible). Aussi, nous avons commencé à réfléchir sur une classe Date (ou DateTime) qui simplifierait cela au cours d’un atelier du lundi.

Nous avons également fait une session intitulée “A la découverte de SproutCore”. SproutCore est un framework javascript qui a bénéficié du buzz lord de la dernière Keynote d’Apple. Aussi, il nous semblait intéressant de voir quel est le potentiel de ce framework. Nous sommes arrivés à la conclusion qu’il était encore trop tôt pour juger (pas encore de d’applications en ligne, pas de tutoriels à part le Hello World de base, etc.).

Pour ces 2 sessions, les slides sont disponibles : classe Date pour PHP et A la découverte de SproutCore.

Click to continue reading

I looked for a nice clean class implementation in PHP for embedding videos from youtube and such and could not find anything that was nice enough. So here is my take on embedding videos in php.
As the embed code is reconstructed it should be safe enough put probably some more checks need to be done after extracting the id to see there is nothing hostile there.

Configuration:
This class requires the SpyC library to read the cobnfiguration file. The library is assumed to be in the SITEBASE/include/yaml/ directory.

PHP:
  1. define('SITEBASE', '/var/www/mysite'); // path to the root of the site (not forcefully public)
  2. define('VIDEO_EMBED_CONFIG_FILE', SITEBASE.'/config/video_embed.yaml'); //path of video embed config file
  3. define('DEBUG', true); //to activate debug mode and false for production usage. it will write to a log file when something goes wrong but should not produce exceptions in production enviroment

USAGE
note: The embed code may either be embed or url

PHP:
  1. $embed='http://www.youtube.com/watch?v=h2EUW_rgDVo';
  2. $videoEmbed = new VideoEmbed($embed); //optional width and height may be passed to the constructor
  3. print($videoEmbed->embed);
  4. $videoEmbed->width = 240; // resize
  5. $videoEmbed->height = 120;
  6. print($videoEmbed->embed); // resized video
  7. print($videoEmbed->thumb); // get thumb url

the other public properties are: ->id, ->type, ->url, ->width and ->height
note that magic getters and setters are used to make ->id, ->type, ->url read only

TODO: thumbnails should be cached locally
TODO: Create unit tests (for the moment test_VideoEmbed(); does some testing)

The video services are configured in the configuration file (video_embed.yaml), form:

---
embedTemplate: default embed template
defaultWidth: default width
defaultHeight: default height
services:
    servicename:
        urlPattern: pattern to distinguis between services
        embedUrlTemplate: template (used with sprintf) for construvting the player url
        thumbnailUrlTemplate: template to find thumnbail by video ID (used with sprintf)
        thumbnailUrlExtractPattern: if present the thumbnailUrlTemplate is assumed to be a text resource, and this is a regexp to extract the thumnbail from it
        extractPattern: regexp pattern to extract
        apiUrl: api url (not used for the currently supported services)
        defaultWidth: service default width
        defaultHeight: service default height
		embedTemplate: specific embed template (not used for the current supported services)

Example configuration file for google video youtube and dailymotion (if you configure it for other services please post the config)... :)

---
embedTemplate: <object width="%2$s" height="%3$s" ><param name="movie" value="%1$s"></param><param name="wmode" value="transparent"></param><embed src="%1$s" type="application/x-shockwave-flash" wmode="transparent" width="%2$s" height="%3$s"></embed></object>
defaultWidth: 425
defaultHeight: 350
services:
    youtube:
        urlPattern: youtube.com
        embedUrlTemplate: http://www.youtube.com/v/%1$s&rel=1
        thumbnailUrlTemplate: http://i.ytimg.com/vi/%1$s/default.jpg
        extractPattern: /youtube\.com\/(v\/|watch\?v=)([\w\-]+)/
        apiUrl: http://www.youtube.com/api2_rest
        defaultWidth: 425
        defaultHeight: 350
    google:
        urlPattern: video.google
        extractPattern: /docid=([^&]*)/i
        embedUrlTemplate: http://video.google.com/googleplayer.swf?docId=%1$s
        thumbnailUrlTemplate: http://video.google.com/videofeed?docid=%s
        thumbnailUrlExtractPattern: '/

And here is the code :Complete class code with readme and configuration file

The code referes to a debug function, you can use:

PHP:
  1. function debug_log($msg, $file = "debug")
  2. {
  3.     $dbg = "";
  4.     if (SITE != '[PROD]') {
  5.         $bts = debug_backtrace();
  6.         foreach($bts as $bt) {
  7.             $path = str_replace(SITEBASE, '', $bt ['file']);
  8.             $dbg .= $path . " line " . $bt['line'] . " (function " . $bt['function'] . ")\n";
  9.         }
  10.         $handle = fopen(SITEBASE . "/../log/{$file}.log", "a");
  11.         fwrite($handle, strftime("%Y-%m-%d %H:%M:%S  ") . $dbg . $msg . "\n------------------\n");
  12.         fclose($handle);
  13.     }
  14. }

Click to continue reading

Our good and extremly competent friends at Bearstech saw my post about Geo encoding (Retrouver par code postal tous les lieux qui sont du même dépratement, de la même région ou de la même ville (mysql, php)) of French data and decided, this was no way to go around this! So Vincent Caron decided to create for all those interested a great GPLed package to help you will all your geocoding woes for France! so go over to the Bearstech forge (http://forge.bearstech.com/) where you can download the package or browse the php source code through the trac SVN interface.

Geo-Data (France) ¶
Features ¶

This is a compilation of simple administrative and geographic informations for France, up to the city and district level:

* 32,856 cities with their official zipcode and préfecture flag. Paris, Lyon and Marseille are split into arrondissements.
* 96 départements, 6 DOM and 3 TOM (within the same hierarchical level). Proper keying is used (ie. 2A for Corse du Sud, no "20" or "97" shortcuts).
* 22 régions, with two supplementary to classify départements from DOM and TOM.

Redundant data in all tables help make you sure you can all information available in a single SELECT lookup:

* asking for a département gives its région
* asking for a city also gives its corresponding département and région

Note: the city database might be incomplete, our source was not properly time stamped.
History ¶

This compilation of PHP and SQL code was extracted from a production real-estate web site, which uses extensively this geographical data to search, filter and match people wishes with other's desires.

The data was collected from various public french sources and meticulously, patiently reworked and modified by Bearstech according to professionnals and users feedback while using the data.
Copyright ¶

Click to continue reading

For the benefit of those who participated in the Google developers day presentation a French only post.

Dans ce billet vous trouverez les sources et les présentation de la session Google Maps lors du Google Developers Day à Paris du 31 mai 2007 . Dans le poste du 25 mai vous pouvez trouver le code pour travailler avec les adresses françaises... Suivez ce lien pour la présentation de Clément Hallet sur les bases d'utilisation de Google Maps API et celui ci pour la présentation sur des thèmes plus avancés (géocodage côté serveur, chargement asynchrone des marquers et calcul des distances).

Ici vous pouvez télécharger le code d'exemple utilisé dans la présentation Google Maps API - Basics. Notez que la clé utilisée (ABQIAAAAyzlxpGWavaTREVb4HcYiUhT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSYK1OvuhDXV84EQwe2sBFw6vUHtg) marchera sur http://localhost - adaptez la à vos besoins, pour générer votre propre clé Google Maps API cliquez ici (vous pouvez consulter mon billet sur la gestion de configuration par virtual host pour résoudre le problème des clés google utilisé conjointement avec mod_proxy et PHP ).

Click to continue reading

EN: Imagine you have a google maps application (or anything else that deals with places) with data in France, now often you would want to get places that are in the same area as one chosen by the user. Here is a bit of PHP code to help you with that...
It will help you select all the places from your database that have the same postal code (easy) are in the same city, are in the same department or are in the same region (a bit harder). All of this is extremely French and of no use anywhere else... Don't forget to download and importfrench_cities_zipcodes.zip into your MySQL database...

CAVEAT: This code has not been tested yet... There may be some typos in here...

FR: Vous voulez faire une petite application Google Maps ou n'importe quel code PHP où vous avez besoin de trouver pour un lieu les autres lieux qui sont de la même région, du même département ou de la même ville... Voilà un bout de code qui pourra vous être utile.
N'oubliez pas de télécharger et d'importer la table french_cities_zipcodes.zipdans votre base MySQL

CAVEAT: TCe code n'a pas encore été testé du tout... il peut y avoir de fautes de frappe...

PHP:
  1. /**
  2. * get Departments For Region By Postal Code
  3. * EN: This function will return all the French deprtments that are in the same region for a given
  4. * Postal code or the name of the region if $retournerNomRegion=True is passed
  5. * This code is VERY French specific.
  6. * FR: Cette fonction retourne tous les départements Français qui sont dans la même region qu'un code postal donné
  7. * Ou le nom de la région si la valeur $retournerNomRegion=true lui est passée
  8. * <b>USAGE</b>:
  9. * <code>
  10. * //Exemple:
  11. *   getDepartementsForRegionByPostalCode('75005');
  12. *  result:'75','77','78','91','92','93','94','95'
  13. *
  14. *  getDepartementsForRegionByPostalCode('75005');
  15. *  result: 'Ile de France'
  16. * </code>
  17. * @param   $zipcode string (we need to keep leading zeros) zipcode to search for
  18. * @return  always returns true
  19. * @author  ori@af83.com
  20. * @since   Wed March 19 2007 18:09:09 GMT+0200
  21. * @version v 0.01 Wed May 22 2007 18:09:09 GMT+0200
  22. * For an up to date version go to http://dev.af83.com
  23. */
  24.  
  25. function getDepartementsForRegionByPostalCode($zipCode, $retournerNomRegion=false)
  26.  
  27. {
  28. $liste_regions = array (
  29.     "Alsace" => array("67","68"),
  30.     "Aquitaine" => array("24","33","40","47","64"),
  31.     "Auvergne" => array ("03","15","43","63"),
  32.     "Basse-Normandie" => array ("14","50","61"),
  33.     "Bourgogne" => array ("21","58","71","89"),
  34.     "Bretagne" => array ("22","29","35","56"),
  35.     "Centre" => array ("18","28","36","37","41","45"),
  36.     "Champagne-Ardenne" => array ("08","10","51","52"),
  37.     "Corse" => array("20"),
  38.     "DOM-TOM" => array("97"),
  39.     "Franche-Comté" => array ("25","39","70","90"),
  40.     "Haute-Normandie" => array ("27","76"),
  41.     "Ile de France" => array("75","77","78","91","92","93","94","95"),
  42.     "Languedoc-Roussillon" => array("11","30","34","48","66"),
  43.     "Limousin" => array("19","23","87"),
  44.     "Lorraine" => array ("54","55","57","88"),
  45.     "Midi-Pyrénées" => array("09","12","31","32","46","65","81","82"),
  46.     "Nord / Pas-de-Calais" => array("59","62"),
  47.     "Pays de la Loire" => array ("44","49","53","72","85"),
  48.     "Picardie" => array ("02","60","80"),
  49.     "Poitou-Charentes" => array ("16","17","79","86"),
  50.     "PACA" => array("04","05","06","13","83","84"),
  51.     "Rhône-Alpes" => array ("01","07","26","38","42","69","73","74")
  52. );
  53.         $departement = substr($zipCode,0,2);
  54.        
  55.         foreach($liste_regions as $region => $liste_dep)
  56.         {
  57.             if (in_array($departement, $liste_dep))
  58.             {
  59.                 return $retournerNomRegion ? $region: implode (',',$liste_dep);
  60.             }
  61.         }      
  62. }
  63.  
  64. /**
  65. * get SQL For Search By zipcode
  66. * EN: This function will return an sql statement to search for either all places that are in the same postal code,
  67. * All places that are in the same town, all places that are in the same deparment or all places that are from the same region
  68. * We assume here you have a table "places" that has a column for the french zipcode. Change to meet your needs...
  69. * This code is VERY French specific.
  70. * To use this you will need to import the table (mysql format) joined to this blog post (french_cities_zipcodes) it contains the
  71. * correspondance between cities and zipcodes
  72. * FR: Cette fonction retourne une requête SQL pour retrouver par code postal tous les lieux qui sont du même code postal, de la même
  73. * Ville du même Déprtement ou de la même Région
  74. * Le code prend comme postulat l'existence d'une table "places" qui a une colonne "zipcode" pour le code postal.
  75. * Pour l'utiliser vous devez importer la table french_cities_zipcodes jointe à ce billet de blog qui contient la correspondance entre les code postaux et les villes.
  76. *
  77. * <b>USAGE</b>:
  78. * <code>
  79. * //Exemple:
  80. *   getSQLForSearchByzipcode('75005', 'zipcode');
  81. * </code>
  82. * @param   $zipcode string  zipcode to search for (we need to keep leading zeros)
  83. * @return  String Sql Statement
  84. * @author  ori@af83.com
  85. * @since   Wed March 19 2007 18:09:09 GMT+0200
  86. * @version v 0.01 Wed May 22 2007 18:09:09 GMT+0200
  87. * For an up to date version go to http://dev.af83.com
  88. */
  89.  
  90. function $getSQLForSearchByzipcode($zipcode,$resultFrom){
  91.         $sqlSelect=" SELECT * from places as p";
  92.         if($zipcode!='' && is_numeric($zipcode)){
  93.             switch ($resultFrom)
  94.             {   case 'zipcode': //places from the same zipcode
  95.                     $sqlWhere=" WHERE zipcode LIKE '".$zipcode."'  ";
  96.                 break;
  97.                 case 'region'//places from the same region
  98.                     $zipSearch= getDepartementsForRegionByPostalCode ($zipcode);
  99.                     $sqlWhere=" WHERE LEFT(p.zipcode,2) in (".$zipSearch.")  ";
  100.                 break;
  101.                 case 'departement': // in France all zipcodes from the same department start with the same two numbers which is the deprtment identifier
  102.                     $zipSearch=substr($zipcode,0,2);
  103.                     $sqlWhere=" WHERE LEFT(p.zipcode,2) = $zipSearch  ";
  104.                 break;
  105.                 case 'city': // for this you will need a table containing the correspondance between cities and postal codes in your database
  106.                     $sqlSelect=" SELECT * from places as p left join  `french_cities_zipcodes` as fcz on p.zipcode =fcz.`zipcode` left join `french_cities_zipcodes` as fcz2 on fcz.city=fcz2.city and fcz.departement=fcz2.departement ";
  107.                     $sqlWhere=" WHERE fcz2.zipcode='$zipcode'  ";
  108.                 break;
  109.             }
  110.         }
  111.         return $sqlSelect.$sqlWhere;
  112. }

Click to continue reading

If you want to log what a user is doing, or have any other reason to get his ip using HTTP_CLIENT_IP to get the remote user IP is not at all enough, if the client is connecting through a proxy (for an example your site is configured behind an apache_mod_proxy) you should also test for HTTP_X_FORWARDED_FOR and fall back on REMOTE_ADDR or you might always be getting the proxie's IP.

PHP:
  1. function getIP() {
  2. $ip;
  3.  
  4. if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP");
  5. else if(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR");
  6. else if(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR");
  7. else $ip = "UNKNOWN";
  8.  
  9. return $ip;
  10.  
  11. }

Click to continue reading

Sometimes (often) you would want your script to have different configurations based on the environment in which it runs (dev, test, prod). Sometimes the same script may even be run from the console and you really want to have a different configuration for that. Now you may run into some trouble using just the $_SERVER["HTTP_HOST"] variable. Even more so if you are running behind an proxy (such as mod_proxy for apache).

Here is a small snippet that will help you cover almost every instance... and tell you what is the execution context of the script so you can change the db setup, turn on or off the debugging etc...

Note that in this case the $vhost here may very well contain a list of hosts separated by commas.

PHP:
  1. if ((isset($_SERVER["SESSIONNAME"]) && $_SERVER["SESSIONNAME"] =="Console") || (isset ($_SERVER["TERM"])))
  2. {
  3.     $vhost="console";
  4. } else
  5.     {
  6.     if (isset($_SERVER["HTTP_X_FORWARDED_HOST"])){$vhost=$_SERVER["HTTP_X_FORWARDED_HOST"];}
  7.         else
  8.             {
  9.             if (isset ($_SERVER["HTTP_HOST"])) $vhost = $_SERVER["HTTP_HOST"];
  10.                 else 
  11.             $vhost = $_SERVER["SERVER_NAME"];
  12.             }
  13.     }
  14. switch($vhost){
  15.     case 'myproductionhost.com':
  16.         //setup configuration   
  17.     break;
  18.     case 'myproductionhost.com, someotherhostusingmodproxy.com':
  19.         //setup configuration
  20.     break;
  21.     case 'mytesthost.com':
  22.         //setup configuration
  23.     break;
  24.     case 'console':
  25.         //setup configuration
  26.     break;
  27.     case 'locahost':
  28.         //setup configuration
  29.     break;
  30.     }

Click to continue reading

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.0 License.