From 142611e69dd962edbed46fb7a57dce8b72a9b839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Tempez?= Date: Thu, 10 Mar 2022 17:06:28 +0100 Subject: [PATCH] theme WIP --- core/module/theme/theme.php | 2112 ++++++++++++++++++----------------- 1 file changed, 1063 insertions(+), 1049 deletions(-) diff --git a/core/module/theme/theme.php b/core/module/theme/theme.php index 19a209c1..5fa0430f 100644 --- a/core/module/theme/theme.php +++ b/core/module/theme/theme.php @@ -1,1049 +1,1063 @@ - - * @copyright Copyright (C) 2008-2018, Rémi Jean - * @license GNU General Public License, version 3 - * @link http://zwiicms.fr/ - * @copyright : Frédéric Tempez - * @copyright Copyright (C) 2018-2022, Frédéric Tempez - */ - -class theme extends common { - - public static $actions = [ - 'advanced' => self::GROUP_ADMIN, - 'body' => self::GROUP_ADMIN, - 'footer' => self::GROUP_ADMIN, - 'header' => self::GROUP_ADMIN, - 'index' => self::GROUP_ADMIN, - 'menu' => self::GROUP_ADMIN, - 'reset' => self::GROUP_ADMIN, - 'site' => self::GROUP_ADMIN, - 'admin' => self::GROUP_ADMIN, - 'manage' => self::GROUP_ADMIN, - 'export' => self::GROUP_ADMIN, - 'import' => self::GROUP_ADMIN, - 'save' => self::GROUP_ADMIN, - 'fonts' => self::GROUP_ADMIN, - 'fontAdd' => self::GROUP_ADMIN, - 'fontDelete' => self::GROUP_ADMIN - ]; - public static $aligns = [ - 'left' => 'À gauche', - 'center' => 'Au centre', - 'right' => 'À droite' - ]; - public static $attachments = [ - 'scroll' => 'Standard', - 'fixed' => 'Fixe' - ]; - public static $containerWides = [ - 'container' => 'Limitée au site', - 'none' => 'Etendue sur la page' - ]; - public static $footerblocks = [ - 1 => [ - 'hide' => 'Masqué', - 'center' => 'Affiché' ], - 2 => [ - 'hide' => 'Masqué', - 'left' => 'À gauche', - 'right' => 'À droite' ], - 3 => [ - 'hide' => 'Masqué', - 'left' => 'À gauche', - 'center' => 'Au centre', - 'right' => 'À droite' ], - 4 => [ - 'hide' => 'Masqué', - 'left' => 'En haut', - 'center' => 'Au milieu', - 'right' => 'En bas' ] - ]; - - public static $fontWeights = [ - 'normal' => 'Maigre', - 'bold' => 'Gras' - ]; - public static $footerHeights = [ - '0px' => 'Nulles (0px)', - '5px' => 'Très petites (5px)', - '10px' => 'Petites (10px)', - '15px' => 'Moyennes (15px)', - '20px' => 'Grandes (20px)' - ]; - public static $footerPositions = [ - 'hide' => 'Caché', - 'site' => 'Dans le site', - 'body' => 'En dessous du site' - ]; - public static $footerFontSizes = [ - '.8em' => 'Très petite (80%)', - '.9em' => 'Petite (90%)', - '1em' => 'Standard (100%)', - '1.1em' => 'Moyenne (110%)', - '1.2em' => 'Grande (120%)', - '1.3em' => 'Très grande (130%)' - ]; - public static $headerFontSizes = [ - '1.6em' => 'Très petite (160%)', - '1.8em' => 'Petite (180%)', - '2em' => 'Moyenne (200%)', - '2.2em' => 'Grande (220%)', - '2.4vmax' => 'Très grande (240%)' - ]; - public static $headerHeights = [ - 'unset' => 'Libre', // texte dynamique cf header.js.php - '100px' => 'Très petite (100px) ', - '150px' => 'Petite (150px)', - '200px' => 'Moyenne (200px)', - '300px' => 'Grande (300px)', - '400px' => 'Très grande (400px)', - ]; - public static $headerPositions = [ - 'body' => 'Au dessus du site', - 'site' => 'Dans le site', - 'hide' => 'Cachée' - ]; - public static $headerFeatures = [ - 'wallpaper' => 'Couleur unie ou papier-peint', - 'feature' => 'Contenu personnalisé' - ]; - public static $imagePositions = [ - 'top left' => 'En haut à gauche', - 'top center' => 'En haut au centre', - 'top right' => 'En haut à droite', - 'center left' => 'Au milieu à gauche', - 'center center' => 'Au milieu au centre', - 'center right' => 'Au milieu à droite', - 'bottom left' => 'En bas à gauche', - 'bottom center' => 'En bas au centre', - 'bottom right' => 'En bas à droite' - ]; - public static $menuFontSizes = [ - '.8em' => 'Très petite (80%)', - '.9em' => 'Petite (90%)', - '1em' => 'Standard (100%)', - '1.1em' => 'Moyenne (110%)', - '1.2em' => 'Grande (120%)', - '1.3em' => 'Très grande (130%)' - ]; - public static $menuHeights = [ - '5px 10px' => 'Très petite', - '10px' => 'Petite', - '15px 10px' => 'Moyenne', - '20px 15px' => 'Grande', - '25px 15px' => 'Très grande' - ]; - public static $menuPositionsSite = [ - 'top' => 'En-dehors du site', - 'site-first' => 'Avant la bannière', - 'site-second' => 'Après la bannière', - 'hide' => 'Caché' - ]; - public static $menuPositionsBody = [ - 'top' => 'En-dehors du site', - 'body-first' => 'Avant la bannière', - 'body-second' => 'Après la bannière', - 'site' => 'Dans le site', - 'hide' => 'Caché' - ]; - public static $menuRadius = [ - '0px' => 'Aucun', - '3px 3px 0px 0px' => 'Très léger', - '6px 6px 0px 0px' => 'Léger', - '9px 9px 0px 0px' => 'Moyen', - '12px 12px 0px 0px' => 'Important', - '15px 15px 0px 0px' => 'Très important' - ]; - public static $radius = [ - '0px' => 'Aucun', - '5px' => 'Très léger', - '10px' => 'Léger', - '15px' => 'Moyen', - '25px' => 'Important', - '50px' => 'Très important' - ]; - public static $repeats = [ - 'no-repeat' => 'Ne pas répéter', - 'repeat-x' => 'Sur l\'axe horizontal', - 'repeat-y' => 'Sur l\'axe vertical', - 'repeat' => 'Sur les deux axes' - ]; - public static $shadows = [ - '0px' => 'Aucune', - '1px 1px 5px' => 'Très légère', - '1px 1px 10px' => 'Légère', - '1px 1px 15px' => 'Moyenne', - '1px 1px 25px' => 'Importante', - '1px 1px 50px' => 'Très importante' - ]; - public static $siteFontSizes = [ - '12px' => '12 pixels', - '13px' => '13 pixels', - '14px' => '14 pixels', - '15px' => '15 pixels', - '16px' => '16 pixels' - ]; - public static $bodySizes = [ - 'auto' => 'Automatique', - '100% 100%' => 'Image étirée (100% 100%)', - 'cover' => 'Responsive (cover)', - 'contain' => 'Responsive (contain)' - ]; - public static $textTransforms = [ - 'none' => 'Standard', - 'lowercase' => 'Minuscules', - 'uppercase' => 'Majuscules', - 'capitalize' => 'Majuscule à chaque mot' - ]; - public static $siteWidths = [ - '750px' => 'Petite (750 pixels)', - '960px' => 'Moyenne (960 pixels)', - '1170px' => 'Grande (1170 pixels)', - '100%' => 'Fluide (100%)' - ]; - public static $headerWide = [ - 'auto auto' => 'Automatique', - '100% 100%' => 'Image étirée (100% 100%)', - 'cover' => 'Responsive (cover)', - 'contain' => 'Responsive (contain)' - ]; - public static $footerTemplate = [ - '1' => 'Une seule colonne', - '2' => 'Deux colonnes : 1/2 - 1/2', - '3' => 'Trois colonnes : 1/3 - 1/3 - 1/3', - '4' => 'Trois lignes superposées' - ]; - public static $burgerContent = [ - 'none' => 'Aucun', - 'title' => 'Titre du site', - 'logo' => 'Logo du site' - ]; - - - // Variable pour construire la liste des pages du site - public static $pagesList = []; - // Variable pour construire la liste des fontes installées - public static $fontsList = []; - - /** - * Thème des écrans d'administration - */ - public function admin() { - // Soumission du formulaire - if($this->isPost()) { - $this->setData(['admin', [ - 'backgroundColor' => $this->getInput('adminBackgroundColor'), - 'colorTitle' => $this->getInput('adminColorTitle'), - 'colorText' => $this->getInput('adminColorText'), - 'colorButtonText' => $this->getInput('adminColorButtonText'), - 'backgroundColorButton' => $this->getInput('adminColorButton'), - 'backgroundColorButtonGrey' => $this->getInput('adminColorGrey'), - 'backgroundColorButtonRed' => $this->getInput('adminColorRed'), - 'backgroundColorButtonGreen'=> $this->getInput('adminColorGreen'), - 'backgroundColorButtonHelp'=> $this->getInput('adminColorHelp'), - 'fontText' => $this->getInput('adminFontText'), - 'fontSize' => $this->getInput('adminFontTextSize'), - 'fontTitle' => $this->getInput('adminFontTitle'), - 'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'), - 'borderBlockColor' => $this->getInput('adminBorderBlockColor'), - ]]); - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme/admin', - 'state' => true - ]); - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Administration', - 'view' => 'admin', - 'vendor' => [ - 'tinycolorpicker' - ], - ]); - } - - /** - * Mode avancé - */ - public function advanced() { - // Soumission du formulaire - if($this->isPost()) { - // Enregistre le CSS - file_put_contents(self::DATA_DIR.'custom.css', $this->getInput('themeAdvancedCss', null)); - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme/advanced', - 'state' => true - ]); - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Éditeur CSS', - 'vendor' => [ - 'codemirror' - ], - 'view' => 'advanced' - ]); - } - - /** - * Options de l'arrière plan - */ - public function body() { - // Soumission du formulaire - if($this->isPost()) { - $this->setData(['theme', 'body', [ - 'backgroundColor' => $this->getInput('themeBodyBackgroundColor'), - 'image' => $this->getInput('themeBodyImage'), - 'imageAttachment' => $this->getInput('themeBodyImageAttachment'), - 'imagePosition' => $this->getInput('themeBodyImagePosition'), - 'imageRepeat' => $this->getInput('themeBodyImageRepeat'), - 'imageSize' => $this->getInput('themeBodyImageSize'), - 'toTopbackgroundColor' => $this->getInput('themeBodyToTopBackground'), - 'toTopColor' => $this->getInput('themeBodyToTopColor') - ]]); - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme', - 'state' => true - ]); - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Personnalisation de l\'arrière plan', - 'vendor' => [ - 'tinycolorpicker' - ], - 'view' => 'body' - ]); - } - - /** - * Options du pied de page - */ - public function footer() { - // Soumission du formulaire - if($this->isPost()) { - if ( $this->getInput('themeFooterCopyrightPosition') === 'hide' && - $this->getInput('themeFooterSocialsPosition') === 'hide' && - $this->getInput('themeFooterTextPosition') === 'hide' ) { - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Sélectionnez au moins un contenu à afficher', - 'redirect' => helper::baseUrl() . 'theme/footer', - 'state' => false - ]); - } else { - $this->setData(['theme', 'footer', [ - 'backgroundColor' => $this->getInput('themeFooterBackgroundColor'), - 'copyrightAlign' => $this->getInput('themeFooterCopyrightAlign'), - 'height' => $this->getInput('themeFooterHeight'), - 'loginLink' => $this->getInput('themeFooterLoginLink'), - 'margin' => $this->getInput('themeFooterMargin', helper::FILTER_BOOLEAN), - 'position' => $this->getInput('themeFooterPosition'), - 'fixed' => $this->getInput('themeFooterFixed', helper::FILTER_BOOLEAN), - 'socialsAlign' => $this->getInput('themeFooterSocialsAlign'), - 'text' => $this->getInput('themeFooterText', null), - 'textAlign' => $this->getInput('themeFooterTextAlign'), - 'textColor' => $this->getInput('themeFooterTextColor'), - 'copyrightPosition' => $this->getInput('themeFooterCopyrightPosition'), - 'textPosition' => $this->getInput('themeFooterTextPosition'), - 'socialsPosition' => $this->getInput('themeFooterSocialsPosition'), - 'textTransform' => $this->getInput('themeFooterTextTransform'), - 'font' => $this->getInput('themeFooterFont'), - 'fontSize' => $this->getInput('themeFooterFontSize'), - 'fontWeight' => $this->getInput('themeFooterFontWeight'), - 'displayVersion' => $this->getInput('themefooterDisplayVersion', helper::FILTER_BOOLEAN), - 'displaySiteMap' => $this->getInput('themefooterDisplaySiteMap', helper::FILTER_BOOLEAN), - 'displayCopyright' => $this->getInput('themefooterDisplayCopyright', helper::FILTER_BOOLEAN), - 'displayCookie' => $this->getInput('themefooterDisplayCookie', helper::FILTER_BOOLEAN), - 'displayLegal' => $this->getInput('themeFooterDisplayLegal', helper::FILTER_BOOLEAN), - 'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN), - 'displayMemberBar'=> $this->getInput('themeFooterDisplayMemberBar', helper::FILTER_BOOLEAN), - 'template' => $this->getInput('themeFooterTemplate') - ]]); - - // Sauvegarder la configuration localisée - $this->setData(['locale','legalPageId', $this->getInput('configLegalPageId')]); - $this->setData(['locale','searchPageId', $this->getInput('configSearchPageId')]); - - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme', - 'state' => true - ]); - } - } - - // Liste des pages - self::$pagesList = $this->getData(['page']); - foreach(self::$pagesList as $page => $pageId) { - if ($this->getData(['page',$page,'block']) === 'bar' || - $this->getData(['page',$page,'disable']) === true) { - unset(self::$pagesList[$page]); - } - } - - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Personnalisation du pied de page', - 'vendor' => [ - 'tinycolorpicker', - 'tinymce' - ], - 'view' => 'footer' - ]); - } - - /** - * Options de la bannière - */ - public function header() { - // Soumission du formulaire - if($this->isPost()) { - // Modification des URL des images dans la bannière perso - $featureContent = $this->getInput('themeHeaderText', null); - $featureContent = str_replace(helper::baseUrl(false,false), './', $featureContent); - - /** - * Stocker les images incluses dans la bannière perso dans un tableau - */ - preg_match_all('/]+>/i',$featureContent, $results); - foreach($results[0] as $value) { - // Lire le contenu XML - $sx = simplexml_load_string($value); - // Élément à remplacer - $files [] = str_replace('./site/file/source/','',(string) $sx[0]['src']); - } - - // Sauvegarder - $this->setData(['theme', 'header', [ - 'backgroundColor' => $this->getInput('themeHeaderBackgroundColor'), - 'font' => $this->getInput('themeHeaderFont'), - 'fontSize' => $this->getInput('themeHeaderFontSize'), - 'fontWeight' => $this->getInput('themeHeaderFontWeight'), - 'height' => $this->getInput('themeHeaderHeight'), - 'wide' => $this->getInput('themeHeaderWide'), - 'image' => $this->getInput('themeHeaderImage'), - 'imagePosition' => $this->getInput('themeHeaderImagePosition'), - 'imageRepeat' => $this->getInput('themeHeaderImageRepeat'), - 'margin' => $this->getInput('themeHeaderMargin', helper::FILTER_BOOLEAN), - 'position' => $this->getInput('themeHeaderPosition'), - 'textAlign' => $this->getInput('themeHeaderTextAlign'), - 'textColor' => $this->getInput('themeHeaderTextColor'), - 'textHide' => $this->getInput('themeHeaderTextHide', helper::FILTER_BOOLEAN), - 'textTransform' => $this->getInput('themeHeaderTextTransform'), - 'linkHomePage' => $this->getInput('themeHeaderlinkHomePage',helper::FILTER_BOOLEAN), - 'imageContainer' => $this->getInput('themeHeaderImageContainer'), - 'tinyHidden' => $this->getInput('themeHeaderTinyHidden', helper::FILTER_BOOLEAN), - 'feature' => $this->getInput('themeHeaderFeature'), - 'featureContent' => $featureContent, - 'featureFiles' => $files - ]]); - // Modification de la position du menu selon la position de la bannière - if ( $this->getData(['theme','header','position']) == 'site' ) - { - $this->setData(['theme', 'menu', 'position',str_replace ('body-','site-',$this->getData(['theme','menu','position']))]); - } - if ( $this->getData(['theme','header','position']) == 'body') - { - $this->setData(['theme', 'menu', 'position',str_replace ('site-','body-',$this->getData(['theme','menu','position']))]); - } - // Menu accroché à la bannière qui devient cachée - if ( $this->getData(['theme','header','position']) == 'hide' && - in_array( $this->getData(['theme','menu','position']) , ['body-first', 'site-first', 'body-first' , 'site-second']) - ) { - $this->setData(['theme', 'menu', 'position','site']); - } - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme', - 'state' => true - ]); - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Personnalisation de la bannière', - 'vendor' => [ - 'tinycolorpicker', - 'tinymce' - ], - 'view' => 'header' - ]); - } - - /** - * Accueil de la personnalisation - */ - public function index() { - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Personnalisation des thèmes', - 'view' => 'index' - ]); - } - - /** - * Options du menu - */ - public function menu() { - // Soumission du formulaire - if($this->isPost()) { - $this->setData(['theme', 'menu', [ - 'backgroundColor' => $this->getInput('themeMenuBackgroundColor'), - 'backgroundColorSub' => $this->getInput('themeMenuBackgroundColorSub'), - 'font' => $this->getInput('themeMenuFont'), - 'fontSize' => $this->getInput('themeMenuFontSize'), - 'fontWeight' => $this->getInput('themeMenuFontWeight'), - 'height' => $this->getInput('themeMenuHeight'), - 'wide' => $this->getInput('themeMenuWide'), - 'loginLink' => $this->getInput('themeMenuLoginLink', helper::FILTER_BOOLEAN), - 'margin' => $this->getInput('themeMenuMargin', helper::FILTER_BOOLEAN), - 'position' => $this->getInput('themeMenuPosition'), - 'textAlign' => $this->getInput('themeMenuTextAlign'), - 'textColor' => $this->getInput('themeMenuTextColor'), - 'textTransform' => $this->getInput('themeMenuTextTransform'), - 'fixed' => $this->getInput('themeMenuFixed', helper::FILTER_BOOLEAN), - 'activeColorAuto' => $this->getInput('themeMenuActiveColorAuto', helper::FILTER_BOOLEAN), - 'activeColor' => $this->getInput('themeMenuActiveColor'), - 'activeTextColor' => $this->getInput('themeMenuActiveTextColor'), - 'radius' => $this->getInput('themeMenuRadius'), - 'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN), - 'memberBar' => $this->getInput('themeMenuMemberBar', helper::FILTER_BOOLEAN), - 'burgerLogo' => $this->getInput('themeMenuBurgerLogo'), - 'burgerContent' => $this->getInput('themeMenuBurgerContent') - ]]); - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme', - 'state' => true - ]); - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Personnalisation du menu', - 'vendor' => [ - 'tinycolorpicker' - ], - 'view' => 'menu' - ]); - } - - /** - * Options des fontes - */ - public function fonts() { - - // Polices trouvées dans la configuration - $fonts = $this->getData(['fonts']); - - // Polices liées au thème - $used = [ - 'Bannière' => $this->getData (['theme', 'header', 'font']), - 'Menu' => $this->getData (['theme', 'menu', 'font']), - 'Titre ' => $this->getData (['theme', 'title', 'font']), - 'Texte' => $this->getData (['theme', 'text', 'font']), - 'Pied de page' => $this->getData (['theme', 'footer', 'font']), - 'Titre (admin)' => $this->getData (['admin', 'fontTitle' ]), - 'Admin (texte)' => $this->getData (['admin', 'fontText' ]) - ]; - - // Parcourir les fontes installées et construire le tableau pour le formulaire - foreach (self::$fonts as $fontId => $fontName) { - - // Fontes utilisées par le thème - $fontUsed[$fontId] = ''; - foreach ($used as $key => $value) { - if ( $value === $fontId) { - $fontUsed[$fontId] .= $key . '
'; - } - } - self::$fontsList [] = [ - '' . $fontName . '' , - $fontId, - $fontUsed[$fontId], - //array_key_exists($fontId, $fonts['imported']) ? 'Importée' : '', - array_key_exists($fontId, $fonts['files']) ? - $fonts['files'][$fontId] : - (array_key_exists($fontId, self::$fontsWebSafe) ? 'WebSafe' : 'CDN Fonts'), - array_key_exists($fontId, $fonts['imported']) || array_key_exists($fontId, $fonts['files']) - ? template::button('themeFontDelete' . $fontId, [ - 'class' => 'themeFontDelete buttonRed', - 'href' => helper::baseUrl() . $this->getUrl(0) . '/fontDelete/' . $fontId . '/' . $_SESSION['csrf'], - 'value' => template::ico('cancel'), - 'disabled' => !empty($fontUsed[$fontId]) - ]) - : '' - ]; - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Gestion des fontes', - 'view' => 'fonts' - ]); - } - - /** - * Ajouter une fonte - */ - public function fontAdd() { - // Soumission du formulaire - if ($this->isPost()) { - - $fontId = $this->getInput('fontAddFontId', null, true); - $fontName = $this->getInput('fontAddFontName', null, true); - $filePath = $this->getInput('fontAddFile', null); - $e = explode ('/', $filePath); - $file = $e[count($e) - 1 ]; - - // Vérifier l'existence de fontId et validité de family namesi usage en ligne de cdnFonts - $data = helper::getUrlContents('https://www.cdnfonts.com/' . $fontId . '.font'); - - if ( $filePath === '' - && $fontName !== '' - && strpos($data, $fontName) === false - ) { - - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Erreur de nom de fonte ou d\'identifiant', - 'redirect' => helper::baseUrl() . 'theme/fontAdd', - 'state' => false - ]); - - } else { - - // Charger les données des fontes - $files = $this->getData(['fonts', 'files']); - $imported = $this->getData(['fonts', 'imported']); - - // Concaténation dans les tableaux existants - $imported = array_merge([$fontId => $fontName], $imported); - $files = array_merge([$fontId => $file], $files); - - // Copier la fonte si le nom du fichier est fourni - if (!empty($filePath)) { - copy ( self::FILE_DIR . 'source/' . $filePath, self::DATA_DIR . 'fonts/' . $file ); - } - - // Mettre à jour le fichier des fontes - $this->setData(['fonts', 'imported', $imported ]); - if (!empty($filePath) ) { - $this->setData(['fonts', 'files', $files ]); - } - - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'La fonte a été importée', - 'redirect' => helper::baseUrl() . 'theme/fonts', - 'state' => true - ]); - } - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Ajouter une fonte', - 'view' => 'fontAdd' - ]); - } - - /** - * Effacer une fonte - */ - public function fontDelete() { - // Jeton incorrect - if ($this->getUrl(3) !== $_SESSION['csrf']) { - // Valeurs en sortie - $this->addOutput([ - 'redirect' => helper::baseUrl() . 'theme/fonts', - 'notification' => 'Action non autorisée' - ]); - } - // Suppression - else { - - // Charger les données des fontes - $files = $this->getData(['fonts', 'files']); - $imported = $this->getData(['fonts', 'imported']); - - // Effacer le fichier existant - if ( file_exists(self::DATA_DIR . $files[$this->getUrl(2)]) ) { - unlink(self::DATA_DIR . $files[$this->getUrl(2)]); - } - - // Supprimer les entrées - unset($files[$this->getUrl(2)]); - unset($imported[$this->getUrl(2)]); - - // Mettre à jour le fichier des fontes - $this->setData(['fonts', 'files', $files ]); - $this->setData(['fonts', 'imported', $imported ]); - // Valeurs en sortie - $this->addOutput([ - 'redirect' => helper::baseUrl() . 'theme/fonts', - 'notification' => 'Fonte supprimée', - 'state' => true - ]); - } - } - - - /** - * Réinitialisation de la personnalisation avancée - */ - public function reset() { - // $url prend l'adresse sans le token - $url = explode('&',$this->getUrl(2)); - - if ( isset($_GET['csrf']) - AND $_GET['csrf'] === $_SESSION['csrf'] - ) { - // Réinitialisation - $redirect =''; - switch ($url[0]) { - case 'admin': - $this->initData('admin'); - $redirect = helper::baseUrl() . 'theme/admin'; - break; - case 'manage': - $this->initData('theme'); - $redirect = helper::baseUrl() . 'theme/manage'; - break; - case 'custom': - unlink(self::DATA_DIR.'custom.css'); - $redirect = helper::baseUrl() . 'theme/advanced'; - break; - default : - $redirect = helper::baseUrl() . 'theme'; - } - - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Réinitialisation effectuée', - 'redirect' => $redirect, - 'state' => true - ]); - } else { - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Jeton incorrect' - ]); - } - } - - - /** - * Options du site - */ - public function site() { - // Soumission du formulaire - if($this->isPost()) { - $this->setData(['theme', 'title', [ - 'font' => $this->getInput('themeTitleFont'), - 'textColor' => $this->getInput('themeTitleTextColor'), - 'fontWeight' => $this->getInput('themeTitleFontWeight'), - 'textTransform' => $this->getInput('themeTitleTextTransform') - ]]); - $this->setData(['theme', 'text', [ - 'font' => $this->getInput('themeTextFont'), - 'fontSize' => $this->getInput('themeTextFontSize'), - 'textColor' => $this->getInput('themeTextTextColor'), - 'linkColor'=> $this->getInput('themeTextLinkColor') - ]]); - $this->setData(['theme', 'site', [ - 'backgroundColor' => $this->getInput('themeSiteBackgroundColor'), - 'radius' => $this->getInput('themeSiteRadius'), - 'shadow' => $this->getInput('themeSiteShadow'), - 'width' => $this->getInput('themeSiteWidth'), - 'margin' => $this->getInput('themeSiteMargin',helper::FILTER_BOOLEAN) - ]]); - $this->setData(['theme', 'button', [ - 'backgroundColor' => $this->getInput('themeButtonBackgroundColor') - ]]); - $this->setData(['theme', 'block', [ - 'backgroundColor' => $this->getInput('themeBlockBackgroundColor'), - 'borderColor' => $this->getInput('themeBlockBorderColor') - ]]); - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Modifications enregistrées', - 'redirect' => helper::baseUrl() . 'theme', - 'state' => true - ]); - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Personnalisation du site', - 'vendor' => [ - 'tinycolorpicker', - 'tinymce' - ], - 'view' => 'site' - ]); - } - - /** - * Import du thème - */ - public function manage() { - if($this->isPost() ) { - - $zipFilename = $this->getInput('themeManageImport', helper::FILTER_STRING_SHORT, true); - $data = $this->import(self::FILE_DIR.'source/' . $zipFilename); - if ($data['success']) { - header("Refresh:0"); - } else { - // Valeurs en sortie - $this->addOutput([ - 'notification' => $data['notification'], - 'state' => $data['success'], - 'title' => 'Gestion des thèmes', - 'view' => 'manage' - ]);; - } - } - // Valeurs en sortie - $this->addOutput([ - 'title' => 'Gestion des thèmes', - 'view' => 'manage' - ]); - } - - /** - * Importe un thème - * @param string Url du thème à télécharger - * @param @return array contenant $success = true ou false ; $ notification string message à afficher - */ - - public function import($zipName = '') { - - if ($zipName !== '' && - file_exists($zipName)) { - // Init variables de retour - $success = false; - $notification = ''; - // Dossier temporaire - $tempFolder = uniqid(); - // Ouvrir le zip - $zip = new ZipArchive(); - if ($zip->open($zipName) === TRUE) { - mkdir (self::TEMP_DIR . $tempFolder, 0755); - $zip->extractTo(self::TEMP_DIR . $tempFolder ); - $modele = ''; - // Archive de thème ? - if ( - file_exists(self::TEMP_DIR . $tempFolder . '/site/data/custom.css') - AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.css') - AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.json') - ) { - $modele = 'theme'; - } - if( - file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.json') - AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.css') - ) { - $modele = 'admin'; - - } - if (!empty($modele) - ) { - // traiter l'archive - $success = $zip->extractTo('.'); - - // Substitution des fontes Google - if ($modele = 'theme') { - $c = $this->subFonts(self::DATA_DIR . 'theme.json'); - // Un remplacement nécessite la régénération de la feuille de style - if ($c > 0 - AND file_exists(self::DATA_DIR . 'theme.css') - ) { - unlink(self::DATA_DIR . 'theme.css'); - } - } - if ($modele = 'admin') { - $c = $this->subFonts(self::DATA_DIR . 'admin.json'); - // Un remplacement nécessite la régénération de la feuille de style - if ($c > 0 - AND file_exists(self::DATA_DIR . 'admin.css') - ) { - unlink(self::DATA_DIR . 'admin.css'); - } - } - - // traitement d'erreur - $notification = $success ? 'Le thème a été importé' : 'Erreur lors de l\'extraction, vérifiez les permissions.'; - - - } else { - // pas une archive de thème - $success = false; - $notification = 'Ce n\'est pas l\'archive d\'un thème !'; - } - // Supprimer le dossier temporaire même si le thème est invalide - $this->removeDir(self::TEMP_DIR . $tempFolder); - $zip->close(); - } else { - // erreur à l'ouverture - $success = false; - $notification = 'Impossible d\'ouvrir l\'archive'; - } - return (['success' => $success, 'notification' => $notification]); - } - - return (['success' => false, 'notification' => 'Archive non spécifiée ou introuvable']); - } - - - - /** - * Export du thème - */ - public function export() { - // Make zip - $zipFilename = $this->zipTheme($this->getUrl(2)); - // Téléchargement du ZIP - header('Content-Description: File Transfer'); - header('Content-Type: application/octet-stream'); - header('Content-Transfer-Encoding: binary'); - header('Content-Disposition: attachment; filename="' . $zipFilename . '"'); - header('Content-Length: ' . filesize(self::TEMP_DIR . $zipFilename)); - readfile(self::TEMP_DIR . $zipFilename); - // Nettoyage du dossier - unlink (self::TEMP_DIR . $zipFilename); - exit(); - } - - /** - * Export du thème - */ - public function save() { - // Make zip - $zipFilename = $this->zipTheme($this->getUrl(2)); - // Téléchargement du ZIP - if (!is_dir(self::FILE_DIR.'source/theme')) { - mkdir(self::FILE_DIR.'source/theme', 0755); - } - copy (self::TEMP_DIR . $zipFilename , self::FILE_DIR.'source/theme/' . $zipFilename); - // Nettoyage du dossier - unlink (self::TEMP_DIR . $zipFilename); - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Archive '.$zipFilename.' sauvegardée avec succès', - 'redirect' => helper::baseUrl() . 'theme/manage', - 'state' => true - ]); - } - - /** - * construction du zip Fonction appelée par export() et save() - * @param string $modele theme ou admin - */ - private function zipTheme($modele) { - // Creation du dossier - $zipFilename = $modele . date('Y-m-d-H-i-s', time()) . '.zip'; - $zip = new ZipArchive(); - if ($zip->open(self::TEMP_DIR . $zipFilename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) === TRUE) { - switch ($modele) { - case 'admin': - $zip->addFile(self::DATA_DIR.'admin.json',self::DATA_DIR.'admin.json'); - $zip->addFile(self::DATA_DIR.'admin.css',self::DATA_DIR.'admin.css'); - break; - case 'theme': - $zip->addFile(self::DATA_DIR.'theme.json',self::DATA_DIR.'theme.json'); - $zip->addFile(self::DATA_DIR.'theme.css',self::DATA_DIR.'theme.css'); - $zip->addFile(self::DATA_DIR.'custom.css',self::DATA_DIR.'custom.css'); - // Traite l'image dans le body - if ($this->getData(['theme','body','image']) !== '' ) { - $zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','body','image']), - self::FILE_DIR.'source/'.$this->getData(['theme','body','image']) - ); - } - // Traite l'image dans le header - if ($this->getData(['theme','header','image']) !== '' ) { - $zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','header','image']), - self::FILE_DIR.'source/'.$this->getData(['theme','header','image']) - ); - } - // Traite les images du header perso - if (!empty($this->getData(['theme','header','featureFiles'])) ) { - foreach($this->getData(['theme','header','featureFiles']) as $value) { - $zip->addFile(self::FILE_DIR . 'source/' . $value, - self::FILE_DIR . 'source/' . $value ); - } - } - break; - } - $ret = $zip->close(); - } - return ($zipFilename); - } - - /** - * Subsitution des fontes de Google Fonts vers CdnFont grâce à un tableau de conversion - * @param string $file, nom du fichier json à convertir - * @return int nombre de substitution effectuées - */ - private function subFonts($file) { - // Tableau de substitution des fontes - $fonts = [ - 'Abril+Fatface' => 'abril-fatface', - 'Arimo' => 'arimo', - 'Arvo' => 'arvo', - 'Berkshire+Swash' => 'berkshire-swash', - 'Cabin' => 'genera', - 'Dancing+Script' => 'dancing-script', - 'Droid+Sans' => 'droid-sans-2', - 'Droid+Serif' => 'droid-serif-2', - 'Fira+Sans' => 'fira-sans', - 'Inconsolata' => 'inconsolata-2', - 'Indie+Flower' =>'indie-flower', - 'Josefin+Slab' => 'josefin-sans-std', - 'Lobster' => 'lobster-2', - 'Lora' => 'lora', - 'Lato' =>'lato', - 'Marvel' => 'montserrat-ace', - 'Old+Standard+TT' => 'old-standard-tt-3', - 'Open+Sans' =>'open-sans', - // Corriger l'erreur de nom de police installée par défaut, il manquait un O en majuscule - 'open+Sans' =>'open-sans', - 'Oswald' =>'oswald-4', - 'PT+Mono' => 'pt-mono', - 'PT+Serif' =>'pt-serif', - 'Raleway' => 'raleway-5', - 'Rancho' => 'rancho', - 'Roboto' => 'Roboto', - 'Signika' => 'signika', - 'Ubuntu' => 'ubuntu', - 'Vollkorn' => 'vollkorn' - ]; - - $data = file_get_contents($file); - $count = 0; - foreach ($fonts as $oldId => $newId){ - $data = str_replace($oldId, $newId, $data, $c); - $count = $count + (int) $c; - } - // Sauvegarder la chaîne modifiée - if ($count > 0) { - file_put_contents($file, $data); - } - // Retourner le nombre d'occurrences - return ($count); - } - -} + + * @copyright Copyright (C) 2008-2018, Rémi Jean + * @license GNU General Public License, version 3 + * @link http://zwiicms.fr/ + * @copyright : Frédéric Tempez + * @copyright Copyright (C) 2018-2022, Frédéric Tempez + */ + +class theme extends common { + + public static $actions = [ + 'advanced' => self::GROUP_ADMIN, + 'body' => self::GROUP_ADMIN, + 'footer' => self::GROUP_ADMIN, + 'header' => self::GROUP_ADMIN, + 'index' => self::GROUP_ADMIN, + 'menu' => self::GROUP_ADMIN, + 'reset' => self::GROUP_ADMIN, + 'site' => self::GROUP_ADMIN, + 'admin' => self::GROUP_ADMIN, + 'manage' => self::GROUP_ADMIN, + 'export' => self::GROUP_ADMIN, + 'import' => self::GROUP_ADMIN, + 'save' => self::GROUP_ADMIN, + 'fonts' => self::GROUP_ADMIN, + 'fontAdd' => self::GROUP_ADMIN, + 'fontDelete' => self::GROUP_ADMIN + ]; + public static $aligns = [ + 'left' => 'À gauche', + 'center' => 'Au centre', + 'right' => 'À droite' + ]; + public static $attachments = [ + 'scroll' => 'Standard', + 'fixed' => 'Fixe' + ]; + public static $containerWides = [ + 'container' => 'Limitée au site', + 'none' => 'Etendue sur la page' + ]; + public static $footerblocks = [ + 1 => [ + 'hide' => 'Masqué', + 'center' => 'Affiché' ], + 2 => [ + 'hide' => 'Masqué', + 'left' => 'À gauche', + 'right' => 'À droite' ], + 3 => [ + 'hide' => 'Masqué', + 'left' => 'À gauche', + 'center' => 'Au centre', + 'right' => 'À droite' ], + 4 => [ + 'hide' => 'Masqué', + 'left' => 'En haut', + 'center' => 'Au milieu', + 'right' => 'En bas' ] + ]; + + public static $fontWeights = [ + 'normal' => 'Maigre', + 'bold' => 'Gras' + ]; + public static $footerHeights = [ + '0px' => 'Nulles (0px)', + '5px' => 'Très petites (5px)', + '10px' => 'Petites (10px)', + '15px' => 'Moyennes (15px)', + '20px' => 'Grandes (20px)' + ]; + public static $footerPositions = [ + 'hide' => 'Caché', + 'site' => 'Dans le site', + 'body' => 'En dessous du site' + ]; + public static $footerFontSizes = [ + '.8em' => 'Très petite (80%)', + '.9em' => 'Petite (90%)', + '1em' => 'Standard (100%)', + '1.1em' => 'Moyenne (110%)', + '1.2em' => 'Grande (120%)', + '1.3em' => 'Très grande (130%)' + ]; + public static $headerFontSizes = [ + '1.6em' => 'Très petite (160%)', + '1.8em' => 'Petite (180%)', + '2em' => 'Moyenne (200%)', + '2.2em' => 'Grande (220%)', + '2.4vmax' => 'Très grande (240%)' + ]; + public static $headerHeights = [ + 'unset' => 'Libre', // texte dynamique cf header.js.php + '100px' => 'Très petite (100px) ', + '150px' => 'Petite (150px)', + '200px' => 'Moyenne (200px)', + '300px' => 'Grande (300px)', + '400px' => 'Très grande (400px)', + ]; + public static $headerPositions = [ + 'body' => 'Au dessus du site', + 'site' => 'Dans le site', + 'hide' => 'Cachée' + ]; + public static $headerFeatures = [ + 'wallpaper' => 'Couleur unie ou papier-peint', + 'feature' => 'Contenu personnalisé' + ]; + public static $imagePositions = [ + 'top left' => 'En haut à gauche', + 'top center' => 'En haut au centre', + 'top right' => 'En haut à droite', + 'center left' => 'Au milieu à gauche', + 'center center' => 'Au milieu au centre', + 'center right' => 'Au milieu à droite', + 'bottom left' => 'En bas à gauche', + 'bottom center' => 'En bas au centre', + 'bottom right' => 'En bas à droite' + ]; + public static $menuFontSizes = [ + '.8em' => 'Très petite (80%)', + '.9em' => 'Petite (90%)', + '1em' => 'Standard (100%)', + '1.1em' => 'Moyenne (110%)', + '1.2em' => 'Grande (120%)', + '1.3em' => 'Très grande (130%)' + ]; + public static $menuHeights = [ + '5px 10px' => 'Très petite', + '10px' => 'Petite', + '15px 10px' => 'Moyenne', + '20px 15px' => 'Grande', + '25px 15px' => 'Très grande' + ]; + public static $menuPositionsSite = [ + 'top' => 'En-dehors du site', + 'site-first' => 'Avant la bannière', + 'site-second' => 'Après la bannière', + 'hide' => 'Caché' + ]; + public static $menuPositionsBody = [ + 'top' => 'En-dehors du site', + 'body-first' => 'Avant la bannière', + 'body-second' => 'Après la bannière', + 'site' => 'Dans le site', + 'hide' => 'Caché' + ]; + public static $menuRadius = [ + '0px' => 'Aucun', + '3px 3px 0px 0px' => 'Très léger', + '6px 6px 0px 0px' => 'Léger', + '9px 9px 0px 0px' => 'Moyen', + '12px 12px 0px 0px' => 'Important', + '15px 15px 0px 0px' => 'Très important' + ]; + public static $radius = [ + '0px' => 'Aucun', + '5px' => 'Très léger', + '10px' => 'Léger', + '15px' => 'Moyen', + '25px' => 'Important', + '50px' => 'Très important' + ]; + public static $repeats = [ + 'no-repeat' => 'Ne pas répéter', + 'repeat-x' => 'Sur l\'axe horizontal', + 'repeat-y' => 'Sur l\'axe vertical', + 'repeat' => 'Sur les deux axes' + ]; + public static $shadows = [ + '0px' => 'Aucune', + '1px 1px 5px' => 'Très légère', + '1px 1px 10px' => 'Légère', + '1px 1px 15px' => 'Moyenne', + '1px 1px 25px' => 'Importante', + '1px 1px 50px' => 'Très importante' + ]; + public static $siteFontSizes = [ + '12px' => '12 pixels', + '13px' => '13 pixels', + '14px' => '14 pixels', + '15px' => '15 pixels', + '16px' => '16 pixels' + ]; + public static $bodySizes = [ + 'auto' => 'Automatique', + '100% 100%' => 'Image étirée (100% 100%)', + 'cover' => 'Responsive (cover)', + 'contain' => 'Responsive (contain)' + ]; + public static $textTransforms = [ + 'none' => 'Standard', + 'lowercase' => 'Minuscules', + 'uppercase' => 'Majuscules', + 'capitalize' => 'Majuscule à chaque mot' + ]; + public static $siteWidths = [ + '750px' => 'Petite (750 pixels)', + '960px' => 'Moyenne (960 pixels)', + '1170px' => 'Grande (1170 pixels)', + '100%' => 'Fluide (100%)' + ]; + public static $headerWide = [ + 'auto auto' => 'Automatique', + '100% 100%' => 'Image étirée (100% 100%)', + 'cover' => 'Responsive (cover)', + 'contain' => 'Responsive (contain)' + ]; + public static $footerTemplate = [ + '1' => 'Une seule colonne', + '2' => 'Deux colonnes : 1/2 - 1/2', + '3' => 'Trois colonnes : 1/3 - 1/3 - 1/3', + '4' => 'Trois lignes superposées' + ]; + public static $burgerContent = [ + 'none' => 'Aucun', + 'title' => 'Titre du site', + 'logo' => 'Logo du site' + ]; + + + // Variable pour construire la liste des pages du site + public static $pagesList = []; + // Variable pour construire la liste des fontes installées + public static $fontsList = []; + + /** + * Thème des écrans d'administration + */ + public function admin() { + // Soumission du formulaire + if($this->isPost()) { + $this->setData(['admin', [ + 'backgroundColor' => $this->getInput('adminBackgroundColor'), + 'colorTitle' => $this->getInput('adminColorTitle'), + 'colorText' => $this->getInput('adminColorText'), + 'colorButtonText' => $this->getInput('adminColorButtonText'), + 'backgroundColorButton' => $this->getInput('adminColorButton'), + 'backgroundColorButtonGrey' => $this->getInput('adminColorGrey'), + 'backgroundColorButtonRed' => $this->getInput('adminColorRed'), + 'backgroundColorButtonGreen'=> $this->getInput('adminColorGreen'), + 'backgroundColorButtonHelp'=> $this->getInput('adminColorHelp'), + 'fontText' => $this->getInput('adminFontText'), + 'fontSize' => $this->getInput('adminFontTextSize'), + 'fontTitle' => $this->getInput('adminFontTitle'), + 'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'), + 'borderBlockColor' => $this->getInput('adminBorderBlockColor'), + ]]); + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme/admin', + 'state' => true + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Administration', + 'view' => 'admin', + 'vendor' => [ + 'tinycolorpicker' + ], + ]); + } + + /** + * Mode avancé + */ + public function advanced() { + // Soumission du formulaire + if($this->isPost()) { + // Enregistre le CSS + file_put_contents(self::DATA_DIR.'custom.css', $this->getInput('themeAdvancedCss', null)); + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme/advanced', + 'state' => true + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Éditeur CSS', + 'vendor' => [ + 'codemirror' + ], + 'view' => 'advanced' + ]); + } + + /** + * Options de l'arrière plan + */ + public function body() { + // Soumission du formulaire + if($this->isPost()) { + $this->setData(['theme', 'body', [ + 'backgroundColor' => $this->getInput('themeBodyBackgroundColor'), + 'image' => $this->getInput('themeBodyImage'), + 'imageAttachment' => $this->getInput('themeBodyImageAttachment'), + 'imagePosition' => $this->getInput('themeBodyImagePosition'), + 'imageRepeat' => $this->getInput('themeBodyImageRepeat'), + 'imageSize' => $this->getInput('themeBodyImageSize'), + 'toTopbackgroundColor' => $this->getInput('themeBodyToTopBackground'), + 'toTopColor' => $this->getInput('themeBodyToTopColor') + ]]); + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme', + 'state' => true + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Personnalisation de l\'arrière plan', + 'vendor' => [ + 'tinycolorpicker' + ], + 'view' => 'body' + ]); + } + + /** + * Options du pied de page + */ + public function footer() { + // Soumission du formulaire + if($this->isPost()) { + if ( $this->getInput('themeFooterCopyrightPosition') === 'hide' && + $this->getInput('themeFooterSocialsPosition') === 'hide' && + $this->getInput('themeFooterTextPosition') === 'hide' ) { + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Sélectionnez au moins un contenu à afficher', + 'redirect' => helper::baseUrl() . 'theme/footer', + 'state' => false + ]); + } else { + $this->setData(['theme', 'footer', [ + 'backgroundColor' => $this->getInput('themeFooterBackgroundColor'), + 'copyrightAlign' => $this->getInput('themeFooterCopyrightAlign'), + 'height' => $this->getInput('themeFooterHeight'), + 'loginLink' => $this->getInput('themeFooterLoginLink'), + 'margin' => $this->getInput('themeFooterMargin', helper::FILTER_BOOLEAN), + 'position' => $this->getInput('themeFooterPosition'), + 'fixed' => $this->getInput('themeFooterFixed', helper::FILTER_BOOLEAN), + 'socialsAlign' => $this->getInput('themeFooterSocialsAlign'), + 'text' => $this->getInput('themeFooterText', null), + 'textAlign' => $this->getInput('themeFooterTextAlign'), + 'textColor' => $this->getInput('themeFooterTextColor'), + 'copyrightPosition' => $this->getInput('themeFooterCopyrightPosition'), + 'textPosition' => $this->getInput('themeFooterTextPosition'), + 'socialsPosition' => $this->getInput('themeFooterSocialsPosition'), + 'textTransform' => $this->getInput('themeFooterTextTransform'), + 'font' => $this->getInput('themeFooterFont'), + 'fontSize' => $this->getInput('themeFooterFontSize'), + 'fontWeight' => $this->getInput('themeFooterFontWeight'), + 'displayVersion' => $this->getInput('themefooterDisplayVersion', helper::FILTER_BOOLEAN), + 'displaySiteMap' => $this->getInput('themefooterDisplaySiteMap', helper::FILTER_BOOLEAN), + 'displayCopyright' => $this->getInput('themefooterDisplayCopyright', helper::FILTER_BOOLEAN), + 'displayCookie' => $this->getInput('themefooterDisplayCookie', helper::FILTER_BOOLEAN), + 'displayLegal' => $this->getInput('themeFooterDisplayLegal', helper::FILTER_BOOLEAN), + 'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN), + 'displayMemberBar'=> $this->getInput('themeFooterDisplayMemberBar', helper::FILTER_BOOLEAN), + 'template' => $this->getInput('themeFooterTemplate') + ]]); + + // Sauvegarder la configuration localisée + $this->setData(['locale','legalPageId', $this->getInput('configLegalPageId')]); + $this->setData(['locale','searchPageId', $this->getInput('configSearchPageId')]); + + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme', + 'state' => true + ]); + } + } + + // Liste des pages + self::$pagesList = $this->getData(['page']); + foreach(self::$pagesList as $page => $pageId) { + if ($this->getData(['page',$page,'block']) === 'bar' || + $this->getData(['page',$page,'disable']) === true) { + unset(self::$pagesList[$page]); + } + } + + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Personnalisation du pied de page', + 'vendor' => [ + 'tinycolorpicker', + 'tinymce' + ], + 'view' => 'footer' + ]); + } + + /** + * Options de la bannière + */ + public function header() { + // Soumission du formulaire + if($this->isPost()) { + // Modification des URL des images dans la bannière perso + $featureContent = $this->getInput('themeHeaderText', null); + $featureContent = str_replace(helper::baseUrl(false,false), './', $featureContent); + + /** + * Stocker les images incluses dans la bannière perso dans un tableau + */ + preg_match_all('/]+>/i',$featureContent, $results); + foreach($results[0] as $value) { + // Lire le contenu XML + $sx = simplexml_load_string($value); + // Élément à remplacer + $files [] = str_replace('./site/file/source/','',(string) $sx[0]['src']); + } + + // Sauvegarder + $this->setData(['theme', 'header', [ + 'backgroundColor' => $this->getInput('themeHeaderBackgroundColor'), + 'font' => $this->getInput('themeHeaderFont'), + 'fontSize' => $this->getInput('themeHeaderFontSize'), + 'fontWeight' => $this->getInput('themeHeaderFontWeight'), + 'height' => $this->getInput('themeHeaderHeight'), + 'wide' => $this->getInput('themeHeaderWide'), + 'image' => $this->getInput('themeHeaderImage'), + 'imagePosition' => $this->getInput('themeHeaderImagePosition'), + 'imageRepeat' => $this->getInput('themeHeaderImageRepeat'), + 'margin' => $this->getInput('themeHeaderMargin', helper::FILTER_BOOLEAN), + 'position' => $this->getInput('themeHeaderPosition'), + 'textAlign' => $this->getInput('themeHeaderTextAlign'), + 'textColor' => $this->getInput('themeHeaderTextColor'), + 'textHide' => $this->getInput('themeHeaderTextHide', helper::FILTER_BOOLEAN), + 'textTransform' => $this->getInput('themeHeaderTextTransform'), + 'linkHomePage' => $this->getInput('themeHeaderlinkHomePage',helper::FILTER_BOOLEAN), + 'imageContainer' => $this->getInput('themeHeaderImageContainer'), + 'tinyHidden' => $this->getInput('themeHeaderTinyHidden', helper::FILTER_BOOLEAN), + 'feature' => $this->getInput('themeHeaderFeature'), + 'featureContent' => $featureContent, + 'featureFiles' => $files + ]]); + // Modification de la position du menu selon la position de la bannière + if ( $this->getData(['theme','header','position']) == 'site' ) + { + $this->setData(['theme', 'menu', 'position',str_replace ('body-','site-',$this->getData(['theme','menu','position']))]); + } + if ( $this->getData(['theme','header','position']) == 'body') + { + $this->setData(['theme', 'menu', 'position',str_replace ('site-','body-',$this->getData(['theme','menu','position']))]); + } + // Menu accroché à la bannière qui devient cachée + if ( $this->getData(['theme','header','position']) == 'hide' && + in_array( $this->getData(['theme','menu','position']) , ['body-first', 'site-first', 'body-first' , 'site-second']) + ) { + $this->setData(['theme', 'menu', 'position','site']); + } + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme', + 'state' => true + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Personnalisation de la bannière', + 'vendor' => [ + 'tinycolorpicker', + 'tinymce' + ], + 'view' => 'header' + ]); + } + + /** + * Accueil de la personnalisation + */ + public function index() { + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Personnalisation des thèmes', + 'view' => 'index' + ]); + } + + /** + * Options du menu + */ + public function menu() { + // Soumission du formulaire + if($this->isPost()) { + $this->setData(['theme', 'menu', [ + 'backgroundColor' => $this->getInput('themeMenuBackgroundColor'), + 'backgroundColorSub' => $this->getInput('themeMenuBackgroundColorSub'), + 'font' => $this->getInput('themeMenuFont'), + 'fontSize' => $this->getInput('themeMenuFontSize'), + 'fontWeight' => $this->getInput('themeMenuFontWeight'), + 'height' => $this->getInput('themeMenuHeight'), + 'wide' => $this->getInput('themeMenuWide'), + 'loginLink' => $this->getInput('themeMenuLoginLink', helper::FILTER_BOOLEAN), + 'margin' => $this->getInput('themeMenuMargin', helper::FILTER_BOOLEAN), + 'position' => $this->getInput('themeMenuPosition'), + 'textAlign' => $this->getInput('themeMenuTextAlign'), + 'textColor' => $this->getInput('themeMenuTextColor'), + 'textTransform' => $this->getInput('themeMenuTextTransform'), + 'fixed' => $this->getInput('themeMenuFixed', helper::FILTER_BOOLEAN), + 'activeColorAuto' => $this->getInput('themeMenuActiveColorAuto', helper::FILTER_BOOLEAN), + 'activeColor' => $this->getInput('themeMenuActiveColor'), + 'activeTextColor' => $this->getInput('themeMenuActiveTextColor'), + 'radius' => $this->getInput('themeMenuRadius'), + 'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN), + 'memberBar' => $this->getInput('themeMenuMemberBar', helper::FILTER_BOOLEAN), + 'burgerLogo' => $this->getInput('themeMenuBurgerLogo'), + 'burgerContent' => $this->getInput('themeMenuBurgerContent') + ]]); + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme', + 'state' => true + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Personnalisation du menu', + 'vendor' => [ + 'tinycolorpicker' + ], + 'view' => 'menu' + ]); + } + + /** + * Options des fontes + */ + public function fonts() { + + $this->listFonts(); + //echo "
";
+
+
+		// Polices liées au thème
+		$used = [
+			'Bannière' 		=> $this->getData (['theme', 'header', 'font']),
+			'Menu' 			=> $this->getData (['theme', 'menu', 'font']),
+			'Titre ' 		=> $this->getData (['theme', 'title', 'font']),
+			'Texte'   		=> $this->getData (['theme', 'text', 'font']),
+			'Pied de page' 	=> $this->getData (['theme', 'footer', 'font']),
+			'Titre (admin)' => $this->getData (['admin', 'fontTitle' ]),
+			'Admin (texte)' => $this->getData (['admin', 'fontText' ])
+		];
+
+		// Parcourir les fontes installées et construire le tableau pour le formulaire
+		foreach (self::$fonts as $fontId => $fontName) {
+
+			// Fontes utilisées par le thème
+			$fontUsed[$fontId] = '';
+			foreach ($used as $key => $value) {
+				if ( $value === $fontId) {
+					$fontUsed[$fontId] .=  $key . '
'; + } + } + self::$fontsList [] = [ + '' . $fontName . '' , + $fontId, + $fontUsed[$fontId], + //array_key_exists($fontId, $fonts['imported']) ? 'Importée' : '', + array_key_exists($fontId, $fonts['files']) ? + $fonts['files'][$fontId] : + (array_key_exists($fontId, self::$fontsWebSafe) ? 'WebSafe' : 'CDN Fonts'), + array_key_exists($fontId, $fonts['imported']) || array_key_exists($fontId, $fonts['files']) + ? template::button('themeFontDelete' . $fontId, [ + 'class' => 'themeFontDelete buttonRed', + 'href' => helper::baseUrl() . $this->getUrl(0) . '/fontDelete/' . $fontId . '/' . $_SESSION['csrf'], + 'value' => template::ico('cancel'), + 'disabled' => !empty($fontUsed[$fontId]) + ]) + : '' + ]; + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Gestion des fontes', + 'view' => 'fonts' + ]); + } + + /** + * Ajouter une fonte + */ + public function fontAdd() { + // Soumission du formulaire + if ($this->isPost()) { + + $fontId = $this->getInput('fontAddFontId', null, true); + $fontName = $this->getInput('fontAddFontName', null, true); + $filePath = $this->getInput('fontAddFile', null); + $e = explode ('/', $filePath); + $file = $e[count($e) - 1 ]; + + // Vérifier l'existence de fontId et validité de family namesi usage en ligne de cdnFonts + $data = helper::getUrlContents('https://www.cdnfonts.com/' . $fontId . '.font'); + + if ( $filePath === '' + && $fontName !== '' + && strpos($data, $fontName) === false + ) { + + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Erreur de nom de fonte ou d\'identifiant', + 'redirect' => helper::baseUrl() . 'theme/fontAdd', + 'state' => false + ]); + + } else { + + // Charger les données des fontes + $files = $this->getData(['fonts', 'files']); + $imported = $this->getData(['fonts', 'imported']); + + // Concaténation dans les tableaux existants + $imported = array_merge([$fontId => $fontName], $imported); + $files = array_merge([$fontId => $file], $files); + + // Copier la fonte si le nom du fichier est fourni + if (!empty($filePath)) { + copy ( self::FILE_DIR . 'source/' . $filePath, self::DATA_DIR . 'fonts/' . $file ); + } + + // Mettre à jour le fichier des fontes + $this->setData(['fonts', 'imported', $imported ]); + if (!empty($filePath) ) { + $this->setData(['fonts', 'files', $files ]); + } + + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'La fonte a été importée', + 'redirect' => helper::baseUrl() . 'theme/fonts', + 'state' => true + ]); + } + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Ajouter une fonte', + 'view' => 'fontAdd' + ]); + } + + /** + * Effacer une fonte + */ + public function fontDelete() { + // Jeton incorrect + if ($this->getUrl(3) !== $_SESSION['csrf']) { + // Valeurs en sortie + $this->addOutput([ + 'redirect' => helper::baseUrl() . 'theme/fonts', + 'notification' => 'Action non autorisée' + ]); + } + // Suppression + else { + + // Charger les données des fontes + $files = $this->getData(['fonts', 'files']); + $imported = $this->getData(['fonts', 'imported']); + + // Effacer le fichier existant + if ( file_exists(self::DATA_DIR . $files[$this->getUrl(2)]) ) { + unlink(self::DATA_DIR . $files[$this->getUrl(2)]); + } + + // Supprimer les entrées + unset($files[$this->getUrl(2)]); + unset($imported[$this->getUrl(2)]); + + // Mettre à jour le fichier des fontes + $this->setData(['fonts', 'files', $files ]); + $this->setData(['fonts', 'imported', $imported ]); + // Valeurs en sortie + $this->addOutput([ + 'redirect' => helper::baseUrl() . 'theme/fonts', + 'notification' => 'Fonte supprimée', + 'state' => true + ]); + } + } + + + /** + * Réinitialisation de la personnalisation avancée + */ + public function reset() { + // $url prend l'adresse sans le token + $url = explode('&',$this->getUrl(2)); + + if ( isset($_GET['csrf']) + AND $_GET['csrf'] === $_SESSION['csrf'] + ) { + // Réinitialisation + $redirect =''; + switch ($url[0]) { + case 'admin': + $this->initData('admin'); + $redirect = helper::baseUrl() . 'theme/admin'; + break; + case 'manage': + $this->initData('theme'); + $redirect = helper::baseUrl() . 'theme/manage'; + break; + case 'custom': + unlink(self::DATA_DIR.'custom.css'); + $redirect = helper::baseUrl() . 'theme/advanced'; + break; + default : + $redirect = helper::baseUrl() . 'theme'; + } + + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Réinitialisation effectuée', + 'redirect' => $redirect, + 'state' => true + ]); + } else { + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Jeton incorrect' + ]); + } + } + + + /** + * Options du site + */ + public function site() { + // Soumission du formulaire + if($this->isPost()) { + $this->setData(['theme', 'title', [ + 'font' => $this->getInput('themeTitleFont'), + 'textColor' => $this->getInput('themeTitleTextColor'), + 'fontWeight' => $this->getInput('themeTitleFontWeight'), + 'textTransform' => $this->getInput('themeTitleTextTransform') + ]]); + $this->setData(['theme', 'text', [ + 'font' => $this->getInput('themeTextFont'), + 'fontSize' => $this->getInput('themeTextFontSize'), + 'textColor' => $this->getInput('themeTextTextColor'), + 'linkColor'=> $this->getInput('themeTextLinkColor') + ]]); + $this->setData(['theme', 'site', [ + 'backgroundColor' => $this->getInput('themeSiteBackgroundColor'), + 'radius' => $this->getInput('themeSiteRadius'), + 'shadow' => $this->getInput('themeSiteShadow'), + 'width' => $this->getInput('themeSiteWidth'), + 'margin' => $this->getInput('themeSiteMargin',helper::FILTER_BOOLEAN) + ]]); + $this->setData(['theme', 'button', [ + 'backgroundColor' => $this->getInput('themeButtonBackgroundColor') + ]]); + $this->setData(['theme', 'block', [ + 'backgroundColor' => $this->getInput('themeBlockBackgroundColor'), + 'borderColor' => $this->getInput('themeBlockBorderColor') + ]]); + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Modifications enregistrées', + 'redirect' => helper::baseUrl() . 'theme', + 'state' => true + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Personnalisation du site', + 'vendor' => [ + 'tinycolorpicker', + 'tinymce' + ], + 'view' => 'site' + ]); + } + + /** + * Import du thème + */ + public function manage() { + if($this->isPost() ) { + + $zipFilename = $this->getInput('themeManageImport', helper::FILTER_STRING_SHORT, true); + $data = $this->import(self::FILE_DIR.'source/' . $zipFilename); + if ($data['success']) { + header("Refresh:0"); + } else { + // Valeurs en sortie + $this->addOutput([ + 'notification' => $data['notification'], + 'state' => $data['success'], + 'title' => 'Gestion des thèmes', + 'view' => 'manage' + ]);; + } + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Gestion des thèmes', + 'view' => 'manage' + ]); + } + + /** + * Importe un thème + * @param string Url du thème à télécharger + * @param @return array contenant $success = true ou false ; $ notification string message à afficher + */ + + public function import($zipName = '') { + + if ($zipName !== '' && + file_exists($zipName)) { + // Init variables de retour + $success = false; + $notification = ''; + // Dossier temporaire + $tempFolder = uniqid(); + // Ouvrir le zip + $zip = new ZipArchive(); + if ($zip->open($zipName) === TRUE) { + mkdir (self::TEMP_DIR . $tempFolder, 0755); + $zip->extractTo(self::TEMP_DIR . $tempFolder ); + $modele = ''; + // Archive de thème ? + if ( + file_exists(self::TEMP_DIR . $tempFolder . '/site/data/custom.css') + AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.css') + AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.json') + ) { + $modele = 'theme'; + } + if( + file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.json') + AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.css') + ) { + $modele = 'admin'; + + } + if (!empty($modele) + ) { + // traiter l'archive + $success = $zip->extractTo('.'); + + // Substitution des fontes Google + if ($modele = 'theme') { + $c = $this->subFonts(self::DATA_DIR . 'theme.json'); + // Un remplacement nécessite la régénération de la feuille de style + if ($c > 0 + AND file_exists(self::DATA_DIR . 'theme.css') + ) { + unlink(self::DATA_DIR . 'theme.css'); + } + } + if ($modele = 'admin') { + $c = $this->subFonts(self::DATA_DIR . 'admin.json'); + // Un remplacement nécessite la régénération de la feuille de style + if ($c > 0 + AND file_exists(self::DATA_DIR . 'admin.css') + ) { + unlink(self::DATA_DIR . 'admin.css'); + } + } + + // traitement d'erreur + $notification = $success ? 'Le thème a été importé' : 'Erreur lors de l\'extraction, vérifiez les permissions.'; + + + } else { + // pas une archive de thème + $success = false; + $notification = 'Ce n\'est pas l\'archive d\'un thème !'; + } + // Supprimer le dossier temporaire même si le thème est invalide + $this->removeDir(self::TEMP_DIR . $tempFolder); + $zip->close(); + } else { + // erreur à l'ouverture + $success = false; + $notification = 'Impossible d\'ouvrir l\'archive'; + } + return (['success' => $success, 'notification' => $notification]); + } + + return (['success' => false, 'notification' => 'Archive non spécifiée ou introuvable']); + } + + + + /** + * Export du thème + */ + public function export() { + // Make zip + $zipFilename = $this->zipTheme($this->getUrl(2)); + // Téléchargement du ZIP + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Transfer-Encoding: binary'); + header('Content-Disposition: attachment; filename="' . $zipFilename . '"'); + header('Content-Length: ' . filesize(self::TEMP_DIR . $zipFilename)); + readfile(self::TEMP_DIR . $zipFilename); + // Nettoyage du dossier + unlink (self::TEMP_DIR . $zipFilename); + exit(); + } + + /** + * Export du thème + */ + public function save() { + // Make zip + $zipFilename = $this->zipTheme($this->getUrl(2)); + // Téléchargement du ZIP + if (!is_dir(self::FILE_DIR.'source/theme')) { + mkdir(self::FILE_DIR.'source/theme', 0755); + } + copy (self::TEMP_DIR . $zipFilename , self::FILE_DIR.'source/theme/' . $zipFilename); + // Nettoyage du dossier + unlink (self::TEMP_DIR . $zipFilename); + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Archive '.$zipFilename.' sauvegardée avec succès', + 'redirect' => helper::baseUrl() . 'theme/manage', + 'state' => true + ]); + } + + /** + * construction du zip Fonction appelée par export() et save() + * @param string $modele theme ou admin + */ + private function zipTheme($modele) { + // Creation du dossier + $zipFilename = $modele . date('Y-m-d-H-i-s', time()) . '.zip'; + $zip = new ZipArchive(); + if ($zip->open(self::TEMP_DIR . $zipFilename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) === TRUE) { + switch ($modele) { + case 'admin': + $zip->addFile(self::DATA_DIR.'admin.json',self::DATA_DIR.'admin.json'); + $zip->addFile(self::DATA_DIR.'admin.css',self::DATA_DIR.'admin.css'); + break; + case 'theme': + $zip->addFile(self::DATA_DIR.'theme.json',self::DATA_DIR.'theme.json'); + $zip->addFile(self::DATA_DIR.'theme.css',self::DATA_DIR.'theme.css'); + $zip->addFile(self::DATA_DIR.'custom.css',self::DATA_DIR.'custom.css'); + // Traite l'image dans le body + if ($this->getData(['theme','body','image']) !== '' ) { + $zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','body','image']), + self::FILE_DIR.'source/'.$this->getData(['theme','body','image']) + ); + } + // Traite l'image dans le header + if ($this->getData(['theme','header','image']) !== '' ) { + $zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','header','image']), + self::FILE_DIR.'source/'.$this->getData(['theme','header','image']) + ); + } + // Traite les images du header perso + if (!empty($this->getData(['theme','header','featureFiles'])) ) { + foreach($this->getData(['theme','header','featureFiles']) as $value) { + $zip->addFile(self::FILE_DIR . 'source/' . $value, + self::FILE_DIR . 'source/' . $value ); + } + } + break; + } + $ret = $zip->close(); + } + return ($zipFilename); + } + + /** + * Substitution des fontes de Google Fonts vers CdnFont grâce à un tableau de conversion + * Cette fonction est utilisée par l'import. + * @param string $file, nom du fichier json à convertir + * @return int nombre de substitution effectuées + */ + private function subFonts($file) { + // Tableau de substitution des fontes + $fonts = [ + 'Abril+Fatface' => 'abril-fatface', + 'Arimo' => 'arimo', + 'Arvo' => 'arvo', + 'Berkshire+Swash' => 'berkshire-swash', + 'Cabin' => 'genera', + 'Dancing+Script' => 'dancing-script', + 'Droid+Sans' => 'droid-sans-2', + 'Droid+Serif' => 'droid-serif-2', + 'Fira+Sans' => 'fira-sans', + 'Inconsolata' => 'inconsolata-2', + 'Indie+Flower' =>'indie-flower', + 'Josefin+Slab' => 'josefin-sans-std', + 'Lobster' => 'lobster-2', + 'Lora' => 'lora', + 'Lato' =>'lato', + 'Marvel' => 'montserrat-ace', + 'Old+Standard+TT' => 'old-standard-tt-3', + 'Open+Sans' =>'open-sans', + // Corriger l'erreur de nom de police installée par défaut, il manquait un O en majuscule + 'open+Sans' =>'open-sans', + 'Oswald' =>'oswald-4', + 'PT+Mono' => 'pt-mono', + 'PT+Serif' =>'pt-serif', + 'Raleway' => 'raleway-5', + 'Rancho' => 'rancho', + 'Roboto' => 'Roboto', + 'Signika' => 'signika', + 'Ubuntu' => 'ubuntu', + 'Vollkorn' => 'vollkorn' + ]; + + $data = file_get_contents($file); + $count = 0; + foreach ($fonts as $oldId => $newId){ + $data = str_replace($oldId, $newId, $data, $c); + $count = $count + (int) $c; + } + // Sauvegarder la chaîne modifiée + if ($count > 0) { + file_put_contents($file, $data); + } + // Retourner le nombre d'occurrences + return ($count); + } + + // Peule la variable self:$fonts avec les fontes disponibles. + public function listFonts() { + // Récupère la liste des fontes installées + $f = $this->getFonts(); + // Construit un tableau avec leur ID et leur famille + foreach(['websafe', 'imported', 'files'] as $type) { + foreach ($f[$type] as $fontId => $fontValue ) { + self::$fonts [$fontId] = $fontValue['name']; + } + } + } + +}