ZwiiCMS, le gestionnaire de site Web sans base de données. #zwii #cms #nosql #json https://www.zwiicms.fr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

809 lines
26 KiB

3 years ago
5 months ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
9 months ago
3 years ago
9 months ago
9 months ago
9 months ago
9 months ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
1 year ago
3 years ago
1 year ago
1 year ago
1 year ago
3 years ago
3 years ago
2 years ago
  1. <?php
  2. /**
  3. * This file is part of Zwii.
  4. *
  5. * For full copyright and license information, please see the LICENSE
  6. * file that was distributed with this source code.
  7. *
  8. * @author Rémi Jean <remi.jean@outlook.com>
  9. * @copyright Copyright (C) 2008-2018, Rémi Jean
  10. * @license GNU General Public License, version 3
  11. * @link http://zwiicms.fr/
  12. * @copyright : Frédéric Tempez <frederic.tempez@outlook.com>
  13. * @copyright Copyright (C) 2018-2021, Frédéric Tempez
  14. */
  15. class theme extends common {
  16. public static $actions = [
  17. 'advanced' => self::GROUP_ADMIN,
  18. 'body' => self::GROUP_ADMIN,
  19. 'footer' => self::GROUP_ADMIN,
  20. 'header' => self::GROUP_ADMIN,
  21. 'index' => self::GROUP_ADMIN,
  22. 'menu' => self::GROUP_ADMIN,
  23. 'reset' => self::GROUP_ADMIN,
  24. 'site' => self::GROUP_ADMIN,
  25. 'admin' => self::GROUP_ADMIN,
  26. 'manage' => self::GROUP_ADMIN,
  27. 'export' => self::GROUP_ADMIN,
  28. 'save' => self::GROUP_ADMIN,
  29. 'checkImport' => self::GROUP_ADMIN
  30. ];
  31. public static $aligns = [
  32. 'left' => 'À gauche',
  33. 'center' => 'Au centre',
  34. 'right' => 'À droite'
  35. ];
  36. public static $attachments = [
  37. 'scroll' => 'Standard',
  38. 'fixed' => 'Fixe'
  39. ];
  40. public static $fonts = [
  41. 'Abril+Fatface' => 'Abril Fatface',
  42. 'Arimo' => 'Arimo',
  43. 'Arvo' => 'Arvo',
  44. 'Berkshire+Swash' => 'Berkshire Swash',
  45. 'Cabin' => 'Cabin',
  46. 'Dancing+Script' => 'Dancing Script',
  47. 'Droid+Sans' => 'Droid Sans',
  48. 'Droid+Serif' => 'Droid Serif',
  49. 'Fira+Sans' => 'Fira Sans',
  50. 'Inconsolata' => 'Inconsolata',
  51. 'Indie+Flower' => 'Indie Flower',
  52. 'Josefin+Slab' => 'Josefin Slab',
  53. 'Lobster' => 'Lobster',
  54. 'Lora' => 'Lora',
  55. 'Lato' => 'Lato',
  56. 'Marvel' => 'Marvel',
  57. 'Old+Standard+TT' => 'Old Standard TT',
  58. 'Open+Sans' => 'Open Sans',
  59. 'Oswald' => 'Oswald',
  60. 'PT+Mono' => 'PT Mono',
  61. 'PT+Serif' => 'PT Serif',
  62. 'Raleway' => 'Raleway',
  63. 'Rancho' => 'Rancho',
  64. 'Roboto' => 'Roboto',
  65. 'Signika' => 'Signika',
  66. 'Ubuntu' => 'Ubuntu',
  67. 'Vollkorn' => 'Vollkorn'
  68. ];
  69. public static $footerblocks = [
  70. 1 => [
  71. 'hide' => 'Masqué',
  72. 'center' => 'Affiché' ],
  73. 2 => [
  74. 'hide' => 'Masqué',
  75. 'left' => 'À gauche',
  76. 'right' => 'À droite' ],
  77. 3 => [
  78. 'hide' => 'Masqué',
  79. 'left' => 'À gauche',
  80. 'center' => 'Au centre',
  81. 'right' => 'À droite' ],
  82. 4 => [
  83. 'hide' => 'Masqué',
  84. 'left' => 'En haut',
  85. 'center' => 'Au milieu',
  86. 'right' => 'En bas' ]
  87. ];
  88. public static $fontWeights = [
  89. 'normal' => 'Maigre',
  90. 'bold' => 'Gras'
  91. ];
  92. public static $footerHeights = [
  93. '0px' => 'Nulles (0px)',
  94. '5px' => 'Très petites (5px)',
  95. '10px' => 'Petites (10px)',
  96. '15px' => 'Moyennes (15px)',
  97. '20px' => 'Grandes (20px)'
  98. ];
  99. public static $footerPositions = [
  100. 'hide' => 'Caché',
  101. 'site' => 'Dans le site',
  102. 'body' => 'En dessous du site'
  103. ];
  104. public static $footerFontSizes = [
  105. '.8em' => 'Très petite (80%)',
  106. '.9em' => 'Petite (90%)',
  107. '1em' => 'Standard (100%)',
  108. '1.1em' => 'Moyenne (110%)',
  109. '1.2em' => 'Grande (120%)',
  110. '1.3em' => 'Très grande (130%)'
  111. ];
  112. public static $headerFontSizes = [
  113. '1.6em' => 'Très petite (160%)',
  114. '1.8em' => 'Petite (180%)',
  115. '2em' => 'Moyenne (200%)',
  116. '2.2em' => 'Grande (220%)',
  117. '2.4vmax' => 'Très grande (240%)'
  118. ];
  119. public static $headerHeights = [
  120. 'none' => 'Hauteur de l\'image sélectionnée',
  121. '100px' => 'Très petite (100px) ',
  122. '150px' => 'Petite (150px)',
  123. '200px' => 'Moyenne (200px)',
  124. '300px' => 'Grande (300px)',
  125. '400px' => 'Très grande (400px)'
  126. ];
  127. public static $headerPositions = [
  128. 'body' => 'Au dessus du site',
  129. 'site' => 'Dans le site',
  130. 'hide' => 'Cachée'
  131. ];
  132. public static $imagePositions = [
  133. 'top left' => 'En haut à gauche',
  134. 'top center' => 'En haut au centre',
  135. 'top right' => 'En haut à droite',
  136. 'center left' => 'Au milieu à gauche',
  137. 'center center' => 'Au milieu au centre',
  138. 'center right' => 'Au milieu à droite',
  139. 'bottom left' => 'En bas à gauche',
  140. 'bottom center' => 'En bas au centre',
  141. 'bottom right' => 'En bas à droite'
  142. ];
  143. public static $menuFontSizes = [
  144. '.8em' => 'Très petite (80%)',
  145. '.9em' => 'Petite (90%)',
  146. '1em' => 'Standard (100%)',
  147. '1.1em' => 'Moyenne (110%)',
  148. '1.2em' => 'Grande (120%)',
  149. '1.3em' => 'Très grande (130%)'
  150. ];
  151. public static $menuHeights = [
  152. '5px 10px' => 'Très petite',
  153. '10px' => 'Petite',
  154. '15px 10px' => 'Moyenne',
  155. '20px 15px' => 'Grande',
  156. '25px 15px' => 'Très grande'
  157. ];
  158. public static $menuPositionsSite = [
  159. 'top' => 'En-dehors du site',
  160. 'site-first' => 'Avant la bannière',
  161. 'site-second' => 'Après la bannière',
  162. 'hide' => 'Caché'
  163. ];
  164. public static $menuPositionsBody = [
  165. 'top' => 'En-dehors du site',
  166. 'body-first' => 'Avant la bannière',
  167. 'body-second' => 'Après la bannière',
  168. 'site' => 'Dans le site',
  169. 'hide' => 'Caché'
  170. ];
  171. public static $menuRadius = [
  172. '0px' => 'Aucun',
  173. '3px 3px 0px 0px' => 'Très léger',
  174. '6px 6px 0px 0px' => 'Léger',
  175. '9px 9px 0px 0px' => 'Moyen',
  176. '12px 12px 0px 0px' => 'Important',
  177. '15px 15px 0px 0px' => 'Très important'
  178. ];
  179. public static $radius = [
  180. '0px' => 'Aucun',
  181. '5px' => 'Très léger',
  182. '10px' => 'Léger',
  183. '15px' => 'Moyen',
  184. '25px' => 'Important',
  185. '50px' => 'Très important'
  186. ];
  187. public static $repeats = [
  188. 'no-repeat' => 'Ne pas répéter',
  189. 'repeat-x' => 'Sur l\'axe horizontal',
  190. 'repeat-y' => 'Sur l\'axe vertical',
  191. 'repeat' => 'Sur les deux axes'
  192. ];
  193. public static $shadows = [
  194. '0px' => 'Aucune',
  195. '1px 1px 5px' => 'Très légère',
  196. '1px 1px 10px' => 'Légère',
  197. '1px 1px 15px' => 'Moyenne',
  198. '1px 1px 25px' => 'Importante',
  199. '1px 1px 50px' => 'Très importante'
  200. ];
  201. public static $siteFontSizes = [
  202. '12px' => '12 pixels',
  203. '13px' => '13 pixels',
  204. '14px' => '14 pixels',
  205. '15px' => '15 pixels',
  206. '16px' => '16 pixels'
  207. ];
  208. public static $bodySizes = [
  209. 'auto' => 'Automatique',
  210. '100% 100%' => 'Image étirée (100% 100%)',
  211. 'cover' => 'Responsive (cover)',
  212. 'contain' => 'Responsive (contain)'
  213. ];
  214. public static $textTransforms = [
  215. 'none' => 'Standard',
  216. 'lowercase' => 'Minuscules',
  217. 'uppercase' => 'Majuscules',
  218. 'capitalize' => 'Majuscule à chaque mot'
  219. ];
  220. public static $widths = [
  221. '750px' => 'Petite (750 pixels)',
  222. '960px' => 'Moyenne (960 pixels)',
  223. '1170px' => 'Grande (1170 pixels)',
  224. '100%' => 'Fluide (100%)'
  225. ];
  226. public static $headerWide = [
  227. 'auto auto' => 'Automatique',
  228. '100% 100%' => 'Image étirée (100% 100%)',
  229. 'cover' => 'Responsive (cover)',
  230. 'contain' => 'Responsive (contain)'
  231. ];
  232. public static $footerTemplate = [
  233. '1' => 'Une seule colonne',
  234. '2' => 'Deux colonnes : 1/2 - 1/2',
  235. '3' => 'Trois colonnes : 1/3 - 1/3 - 1/3',
  236. '4' => 'Trois lignes superposées'
  237. ];
  238. /**
  239. * Thème des écrans d'administration
  240. */
  241. public function admin() {
  242. // Soumission du formulaire
  243. if($this->isPost()) {
  244. $this->setData(['admin', [
  245. 'backgroundColor' => $this->getInput('adminBackgroundColor'),
  246. 'colorTitle' => $this->getInput('adminColorTitle'),
  247. 'colorText' => $this->getInput('adminColorText'),
  248. 'colorButtonText' => $this->getInput('adminColorButtonText'),
  249. 'backgroundColorButton' => $this->getInput('adminColorButton'),
  250. 'backgroundColorButtonGrey' => $this->getInput('adminColorGrey'),
  251. 'backgroundColorButtonRed' => $this->getInput('adminColorRed'),
  252. 'backgroundColorButtonGreen'=> $this->getInput('adminColorGreen'),
  253. 'fontText' => $this->getInput('adminFontText'),
  254. 'fontSize' => $this->getInput('adminFontTextSize'),
  255. 'fontTitle' => $this->getInput('adminFontTitle'),
  256. 'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'),
  257. 'borderBlockColor' => $this->getInput('adminBorderBlockColor'),
  258. ]]);
  259. // Valeurs en sortie
  260. $this->addOutput([
  261. 'notification' => 'Modifications enregistrées',
  262. 'redirect' => helper::baseUrl() . 'theme/admin',
  263. 'state' => true
  264. ]);
  265. }
  266. // Valeurs en sortie
  267. $this->addOutput([
  268. 'title' => 'Administration',
  269. 'view' => 'admin',
  270. 'vendor' => [
  271. 'tinycolorpicker'
  272. ],
  273. ]);
  274. }
  275. /**
  276. * Mode avancé
  277. */
  278. public function advanced() {
  279. // Soumission du formulaire
  280. if($this->isPost()) {
  281. // Enregistre le CSS
  282. file_put_contents(self::DATA_DIR.'custom.css', $this->getInput('themeAdvancedCss', null));
  283. // Valeurs en sortie
  284. $this->addOutput([
  285. 'notification' => 'Modifications enregistrées',
  286. 'redirect' => helper::baseUrl() . 'theme/advanced',
  287. 'state' => true
  288. ]);
  289. }
  290. // Valeurs en sortie
  291. $this->addOutput([
  292. 'title' => 'Éditeur CSS',
  293. 'vendor' => [
  294. 'codemirror'
  295. ],
  296. 'view' => 'advanced'
  297. ]);
  298. }
  299. /**
  300. * Options de l'arrière plan
  301. */
  302. public function body() {
  303. // Soumission du formulaire
  304. if($this->isPost()) {
  305. $this->setData(['theme', 'body', [
  306. 'backgroundColor' => $this->getInput('themeBodyBackgroundColor'),
  307. 'image' => $this->getInput('themeBodyImage'),
  308. 'imageAttachment' => $this->getInput('themeBodyImageAttachment'),
  309. 'imagePosition' => $this->getInput('themeBodyImagePosition'),
  310. 'imageRepeat' => $this->getInput('themeBodyImageRepeat'),
  311. 'imageSize' => $this->getInput('themeBodyImageSize'),
  312. 'toTopbackgroundColor' => $this->getInput('themeBodyToTopBackground'),
  313. 'toTopColor' => $this->getInput('themeBodyToTopColor')
  314. ]]);
  315. // Valeurs en sortie
  316. $this->addOutput([
  317. 'notification' => 'Modifications enregistrées',
  318. 'redirect' => helper::baseUrl() . 'theme',
  319. 'state' => true
  320. ]);
  321. }
  322. // Valeurs en sortie
  323. $this->addOutput([
  324. 'title' => 'Personnalisation de l\'arrière plan',
  325. 'vendor' => [
  326. 'tinycolorpicker'
  327. ],
  328. 'view' => 'body'
  329. ]);
  330. }
  331. /**
  332. * Options du pied de page
  333. */
  334. public function footer() {
  335. // Soumission du formulaire
  336. if($this->isPost()) {
  337. if ( $this->getInput('themeFooterCopyrightPosition') === 'hide' &&
  338. $this->getInput('themeFooterSocialsPosition') === 'hide' &&
  339. $this->getInput('themeFooterTextPosition') === 'hide' ) {
  340. // Valeurs en sortie
  341. $this->addOutput([
  342. 'notification' => 'Sélectionnez au moins un contenu à afficher',
  343. 'redirect' => helper::baseUrl() . 'theme/footer',
  344. 'state' => false
  345. ]);
  346. } else {
  347. $this->setData(['theme', 'footer', [
  348. 'backgroundColor' => $this->getInput('themeFooterBackgroundColor'),
  349. 'copyrightAlign' => $this->getInput('themeFooterCopyrightAlign'),
  350. 'height' => $this->getInput('themeFooterHeight'),
  351. 'loginLink' => $this->getInput('themeFooterLoginLink'),
  352. 'margin' => $this->getInput('themeFooterMargin', helper::FILTER_BOOLEAN),
  353. 'position' => $this->getInput('themeFooterPosition'),
  354. 'fixed' => $this->getInput('themeFooterFixed', helper::FILTER_BOOLEAN),
  355. 'socialsAlign' => $this->getInput('themeFooterSocialsAlign'),
  356. 'text' => $this->getInput('themeFooterText', null),
  357. 'textAlign' => $this->getInput('themeFooterTextAlign'),
  358. 'textColor' => $this->getInput('themeFooterTextColor'),
  359. 'copyrightPosition' => $this->getInput('themeFooterCopyrightPosition'),
  360. 'textPosition' => $this->getInput('themeFooterTextPosition'),
  361. 'socialsPosition' => $this->getInput('themeFooterSocialsPosition'),
  362. 'textTransform' => $this->getInput('themeFooterTextTransform'),
  363. 'font' => $this->getInput('themeFooterFont'),
  364. 'fontSize' => $this->getInput('themeFooterFontSize'),
  365. 'fontWeight' => $this->getInput('themeFooterFontWeight'),
  366. 'displayVersion' => $this->getInput('themefooterDisplayVersion', helper::FILTER_BOOLEAN),
  367. 'displaySiteMap' => $this->getInput('themefooterDisplaySiteMap', helper::FILTER_BOOLEAN),
  368. 'displayCopyright' => $this->getInput('themefooterDisplayCopyright', helper::FILTER_BOOLEAN),
  369. 'displayLegal' => $this->getInput('themeFooterDisplayLegal', helper::FILTER_BOOLEAN),
  370. 'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN),
  371. 'displayMemberBar'=> $this->getInput('themeFooterDisplayMemberBar', helper::FILTER_BOOLEAN),
  372. 'template' => $this->getInput('themeFooterTemplate')
  373. ]]);
  374. // Valeurs en sortie
  375. $this->addOutput([
  376. 'notification' => 'Modifications enregistrées',
  377. 'redirect' => helper::baseUrl() . 'theme',
  378. 'state' => true
  379. ]);
  380. }
  381. }
  382. // Valeurs en sortie
  383. $this->addOutput([
  384. 'title' => 'Personnalisation du pied de page',
  385. 'vendor' => [
  386. 'tinycolorpicker',
  387. 'tinymce'
  388. ],
  389. 'view' => 'footer'
  390. ]);
  391. }
  392. /**
  393. * Options de la bannière
  394. */
  395. public function header() {
  396. // Soumission du formulaire
  397. if($this->isPost()) {
  398. // Si une image est positionnée, l'arrière en transparent.
  399. $this->setData(['theme', 'header', [
  400. 'backgroundColor' => $this->getInput('themeHeaderBackgroundColor'),
  401. 'font' => $this->getInput('themeHeaderFont'),
  402. 'fontSize' => $this->getInput('themeHeaderFontSize'),
  403. 'fontWeight' => $this->getInput('themeHeaderFontWeight'),
  404. 'height' => $this->getInput('themeHeaderHeight'),
  405. 'image' => $this->getInput('themeHeaderImage'),
  406. 'imagePosition' => $this->getInput('themeHeaderImagePosition'),
  407. 'imageRepeat' => $this->getInput('themeHeaderImageRepeat'),
  408. 'margin' => $this->getInput('themeHeaderMargin', helper::FILTER_BOOLEAN),
  409. 'position' => $this->getInput('themeHeaderPosition'),
  410. 'textAlign' => $this->getInput('themeHeaderTextAlign'),
  411. 'textColor' => $this->getInput('themeHeaderTextColor'),
  412. 'textHide' => $this->getInput('themeHeaderTextHide', helper::FILTER_BOOLEAN),
  413. 'textTransform' => $this->getInput('themeHeaderTextTransform'),
  414. 'linkHomePage' => $this->getInput('themeHeaderlinkHomePage',helper::FILTER_BOOLEAN),
  415. 'imageContainer' => $this->getInput('themeHeaderImageContainer')
  416. ]]);
  417. // Modification de la position du menu selon la position de la bannière
  418. if ( $this->getInput('themeHeaderPosition') &&
  419. ( $this->getData(['theme','menu','position']) !== 'site' ||
  420. $this->getData(['theme','menu','position']) !== 'top') )
  421. {
  422. switch ($this->getInput('themeHeaderPosition')) {
  423. case 'site' :
  424. $position = str_replace ('body','site',$this->getData(['theme','menu','position']));
  425. break;
  426. case 'body' :
  427. $position = str_replace ('site','body',$this->getData(['theme','menu','position']));
  428. break;
  429. default:
  430. $position = $this->getData(['theme','menu','position']);
  431. }
  432. }
  433. $this->setData(['theme', 'menu', [
  434. 'backgroundColor' => $this->getData(['theme', 'menu', 'backgroundColor']),
  435. 'backgroundColorSub' => $this->getData(['theme', 'menu', 'backgroundColorSub']),
  436. 'font' => $this->getData(['theme', 'menu', 'font']),
  437. 'fontSize' => $this->getData(['theme', 'menu', 'fontSize']),
  438. 'fontWeight' => $this->getData(['theme', 'menu', 'fontWeight']),
  439. 'height' => $this->getData(['theme', 'menu', 'height']),
  440. 'loginLink' => $this->getData(['theme', 'menu', 'loginLink']),
  441. 'margin' => $this->getData(['theme', 'menu', 'margin']),
  442. 'position' => $position,
  443. 'textAlign' => $this->getData(['theme', 'menu', 'textAlign']),
  444. 'textColor' => $this->getData(['theme', 'menu', 'textColor']),
  445. 'textTransform' => $this->getData(['theme','menu','textTransform']),
  446. 'fixed' => $this->getData(['theme','menu','fixed']),
  447. 'activeColorAuto' => $this->getData(['theme','menu','activeColorAuto']),
  448. 'activeColor' => $this->getData(['theme','menu','activeColor']),
  449. 'activeTextColor' => $this->getData(['theme','menu','activeTextColor']),
  450. 'radius' => $this->getData(['theme','menu','radius']),
  451. 'memberBar' => $this->getData(['theme','menu','memberBar'])
  452. ]]);
  453. // Valeurs en sortie
  454. $this->addOutput([
  455. 'notification' => 'Modifications enregistrées',
  456. 'redirect' => helper::baseUrl() . 'theme',
  457. 'state' => true
  458. ]);
  459. }
  460. // Valeurs en sortie
  461. $this->addOutput([
  462. 'title' => 'Personnalisation de la bannière',
  463. 'vendor' => [
  464. 'tinycolorpicker'
  465. ],
  466. 'view' => 'header'
  467. ]);
  468. }
  469. /**
  470. * Accueil de la personnalisation
  471. */
  472. public function index() {
  473. // Valeurs en sortie
  474. $this->addOutput([
  475. 'title' => 'Personnalisation des thèmes',
  476. 'view' => 'index'
  477. ]);
  478. }
  479. /**
  480. * Options du menu
  481. */
  482. public function menu() {
  483. // Soumission du formulaire
  484. if($this->isPost()) {
  485. $this->setData(['theme', 'menu', [
  486. 'backgroundColor' => $this->getInput('themeMenuBackgroundColor'),
  487. 'backgroundColorSub' => $this->getInput('themeMenuBackgroundColorSub'),
  488. 'font' => $this->getInput('themeMenuFont'),
  489. 'fontSize' => $this->getInput('themeMenuFontSize'),
  490. 'fontWeight' => $this->getInput('themeMenuFontWeight'),
  491. 'height' => $this->getInput('themeMenuHeight'),
  492. 'loginLink' => $this->getInput('themeMenuLoginLink', helper::FILTER_BOOLEAN),
  493. 'margin' => $this->getInput('themeMenuMargin', helper::FILTER_BOOLEAN),
  494. 'position' => $this->getInput('themeMenuPosition'),
  495. 'textAlign' => $this->getInput('themeMenuTextAlign'),
  496. 'textColor' => $this->getInput('themeMenuTextColor'),
  497. 'textTransform' => $this->getInput('themeMenuTextTransform'),
  498. 'fixed' => $this->getInput('themeMenuFixed', helper::FILTER_BOOLEAN),
  499. 'activeColorAuto' => $this->getInput('themeMenuActiveColorAuto', helper::FILTER_BOOLEAN),
  500. 'activeColor' => $this->getInput('themeMenuActiveColor'),
  501. 'activeTextColor' => $this->getInput('themeMenuActiveTextColor'),
  502. 'radius' => $this->getInput('themeMenuRadius'),
  503. 'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN),
  504. 'memberBar' => $this->getInput('themeMenuMemberBar', helper::FILTER_BOOLEAN)
  505. ]]);
  506. // Valeurs en sortie
  507. $this->addOutput([
  508. 'notification' => 'Modifications enregistrées',
  509. 'redirect' => helper::baseUrl() . 'theme',
  510. 'state' => true
  511. ]);
  512. }
  513. // Valeurs en sortie
  514. $this->addOutput([
  515. 'title' => 'Personnalisation du menu',
  516. 'vendor' => [
  517. 'tinycolorpicker'
  518. ],
  519. 'view' => 'menu'
  520. ]);
  521. }
  522. /**
  523. * Réinitialisation de la personnalisation avancée
  524. */
  525. public function reset() {
  526. // $url prend l'adresse sans le token
  527. $url = explode('&',$this->getUrl(2));
  528. if ( isset($_GET['csrf'])
  529. AND $_GET['csrf'] === $_SESSION['csrf']
  530. ) {
  531. // Réinitialisation
  532. $redirect ='';
  533. switch ($url[0]) {
  534. case 'admin':
  535. $this->initData('admin');
  536. $redirect = helper::baseUrl() . 'theme/admin';
  537. break;
  538. case 'manage':
  539. $this->initData('theme');
  540. $redirect = helper::baseUrl() . 'theme/manage';
  541. break;
  542. case 'custom':
  543. unlink(self::DATA_DIR.'custom.css');
  544. $redirect = helper::baseUrl() . 'theme/advanced';
  545. break;
  546. default :
  547. $redirect = helper::baseUrl() . 'theme';
  548. }
  549. // Valeurs en sortie
  550. $this->addOutput([
  551. 'notification' => 'Réinitialisation effectuée',
  552. 'redirect' => $redirect,
  553. 'state' => true
  554. ]);
  555. } else {
  556. // Valeurs en sortie
  557. $this->addOutput([
  558. 'notification' => 'Jeton incorrect'
  559. ]);
  560. }
  561. }
  562. /**
  563. * Options du site
  564. */
  565. public function site() {
  566. // Soumission du formulaire
  567. if($this->isPost()) {
  568. $this->setData(['theme', 'title', [
  569. 'font' => $this->getInput('themeTitleFont'),
  570. 'textColor' => $this->getInput('themeTitleTextColor'),
  571. 'fontWeight' => $this->getInput('themeTitleFontWeight'),
  572. 'textTransform' => $this->getInput('themeTitleTextTransform')
  573. ]]);
  574. $this->setData(['theme', 'text', [
  575. 'font' => $this->getInput('themeTextFont'),
  576. 'fontSize' => $this->getInput('themeTextFontSize'),
  577. 'textColor' => $this->getInput('themeTextTextColor'),
  578. 'linkColor'=> $this->getInput('themeTextLinkColor')
  579. ]]);
  580. $this->setData(['theme', 'site', [
  581. 'backgroundColor' => $this->getInput('themeSiteBackgroundColor'),
  582. 'radius' => $this->getInput('themeSiteRadius'),
  583. 'shadow' => $this->getInput('themeSiteShadow'),
  584. 'width' => $this->getInput('themeSiteWidth'),
  585. 'margin' => $this->getInput('themeSiteMargin',helper::FILTER_BOOLEAN)
  586. ]]);
  587. $this->setData(['theme', 'button', [
  588. 'backgroundColor' => $this->getInput('themeButtonBackgroundColor')
  589. ]]);
  590. $this->setData(['theme', 'block', [
  591. 'backgroundColor' => $this->getInput('themeBlockBackgroundColor'),
  592. 'borderColor' => $this->getInput('themeBlockBorderColor')
  593. ]]);
  594. // Valeurs en sortie
  595. $this->addOutput([
  596. 'notification' => 'Modifications enregistrées',
  597. 'redirect' => helper::baseUrl() . 'theme',
  598. 'state' => true
  599. ]);
  600. }
  601. // Valeurs en sortie
  602. $this->addOutput([
  603. 'title' => 'Personnalisation du site',
  604. 'vendor' => [
  605. 'tinycolorpicker',
  606. 'tinymce'
  607. ],
  608. 'view' => 'site'
  609. ]);
  610. }
  611. /**
  612. * Import du thème
  613. */
  614. public function manage() {
  615. if($this->isPost() ) {
  616. $zipFilename = $this->getInput('themeManageImport', helper::FILTER_STRING_SHORT, true);
  617. $tempFolder = uniqid();
  618. $zip = new ZipArchive();
  619. if ($zip->open(self::FILE_DIR.'source/'.$zipFilename) === TRUE) {
  620. mkdir (self::TEMP_DIR . $tempFolder);
  621. $zip->extractTo(self::TEMP_DIR . $tempFolder );
  622. $modele = '';
  623. // Archive de thème ?
  624. if (
  625. file_exists(self::TEMP_DIR . $tempFolder . '/site/data/custom.css')
  626. AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.css')
  627. AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/theme.json')
  628. ) {
  629. $modele = 'theme';
  630. }
  631. if(
  632. file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.json')
  633. AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.css')
  634. ) {
  635. $modele = 'admin';
  636. }
  637. if (!empty($modele)
  638. ) {
  639. // traiter l'archive
  640. $success = $zip->extractTo('.');
  641. // traitement de l'erreur
  642. $notification = $success ? 'Le thème a été importé' : 'Erreur lors de l\'extraction, vérifiez les permissions.';
  643. // Check le thème
  644. // $this->checkImport($modele);
  645. } else {
  646. // pas une archive de thème
  647. $success = false;
  648. $notification = 'Ce n\'est pas l\'archive d\'un thème !';
  649. }
  650. // Supprimer le dossier temporaire même si le thème est invalide
  651. $this->removeDir(self::TEMP_DIR . $tempFolder);
  652. $zip->close();
  653. } else {
  654. // erreur à l'ouverture
  655. $success = false;
  656. $notification = 'Impossible d\'ouvrir l\'archive';
  657. }
  658. // Valeurs en sortie
  659. $this->addOutput([
  660. 'notification' => $notification,
  661. 'state' => $success,
  662. 'title' => 'Gestion des thèmes',
  663. 'view' => 'manage'
  664. ]);;
  665. }
  666. // Valeurs en sortie
  667. $this->addOutput([
  668. 'title' => 'Gestion des thèmes',
  669. 'view' => 'manage'
  670. ]);
  671. }
  672. /**
  673. * Export du thème
  674. */
  675. public function export() {
  676. // Make zip
  677. $zipFilename = $this->zipTheme($this->getUrl(2));
  678. // Téléchargement du ZIP
  679. header('Content-Description: File Transfer');
  680. header('Content-Type: application/octet-stream');
  681. header('Content-Transfer-Encoding: binary');
  682. header('Content-Disposition: attachment; filename="' . $zipFilename . '"');
  683. header('Content-Length: ' . filesize(self::TEMP_DIR . $zipFilename));
  684. readfile(self::TEMP_DIR . $zipFilename);
  685. // Nettoyage du dossier
  686. unlink (self::TEMP_DIR . $zipFilename);
  687. exit();
  688. }
  689. /**
  690. * Export du thème
  691. */
  692. public function save() {
  693. // Make zip
  694. $zipFilename = $this->zipTheme($this->getUrl(2));
  695. // Téléchargement du ZIP
  696. if (!is_dir(self::FILE_DIR.'source/theme')) {
  697. mkdir(self::FILE_DIR.'source/theme');
  698. }
  699. copy (self::TEMP_DIR . $zipFilename , self::FILE_DIR.'source/theme/' . $zipFilename);
  700. // Nettoyage du dossier
  701. unlink (self::TEMP_DIR . $zipFilename);
  702. // Valeurs en sortie
  703. $this->addOutput([
  704. 'notification' => 'Archive <b>'.$zipFilename.'</b> sauvegardée avec succès',
  705. 'redirect' => helper::baseUrl() . 'theme/manage',
  706. 'state' => true
  707. ]);
  708. }
  709. /**
  710. * Contrôle du thème
  711. * Vérifie la présence de toutes les clés par rapport au thème par défaut
  712. * les créer si elles n'existent pas.
  713. */
  714. private function checkImport ($modele = 'theme') {
  715. require_once('core/module/install/ressource/defaultdata.php');
  716. switch ($modele) {
  717. case 'theme':
  718. $default['theme'] = init::$defaultData['theme'];
  719. // Check le thème
  720. $dataKeys = ['body','footer','header','menu','site','block','text','title','button'];
  721. // Parcourir les clés principales et stocker les contenus
  722. foreach($dataKeys as $key1) {
  723. $itemKeys = $default['theme'][$key1];
  724. // Parcourir les clés secondaires
  725. foreach ($itemKeys as $key2 => $value) {
  726. // Données nulles ou vides instaurer la donnée par défaut
  727. if ($this->getData(['theme',$key1,$key2]) === NULL
  728. ) {
  729. $this->setData(['theme',$key1,$key2,$value]);
  730. }
  731. }
  732. }
  733. break;
  734. case 'admin':
  735. // Check Admin
  736. $default['admin'] = init::$defaultData['admin'];
  737. // Pas de clé secondaire
  738. $itemKeys = $default['admin'];
  739. foreach ($itemKeys as $key1 => $value) {
  740. // Données nulles ou vides instaurer la donnée par défaut
  741. if ($this->getData(['admin',$key1]) === NULL
  742. ) {
  743. $this->setData(['admin',$key1,$value]);
  744. }
  745. }
  746. break;
  747. }
  748. }
  749. /**
  750. * construction du zip
  751. * @param string $modele theme ou admin
  752. */
  753. private function zipTheme($modele) {
  754. // Creation du dossier
  755. $zipFilename = $modele . date('Y-m-d-H-i-s', time()) . '.zip';
  756. $zip = new ZipArchive();
  757. if ($zip->open(self::TEMP_DIR . $zipFilename, ZipArchive::CREATE | ZipArchive::OVERWRITE ) === TRUE) {
  758. switch ($modele) {
  759. case 'admin':
  760. $zip->addFile(self::DATA_DIR.'admin.json',self::DATA_DIR.'admin.json');
  761. $zip->addFile(self::DATA_DIR.'admin.css',self::DATA_DIR.'admin.css');
  762. break;
  763. case 'theme':
  764. $zip->addFile(self::DATA_DIR.'theme.json',self::DATA_DIR.'theme.json');
  765. $zip->addFile(self::DATA_DIR.'theme.css',self::DATA_DIR.'theme.css');
  766. $zip->addFile(self::DATA_DIR.'custom.css',self::DATA_DIR.'custom.css');
  767. if ($this->getData(['theme','body','image']) !== '' ) {
  768. $zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','body','image']),
  769. self::FILE_DIR.'source/'.$this->getData(['theme','body','image'])
  770. );
  771. }
  772. if ($this->getData(['theme','header','image']) !== '' ) {
  773. $zip->addFile(self::FILE_DIR.'source/'.$this->getData(['theme','header','image']),
  774. self::FILE_DIR.'source/'.$this->getData(['theme','header','image'])
  775. );
  776. }
  777. break;
  778. }
  779. $ret = $zip->close();
  780. }
  781. return ($zipFilename);
  782. }
  783. }