Import ICS — agenda distant

Le plugin “Import ICS” permet l’ajout automatique d’évènements distants dans la liste des évènements d’un site.

Le besoin

Le plugin Agenda permet de gérer des évènements. Il peut être utile de récupérer automatiquement des évènements d’un site distant qui fournirait un fichier .ics, afin de proposer un site agrégeant les calendriers de différents sites.

Exemple de cas d’application:

  • des séminaires de recherche de plusieurs organismes diffusés sur le même site;
  • un site d’information locale reprenant les évènements des associations et entreprises locales;
  • un site d’association affichant les évènements de ses partenaires.

Utilisation avec un site SPIP distant

Dans le cas d’un site distant sous SPIP utilisant le plugin agenda, le fichier .ics distant est disponible à la page http://url-du-site/spip.php?page=agenda-ical. Un paramètre &id_article=xxx ou &id_mot=xxx peut être ajouté pour filtre par article ou par mot clé.

Fonctionnement

Ce plugin permet de s’abonner à un calendrier distant. L’abonnement se fait via la création d’un nouvel objet “Almanach”. Celui-ci est lié à un fichier ics distant. Le plugin lira régulièrement ce fichier et ajoutera automatiquement des évènements dans la base de données du site SPIP local. Les évènements créés sont du même type que ceux gérés par le plugin Agenda.

Les évènements ainsi ajoutés seront liés:

  • à l’almanach;
  • à l’article choisi lors de la création de l’almanach;

Ce plugin ajoute donc une entrée “Almanachs” au menu “Édition” ainsi qu’un bouton d’ajout rapide d’almanach. Les évènements importés sont liés à ces objets.

La page {Almanachs} permet de lister les almanachs présents sur le site et de les administrer.

Configuration du plugin

Une fois le plugin installé, il existe deux possibilités de configurer le plugin:

  • soit à travers le formulaire accessible à travers le lien de configuration sur la page de gestion des plugins ;
  • soit par des constantes PHP mises dans le fichier mes_options.php – ou dans un fichier options.php d’un plugin. Ceci permet de déployer rapidement à grande échelle une configuration du plugin.

La configuration PHP l’emporte sur la configuration par formulaire.

Voici la liste des paramètres configurables:

  • Définir l’article par défaut. Pas de constante PHP.
  • Archiver automatiquement les évènements distants qui ne sont plus présents dans le fichier ics distant lors de la vérification de celui-ci. En PHP define ('_IMPORT_ICS_DEPUBLIER_ANCIENS_EVTS','on');.
  • Ne pas importer les évènements passés, utiles pour les sites qui se contente d’afficher les évènements à venir.
  • Permettre d’éditer certains champs manuellement

Ajouter un almanach

L’ajout d’un almanach est simple. Il suffit de remplir le formulaire d’ajout dans lequel tous les champs sont obligatoires.

Formulaire d’ajout d’almanach

L’url du flux peut être de la forme http, https ou webcal.

Une fois le formulaire validé, les évènements importés apparaissent dans la page récapitulative de l’almanach. Si ces évènements sont trop nombreux, la liste est paginée. Le plugin récupérera à intervalle régulier la nouvelle version du flux pour mettre à jour la liste des évènements.

À noter :

  • si un évènement apparaît dans plusieurs flux avec le même uid (identifiant unique distant), il ne sera pas réimporté ;
  • afin que la reconnaissance de l’heure d’été / d’hiver puisse fonctionner, il est nécessaire que la configuration PHP ait un timezone correspondant à un pays où le changement d’heure est effectué. SPIP permet de configurer si besoin le timezone.

Supprimer un almanach

Pour supprimer un almanach, le passer en statut “à la poubelle”. Tous les évènements liés sont alors basculés en “à la poubelle”.

Comme pour les articles, SPIP supprime régulièrement les évènements et les almanachs à la poubelle.

Statut des évènements

