Skip to content

Instantly share code, notes, and snippets.

@judbd
Last active November 23, 2015 19:47
Show Gist options
  • Save judbd/dbb958dcf435722ae9ba to your computer and use it in GitHub Desktop.
Save judbd/dbb958dcf435722ae9ba to your computer and use it in GitHub Desktop.
<?php
/*
l'idée première est d'ajouter un tag en kirbytext, pour avoir des dates dynamiques en markdown,
par ex pour dire "j'ai 30 ans" et ne pas l'updater tous les ans, mettre j'ai (from:1985) par ex
l'explication de comment ajouter des tags est ici, mais ça ça va : http://getkirby.com/docs/advanced/kirbytext
*/
kirbytext::$tags['from'] = array(
'attr' => array(
'to',
'format'
),
'html' => function($tag) {
$now = date('Y-m-d');
/*la date de départ qui peut être sous n'importe quelle forme genre 2002 ou 2002-01 ou 2002-05-06 */
$from = $tag->attr('from');
/*la date de fin qui peut être sous n'importe quelle forme genre 2015 ou 2008-01 ou 2012-05-06 */
$to = $tag->attr('to', $now);
/*lle format d'affichage mais on verra ça plus tard */
$format = $tag->attr('format', 'y');
/*
ACCEPTED FORMATS (pour le moment que Y)
http://php.net/manual/en/dateinterval.format.php
Y Years, numeric, at least 2 digits with leading 0 01, 03
y Years, numeric 1, 3
M Months, numeric, at least 2 digits with leading 0 01, 03, 12
m Months, numeric 1, 3, 12
D Days, numeric, at least 2 digits with leading 0 01, 03, 31
d Days, numeric 1, 3, 31
a Total number of days as a result of a DateTime::diff() or (unknown) otherwise 4, 18, 8123
H Hours, numeric, at least 2 digits with leading 0 01, 03, 23
h Hours, numeric 1, 3, 23
I Minutes, numeric, at least 2 digits with leading 0 01, 03, 59
i Minutes, numeric 1, 3, 59
S Seconds, numeric, at least 2 digits with leading 0 01, 03, 57
s Seconds, numeric 1, 3, 57
R Sign "-" when negative, "+" when positive -, +
r Sign "-" when negative, empty when positive -,
*/
/*avant ça il faudrait une astuce pour compléter les dates incomplètes */
$from = new DateTime($from);
$to = new DateTime($to);
/*et là ça ne marche bien que si la date est complète genre 2012-01-01 */
$interval = $from->diff($to);
/*en vrai les formats ne marchent pas vraiment comme ça à part "a" et "Y" mais je verrai ça plus tard*/
return $interval->format('%'.$format);
}
);
@rgsone
Copy link

rgsone commented Nov 23, 2015

Ton idée est bonne, le problème vient du fait que, quand tu passe "2005" à strtotime ou à DateTime, il va interpréter la chaîne de caractère comme l'heure "20 h 05" au lieu de l'année "2005", voir ici.

Tu peux comme solution (un peu brute), détecter la longueur de la chaîne. Et suivant la longueur retourné ajouter les segments manquant.

if ( strlen( $from ) == 4 )
    $from .= '-01-01';
elseif ( strlen( $from ) == 7 )
    $from .= '-01'; 

puis simplement le passer à ton DateTime comme tu le fait dans ton code.

$from = new DateTime( $from );

C'est pas la solution la plus élégante mais c'est pour te donner une piste.

@HackJack-101
Copy link

Voici la solution que je te propose, elle est simple et utilise la strotime de PHP :
https://gist.github.com/Jack3113/50a56f069e55dbfca22b

@rgsone
Copy link

rgsone commented Nov 23, 2015

@Jack3113 le soucis persiste toujours avec ta solution. Le strtotime() interprétera toujours certaines années comme des heures. Voir le lien dans mon message.
En fait tu test juste les cas où strtotime() ne peut pas interpréter correctement la date, exemple :

# $test vaut false car la date doit être au format yyyy-mm-dd et non yyyy-dd-mm
$test = strtotime( "2005-19-02" );
# ici $test2 renverra bien un timestamp mais 2005 sera interprété comme l'heure "20 h 05" et non l'année 2005
$test2 = strtotime( "2005" );

@rgsone
Copy link

rgsone commented Nov 23, 2015

Ça devrait fonctionner :

kirbytext::$tags['from'] = array(
    'attr' => array(
        'to',
        'format'
    ),
    'html' => function( $tag ) {

        $from = $tag->attr( 'from' );
        $to = $tag->attr( 'to', '' );
        $format = $tag->attr( 'format', '%y' );

        # normalement il faudrait faire plus de vérification pour prendre en compte tous les cas
        # on pourrait tester le pattern avec des regex par exemple, pour restreindre à 3 formats
        # de date possible (yyyy-mm-dd ou yyyy-mm ou yyyy). Mais aussi tester si chaque segment
        # est un chiffre et si il rentre dans une tranche donnée, etc.

        # $to + $from len
        $fromLen = strlen( $from );
        $toLen = strlen( $to );

        # si from est du format yyyy
        if ( $fromLen == 4 ) $from .= '-01-01';
        # si from est du format yyyy-mm
        elseif ( $fromLen == 7 ) $from .= '-01';
        # si la chaîne n'est pas dans un format accepté on lance une exception
        elseif ( $fromLen != 10 ) throw new Exception( 'Le format de from n\'est pas valide.' );

        # on effectue les même vérifications pour $to
        if ( $toLen == 4 ) $to .= '-01-01';
        elseif ( $toLen == 7 ) $to .= '-01';
        # ici, on défini simplement $to à la date/heure actuelle
        elseif ( $toLen != 10 ) $to = 'now';

        $dtFrom = new DateTime( $from );
        $dtTo = new DateTime( $to );

        return $dtFrom->diff( $dtTo )->format( $format );
    }
);

@judbd
Copy link
Author

judbd commented Nov 23, 2015

Merci @rgsone j'ai l'impression que ça fonctionne, dommage que du coup ça tue les formats de style 02/1985 mais c'est pas grave, je vais essayer d'ajouter des tests pour que l'ajout des dates gère les différents formats et ajouter les 01 aux bons endroits.

<?php 
echo date("jS F, Y", strtotime("11.12.10")); 
// outputs 10th December, 2011 

echo date("jS F, Y", strtotime("11/12/10")); 
// outputs 12th November, 2010 

echo date("jS F, Y", strtotime("11-12-10")); 
// outputs 11th December, 2010  
?> 

@rgsone
Copy link

rgsone commented Nov 23, 2015

@judbd comme je l'explique en commentaire dans le bout de code il faudrait faire plein de tests pour gérer plus de chose. Ici j'ai juste donné une solution au problème avec les année simple et strtotime()/DateTime(). :) Gérer les dates ça demande du boulot. Mais heureusement y'a de bonne librairie comme Carbon.
Après tu as donné le lien d'un plugin pour kirby sur twitter, si ça répond à tes besoins c'est cool. Sinon regarde du côté de Carbon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment