Générer un évenement *.ics pour outlook en PHP

Il est maintenant possible de l’utiliser via composer :

"calendar/icsfile": "dev-master"

Salut,

Pour un besoin personnel j’ai du créer cette class PHP qui génère un événement pour Outlook, gmail…
Voici la classe en question :

<?php
/*
 * Variables used in this script:
 * $summary     - text title of the event
 * $dateStart   - the starting date (in seconds since unix epoch)
 * $dateEnd     - the ending date (in seconds since unix epoch)
 * $address     - the event's address
 * $description - text description of the event
 * $filename    - the name of this file for saving (e.g. my-event-name.ics)
 */

namespace ical;

class ical {

    private $name;
    private $timezoneICal = 'Europe/Paris';
    private $dateStart;
    private $summary;
    private $dateEnd;
    private $filename;
    private $address;
    private $description;
    private $alarm        = FALSE;
    private $repeat       = FALSE;
    
    public function getName() {
        return $this->name;
    }

    public function getTimezoneICal() {
        return $this->timezoneICal;
    }

    public function getDateStart() {
        return $this->dateStart;
    }

    public function getSummary() {
        return $this->summary;
    }

    public function getDateEnd() {
        return $this->dateEnd;
    }

    public function getFilename() {
        return $this->filename;
    }

    public function getAddress() {
        return $this->address;
    }

    public function getDescription() {
        return $this->description;
    }

    public function getAlarm() {
        return $this->alarm;
    }

    public function getRepeat() {
        return $this->repeat;
    }

    public function setName($name) {
        $this->name = $name;
        return $this;
    }
   
    public function setTimezoneICal($timezoneICal) {
        $this->timezoneICal = $timezoneICal;
        return $this;
    }

    public function setDateStart($dateStart) {
        $this->dateStart = $this->_dateToCal($this->_human_to_unix($dateStart));
        return $this;
    }

    public function setSummary($summary) {
        $this->summary = $summary;
        return $this;
    }

    public function setDateEnd($dateEnd) {
        $this->dateEnd = $this->_dateToCal($this->_human_to_unix($dateEnd));
        return $this;
    }

    public function setFilename($filename) {
        $this->filename = $filename;
        return $this;
    }

    public function setAddress($address) {
        $this->address = $address;
        return $this;
    }

    public function setDescription($description) {
        $this->description = $description;
        return $this;
    }

    public function setAlarm($alarm) {

        if (is_int($alarm)) {
            $this->alarm = $alarm;
            return $this;
        } else {
            throw new \Exception(__CLASS__ . " : It's not an integer", 01);
        }
    }

    public function setRepeat($repeat) {
        $this->repeat = $repeat;
        return $this;
    }

    /**
     * @name getICAL()
     * @access public
     * @return string $iCal
     */
    public function getICAL() {

        $iCal = "BEGIN:VCALENDAR" . "\r\n";
        $iCal .= 'VERSION:2.0' . "\r\n";
        $iCal .= "PRODID:" . $this->getName() . "\r\n";
        $iCal .= "CALSCALE:GREGORIAN " . "\r\n";
        $iCal .= "BEGIN:VEVENT" . "\r\n";
        $iCal .= "DTSTART:" . $this->getDateStart() . "\r\n";
        $iCal .= "DTEND:" . $this->getDateEnd() . "\r\n";
        $iCal .= "SUMMARY:" . $this->_escapeString($this->getSummary()) . "\r\n";
        $iCal .= 'UID:' . uniqid() . "\r\n";
        $iCal .= 'LOCATION: ' . $this->_escapeString($this->getAddress()) . "\r\n";
        $iCal .= 'DESCRIPTION:' . $this->_escapeString($this->getDescription()) . "\r\n";

        if ($this->getAlarm()) {
            $iCal .= 'BEGIN:VALARM' . "\r\n";
            $iCal .= 'ACTION:DISPLAY' . "\r\n";
            $iCal .= 'DESCRIPTION:Reminder' . "\r\n";
            $iCal .= 'TRIGGER:-PT' . $this->getAlarm() . 'M' . "\r\n";
            if ($this->getRepeat()) {
                $iCal .= 'REPEAT:' . $this->getRepeat() . "\r\n";
            }
            $iCal .= "END:VALARM" . "\r\n";
        }
        $iCal .= 'END:VEVENT' . "\r\n";
        $iCal .= 'END:VCALENDAR' . "\r\n";
        return $iCal;
    }

    /**
     * @name _dateToCal()
     * @access private
     * @param string $timestamp
     * @return string
     */
    private function _dateToCal($timestamp) {

        return date('Ymd\THis\Z', $timestamp);
    }

    /**
     * @name _escapeString()
     * @abstract Escapes a string of characters
     * @param string $string
     * @return string
     */
    private function _escapeString($string) {
        return preg_replace('/([\,;])/', '\\\$1', $string);
    }