Les évènements possèdent le statut de l’almanach:

  • si l’almanach est publié, les évènements sont automatiquement publiés (modération a posteriori), à condition que l’article lui-même soit publié ;
  • si l’almanach est proposé, les évènements sont proposés, et il vous faut les publier manuellement (modération a priori).

Lorsque vous modifiez le statut d’un almanach, les évènements voient leurs statuts modifiés.

Lorsque vous modifiez le statut d’un article, les évènements et almanachs liés voient leurs statuts modifiés.

Le plugin ajoute également un statut “archivé” aux évènements, pour les évènements qui ne sont plus présents sur le flux distant. Une fois un évènement archivé, il n’est plus jamais désarchivé, sauf intervention manuel d’une rédacteurctrice.

Mots-clé

Dans la configuration des mots-clé, vous pouvez activer l’ajout de mots-clés aux almanachs.

Les évènements associés à un almanach reçoivent automatiquement les mots-clé de l’almanach. Si les mots-clé de l’almanach changent, les mots-clé des évènements sont automatiquement modifiés.

Outils pour squelette

Le plugin ajoute le critère {id_almanach} sur la boucle (EVENEMENTS) pour sélectionner les évènements liés à un almanach précis.

Usages avancés

Champs extras, adresse, gestion des inscriptions

Le flux ICAL du plugin peut agenda peut transmettre, sous forme de propriété supplémentaire :

  • l’adresse (et pas seulement le lieu)
  • le nombre de places et s’il faut gérer les inscriptions
  • les éventuels champs extras Pour ce faire il faut definir à true la constant PHP _EVENEMENT_ICAL_X_PROPERTIES.

Techniquement, ces champs sont passés dans le flux ICAL sous forme de propriétés préfixées par X. Dans l’exemple ci-dessous, est indiqué l’adresse, le nombre de place, la gestion de la réservation ainsi qu’un champ extra public.

X-ADRESSE:3 place Babel
X-INSCRIPTION:1
X-PLACES:10
X-PLACES-RESERVEES:6
X-PLACES-RESTANTES:4
X-PUBLIC:enfants

Un site SPIP peut abonné à flux distant peut également insérer la valeur de ces champs dans sa base de données. Les champs synchronisés sont :

  • adresse
  • nombre d’inscriptions
  • gestion des inscriptions
  • champs extra, s’ils existent sur le site receveur, L’identification se base par homonymie. Ainsi dans l’exemple précédent, X-PUBLIC alimentera le champ public.

Pipeline

Le principe du plugin est de convertir des champs d’un flux ICAL en champ SQL. Le plugin propose des équivalences par défaut. Mais il est possible de modifier cela, en utilisant le pipeline evenement_ical_to_sql. Ce pipeline reçoit en arguments:

  • data la valeur des champs SQL qui seront mis en base;
  • args un tableau regroupant différents paramètres :
    • objet_evenement un objet PHP décrivant l’évènement, généré par la librairie IcalCreator
    • decalage : les infos à propos du décalage horaire pour l’almanach courant
    • dtend_inclus : si le DTEND est inclus dans l’évènement pour l’almanach courant
    • xprops les propriétés ICAL d’évènements préfixées par X; qui sont difficiles à récupérer depuis objet_evenement
    • champs_x la liste des champs SQL ayant des équivalents potentiels dans les propriétés ICAL préfixées par X (champs extra, gestion des inscriptions, etc).

Exemple : pour un site, je souhaite que la synchronisation des évènements récupère dans le champ places le nombre de places restantes, et non pas le nombre de places totales. Après avoir déclarer dans paquet.xml l’emploi du pipeline, je le règle ainsi :

function formations_evenement_ical_to_sql($flux = array()) {
	if (isset($flux['data']['places'])) {
			$flux['data']['places'] = $flux['args']['xprops']['X-PLACES-RESTANTES'];
	}
	return $flux;
}

Fréquence d’actualisation

