src/Twig/Extension/Apik.php line 768

Open in your IDE?
  1. <?php
  2. namespace App\Twig\Extension;
  3. use Twig\Extension\AbstractExtension;
  4. use Twig\TwigFunction;
  5. use Pimcore\Model\Document;
  6. use Pimcore\Model\Document as PimcoreDocument;
  7. use Pimcore\Model\Document\Page;
  8. use Pimcore\Tool\Transliteration;
  9. use Pimcore\Model\WebsiteSetting;
  10. use Pimcore\Tool;
  11. use Symfony\Contracts\Translation\TranslatorInterface;
  12. use Carbon\Carbon;
  13. class Apik extends AbstractExtension
  14. {
  15.      // Création de la variable $this->translator pour les traductions
  16.      private $translator;
  17.      public function __construct(TranslatorInterface $translator) {
  18.          $this->translator = $translator;
  19.      }
  20.     /** Listing des fonctions reprises en dessous de ce block */
  21.     public function getFunctions(): array
  22.     {
  23.         return [
  24.             new TwigFunction('build_data_object_url', [$this, 'buildDataObjectUrl']),
  25.             new TwigFunction('build_data_tag_url', [$this, 'buildDataTagUrl']),
  26.             new TwigFunction('build_data_tag_array_url', [$this, 'buildDataTagArrayUrl']),
  27.             new TwigFunction('get_localized_page_url', [$this, 'getLocalizedPageUrl']),
  28.             new TwigFunction('get_language_switcher', [$this, 'getLanguageSwitcher']),
  29.             new TwigFunction('get_language_switcher_html', [$this, 'getLanguageSwitcherHtml']),
  30.             new TwigFunction('email_obfuscator', [$this, 'emailObfuscator']),
  31.             new TwigFunction('email_obfuscator_svg', [$this, 'emailObfuscatorSvg']),
  32.             new TwigFunction('email_obfuscator_svg_only', [$this, 'emailObfuscatorSvgOnly']),
  33.             new TwigFunction('convert_phone_to_url', [$this, 'convertPhoneToPhoneUrl']),
  34.             new TwigFunction('get_body_class', [$this, 'getBodyClass']),
  35.             new TwigFunction('get_robots_index', [$this, 'getRobotsIndex']),
  36.             new TwigFunction('get_links_alternate', [$this, 'getLinksAlternate']),
  37.             new TwigFunction('website_config_advanced', [$this, 'websiteConfigAdvanced']),
  38.             new TwigFunction('to_url', [$this, 'toUrl']),
  39.             new TwigFunction('convert_date', [$this, 'convertDate']),
  40.             new TwigFunction('metadatas_image', [$this, 'metadatasImage']),
  41.             new TwigFunction('set_seo', [$this, 'setSeo']),
  42.             new TwigFunction('get_default_language', [$this, 'getDefaultLanguage']),
  43.             new TwigFunction('compare_date_submit', [$this, 'compareDateSubmit'])
  44.         ];
  45.         
  46.     }
  47.     /**
  48.      * Construit l'URL d'un Data Object
  49.      * @param $staticRouteNameNotLocalized Le nom de la Static Route non localisée (ex pour 'recette_fr', alors la valeur sera 'recette')
  50.      * @param $language La langue à retourner
  51.      * @param $dataObject Le Data Object
  52.      * @return $string
  53.      *
  54.      * Exemple:
  55.      * <?php
  56.      * $dataObjectUrl = buildDataObjectUrl('recette', $this->getLocale(), $monDataObject);
  57.      *
  58.      * Remarque:
  59.      * - Le code actuel ne prend en charge que les Static Route construite de la sorte: %lang/%prefix/%slug-%id
  60.      * - Le Data Object doit obligatoirement posséder un champ 'Slug'
  61.      * - Le champ slug doit être automatiquement généré via l'EventListener SaveDataObjectListener
  62.      */
  63.     function buildDataObjectUrl($staticRouteNameNotLocalized, $language, $dataObject)
  64.     {
  65.         //$staticRouteLocalized = \Pimcore\Model\Staticroute::getByName($staticRouteNameNotLocalized . '_' . $language);
  66.         $staticRouteLocalized = \Pimcore\Model\Staticroute::getByName($staticRouteNameNotLocalized);
  67.         if ($staticRouteLocalized) {
  68.             $link = $staticRouteLocalized->getReverse(); // %lang/%prefix/%slug-%id
  69.             $link = str_replace('%lang', $language, $link);
  70.             $link = str_replace('%prefix', $staticRouteLocalized->getDefaults(), $link);
  71.             if(strpos($link, '%slug') !== false):
  72.                 $link = str_replace('%slug', $dataObject->getSlug($language), $link);
  73.             endif;
  74.             if(strpos($link, '%name') !== false):
  75.                 $link = str_replace('%name', self::toUrl($dataObject->getName($language)), $link);
  76.             endif;
  77.             if(strpos($link, '%title') !== false):
  78.                 $link = str_replace('%title', self::toUrl($dataObject->getTitle($language)), $link);
  79.             endif;
  80.             $link = str_replace('%id', 'id'.$dataObject->getId(), $link);
  81.         }
  82.         return '/' . $link;
  83.     }
  84.     /**
  85.      * Construit l'URL pour un tag
  86.      * @param $staticRouteNameNotLocalized Le nom de la Static Route non localisée (ex pour 'recette_fr', alors la valeur sera 'recette')
  87.      * @param $language La langue à retourner
  88.      * @param $dataObject Le Data Object
  89.      * @return $string
  90.      *
  91.      */
  92.     function buildDataTagUrl($staticRouteNameNotLocalized, $language, $dataObject)
  93.     {
  94.         $staticRouteLocalized = \Pimcore\Model\Staticroute::getByName($staticRouteNameNotLocalized . '_' . $language);
  95.         if ($staticRouteLocalized) {
  96.             $link = $staticRouteLocalized->getReverse(); // %lang/%prefix/%slug-%id
  97.             $link = str_replace('%lang', $language, $link);
  98.             $link = str_replace('%prefix', $staticRouteLocalized->getDefaults(), $link);
  99.             $link = str_replace('%name', self::toUrl($dataObject->getName($language)), $link);
  100.             $link = str_replace('%id', 'id'.$dataObject->getId(), $link);
  101.         }
  102.         return '/' . $link;
  103.     }
  104.     function buildDataTagArrayUrl($staticRouteNameNotLocalized, $language, $dataArray)
  105.     {
  106.         $staticRouteLocalized = \Pimcore\Model\Staticroute::getByName($staticRouteNameNotLocalized . '_' . $language);
  107.         if ($staticRouteLocalized) {
  108.             $link = $staticRouteLocalized->getReverse(); // %lang/%prefix/%slug-%id
  109.             $link = str_replace('%lang', $language, $link);
  110.             $link = str_replace('%prefix', $staticRouteLocalized->getDefaults(), $link);
  111.             $link = str_replace('%name', self::toUrl($dataArray['name']), $link);
  112.             $link = str_replace('%id', 'id'.$dataArray['id'], $link);
  113.         }
  114.         return '/' . $link;
  115.     }
  116.     /**
  117.      * Localise une Page (Document) dans la langue courante à partir de son ID et retourne son URL (string)
  118.      * @param $objectThis L'objet $this appelée depuis la vue
  119.      * @param $pageId L'ID de la Page (Document)
  120.      * @return null|PimcoreDocument
  121.      *
  122.      * Exemple:
  123.      * echo Apik::getLocalizedPageUrl($this, 123);
  124.      */
  125.     public static function getLocalizedPageUrl($pageId)
  126.     {
  127.         $localizedPage = self::getLocalizedPage($pageId);
  128.         if ($localizedPage) {
  129.             return $localizedPage->getFullPath();
  130.         }
  131.         return '';
  132.     }
  133.     /**
  134.      * Localise une Page (Document) dans la langue courante à partir de son ID et retourne son document (objet)
  135.      * @param $objectThis L'objet $this appelée depuis la vue
  136.      * @param $pageId L'ID de la Page (Document)
  137.      * @return null|PimcoreDocument
  138.      *
  139.      * Exemple:
  140.      * $localizedPage = Apik::getLocalizedPage($this, 123);
  141.      * if ($localizedPage) {
  142.      *      echo $localizedPage->getFullPath();
  143.      * }
  144.      */
  145.     public static function getLocalizedPage($pageId)
  146.     {
  147.         $document = Document::getById($pageId);
  148.         if ($document instanceof Document) {
  149.             if ($document instanceof Document\Page) {
  150.                 /** @var Document\Service $service */
  151.                 $service = new Document\Service();
  152.                 $linkedDocuments = $service->getTranslations($document);
  153.                 if (count($linkedDocuments) == 0) {
  154.                     return $document;
  155.                 } else {
  156.                     foreach ($linkedDocuments as $docLanguage => $docId) {
  157.                         if ($docLanguage == $this->getLocale()) {
  158.                             /** @var Document $doc */
  159.                             $doc = Document::getById($docId);
  160.                             if ($doc instanceof Document\Page) {
  161.                                 return $doc;
  162.                             }
  163.                         }
  164.                     }
  165.                 }
  166.             }
  167.         }
  168.         return null;
  169.     }
  170.     /**
  171.      * Retourne le sélecteur de langues sous forme de tableau
  172.      * @param $objectThis L'objet $this appelée depuis la vue
  173.      * @return array
  174.      *
  175.      * Exemple:
  176.      * $languageSwitcher = Apik::getLanguageSwitcher($this);
  177.      * print_r($languageSwitcher);
  178.      */
  179.     public static function getLanguageSwitcher($objectThis)
  180.     {
  181.         $CurrentLanguageCode = $objectThis->getProperty("language");
  182.        
  183.         $service = new PimcoreDocument\Service;
  184.         /** @var \App\Templating\Helper\LanguageSwitcher $languageSwitcher */
  185.         $languageSwitcher = new \App\Templating\Helper\LanguageSwitcher($service);
  186.        
  187.         $switcher = [];
  188.         $switcher['current'] = [];
  189.         $switcher['current_id'] = $objectThis->getId();
  190.         $switcher['other'] = [];
  191.         $switcher['all'] = [];
  192.         
  193.         foreach ($languageSwitcher->getLocalizedLinks($objectThis) as $link => $language):
  194.            
  195.             $host = parse_url($link, PHP_URL_HOST);
  196.             // Si domaine courant, alors $link ne contiendra que le chemin de la page (ex: /exemple) sans l'host
  197.             // On va donc rajouter le protoctol et l'host.
  198.             if (empty($host)) {
  199.                 $link = \Pimcore\Tool::getHostUrl() .'/'. $link;
  200.             }
  201.            
  202.             if ($language['code'] == $CurrentLanguageCode) {
  203.                 $switcher['current'] = array_merge(['url' => $link], $language);
  204.             } else {
  205.                 $switcher['other'][] = array_merge(['url' => $link], $language);
  206.             }
  207.             $switcher['all'][] = array_merge(['current' => $language['code'] == $CurrentLanguageCode, 'url' => $link], $language);
  208.         endforeach;
  209.         
  210.         $_switcher = $switcher;
  211.         $_switcher['current'] = $switcher['current'];
  212.         $_switcher['other'] = $switcher['other'];
  213.         $_switcher['all'] = $switcher['all'];
  214.         $switcher = $_switcher;
  215.         return $switcher;
  216.     }
  217.     /**
  218.      * Retourne le sélecteur de langues en HTML
  219.      * @param $objectThis (Obligatoire) L'objet $this appelée depuis la vue
  220.      * @param string $render (Obligatoire) Le format de retour : 'inline' ou 'dropdown'
  221.      * @param string $show (Obligatoire) Ce qu'il faut montrer : 'label' (Français,...), 'code' (FR,...) ou $replace pour un libellé personnalisé
  222.      * @param string $options (Facultatif) Options pour personnaliser le sélecteur de langue
  223.      *
  224.      * $replace est permet remplacer le libellé code/label par un libellé personnalisé.
  225.      *
  226.      * Exemple:
  227.      * echo getLanguageSwitcherHtml($this, 'dropdown', 'label');
  228.      *
  229.      * Exemple d'utilisation de $replace pour le paramètre $show:
  230.      * $replace = [
  231.      *      'fr_FR' => $this->translate('FR (France)'), // Affichera 'FR (France)' si le code de langue est fr_FR
  232.      *      'fr_BE' => $this->translate('FR (Belgique)'), // Affichera 'FR (Belgique)' si le code de langue est fr_BE
  233.      *      'nl_BE' => $this->translate('NL'), // Affichera 'NL' si le code de langue est nl_BE
  234.      * ];e
  235.      *
  236.      * Exemple d'utilisation de $options:
  237.      * Pour utiliser $options, copier/coller du tableau $options ci-dessous et le passer en paramètre à la fonction getLanguageSwitcherHtml(). La documentation de chaque option y est indiquée.
  238.      *
  239.      * @return string
  240.      */
  241.     public static function getLanguageSwitcherHtml($document, $render, $show, $options = [])
  242.     {
  243.        
  244.     
  245.         $custom_options = $options;
  246.         $switcher = self::getLanguageSwitcher($document);
  247.     
  248.         $options = [
  249.             'classes' => [
  250.                 'current' => 'uk-active', // Classe à ajouter sur la langue courante
  251.                 'other' => '' // Classe à ajouter sur les autres langues
  252.             ],
  253.             'dropdown' => [
  254.                 'properties' => 'pos: bottom-center' // Propriété du dropdown
  255.             ]
  256.         ];
  257.         // Fusionne les options
  258.         $options = array_merge($options, $custom_options);
  259.         $html = '';
  260.       
  261.         if ($render == 'inline') {
  262.             $html .= '<nav class="apk-language-switcher">';
  263.             $html .= '<ul class="uk-subnav uk-subnav-divider">';
  264.             foreach ($switcher['all'] as $language):
  265.                 $html .= '<li';
  266.                 if ($language['current']) {
  267.                     $html .= ' class="uk-active"';
  268.                 }
  269.                 $html .= '>';
  270.                 $html .= '<a href="' . $language['url'] . '"';
  271.                 if ($language['current'] && array_key_exists('current', $options['classes']) && !empty($options['classes']['current'])) {
  272.                     $html .= ' class="' . $options['classes']['current'] . '"';
  273.                 } elseif (!$language['current'] && array_key_exists('other', $options['classes']) && !empty($options['classes']['other'])) {
  274.                     $html .= ' class="' . $options['classes']['other'] . '"';
  275.                 }
  276.                 $html .= '>';
  277.                 if ($show == 'label') {
  278.                     $html .= ucfirst($language['label']);
  279.                 } elseif ($show == 'code') {
  280.                     $html .= strtoupper($language['code']);
  281.                 } elseif (is_array($show)) {
  282.                     if (array_key_exists($language['code'], $show)) {
  283.                         $html .= $show[$language['code']];
  284.                     } else {
  285.                         $html .= strtoupper($language['code']);
  286.                     }
  287.                 }
  288.                 $html .= '</a>';
  289.                 $html .= '</li>';
  290.             endforeach;
  291.             $html .= '</ul>';
  292.             $html .= '</nav>';
  293.         } elseif ($render == 'dropdown') {
  294.             $html .= '<nav class="apk-language-switcher uk-display-inline-block">';
  295.             $html .= '<div class="uk-active';
  296.             if (array_key_exists('current', $options['classes']) && !empty($options['classes']['current'])) {
  297.                 $html .= ' ' . $options['classes']['current'];
  298.             }
  299.             $html .= '">';
  300.             if ($show == 'label') {
  301.                 $html .= ucfirst($switcher['current']['label']);
  302.             } elseif ($show == 'code') {
  303.                 $html .= '<span>'.strtoupper($switcher['current']['code']).'</span>';
  304.             } elseif (is_array($show)) {
  305.                 if (array_key_exists($switcher['current']['code'], $show)) {
  306.                     $html .= $show[$switcher['current']['code']];
  307.                 } else {
  308.                     $html .= strtoupper($switcher['current']['code']);
  309.                 }
  310.             }
  311.             $html .= '<svg class="uk-margin-small-left" xmlns="http://www.w3.org/2000/svg" width="11" height="7" viewBox="0 0 11 7"><g><g><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="20" stroke-width="2" d="M1.24 1.5v0l4.374 4.374v0L9.988 1.5v0"/></g></g></svg>';
  312.             $html .= '</div>';
  313.             $html .= '<div class="uk-dropdown" uk-dropdown="' . $options['dropdown']['properties'] . '">';
  314.             $html .= '<ul class="uk-nav uk-dropdown-nav uk-text-left">';
  315.             foreach ($switcher['other'] as $language):
  316.               
  317.                 $html .= '<li>';
  318.                 $html .= '<a href="' . $language['url'] . '"';
  319.                 if (array_key_exists('other', $options['classes']) && !empty($options['classes']['other'])) {
  320.                     $html .= ' class="' . $options['classes']['other'] . '"';
  321.                 }
  322.                 $html .= '>';
  323.                 if ($show == 'label') {
  324.                     $html .= ucfirst($language['label']);
  325.                 } elseif ($show == 'code') {
  326.                     $html .= strtoupper($language['code']);
  327.                 } elseif (is_array($show)) {
  328.                     if (array_key_exists($language['code'], $show)) {
  329.                         $html .= $show[$language['code']];
  330.                     } else {
  331.                         $html .= strtoupper($language['code']);
  332.                     }
  333.                 }
  334.                 $html .= '</a>';
  335.                 $html .= '</li>';
  336.             endforeach;
  337.             $html .= '</ul>';
  338.             $html .= '</div>';
  339.             $html .= '</nav>';
  340.         }
  341.         
  342.         return $html;
  343.     }
  344.     
  345.     /**
  346.      * Retourne un lien mailto en cryptant l'adresse email ( OBFUSCATOR )
  347.      * Basé sur le script 2.1 de Andrew Moulden ( https://www.jottings.com/obfuscator/ )
  348.      * @param $email
  349.      * @return string
  350.      *
  351.      * @Author : Bastien Heynderickx <info@hachbe.be> updated by Grégory Lemmens
  352.      * @Version : 1.1
  353.      * @Description :
  354.      *      permet de générer un lien mailto en protégeant l'adresse email (Obfuscator)
  355.      *      ex : {{ email_obfuscator(+32 478 60 52 47)|raw }}
  356.      *      /!\ le filtre row permet de convertir le code en html
  357.      *          - https://www.jottings.com/obfuscator/
  358.      */
  359.     public function emailObfuscator($address)
  360.     {
  361.         $address = strtolower($address);
  362.         $coded = "";
  363.         $unmixedkey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.@";
  364.         $inprogresskey = $unmixedkey;
  365.         $mixedkey = "";
  366.         $unshuffled = strlen($unmixedkey);
  367.         for ($i = 0; $i < strlen($unmixedkey); $i++) {
  368.             $ranpos = rand(0, $unshuffled - 1);
  369.             $nextchar = $inprogresskey[$ranpos];
  370.             $mixedkey .= $nextchar;
  371.             $before = substr($inprogresskey, 0, $ranpos);
  372.             $after = substr($inprogresskey, $ranpos + 1, $unshuffled - ($ranpos + 1));
  373.             $inprogresskey = $before . '' . $after;
  374.             $unshuffled -= 1;
  375.         }
  376.         $cipher = $mixedkey;
  377.         $shift = strlen($address);
  378.         $txt = "<script type=\"text/javascript\" language=\"javascript\">\n" .
  379.             "<!-" . "-\n" .
  380.             "// Email obfuscator script 2.1 by Tim Williams, University of Arizona\n" .
  381.             "// Random encryption key feature by Andrew Moulden, Site Engineering Ltd\n" .
  382.             "// PHP version coded by Ross Killen, Celtic Productions Ltd\n" .
  383.             "// This code is freeware provided these six comment lines remain intact\n" .
  384.             "// A wizard to generate this code is at http://www.jottings.com/obfuscator/\n" .
  385.             "// The PHP code may be obtained from http://www.celticproductions.net/\n\n";
  386.         for ($j = 0; $j < strlen($address); $j++) {
  387.             if (strpos($cipher, $address[$j]) == -1) {
  388.                 $chr = $address[$j];
  389.                 $coded .= $address[$j];
  390.             } else {
  391.                 $chr = (strpos($cipher, $address[$j]) + $shift) % strlen($cipher);
  392.                 $coded .= $cipher[$chr];
  393.             }
  394.         }
  395.         $txt .= "\ncoded = \"" . $coded . "\"\n" .
  396.             " key = \"" . $cipher . "\"\n" .
  397.             " shift=coded.length\n" .
  398.             " link=\"\"\n" .
  399.             " for (i=0; i<coded.length; i++) {\n" .
  400.             " if (key.indexOf(coded.charAt(i))==-1) {\n" .
  401.             " ltr = coded.charAt(i)\n" .
  402.             " link += (ltr)\n" .
  403.             " }\n" .
  404.             " else { \n" .
  405.             " ltr = (key.indexOf(coded.charAt(i))-
  406. shift+key.length) % key.length\n" .
  407.             " link += (key.charAt(ltr))\n" .
  408.             " }\n" .
  409.             " }\n" .
  410.             "document.write(\"<a href='mailto:\"+link+\"'>\"+link+\"</a>\")\n" .
  411.             "\n" .
  412.             "//-" . "->\n" .
  413.             "<" . "/script><noscript>Sorry, you need Javascript on to email us." .
  414.             "<" . "/noscript>";
  415.         return $txt;
  416.     }
  417.     /**
  418.      * Retourne un lien mailto en cryptant l'adresse email ( OBFUSCATOR )
  419.      * Basé sur le script 2.1 de Andrew Moulden ( https://www.jottings.com/obfuscator/ )
  420.      * @param $email
  421.      * @return string
  422.      *
  423.      * @Author : Bastien Heynderickx <info@hachbe.be> updated by Grégory Lemmens
  424.      * @Version : 1.1
  425.      * @Description :
  426.      *      permet de générer un lien mailto en protégeant l'adresse email (Obfuscator)
  427.      *      ex : {{ email_obfuscator(+32 478 60 52 47)|raw }}
  428.      *      /!\ le filtre row permet de convertir le code en html
  429.      *          - https://www.jottings.com/obfuscator/
  430.      */
  431.     public function emailObfuscatorSvg($address)
  432.     {
  433.         $address = strtolower($address);
  434.         $coded = "";
  435.         $unmixedkey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.@";
  436.         $inprogresskey = $unmixedkey;
  437.         $mixedkey = "";
  438.         $svg = "<img class='uk-margin-small-right' width='25' height='25' src='/static/img/pictos/mail.svg' alt='Mail'>";
  439.         $unshuffled = strlen($unmixedkey);
  440.         for ($i = 0; $i < strlen($unmixedkey); $i++) {
  441.             $ranpos = rand(0, $unshuffled - 1);
  442.             $nextchar = $inprogresskey[$ranpos];
  443.             $mixedkey .= $nextchar;
  444.             $before = substr($inprogresskey, 0, $ranpos);
  445.             $after = substr($inprogresskey, $ranpos + 1, $unshuffled - ($ranpos + 1));
  446.             $inprogresskey = $before . '' . $after;
  447.             $unshuffled -= 1;
  448.         }
  449.         $cipher = $mixedkey;
  450.         $shift = strlen($address);
  451.         $txt = "<script type=\"text/javascript\" language=\"javascript\">\n" .
  452.             "<!-" . "-\n" .
  453.             "// Email obfuscator script 2.1 by Tim Williams, University of Arizona\n" .
  454.             "// Random encryption key feature by Andrew Moulden, Site Engineering Ltd\n" .
  455.             "// PHP version coded by Ross Killen, Celtic Productions Ltd\n" .
  456.             "// This code is freeware provided these six comment lines remain intact\n" .
  457.             "// A wizard to generate this code is at http://www.jottings.com/obfuscator/\n" .
  458.             "// The PHP code may be obtained from http://www.celticproductions.net/\n\n";
  459.         for ($j = 0; $j < strlen($address); $j++) {
  460.             if (strpos($cipher, $address[$j]) == -1) {
  461.                 $chr = $address[$j];
  462.                 $coded .= $address[$j];
  463.             } else {
  464.                 $chr = (strpos($cipher, $address[$j]) + $shift) % strlen($cipher);
  465.                 $coded .= $cipher[$chr];
  466.             }
  467.         }
  468.         $txt .= "\ncoded = \"" . $coded . "\"\n" .
  469.             " key = \"" . $cipher . "\"\n" .
  470.             " svg = \"" . $svg . "\"\n" .
  471.             " shift=coded.length\n" .
  472.             " link=\"\"\n" .
  473.             " for (i=0; i<coded.length; i++) {\n" .
  474.             " if (key.indexOf(coded.charAt(i))==-1) {\n" .
  475.             " ltr = coded.charAt(i)\n" .
  476.             " link += (ltr)\n" .
  477.             " }\n" .
  478.             " else { \n" .
  479.             " ltr = (key.indexOf(coded.charAt(i))-
  480. shift+key.length) % key.length\n" .
  481.             " link += (key.charAt(ltr))\n" .
  482.             " }\n" .
  483.             " }\n" .
  484.             "document.write(\"<a href='mailto:\"+link+\"' target='_blank'>\"+svg+link+\"</a>\")\n" .
  485.             "\n" .
  486.             "//-" . "->\n" .
  487.             "<" . "/script><noscript>Sorry, you need Javascript on to email us." .
  488.             "<" . "/noscript>";
  489.         return $txt;
  490.     }
  491.     /**
  492.      * Retourne un lien mailto en cryptant l'adresse email ( OBFUSCATOR )
  493.      * Basé sur le script 2.1 de Andrew Moulden ( https://www.jottings.com/obfuscator/ )
  494.      * @param $email
  495.      * @return string
  496.      *
  497.      * @Author : Bastien Heynderickx <info@hachbe.be> updated by Grégory Lemmens
  498.      * @Version : 1.1
  499.      * @Description :
  500.      *      permet de générer un lien mailto en protégeant l'adresse email (Obfuscator)
  501.      *      ex : {{ email_obfuscator(+32 478 60 52 47)|raw }}
  502.      *      /!\ le filtre row permet de convertir le code en html
  503.      *          - https://www.jottings.com/obfuscator/
  504.      */
  505.     public function emailObfuscatorSvgOnly($address)
  506.     {
  507.         $address = strtolower($address);
  508.         $coded = "";
  509.         $unmixedkey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.@";
  510.         $inprogresskey = $unmixedkey;
  511.         $mixedkey = "";
  512.         $svg = "<img uk-svg width='29' height='29' src='/static/img/icons/email.svg' alt='Tel' />";
  513.         $unshuffled = strlen($unmixedkey);
  514.         for ($i = 0; $i < strlen($unmixedkey); $i++) {
  515.             $ranpos = rand(0, $unshuffled - 1);
  516.             $nextchar = $inprogresskey[$ranpos];
  517.             $mixedkey .= $nextchar;
  518.             $before = substr($inprogresskey, 0, $ranpos);
  519.             $after = substr($inprogresskey, $ranpos + 1, $unshuffled - ($ranpos + 1));
  520.             $inprogresskey = $before . '' . $after;
  521.             $unshuffled -= 1;
  522.         }
  523.         $cipher = $mixedkey;
  524.         $shift = strlen($address);
  525.         $txt = "<script type=\"text/javascript\" language=\"javascript\">\n" .
  526.             "<!-" . "-\n" .
  527.             "// Email obfuscator script 2.1 by Tim Williams, University of Arizona\n" .
  528.             "// Random encryption key feature by Andrew Moulden, Site Engineering Ltd\n" .
  529.             "// PHP version coded by Ross Killen, Celtic Productions Ltd\n" .
  530.             "// This code is freeware provided these six comment lines remain intact\n" .
  531.             "// A wizard to generate this code is at http://www.jottings.com/obfuscator/\n" .
  532.             "// The PHP code may be obtained from http://www.celticproductions.net/\n\n";
  533.         for ($j = 0; $j < strlen($address); $j++) {
  534.             if (strpos($cipher, $address[$j]) == -1) {
  535.                 $chr = $address[$j];
  536.                 $coded .= $address[$j];
  537.             } else {
  538.                 $chr = (strpos($cipher, $address[$j]) + $shift) % strlen($cipher);
  539.                 $coded .= $cipher[$chr];
  540.             }
  541.         }
  542.         $txt .= "\ncoded = \"" . $coded . "\"\n" .
  543.             " key = \"" . $cipher . "\"\n" .
  544.             " svg = \"" . $svg . "\"\n" .
  545.             " shift=coded.length\n" .
  546.             " link=\"\"\n" .
  547.             " for (i=0; i<coded.length; i++) {\n" .
  548.             " if (key.indexOf(coded.charAt(i))==-1) {\n" .
  549.             " ltr = coded.charAt(i)\n" .
  550.             " link += (ltr)\n" .
  551.             " }\n" .
  552.             " else { \n" .
  553.             " ltr = (key.indexOf(coded.charAt(i))-
  554. shift+key.length) % key.length\n" .
  555.             " link += (key.charAt(ltr))\n" .
  556.             " }\n" .
  557.             " }\n" .
  558.             "document.write(\"<a href='mailto:\"+link+\"'>\"+svg+\"</a>\")\n" .
  559.             "\n" .
  560.             "//-" . "->\n" .
  561.             "<" . "/script><noscript>Sorry, you need Javascript on to email us." .
  562.             "<" . "/noscript>";
  563.         return $txt;
  564.     }
  565.     /**
  566.      * Convertit un numéro de téléphone au format lien "tel:"
  567.      * Exemple: // +32 2 357 33 00 -> +3223573300
  568.      * @param $phone
  569.      * @return string
  570.      *
  571.      * @Author : Bastien Heynderickx <info@hachbe.be> basé sur la version WordPress de Jérôme De Boysère
  572.      * @Version : 1.0
  573.      * @Description :
  574.      *      permet de convertir un numéro de téléphone au format url | lien "tel:"
  575.      */
  576.     public static function convertPhoneToPhoneUrl($phone)
  577.     {
  578.         if (!empty($phone)) {
  579.             $phone = trim($phone);
  580.             $phone = preg_replace('/\s/', '', $phone); // +32 2 357 33 00 -> +3223573300
  581.         }
  582.         return $phone;
  583.     }
  584.     /**
  585.      * Génère des classes CSS pour facilité l'intégration web (à utiliser pour le <body> depuis le layout).
  586.      * @param $objectThis L'objet $this appelé depuis layout
  587.      * @param $__FILE__ La variable __FILE__ appelée depuis le layout
  588.      * @return string
  589.      *
  590.      * Exemple:
  591.      * echo Apik::getBodyClass($this, __FILE__);
  592.      */
  593.      /* ToDO: To refactoring for twig */
  594.     public static function getBodyClass($objectThis, $__FILE__)
  595.     {
  596.         // - Ajoute le CMS utilisé
  597.         // - Ajoute 'editmode' si on est en mode édition
  598.         $bodyClasses = array();
  599.         $bodyClasses[] = 'apk-cms-pimcore';
  600.         if ($objectThis->editmode) {
  601.             $bodyClasses[] = 'editmode';
  602.         }
  603.         // - CXréation d'une classe en fonction du controller + action + (template) + vue
  604.         $class = pathinfo($__FILE__, PATHINFO_BASENAME);
  605.         //$class = strtr($class, array('.html.php' => '-html', '.' => '-', '/' => '_'));
  606.         $class = str_replace('.html.php', '', strtolower($class));
  607.         $class = strtolower($class);
  608.         $bodyClasses[] = 'pimcore-layout-' . $class;
  609.         // Template : Default/home.html.php => gs-template_default_home-html
  610.         /*if ($objectThis->document->getTemplate()) {
  611.             $class = $objectThis->document->getTemplate();
  612.             $class = strtr($class, array('.html.php' => '-html', '.' => '-', '/' => '_'));
  613.             $class = strtolower($class);
  614.             $bodyClasses[] = 'gs-template_' . $class;
  615.             $hasTemplate = true;
  616.         } elseif ($objectThis->document->getController() == 'default' && $objectThis->document->getAction() == 'default') {
  617.             $bodyClasses[] = 'gs-template-by-default';
  618.         }*/
  619.         $controller = '';
  620.         if ($objectThis->document->getController()) {
  621.             $class = $objectThis->document->getController();
  622.             $class = strtolower($class);
  623.             $class = explode('\\', $class);
  624.             //$class = end($class);
  625.             $class = str_replace('controller', '', end($class));
  626.             $controller = $class;
  627.             //$bodyClasses[] = 'gs-controller_' . $class;
  628.         }
  629.         $action = '';
  630.         if ($objectThis->document->getAction()) {
  631.             $class = $objectThis->document->getAction();
  632.             $class = strtolower($class);
  633.             $action = $class;
  634.             //$bodyClasses[] = 'gs-action_' . $class;
  635.         }
  636.         if ($controller && $action) {
  637.             $bodyClasses[] = 'pimcore-' . $controller . '-' . $action;
  638.         }
  639.         return implode(' ', $bodyClasses);
  640.     }
  641.     /**
  642.      * Retourne le tag concernant l'indexation pour les robots
  643.      * @return string
  644.      *
  645.      * Exemple:
  646.      * echo Apik::getRobotsIndex();
  647.      */
  648.     public static function getRobotsIndex()
  649.     {
  650.         $return = '';
  651.         $return .= "\n" . '<!-- Robots indexation -->' . "\n";
  652.         //if (getenv('PIMCORE_ENVIRONMENT') == "prod") {
  653.         if (strpos($_SERVER['HTTP_HOST'], "apik-pp") === FALSE && strpos($_SERVER['HTTP_HOST'], "atypic-pp") === FALSE) {
  654.             $return .= '<meta name="robots" content="INDEX, FOLLOW" />';
  655.         } else {
  656.             $return .= '<meta name="robots" content="NOINDEX, NOFOLLOW" />';
  657.         }
  658.         return $return;
  659.     }
  660.        
  661.     /**
  662.      * Retourne tous les <link rel="alternate" href="..." hreflang="..." />
  663.      * @param $document
  664.      * @return string
  665.      *
  666.      * @Author : Cédric Moriot <cedric@atypic.be>, Jérôme De Boysère <jerome@atypic.be>
  667.      * @Version : 2.0
  668.      * @Description :
  669.      *      Permet d'ajouter les balises hreflang, conformément à la doc Google :
  670.      *          - https://support.google.com/webmasters/answer/189077?hl=fr
  671.      */
  672.     public static function getLinksAlternate($document)
  673.     {
  674.         $return = '';
  675.         $links = [];
  676.         $languageSwitcher = self::getLanguageSwitcher($document);
  677.         foreach ($languageSwitcher['all'] as $k => $lang) {
  678.             $links[$lang['code']] = '<link rel="alternate" hreflang="' . str_replace('_', '-', $lang['code']) . '" href="' . $lang['url'] . '" />';
  679.         }
  680.         $return .= "\n" . '<!-- Link alternate -->' . "\n";
  681.         $return .= count($links) > 0 ? implode("\n", $links) : '<!-- Nothing to do because there is only 1 language configured on this website. -->';
  682.         return $return;
  683.         /*$links = [];
  684.         $service = new PimcoreDocument\Service;
  685.         $validLanguages = \Pimcore\Tool::getValidLanguages();
  686.         $languageSwitcher = $objectThis->languageSwitcher();
  687.         $arrayUrlForHrefLang = $languageSwitcher->getLocalizedLinks($objectThis->document);
  688.         if (is_array($arrayUrlForHrefLang)) {
  689.             foreach ($arrayUrlForHrefLang as $link => $text) {
  690.                 if (in_array($text['code'], $validLanguages)) {
  691.                     $translations = $service->getTranslations($objectThis->document);
  692.                     $tempLink = \Pimcore\Model\Document::getById($translations[$text['code']]);
  693.                     $finalLink = '';
  694.                     if ($text['code'] == $objectThis->getLocale()) {
  695.                         //Active Page
  696.                         $finalLink = $objectThis->document->getFullPath();
  697.                     } else if (is_object($tempLink) && !empty($tempLink->getPrettyUrl())) {
  698.                         $finalLink = $tempLink->getPrettyUrl();
  699.                     } elseif (is_object($tempLink)) {
  700.                         //Alternate Page W/O Pretty URL
  701.                         $finalLink = $tempLink->getPath() . $tempLink->getKey();
  702.                     }
  703.                     if (!empty($finalLink)) {
  704.                         $links[$text['code']] = '<link rel="alternate" href="' . \Pimcore\Tool::getHostUrl() . $finalLink . '" hreflang="' . $text['code'] . '" />';
  705.                     } else {
  706.                         $links[$text['code']] = '<!-- Link alternate - No page found for the language : ' . $text['label'] . ' (' . $text['code'] . ') -->';
  707.                     }
  708.                 }
  709.             }
  710.         }
  711.         return count($validLanguages) > 1 ? implode("\n", $links) : '<!-- Link alternate - Nothing to do because there is only 1 language configured on this website. -->';
  712.     */
  713.     }
  714.     /**
  715.      * Retourne la valeur du website setting localisé
  716.      * @param $objectThis
  717.      * @return string
  718.      *
  719.      * @Author : Bastien Heynderickx <info@hachbe.be>
  720.      * @Version : 1.0
  721.      * @Description :
  722.      *      permet de récupérer la valeur d'un website setting sur base la localisation
  723.      *          - https://support.google.com/webmasters/answer/189077?hl=fr
  724.      */
  725.     public static function websiteConfigAdvanced($name, $siteId = null, $language = null, $fallbackLanguage = null)
  726.     {
  727.         return WebsiteSetting::getByName($name, $siteId, $language)->getData();
  728.     }
  729.     
  730.     /**
  731.      * Create a web friendly URL slug from a string.
  732.      *
  733.      * Although supported, transliteration is discouraged because
  734.      *     1) most web browsers support UTF-8 characters in URLs
  735.      *     2) transliteration causes a loss of information
  736.      *
  737.      * @author Sean Murphy <sean@iamseanmurphy.com>
  738.      * @copyright Copyright 2012 Sean Murphy. All rights reserved.
  739.      * @license http://creativecommons.org/publicdomain/zero/1.0/
  740.      *
  741.      * @param string $str
  742.      * @param array $options
  743.      * @return string
  744.      */
  745.     public static function toUrl($str, $options = array())
  746.     {
  747.         // Make sure string is in UTF-8 and strip invalid UTF-8 characters
  748.         $str = mb_convert_encoding((string)$str, 'UTF-8', mb_list_encodings());
  749.         $defaults = array(
  750.             'delimiter' => '-',
  751.             'limit' => null,
  752.             'lowercase' => true,
  753.             'replacements' => array(),
  754.             'transliterate' => true,
  755.         );
  756.         // Merge options
  757.         $options = array_merge($defaults, $options);
  758.         $char_map = array(
  759.             // Latin
  760.             'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'AE', 'Ç' => 'C',
  761.             'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I',
  762.             'Ð' => 'D', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ő' => 'O',
  763.             'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ű' => 'U', 'Ý' => 'Y', 'Þ' => 'TH',
  764.             'ß' => 'ss',
  765.             'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'ae', 'ç' => 'c',
  766.             'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i',
  767.             'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ő' => 'o',
  768.             'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ű' => 'u', 'ý' => 'y', 'þ' => 'th',
  769.             'ÿ' => 'y',
  770.             // Latin symbols
  771.             '©' => '(c)',
  772.             // Greek
  773.             'Α' => 'A', 'Β' => 'B', 'Γ' => 'G', 'Δ' => 'D', 'Ε' => 'E', 'Ζ' => 'Z', 'Η' => 'H', 'Θ' => '8',
  774.             'Ι' => 'I', 'Κ' => 'K', 'Λ' => 'L', 'Μ' => 'M', 'Ν' => 'N', 'Ξ' => '3', 'Ο' => 'O', 'Π' => 'P',
  775.             'Ρ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'Υ' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'PS', 'Ω' => 'W',
  776.             'Ά' => 'A', 'Έ' => 'E', 'Ί' => 'I', 'Ό' => 'O', 'Ύ' => 'Y', 'Ή' => 'H', 'Ώ' => 'W', 'Ϊ' => 'I',
  777.             'Ϋ' => 'Y',
  778.             'α' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd', 'ε' => 'e', 'ζ' => 'z', 'η' => 'h', 'θ' => '8',
  779.             'ι' => 'i', 'κ' => 'k', 'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => '3', 'ο' => 'o', 'π' => 'p',
  780.             'ρ' => 'r', 'σ' => 's', 'τ' => 't', 'υ' => 'y', 'φ' => 'f', 'χ' => 'x', 'ψ' => 'ps', 'ω' => 'w',
  781.             'ά' => 'a', 'έ' => 'e', 'ί' => 'i', 'ό' => 'o', 'ύ' => 'y', 'ή' => 'h', 'ώ' => 'w', 'ς' => 's',
  782.             'ϊ' => 'i', 'ΰ' => 'y', 'ϋ' => 'y', 'ΐ' => 'i',
  783.             // Turkish
  784.             'Ş' => 'S', 'İ' => 'I', 'Ç' => 'C', 'Ü' => 'U', 'Ö' => 'O', 'Ğ' => 'G',
  785.             'ş' => 's', 'ı' => 'i', 'ç' => 'c', 'ü' => 'u', 'ö' => 'o', 'ğ' => 'g',
  786.             // Russian
  787.             'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo', 'Ж' => 'Zh',
  788.             'З' => 'Z', 'И' => 'I', 'Й' => 'J', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O',
  789.             'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C',
  790.             'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sh', 'Ъ' => '', 'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'Yu',
  791.             'Я' => 'Ya',
  792.             'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'ж' => 'zh',
  793.             'з' => 'z', 'и' => 'i', 'й' => 'j', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o',
  794.             'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c',
  795.             'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sh', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu',
  796.             'я' => 'ya',
  797.             // Ukrainian
  798.             'Є' => 'Ye', 'І' => 'I', 'Ї' => 'Yi', 'Ґ' => 'G',
  799.             'є' => 'ye', 'і' => 'i', 'ї' => 'yi', 'ґ' => 'g',
  800.             // Czech
  801.             'Č' => 'C', 'Ď' => 'D', 'Ě' => 'E', 'Ň' => 'N', 'Ř' => 'R', 'Š' => 'S', 'Ť' => 'T', 'Ů' => 'U',
  802.             'Ž' => 'Z',
  803.             'č' => 'c', 'ď' => 'd', 'ě' => 'e', 'ň' => 'n', 'ř' => 'r', 'š' => 's', 'ť' => 't', 'ů' => 'u',
  804.             'ž' => 'z',
  805.             // Polish
  806.             'Ą' => 'A', 'Ć' => 'C', 'Ę' => 'e', 'Ł' => 'L', 'Ń' => 'N', 'Ó' => 'o', 'Ś' => 'S', 'Ź' => 'Z',
  807.             'Ż' => 'Z',
  808.             'ą' => 'a', 'ć' => 'c', 'ę' => 'e', 'ł' => 'l', 'ń' => 'n', 'ó' => 'o', 'ś' => 's', 'ź' => 'z',
  809.             'ż' => 'z',
  810.             // Latvian
  811.             'Ā' => 'A', 'Č' => 'C', 'Ē' => 'E', 'Ģ' => 'G', 'Ī' => 'i', 'Ķ' => 'k', 'Ļ' => 'L', 'Ņ' => 'N',
  812.             'Š' => 'S', 'Ū' => 'u', 'Ž' => 'Z',
  813.             'ā' => 'a', 'č' => 'c', 'ē' => 'e', 'ģ' => 'g', 'ī' => 'i', 'ķ' => 'k', 'ļ' => 'l', 'ņ' => 'n',
  814.             'š' => 's', 'ū' => 'u', 'ž' => 'z'
  815.         );
  816.         // Make custom replacements
  817.         $str = preg_replace(array_keys($options['replacements']), $options['replacements'], $str);
  818.         // Transliterate characters to ASCII
  819.         if ($options['transliterate']) {
  820.             $str = str_replace(array_keys($char_map), $char_map, $str);
  821.         }
  822.         // Replace non-alphanumeric characters with our delimiter
  823.         $str = preg_replace('/[^\p{L}\p{Nd}]+/u', $options['delimiter'], $str);
  824.         // Remove duplicate delimiters
  825.         $str = preg_replace('/(' . preg_quote($options['delimiter'], '/') . '){2,}/', '$1', $str);
  826.         // Truncate slug to max. characters
  827.         $str = mb_substr($str, 0, ($options['limit'] ? $options['limit'] : mb_strlen($str, 'UTF-8')), 'UTF-8');
  828.         // Remove delimiter from ends
  829.         $str = trim($str, $options['delimiter']);
  830.         return $options['lowercase'] ? mb_strtolower($str, 'UTF-8') : $str;
  831.     }
  832.     /**
  833.      * Convertit la date YYYY/MM/DD dans un autre format
  834.      * @param $date La date au format YYYY/MM/DD
  835.      * @param $outputFormat (Facultatif) Le format de sortie (d/m/Y, \O\n j F, Y,...)
  836.      * @return string
  837.      *
  838.      * Exemple:
  839.      * echo Apik::convertDate('2019/12/24', 'd/m/Y');
  840.      */
  841.     public static function convertDate($yyyy_mm_dd, $outputFormat = 'd/m/Y', $lang = null)
  842.     {
  843.         $date = new \DateTime($yyyy_mm_dd);
  844.         if($lang!=null && $lang!='en'):
  845.             $date = $date->format($outputFormat);
  846.             $english_days = array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');
  847.             $french_days = array('Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
  848.             $dutch_days = array('Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag');
  849.             $english_months = array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
  850.             $french_months = array('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');
  851.             $dutch_months = array('Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December');
  852.             switch($lang):
  853.                 case 'fr': $date_localized =  str_replace($english_months, $french_months, str_replace($english_days, $french_days, $date ));
  854.                     break;
  855.                 case 'nl': $date_localized =  str_replace($english_months, $dutch_months, str_replace($english_days, $dutch_days, $date ));
  856.                     break;
  857.             endswitch;
  858.             return $date_localized;
  859.         else:
  860.             return $date->format($outputFormat);
  861.         endif;
  862.     }
  863.      /**
  864.      *
  865.      * @param string $image
  866.      * @param string $defaultAlt
  867.      * @param string $language
  868.      * 
  869.      * @return string
  870.      *
  871.      * @Author : Grégory Lemmens
  872.      * @Version : 1.0
  873.      * @Description :
  874.      *      permet de créer les attributs titres et alt et copyright pour les images
  875.      *           
  876.      */
  877.     public static function metadatasImage($image, $defaultAlt, $language){
  878.         if($image->getMetadata('alt')){
  879.             if($image->getMetadata('copyright')){
  880.                 $imageAlt = ' alt="' . $image->getMetadata('alt') . ' | © '. $image->getMetadata('copyright') .'"';
  881.             }elseif($image->getMetadata('copyright', $language)){
  882.                 $imageAlt = ' alt="' . $image->getMetadata('alt') . ' | © '. $image->getMetadata('copyright', $language) .'"';
  883.             }else{
  884.                 $imageAlt = ' alt="' . $image->getMetadata('alt') . '"';
  885.             }
  886.             
  887.         }elseif($image->getMetadata('alt', $language)){
  888.             
  889.             if($image->getMetadata('copyright')){
  890.                 $imageAlt = ' alt="' . $image->getMetadata('alt', $language) . ' | © '. $image->getMetadata('copyright') .'"';
  891.             }elseif($image->getMetadata('copyright', $language)){
  892.                 $imageAlt = ' alt="' . $image->getMetadata('alt', $language) . ' | © '. $image->getMetadata('copyright', $language) .'"';
  893.             }else{
  894.                 $imageAlt = ' alt="' . $image->getMetadata('alt', $language) . '"';
  895.             }
  896.             
  897.         }else{
  898.             if($image->getMetadata('copyright')){
  899.                 $imageAlt = ' alt="' . $defaultAlt . ' | © '. $image->getMetadata('copyright') .'"';
  900.             }elseif($image->getMetadata('copyright', $language)){
  901.                 $imageAlt = ' alt="' . $defaultAlt . ' | © '. $image->getMetadata('copyright', $language) .'"';
  902.             }else{
  903.                 $imageAlt = ' alt="' . $defaultAlt . '"';
  904.             }
  905.         }
  906.         if($image->getMetadata('title')){
  907.             if($image->getMetadata('copyright')){
  908.                 $imageTitle = ' title="' . $image->getMetadata('title') . ' | © '. $image->getMetadata('copyright') .'"';
  909.             }elseif($image->getMetadata('copyright', $language)){
  910.                 $imageTitle = ' title="' . $image->getMetadata('title') . ' | © '. $image->getMetadata('copyright', $language) .'"';
  911.             }else{
  912.                 $imageTitle = ' title="' . $image->getMetadata('title') . '"';
  913.             }
  914.         }elseif($image->getMetadata('title', $language)){
  915.             if($image->getMetadata('copyright')){
  916.                 $imageTitle = ' title="' . $image->getMetadata('title', $language) . ' | © '. $image->getMetadata('copyright') .'"';
  917.             }elseif($image->getMetadata('copyright', $language)){
  918.                 $imageTitle = ' title="' . $image->getMetadata('title', $language) . ' | © '. $image->getMetadata('copyright', $language) .'"';
  919.             }else{
  920.                 $imageTitle = ' title="' . $image->getMetadata('title', $language) . '"';
  921.             }
  922.         }else{
  923.             $imageTitle = '';
  924.         }
  925.         $metaDatas = $imageAlt . $imageTitle;
  926.         
  927.         return $metaDatas;
  928.     }
  929.      /**
  930.      *
  931.      * @param string $headTitle
  932.      * @param string $headMeta
  933.      * @param string $title
  934.      * @param string $description
  935.      * @param string $image
  936.      * @param string $overwriteTitle
  937.      * @param string $overwriteDescription
  938.      * @param string $overwriteImage
  939.      * 
  940.      * @return string
  941.      *
  942.      * @Author : Grégory Lemmens
  943.      * @Version : 1.3
  944.      * 
  945.      * @Description :
  946.      *      Permet de setter le SEO sur les objets
  947.      * 
  948.      * {{ set_seo(
  949.      *      pimcore_head_title(),
  950.      *      pimcore_head_meta(),
  951.      *      news.title,
  952.      *      news.shortText ? news.shortText|striptags|slice(0, 200)|raw : news.shortText|length > 200 ? news.shortText|striptags|slice(0, 200)|raw ~ '...' : news.shortText|striptags,
  953.      *      document.property('seoImage'),
  954.      *      news.seoTitle,
  955.      *      news.seoDescription,
  956.      *      news.seoImage
  957.      *  ) }}
  958.      *           
  959.      */
  960.     function setSeo($headTitle, $headMeta ,$title, $description, $image, $overwriteTitle = null, $overwriteDescription = null, $overwriteImage = null){
  961.         
  962.         if($overwriteTitle !== null && !empty($overwriteTitle)){
  963.             $headTitle->set($overwriteTitle);
  964.         }else{
  965.             $headTitle->set($title);
  966.         }
  967.         if($overwriteDescription !== null && !empty($overwriteDescription)){
  968.             $headMeta->setDescription(strip_tags($overwriteDescription));
  969.         }else{
  970.             $headMeta->setDescription((strip_tags($description)));
  971.         }
  972.         $headMeta->setProperty('og:type', 'website');
  973.         $headMeta->setProperty('og:url', \Pimcore\Tool::getHostUrl(). $_SERVER['REQUEST_URI']);
  974.         if($overwriteTitle !== null && !empty($overwriteTitle)){
  975.             $headMeta->setProperty('og:title', $overwriteTitle);
  976.         }else{
  977.             $headMeta->setProperty('og:title', $title);
  978.         }
  979.         if($overwriteDescription !== null && !empty($overwriteDescription)){
  980.             $headMeta->setProperty('og:description', strip_tags($overwriteDescription));
  981.         }else{
  982.             $headMeta->setProperty('og:description', strip_tags($description));
  983.         };
  984.         if($overwriteImage !== null && !empty($overwriteImage)) {
  985.             $headMeta->setProperty('og:image', \Pimcore\Tool::getHostUrl() . $overwriteImage->getThumbnail('seoImage', true)); 
  986.         } elseif($image){
  987.             $headMeta->setProperty('og:image', \Pimcore\Tool::getHostUrl() . $image->getThumbnail('seoImage', true));
  988.         }
  989.         
  990.         return;
  991.     }
  992.      /**
  993.      * @return string
  994.      *
  995.      * @Author : Grégory Lemmens
  996.      * @Version : 1.0
  997.      * @Description :
  998.      *      permet de récupérer la langue par défaut de pimcore
  999.      *           
  1000.      */
  1001.     function getDefaultLanguage(){
  1002.         $defaultLanguage = Tool::getDefaultLanguage();
  1003.         return $defaultLanguage;
  1004.     }
  1005.     /**
  1006.      * @return string
  1007.      *
  1008.      * @Author : Grégory Lemmens
  1009.      * @Version : 1.0
  1010.      * @Description :
  1011.      *      permet de comparer l'heure de publication par rapport à maintenant
  1012.      *           
  1013.      */
  1014.     function compareDateSubmit($datePublished)
  1015.     {
  1016.         if ($datePublished == null) return '';
  1017.         else
  1018.         {
  1019.             $now = Carbon::now();
  1020.             
  1021.             if($now > $datePublished->copy()->addMonths(4))
  1022.                 return $this->translator->trans('Le'). ' '.$datePublished->format('d/m/y'). ' '.  $this->translator->trans('à'). ' '. $datePublished->format('H:i');
  1023.             else if($now > $datePublished->copy()->addMonths(3))
  1024.                 return $this->translator->trans('Il y a 3 mois');
  1025.             else if($now > $datePublished->copy()->addMonths(2))
  1026.                 return $this->translator->trans('Il y a 2 mois');
  1027.             else if($now > $datePublished->copy()->addMonth())
  1028.                 return $this->translator->trans('Il y a un mois');
  1029.             else if($now > $datePublished->copy()->addWeeks(4))
  1030.                 return $this->translator->trans('Il y a 4 semaines');
  1031.             else if($now > $datePublished->copy()->addWeeks(3))
  1032.                 return $this->translator->trans('Il y a 3 semaines');
  1033.             else if($now > $datePublished->copy()->addWeeks(2))
  1034.                 return $this->translator->trans('Il y a 2 semaines');
  1035.             else if($now > $datePublished->copy()->addWeek())
  1036.                 return $this->translator->trans('Il y a une semaine');
  1037.             else if($now > $datePublished->copy()->addDays(6))
  1038.                 return $this->translator->trans('Il y a 6 jours');
  1039.             else if($now > $datePublished->copy()->addDays(5))
  1040.                 return $this->translator->trans('Il y a 5 jours');
  1041.             else if($now > $datePublished->copy()->addDays(4))
  1042.                 return $this->translator->trans('Il y a 4 jours');
  1043.             else if($now > $datePublished->copy()->addDays(3))
  1044.                 return $this->translator->trans('Il y a 3 jours');
  1045.             else if($now > $datePublished->copy()->addDays(2))
  1046.                 return $this->translator->trans('avant-hier');
  1047.             else if($now > $datePublished->copy()->addDay())
  1048.                 return $this->translator->trans('hier');
  1049.             else if ($now > $datePublished->copy()->addHours(24))
  1050.                 return $this->translator->trans('aujourd\'hui');
  1051.             else if ($now > $datePublished->copy()->addHour(22))
  1052.                 return $this->translator->trans('Il y a moins de 23 heures');
  1053.             else if ($now > $datePublished->copy()->addHour(21))
  1054.                 return $this->translator->trans('Il y a moins de 22 heures');
  1055.             else if ($now > $datePublished->copy()->addHour(20))
  1056.                 return $this->translator->trans('Il y a moins de 21 heures');
  1057.             else if ($now > $datePublished->copy()->addHour(19))
  1058.                 return $this->translator->trans('Il y a moins de 20 heures');
  1059.             else if ($now > $datePublished->copy()->addHour(18))
  1060.                 return $this->translator->trans('Il y a moins de 19 heures');
  1061.             else if ($now > $datePublished->copy()->addHour(17))
  1062.                 return $this->translator->trans('Il y a moins de 18 heures');
  1063.             else if ($now > $datePublished->copy()->addHour(16))
  1064.                 return $this->translator->trans('Il y a moins de 17 heures');
  1065.             else if ($now > $datePublished->copy()->addHour(15))
  1066.                 return $this->translator->trans('Il y a moins de 16 heures');
  1067.             else if ($now > $datePublished->copy()->addHour(14))
  1068.                 return $this->translator->trans('Il y a moins de 15 heures');
  1069.             else if ($now > $datePublished->copy()->addHour(13))
  1070.                 return $this->translator->trans('Il y a moins de 14 heures');
  1071.             else if ($now > $datePublished->copy()->addHour(12))
  1072.                 return $this->translator->trans('Il y a moins de 13 heures');
  1073.             else if ($now > $datePublished->copy()->addHour(11))
  1074.                 return $this->translator->trans('Il y a moins de 12 heures');
  1075.             else if ($now > $datePublished->copy()->addHour(10))
  1076.                 return $this->translator->trans('Il y a moins de 11 heures');
  1077.             else if ($now > $datePublished->copy()->addHour(9))
  1078.                 return $this->translator->trans('Il y a moins de 10 heures');
  1079.             else if ($now > $datePublished->copy()->addHour(8))
  1080.                 return $this->translator->trans('Il y a moins de 9 heures');
  1081.             else if ($now > $datePublished->copy()->addHour(7))
  1082.                 return $this->translator->trans('Il y a moins de 8 heures');
  1083.             else if ($now > $datePublished->copy()->addHour(6))
  1084.                 return $this->translator->trans('Il y a moins de 7 heures');
  1085.             else if ($now > $datePublished->copy()->addHour(5))
  1086.                 return $this->translator->trans('Il y a moins de 6 heures');
  1087.             else if ($now > $datePublished->copy()->addHour(4))
  1088.                 return $this->translator->trans('Il y a moins de 5 heures');
  1089.             else if ($now > $datePublished->copy()->addHour(3))
  1090.                 return $this->translator->trans('Il y a moins de 4 heures');
  1091.             else if ($now > $datePublished->copy()->addHours(2))
  1092.                 return $this->translator->trans('Il y a moins de 3 heures');
  1093.             else if ($now > $datePublished->copy()->addHour())
  1094.                 return $this->translator->trans('Il y a moins de 2 heures');
  1095.             else if ($now > $datePublished->copy()->addMinutes(59))
  1096.                 return $this->translator->trans('Il y a moins d\'une heure');
  1097.             else if ($now > $datePublished->copy()->addMinutes(31))
  1098.                 return $this->translator->trans('Il y a 30 minutes');
  1099.             else if ($now > $datePublished->copy()->addMinutes(11))
  1100.                 return $this->translator->trans('Il y a 10 minutes');
  1101.             else if ($now > $datePublished->copy()->addMinutes(10))
  1102.                 return $this->translator->trans('Il y a 9 minutes');
  1103.             else if ($now > $datePublished->copy()->addMinutes(8))
  1104.                 return $this->translator->trans('Il y a 8 minutes');
  1105.             else if ($now > $datePublished->copy()->addMinutes(7))
  1106.                 return $this->translator->trans('Il y a 7 minutes');
  1107.             else if ($now > $datePublished->copy()->addMinutes(6))
  1108.                 return $this->translator->trans('Il y a 6 minutes');
  1109.             else if ($now > $datePublished->copy()->addMinutes(5))
  1110.                 return $this->translator->trans('Il y a 5 minutes');
  1111.             else if ($now > $datePublished->copy()->addMinutes(4))
  1112.                 return $this->translator->trans('Il y a 4 minutes');
  1113.             else if ($now > $datePublished->copy()->addMinutes(3))
  1114.                 return $this->translator->trans('Il y a 3 minutes');
  1115.             else if ($now > $datePublished->copy()->addMinutes(2))
  1116.                 return $this->translator->trans('Il y a 2 minutes');
  1117.             else if ($now > $datePublished->copy()->addMinute(0))
  1118.                 return $this->translator->trans('Il y a une minute');
  1119.             elseif ($now > $datePublished->copy())
  1120.                 return $this->translator->trans('À l\'instant');
  1121.         }
  1122.     }
  1123. }