    /**
     * @name $setHeader();
     */
    public function setHeader() {
        header('Content-type: text/calendar; charset=utf-8');
        header('Content-Disposition: attachment; filename=' . $this->getFilename() . '.ics');
    }

    /**
     * @name _human_to_unix()
     * @desciption this function is from codeigniter frameWork
     * @param string $datestr
     * @return boolean
     */
    private function _human_to_unix($datestr) {

        $datestr = preg_replace("/\040+/", ' ', trim($datestr));

        if (!preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr)) {
            throw new \Exception(__CLASS__ . " : bad" . $datestr);
        }

        $split = explode(' ', $datestr);

        $ex = explode("-", $split['0']);

        $year  = (strlen($ex['0']) == 2) ? '20' . $ex['0'] : $ex['0'];
        $month = (strlen($ex['1']) == 1) ? '0' . $ex['1'] : $ex['1'];
        $day   = (strlen($ex['2']) == 1) ? '0' . $ex['2'] : $ex['2'];

        $ex = explode(":", $split['1']);

        $hour = (strlen($ex['0']) == 1) ? '0' . $ex['0'] : $ex['0'];
        $min  = (strlen($ex['1']) == 1) ? '0' . $ex['1'] : $ex['1'];

        if (isset($ex['2']) && preg_match('/[0-9]{1,2}/', $ex['2'])) {
            $sec = (strlen($ex['2']) == 1) ? '0' . $ex['2'] : $ex['2'];
        } else {
            // Unless specified, seconds get set to zero.
            $sec = '00';
        }

        if (isset($split['2'])) {
            $ampm = strtolower($split['2']);

            if (substr($ampm, 0, 1) == 'p' AND $hour < 12)
                $hour = $hour + 12;

            if (substr($ampm, 0, 1) == 'a' AND $hour == 12)
                $hour = '00';

            if (strlen($hour) == 1)
                $hour = '0' . $hour;
        }

        return mktime($hour, $min, $sec, $month, $day, $year);
    }

}

Pour l’utiliser voici le code :

 <?php      
 require_once 'vendor/autoload.php';

    use ical\ical;
try {
 
        $ical = new ical();
        $ical->setAddress('Paris');
        $ical->setDateStart('2014-11-21 15:00:00');
        $ical->setDateEnd('2014-11-21 16:00:00');
        $ical->setDescription('wonder description');
        $ical->setSummary('Running');
        $ical->setFilename(uniqid());
        $ical->setHeader();
       
    echo $ical->getICAL();
            
  
        } catch (Exception $exc) {
            echo $exc->getMessage();
}

Cette class est disponible sous Bitbucket, voici l’adresse https://bitbucket.org/colonelMoutarde/icalendar-generator.


Publié

dans

par

Étiquettes :

Commentaires

7 réponses à “Générer un évenement *.ics pour outlook en PHP”

  1. Avatar de maxime

    Bonjour Grand Maitre L,

    après quelques recherches je suis tombé sur ton site et ton travail, ça semble correspondre exactement à ce que je veux (envoyer un lien par mail pour intégrer un événement dans un agenda outlook/google etc). Je travaille sur une appli développée sous symfony 3, j’espère m’en sortir.

    Merci pour le boulot en tout cas !

    Petit Padawan M.

    1. Avatar de Grand Maître L

      Merci beaucoup 🙂

  2. Avatar de Grand Maître L

    J’ai corrigé la doc, elle comportait une petit erreur

  3. Avatar de Cossais
    Cossais

    Bonjour,

    Tout d’abord, félicitation pour ton travail !
    Je dois moi aussi faire une invitation avec envoi de mail.
    Mais dans ta classe et comment tu utilises ton code, je ne vois pas comment l’invitation va arriver chez ton destinataire… Je n’ai pas compris où mettre ton code après ton exemple pour qu’il aille à ton destinataire, il faut bien un destinataire et un mail de départ pour pouvoir envoyer l’invitation .. ?

    Merci d’avance,

    Cordialement,

    Julien COSSAIS

    1. Avatar de Grand Maître L

      Salut,
      La classe se contente de générer un fichier de type .ics, libre à toi de générer le fichier et de le mettre en pièce jointe d’un eMail. Tu peux aussi créer un lien (url) qui va appeler la class pour générer le fichier. Si l’utilisateur a outlook ou un équivalent sur son smartphone, l’appareil va reconnaitre le format et ouvrir la bonne application.

      1. Avatar de Cossais
        Cossais

        Je ne sais pas si c’est moi, mais ton namespace me perd la classe, quand je l’a commente ça marche.
        Et aussi normalement, remplace $require_once(‘ical.php’); par require_once(‘ical.php’); pour appeler ton fichier ical.php.

        Si je me trompe dis moi !

        Merci d’avance

        1. Avatar de Grand Maître L

          Je te conseille fortement d’utiliser composer, l’installation et l’utilisation se fera très simplement.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.