Toutes les 5 minutes, sous réserves que le site soit visités, le plugin :

  • recherche le flux dont l’actualisation est la plus ancienne, s’il a été actualisé il y a plus de 1,5 h ;
  • recherche un flux qui a (éventuellement) échoué à être actualisé, il y a plus de 1,5 h, en commencant par celui dont l’echec d’actualisation est le plus ancien ;
  • actualise les 1 ou 2 flux trouvés.

Il est possible de définir dans un fichier mes_options.php la constante _PERIODE_IMPORT_ICS pour régler le temps d’actualisation (en secondes, par défaut 5400 = 1,5h).

Attention à ne pas actualiser trop souvent : lire un flux ICAL et l’interpréter mobilise des ressources importantes.

Discussion

23 discussions

  • 5

    Bonjour

    Vous dites : “Le plugin lira régulièrement ce fichier [ics distant]”.
    Mais quelle est exactement la périodicité. Je crois avoir lu 24h mais je ne retrouve plus où.
    Si c’est bien cela, c’est définitivement insuffisant.
    Quel est le meilleur moyen d’augmenter la fréquence ? (toutes les heures, voire 30mn me conviendrait)
    Ce serait grandiose si cela pouvait être un paramètre de configuration, sinon en attendant que faut-il bidouiller ?

    Merci !

    • Bonjour,

      le plugin actualise 1 flux toutes les 1,5 h, en alternances (et sous réserve que le site soit visités, puisqu’on se base sur le cron de SPIP). Autrement dit si vous avez 3 flux, chaque flux sera actualisé toutes les 3*1,5h = 4,5 h.

      Il est possible de définir dans un fichier mes_options.php la constante _PERIODE_IMPORT_ICS pour régler le temps (en secondes).

      > Si c’est bien cela, c’est définitivement insuffisant.
      Précisons, insuffisant pour votre cas d’usage. Tout dépend des besoins. Lire et interpréter un flux ICAL mobilise des ressources, donc il est normal de ne pas le faire trop souvent.

    • Merci pour ces informations !
      Ne devraient-elles pas être précisées dans la documentation ?

    • Si, mais actualiser une doc au fur et à mesure des dev n’est pas évident.

      C’est fait.

    • C’est aussi pour cela qu’il y a des forums...
      Encore merci !

    • En tombant sur le code hier par hasard, je me suis apercu que j’ai dit n’importe quoi sur cette affaire d’actualisation. Je viens de modifier la doc pour dire ce qu’il en est.

      En gros, sauf echec d’actualisation sur un flux, on actualise toutes les 5 minutes un flux qui a été actualisé il y a plus de 1,5, en commencant par celui qui a été actualisé le plus loin dans le passé.

    Reply to this message

  • 1

    Encore un problème.

    Mon site est multilingue en Français (langue de référence), Anglais et Italien.

    En français la page https://dev.brochards.com/spip.php?page=testcal&id_article=20 affiche bien des dates d’événements (Donnez user=spipeur pass=merci, et avancez éventuellement à février 2026).

    En italien avec https://dev.brochards.com/spip.php?page=testcal&id_article=20&lang=it, tout s’affiche aussi comme prévu dans cette langue.

    Mais en anglais avec https://dev.brochards.com/spip.php?page=testcal&id_article=20&lang=en le calendrier mini commence à january 1 (l’an 1 au lieu de 2026).

    J’imagine que c’est dû aux formats de date anglais... mais c’est bien gênant.

    Le squelette simplifié est le suivant :

    #CACHE{0}
    <!DOCTYPE html>
    <html dir="#LANG_DIR" lang="#LANG">
    <head>
    <meta http-equiv='Content-Language' content='#LANG' />
    <meta http-equiv='Content-Type' content='text/html; charset=#CHARSET' />
    #INSERT_HEAD
    <!-- fin insert_head -->
    <title>[(#NOM_SITE_SPIP|textebrut)] - [(#TITRE|textebrut)]</title>
    </head>
    <body>
    [(#REM) L'article demandé dans l'URL sans tenir compte de la langue demandée]
    <BOUCLE_article_demande(ARTICLES) {id_article}>
      <BOUCLE_art_ref(ARTICLES) {traduction} {origine_traduction}>
        #SET{idart_ref,#ID_ARTICLE}
      </BOUCLE_art_ref>
    </BOUCLE_article_demande>
    <div>
    <p>Article_ref= #GET{idart_ref}<br /> #MAINTENANT</p>
    #CALENDRIER_MINI{#SELF, #URL_PAGE{calendrier_mini_dispo.json,id_article=#GET{idart_ref}}}
    </div>
    </body>
    </html>
    • Ce problème est lié à calendrier mini, je vous invite à en discuter sur le forum du plugin en question, ou sur discuter.spip.net

    Reply to this message

  • 3

    Bonjour
    Je rencontre un problème bizarre avec un almanach.

    Après sa création je l’ai associé à l’article 1 et je pouvais en lister les événements avec, par exemple le code ci-dessous, en passant l’article 1 en argument :

    [<BOUCLE_agenda(EVENEMENTS){id_article}{par date_debut}{', '}>
    [(#ARRAY{
    id,#ID_EVENEMENT,
    title,"Réservé",
    allDay,#EVAL{false},
    start,#DATE_DEBUT,
    end,#DATE_FIN,
    url,#URL_EVENEMENT,
    className,calendrier-couleur-reserve,
    description,""}|json_encode)]
    </BOUCLE_agenda>]

    J’ai eu besoin de le changer d’article, il a donc été associé à l’article 20 (avec l’espace privé).

    Dans l’espace privé il apparaît bien avec l’article 20 avec le nombre d’événements attendu. Dans la base de données également.

    Mais la boucle ci-dessus ne me retourne ses événements que si je mets l’ancien article 1 en argument. Avec l’article 20, aucun événement n’est trouvé.

    J’ai, bien sûr, recalculé la page, désactivé, effacé le cache et attendu plusieurs heures...

    Que faire ?

    • Hum. Etrange.

      L’article 20 est bien publié ? Et les evenement sont bien associés à l’article 20 ?

    • Oui, l’article était bien publié et les événements visibles.

      Ce soir, c’était la même chose.
      Puis, pour faire quelques essais, j’ai juste créé un second almanach qui a pris le n° 3 (pourquoi ?) avec la même source ical et l’ai associé au même article 20. Je le publie, et là je vois apparaître les dates attendues dans le calendrier mini sans toucher à rien d’autre ! Ensuite, je mets à la poubelle ce dernier almanach et tout fonctionne bien...

      Est-ce qu’il n’y a pas un problème de cache mal rafraîchi ? (pourtant désactivé et effacé).

      Problème résolu, mais qui reste potentiellement inquiétant.

    • Le plugin n’a pas de cache spécifique, il se base sur le cache de spip.

      > les événements visibles.

      Vous voulez dire visible sur la page de l’article 20 ?

      > Est-ce qu’il n’y a pas un problème de cache mal rafraîchi ? (pourtant désactivé et effacé).

      le plugin n’a pas de cache spécifique. Mais si votre problème concerne uniquement le calendrier mini, il se peut qu’il y ait un cache navigateur sur la requete au JSON.

    Reply to this message

  • 1

    Bonjour,

    J’ai une erreur :
    Got error 'PHP message: PHP Fatal error:  Uncaught Error: Undefined constant Kigkonsult\\Icalcreator\\Vcalendar::PRIVATE in /home/mutu/web/_mutu/plugins/auto/import_ics/v4.2.1/inc/import_ics.php:75 Stack trace: #0 /home/mutu/web/_mutu/plugins/auto/import_ics/v4.2.1/genie/import_ics_synchro.php(55): importer_almanach() #1 /home/mutu/web/_mutu/ecrire/inc/queue.php(265): genie_import_ics_synchro_dist() #2 /home/mutu/web/_mutu/ecrire/inc/queue.php(360): queue_start_job() #3 /home/mutu/web/_mutu/ecrire/inc/genie.php(98): queue_schedule() #4 /home/mutu/web/_mutu/ecrire/inc/utils.php(1104): inc_genie_dist() #5 /home/mutu/web/_mutu/ecrire/inc/utils.php(1072): cron() #6 /home/mutu/web/_mutu/ecrire/public/aiguiller.php(80): action_cron() #7 /home/mutu/web/_mutu/ecrire/public.php(98): traiter_appels_actions() #8 /home/mutu/web/_mutu/spip.php(20): include('...') #9 {main}  thrown in /home/mutu/web/_mutu/plugins/auto/import_ics/v4.2.1/inc/import_ics.php on line 75'

    Je ne sais pas quoi faire pour aller plus loin.

    Reply to this message

  • 6

    Bonjour

    Je teste ce plugin en local sur un spip 4.1.10 et j’ai un souci : qaud je veux créer un almanach, la page ecrire/?exec=almanach_edit&new=oui ne m’affiche que “Créer un almanach / Sans titre” sans le formulaire de création.

    La même page sur un site en ligne en spip 4.2.3 m’affiche bien les éléments du formulaire à compléter.

    Je n’arrive pas à trouver d’où cela peut venir. Une piste ?

    Reply to this message

  • 3

    Bonjour,

    Est-ce que c’est une erreur de ma part, ou est-ce que ce plugin ne gère pas les événements récurrents ?
    En effet, j’ai essayé d’importer un agenda qui a été configuré en 2015 avec une date le 14 septembre, répétée chaque année et seule la date de 14/09/2015 est enregistrée.

    Je suppose que c’est parce que le plugin Agenda de SPIP ne gère pas les récurrences automatiques.

    • oui, le plugin ne gère pas la récurrence des evenements, précisement à cause du fait qu’agenda spip ne le gère pas. Il faudrait imaginer un système pour gerer la recurrence jusqu’a une certaine date, mais c’est compliqué et pas évident.

    • Est-ce qu’il serait imaginable de créer les prochaines répétions jusqu’à +365 jours ?

    • tout est imaginable, reste à avoir du temps. Mais je pensais plutot à une extension d’agenda qui gérerait la récurrence par date, et crééerai tous seul la recurrence.

    Reply to this message

  • 2

    Bonjour.
    Les événements récurrents (importés depuis un webcalendar) n’apparaissent qu’à la date initiale. Une idée ?
    Merci de toutes façons pour ce super outil. Depuis qu’agenda est passé en événements et non plus en articles, c’était vraiment galère pour synchroniser....
    Alain

    • C’est un peu compliqué à gérer, car les evenemtns dans SPIP n’ont pas de vraie idée de récurrence. C’est pourquoi je n’ai pas ajouté cette fonction : je ne vois pas comment gérer cela correctement.

    • Suggestion :
      -  si la récurrence a une date de fin ou un nombre limité d’itérations, créer les événements SPIP correspondants en utilisant la méthode d’agenda pour les événements récurrents (pour l’archivage, il faudra utiliser le champ “événement source” pour tout archiver je pense.).
      -  si pas de date de fin, ajouter un paramètre pour définir le nombre maximal d’itération à ajouter à SPIP.

      Ceci dit, je n’ai aucune idée de comment faire ça, et je ne sais même pas si c’est praticable :-)

    Reply to this message

  • 10

    Petit Bug détecté sur les imports d’événements dont la case “toute la journée” est cochée sur le site source.

    Dès que cette case “toute la journée” est cochée, import ICS ajouter j+1 pour la date de fin.

    Exemple : pour un événement dont les dates de début et de fin sont le 5 janvier, avec la case “toute la journée” cochée, l’import ics indique “du 5 janvier au 6 janvier”.

    J’ai vérifié sur le site d’origine, vider le cache et forcer l’actualisation... cette fois -ci ! Donc ça m’a bien l’air d’être un bug...

    Sinon, bravo pour toutes les améliorations de ce plugin... qui fait gagner un temps fou !

    • tu aurais une url de flux ical que je regarde?

      je pense que le problème est cela fonction de minuit à minuit

    • Le flux est celui du ciné-club françois truffaut.
      http://www.cineclubfrancoistruffaut.fr/?page=agenda-ical

      Voici un événement précis qui pose problème : http://www.cineclubfrancoistruffaut.fr/spip.php?article12&id_evenement=21

      Le résultat sur valleeducousin.fr :
      http://www.valleeducousin.fr/spip.php?article75#evt2223

      Mais tous les événements de ce type connaissent le même problème.

    • Les horaires des évènements sur une journée ne sont pas indiqués dans le flux ical:

      DTSTART;VALUE=DATE:20151005
      DTEND;VALUE=DATE:20151006

      Cela correspond effectivement à la note ICAL, qui indique que la propriété DTEND s’entend du moment de fin non inclus.

      http://www.faqs.org/rfcs/rfc2445.html

      Je vais donc modifier le plugin import-ics en ce sens.

    • La version 4.3.0 corrige le problème.

      Il faut simplement que tu efface les documents concernés, puisque tu réimporte (une fois avoir mis à jour le plugin!)

    • Je viens de rentrer... c’est pourquoi je n’ai pas répondu aux différents messages.

      C’est super, tout fonctionne ! Un grand merci !

    • Bonjour.
      Je suis confronté à un phénomène bizarre : en récupérant les évènement sur une instance webcalendar, mes événements à la journée apparaissent comme allant du jour à ... la veille ! En supprimant la correction introduite par Maïeul dans import_ics.php, ça a l’air de marcher. La norme ics aurait-elle changé ? dois-je chercher un bug ailleurs (dans webcalendar par exemple) ?
      Merci
      Alain

    • On pourrait avoir le flux ical en question pour voir s’il est correct ou pas ? Il se pourrait que ce soit ta source qui produit un flux non conforme à la norme ical...

    • La version 4.5.0 permet d’avoir une option pour ce genre de flux qui ne respectent pas la norme ICAL sur ce point.

    • Super réactivité :-)

      En ce qui concerne webcalendar, j’ai fait un rapport de bug et soumis une amorce de solution : supprimer l’émission de DTEND pour les événements intemporels. Ça a l’air de bie marcher ici avec import-ics 4.4.4. Mais ce n’est peut-être pas une solution complète.

      En tous cas, la nouvelle option de 4.5 permettra de s’en sortir avec d’autres sources qui ne seraient pas à la norme.
      Merci.

    Reply to this message

  • 1

    Pour la synchronisation avec framagenda (ou nextcloud) ça marche très bien !

    1/ Dans la colonne de gauche du framagenda, choisissez partager avec un lien public
    2/ cliquez sur l’icone du lien généré
    3/ la page de l’agenda public s’ouvre, récupérer son lien en haut à droite (bouton S’abonner)
    modifiez l’adresse de type

    webcal://framagenda.org/remote.php/dav/public-calendars/tgee5FmMq3IId55Wy?export

    par

    http://framagenda.org/remote.php/dav/public-calendars/tgee5FmMq3Xd55Wy?export

    4/ Entrez cette adresse sur la page d’édition de votre almanach SPIP (URL d’origine du calendrier)
    Et voila !

    • Merci pour ton retour.
      Il me semblait que les dernières version acceptaient directement le protocole webcal. Mais je me trompe peut être.

    Reply to this message

  • 1

    Bonjour à tous,

    Très bon plugin qui me donne toute satisfaction pour synchroniser des agendas distants de type indico.

    Je souhaite intégrer un widget calendrier à mon propre squelette sous boostrap 4 et c’est là que cela se complique !
    Comment procède-t-on pour intégrer les événements ics dans un calendrier type mini-calendrier ?

    Merci de votre aide

    Francis

    • aucune idée. Je n’utilise pas de mini calendrier ni de bootstrap.

      Le seul point que je peux dire : que ce soit des evenements distant ou des evenements internes, SPIP à la même structure, et donc tu peux faire les mêmes boucles.

    Reply to this message

Add a comment

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Who are you?
[Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom