This commit is contained in:
Deltacms 2022-01-31 09:10:49 +01:00
parent 4189506414
commit 5c8fb38472
978 changed files with 145237 additions and 0 deletions

3
core/class/.htaccess Normal file
View File

@ -0,0 +1,3 @@
# Bloque l'accès à la librairie
Order deny,allow
Deny from all

16
core/class/autoload.php Normal file
View File

@ -0,0 +1,16 @@
<?php
class autoload {
public static function autoloader () {
require_once 'core/class/helper.class.php';
require_once 'core/class/template.class.php';
require_once 'core/class/sitemap/Runtime.class.php';
require_once 'core/class/sitemap/FileSystem.class.php';
require_once 'core/class/sitemap/SitemapGenerator.class.php';
require_once 'core/class/phpmailer/PHPMailer.class.php';
require_once 'core/class/phpmailer/Exception.class.php';
require_once 'core/class/phpmailer/SMTP.class.php';
require_once "core/class/jsondb/Dot.class.php";
require_once "core/class/jsondb/JsonDb.class.php";
}
}

588
core/class/helper.class.php Normal file
View File

@ -0,0 +1,588 @@
<?php
class helper {
/** Statut de la réécriture d'URL (pour éviter de lire le contenu du fichier .htaccess à chaque self::baseUrl()) */
public static $rewriteStatus = null;
/** Filtres personnalisés */
const FILTER_BOOLEAN = 1;
const FILTER_DATETIME = 2;
const FILTER_FLOAT = 3;
const FILTER_ID = 4;
const FILTER_INT = 5;
const FILTER_MAIL = 6;
const FILTER_PASSWORD = 7;
const FILTER_STRING_LONG = 8;
const FILTER_STRING_SHORT = 9;
const FILTER_TIMESTAMP = 10;
const FILTER_URL = 11;
/**
* Récupérer l'adresse IP sans tenir compte du proxy
* @param integer Niveau d'anonymat 0 aucun, 1 octet à droite, etc..
* @return string IP adress
* Cette fonction est utilisée par user
*/
public static function getIp($anon = 4) {
if(!empty($_SERVER['HTTP_CLIENT_IP'])){
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip=$_SERVER['REMOTE_ADDR'];
}
// Anonymiser l'adresse IP v4
$d = array_slice(explode('.', $ip), 0, $anon);
$d = implode ('.', $d);
$j = array_fill(0, 4 - $anon, 'x');
$k = implode ('.', $j);
$ip = count($j) == 0 ? $d : $d . '.' . $k;
return $ip;
}
/**
* Fonction pour récupérer le numéro de version en ligne et le catalogue des modules
* @param string $url à récupérer
* @return mixed données récupérées
*/
public static function urlGetContents ($url) {
// Ejecter free.fr
if (strpos(self::baseUrl(),'free.fr') > 0 ){
return false;
}
if(function_exists('file_get_contents') &&
ini_get('allow_url_fopen') ){
$url_get_contents_data = @file_get_contents($url); // Masque un warning éventuel
}elseif(function_exists('curl_version')){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$url_get_contents_data = curl_exec($ch);
curl_close($ch);
}elseif(function_exists('fopen') &&
function_exists('stream_get_contents') &&
ini_get('allow_url_fopen')){
$handle = fopen ($url, "r");
$url_get_contents_data = stream_get_contents($handle);
}else{
$url_get_contents_data = false;
}
return $url_get_contents_data;
}
/**
* Retourne les valeurs d'une colonne du tableau de données
* @param array $array Tableau cible
* @param string $column Colonne à extraire
* @param string $sort Type de tri à appliquer au tableau (SORT_ASC, SORT_DESC, ou null)
* @return array
*/
public static function arrayCollumn($array, $column, $sort = null) {
$newArray = [];
if(empty($array) === false) {
$newArray = array_map(function($element) use($column) {
return $element[$column];
}, $array);
switch($sort) {
case 'SORT_ASC':
asort($newArray);
break;
case 'SORT_DESC':
arsort($newArray);
break;
}
}
return $newArray;
}
/**
* Génère un backup des données de site
* @param string $folder dossier de sauvegarde
* @param array $exclude dossier exclus
* @return string nom du fichier de sauvegarde
*/
public static function autoBackup($folder, $filter = ['backup','tmp'] ) {
// Creation du ZIP
$baseName = str_replace('/','',helper::baseUrl(false,false));
$baseName = empty($baseName) ? 'DeltaCMS' : $baseName;
$fileName = $baseName . '-backup-' . date('Y-m-d-H-i-s', time()) . '.zip';
$zip = new ZipArchive();
$zip->open($folder . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$directory = 'site/';
//$filter = array('backup','tmp','file');
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$directory,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($fileInfo, $key, $iterator) use ($filter) {
return $fileInfo->isFile() || !in_array($fileInfo->getBaseName(), $filter);
}
)
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen(realpath($directory)) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
return ($fileName);
}
/**
* Retourne la liste des modules installés dans un tableau composé
* du nom réel
* du numéro de version
*/
public static function getModules() {
$modules = array();
$dirs = array_diff(scandir('module'), array('..', '.'));
foreach ($dirs as $key => $value) {
// Dossier non vide
if (file_exists('module/' . $value . '/' . $value . '.php')) {
// Lire les constantes en gérant les erreurs de nom de classe
try {
$class_reflex = new \ReflectionClass($value);
$class_constants = $class_reflex->getConstants();
// Constante REALNAME
if (array_key_exists('REALNAME', $class_constants)) {
$realName = $value::REALNAME;
} else {
$realName = ucfirst($value);
}
// Constante VERSION
if (array_key_exists('VERSION', $class_constants)) {
$version = $value::VERSION;
} else {
$version = '0.0';
}
// Constante UPDATE
if (array_key_exists('UPDATE', $class_constants)) {
$update = $value::UPDATE;
} else {
$update = '0.0';
}
// Constante DELETE
if (array_key_exists('DELETE', $class_constants)) {
$delete = $value::DELETE;
} else {
$delete = true;
}
// Constante DATADIRECTORY
if ( array_key_exists('DATADIRECTORY', $class_constants)) {
$dataDirectory = $value::DATADIRECTORY;
} else {
$dataDirectory = '';
}
// Affection
$modules [$value] = [
'realName' => $realName,
'version' => $version,
'update' => $update,
'delete' => $delete,
'dataDirectory' => $dataDirectory
];
} catch (Exception $e){
// on ne fait rien
}
}
}
return($modules);
}
/**
* Retourne true si le protocole est en TLS
* @return bool
*/
public static function isHttps() {
if(
(empty($_SERVER['HTTPS']) === false AND $_SERVER['HTTPS'] !== 'off')
OR $_SERVER['SERVER_PORT'] === 443
) {
return true;
} else {
return false;
}
}
/**
* Retourne l'URL de base du site
* @param bool $queryString Affiche ou non le point d'interrogation
* @param bool $host Affiche ou non l'host
* @return string
*/
public static function baseUrl($queryString = true, $host = true) {
// Protocole
$protocol = helper::isHttps() === true ? 'https://' : 'http://';
// Host
if($host) {
$host = $protocol . $_SERVER['HTTP_HOST'];
}
// Pathinfo
$pathInfo = pathinfo($_SERVER['PHP_SELF']);
// Querystring
if($queryString AND helper::checkRewrite() === false) {
$queryString = '?';
}
else {
$queryString = '';
}
return $host . rtrim($pathInfo['dirname'], ' ' . DIRECTORY_SEPARATOR) . '/' . $queryString;
}
/**
* Check le statut de l'URL rewriting
* @return bool
*/
public static function checkRewrite() {
if(self::$rewriteStatus === null) {
// Ouvre et scinde le fichier .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
// Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
self::$rewriteStatus = (empty($htaccess[1]) === false);
}
return self::$rewriteStatus;
}
/**
* Renvoie le numéro de version de DeltaCMS est en ligne
* @return string
*/
public static function getOnlineVersion() {
return (helper::urlGetContents(common::DELTA_UPDATE_URL . common::DELTA_UPDATE_CHANNEL . '/version'));
}
/**
* Check si une nouvelle version de DeltaCMS est disponible
* @return bool
*/
public static function checkNewVersion() {
if($version = helper::getOnlineVersion()) {
return ((version_compare(common::DELTA_VERSION,$version)) === -1);
}
else {
return false;
}
}
/**
* Génère des variations d'une couleur
* @param string $rgba Code rgba de la couleur
* @return array
*/
public static function colorVariants($rgba) {
preg_match('#\(+(.*)\)+#', $rgba, $matches);
$rgba = explode(', ', $matches[1]);
return [
'normal' => 'rgba(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ',' . $rgba[3] . ')',
'darken' => 'rgba(' . max(0, $rgba[0] - 15) . ',' . max(0, $rgba[1] - 15) . ',' . max(0, $rgba[2] - 15) . ',' . $rgba[3] . ')',
'veryDarken' => 'rgba(' . max(0, $rgba[0] - 20) . ',' . max(0, $rgba[1] - 20) . ',' . max(0, $rgba[2] - 20) . ',' . $rgba[3] . ')',
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')'
];
}
/**
* Supprime un cookie
* @param string $cookieKey Clé du cookie à supprimer
*/
public static function deleteCookie($cookieKey) {
unset($_COOKIE[$cookieKey]);
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
}
/**
* Filtre une chaîne en fonction d'un tableau de données
* @param string $text Chaîne à filtrer
* @param int $filter Type de filtre à appliquer
* @return string
*/
public static function filter($text, $filter) {
$text = trim($text);
switch($filter) {
case self::FILTER_BOOLEAN:
$text = (bool) $text;
break;
case self::FILTER_DATETIME:
$timezone = new DateTimeZone(core::$timezone);
$date = new DateTime($text);
$date->setTimezone($timezone);
$text = (int) $date->format('U');
break;
case self::FILTER_FLOAT:
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT);
$text = (float) $text;
break;
case self::FILTER_ID:
$text = mb_strtolower($text, 'UTF-8');
$text = strip_tags(str_replace(
explode(',', 'á,à,â,ä,ã,å,ç,é,è,ê,ë,í,ì,î,ï,ñ,ó,ò,ô,ö,õ,ú,ù,û,ü,ý,ÿ,\',", '),
explode(',', 'a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,n,o,o,o,o,o,u,u,u,u,y,y,-,-,-'),
$text
));
$text = preg_replace('/([^a-z0-9-])/', '', $text);
// Supprime les emoji
$text = preg_replace('/[[:^print:]]/', '', $text);
// Supprime les tirets en fin de chaine (emoji en fin de nom)
$text = rtrim($text,'-');
// Cas où un identifiant est vide
if (empty($text)) {
$text = uniqid('');
}
// Un ID ne peut pas être un entier, pour éviter les conflits avec le système de pagination
if(intval($text) !== 0) {
$text = '_' . $text;
}
break;
case self::FILTER_INT:
$text = (int) filter_var($text, FILTER_SANITIZE_NUMBER_INT);
break;
case self::FILTER_MAIL:
$text = filter_var($text, FILTER_SANITIZE_EMAIL);
break;
case self::FILTER_PASSWORD:
$text = password_hash($text, PASSWORD_BCRYPT);
break;
case self::FILTER_STRING_LONG:
$text = mb_substr(filter_var($text, FILTER_SANITIZE_STRING), 0, 500000);
break;
case self::FILTER_STRING_SHORT:
$text = mb_substr(filter_var($text, FILTER_SANITIZE_STRING), 0, 500);
break;
case self::FILTER_TIMESTAMP:
$text = date('Y-m-d H:i:s', $text);
break;
case self::FILTER_URL:
$text = filter_var($text, FILTER_SANITIZE_URL);
break;
}
return $text;
}
/**
* Incrémente une clé en fonction des clés ou des valeurs d'un tableau
* @param mixed $key Clé à incrémenter
* @param array $array Tableau à vérifier
* @return string
*/
public static function increment($key, $array = []) {
// Pas besoin d'incrémenter si la clef n'existe pas
if($array === []) {
return $key;
}
// Incrémente la clef
else {
// Si la clef est numérique elle est incrémentée
if(is_numeric($key)) {
$newKey = $key;
while(array_key_exists($newKey, $array) OR in_array($newKey, $array)) {
$newKey++;
}
}
// Sinon l'incrémentation est ajoutée après la clef
else {
$i = 2;
$newKey = $key;
while(array_key_exists($newKey, $array) OR in_array($newKey, $array)) {
$newKey = $key . '-' . $i;
$i++;
}
}
return $newKey;
}
}
/**
* Minimise du css
* @param string $css Css à minimiser
* @return string
*/
public static function minifyCss($css) {
// Supprime les commentaires
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
// Supprime les tabulations, espaces, nouvelles lignes, etc...
$css = str_replace(["\r\n", "\r", "\n" ,"\t", ' ', ' ', ' '], '', $css);
$css = preg_replace(['(( )+{)', '({( )+)'], '{', $css);
$css = preg_replace(['(( )+})', '(}( )+)', '(;( )*})'], '}', $css);
$css = preg_replace(['(;( )+)', '(( )+;)'], ';', $css);
// Retourne le css minifié
return $css;
}
/**
* Minimise du js
* @param string $js Js à minimiser
* @return string
*/
public static function minifyJs($js) {
// Supprime les commentaires
$js = preg_replace('/\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/|\s*(?<![\:\=])\/\/.*/', '', $js);
// Supprime les tabulations, espaces, nouvelles lignes, etc...
$js = str_replace(["\r\n", "\r", "\t", "\n", ' ', ' ', ' '], '', $js);
$js = preg_replace(['(( )+\))', '(\)( )+)'], ')', $js);
// Retourne le js minifié
return $js;
}
/**
* Crée un système de pagination (retourne un tableau contenant les informations sur la pagination (first, last, pages))
* @param array $array Tableau de donnée à utiliser
* @param string $url URL à utiliser, la dernière partie doit correspondre au numéro de page, par défaut utiliser $this->getUrl()
* @param string $item pagination nombre d'éléments par page
* @param null|int $sufix Suffixe de l'url
* @return array
*/
public static function pagination($array, $url, $item, $sufix = null) {
// Scinde l'url
$url = explode('/', $url);
// Url de pagination
$urlPagination = is_numeric($url[count($url) - 1]) ? array_pop($url) : 1;
// Url de la page courante
$urlCurrent = implode('/', $url);
// Nombre d'éléments à afficher
$nbElements = count($array);
// Nombre de page
$nbPage = ceil($nbElements / $item);
// Page courante
$currentPage = is_numeric($urlPagination) ? self::filter($urlPagination, self::FILTER_INT) : 1;
// Premier élément de la page
$firstElement = ($currentPage - 1) * $item;
// Dernier élément de la page
$lastElement = $firstElement + $item;
$lastElement = ($lastElement > $nbElements) ? $nbElements : $lastElement;
// Mise en forme de la liste des pages
$pages = '';
if($nbPage > 1) {
for($i = 1; $i <= $nbPage; $i++) {
$disabled = ($i === $currentPage) ? ' class="disabled"' : false;
$pages .= '<a href="' . helper::baseUrl() . $urlCurrent . '/' . $i . $sufix . '"' . $disabled . '>' . $i . '</a>';
}
$pages = '<div class="pagination">' . $pages . '</div>';
}
// Retourne un tableau contenant les informations sur la pagination
return [
'first' => $firstElement,
'last' => $lastElement,
'pages' => $pages
];
}
/**
* Calcul de la luminance relative d'une couleur
*/
public static function relativeLuminanceW3C($rgba) {
// Conversion en sRGB
$RsRGB = $rgba[0] / 255;
$GsRGB = $rgba[1] / 255;
$BsRGB = $rgba[2] / 255;
// Ajout de la transparence
$RsRGBA = $rgba[3] * $RsRGB + (1 - $rgba[3]);
$GsRGBA = $rgba[3] * $GsRGB + (1 - $rgba[3]);
$BsRGBA = $rgba[3] * $BsRGB + (1 - $rgba[3]);
// Calcul de la luminance
$R = ($RsRGBA <= .03928) ? $RsRGBA / 12.92 : pow(($RsRGBA + .055) / 1.055, 2.4);
$G = ($GsRGBA <= .03928) ? $GsRGBA / 12.92 : pow(($GsRGBA + .055) / 1.055, 2.4);
$B = ($BsRGBA <= .03928) ? $BsRGBA / 12.92 : pow(($BsRGBA + .055) / 1.055, 2.4);
return .2126 * $R + .7152 * $G + .0722 * $B;
}
/**
* Retourne les attributs d'une balise au bon format
* @param array $array Liste des attributs ($key => $value)
* @param array $exclude Clés à ignorer ($key)
* @return string
*/
public static function sprintAttributes(array $array = [], array $exclude = []) {
$exclude = array_merge(
[
'before',
'classWrapper',
'help',
'label'
],
$exclude
);
$attributes = [];
foreach($array as $key => $value) {
if(($value OR $value === 0) AND in_array($key, $exclude) === false) {
// Désactive le message de modifications non enregistrées pour le champ
if($key === 'noDirty') {
$attributes[] = 'data-no-dirty';
}
// Disabled
// Readonly
elseif(in_array($key, ['disabled', 'readonly'])) {
$attributes[] = sprintf('%s', $key);
}
// Autres
else {
$attributes[] = sprintf('%s="%s"', $key, $value);
}
}
}
return implode(' ', $attributes);
}
/**
* Retourne un segment de chaîne sans couper de mot
* @param string $text Texte à scinder
* @param int $start (voir substr de PHP pour fonctionnement)
* @param int $length (voir substr de PHP pour fonctionnement)
* @return string
*/
public static function subword($text, $start, $length) {
$text = trim($text);
if(strlen($text) > $length) {
$text = mb_substr($text, $start, $length);
$text = mb_substr($text, 0, min(mb_strlen($text), mb_strrpos($text, ' ')));
}
return $text;
}
/**
* Cryptage
* @param string $key la clé d'encryptage
* @param string $payload la chaine à coder
* @return string
*/
public static function encrypt($key, $payload) {
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
return base64_encode($encrypted . '::' . $iv);
}
/**
* Décryptage
* @param string $key la clé d'encryptage
* @param string $garble la chaine à décoder
* @return string
*/
public static function decrypt($key, $garble) {
list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
}
}

View File

@ -0,0 +1,316 @@
<?php
namespace Prowebcraft;
use ArrayAccess;
/**
* Dot Notation
*
* This class provides dot notation access to arrays, so it's easy to handle
* multidimensional data in a clean way.
*/
class Dot implements ArrayAccess
{
/** @var array Data */
protected $data = [];
/**
* Constructor
*
* @param array|null $data Data
*/
public function __construct(array $data = null)
{
if (is_array($data)) {
$this->data = $data;
}
}
/**
* Get value of path, default value if path doesn't exist or all data
*
* @param array $array Source Array
* @param mixed|null $key Path
* @param mixed|null $default Default value
* @return mixed Value of path
*/
public static function getValue($array, $key, $default = null)
{
if (is_string($key)) {
// Iterate path
$keys = explode('.', $key);
foreach ($keys as $key) {
if (!isset($array[$key])) {
return $default;
}
$array = &$array[$key];
}
// Get value
return $array;
} elseif (is_null($key)) {
// Get all data
return $array;
}
return null;
}
/**
* Set value or array of values to path
*
* @param array $array Target array with data
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
*/
public static function setValue(&$array, $key, $value)
{
if (is_string($key)) {
// Iterate path
$keys = explode('.', $key);
foreach ($keys as $key) {
if (!isset($array[$key]) || !is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
// Set value to path
$array = $value;
} elseif (is_array($key)) {
// Iterate array of paths and values
foreach ($key as $k => $v) {
self::setValue($array, $k, $v);
}
}
}
/**
* Add value or array of values to path
*
* @param array $array Target array with data
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
* @param boolean $pop Helper to pop out last key if value is an array
*/
public static function addValue(&$array, $key, $value = null, $pop = false)
{
if (is_string($key)) {
// Iterate path
$keys = explode('.', $key);
if ($pop === true) {
array_pop($keys);
}
foreach ($keys as $key) {
if (!isset($array[$key]) || !is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
// Add value to path
$array[] = $value;
} elseif (is_array($key)) {
// Iterate array of paths and values
foreach ($key as $k => $v) {
self::addValue($array, $k, $v);
}
}
}
/**
* Delete path or array of paths
*
* @param array $array Target array with data
* @param mixed $key Path or array of paths to delete
*/
public static function deleteValue(&$array, $key)
{
if (is_string($key)) {
// Iterate path
$keys = explode('.', $key);
$last = array_pop($keys);
foreach ($keys as $key) {
if (!isset($array[$key])) {
return;
}
$array = &$array[$key];
}
if (isset($array[$last])) {
// Detele path
unset($array[$last]);
}
} elseif (is_array($key)) {
// Iterate array of paths
foreach ($key as $k) {
self::delete($k);
}
}
}
/**
* Get value of path, default value if path doesn't exist or all data
*
* @param mixed|null $key Path
* @param mixed|null $default Default value
* @return mixed Value of path
*/
public function get($key = null, $default = null)
{
return self::getValue($this->data, $key, $default);
}
/**
* Set value or array of values to path
*
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
*/
public function set($key, $value = null)
{
return self::setValue($this->data, $key, $value);
}
/**
* Add value or array of values to path
*
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
* @param boolean $pop Helper to pop out last key if value is an array
*/
public function add($key, $value = null, $pop = false)
{
return self::addValue($this->data, $key, $value, $pop);
}
/**
* Check if path exists
*
* @param string $key Path
* @return boolean
*/
public function has($key)
{
$keys = explode('.', (string)$key);
$data = &$this->data;
foreach ($keys as $key) {
if (!isset($data[$key])) {
return false;
}
$data = &$data[$key];
}
return true;
}
/**
* Delete path or array of paths
*
* @param mixed $key Path or array of paths to delete
*/
public function delete($key)
{
return self::deleteValue($this->data, $key);
}
/**
* Delete all data, data from path or array of paths and
* optionally format path if it doesn't exist
*
* @param mixed|null $key Path or array of paths to clean
* @param boolean $format Format option
*/
public function clear($key = null, $format = false)
{
if (is_string($key)) {
// Iterate path
$keys = explode('.', $key);
$data = &$this->data;
foreach ($keys as $key) {
if (!isset($data[$key]) || !is_array($data[$key])) {
if ($format === true) {
$data[$key] = [];
} else {
return;
}
}
$data = &$data[$key];
}
// Clear path
$data = [];
} elseif (is_array($key)) {
// Iterate array
foreach ($key as $k) {
$this->clear($k, $format);
}
} elseif (is_null($key)) {
// Clear all data
$this->data = [];
}
}
/**
* Set data
*
* @param array $data
*/
public function setData(array $data)
{
$this->data = $data;
}
/**
* Set data as a reference
*
* @param array $data
*/
public function setDataAsRef(array &$data)
{
$this->data = &$data;
}
/**
* ArrayAccess abstract methods
*/
public function offsetSet($offset, $value)
{
$this->set($offset, $value);
}
public function offsetExists($offset)
{
return $this->has($offset);
}
public function offsetGet($offset)
{
return $this->get($offset);
}
public function offsetUnset($offset)
{
$this->delete($offset);
}
/**
* Magic methods
*/
public function __set($key, $value = null)
{
$this->set($key, $value);
}
public function __get($key)
{
return $this->get($key);
}
public function __isset($key)
{
return $this->has($key);
}
public function __unset($key)
{
$this->delete($key);
}
}

View File

@ -0,0 +1,155 @@
<?php
/**
* Created by PhpStorm.
* User: Andrey Mistulov
* Company: Aristos
* Date: 14.03.2017
* Time: 15:25
*/
namespace Prowebcraft;
/**
* Class Data
* @package Aristos
*/
class JsonDb extends \Prowebcraft\Dot
{
protected $db = '';
protected $data = null;
protected $config = [];
public function __construct($config = [])
{
$this->config = array_merge([
'name' => 'data.json',
'backup' => false,
'dir' => getcwd()
//'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json'
], $config);
$this->loadData();
parent::__construct();
}
/**
* Set value or array of values to path
*
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
* @param bool $save Save data to database
* @return $this
*/
public function set($key, $value = null, $save = true)
{
parent::set($key, $value);
if ($save) $this->save();
return $this;
}
/**
* Add value or array of values to path
*
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
* @param boolean $pop Helper to pop out last key if value is an array
* @param bool $save Save data to database
* @return $this
*/
public function add($key, $value = null, $pop = false, $save = true)
{
parent::add($key, $value, $pop);
if ($save) $this->save();
return $this;
}
/**
* Delete path or array of paths
*
* @param mixed $key Path or array of paths to delete
* @param bool $save Save data to database
* @return $this
*/
public function delete($key, $save = true)
{
parent::delete($key);
if ($save) $this->save();
return $this;
}
/**
* Delete all data, data from path or array of paths and
* optionally format path if it doesn't exist
*
* @param mixed|null $key Path or array of paths to clean
* @param boolean $format Format option
* @param bool $save Save data to database
* @return $this
*/
public function clear($key = null, $format = false, $save = true)
{
parent::clear($key, $format);
if ($save) $this->save();
return $this;
}
/**
* Local database upload
* @param bool $reload Reboot data?
* @return array|mixed|null
*/
protected function loadData($reload = false) {
if ($this->data === null || $reload) {
// $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
$this->db = $this->config['dir'] . $this->config['name'];
if (!file_exists($this->db)) {
return null;
} else {
// 3 essais
for($i = 0; $i <3; $i++) {
if ($this->data = json_decode(@file_get_contents($this->db), true) ) {
break;
}
// Pause de 10 millisecondes
usleep(10000);
}
// Gestion de l'erreur
if (!$this->data === null) {
exit ('JsonDB : Erreur de lecture du fichier de données ' . $this->db .'. Aucune donnée lisible, essayez dans quelques instants ou vérifiez le système de fichiers.');
}
}
}
return $this->data;
}
/**
* Saving to local database
*/
public function save() {
// Fichier inexistant, le créer
if ( !file_exists($this->db) ) {
touch($this->db);
}
// Backup file
if ($this->config['backup'] === true) {
copy ($this->db, str_replace('json' , 'backup.json', $this->db));
}
if ( is_writable($this->db) ) {
// 3 essais
for($i = 0; $i < 3; $i++) {
if( @file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) {
break;
}
// Pause de 10 millisecondes
usleep(10000);
}
if ($i === 2) {
exit ('Jsondb : Erreur d\'écriture dans le fichier de données ' . $this->db . '. Vérifiez le système de fichiers.' );
}
} else {
exit ('Jsondb : Écriture interdite dans le fichier de données ' . $this->db .'. Vérifiez les permissions.' );
}
}
}

View File

@ -0,0 +1,3 @@
# Bloque l'accès à la librairie
Order deny,allow
Deny from all

View File

@ -0,0 +1,39 @@
<?php
/**
* PHPMailer Exception class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer exception handler.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/
class Exception extends \Exception
{
/**
* Prettify error message output.
*
* @return string
*/
public function errorMessage()
{
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
<?php
namespace Icamys\SitemapGenerator;
class FileSystem
{
public function file_get_contents($filepath)
{
return file_get_contents($filepath);
}
public function file_put_contents($filepath, $content, $flags = 0)
{
return file_put_contents($filepath, $content, $flags);
}
public function file_exists($filepath)
{
return file_exists($filepath);
}
public function rename($oldname, $newname)
{
return rename($oldname, $newname);
}
public function copy($source, $destination)
{
return copy($source, $destination);
}
public function unlink($filepath)
{
return unlink($filepath);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Icamys\SitemapGenerator;
class Runtime
{
public function extension_loaded($extname)
{
return extension_loaded($extname);
}
public function is_writable($filepath)
{
return is_writable($filepath);
}
public function curl_init($url)
{
return curl_init($url);
}
public function curl_setopt($handle, $option, $value)
{
return curl_setopt($handle, $option, $value);
}
public function curl_exec($handle)
{
return curl_exec($handle);
}
public function curl_getinfo($handle, $option = null)
{
return curl_getinfo($handle, $option);
}
}

View File

@ -0,0 +1,705 @@
<?php
namespace Icamys\SitemapGenerator;
use BadMethodCallException;
use DateTime;
use Icamys\SitemapGenerator\Extensions\GoogleVideoExtension;
use InvalidArgumentException;
use OutOfRangeException;
use RuntimeException;
use XMLWriter;
/**
* Class SitemapGenerator
* @package Icamys\SitemapGenerator
*/
class SitemapGenerator
{
/**
* Max size of a sitemap according to spec.
* @see https://www.sitemaps.org/protocol.html
*/
private const MAX_FILE_SIZE = 52428800;
/**
* Max number of urls per sitemap according to spec.
* @see https://www.sitemaps.org/protocol.html
*/
private const MAX_URLS_PER_SITEMAP = 50000;
/**
* Max number of sitemaps per index file according to spec.
* @see http://www.sitemaps.org/protocol.html
*/
private const MAX_SITEMAPS_PER_INDEX = 50000;
/**
* Total max number of URLs.
*/
private const TOTAL_MAX_URLS = self::MAX_URLS_PER_SITEMAP * self::MAX_SITEMAPS_PER_INDEX;
/**
* Max url length according to spec.
* @see https://www.sitemaps.org/protocol.html#xmlTagDefinitions
*/
private const MAX_URL_LEN = 2048;
/**
* Robots file name
* @var string
* @access public
*/
private $robotsFileName = "robots.txt";
/**
* Name of sitemap file
* @var string
* @access public
*/
private $sitemapFileName = "sitemap.xml";
/**
* Name of sitemap index file
* @var string
* @access public
*/
private $sitemapIndexFileName = "sitemap-index.xml";
/**
* Quantity of URLs per single sitemap file.
* If Your links are very long, sitemap file can be bigger than 10MB,
* in this case use smaller value.
* @var int
* @access public
*/
private $maxUrlsPerSitemap = self::MAX_URLS_PER_SITEMAP;
/**
* If true, two sitemap files (.xml and .xml.gz) will be created and added to robots.txt.
* If true, .gz file will be submitted to search engines.
* If quantity of URLs will be bigger than 50.000, option will be ignored,
* all sitemap files except sitemap index will be compressed.
* @var bool
* @access public
*/
private $isCompressionEnabled = false;
/**
* URL to Your site.
* Script will use it to send sitemaps to search engines.
* @var string
* @access private
*/
private $baseURL;
/**
* Base path. Relative to script location.
* Use this if Your sitemap and robots files should be stored in other
* directory then script.
* @var string
* @access private
*/
private $basePath;
/**
* Version of this class
* @var string
* @access private
*/
private $classVersion = "4.3.1";
/**
* Search engines URLs
* @var array of strings
* @access private
*/
private $searchEngines = [
[
"http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=USERID&url=",
"http://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap=",
],
"http://www.google.com/ping?sitemap=",
"http://submissions.ask.com/ping?sitemap=",
"http://www.bing.com/ping?sitemap=",
"http://www.webmaster.yandex.ru/ping?sitemap=",
];
/**
* Array with urls
* @var array
* @access private
*/
private $urls;
/**
* Lines for robots.txt file that are written if file does not exist
* @var array
*/
private $sampleRobotsLines = [
"User-agent: *",
"Allow: /",
];
/**
* @var array list of valid changefreq values according to the spec
*/
private $validChangefreqValues = [
'always',
'hourly',
'daily',
'weekly',
'monthly',
'yearly',
'never',
];
/**
* @var float[] list of valid priority values according to the spec
*/
private $validPriorities = [
0.0,
0.1,
0.2,
0.3,
0.4,
0.5,
0.6,
0.7,
0.8,
0.9,
1.0,
];
/**
* @var FileSystem object used to communicate with file system
*/
private $fs;
/**
* @var Runtime object used to communicate with runtime
*/
private $runtime;
/**
* @var XMLWriter Used for writing xml to files
*/
private $xmlWriter;
/**
* @var string
*/
private $flushedSitemapFilenameFormat;
/**
* @var int
*/
private $flushedSitemapSize = 0;
/**
* @var int
*/
private $flushedSitemapCounter = 0;
/**
* @var array
*/
private $flushedSitemaps = [];
/**
* @var bool
*/
private $isSitemapStarted = false;
/**
* @var int
*/
private $totalUrlCount = 0;
/**
* @var int
*/
private $urlsetClosingTagLen = 10; // strlen("</urlset>\n")
private $sitemapUrlCount = 0;
private $generatedFiles = [];
/**
* @param string $baseURL You site URL
* @param string $basePath Relative path where sitemap and robots should be stored.
* @param FileSystem|null $fs
* @param Runtime|null $runtime
*/
public function __construct(string $baseURL, string $basePath = "", FileSystem $fs = null, Runtime $runtime = null)
{
$this->urls = [];
$this->baseURL = rtrim($baseURL, '/');
if ($fs === null) {
$this->fs = new FileSystem();
} else {
$this->fs = $fs;
}
if ($runtime === null) {
$this->runtime = new Runtime();
} else {
$this->runtime = $runtime;
}
if ($this->runtime->is_writable($basePath) === false) {
throw new InvalidArgumentException(
sprintf('the provided basePath (%s) should be a writable directory,', $basePath) .
' please check its existence and permissions'
);
}
if (strlen($basePath) > 0 && substr($basePath, -1) != DIRECTORY_SEPARATOR) {
$basePath = $basePath . DIRECTORY_SEPARATOR;
}
$this->basePath = $basePath;
$this->xmlWriter = $this->createXmlWriter();
$this->flushedSitemapFilenameFormat = sprintf("sm-%%d-%d.xml", time());
}
private function createXmlWriter(): XMLWriter
{
$w = new XMLWriter();
$w->openMemory();
$w->setIndent(true);
return $w;
}
/**
* @param string $filename
* @return SitemapGenerator
*/
public function setSitemapFilename(string $filename = ''): SitemapGenerator
{
if (strlen($filename) === 0) {
throw new InvalidArgumentException('sitemap filename should not be empty');
}
if (pathinfo($filename, PATHINFO_EXTENSION) !== 'xml') {
throw new InvalidArgumentException('sitemap filename should have *.xml extension');
}
$this->sitemapFileName = $filename;
return $this;
}
/**
* @param string $filename
* @return $this
*/
public function setSitemapIndexFilename(string $filename = ''): SitemapGenerator
{
if (strlen($filename) === 0) {
throw new InvalidArgumentException('filename should not be empty');
}
$this->sitemapIndexFileName = $filename;
return $this;
}
/**
* @param string $filename
* @return $this
*/
public function setRobotsFileName(string $filename): SitemapGenerator
{
if (strlen($filename) === 0) {
throw new InvalidArgumentException('filename should not be empty');
}
$this->robotsFileName = $filename;
return $this;
}
/**
* @param int $value
* @return $this
*/
public function setMaxUrlsPerSitemap(int $value): SitemapGenerator
{
if ($value < 1 || self::MAX_URLS_PER_SITEMAP < $value) {
throw new OutOfRangeException(
sprintf('value %d is out of range 1-%d', $value, self::MAX_URLS_PER_SITEMAP)
);
}
$this->maxUrlsPerSitemap = $value;
return $this;
}
public function enableCompression(): SitemapGenerator
{
$this->isCompressionEnabled = true;
return $this;
}
public function disableCompression(): SitemapGenerator
{
$this->isCompressionEnabled = false;
return $this;
}
public function isCompressionEnabled(): bool
{
return $this->isCompressionEnabled;
}
public function validate(
string $path,
DateTime $lastModified = null,
string $changeFrequency = null,
float $priority = null,
array $alternates = null,
array $extensions = [])
{
if (!(1 <= mb_strlen($path) && mb_strlen($path) <= self::MAX_URL_LEN)) {
throw new InvalidArgumentException(
sprintf("The urlPath argument length must be between 1 and %d.", self::MAX_URL_LEN)
);
}
if ($changeFrequency !== null && !in_array($changeFrequency, $this->validChangefreqValues)) {
throw new InvalidArgumentException(
'The change frequency argument should be one of: %s' . implode(',', $this->validChangefreqValues)
);
}
if ($priority !== null && !in_array($priority, $this->validPriorities)) {
throw new InvalidArgumentException("Priority argument should be a float number in the range [0.0..1.0]");
}
if ($extensions !== null && isset($extensions['google_video'])) {
GoogleVideoExtension::validate($this->baseURL . $path, $extensions['google_video']);
}
}
/**
* Add url components.
* Instead of storing all urls in the memory, the generator will flush sets of added urls
* to the temporary files created on your disk.
* The file format is 'sm-{index}-{timestamp}.xml'
* @param string $path
* @param DateTime|null $lastModified
* @param string|null $changeFrequency
* @param float|null $priority
* @param array|null $alternates
* @param array $extensions
* @return $this
*/
public function addURL(
string $path,
DateTime $lastModified = null,
string $changeFrequency = null,
float $priority = null,
array $alternates = null,
array $extensions = []
): SitemapGenerator
{
$this->validate($path, $lastModified, $changeFrequency, $priority, $alternates, $extensions);
if ($this->totalUrlCount >= self::TOTAL_MAX_URLS) {
throw new OutOfRangeException(
sprintf("Max url limit reached (%d)", self::TOTAL_MAX_URLS)
);
}
if ($this->isSitemapStarted === false) {
$this->writeSitemapStart();
}
$this->writeSitemapUrl($this->baseURL . $path, $lastModified, $changeFrequency, $priority, $alternates, $extensions);
if ($this->totalUrlCount % 1000 === 0 || $this->sitemapUrlCount >= $this->maxUrlsPerSitemap) {
$this->flushWriter();
}
if ($this->sitemapUrlCount === $this->maxUrlsPerSitemap) {
$this->writeSitemapEnd();
}
return $this;
}
private function writeSitemapStart()
{
$this->xmlWriter->startDocument("1.0", "UTF-8");
$this->xmlWriter->writeComment(sprintf('generator-class="%s"', get_class($this)));
$this->xmlWriter->writeComment(sprintf('generator-version="%s"', $this->classVersion));
$this->xmlWriter->writeComment(sprintf('generated-on="%s"', date('c')));
$this->xmlWriter->startElement('urlset');
$this->xmlWriter->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
$this->xmlWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
$this->xmlWriter->writeAttribute('xmlns:video', 'http://www.google.com/schemas/sitemap-video/1.1');
$this->xmlWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$this->xmlWriter->writeAttribute('xsi:schemaLocation', 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd');
$this->isSitemapStarted = true;
}
private function writeSitemapUrl($loc, $lastModified, $changeFrequency, $priority, $alternates, $extensions)
{
$this->xmlWriter->startElement('url');
$this->xmlWriter->writeElement('loc', htmlspecialchars($loc, ENT_QUOTES));
if ($lastModified !== null) {
$this->xmlWriter->writeElement('lastmod', $lastModified->format(DateTime::ATOM));
}
if ($changeFrequency !== null) {
$this->xmlWriter->writeElement('changefreq', $changeFrequency);
}
if ($priority !== null) {
$this->xmlWriter->writeElement('priority', number_format($priority, 1, ".", ""));
}
if (is_array($alternates) && count($alternates) > 0) {
foreach ($alternates as $alternate) {
if (is_array($alternate) && isset($alternate['hreflang']) && isset($alternate['href'])) {
$this->xmlWriter->startElement('xhtml:link');
$this->xmlWriter->writeAttribute('rel', 'alternate');
$this->xmlWriter->writeAttribute('hreflang', $alternate['hreflang']);
$this->xmlWriter->writeAttribute('href', $alternate['href']);
$this->xmlWriter->endElement();
}
}
}
foreach ($extensions as $extName => $extFields) {
if ($extName === 'google_video') {
GoogleVideoExtension::writeVideoTag($this->xmlWriter, $loc, $extFields);
}
}
$this->xmlWriter->endElement(); // url
$this->sitemapUrlCount++;
$this->totalUrlCount++;
}
private function flushWriter()
{
$targetSitemapFilepath = $this->basePath . sprintf($this->flushedSitemapFilenameFormat, $this->flushedSitemapCounter);
$flushedString = $this->xmlWriter->outputMemory(true);
$flushedStringLen = mb_strlen($flushedString);
if ($flushedStringLen === 0) {
return;
}
$this->flushedSitemapSize += $flushedStringLen;
if ($this->flushedSitemapSize > self::MAX_FILE_SIZE - $this->urlsetClosingTagLen) {
$this->writeSitemapEnd();
$this->writeSitemapStart();
}
$this->fs->file_put_contents($targetSitemapFilepath, $flushedString, FILE_APPEND);
}
private function writeSitemapEnd()
{
$targetSitemapFilepath = $this->basePath . sprintf($this->flushedSitemapFilenameFormat, $this->flushedSitemapCounter);
$this->xmlWriter->endElement(); // urlset
$this->xmlWriter->endDocument();
$this->fs->file_put_contents($targetSitemapFilepath, $this->xmlWriter->flush(true), FILE_APPEND);
$this->isSitemapStarted = false;
$this->flushedSitemaps[] = $targetSitemapFilepath;
$this->flushedSitemapCounter++;
$this->sitemapUrlCount = 0;
}
/**
* Flush all stored urls from memory to the disk and close all necessary tags.
*/
public function flush()
{
$this->flushWriter();
if ($this->isSitemapStarted) {
$this->writeSitemapEnd();
}
}
/**
* Move flushed files to their final location. Compress if necessary.
*/
public function finalize()
{
$this->generatedFiles = [];
if (count($this->flushedSitemaps) === 1) {
$targetSitemapFilename = $this->sitemapFileName;
if ($this->isCompressionEnabled) {
$targetSitemapFilename .= '.gz';
}
$targetSitemapFilepath = $this->basePath . $targetSitemapFilename;
if ($this->isCompressionEnabled) {
$this->fs->copy($this->flushedSitemaps[0], 'compress.zlib://' . $targetSitemapFilepath);
$this->fs->unlink($this->flushedSitemaps[0]);
} else {
$this->fs->rename($this->flushedSitemaps[0], $targetSitemapFilepath);
}
$this->generatedFiles['sitemaps_location'] = [$targetSitemapFilepath];
$this->generatedFiles['sitemaps_index_url'] = $this->baseURL . '/' . $targetSitemapFilename;
} else if (count($this->flushedSitemaps) > 1) {
$ext = '.' . pathinfo($this->sitemapFileName, PATHINFO_EXTENSION);
$targetExt = $ext;
if ($this->isCompressionEnabled) {
$targetExt .= '.gz';
}
$sitemapsUrls = [];
$targetSitemapFilepaths = [];
foreach ($this->flushedSitemaps as $i => $flushedSitemap) {
$targetSitemapFilename = str_replace($ext, ($i + 1) . $targetExt, $this->sitemapFileName);
$targetSitemapFilepath = $this->basePath . $targetSitemapFilename;
if ($this->isCompressionEnabled) {
$this->fs->copy($flushedSitemap, 'compress.zlib://' . $targetSitemapFilepath);
$this->fs->unlink($flushedSitemap);
} else {
$this->fs->rename($flushedSitemap, $targetSitemapFilepath);
}
$sitemapsUrls[] = htmlspecialchars($this->baseURL . '/' . $targetSitemapFilename, ENT_QUOTES);
$targetSitemapFilepaths[] = $targetSitemapFilepath;
}
$targetSitemapIndexFilepath = $this->basePath . $this->sitemapIndexFileName;
$this->createSitemapIndex($sitemapsUrls, $targetSitemapIndexFilepath);
$this->generatedFiles['sitemaps_location'] = $targetSitemapFilepaths;
$this->generatedFiles['sitemaps_index_location'] = $targetSitemapIndexFilepath;
$this->generatedFiles['sitemaps_index_url'] = $this->baseURL . '/' . $this->sitemapIndexFileName;
} else {
throw new RuntimeException('failed to finalize, please add urls and flush first');
}
}
private function createSitemapIndex($sitemapsUrls, $sitemapIndexFileName)
{
$this->xmlWriter->flush(true);
$this->writeSitemapIndexStart();
foreach ($sitemapsUrls as $sitemapsUrl) {
$this->writeSitemapIndexUrl($sitemapsUrl);
}
$this->writeSitemapIndexEnd();
$this->fs->file_put_contents(
$sitemapIndexFileName,
$this->xmlWriter->flush(true),
FILE_APPEND
);
}
private function writeSitemapIndexStart()
{
$this->xmlWriter->startDocument("1.0", "UTF-8");
$this->xmlWriter->writeComment(sprintf('generator-class="%s"', get_class($this)));
$this->xmlWriter->writeComment(sprintf('generator-version="%s"', $this->classVersion));
$this->xmlWriter->writeComment(sprintf('generated-on="%s"', date('c')));
$this->xmlWriter->startElement('sitemapindex');
$this->xmlWriter->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
$this->xmlWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$this->xmlWriter->writeAttribute('xsi:schemaLocation', 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd');
}
private function writeSitemapIndexUrl($url)
{
$this->xmlWriter->startElement('sitemap');
$this->xmlWriter->writeElement('loc', htmlspecialchars($url, ENT_QUOTES));
$this->xmlWriter->writeElement('lastmod', date('c'));
$this->xmlWriter->endElement(); // sitemap
}
private function writeSitemapIndexEnd()
{
$this->xmlWriter->endElement(); // sitemapindex
$this->xmlWriter->endDocument();
}
/**
* @return array Array of previously generated files
*/
public function getGeneratedFiles(): array
{
return $this->generatedFiles;
}
/**
* Will inform search engines about newly created sitemaps.
* Google, Ask, Bing and Yahoo will be noticed.
* If You don't pass yahooAppId, Yahoo still will be informed,
* but this method can be used once per day. If You will do this often,
* message that limit was exceeded will be returned from Yahoo.
* @param string $yahooAppId Your site Yahoo appid.
* @return array of messages and http codes from each search engine
* @access public
* @throws BadMethodCallException
*/
public function submitSitemap($yahooAppId = null): array
{
if (count($this->generatedFiles) === 0) {
throw new BadMethodCallException("To update robots.txt, call finalize() first.");
}
if (!$this->runtime->extension_loaded('curl')) {
throw new BadMethodCallException("cURL extension is needed to do submission.");
}
$searchEngines = $this->searchEngines;
$searchEngines[0] = isset($yahooAppId) ?
str_replace("USERID", $yahooAppId, $searchEngines[0][0]) :
$searchEngines[0][1];
$result = [];
for ($i = 0; $i < count($searchEngines); $i++) {
$submitUrl = $searchEngines[$i] . htmlspecialchars($this->generatedFiles['sitemaps_index_url'], ENT_QUOTES);
$submitSite = $this->runtime->curl_init($submitUrl);
$this->runtime->curl_setopt($submitSite, CURLOPT_RETURNTRANSFER, true);
$responseContent = $this->runtime->curl_exec($submitSite);
$response = $this->runtime->curl_getinfo($submitSite);
$submitSiteShort = array_reverse(explode(".", parse_url($searchEngines[$i], PHP_URL_HOST)));
$result[] = [
"site" => $submitSiteShort[1] . "." . $submitSiteShort[0],
"fullsite" => $submitUrl,
"http_code" => $response['http_code'],
"message" => str_replace("\n", " ", strip_tags($responseContent)),
];
}
return $result;
}
/**
* Adds sitemap url to robots.txt file located in basePath.
* If robots.txt file exists,
* the function will append sitemap url to file.
* If robots.txt does not exist,
* the function will create new robots.txt file with sample content and sitemap url.
* @access public
* @throws BadMethodCallException
* @throws RuntimeException
*/
public function updateRobots(): SitemapGenerator
{
if (count($this->generatedFiles) === 0) {
throw new BadMethodCallException("To update robots.txt, call finalize() first.");
}
$robotsFilePath = $this->basePath . $this->robotsFileName;
$robotsFileContent = $this->createNewRobotsContentFromFile($robotsFilePath);
$this->fs->file_put_contents($robotsFilePath, $robotsFileContent);
return $this;
}
/**
* @param $filepath
* @return string
*/
private function createNewRobotsContentFromFile($filepath): string
{
if ($this->fs->file_exists($filepath)) {
$robotsFileContent = "";
$robotsFile = explode(PHP_EOL, $this->fs->file_get_contents($filepath));
foreach ($robotsFile as $key => $value) {
if (substr($value, 0, 8) == 'Sitemap:') {
unset($robotsFile[$key]);
} else {
$robotsFileContent .= $value . PHP_EOL;
}
}
} else {
$robotsFileContent = $this->getSampleRobotsContent();
}
$robotsFileContent .= "Sitemap: {$this->generatedFiles['sitemaps_index_url']}";
return $robotsFileContent;
}
/**
* @return string
* @access private
*/
private function getSampleRobotsContent(): string
{
return implode(PHP_EOL, $this->sampleRobotsLines) . PHP_EOL;
}
}

View File

@ -0,0 +1,868 @@
<?php
class template {
/**
* Crée un bouton
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function button($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'class' => '',
'disabled' => false,
'href' => 'javascript:void(0);',
'ico' => '',
'id' => $nameId,
'name' => $nameId,
'target' => '',
'uniqueSubmission' => false,
'value' => 'Bouton'
], $attributes);
// Retourne le html
return sprintf(
'<a %s class="button %s %s %s">%s</a>',
helper::sprintAttributes($attributes, ['class', 'disabled', 'ico', 'value']),
$attributes['disabled'] ? 'disabled' : '',
$attributes['class'],
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
($attributes['ico'] ? template::ico($attributes['ico'], 'right') : '') . $attributes['value']
);
}
/**
* Crée un champ captcha
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function captcha($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'class' => '',
'classWrapper' => '',
'help' => '',
'id' => $nameId,
'name' => $nameId,
'value' => '',
'limit' => false, // captcha simple
'type'=> 'alpha' // num(érique) ou alpha(bétique)
], $attributes);
// Captcha quatre opérations
// Limite addition et soustraction selon le type de captcha
$numbers = [0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20];
$letters = ['u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'];
$limit = $attributes['limit'] ? count($letters)-1 : 10;
// Tirage de l'opération
mt_srand((float) microtime()*1000000);
// Captcha simple limité à l'addition
$operator = $attributes['limit'] ? mt_rand (1, 4) : 1;
// Limite si multiplication ou division
if ($operator > 2) {
$limit = 10;
}
// Tirage des nombres
mt_srand((float) microtime()*1000000);
$firstNumber = mt_rand (1, $limit);
mt_srand((float) microtime()*1000000);
$secondNumber = mt_rand (1, $limit);
// Permutation si addition ou soustraction
if (($operator < 3) and ($firstNumber < $secondNumber)) {
$temp = $firstNumber;
$firstNumber = $secondNumber;
$secondNumber = $temp;
}
// Icône de l'opérateur et calcul du résultat
switch ($operator) {
case 1:
$operator = template::ico('plus');
$result = $firstNumber + $secondNumber;
break;
case 2:
$operator = template::ico('minus');
$result = $firstNumber - $secondNumber;
break;
case 3:
$operator = template::ico('cancel');
$result = $firstNumber * $secondNumber;
break;
case 4:
$operator = template::ico('divide');
$limit2 = [10, 10, 6, 5, 4, 3, 2, 2, 2, 2];
for ($i = 1; $i <= $firstNumber; $i++) {
$limit = $limit2[$i-1];
}
mt_srand((float) microtime()*1000000);
$secondNumber = mt_rand(1, $limit);
$firstNumber = $firstNumber * $secondNumber;
$result = $firstNumber / $secondNumber;
break;
}
// Hashage du résultat
$result = password_hash($result, PASSWORD_BCRYPT);
// Codage des valeurs de l'opération
$firstLetter = uniqid();
$secondLetter = uniqid();
// Masquage image source pour éviter un décodage
copy ('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png');
copy ('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="captcha inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
$html .= self::label($attributes['id'],
'<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" />&nbsp;<strong>' . $operator . '</strong>&nbsp;<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" /> en chiffres ?', [
'help' => $attributes['help']
]);
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// captcha
$html .= sprintf(
'<input type="text" %s>',
helper::sprintAttributes($attributes)
);
// Champ résultat codé
$html .= self::hidden($attributes['id'] . 'Result', [
'value' => $result,
'before' => false
]);
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée une case à cocher à sélection multiple
* @param string $nameId Nom et id du champ
* @param string $value Valeur de la case à cocher
* @param string $label Label de la case à cocher
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function checkbox($nameId, $value, $label, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'before' => true,
'checked' => '',
'class' => '',
'classWrapper' => '',
'disabled' => false,
'help' => '',
'id' => $nameId,
'name' => $nameId
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['checked'] = (bool) common::$inputBefore[$attributes['id']];
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Case à cocher
$html .= sprintf(
'<input type="checkbox" value="%s" %s>',
$value,
helper::sprintAttributes($attributes)
);
// Label
$html .= self::label($attributes['id'], '<span>' . $label . '</span>', [
'help' => $attributes['help']
]);
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée un champ date
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function date($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'autocomplete' => 'on',
'before' => true,
'class' => '',
'classWrapper' => '',
'noDirty' => false,
'disabled' => false,
'help' => '',
'id' => $nameId,
'label' => '',
'name' => $nameId,
'placeholder' => '',
'readonly' => true,
'value' => ''
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
}
else {
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], helper::FILTER_TIMESTAMP) : '');
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Date visible
$html .= '<div class="inputDateManagerWrapper">';
$html .= sprintf(
'<input type="text" class="datepicker %s" value="%s" %s>',
$attributes['class'],
$attributes['value'],
helper::sprintAttributes($attributes, ['class', 'value'])
);
$html .= self::button($attributes['id'] . 'Delete', [
'class' => 'inputDateDelete',
'value' => self::ico('cancel')
]);
$html .= '</div>';
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée un champ d'upload de fichier
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function file($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'before' => true,
'class' => '',
'classWrapper' => '',
'noDirty' => false,
'disabled' => false,
'extensions' => '',
'help' => '',
'id' => $nameId,
'label' => '',
'maxlength' => '500',
'name' => $nameId,
'type' => 2,
'value' => ''
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Champ caché contenant l'url de la page
$html .= self::hidden($attributes['id'], [
'class' => 'inputFileHidden',
'disabled' => $attributes['disabled'],
'maxlength' => $attributes['maxlength'],
'value' => $attributes['value']
]);
// Champ d'upload
$html .= '<div class="inputFileManagerWrapper">';
$html .= sprintf(
'<a
href="' .
helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php' .
'?relative_url=1' .
'&field_id=' . $attributes['id'] .
'&type=' . $attributes['type'] .
'&akey=' . md5_file(core::DATA_DIR.'core.json') .
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
. '"
class="inputFile %s %s"
%s
data-lity
>
' . self::ico('upload', 'right') . '
<span class="inputFileLabel"></span>
</a>',
$attributes['class'],
$attributes['disabled'] ? 'disabled' : '',
helper::sprintAttributes($attributes, ['class', 'extensions', 'type', 'maxlength'])
);
$html .= self::button($attributes['id'] . 'Delete', [
'class' => 'inputFileDelete',
'value' => self::ico('cancel')
]);
$html .= '</div>';
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Ferme un formulaire
* @return string
*/
public static function formClose() {
return '</form>';
}
/**
* Ouvre un formulaire protégé par CSRF
* @param string $id Id du formulaire
* @return string
*/
public static function formOpen($id) {
// Ouverture formulaire
$html = '<form id="' . $id . '" method="post">';
// Stock le token CSRF
$html .= self::hidden('csrf', [
'value' => $_SESSION['csrf']
]);
// Retourne le html
return $html;
}
/**
* Crée une aide qui s'affiche au survole
* @param string $text Texte de l'aide
* @return string
*/
public static function help($text) {
return '<span class="helpButton" data-tippy-content="' . $text . '">' . self::ico('help') . '<!----></span>';
}
/**
* Crée un champ caché
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function hidden($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'before' => true,
'class' => '',
'noDirty' => false,
'id' => $nameId,
//'maxlength' => '500',
'name' => $nameId,
'value' => ''
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
}
// Texte
$html = sprintf('<input type="hidden" %s>', helper::sprintAttributes($attributes, ['before']));
// Retourne le html
return $html;
}
/**
* Crée un icône
* @param string $ico Classe de l'icône
* @param string $margin Ajoute un margin autour de l'icône (choix : left, right, all)
* @param bool $animate Ajoute une animation à l'icône
* @param string $fontSize Taille de la police
* @return string
*/
public static function ico($ico, $margin = '', $animate = false, $fontSize = '1em') {
return '<span class="zwiico-' . $ico . ($margin ? ' zwiico-margin-' . $margin : '') . ($animate ? ' animate-spin' : '') . '" style="font-size:' . $fontSize . '"><!----></span>';
}
/**
* Crée un drapeau du site courant
* @param string $langId Id de la langue à affiche ou site pour la langue traduite courante
* @param string $margin Ajoute un margin autour de l'icône (choix : left, right, all)
* @return string
*/
public static function flag($langId, $size = 'auto') {
switch ($langId) {
case '':
$lang = 'fr';
break;
case in_array($langId,['fr', 'de', 'en', 'es', 'it', 'nl', 'pt']):
$lang = $langId;
break;
case 'site':
if ( isset($_COOKIE['DELTA_I18N_SITE'])
) {
$lang = $_COOKIE['DELTA_I18N_SITE'];
} else {
$lang = 'fr';
}
}
return '<img class="flag" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png"
width="' . $size .'"
height="' . $size .'"
title="' . $lang .'"
alt="(' . $lang . ')"/>';
}
/**
* Crée un label
* @param string $for For du label
* @param array $attributes Attributs ($key => $value)
* @param string $text Texte du label
* @return string
*/
public static function label($for, $text, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'class' => '',
'for' => $for,
'help' => ''
], $attributes);
// Ajout d'une aide
if($attributes['help'] !== '') {
$text = $text . self::help($attributes['help']);
}
// Retourne le html
return sprintf(
'<label %s>%s</label>',
helper::sprintAttributes($attributes),
$text
);
}
/**
* Crée un champ mail
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function mail($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'autocomplete' => 'on',
'before' => true,
'class' => '',
'classWrapper' => '',
'noDirty' => false,
'disabled' => false,
'help' => '',
'id' => $nameId,
'label' => '',
//'maxlength' => '500',
'name' => $nameId,
'placeholder' => '',
'readonly' => false,
'value' => ''
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Texte
$html .= sprintf(
'<input type="email" %s>',
helper::sprintAttributes($attributes)
);
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée une notice
* @param string $id Id du champ
* @param string $notice Notice
* @return string
*/
public static function notice($id, $notice) {
return ' <span id="' . $id . 'Notice" class="notice ' . ($notice ? '' : 'displayNone') . '">' . $notice . '</span>';
}
/**
* Crée un champ mot de passe
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function password($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'autocomplete' => 'on',
'class' => '',
'classWrapper' => '',
'noDirty' => false,
'disabled' => false,
'help' => '',
'id' => $nameId,
'label' => '',
//'maxlength' => '500',
'name' => $nameId,
'placeholder' => '',
'readonly' => false
], $attributes);
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Mot de passe
$html .= sprintf(
'<input type="password" %s >',
helper::sprintAttributes($attributes)
);
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée un champ sélection
* @param string $nameId Nom et id du champ
* @param array $options Liste des options du champ de sélection ($value => $text)
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function select($nameId, array $options, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'before' => true,
'class' => '',
'classWrapper' => '',
'noDirty' => false,
'disabled' => false,
'help' => '',
'id' => $nameId,
'label' => '',
'name' => $nameId,
'selected' => '',
'fonts' => false
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['selected'] = common::$inputBefore[$attributes['id']];
}
// Liste des polices à intégrer
if ($attributes['fonts'] === true) {
foreach ($options as $fontId) {
echo "<link href='https://fonts.googleapis.com/css?family=".str_replace(" ", "+", $fontId)."' rel='stylesheet' type='text/css'>\n";
}
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Début sélection
$html .= sprintf('<select %s>',
helper::sprintAttributes($attributes)
);
foreach($options as $value => $text) {
$html .= $attributes['fonts'] === true ? sprintf(
'<option value="%s"%s style="font-family: %s;">%s</option>',
$value,
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
str_replace('+',' ',$value),
$text
) : sprintf(
'<option value="%s"%s>%s</option>',
$value,
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
$text
);
}
// Fin sélection
$html .= '</select>';
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée une bulle de dialogue
* @param string $text Texte de la bulle
* @return string
*/
public static function speech($text) {
return '<div class="speech"><div class="speechBubble">' . $text . '</div></div>';
}
/**
* Crée un bouton validation
* @param string $nameId Nom & id du bouton validation
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function submit($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'class' => '',
'disabled' => false,
'ico' => 'check',
'id' => $nameId,
'name' => $nameId,
'uniqueSubmission' => false, //true avant 9.1.08
'value' => 'Enregistrer'
], $attributes);
// Retourne le html
return sprintf(
'<button type="submit" class="%s%s" %s>%s</button>',
$attributes['class'],
$attributes['uniqueSubmission'] ? 'uniqueSubmission' : '',
helper::sprintAttributes($attributes, ['class', 'ico', 'value']),
($attributes['ico'] ? template::ico($attributes['ico'], 'right') : '') . $attributes['value']
);
}
/**
* Crée un tableau
* @param array $cols Cols des colonnes (format: [col colonne1, col colonne2, etc])
* @param array $body Contenu (format: [[contenu1, contenu2, etc], [contenu1, contenu2, etc]])
* @param array $head Entêtes (format : [[titre colonne1, titre colonne2, etc])
* @param array $rowsId Id pour la numérotation des rows (format : [id colonne1, id colonne2, etc])
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function table(array $cols = [], array $body = [], array $head = [], array $attributes = [], array $rowsId = []) {
// Attributs par défaut
$attributes = array_merge([
'class' => '',
'classWrapper' => '',
'id' => ''
], $attributes);
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="tableWrapper ' . $attributes['classWrapper']. '">';
// Début tableau
$html .= '<table id="' . $attributes['id'] . '" class="table ' . $attributes['class']. '">';
// Entêtes
if($head) {
// Début des entêtes
$html .= '<thead>';
$html .= '<tr class="nodrag">';
$i = 0;
foreach($head as $th) {
$html .= '<th class="col' . $cols[$i++] . '">' . $th . '</th>';
}
// Fin des entêtes
$html .= '</tr>';
$html .= '</thead>';
}
// Pas de tableau d'Id transmis, générer une numérotation
if (empty($rowsId)) {
$rowsId = range(0,count($body));
}
// Début contenu
$j = 0;
foreach($body as $tr) {
// Id de ligne pour les tableaux drag and drop
$html .= '<tr id="' . $rowsId[$j++] . '">';
$i = 0;
foreach($tr as $td) {
$html .= '<td class="col' . $cols[$i++] . '">' . $td . '</td>';
}
$html .= '</tr>';
}
// Fin contenu
$html .= '</tbody>';
// Fin tableau
$html .= '</table>';
// Fin container
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée un champ texte court
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function text($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'autocomplete' => 'on',
'before' => true,
'class' => '',
'classWrapper' => '',
'noDirty' => false,
'disabled' => false,
'help' => '',
'id' => $nameId,
'label' => '',
//'maxlength' => '500',
'name' => $nameId,
'placeholder' => '',
'readonly' => false,
'value' => ''
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Texte
$html .= sprintf(
'<input type="text" %s>',
helper::sprintAttributes($attributes)
);
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
/**
* Crée un champ texte long
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function textarea($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'before' => true,
'class' => '', // editorWysiwyg et editor possible pour utiliser un éditeur (il faut également instancier les librairies)
'classWrapper' => '',
'disabled' => false,
'noDirty' => false,
'help' => '',
'id' => $nameId,
'label' => '',
//'maxlength' => '500',
'name' => $nameId,
'readonly' => false,
'value' => ''
], $attributes);
// Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
if($attributes['label']) {
$html .= self::label($attributes['id'], $attributes['label'], [
'help' => $attributes['help']
]);
}
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']];
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Texte long
$html .= sprintf(
'<textarea %s>%s</textarea>',
helper::sprintAttributes($attributes, ['value']),
$attributes['value']
);
// Fin du wrapper
$html .= '</div>';
// Retourne le html
return $html;
}
}

549
core/core.js.php Normal file
View File

@ -0,0 +1,549 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
var core = {};
/**
* Crée un message d'alerte
*/
core.alert = function(text) {
var lightbox = lity(function($) {
return $("<div>")
.addClass("lightbox")
.append(
$("<span>").text(text),
$("<div>")
.addClass("lightboxButtons")
.append(
$("<a>")
.addClass("button")
.text("Ok")
.on("click", function() {
lightbox.close();
})
)
)
}(jQuery));
// Validation de la lightbox avec le bouton entrée
$(document).on("keyup", function(event) {
if(event.keyCode === 13) {
lightbox.close();
}
});
return false;
};
/**
* Génère des variations d'une couleur
*/
core.colorVariants = function(rgba) {
rgba = rgba.match(/\(+(.*)\)/);
rgba = rgba[1].split(", ");
return {
"normal": "rgba(" + rgba[0] + "," + rgba[1] + "," + rgba[2] + "," + rgba[3] + ")",
"darken": "rgba(" + Math.max(0, rgba[0] - 15) + "," + Math.max(0, rgba[1] - 15) + "," + Math.max(0, rgba[2] - 15) + "," + rgba[3] + ")",
"veryDarken": "rgba(" + Math.max(0, rgba[0] - 20) + "," + Math.max(0, rgba[1] - 20) + "," + Math.max(0, rgba[2] - 20) + "," + rgba[3] + ")",
//"text": core.relativeLuminanceW3C(rgba) > .22 ? "inherit" : "white"
"text": core.relativeLuminanceW3C(rgba) > .22 ? "#222" : "#DDD"
};
};
/**
* Crée un message de confirmation
*/
core.confirm = function(text, yesCallback, noCallback) {
var lightbox = lity(function($) {
return $("<div>")
.addClass("lightbox")
.append(
$("<span>").text(text),
$("<div>")
.addClass("lightboxButtons")
.append(
$("<a>")
.addClass("button grey")
.text("Non")
.on("click", function() {
lightbox.options('button', true);
lightbox.close();
if(typeof noCallback !== "undefined") {
noCallback();
}
}),
$("<a>")
.addClass("button")
.text("Oui")
.on("click", function() {
lightbox.options('button', true);
lightbox.close();
if(typeof yesCallback !== "undefined") {
yesCallback();
}
})
)
)
}(jQuery));
// Callback lors d'un clic sur le fond et sur la croix de fermeture
lightbox.options('button', false);
$(document).on('lity:close', function(event, instance) {
if(
instance.options('button') === false
&& typeof noCallback !== "undefined"
) {
noCallback();
}
});
// Validation de la lightbox avec le bouton entrée
$(document).on("keyup", function(event) {
if(event.keyCode === 13) {
lightbox.close();
if(typeof yesCallback !== "undefined") {
yesCallback();
}
}
});
return false;
};
/**
* Scripts à exécuter en dernier
*/
core.end = function() {
/**
* Modifications non enregistrées du formulaire
*/
var formDOM = $("form");
// Ignore :
// - TinyMCE car il gère lui même le message
// - Les champs avec data-no-dirty
var inputsDOM = formDOM.find("input:not([data-no-dirty]), select:not([data-no-dirty]), textarea:not(.editorWysiwyg):not([data-no-dirty])");
var inputSerialize = inputsDOM.serialize();
$(window).on("beforeunload", function() {
if(inputsDOM.serialize() !== inputSerialize) {
return "Les modifications que vous avez apportées ne seront peut-être pas enregistrées.";
}
});
formDOM.submit(function() {
$(window).off("beforeunload");
});
};
$(function() {
core.end();
});
/**
* Ajoute une notice
*/
core.noticeAdd = function(id, notice) {
$("#" + id + "Notice").text(notice).removeClass("displayNone");
$("#" + id).addClass("notice");
};
/**
* Supprime une notice
*/
core.noticeRemove = function(id) {
$("#" + id + "Notice").text("").addClass("displayNone");
$("#" + id).removeClass("notice");
};
/**
* Scripts à exécuter en premier
*/
core.start = function() {
/**
* Remonter en haut au clic sur le bouton
*/
var backToTopDOM = $("#backToTop");
backToTopDOM.on("click", function() {
$("body, html").animate({scrollTop: 0}, "400");
});
/**
* Affiche / Cache le bouton pour remonter en haut
*/
$(window).on("scroll", function() {
if($(this).scrollTop() > 200) {
backToTopDOM.fadeIn();
}
else {
backToTopDOM.fadeOut();
}
});
/**
* Cache les notifications
*/
var notificationTimer;
$("#notification")
.on("mouseenter", function() {
clearTimeout(notificationTimer);
$("#notificationProgress")
.stop()
.width("100%");
})
.on("mouseleave", function() {
// Disparition de la notification
notificationTimer = setTimeout(function() {
$("#notification").fadeOut();
}, 3000);
// Barre de progression
$("#notificationProgress").animate({
"width": "0%"
}, 3000, "linear");
})
.trigger("mouseleave");
$("#notificationClose").on("click", function() {
clearTimeout(notificationTimer);
$("#notification").fadeOut();
$("#notificationProgress").stop();
});
/**
* Traitement du formulaire cookies
*/
$("#cookieForm").submit(function(event){
// Varables des cookies
var samesite = "samesite=lax";
var getUrl = window.location;
var domain = "domain=" + getUrl.host;
var path = "path=" + getUrl.pathname.split('/')[1];
var samesite = "samesite=lax";
var e = new Date();
e.setFullYear(e.getFullYear() + 1);
var expires = "expires=" + e.toUTCString();
// Crée le cookie d'acceptation Cookies Externes (tiers) si le message n'est pas vide
var messageCookieExt = "<?php echo $this->getData(['locale', 'cookies', 'cookiesExtText']);?>";
// le message de consentement des cookies externes est défini en configuration, afficher la checkbox d'acceptation
if( messageCookieExt.length > 0){
// Traitement du retour de la checkbox
if ($("#cookiesExt").is(":checked")) {
// L'URL du serveur faut TRUE
document.cookie = "DELTA_COOKIE_EXT_CONSENT=true;" + domain + ";" + path + ";" + samesite + ";" + expires;
} else {
document.cookie = "DELTA_COOKIE_EXT_CONSENT=false;" + domain + ";" + path + ";" + samesite + ";" + expires;
}
}
// Stocke le cookie d'acceptation
document.cookie = "DELTA_COOKIE_CONSENT=true;" + domain + ";" + path + ";" + samesite + ";" + expires;
});
/**
* Fermeture de la popup des cookies
*/
$("#cookieConsent .cookieClose").on("click", function() {
$('#cookieConsent').addClass("displayNone");
});
/**
* Commande de gestion des cookies dans le footer
*/
$("#footerLinkCookie").on("click", function() {
$("#cookieConsent").removeClass("displayNone");
});
/**
* Affiche / Cache le menu en mode responsive
*/
var menuDOM = $("#menu");
$("#toggle").on("click", function() {
menuDOM.slideToggle();
});
$(window).on("resize", function() {
if($(window).width() > 768) {
menuDOM.css("display", "");
}
});
/**
* Choix de page dans la barre de membre
*/
$("#barSelectPage").on("change", function() {
var pageUrl = $(this).val();
if(pageUrl) {
$(location).attr("href", pageUrl);
}
});
/**
* Champs d'upload de fichiers
*/
// Mise à jour de l'affichage des champs d'upload
$(".inputFileHidden").on("change", function() {
var inputFileHiddenDOM = $(this);
var fileName = inputFileHiddenDOM.val();
if(fileName === "") {
fileName = "Choisissez un fichier";
$(inputFileHiddenDOM).addClass("disabled");
}
else {
$(inputFileHiddenDOM).removeClass("disabled");
}
inputFileHiddenDOM.parent().find(".inputFileLabel").text(fileName);
}).trigger("change");
// Suppression du fichier contenu dans le champ
$(".inputFileDelete").on("click", function() {
$(this).parents(".inputWrapper").find(".inputFileHidden").val("").trigger("change");
});
// Suppression de la date contenu dans le champ
$(".inputDateDelete").on("click", function() {
$(this).parents(".inputWrapper").find(".datepicker").val("").trigger("change");
});
// Confirmation de mise à jour
$("#barUpdate").on("click", function() {
return core.confirm("Effectuer la mise à jour ?", function() {
$(location).attr("href", $("#barUpdate").attr("href"));
});
});
// Confirmation de déconnexion
$("#barLogout").on("click", function() {
return core.confirm("Se déconnecter ?", function() {
$(location).attr("href", $("#barLogout").attr("href"));
});
});
/**
* Bloque la multi-soumission des boutons
*/
$("form").on("submit", function() {
$(this).find(".uniqueSubmission")
.addClass("disabled")
.prop("disabled", true)
.empty()
.append(
$("<span>").addClass("zwiico-spin animate-spin")
)
});
/**
* Check adresse email
*/
$("[type=email]").on("change", function() {
var _this = $(this);
var pattern = /^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i;
if(pattern.test(_this.val())) {
core.noticeRemove(_this.attr("id"));
}
else {
core.noticeAdd(_this.attr("id"), "Format incorrect");
}
});
/**
* Iframes et vidéos responsives
*/
var elementDOM = $("iframe, video, embed, object");
// Calcul du ratio et suppression de la hauteur / largeur des iframes
elementDOM.each(function() {
var _this = $(this);
_this
.data("ratio", _this.height() / _this.width())
.data("maxwidth", _this.width())
.removeAttr("width height");
});
// Prend la largeur du parent et détermine la hauteur à l'aide du ratio lors du resize de la fenêtre
$(window).on("resize", function() {
elementDOM.each(function() {
var _this = $(this);
var width = _this.parent().first().width();
if (width > _this.data("maxwidth")){ width = _this.data("maxwidth");}
_this
.width(width)
.height(width * _this.data("ratio"));
});
}).trigger("resize");
/*
* Header responsive
*/
$(window).on("resize", function() {
var responsive = "<?php echo $this->getdata(['theme','header','imageContainer']);?>";
var feature = "<?php echo $this->getdata(['theme','header','feature']);?>";
if ( (responsive === "cover" || responsive === "contain") && feature !== "feature" ) {
var widthpx = "<?php echo $this->getdata(['theme','site','width']);?>";
var width = widthpx.substr(0,widthpx.length-2);
var heightpx = "<?php echo $this->getdata(['theme','header','height']);?>";
var height = heightpx.substr(0,heightpx.length-2);
var ratio = width / height;
var feature = "<?php echo $this->getdata(['theme','header','feature']);?>";
if ( ($(window).width() / ratio) <= height) {
$("header").height( $(window).width() / ratio );
$("header").css("line-height", $(window).width() / ratio + "px");
}
}
}).trigger("resize");
};
core.start();
/**
* Confirmation de suppression
*/
$("#pageDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette page ?", function() {
$(location).attr("href", _this.attr("href"));
});
});
/**
* Calcul de la luminance relative d'une couleur
*/
core.relativeLuminanceW3C = function(rgba) {
// Conversion en sRGB
var RsRGB = rgba[0] / 255;
var GsRGB = rgba[1] / 255;
var BsRGB = rgba[2] / 255;
// Ajout de la transparence
var RsRGBA = rgba[3] * RsRGB + (1 - rgba[3]);
var GsRGBA = rgba[3] * GsRGB + (1 - rgba[3]);
var BsRGBA = rgba[3] * BsRGB + (1 - rgba[3]);
// Calcul de la luminance
var R = (RsRGBA <= .03928) ? RsRGBA / 12.92 : Math.pow((RsRGBA + .055) / 1.055, 2.4);
var G = (GsRGBA <= .03928) ? GsRGBA / 12.92 : Math.pow((GsRGBA + .055) / 1.055, 2.4);
var B = (BsRGBA <= .03928) ? BsRGBA / 12.92 : Math.pow((BsRGBA + .055) / 1.055, 2.4);
return .2126 * R + .7152 * G + .0722 * B;
};
$(document).ready(function(){
/**
* Affiche le sous-menu quand il est sticky
*/
$("nav").mouseenter(function(){
$("#navfixedlogout .navSub").css({ 'pointer-events' : 'auto' });
$("#navfixedconnected .navSub").css({ 'pointer-events' : 'auto' });
});
$("nav").mouseleave(function(){
$("#navfixedlogout .navSub").css({ 'pointer-events' : 'none' });
$("#navfixedconnected .navSub").css({ 'pointer-events' : 'none' });
});
/**
* Chargement paresseux des images et des iframes
*/
$("img,picture,iframe").attr("loading","lazy");
/**
* Effet accordéon
*/
$('.accordion').each(function(e) {
// on stocke l'accordéon dans une variable locale
var accordion = $(this);
// on récupère la valeur data-speed si elle existe
var toggleSpeed = accordion.attr('data-speed') || 100;
// fonction pour afficher un élément
function open(item, speed) {
// on récupère tous les éléments, on enlève l'élément actif de ce résultat, et on les cache
accordion.find('.accordion-item').not(item).removeClass('active')
.find('.accordion-content').slideUp(speed);
// on affiche l'élément actif
item.addClass('active')
.find('.accordion-content').slideDown(speed);
}
function close(item, speed) {
accordion.find('.accordion-item').removeClass('active')
.find('.accordion-content').slideUp(speed);
}
// on initialise l'accordéon, sans animation
open(accordion.find('.active:first'), 0);
// au clic sur un titre...
accordion.on('click', '.accordion-title', function(ev) {
ev.preventDefault();
// Masquer l'élément déjà actif
if ($(this).closest('.accordion-item').hasClass('active')) {
close($(this).closest('.accordion-item'), toggleSpeed);
} else {
// ...on lance l'affichage de l'élément, avec animation
open($(this).closest('.accordion-item'), toggleSpeed);
}
});
});
/**
* Icône du Menu Burger
*/
$("#toggle").click(function() {
var changeIcon = $('#toggle').children("span");
if ( $(changeIcon).hasClass('zwiico-menu') ) {
$(changeIcon).removeClass('zwiico-menu').addClass('zwiico-cancel');
}
else {
$(changeIcon).addClass('zwiico-menu');
};
});
/**
* Active le système d'aide interne
*
*/
$(".buttonHelp").click(function() {
$(".helpDisplayContent").slideToggle();
/**
if( $(".buttonHelp").css('opacity') > '0.75'){
$(".buttonHelp").css('opacity','0.5');
}
else{
$(".buttonHelp").css('opacity','1');
}
*/
});
$(".helpDisplayContent").click(function() {
$(".helpDisplayContent").slideToggle();
});
/**
* Remove ID Facebook from URL
*/
if(/^\?fbclid=/.test(location.search))
location.replace(location.href.replace(/\?fbclid.+/, ""));
/**
* No translate Lity close
*/
$(document).on('lity:ready', function(event, instance) {
$('.lity-close').addClass('notranslate');
});
/**
* Bouton screenshot
*/
var dataURL = {};
$('#screenshot').click(function() {
html2canvas(document.querySelector("#main_screenshot")).then(canvas => {
dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
contentType:"application/x-www-form-urlencoded",
url: "screenshot.php",
data: {
image: dataURL
},
dataType: "html"
});
});
});
});

View File

@ -0,0 +1,13 @@
<?php
/**
* Mises à jour suivant les versions de DeltaCMS
*/
if ($this->getData(['core', 'dataVersion']) < 3101) {
// Mise à jour
$this->setData(['core', 'dataVersion', 3101]);
}
?>

23
core/layout/blank.css Normal file
View File

@ -0,0 +1,23 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Éléments génériques
*/
body {
background : #FFF !important;
}

21
core/layout/blank.php Normal file
View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo self::$i18n;?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $this->showMetaTitle(); ?>
<?php $this->showMetaDescription(); ?>
<?php $this->showMetaType(); ?>
<?php $this->showMetaImage(); ?>
<?php $this->showFavicon(); ?>
<?php $this->showVendor(); ?>
<?php $this->showStyle(); ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/blank.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR.'custom.css'); ?>"></head>
<body>
<?php $this->showContent(); ?>
<?php $this->showScript(); ?>
</body>
</html>

1784
core/layout/common.css Normal file

File diff suppressed because it is too large Load Diff

28
core/layout/light.css Normal file
View File

@ -0,0 +1,28 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Éléments spécifiques
*/
/* Site */
#site {
max-width: 600px !important;
}
section {
min-height: 0px;
}

25
core/layout/light.php Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo self::$i18n;?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $this->showMetaTitle(); ?>
<?php $this->showMetaDescription(); ?>
<?php $this->showMetaType(); ?>
<?php $this->showMetaImage(); ?>
<?php $this->showFavicon(); ?>
<?php $this->showVendor(); ?>
<?php $this->showStyle(); ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/light.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR.'custom.css'); ?>">
</head>
<body>
<?php $this->showNotification(); ?>
<div id="site" class="container light">
<section><?php $this->showContent(); ?></section>
</div>
<?php $this->showScript(); ?>
</body>
</html>

138
core/layout/mail.php Normal file
View File

@ -0,0 +1,138 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="x-apple-disable-message-reformatting">
<title><?php echo $subject; ?></title>
<!--[if mso]>
<style>
* {
font-family: sans-serif !important;
}
</style>
<![endif]-->
<!--[if !mso]>
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<![endif]-->
<style>
html,
body {
margin: 0 auto !important;
padding: 0 !important;
height: 100% !important;
width: 100% !important;
}
* {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
div[style*="margin: 16px 0"] {
margin:0 !important;
}
table,
td {
mso-table-lspace: 0pt !important;
mso-table-rspace: 0pt !important;
}
table {
border-spacing: 0 !important;
border-collapse: collapse !important;
table-layout: fixed !important;
margin: 0 auto !important;
}
table table table {
table-layout: auto;
}
*[x-apple-data-detectors] {
color: inherit !important;
text-decoration: none !important;
}
.x-gmail-data-detectors,
.x-gmail-data-detectors *,
.aBn {
border-bottom: 0 !important;
cursor: default !important;
}
.a6S {
display: none !important;
opacity: 0.01 !important;
}
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
.email-container {
min-width: 375px !important;
}
}
</style>
</head>
<body width="100%" bgcolor="#EBEEF2" style="margin: 0; padding: 10px; mso-line-height-rule: exactly;">
<center style="width: 100%; background: #EBEEF2; text-align: left;">
<div style="display:none;font-size:1px;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;mso-hide:all;font-family: sans-serif;">
<?php echo $subject; ?>
</div>
<div style="max-width: 500px; margin: auto; margin-top: 30px; border: #aaa 1px solid;" class="email-container">
<!--[if mso]>
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="500" align="center">
<tr>
<td>
<![endif]-->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%" style="max-width: 500px;">
<tr>
<td bgcolor="#ffffff">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="border-bottom: 1px solid #EBEEF2; padding: 20px; font-family: 'Open Sans', sans-serif; font-size: 19px; line-height: 24px; text-align: center; color: #212223;">
<?php echo $this->getData(['locale', 'title']); ?>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%" style="max-width: 500px;">
<tr>
<td bgcolor="#ffffff">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="padding: 30px; font-family: 'Open Sans', sans-serif; font-size: 14px; line-height: 19px; color: #212223;">
<?php echo nl2br($content); ?>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%" style="max-width: 500px;">
<tr>
<td bgcolor="#ffffff">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="border-top: 1px solid #EBEEF2; padding: 20px; text-align: center; font-family: 'Open Sans', sans-serif; font-size: 12px; line-height: 17px; color: #212223;">
<a href="<?php echo helper::baseUrl(false); ?>" target="_blank">
<?php
if($this->getData(['module', $this->getUrl(0), 'config', 'signature' ]) === 'logo' && is_file( 'site/file/source/'. $this->getData(['module', $this->getUrl(0), 'config', 'logoUrl' ]))){
$imageFile = helper::baseUrl(false).'site/file/source/'. $this->getData(['module', $this->getUrl(0), 'config', 'logoUrl' ]) ;
$imageBase64 = base64_encode(file_get_contents($imageFile));
?><img src=" data:image/<?php echo pathinfo($imageFile, PATHINFO_EXTENSION); ?>;base64,<?php echo $imageBase64; ?>" border="0" width="<?php echo $this->getData(['module', $this->getUrl(0), 'config', 'logoWidth']) ?>%" >
<?php
}
else{
echo $this->getData(['locale', 'title']);
} ?>
</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!--[if mso]>
</td>
</tr>
</table>
<![endif]-->
</div>
</center>
</body>
</html>

229
core/layout/main.php Normal file
View File

@ -0,0 +1,229 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo self::$i18n;?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php $this->showMetaTitle(); ?>
<?php $this->showMetaDescription(); ?>
<?php $this->showMetaType(); ?>
<?php $this->showMetaImage(); ?>
<?php $this->showFavicon(); ?>
<?php $this->showVendor(); ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css');?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR.'custom.css'); ?>">
<!-- Détection RSS -->
<?php if ( ( $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
OR $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'news' )
AND $this->getData(['module', $this->getUrl(0), 'config', 'feeds']) === TRUE ): ?>
<link rel="alternate" type="application/rss+xml" href="'<?php echo helper::baseUrl(). $this->getUrl(0) . '/rss';?>" title="fLUX rss">
<?php endif; ?>
<?php $this->showStyle(); ?>
<?php if (file_exists(self::DATA_DIR .'head.inc.html')) {
include(self::DATA_DIR .'head.inc.html');
}?>
<?php if( $_SESSION['screenshot'] === 'on'){ ?>
<script src="./core/vendor/screenshot/html2canvas.min.js"></script>
<?php } ?>
</head>
<body>
<!-- Barre d'administration -->
<?php if($this->getUser('group') > self::GROUP_MEMBER): ?>
<?php $this->showBar(); ?>
<?php endif;?>
<!-- Notifications -->
<?php $this->showNotification(); ?>
<!-- Taille du Logo pour le menu burger -->
<?php $fileLogo = './site/file/source/'. $this->getData(['theme', 'menu', 'burgerLogo']);
if( $this->getData(['theme','menu','burgerContent']) === 'logo'
&& file_exists( $fileLogo)
&& $this->getData(['theme', 'menu', 'burgerLogo']) !== '' ){
$fontsize = $this->getData(['theme', 'text', 'fontSize']);
$pospx = strpos($fontsize, 'px');
$fontsize = (int) substr( $fontsize, 0, $pospx);
$height = $this->getData(['theme', 'menu', 'height']);
$pospx = strpos($height, 'px');
$height = (int) substr( $height, 0, $pospx);
$heightLogo = 2*($height + $fontsize) - 4;
$arrayImage = getimagesize( $fileLogo );
$heightImage = $arrayImage[1];
$widthImage = $arrayImage[0];
if( $heightImage !== 0 && $heightImage !== null){
$widthLogo = (int) ($widthImage * ( ($heightLogo - 1) / $heightImage));
}
else
{
$widthLogo = 30;
}
} ?>
<!-- div screenshot -->
<?php if( $_SESSION['screenshot'] === 'on'){ ?>
<div id="main_screenshot">
<?php } ?>
<!-- Menu dans le fond du site avant la bannière -->
<?php if($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top' ): ?>
<!-- Détermine si le menu est fixe en haut de page lorsque l'utilisateur n'est pas connecté -->
<?php
if ( $this->getData(['theme', 'menu', 'position']) === 'top'
AND $this->getData(['theme', 'menu', 'fixed']) === true
AND $this->getUser('password') === $this->getInput('DELTA_USER_PASSWORD')
AND $this->getUser('group') > self::GROUP_MEMBER) {
echo '<nav id="navfixedconnected" >';
} else {
echo '<nav id="navfixedlogout" >';
}
?>
<!-- Menu Burger -->
<div id="toggle">
<?php echo $this->getData(['theme','menu','burgerContent']) === 'title' ? '<div class="notranslate" id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : '' ;?>
<?php echo $this->getData(['theme','menu','burgerContent']) === 'logo' ? '<div class="notranslate" id="burgerLogo"><img src="'. $fileLogo .'" width="'. $widthLogo.'" height="'. $heightLogo .'"></div>' : '' ;?>
<?php echo template::ico('menu',null,null,'2em'); ?></div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'position']) === 'top' ? 'class="container-large"' : 'class="container"';
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?> >
<?php $this->showMenu(); ?>
</div> <!--fin menu -->
</nav>
<?php endif; ?>
<!-- Bannière dans le fond du site -->
<?php if($this->getData(['theme', 'header', 'position']) === 'body'): ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
$headerClass .= $this->getData(['theme', 'header', 'wide']) === 'none' ? '' : 'container';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"';?>>
<?php echo ($this->getData(['theme','header','linkHomePage']) && $this->getData(['theme','header','feature']) === 'wallpaper' ) ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php if ($this->getData(['theme','header','feature']) === 'wallpaper' ): ?>
<?php if(
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
OR ($this->getUrl(0) === 'theme' AND $this->getUrl(1) === 'header')
): ?>
<span class="notranslate" id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else: ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else: ?>
<div id="featureContent">
<?php echo $this->getData(['theme','header','featureContent']);?>
</div>
<?php endif; ?>
</header>
<?php echo ( $this->getData(['theme','header','linkHomePage']) && $this->getData(['theme','header','feature']) === 'wallpaper' ) ? '</a>' : ''; ?>
<?php endif; ?>
<!-- Menu dans le fond du site après la bannière -->
<?php if($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?>
<nav>
<!-- Menu burger -->
<div id="toggle">
<?php echo $this->getData(['theme','menu','burgerContent']) === 'title' ? '<div class="notranslate" id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : '' ;?>
<?php echo $this->getData(['theme','menu','burgerContent']) === 'logo' ? '<div class="notranslate" id="burgerLogo"><img src="'. $fileLogo .'" width="'. $widthLogo.'" height="'. $heightLogo .'"></div>' : '' ;?>
<?php echo template::ico('menu',null,null,'2em'); ?></div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?> >
<?php $this->showMenu(); ?></div>
</nav>
<?php endif; ?>
<!-- Site -->
<div id="site" class="container">
<?php if($this->getData(['theme', 'menu', 'position']) === 'site-first'): ?>
<!-- Menu dans le site avant la bannière -->
<nav>
<div id="toggle">
<?php echo $this->getData(['theme','menu','burgerContent']) === 'title' ? '<div class="notranslate" id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : '' ;?>
<?php echo $this->getData(['theme','menu','burgerContent']) === 'logo' ? '<div class="notranslate" id="burgerLogo"><img src="'. $fileLogo .'" width="'. $widthLogo.'" height="'. $heightLogo .'"></div>' : '' ;?>
<?php echo template::ico('menu',null,null,'2em'); ?></div>
<div id="menu" class="container"><?php $this->showMenu(); ?></div>
</nav>
<?php endif; ?>
<?php if(
$this->getData(['theme', 'header', 'position']) === 'site'
// Affiche toujours la bannière pour l'édition du thème
OR (
$this->getData(['theme', 'header', 'position']) === 'hide'
AND $this->getUrl(0) === 'theme'
)
): ?>
<!-- Bannière dans le site -->
<?php echo ( $this->getData(['theme','header','linkHomePage']) && $this->getData(['theme','header','feature']) === 'wallpaper' ) ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"';?>>
<?php if ($this->getData(['theme','header','feature']) === 'wallpaper' ): ?>
<?php if(
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
OR ($this->getUrl(0) === 'theme' AND $this->getUrl(1) === 'header')
): ?>
<span class="notranslate" id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else: ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else: ?>
<div id="featureContent">
<?php echo $this->getData(['theme','header','featureContent']);?>
</diV>
<?php endif; ?>
</header>
<?php echo ( $this->getData(['theme','header','linkHomePage']) && $this->getData(['theme','header','feature']) === 'wallpaper' ) ? '</a>' : ''; ?>
<?php endif; ?>
<?php if(
$this->getData(['theme', 'menu', 'position']) === 'site-second' ||
$this->getData(['theme', 'menu', 'position']) === 'site'
// Affiche toujours le menu pour l'édition du thème
OR (
$this->getData(['theme', 'menu', 'position']) === 'hide'
AND $this->getUrl(0) === 'theme'
)
): ?>
<!-- Menu dans le site après la bannière -->
<nav <?php if($this->getData(['theme', 'menu', 'position']) === 'hide'): ?>class="displayNone"<?php endif; ?>>
<div id="toggle">
<?php echo $this->getData(['theme','menu','burgerContent']) === 'title' ? '<div class="notranslate" id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : '' ;?>
<?php echo $this->getData(['theme','menu','burgerContent']) === 'logo' ? '<div class="notranslate" id="burgerLogo"><img src="'. $fileLogo .'" width="'. $widthLogo.'" height="'. $heightLogo .'"></div>' : '' ;?>
<?php echo template::ico('menu',null,null,'2em'); ?></div>
<div id="menu" class="container"><?php $this->showMenu(); ?></div>
</nav>
<?php endif; ?>
<!-- Corps de page -->
<?php $this->showSection();?>
<!-- footer -->
<?php $this->showFooter();?>
<!-- Fin du site -->
<?php echo $this->getData(['theme', 'footer', 'position']) === 'site'? '</div>' : '';?>
<!-- fin de la div main_screenshot et bouton screenshot -->
<?php if( $_SESSION['screenshot'] === 'on'){ ?>
</div>
<div><button id="screenshot" class="buttonScreenshot" type="button" ><img src="<?php echo helper::baseUrl(false); ?>core/vendor/screenshot/appareil_photo.png" width="100px"/></button></div>
<?php } ?>
<!-- Lien remonter en haut -->
<div id="backToTop"><?php echo template::ico('up'); ?></div>
<!-- Affichage du consentement aux cookies-->
<?php $this->showCookies(); ?>
<!-- Les scripts -->
<?php $this->showScript();?>
</body>
</html>

591
core/module/addon/addon.php Normal file
View File

@ -0,0 +1,591 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class addon extends common {
public static $actions = [
'index' => self::GROUP_ADMIN,
'delete' => self::GROUP_ADMIN,
'export' => self::GROUP_ADMIN,
'import' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN,
'upload' => self::GROUP_ADMIN,
'uploadItem'=> self::GROUP_ADMIN
];
// URL des modules
const BASEURL_STORE = 'https://store.deltacms.fr/';
const MODULE_STORE = '?modules/';
// Gestion des modules
public static $modInstal = [];
// pour tests
public static $valeur = [];
// le catalogue
public static $storeList = [];
public static $storeItem = [];
/*
* Effacement d'un module installé et non utilisé
*/
public function delete() {
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon',
'state' => false,
'notification' => 'Action non autorisée'
]);
}
else{
// Suppression des dossiers
$infoModules = helper::getModules();
$module = $this->getUrl(2);
//Liste des dossiers associés au module non effacés
if( $this->removeDir('./module/'.$module ) === true ){
$success = true;
$notification = 'Module '. $module .' désinstallé';
if( is_dir($infoModules[$this->getUrl(2)]['dataDirectory']) ) {
if (!$this->removeDir($infoModules[$this->getUrl(2)]['dataDirectory'])){
$notification = 'Module '.$module .' désinstallé, il reste des données dans ' . $infoModules[$this->getUrl(2)]['dataDirectory'];
}
}
}
else{
$success = false;
$notification = 'La suppression a échouée';
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon',
'notification' => $notification,
'state' => $success
]);
}
}
/***
* Installation d'un module
* Fonction utilisée par upload et storeUpload
*/
private function install ($moduleName, $checkValid){
$tempFolder = 'datamodules';//uniqid();
$zip = new ZipArchive();
if ($zip->open($moduleName) === TRUE) {
$notification = 'Archive ouverte';
mkdir (self::TEMP_DIR . $tempFolder, 0755);
$zip->extractTo(self::TEMP_DIR . $tempFolder );
// Archive de module ?
$success = false;
$notification = 'Ce n\'est pas l\'archive d\'un module !';
$moduleDir = self::TEMP_DIR . $tempFolder . '/module';
$moduleName = '';
if ( is_dir( $moduleDir )) {
// Lire le nom du module
if ($dh = opendir( $moduleDir )) {
while ( false !== ($file = readdir($dh)) ) {
if ($file != "." && $file != "..") {
$moduleName = $file;
}
}
closedir($dh);
}
// Module normalisé ?
if( is_file( $moduleDir.'/'.$moduleName.'/'.$moduleName.'.php' ) AND is_file( $moduleDir.'/'.$moduleName.'/view/index/index.php' ) ){
// Lecture de la version et de la validation d'update du module pour validation de la mise à jour
// Pour une version <= version installée l'utilisateur doit cocher 'Mise à jour forcée'
$version = '0.0';
$update = '0.0';
$valUpdate = false;
$file = file_get_contents( $moduleDir.'/'.$moduleName.'/'.$moduleName.'.php');
$file = str_replace(' ','',$file);
$file = str_replace("\t",'',$file);
$pos1 = strpos($file, 'constVERSION');
if( $pos1 !== false){
$posdeb = strpos($file, "'", $pos1);
$posend = strpos($file, "'", $posdeb + 1);
$version = substr($file, $posdeb + 1, $posend - $posdeb - 1);
}
$pos1 = strpos($file, 'constUPDATE');
if( $pos1 !== false){
$posdeb = strpos($file, "'", $pos1);
$posend = strpos($file, "'", $posdeb + 1);
$update = substr($file, $posdeb + 1, $posend - $posdeb - 1);
}
// Si version actuelle >= version indiquée dans UPDATE la mise à jour est validée
$infoModules = helper::getModules();
if( $infoModules[$moduleName]['update'] >= $update ) $valUpdate = true;
// Module déjà installé ?
$moduleInstal = false;
foreach($infoModules as $key=>$value ){
if($moduleName === $key){
$moduleInstal = true;
}
}
// Validation de la maj si autorisation du concepteur du module ET
// ( Version plus récente OU Check de forçage )
$valNewVersion = floatval($version);
$valInstalVersion = floatval( $infoModules[$moduleName]['version'] );
$newVersion = false;
if( $valNewVersion > $valInstalVersion ) $newVersion = true;
$validMaj = $valUpdate && ( $newVersion || $checkValid);
// Nouvelle installation ou mise à jour du module
if( ! $moduleInstal || $validMaj ){
// Copie récursive des dossiers
$this->copyDir( self::TEMP_DIR . $tempFolder, './' );
$success = true;
if( ! $moduleInstal ){
$notification = 'Module '.$moduleName.' installé';
}
else{
$notification = 'Module '.$moduleName.' mis à jour';
}
}
else{
$success = false;
if( $valNewVersion == $valInstalVersion){
$notification = ' Version détectée '.$version.' = à celle installée '.$infoModules[$moduleName]['version'];
}
else{
$notification = ' Version détectée '.$version.' < à celle installée '.$infoModules[$moduleName]['version'];
}
if( $valUpdate === false){
if( $infoModules[$moduleName]['update'] === $update ){
$notification = ' Mise à jour par ce procédé interdite par le concepteur du module';
}
else{
$notification = ' Mise à jour par ce procédé interdite, votre version est trop ancienne';
}
}
}
}
}
// Supprimer le dossier temporaire même si le module 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
]);
}
/***
* Installation d'un module à partir du gestionnaire de fichier
*/
public function upload() {
// Soumission du formulaire
if($this->isPost()) {
// Installation d'un module
$checkValidMaj = $this->getInput('configModulesCheck', helper::FILTER_BOOLEAN);
$zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
if( $zipFilename !== ''){
$success = [
'success' => false,
'notification'=> ''
];
$state = $this->install(self::FILE_DIR.'source/'.$zipFilename, $checkValidMaj);
}
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(),
'notification' => $state['notification'],
'state' => $state['success']
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Installer un module',
'view' => 'upload'
]);
}
/***
* Installation d'un module par le catalogue
*/
public function uploadItem() {
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'store',
'state' => false,
'notification' => 'Action non autorisée'
]);
} else {
// Récupérer le module en ligne
$moduleName = $this->getUrl(2);
// Informations sur les module en ligne
$store = json_decode(helper::urlGetContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
// Url du module à télécharger
$moduleFilePath = $store[$moduleName]['file'];
// Télécharger le fichier
$moduleData = helper::urlGetContents(self::BASEURL_STORE . self::FILE_DIR . 'source/' . $moduleFilePath);
// Extraire de l'arborescence
$d = explode('/',$moduleFilePath);
$moduleFile = $d[count($d)-1];
// Créer le dossier modules
if (!is_dir(self::FILE_DIR . 'source/modules')) {
mkdir (self::FILE_DIR . 'source/modules', 0755);
}
// Sauver les données du fichiers
file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
/**
* $if( $moduleFile !== ''){
* $success = [
* 'success' => false,
* 'notification'=> ''
* ];
* $state = $this->install(self::FILE_DIR.'source/modules/'.$moduleFile, false);
*}
*/
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon/store',
'notification' => $moduleFile . ' téléchargé dans le dossier modules du gestionnaire de fichiers',
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Catalogue de modules',
'view' => 'store'
]);
}
/**
* Catalogue des modules sur le site DeltaCMS.fr
*/
public function store() {
$store = json_decode(helper::urlGetContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
if ($store) {
// Modules installés
$infoModules = helper::getModules();
// Clés moduleIds dans les pages
$inPages = helper::arrayCollumn($this->getData(['page']),'moduleId', 'SORT_DESC');
foreach( $inPages as $key=>$value){
$inPagesTitle[ $this->getData(['page', $key, 'title' ]) ] = $value;
}
// Parcourir les données des modules
foreach ($store as $key=>$value) {
// Module non installé
$ico = template::ico('download');
$class = '';
// Le module est installé
if (array_key_exists($key,$infoModules) === true) {
$class = 'buttonGreen';
$ico = template::ico('update');
}
// Le module est installé et utilisé
if (in_array($key,$inPages) === true) {
$class = 'buttonRed';
$ico = template::ico('update');
}
self::$storeList [] = [
$store[$key]['category'],
'<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >'.$store[$key]['title'].'</a>',
$store[$key]['version'],
mb_detect_encoding(strftime('%d %B %Y', $store[$key]['versionDate']), 'UTF-8', true)
? strftime('%d %B %Y', $store[$key]['versionDate'])
: utf8_encode(strftime('%d %B %Y', $store[$key]['versionDate'])),
implode(', ', array_keys($inPagesTitle,$key)),
template::button('moduleExport' . $key, [
'class' => $class,
'href' => helper::baseUrl(). $this->getUrl(0) . '/uploadItem/' . $key.'/' . $_SESSION['csrf'],// appel de fonction vaut exécution, utiliser un paramètre
'value' => $ico
])
];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Catalogue de modules en ligne',
'view' => 'store'
]);
}
/**
* Détail d'un objet du catalogue
*/
public function item() {
$store = json_decode(helper::urlGetContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
self::$storeItem = $store [$this->getUrl(2)] ;
self::$storeItem ['fileDate'] = mb_detect_encoding(strftime('%d %B %Y',self::$storeItem ['fileDate']), 'UTF-8', true)
? strftime('%d %B %Y', self::$storeItem ['fileDate'])
: utf8_encode(strftime('%d %B %Y', self::$storeItem ['fileDate']));
// Valeurs en sortie
$this->addOutput([
'title' =>'Module ' . self::$storeItem['title'],
'view' => 'item'
]);
}
/**
* Gestion des modules
*/
public function index() {
// Lister les modules
// $infoModules[nom_module]['realName'], ['version'], ['update'], ['delete'], ['dataDirectory']
$infoModules = helper::getModules();
// Clés moduleIds dans les pages
$inPages = helper::arrayCollumn($this->getData(['page']),'moduleId', 'SORT_DESC');
foreach( $inPages as $key=>$value){
$inPagesTitle[ $this->getData(['page', $key, 'title' ]) ] = $value;
}
// Parcourir les données des modules
foreach ($infoModules as $key=>$value) {
// Construire le tableau de sortie
self::$modInstal[] = [
$key,
$infoModules[$key]['realName'],
$infoModules[$key]['version'],
implode(', ', array_keys($inPagesTitle,$key)),
//|| ('delete',$infoModules[$key]) && $infoModules[$key]['delete'] === true && implode(', ',array_keys($inPages,$key)) === ''
$infoModules[$key]['delete'] === true && implode(', ',array_keys($inPages,$key)) === ''
? template::button('moduleDelete' . $key, [
'class' => 'moduleDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('cancel')
])
: '',
implode(', ',array_keys($inPages,$key)) !== ''
? template::button('moduleExport' . $key, [
'href' => helper::baseUrl(). $this->getUrl(0) . '/export/' . $key . '/' . $_SESSION['csrf'],// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download')
])
: '',
implode(', ',array_keys($inPages,$key)) === ''
? template::button('moduleExport' . $key, [
'href' => helper::baseUrl(). $this->getUrl(0) . '/import/' . $key . '/' . $_SESSION['csrf'],// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('upload')
])
: ''
];
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Gestion des modules',
'view' => 'index'
]);
}
/*
* Export des données d'un module externes ou interne à module.json
*/
public function export(){
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon',
'state' => false,
'notification' => 'Action non autorisée'
]);
}
else {
// Lire les données du module
$infoModules = helper::getModules();
// Créer un dossier par défaut
$tmpFolder = self::TEMP_DIR . uniqid();
//$tmpFolder = self::TEMP_DIR . 'test';
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
// Clés moduleIds dans les pages
$inPages = helper::arrayCollumn($this->getData(['page']),'moduleId', 'SORT_DESC');
// Parcourir les pages utilisant le module
foreach (array_keys($inPages,$this->getUrl(2)) as $pageId) {
// Export des pages hébergeant le module
$pageParam[$pageId] = $this->getData(['page',$pageId]);
// Export du contenu de la page
//$pageContent[$pageId] = file_get_contents(self::DATA_DIR . self::$i18n . '/content/' . $this->getData(['page', $pageId, 'content']));
$pageContent[$pageId] = $this->getPage($pageId, self::$i18n);
// Export de fr/module.json
$moduleId = 'fr/module.json';
$moduleDir = str_replace('site/data/','',$infoModules[$this->getUrl(2)]['dataDirectory']);
// Création de l'arborescence des langues
// Pas de nom dossier de langue - dossier par défaut
$t = explode ('/',$moduleId);
if ( is_array($t)) {
$lang = 'fr';
} else {
$lang = $t[0];
}
// Créer le dossier temporaire si inexistant sinon le nettoie et le créer
if (!is_dir($tmpFolder . '/' . $lang)) {
mkdir ($tmpFolder . '/' . $lang, 0755, true);
} else {
$this->removeDir($tmpFolder . '/' . $lang);
mkdir ($tmpFolder . '/' . $lang, 0755, true);
}
// Créer le dossier temporaire des données du module
if ($infoModules[$this->getUrl(2)]['dataDirectory']) {
if (!is_dir($tmpFolder . '/' . $moduleDir)) {
mkdir ($tmpFolder . '/' . $moduleDir, 0755, true) ;
}
}
// Sauvegarde si données non vides
$tmpData [$pageId] = $this->getData(['module',$pageId ]);
if ($tmpData [$pageId] !== null) {
file_put_contents($tmpFolder . '/' . $moduleId, json_encode($tmpData));
}
// Export des données localisées dans le dossier de données du module
if ($infoModules[$this->getUrl(2)]['dataDirectory'] &&
is_dir($infoModules[$this->getUrl(2)]['dataDirectory'])) {
$this->copyDir ($infoModules[$this->getUrl(2)]['dataDirectory'], $tmpFolder . '/' . $moduleDir);
}
}
// Enregistrement des pages dans le dossier de langue identique à module
if (!file_exists($tmpFolder . '/' . $lang . '/page.json')) {
file_put_contents($tmpFolder . '/' . $lang . '/page.json', json_encode($pageParam));
mkdir ($tmpFolder . '/' . $lang . '/content', 0755);
file_put_contents($tmpFolder . '/' . $lang . '/content/' . $this->getData(['page', $pageId, 'content']), $pageContent);
}
// création du zip
$fileName = $this->getUrl(2) . '.zip';
$this->makeZip ($fileName, $tmpFolder, []);
if (file_exists($fileName)) {
ob_start();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile( $fileName);
unlink($fileName);
$this->removeDir($tmpFolder);
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon',
'notification' => 'Quelque chose s\'est mal passé',
'state' => false
]);
}
}
}
/*
* Importer des données d'un module externes ou interne à module.json
*/
public function import(){
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon',
'state' => false,
'notification' => 'Action non autorisée'
]);
}
else {
// Soumission du formulaire
if($this->isPost()) {
// Récupérer le fichier et le décompacter
$zipFilename = $this->getInput('addonImportFile', helper::FILTER_STRING_SHORT, true);
$tempFolder = uniqid();
mkdir (self::TEMP_DIR . $tempFolder, 0755);
$zip = new ZipArchive();
if ($zip->open(self::FILE_DIR . 'source/' . $zipFilename) === TRUE) {
$zip->extractTo(self::TEMP_DIR . $tempFolder );
}
// Import des données localisées page.json et module.json
// Pour chaque dossier localisé
$dataTarget = array();
$dataSource = array();
// Liste des pages de même nom dans l'archive et le site
$list = '';
foreach (self::$i18nList as $key=>$value) {
// Les Pages et les modules
foreach (['page','module'] as $fileTarget){
if (file_exists(self::TEMP_DIR . $tempFolder . '/' .$key . '/' . $fileTarget . '.json')) {
// Le dossier de langue existe
// faire la fusion
$dataSource = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . '/' .$key . '/' . $fileTarget . '.json'), true);
// Des pages de même nom que celles de l'archive existent
if( $fileTarget === 'page' ){
foreach( $dataSource as $keydataSource=>$valuedataSource ){
foreach( $this->getData(['page']) as $keypage=>$valuepage ){
if( $keydataSource === $keypage){
$list === '' ? $list .= ' '.$this->getData(['page', $keypage, 'title']) : $list .= ', '.$this->getData(['page', $keypage, 'title']);
}
}
}
}
$dataTarget = json_decode(file_get_contents(self::DATA_DIR . $key . '/' . $fileTarget . '.json'), true);
$data [$fileTarget] = array_merge($dataTarget[$fileTarget], $dataSource);
if( $list === ''){
file_put_contents(self::DATA_DIR . '/' .$key . '/' . $fileTarget . '.json', json_encode( $data ,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX) );
}
// copie du contenu de la page
$this->copyDir (self::TEMP_DIR . $tempFolder . '/' .$key . '/content', self::DATA_DIR . '/' .$key . '/content');
// Supprimer les fichiers importés
unlink (self::TEMP_DIR . $tempFolder . '/' .$key . '/' . $fileTarget . '.json');
}
}
}
// Import des fichiers placés ailleurs que dans les dossiers localisés.
$this->copyDir (self::TEMP_DIR . $tempFolder,self::DATA_DIR );
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
if( $list !== '' ){
$success = false;
strpos( $list, ',') === false ? $notification = 'Import impossible la page suivante doit être renommée :'.$list : $notification = 'Import impossible les pages suivantes doivent être renommées :'.$list;
}
else{
$success = true;
$notification = 'Import réussi';
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'addon',
'state' => $success,
'notification' => $notification
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Importer des données de module',
'view' => 'import'
]);
}
}
}

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,31 @@
<?php echo template::formOpen('addonImportForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('addonImportBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'addon',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('addonImportSubmit', [
'value' => 'Appliquer'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Installer des données de module</h4>
<div class="row">
<div class="col6 offset3">
<?php echo template::file('addonImportFile', [
'label' => 'Archive ZIP :',
'type' => 2
]); ?>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,25 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Confirmation de suppression
*/
$(".moduleDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer ce module ?", function() {
$(location).attr("href", _this.attr("href"));
});
});

View File

@ -0,0 +1,31 @@
<div class="row">
<div class="col2">
<?php echo template::button('configModulesBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(),
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configModulesHelp', [
'href' => 'https://doc.deltacms.fr/gestion-des-modules',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset6">
<?php echo template::button('configStoreUpload', [
'href' => helper::baseUrl() . 'addon/upload',
'value' => 'Installer un module'
]); ?>
</div>
</div>
<?php if($module::$modInstal): ?>
<?php echo template::table([2, 2, 2, 2, 1, 1, 1], $module::$modInstal, ['Module installé', 'Alias', 'Version', 'Page(s)', 'Supprimer', 'Exporter', 'Importer']); ?>
<?php else: ?>
<?php echo template::speech('Aucun module installé.'); ?>
<?php endif; ?>

View File

@ -0,0 +1,16 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/

View File

@ -0,0 +1,41 @@
<div class="row">
<div class="col9">
<div class="row">
<div class="col12">
<?php echo $module::$storeItem['content']; ?>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<?php
echo '<img class="downloadItemPicture" src="' . $module::BASEURL_STORE . 'site/file/source/' . $module::$storeItem['picture'] .
'" alt="' . $module::$storeItem['picture'] . '">';
?>
</div>
</div>
<div class="row">
<div class="col12 textAlignCenter">
<?php echo 'Version n°' . $module::$storeItem['fileVersion']; ?>
</div>
</div>
<div class="row">
<div class="col12 textAlignCenter">
<?php echo ' du ' . $module::$storeItem['fileDate']; ?>
</div>
</div>
<div class="row">
<div class="col12 textAlignCenter">
<span>Auteur :
<?php echo $module::$storeItem['fileAuthor']; ?>
</span>
</div>
</div>
<div class="row">
<div class="col12 textAlignCenter">
<span>Licence :
<?php echo $module::$storeItem['fileLicense']; ?>
</span>
</div>
</div>
</div>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,15 @@
<div class="row">
<div class="col2">
<?php echo template::button('configStoreBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'addon/upload',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
</div>
<?php if($module::$storeList): ?>
<?php echo template::table([2, 2, 1, 2, 2, 2, 1], $module::$storeList, ['Catégorie', 'Module', 'Version', 'Date', 'Pages', 'Télécharger']); ?>
<?php else: ?>
<?php echo template::speech('Le catalogue est vide.'); ?>
<?php endif; ?>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,58 @@
<?php echo template::formOpen('configModulesUpload'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configModulesBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'addon',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('addonIndexHelp', [
'href' => 'https://doc.deltacms.fr/installer-un-module',
'target' => '_blank',
'class' => 'buttonHelp',
'ico' => 'help',
'value' => 'Aide'
]); ?>
</div>
<!-- Catalogue en ligne hors service
<div class="col2 ">
<?php echo template::button('configModulesStore', [
'href' => helper::baseUrl() . 'addon/store',
'value' => 'Catalogue en ligne'
]); ?>
</div>
-->
<div class="col2 offset6">
<?php echo template::submit('configModulesSubmit',[
'value' => 'Valider',
'ico' => 'check'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Installer ou mettre à jour un module téléchargé </h4>
<div class="row">
<div class="col6 offset3">
<?php echo template::file('configModulesInstallation', [
'label' => 'Archive ZIP :',
'type' => 2
]); ?>
</div>
</div>
<div class="row">
<div class="col4 offset3">
<?php echo template::checkbox('configModulesCheck', true, 'Mise à jour forcée', [
'checked' => false,
'help' => 'Permet de forcer une mise à jour même si la version du module est inférieure ou égale à celle du module installé.',
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,843 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class config extends common {
public static $actions = [
'backup' => self::GROUP_ADMIN,
'copyBackups'=> self::GROUP_ADMIN,
'configOpenGraph' => self::GROUP_ADMIN,
'generateFiles' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN,
'restore' => self::GROUP_ADMIN,
'updateBaseUrl' => self::GROUP_ADMIN,
'script' => self::GROUP_ADMIN,
'logReset' => self::GROUP_ADMIN,
'logDownload'=> self::GROUP_ADMIN,
'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN,
];
public static $timezones = [
'Pacific/Midway' => '(GMT-11:00) Midway Island',
'US/Samoa' => '(GMT-11:00) Samoa',
'US/Hawaii' => '(GMT-10:00) Hawaii',
'US/Alaska' => '(GMT-09:00) Alaska',
'US/Pacific' => '(GMT-08:00) Pacific Time (US &amp; Canada)',
'America/Tijuana' => '(GMT-08:00) Tijuana',
'US/Arizona' => '(GMT-07:00) Arizona',
'US/Mountain' => '(GMT-07:00) Mountain Time (US &amp; Canada)',
'America/Chihuahua' => '(GMT-07:00) Chihuahua',
'America/Mazatlan' => '(GMT-07:00) Mazatlan',
'America/Mexico_City' => '(GMT-06:00) Mexico City',
'America/Monterrey' => '(GMT-06:00) Monterrey',
'Canada/Saskatchewan' => '(GMT-06:00) Saskatchewan',
'US/Central' => '(GMT-06:00) Central Time (US &amp; Canada)',
'US/Eastern' => '(GMT-05:00) Eastern Time (US &amp; Canada)',
'US/East-Indiana' => '(GMT-05:00) Indiana (East)',
'America/Bogota' => '(GMT-05:00) Bogota',
'America/Lima' => '(GMT-05:00) Lima',
'America/Caracas' => '(GMT-04:30) Caracas',
'Canada/Atlantic' => '(GMT-04:00) Atlantic Time (Canada)',
'America/La_Paz' => '(GMT-04:00) La Paz',
'America/Santiago' => '(GMT-04:00) Santiago',
'Canada/Newfoundland' => '(GMT-03:30) Newfoundland',
'America/Buenos_Aires' => '(GMT-03:00) Buenos Aires',
'Greenland' => '(GMT-03:00) Greenland',
'Atlantic/Stanley' => '(GMT-02:00) Stanley',
'Atlantic/Azores' => '(GMT-01:00) Azores',
'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.',
'Africa/Casablanca' => '(GMT) Casablanca',
'Europe/Dublin' => '(GMT) Dublin',
'Europe/Lisbon' => '(GMT) Lisbon',
'Europe/London' => '(GMT) London',
'Africa/Monrovia' => '(GMT) Monrovia',
'Europe/Amsterdam' => '(GMT+01:00) Amsterdam',
'Europe/Belgrade' => '(GMT+01:00) Belgrade',
'Europe/Berlin' => '(GMT+01:00) Berlin',
'Europe/Bratislava' => '(GMT+01:00) Bratislava',
'Europe/Brussels' => '(GMT+01:00) Brussels',
'Europe/Budapest' => '(GMT+01:00) Budapest',
'Europe/Copenhagen' => '(GMT+01:00) Copenhagen',
'Europe/Ljubljana' => '(GMT+01:00) Ljubljana',
'Europe/Madrid' => '(GMT+01:00) Madrid',
'Europe/Paris' => '(GMT+01:00) Paris',
'Europe/Prague' => '(GMT+01:00) Prague',
'Europe/Rome' => '(GMT+01:00) Rome',
'Europe/Sarajevo' => '(GMT+01:00) Sarajevo',
'Europe/Skopje' => '(GMT+01:00) Skopje',
'Europe/Stockholm' => '(GMT+01:00) Stockholm',
'Europe/Vienna' => '(GMT+01:00) Vienna',
'Europe/Warsaw' => '(GMT+01:00) Warsaw',
'Europe/Zagreb' => '(GMT+01:00) Zagreb',
'Europe/Athens' => '(GMT+02:00) Athens',
'Europe/Bucharest' => '(GMT+02:00) Bucharest',
'Africa/Cairo' => '(GMT+02:00) Cairo',
'Africa/Harare' => '(GMT+02:00) Harare',
'Europe/Helsinki' => '(GMT+02:00) Helsinki',
'Europe/Istanbul' => '(GMT+02:00) Istanbul',
'Asia/Jerusalem' => '(GMT+02:00) Jerusalem',
'Europe/Kiev' => '(GMT+02:00) Kyiv',
'Europe/Minsk' => '(GMT+02:00) Minsk',
'Europe/Riga' => '(GMT+02:00) Riga',
'Europe/Sofia' => '(GMT+02:00) Sofia',
'Europe/Tallinn' => '(GMT+02:00) Tallinn',
'Europe/Vilnius' => '(GMT+02:00) Vilnius',
'Asia/Baghdad' => '(GMT+03:00) Baghdad',
'Asia/Kuwait' => '(GMT+03:00) Kuwait',
'Europe/Moscow' => '(GMT+03:00) Moscow',
'Africa/Nairobi' => '(GMT+03:00) Nairobi',
'Asia/Riyadh' => '(GMT+03:00) Riyadh',
'Europe/Volgograd' => '(GMT+03:00) Volgograd',
'Asia/Tehran' => '(GMT+03:30) Tehran',
'Asia/Baku' => '(GMT+04:00) Baku',
'Asia/Muscat' => '(GMT+04:00) Muscat',
'Asia/Tbilisi' => '(GMT+04:00) Tbilisi',
'Asia/Yerevan' => '(GMT+04:00) Yerevan',
'Asia/Kabul' => '(GMT+04:30) Kabul',
'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg',
'Asia/Karachi' => '(GMT+05:00) Karachi',
'Asia/Tashkent' => '(GMT+05:00) Tashkent',
'Asia/Kolkata' => '(GMT+05:30) Kolkata',
'Asia/Kathmandu' => '(GMT+05:45) Kathmandu',
'Asia/Almaty' => '(GMT+06:00) Almaty',
'Asia/Dhaka' => '(GMT+06:00) Dhaka',
'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk',
'Asia/Bangkok' => '(GMT+07:00) Bangkok',
'Asia/Jakarta' => '(GMT+07:00) Jakarta',
'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk',
'Asia/Chongqing' => '(GMT+08:00) Chongqing',
'Asia/Hong_Kong' => '(GMT+08:00) Hong Kong',
'Asia/Irkutsk' => '(GMT+08:00) Irkutsk',
'Asia/Kuala_Lumpur' => '(GMT+08:00) Kuala Lumpur',
'Australia/Perth' => '(GMT+08:00) Perth',
'Asia/Singapore' => '(GMT+08:00) Singapore',
'Asia/Taipei' => '(GMT+08:00) Taipei',
'Asia/Ulaanbaatar' => '(GMT+08:00) Ulaan Bataar',
'Asia/Urumqi' => '(GMT+08:00) Urumqi',
'Asia/Seoul' => '(GMT+09:00) Seoul',
'Asia/Tokyo' => '(GMT+09:00) Tokyo',
'Asia/Yakutsk' => '(GMT+09:00) Yakutsk',
'Australia/Adelaide' => '(GMT+09:30) Adelaide',
'Australia/Darwin' => '(GMT+09:30) Darwin',
'Australia/Brisbane' => '(GMT+10:00) Brisbane',
'Australia/Canberra' => '(GMT+10:00) Canberra',
'Pacific/Guam' => '(GMT+10:00) Guam',
'Australia/Hobart' => '(GMT+10:00) Hobart',
'Australia/Melbourne' => '(GMT+10:00) Melbourne',
'Pacific/Port_Moresby' => '(GMT+10:00) Port Moresby',
'Australia/Sydney' => '(GMT+10:00) Sydney',
'Asia/Vladivostok' => '(GMT+10:00) Vladivostok',
'Asia/Magadan' => '(GMT+11:00) Magadan',
'Pacific/Auckland' => '(GMT+12:00) Auckland',
'Pacific/Fiji' => '(GMT+12:00) Fiji',
'Asia/Kamchatka' => '(GMT+12:00) Kamchatka'
];
// Type de proxy
public static $proxyType = [
'tcp://' => 'TCP',
'http://' => 'HTTP'
];
// Authentification SMTP
public static $SMTPauth = [
true => 'Oui',
false => 'Non'
];
// Encryptation SMTP
public static $SMTPEnc = [
'' => 'Aucune',
'tls' => 'START TLS',
'ssl' => 'SSL/TLS'
];
// Sécurité de la connexion - tentative max avant blocage
public static $connectAttempt = [
999 => 'Sécurité désactivée',
3 => '3 tentatives',
5 => '5 tentatives',
10 => '10 tentatives'
];
// Sécurité de la connexion - durée du blocage
public static $connectTimeout = [
0 => 'Sécurité désactivée',
300 => '5 minutes',
600 => '10 minutes',
900 => '15 minutes'
];
// Anonymisation des IP du journal
public static $anonIP = [
4 => 'Non tronquées',
3 => 'Niveau 1 (192.168.12.x)',
2 => 'Niveau 2 (192.168.x.x)',
1 => 'Niveau 3 (192.x.x.x)',
];
public static $captchaTypes = [
'num' => 'Chiffres',
'alpha' => 'Lettres'
];
// Langue traduite courante
public static $i18nSite = 'fr';
// Variable pour construire la liste des pages du site
public static $pagesList = [];
public static $orphansList = [];
/**
* Génére les fichiers pour les crawlers
* Sitemap compressé et non compressé
* Robots.txt
*/
public function generateFiles() {
// Mettre à jour le site map
$successSitemap=$this->createSitemap();
// Valeurs en sortie
$this->addOutput([
/*'title' => 'Configuration',
'view' => 'index',*/
'redirect' => helper::baseUrl() . 'config',
'notification' => $successSitemap ? 'Mises à jour des fichiers sitemap et robots.txt' : 'Echec d\'écriture, le site map n\'a pas été mis à jour',
'state' => $successSitemap
]);
}
/**
* Sauvegarde des données
*/
public function backup() {
// Soumission du formulaire
if($this->isPost()) {
// Creation du ZIP
$filter = $this->getInput('configBackupOption',helper::FILTER_BOOLEAN) === true ? ['backup','tmp'] : ['backup','tmp','file'];
$fileName = helper::autoBackup(self::TEMP_DIR,$filter);
// Créer le répertoire manquant
if (!is_dir(self::FILE_DIR.'source/backup')) {
mkdir(self::FILE_DIR.'source/backup', 0755);
}
// Copie dans les fichiers
$success = copy (self::TEMP_DIR . $fileName , self::FILE_DIR.'source/backup/' . $fileName);
// Détruire le temporaire
unlink(self::TEMP_DIR . $fileName);
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => json_encode($success)
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => 'Sauvegarder',
'view' => 'backup'
]);
}
}
/**
* Active ou désactive le mode Open Graph
*/
public function configOpenGraph() {
$texte='';
if( $_SESSION['screenshot'] === 'on'){
$_SESSION['screenshot'] = 'off';
$texte = 'Mode de capture Opengraph désactivé';
if( file_exists('./screenshot.php')) unlink ('./screenshot.php');
}
else{
$_SESSION['screenshot'] = 'on';
$texte = 'Mode de capture Opengraph activé';
if( !file_exists('./screenshot.php')) copy('./core/vendor/screenshot/screenshot.php','./screenshot.php');
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => $texte,
'state' => true
]);
}
/**
* Procédure d'importation
*/
public function restore() {
// Soumission du formulaire
if($this->isPost() ) {
$success = false;
if ($this->getInput('configRestoreImportFile', null, true) ) {
$fileZip = $this->getInput('configRestoreImportFile');
$file_parts = pathinfo($fileZip);
$folder = date('Y-m-d-h-i-s', time());
$zip = new ZipArchive();
if ($file_parts['extension'] !== 'zip') {
// Valeurs en sortie erreur
$this->addOutput([
'title' => 'Restaurer',
'view' => 'restore',
'notification' => 'Le fichier n\'est pas une archive valide',
'state' => false
]);
}
$successOpen = $zip->open(self::FILE_DIR . 'source/' . $fileZip);
if ($successOpen === FALSE) {
// Valeurs en sortie erreur
$this->addOutput([
'title' => 'Restaurer',
'view' => 'restore',
'notification' => 'Impossible de lire l\'archive',
'state' => false
]);
}
// Lire le contenu de l'archive dans le tableau files
for( $i = 0; $i < $zip->numFiles; $i++ ){
$stat = $zip->statIndex( $i );
$files [] = ( basename( $stat['name'] ));
}
// Lire la dataversion
$tmpDir = uniqid(4);
$success = $zip->extractTo( self::TEMP_DIR . $tmpDir );
$data = file_get_contents( self::TEMP_DIR . $tmpDir . '/data/core.json');
$obj = json_decode($data);
$dataVersion = strval ($obj->core->dataVersion);
switch (strlen($dataVersion)) {
case 4:
if (substr($dataVersion,0,1) === '9' ) {
$version = 9;
} else {
$version = 0;
}
break;
case 5:
$version = substr($dataVersion,0,2);
break;
default:
$version = 0;
break;
}
$this->removeDir(self::TEMP_DIR . $tmpDir );
if ($version >= 10 ) {
// Option active, les users sont stockées
if ($this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ) {
$users = $this->getData(['user']);
}
} elseif ($version === 0) { // Version invalide
// Valeurs en sortie erreur
$this->addOutput([
'title' => 'Restaurer',
'view' => 'restore',
'notification' => 'Cette archive n\'est pas une sauvegarde valide',
'state' => false
]);
}
// Préserver les comptes des utilisateurs d'une version 9 si option cochée
// Positionnement d'une variable de session lue au constructeurs
if ($version === 9) {
$_SESSION['KEEP_USERS'] = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN);
}
// Extraire le zip ou 'site/'
$this->removeDir(self::DATA_DIR);
$success = $zip->extractTo( 'site/' );
// Fermer l'archive
$zip->close();
// Restaurer les users originaux d'une v10 si option cochée
if (!empty($users) &&
$version >= 10 &&
$this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true) {
$this->setData(['user',$users]);
}
}
// Message de notification
$notification = $success === true ? 'Restaurer effectuée avec succès' : 'Erreur inconnue';
$redirect = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/restore' : helper::baseUrl() . 'user/login/';
// Valeurs en sortie erreur
$this->addOutput([
/*'title' => 'Restaurer',
'view' => 'restore',*/
'redirect' => $redirect,
'notification' => $notification,
'state' => $success
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Restaurer',
'view' => 'restore'
]);
}
/**
* Configuration
*/
public function index() {
// Soumission du formulaire
if($this->isPost()) {
// Basculement en mise à jour auto, remise à 0 du compteur
if ($this->getData(['config','autoUpdate']) === false &&
$this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN) === true) {
$this->setData(['core','lastAutoUpdate',0]);
}
// Eviter déconnexion automatique après son activation
if ( $this->getData(['config','connect', 'autoDisconnect']) === false
AND $this->getInput('configAutoDisconnect',helper::FILTER_BOOLEAN) === true ) {
$this->setData(['user',$this->getuser('id'),'accessCsrf',$_SESSION['csrf']]);
}
// Répercuter la suppression de la page dans la configuration du footer
if ( $this->getData(['theme','footer','displaySearch']) === true
AND $this->getInput('configSearchPageId') === 'none'
){
$this->setData(['theme', 'footer', 'displaySearch', false]);
}
if ( $this->getData(['theme','footer','displayLegal']) === true
AND $this->getInput('configLegalPageId') === 'none'
){
$this->setData(['theme', 'footer', 'displayLegal', false]);
}
// Sauvegarder les locales
$this->setData([
'locale',
[
'homePageId' => $this->getInput('localeHomePageId', helper::FILTER_ID, true),
'page404' => $this->getInput('localePage404'),
'page403' => $this->getInput('localePage403'),
'page302' => $this->getInput('localePage302'),
'legalPageId' => $this->getInput('localeLegalPageId'),
'searchPageId' => $this->getInput('localeSearchPageId'),
'searchPageLabel' => empty($this->getInput('localeSearchPageLabel', helper::FILTER_STRING_SHORT)) ? 'Rechercher' : $this->getInput('localeSearchPageLabel', helper::FILTER_STRING_SHORT),
'legalPageLabel' => empty($this->getInput('localeLegalPageLabel', helper::FILTER_STRING_SHORT)) ? 'Mentions légales' : $this->getInput('localeLegalPageLabel', helper::FILTER_STRING_SHORT),
'sitemapPageLabel' => empty($this->getInput('localeSitemapPageLabel', helper::FILTER_STRING_SHORT)) ? 'Plan du site' : $this->getInput('localeSitemapPageLabel', helper::FILTER_STRING_SHORT),
'metaDescription' => $this->getInput('localeMetaDescription', helper::FILTER_STRING_LONG, true),
'title' => $this->getInput('localeTitle', helper::FILTER_STRING_SHORT, true),
'cookies' => [
// Les champs sont obligatoires si l'option consentement des cookies est active
'cookiesDeltaText' => $this->getInput('localeCookiesDeltaText', helper::FILTER_STRING_LONG, $this->getData(['config', 'cookieConsent'])),
'cookiesExtText' => $this->getInput('localeCookiesExtText', helper::FILTER_STRING_LONG),
'cookiesTitleText' => $this->getInput('localeCookiesTitleText', helper::FILTER_STRING_SHORT, $this->getData(['config', 'cookieConsent'])),
'cookiesLinkMlText' => $this->getInput('localeCookiesLinkMlText', helper::FILTER_STRING_SHORT, $this->getData(['config', 'cookieConsent'])),
'cookiesCheckboxExtText' => $this->getInput('localeCookiesCheckboxExtText', helper::FILTER_STRING_SHORT),
'cookiesFooterText' => $this->getInput('localeCookiesFooterText', helper::FILTER_STRING_SHORT, $this->getData(['config', 'cookieConsent'])),
'cookiesButtonText' =>$this->getInput('localeCookiesButtonText', helper::FILTER_STRING_SHORT, $this->getData(['config', 'cookieConsent']))
]
]
]);
// Sauvegarder la configuration
$this->setData([
'config',
[
'favicon' => $this->getInput('configFavicon'),
'faviconDark' => $this->getInput('configFaviconDark'),
'timezone' => $this->getInput('configTimezone', helper::FILTER_STRING_SHORT, true),
'autoUpdate' => $this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN),
'autoUpdateHtaccess' => $this->getInput('configAutoUpdateHtaccess', helper::FILTER_BOOLEAN),
'autoBackup' => $this->getInput('configAutoBackup', helper::FILTER_BOOLEAN),
'maintenance' => $this->getInput('configMaintenance', helper::FILTER_BOOLEAN),
'cookieConsent' => $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN),
'proxyType' => $this->getInput('configProxyType'),
'proxyUrl' => $this->getInput('configProxyUrl'),
'proxyPort' => $this->getInput('configProxyPort',helper::FILTER_INT),
'social' => [
'facebookId' => $this->getInput('socialFacebookId'),
'linkedinId' => $this->getInput('socialLinkedinId'),
'instagramId' => $this->getInput('socialInstagramId'),
'pinterestId' => $this->getInput('socialPinterestId'),
'twitterId' => $this->getInput('socialTwitterId'),
'youtubeId' => $this->getInput('socialYoutubeId'),
'youtubeUserId' => $this->getInput('socialYoutubeUserId'),
'githubId' => $this->getInput('socialGithubId')
],
'smtp' => [
'enable' => $this->getInput('smtpEnable',helper::FILTER_BOOLEAN),
'host' => $this->getInput('smtpHost',helper::FILTER_STRING_SHORT,$this->getInput('smtpEnable',helper::FILTER_BOOLEAN)),
'port' => $this->getInput('smtpPort',helper::FILTER_INT,$this->getInput('smtpEnable',helper::FILTER_BOOLEAN)),
'auth' => $this->getInput('smtpAuth',helper::FILTER_BOOLEAN),
'secure' => $this->getInput('smtpSecure',helper::FILTER_BOOLEAN),
'username' => $this->getInput('smtpUsername',helper::FILTER_STRING_SHORT,$this->getInput('smtpAuth',helper::FILTER_BOOLEAN)),
'password' =>helper::encrypt($this->getData(['config','smtp','username']),$this->getInput('smtpPassword',null,$this->getInput('smtpAuth',helper::FILTER_BOOLEAN))),
'sender' => $this->getInput('smtpSender',helper::FILTER_MAIL)
],
'seo' => [
'robots' => $this->getInput('seoRobots',helper::FILTER_BOOLEAN),
'analyticsId' => $this->getInput('seoAnalyticsId')
],
'connect' => [
'attempt' => $this->getInput('connectAttempt',helper::FILTER_INT),
'timeout' => $this->getInput('connectTimeout',helper::FILTER_INT),
'log' => $this->getInput('connectLog',helper::FILTER_BOOLEAN),
'anonymousIp' => $this->getInput('connectAnonymousIp',helper::FILTER_INT),
'captcha' => $this->getInput('connectCaptcha',helper::FILTER_BOOLEAN),
'captchaStrong' => $this->getInput('connectCaptchaStrong',helper::FILTER_BOOLEAN),
'autoDisconnect' => $this->getInput('connectAutoDisconnect',helper::FILTER_BOOLEAN),
'captchaType' => $this->getInput('connectCaptchaType')
],
'i18n' => [
'enable' => $this->getInput('localei18n',helper::FILTER_BOOLEAN),
'scriptGoogle' => $this->getData(['config', 'i18n', 'scriptGoogle']),
'showCredits' => $this->getData(['config', 'i18n', 'showCredits']),
'autoDetect' => $this->getData(['config', 'i18n', 'autoDetect']),
//'admin' => $this->getData(['config', 'i18n', 'admin']),
'fr' => $this->getData(['config', 'i18n', 'fr']),
'de' => $this->getData(['config', 'i18n', 'de']),
'en' => $this->getData(['config', 'i18n', 'en']),
'es' => $this->getData(['config', 'i18n', 'es']),
'it' => $this->getData(['config', 'i18n', 'it']),
'nl' => $this->getData(['config', 'i18n', 'nl']),
'pt' => $this->getData(['config', 'i18n', 'pt'])
]
]
]);
// Efface les fichiers de backup lorsque l'option est désactivée
if ($this->getInput('configFileBackup', helper::FILTER_BOOLEAN) === false) {
$path = realpath('site/data');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
if (strpos($filename,'backup.json')) {
unlink($filename);
}
}
if (file_exists('site/data/.backup')) unlink('site/data/.backup');
} else {
touch('site/data/.backup');
}
// Notice
if(self::$inputNotices === []) {
// Active la réécriture d'URL
$rewrite = $this->getInput('configRewrite', helper::FILTER_BOOLEAN);
if(
$rewrite
AND helper::checkRewrite() === false
) {
// Ajout des lignes dans le .htaccess
file_put_contents(
'.htaccess',
PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>',
FILE_APPEND
);
// Change le statut de la réécriture d'URL (pour le helper::baseUrl() de la redirection)
helper::$rewriteStatus = true;
}
// Désactive la réécriture d'URL
elseif(
$rewrite === false
AND helper::checkRewrite()
) {
// Suppression des lignes dans le .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
file_put_contents('.htaccess', $htaccess[0] . '# URL rewriting');
// Change le statut de la réécriture d'URL (pour le helper::baseUrl() de la redirection)
helper::$rewriteStatus = false;
}
// Met à jour la baseUrl
$this->setData(['core', 'baseUrl', helper::baseUrl(true,false) ]);
}
// Générer robots.txt et sitemap
$this->generateFiles();
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Modifications enregistrées ' ,
'state' => true
]);
}
// Générer la list des pages disponibles
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]);
}
}
self::$orphansList = $this->getData(['page']);
foreach(self::$orphansList as $page => $pageId) {
if ($this->getData(['page',$page,'block']) === 'bar' ||
$this->getData(['page',$page,'disable']) === true ||
$this->getdata(['page',$page, 'position']) !== 0) {
unset(self::$orphansList[$page]);
}
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index'
]);
}
public function script() {
// Soumission du formulaire
if($this->isPost()) {
// Ecrire les fichiers de script
if ($this->geturl(2) === 'head') {
file_put_contents(self::DATA_DIR . 'head.inc.html',$this->getInput('configScriptHead',null));
}
if ($this->geturl(2) === 'body') {
file_put_contents(self::DATA_DIR . 'body.inc.html',$this->getInput('configScriptBody',null));
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Éditeur de script dans ' . ucfirst($this->geturl(2)) ,
'vendor' => [
'codemirror'
],
'view' => 'script',
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Éditeur de script dans ' . ucfirst($this->geturl(2)) ,
'vendor' => [
'codemirror'
],
'view' => 'script'
]);
}
/**
* Met à jour les données de site avec l'adresse transmise
*/
public function updateBaseUrl () {
// Supprimer l'information de redirection
$old = str_replace('?','',$this->getData(['core', 'baseUrl']));
$new = helper::baseUrl(false,false);
$c3 = 0;
$success = false ;
// Boucler sur les pages
foreach($this->getHierarchy(null,null,null) as $parentId => $childIds) {
$content = $this->getPage($parentId, self::$i18n);
$content = $titre . ' ' . $content ;
$replace = str_replace( 'href="' . $old , 'href="'. $new , stripslashes($content),$c1) ;
$replace = str_replace( 'src="' . $old , 'src="'. $new , stripslashes($replace),$c2) ;
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($parentId, $replace, self::$i18n);
$c3 += $c1 + $c2;
}
foreach($childIds as $childId) {
$content = $this->getPage($childId, self::$i18n);
$content = $titre . ' ' . $content ;
$replace = str_replace( 'href="' . $old , 'href="'. $new , stripslashes($content),$c1) ;
$replace = str_replace( 'src="' . $old , 'src="'. $new , stripslashes($replace),$c2) ;
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($childId, $replace, self::$i18n);
$c3 += $c1 + $c2;
}
}
}
// Traiter les modules dont la redirection
$content = $this->getdata(['module']);
$replace = $this->recursive_array_replace('href="' . $old , 'href="'. $new, $content, $c1);
$replace = $this->recursive_array_replace('src="' . $old , 'src="'. $new, $replace, $c2);
if ($content !== $replace) {
$this->setdata(['module',$replace]);
$c3 += $c1 + $c2;
$success = true;
}
// Mettre à jour la base URl
$this->setData(['core','baseUrl',helper::baseUrl(true,false)]);
// Valeurs en sortie
$this->addOutput([
'title' => 'Restaurer',
'view' => 'restore',
'notification' => $success ? $c3. ' conversion' . ($c3 > 1 ? 's' : '') . ' effectuée' . ($c3 > 1 ? 's' : '') : 'Aucune conversion',
'state' => $success ? true : false
]);
}
/**
* Vider le fichier de log
*/
public function logReset() {
if ( file_exists(self::DATA_DIR . 'journal.log') ) {
unlink(self::DATA_DIR . 'journal.log');
// Créer les en-têtes des journaux
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log',$d);
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Journal réinitialisé avec succès',
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Aucun journal à effacer',
'state' => false
]);
}
}
/**
* Télécharger le fichier de log
*/
public function logDownload() {
$fileName = self::DATA_DIR . 'journal.log';
if (file_exists($fileName)) {
ob_start();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile( $fileName);
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Aucun fichier journal à télécharger',
'state' => false
]);
}
}
/**
* Tableau des IP blacklistés
*/
public function blacklistDownload () {
ob_start();
$fileName = self::TEMP_DIR . 'blacklist.log';
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
file_put_contents($fileName,$d);
if ( file_exists($fileName) ) {
$d = $this->getData(['blacklist']);
$data = '';
foreach ($d as $key => $item) {
$data .= mb_detect_encoding(strftime('%d/%m/%y',$item['lastFail']), 'UTF-8', true)
? strftime('%d/%m/%y',$item['lastFail']) . ';' . utf8_encode(strftime('%R',$item['lastFail'])) . ';'
: utf8_encode(strftime('%d/%m/%y',$item['lastFail'])) . ';' . utf8_encode(strftime('%R',$item['lastFail'])) . ';' ;
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
file_put_contents($fileName,$data,FILE_APPEND);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile( $fileName);
unlink(self::TEMP_DIR . 'blacklist.log');
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Aucune liste noire à télécharger',
'state' => false
]);
}
}
/**
* Réinitialiser les ip blacklistées
*/
public function blacklistReset() {
if ( file_exists(self::DATA_DIR . 'blacklist.json') ) {
$this->setData(['blacklist',[]]);
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Liste noire réinitialisée avec succès',
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Pas de liste à effacer',
'state' => false
]);
}
}
/**
* Récupération des backups auto dans le gestionnaire de fichiers
*/
public function copyBackups() {
// Créer le répertoire manquant
if (!is_dir(self::FILE_DIR.'source/backup')) {
mkdir(self::FILE_DIR.'source/backup', 0755);
}
$this->copyDir(self::BACKUP_DIR, self::FILE_DIR . 'source/backup' );
// Valeurs en sortie
$this->addOutput([
'title' => 'Configuration',
'view' => 'index',
'notification' => 'Copie terminée',
'state' => true
]);
}
/**
* Fonction de parcours des données de module
* @param string $find donnée à rechercher
* @param string $replace donnée à remplacer
* @param array tableau à analyser
* @param int count nombres d'occurrences
* @return array avec les valeurs remplacées.
*/
private function recursive_array_replace ($find, $replace, $array, &$count) {
if (!is_array($array)) {
return str_replace($find, $replace, $array, $count);
}
$newArray = [];
foreach ($array as $key => $value) {
$newArray[$key] = $this->recursive_array_replace($find, $replace, $value,$c);
$count += $c;
}
return $newArray;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,58 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
$( document).ready(function() {
$("#configBackupForm").submit( function(e){
//$("#configBackupSubmit").addClass("disabled").prop("disabled", true);
e.preventDefault();
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup";
$.ajax({
type: "POST",
url: url,
data: $("form").serialize(),
success: function(data){
$('body, .button').css('cursor', 'default');
core.alert("La sauvegarde a été générée avec succès.");
},
error: function(data){
$('body, .button').css('cursor', 'default');
core.alert("Une erreur s'est produite, la sauvegarde n'a pas été générée !");
},
complete: function(){
$("#configBackupSubmit").removeClass("disabled").prop("disabled", false);
$("#configBackupSubmit").removeClass("uniqueSubmission").prop("uniqueSubmission", false);
$("#configBackupSubmit span").removeClass("zwiico-spin animate-spin");
$("#configBackupSubmit span").addClass("zwiico-check zwiico-margin-right").text("Sauvegarder");
}
});
});
/**
* Confirmation de sauvegarde complète
*/
$("#configBackupSubmit").on("click", function() {
if ($("input[name=configBackupOption]").is(':checked')) {
return core.confirm("Une sauvegarde avec le contenu du gestionnaire de fichier peut prendre du temps à générer. Confirmez-vous ?", function() {
//$(location).attr("href", _this.attr("href"));
$('body, .button').css('cursor', 'wait');
$('form#configBackupForm').submit();
});
}
});
});

View File

@ -0,0 +1,36 @@
<?php echo template::formOpen('configBackupForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configBackupBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('configBackupSubmit',[
'value' => 'Sauvegarder',
'uniqueSubmission' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres de la sauvegarde</h4>
<div class="row">
<div class="col12">
<?php echo template::checkbox('configBackupOption', true, 'Inclure le contenu du gestionnaire de fichiers', [
'checked' => true,
'help' => 'Si le contenu du gestionnaire de fichiers est très volumineux, mieux vaut une copie par FTP.'
]); ?>
</div>
<div class="col12">
<em>L'archive est générée dans <a href="<?php echo helper::baseUrl(false); ?>core/vendor/filemanager/dialog.php?fldr=backup&type=0&akey=<?php echo md5_file(self::DATA_DIR.'core.json'); ?>" data-lity>le dossier Backup</a> du gestionnaire de fichiers.</em>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,31 @@
<div id="scriptContainer">
<div class="row">
<div class="col12">
<div class="block">
<h4>Scripts externes
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/scripts" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col3 offset3 verticalAlignBottom">
<?php echo template::button('socialScriptHead', [
'href' => helper::baseUrl() . 'config/script/head',
'value' => 'Script dans head',
'ico' => 'pencil'
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<?php echo template::button('socialScriptBody', [
'href' => helper::baseUrl() . 'config/script/body',
'value' => 'Script dans body',
'ico' => 'pencil'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,117 @@
<div id="connectContainer">
<div class="row">
<div class="col12">
<div class="block">
<h4>Sécurité de la connexion
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/connexion" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('connectCaptcha', true, 'Captcha à la connexion', [
'checked' => $this->getData(['config', 'connect','captcha'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('connectCaptchaStrong', true, 'Captcha complexe', [
'checked' => $this->getData(['config', 'connect', 'captchaStrong']),
'help' => 'Option recommandée pour sécuriser la connexion. S\'applique à tous les captchas du site. Le captcha simple se limite à une addition de nombres de 0 à 10. Le captcha complexe utilise quatre opérations de nombres de 0 à 20. Activation recommandée.'
]); ?>
</div>
<div class="col3">
<?php echo template::select('connectCaptchaType', $module::$captchaTypes , [
'label' => 'Type de captcha',
'selected' => $this->getData(['config', 'connect', 'captchaType'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('connectAutoDisconnect', true, 'Déconnexion automatique', [
'checked' => $this->getData(['config','connect', 'autoDisconnect']),
'help' => 'Déconnecte les sessions ouvertes précédemment sur d\'autres navigateurs ou terminaux. Activation recommandée.'
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::select('connectAttempt', $module::$connectAttempt , [
'label' => 'Connexions successives',
'selected' => $this->getData(['config', 'connect', 'attempt'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('connectTimeout', $module::$connectTimeout , [
'label' => 'Blocage après échecs',
'selected' => $this->getData(['config', 'connect', 'timeout'])
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<label id="helpBlacklist">Liste noire :
<?php echo template::help(
'La liste noire énumère les tentatives de connexion à partir de comptes inexistants. Sont stockés : la date, l\'heure, le nom du compte et l\'IP.
Après le nombre de tentatives autorisées, l\'IP et le compte sont bloqués.');
?>
</label>
<?php echo template::button('ConnectBlackListDownload', [
'href' => helper::baseUrl() . 'config/blacklistDownload',
'value' => 'Télécharger la liste',
'ico' => 'download'
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<?php echo template::button('CnnectBlackListReset', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'config/blacklistReset',
'value' => 'Réinitialiser la liste',
'ico' => 'cancel'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Journalisation
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/connexion#journalisation" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('connectLog', true, 'Activer la journalisation', [
'checked' => $this->getData(['config', 'connect', 'log'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('connectAnonymousIp', $module::$anonIP, [
'label' => 'Anonymat des adresses IP',
'selected' => $this->getData(['config', 'connect', 'anonymousIp']),
'help' => 'La réglementation française impose un anonymat de niveau 2'
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<?php echo template::button('ConfigLogDownload', [
'href' => helper::baseUrl() . 'config/logDownload',
'value' => 'Télécharger le journal',
'ico' => 'download'
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<?php echo template::button('ConnectLogReset', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'config/logReset',
'value' => 'Réinitialiser le journal',
'ico' => 'cancel'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,33 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/
#setupContainer {
display: block;
}
.activeButton {
filter : brightness(150%);
}
.buttonNotice {
border: 2px solid red !important;
border-radius: 2px;
}

View File

@ -0,0 +1,278 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
$( document).ready(function() {
// Positionnement inital des options
//-----------------------------------------------------------------------------------------------------
/**
* Afficher et masquer options smtp
*/
if ($("input[name=smtpEnable]").is(':checked')) {
$("#smtpParam").addClass("disabled");
$("#smtpParam").slideDown();
} else {
$("#smtpParam").removeClass("disabled");
$("#smtpParam").slideUp();
}
/**
* Afficher et masquer options Auth
*/
if ($("select[name=smtpAuth]").val() == true) {
$("#smtpAuthParam").addClass("disabled");
$("#smtpAuthParam").slideDown();
} else {
$("#smtpAuthParam").removeClass("disabled");
$("#smtpAuthParam").slideUp();
}
var configLayout = getCookie("configLayout");
if (configLayout == null) {
configLayout = "setup";
setCookie("configLayout","setup");
}
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#setupContainer").hide();
$("#scriptContainer").hide();
$("#" + configLayout + "Container" ).show();
$("#config" + capitalizeFirstLetter(configLayout) + "Button").addClass("activeButton");
// Gestion des événements
//---------------------------------------------------------------------------------------------------------------------
/**
* Afficher et masquer options smtp
*/
$("input[name=smtpEnable]").on("change", function() {
if ($("input[name=smtpEnable]").is(':checked')) {
$("#smtpParam").addClass("disabled");
$("#smtpParam").slideDown();
} else {
$("#smtpParam").removeClass("disabled");
$("#smtpParam").slideUp();
}
});
/**
* Afficher et masquer options Auth
*/
$("select[name=smtpAuth]").on("change", function() {
if ($("select[name=smtpAuth]").val() == true) {
$("#smtpAuthParam").addClass("disabled");
$("#smtpAuthParam").slideDown();
} else {
$("#smtpAuthParam").removeClass("disabled");
$("#smtpAuthParam").slideUp();
}
});
/**
* Options de blocage de connexions
* Contrôle la cohérence des sélections et interdit une seule valeur Aucune
*/
$("select[name=connectAttempt]").on("change", function() {
if ($("select[name=connectAttempt]").val() === "999") {
$("select[name=connectTimeout]").val(0);
} else {
if ($("select[name=connectTimeout]").val() === "0") {
$("select[name=connectTimeout]").val(300);
}
}
});
$("select[name=connectTimeout]").on("change", function() {
if ($("select[name=connectTimeout]").val() === "0") {
$("select[name=connectAttempt]").val(999);
} else {
if ($("select[name=connectAttempt]").val() === "999") {
$("select[name=connectAttempt]").val(3);
}
}
});
/**
* Captcha strong si captcha sélectionné
*/
$("input[name=connectCaptcha]").on("change", function() {
if ($("input[name=connectCaptcha]").is(':checked')) {
$("#connectCaptchaStrongWrapper").addClass("disabled");
$("#connectCaptchaStrongWrapper").slideDown();
$( "#connectCaptchaStrong" ).prop( "checked", false );
} else {
$("#connectCaptchaStrongWrapper").removeClass("disabled");
$("#connectCaptchaStrongWrapper").slideUp();
}
});
/**
* Sélection de la page de configuration à afficher
*/
$("#configSetupButton").on("click", function() {
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#scriptContainer").hide();
$("#setupContainer").show();
$("#configSetupButton").addClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
$("#configScriptButton").removeClass("activeButton");
setCookie("configLayout","setup");
});
$("#configLocaleButton").on("click", function() {
$("#setupContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#scriptContainer").hide();
$("#localeContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").addClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
$("#configScriptButton").removeClass("activeButton");
setCookie("configLayout","locale");
});
$("#configSocialButton").on("click", function() {
$("#connectContainer").hide();
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#networkContainer").hide();
$("#scriptContainer").hide();
$("#socialContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").addClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
$("#configScriptButton").removeClass("activeButton");
setCookie("configLayout","social");
});
$("#configConnectButton").on("click", function() {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#networkContainer").hide();
$("#scriptContainer").hide();
$("#connectContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").addClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
$("#configScriptButton").removeClass("activeButton");
setCookie("configLayout","connect");
});
$("#configNetworkButton").on("click", function() {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#scriptContainer").hide();
$("#networkContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configScriptButton").removeClass("activeButton");
$("#configNetworkButton").addClass("activeButton");
setCookie("configLayout","network");
});
$("#configScriptButton").on("click", function() {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#scriptContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
$("#configScriptButton").addClass("activeButton");
setCookie("configLayout","script");
});
/**
* Aspect de la souris
*/
$("#socialMetaImage, #socialSiteMap, #configBackupCopyButton").click(function(event) {
$('body, .button').css('cursor', 'wait');
});
// Mise en évidence des erreurs de saisie dans les boutons de sélection
var containers = ["setup", "locale", "social", "connect", "network"];
$.each( containers, function( index, value ){
var a = $("div#" + value + "Container").find("input.notice").not(".displayNone");
if (a.length > 0) {
$("#config" + capitalizeFirstLetter(value) + "Button").addClass("buttonNotice");
} else {
$("#config" + capitalizeFirstLetter(value) + "Button").removeClass("buttonNotice");
}
});
// Animation des boutons zwiico-help lien vers la documentation
var colorButton = <?php echo "'".$this->getData(['admin', 'backgroundColorButtonHelp'])."'"; ?> ;
var blockButton = <?php echo "'".$this->getData(['admin', 'backgroundBlockColor'])."'"; ?> ;
$(".helpDisplayButton").mouseenter(function(){
$(this).css("background-color", colorButton);
});
$(".helpDisplayButton").mouseleave(function(){
$(this).css("background-color", blockButton);
});
});
function setCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

View File

@ -0,0 +1,68 @@
<?php echo template::formOpen('configForm');?>
<div class="row">
<div class="col2">
<?php echo template::button('configBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
'ico' => 'home',
'value' => 'Accueil'
]); ?>
</div>
<div class="col2 ">
<?php echo template::button('configHelp', [
'class' => 'buttonHelp',
'href' => 'https://doc.deltacms.fr/configuration-du-site',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide'
]); ?>
</div>
<div class="col2 offset6">
<?php echo template::submit('Submit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="row textAlignCenter">
<div class="col2">
<?php echo template::button('configSetupButton', [
'value' => 'Configuration'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configLocaleButton', [
'value' => 'Localisation'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configSocialButton', [
'value' => 'Référencement'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configConnectButton', [
'value' => 'Connexion'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configNetworkButton', [
'value' => 'Réseau'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configScriptButton', [
'value' => 'Scripts'
]); ?>
</div>
</div>
</div>
</div>
<?php include ('core/module/config/view/setup/setup.php') ?>
<?php include ('core/module/config/view/locale/locale.php') ?>
<?php include ('core/module/config/view/social/social.php') ?>
<?php include ('core/module/config/view/connect/connect.php') ?>
<?php include ('core/module/config/view/network/network.php') ?>
<?php include ('core/module/config/view/bodyheadscript/bodyheadscript.php') ?>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,228 @@
<div id="localeContainer">
<div class="row">
<div class="col12">
<div class="block">
<h4>Langues étrangères</h4>
<div class="row">
<div class="col12">
<?php echo template::checkbox('localei18n', true, 'Activer la gestion des langues étrangères', [
'checked' => $this->getData(['config', 'i18n', 'enable']),
'help'=> 'Une nouvelle icône apparaîtra dans la barre d\'administration. Consultez l\'aide de la page concernée pour en apprendre plus.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Identité du site <?php echo template::flag('site', '20px');?>
<span id="localeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/localisation" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col9">
<?php echo template::text('localeTitle', [
'label' => 'Titre du site' ,
'value' => $this->getData(['locale', 'title']),
'help' => 'Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.'
]); ?>
</div>
<div class="col3">
<?php echo template::text('localeVersion', [
'label' => 'DeltaCMS Version',
'value' => common::DELTA_VERSION,
'readonly' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::textarea('localeMetaDescription', [
'label' => 'Description du site',
'value' => $this->getData(['locale', 'metaDescription']),
'help' => 'La description d\'une page participe à son référencement, chaque page doit disposer d\'une description différente.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Assignation des pages spéciales <?php echo template::flag('site', '20px');?>
<span id="localeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/localisation#pages-speciales" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col4">
<?php echo template::select('localeHomePageId', helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC'), [
'label' => 'Accueil du site',
'selected' =>$this->getData(['locale', 'homePageId']),
'help' => 'La première page que vos visiteurs verront.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localePage403', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Accès interdit, erreur 403',
'selected' =>$this->getData(['locale', 'page403']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localePage404', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Page inexistante, erreur 404',
'selected' =>$this->getData(['locale', 'page404']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('localeLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Mentions légales',
'selected' => $this->getData(['locale', 'legalPageId']),
'help' => 'Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('localeSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Recherche dans le site',
'selected' => $this->getData(['locale', 'searchPageId']),
'help' => 'Sélectionnez une page contenant le module \'Recherche\'. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php
echo template::select('localePage302', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Site en maintenance',
'selected' =>$this->getData(['locale', 'page302']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Etiquettes des pages spéciales <?php echo template::flag('site', '20px');?>
<span id="labelHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/localisation#etiquettes" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col6">
<?php echo template::text('localeLegalPageLabel', [
'label' => 'Mentions légales',
'placeholder' => 'Mentions légales',
'value' => $this->getData(['locale', 'legalPageLabel'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('localeSearchPageLabel', [
'label' => 'Rechercher',
'placeholder' => 'Rechercher',
'value' => $this->getData(['locale', 'searchPageLabel'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::text('localeSitemapPageLabel', [
'label' => 'Plan du site',
'placeholder' => 'Plan du site',
'value' => $this->getData(['locale', 'sitemapPageLabel']),
]); ?>
</div>
<div class="col6">
<?php echo template::text('localeCookiesFooterText', [
'label' => 'Cookies',
'value' => $this->getData(['locale', 'cookies', 'cookiesFooterText']),
'placeHolder' => 'Cookies'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Message d'acceptation des Cookies <?php echo template::flag('site', '20px');?>
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/localisation#cookies" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col12">
<?php echo template::text('localeCookiesTitleText', [
'help' => 'Saisissez le titre de la fenêtre de gestion des cookies.',
'label' => 'Titre de la fenêtre',
'value' => $this->getData(['locale', 'cookies', 'cookiesTitleText']),
'placeHolder' => 'Gérer les cookies'
]); ?>
</div>
</div>
<div class="row">
<div class="col8">
<?php echo template::textarea('localeCookiesDeltaText', [
'help' => 'Saisissez le message pour les cookies déposés par DeltaCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.',
'label' => 'Cookies Deltacms',
'value' => $this->getData(['locale', 'cookies', 'cookiesDeltaText']),
'placeHolder' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeCookiesLinkMlText', [
'help' => 'Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.',
'label' => 'Lien page des mentions légales.',
'value' => $this->getData(['locale', 'cookies', 'cookiesLinkMlText']),
'placeHolder' => 'Consulter les mentions légales'
]); ?>
</div>
</div>
<div class="row">
<div class="col8">
<?php echo template::textarea('localeCookiesExtText', [
'help' => 'Saisissez le message pour les cookies déposés par d\'autres applications dont le consentement est requis sinon laissez vide.',
'label' => 'Cookies tiers',
'value' => $this->getData(['locale', 'cookies', 'cookiesExtText'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('localeCookiesCheckboxExtText', [
'help' => 'Saisissez le texte de la case à cocher d\'acceptation des cookies tiers.',
'label' => 'Checkbox cookies tiers',
'value' => $this->getData(['locale', 'cookies', 'cookiesCheckboxExtText'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4 offset4">
<?php echo template::text('localeCookiesButtonText', [
'label' => 'Bouton de validation',
'value' => $this->getData(['locale', 'cookies', 'cookiesButtonText']),
'placeHolder' => 'J\'ai compris'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,105 @@
<div id="networkContainer">
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/reseau" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col2">
<?php echo template::select('configProxyType', $module::$proxyType, [
'label' => 'Type de proxy',
'selected' => $this->getData(['config', 'proxyType'])
]); ?>
</div>
<div class="col8">
<?php echo template::text('configProxyUrl', [
'label' => 'Adresse du proxy',
'placeholder' => 'cache.proxy.fr',
'value' => $this->getData(['config', 'proxyUrl'])
]); ?>
</div>
<div class="col2">
<?php echo template::text('configProxyPort', [
'label' => 'Port du proxy',
'placeholder' => '6060',
'value' => $this->getData(['config', 'proxyPort'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>SMTP
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/reseau#smtp" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col12">
<?php echo template::checkbox('smtpEnable', true, 'Activer SMTP', [
'checked' => $this->getData(['config', 'smtp','enable']),
'help' => 'Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d\'envoi de mail.'
]); ?>
</div>
</div>
<div id="smtpParam">
<div class="row">
<div class="col8">
<?php echo template::text('smtpHost', [
'label' => 'Adresse SMTP',
'placeholder' => 'smtp.fr',
'value' => $this->getData(['config', 'smtp','host'])
]); ?>
</div>
<div class="col2">
<?php echo template::text('smtpPort', [
'label' => 'Port SMTP',
'placeholder' => '589',
'value' => $this->getData(['config', 'smtp','port'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('smtpAuth', $module::$SMTPauth, [
'label' => 'Authentification',
'selected' => $this->getData(['config', 'smtp','auth'])
]); ?>
</div>
</div>
<div id="smtpAuthParam">
<div class="row">
<div class="col5">
<?php echo template::text('smtpUsername', [
'label' => 'Nom utilisateur',
'value' => $this->getData(['config', 'smtp','username' ])
]); ?>
</div>
<div class="col5">
<?php echo template::password('smtpPassword', [
'label' => 'Mot de passe',
'autocomplete' => 'off',
'value' => $this->getData(['config', 'smtp','username' ]) ? helper::decrypt ($this->getData(['config', 'smtp','username' ]),$this->getData(['config','smtp','password'])) : ''
]); ?>
</div>
<div class="col2">
<?php echo template::select('smtpSecure', $module::$SMTPEnc , [
'label' => 'Sécurité',
'selected' => $this->getData(['config', 'smtp','secure'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,26 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
$( document).ready(function() {
/**
* Aspect de la souris
*/
$("#configRestoreSubmit").click(function(event) {
$('body, .button').css('cursor', 'wait');
});
});

View File

@ -0,0 +1,83 @@
<?php echo template::formOpen('configRestoreForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configRestoreBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('configRestoreSubmit',[
'value' => 'Restaurer',
'uniqueSubmission' => true,
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Archive à restaurer</h4>
<div class="row">
<div class="col10 offset1">
<div class="row">
<?php echo template::file('configRestoreImportFile', [
'label' => 'Sélectionnez une archive au format ZIP',
'type' => 2,
'help' => 'L\'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.'
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('configRestoreImportUser', true, 'Préserver les comptes des utilisateurs déjà installés', [
'checked' => true
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Conversion après la restauration<?php echo template::help('Conversion des URL des ressources multimédia entre deux sites aux arborescences différentes.');?></h4>
<div class="row">
<div class="col4 offset1">
<?php
if (is_null($this->getData(['core', 'baseUrl'])) ) {
$baseUrlValue = 'Pas de donnée dans la sauvegarde';
$buttonClass = 'disabled';
} elseif ($this->getData(['core', 'baseUrl']) === '') {
$baseUrlValue = '/';
$buttonClass = helper::baseUrl(false,false) !== $this->getData(['core', 'baseUrl']) ? '' : 'disabled';
} else {
$baseUrlValue = str_replace('?','',$this->getData(['core', 'baseUrl']));
$buttonClass = helper::baseUrl(false,false) !== $baseUrlValue ? '' : 'disabled';
}
echo template::text('configRestoreBaseURLToConvert', [
'label' => 'Dossier de l\'archive' ,
'value' => $baseUrlValue,
'readonly' => true,
'help' => 'Le dossier de base du site est stockée dans la sauvegarde.'
]); ?>
</div>
<div class="col4">
<?php echo template::text('configRestoreCurrentURL', [
'label' => 'Dossier du site actuel',
'value' => helper::baseUrl(false,false),
'readonly' => true
]); ?>
</div>
<div class="col2 verticalAlignMiddle">
<?php echo template::button('configRestoreUpdateBaseURLButton', [
'href' => helper::baseUrl() . 'config/updateBaseUrl',
'class' => $buttonClass,
'value' => 'convertir'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,38 @@
<?php echo template::formOpen('configScript'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configManageBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('configManageSubmit',[
'value' => 'Valider',
'ico' => 'check'
]); ?>
</div>
</div>
<?php if ($this->geturl(2) === 'head'): ?>
<div class="row">
<div class="col12">
<?php echo template::textarea('configScriptHead', [
'value' => file_exists( self::DATA_DIR . 'head.inc.html') ? file_get_contents (self::DATA_DIR . 'head.inc.html') : '' ,
'class' => 'editor'
]); ?>
</div>
</div>
<?php endif ?>
<?php if ($this->geturl(2) === 'body'): ?>
<div class="row">
<div class="col12">
<?php echo template::textarea('configScriptBody', [
'value' => file_exists( self::DATA_DIR . 'body.inc.html') ? file_get_contents (self::DATA_DIR . 'body.inc.html') : '' ,
'class' => 'editor'
]); ?>
</div>
</div>
<?php endif ?>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,142 @@
<div id="setupContainer">
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres
<span id="setupHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/configuration" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col4">
<?php echo template::file('configFavicon', [
'type' => 1,
'help' => 'Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
'label' => 'Favicon',
'value' => $this->getData(['config', 'favicon'])
]); ?>
</div>
<div class="col4">
<?php echo template::file('configFaviconDark', [
'type' => 1,
'help' => 'Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
'label' => 'Favicon thème sombre',
'value' => $this->getData(['config', 'faviconDark'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('configTimezone', $module::$timezones, [
'label' => 'Fuseau horaire',
'selected' => $this->getData(['config', 'timezone']),
'help' => 'Le fuseau horaire est utile au bon référencement'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('configCookieConsent', true, 'Message de consentement aux cookies', [
'checked' => $this->getData(['config', 'cookieConsent']),
'help' => 'Activation obligatoire selon les lois françaises sauf si vous utilisez votre propre système de consentement.'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('configRewrite', true, 'URL intelligentes', [
'checked' => helper::checkRewrite(),
'help' => 'Vérifiez d\'abord que votre serveur autorise l\'URL rewriting (ce qui n\'est pas le cas chez Free).'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Mise à jour automatisée
<span id="updateHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/configuration#mise-a-jour" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<?php $updateError = helper::urlGetContents(common::DELTA_UPDATE_URL . common::DELTA_UPDATE_CHANNEL . '/version');?>
<div class="row">
<div class="col4">
<?php echo template::checkbox('configAutoUpdate', true, 'Rechercher une mise à jour en ligne', [
'checked' => $this->getData(['config', 'autoUpdate']),
'help' => 'La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.',
'disabled' => !$updateError
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('configAutoUpdateHtaccess', true, 'Préserver le fichier htaccess racine', [
'checked' => $this->getData(['config', 'autoUpdateHtaccess']),
'help' => 'Lors d\'une mise à jour automatique, conserve le fichier htaccess de la racine du site.',
'disabled' => !$updateError
]); ?>
</div>
<div class="col2 offset1">
<?php echo template::button('configUpdateForced', [
'ico' => 'download-cloud',
'href' => helper::baseUrl() . 'install/update',
'value' => 'Réinstaller',
'class' => 'buttonRed',
'disabled' => !$updateError
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Maintenance
<span id="maintenanceHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/configuration#maintenance" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col6">
<?php echo template::checkbox('configAutoBackup', true, 'Sauvegarde automatique quotidienne du site', [
'checked' => $this->getData(['config', 'autoBackup']),
'help' => 'Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.</p><p>Les fichiers du site ne sont pas sauvegardés automatiquement. Activation recommandée.'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('configMaintenance', true, 'Site en maintenance', [
'checked' => $this->getData(['config', 'maintenance'])
]); ?>
</div>
</div>
<div class="rows textAlignCenter">
<div class="col3">
<?php echo template::button('configBackupButton', [
'href' => helper::baseUrl() . 'config/backup',
'value' => 'Sauvegarder',
'ico' => 'download-cloud'
]); ?>
</div>
<div class="col3">
<?php echo template::button('configRestoreButton', [
'href' => helper::baseUrl() . 'config/restore',
'value' => 'Restaurer',
'ico' => 'upload-cloud'
]); ?>
</div>
<div class="col3">
<?php echo template::button('configBackupCopyButton', [
'href' => helper::baseUrl() . 'config/copyBackups',
'value' => 'Copie sauvegardes auto',
'ico' => 'download-cloud'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,132 @@
<div id="socialContainer">
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/referencement" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col4 offset1">
<div class="row">
<div class="col12" id="take_screenshoot">
<?php $texte = $_SESSION['screenshot'] === 'on' ? 'Désactiver le mode de capture Open Graph': 'Activer le mode de capture Open Graph';
echo template::button('socialMetaImage', [
'href' => helper::baseUrl() . 'config/configOpenGraph',
'value' => $texte
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::button('socialSiteMap', [
'href' => helper::baseUrl() . 'config/generateFiles',
'value' => 'Générer sitemap.xml et robots.txt'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::checkbox('seoRobots', true, 'Autoriser les robots à référencer le site', [
'checked' => $this->getData(['config', 'seo','robots'])
]); ?>
</div>
</div>
</div>
<div class="col6 offset1">
<?php if (file_exists(self::FILE_DIR.'source/screenshot.jpg')){ ?>
<div class="row">
<div class="col8 offset2 textAlignCenter">
<img src="<?php echo helper::baseUrl(false) . self::FILE_DIR.'source/screenshot.jpg';?>" data-tippy-content="Cette capture d'écran est nécessaire aux partages sur les réseaux sociaux. Pour la régénérer activer le mode de capture Open Graph et cliquer sur l'appareil photo en bas à droite." />
</div>
</div>
<?php } else{?>
<div class="row">
<div class="col8 offset2 textAlignCenter">
<h4>Image screenshot.jpg absente</h4><p>L'activation du mode de capture Open Graph fait apparaître un appareil photo en bas de page. Un clic dessus génère une image screenshot.jpg à partir de la page active.</p>
</div>
</div>
<?php }?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Réseaux sociaux
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/referencement#reseaux-sociaux" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col3">
<?php echo template::text('socialFacebookId', [
'help' => 'Saisissez votre ID : https://www.facebook.com/[ID].',
'label' => 'Facebook',
'value' => $this->getData(['config', 'social', 'facebookId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialInstagramId', [
'help' => 'Saisissez votre ID : https://www.instagram.com/[ID].',
'label' => 'Instagram',
'value' => $this->getData(['config', 'social', 'instagramId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialYoutubeId', [
'help' => 'ID de la chaîne : https://www.youtube.com/channel/[ID].',
'label' => 'Chaîne Youtube',
'value' => $this->getData(['config', 'social', 'youtubeId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialYoutubeUserId', [
'help' => 'Saisissez votre ID Utilisateur : https://www.youtube.com/user/[ID].',
'label' => 'Youtube',
'value' => $this->getData(['config', 'social', 'youtubeUserId'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::text('socialTwitterId', [
'help' => 'Saisissez votre ID : https://twitter.com/[ID].',
'label' => 'Twitter',
'value' => $this->getData(['config', 'social', 'twitterId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialPinterestId', [
'help' => 'Saisissez votre ID : https://pinterest.com/[ID].',
'label' => 'Pinterest',
'value' => $this->getData(['config', 'social', 'pinterestId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialLinkedinId', [
'help' => 'Saisissez votre ID Linkedin : https://fr.linkedin.com/in/[ID].',
'label' => 'Linkedin',
'value' => $this->getData(['config', 'social', 'linkedinId'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('socialGithubId', [
'help' => 'Saisissez votre ID Github : https://github.com/[ID].',
'label' => 'Github',
'value' => $this->getData(['config', 'social', 'githubId'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,297 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class install extends common {
public static $actions = [
'index' => self::GROUP_VISITOR,
'steps' => self::GROUP_ADMIN,
'update' => self::GROUP_ADMIN
];
// Thèmes proposés à l'installation
public static $themes = [];
public static $newVersion;
/**
* Installation
*/
public function index() {
// Accès refusé
if($this->getData(['user']) !== []) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès autorisé
else {
// Soumission du formulaire
if($this->isPost()) {
$success = true;
// Double vérification pour le mot de passe
if($this->getInput('installPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('installConfirmPassword', helper::FILTER_STRING_SHORT, true)) {
self::$inputNotices['installConfirmPassword'] = 'Incorrect';
$success = false;
}
// Utilisateur
$userFirstname = $this->getInput('installFirstname', helper::FILTER_STRING_SHORT, true);
$userLastname = $this->getInput('installLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('installMail', helper::FILTER_MAIL, true);
$userId = $this->getInput('installId', helper::FILTER_ID, true);
// Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données
$success = $this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'forgot' => 0,
'group' => self::GROUP_ADMIN,
'lastname' => $userLastname,
'pseudo' => 'Admin',
'signature' => 1,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true)
]
]);
// Compte créé, envoi du mail et création des données du site
if ($success) { // Formulaire complété envoi du mail
// Envoie le mail
// Sent contient true si réussite sinon code erreur d'envoi en clair
$sent = $this->sendMail(
$userMail,
'Installation de votre site',
'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
'Voici les détails de votre installation.<br><br>' .
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null
);
// Nettoyer les cookies de langue d'une précédente installation
helper::deleteCookie('DELTA_I18N_SITE');
helper::deleteCookie('DELTA_I18N_SCRIPT');
// Installation du site de test
if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === FALSE) {
$this->initData('page','fr',true);
$this->initData('module','fr',true);
}
// Images exemples livrées dans tous les cas
try {
// Décompression dans le dossier de fichier temporaires
if (file_exists(self::TEMP_DIR . 'files.tar.gz')) {
unlink(self::TEMP_DIR . 'files.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'files.tar')) {
unlink(self::TEMP_DIR . 'files.tar');
}
copy('core/module/install/ressource/files.tar.gz', self::TEMP_DIR . 'files.tar.gz');
$pharData = new PharData(self::TEMP_DIR . 'files.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$success = $e->getMessage();
}
unlink(self::TEMP_DIR . 'files.tar.gz');
unlink(self::TEMP_DIR . 'files.tar');
// Stocker le dossier d'installation
$this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]);
// Créer sitemap
$this->createSitemap();
// Installation du thème sélectionné
$dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json');
$dataThemes = json_decode($dataThemes, true);
$themeId = $dataThemes [$this->getInput('installTheme', helper::FILTER_STRING_SHORT)]['filename'];
if ($themeId !== 'default' ) {
$theme = new theme;
$theme->import('core/module/install/ressource/themes/' . $themeId);
}
// Copie des thèmes dans les fichiers
if (!is_dir(self::FILE_DIR . 'source/theme' )) {
mkdir(self::FILE_DIR . 'source/theme');
}
$this->copyDir('core/module/install/ressource/themes', self::FILE_DIR . 'source/theme');
unlink(self::FILE_DIR . 'source/theme/themes.json');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
'notification' => $sent === true ? 'Installation terminée' : $sent,
'state' => ($sent === true && $success === true) ? true : null
]);
}
}
// Récupération de la liste des thèmes
$dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json');
$dataThemes = json_decode($dataThemes, true);
self::$themes = helper::arrayCollumn($dataThemes, 'name');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => 'Installation',
'view' => 'index'
]);
}
}
/**
* Étapes de mise à jour
*/
public function steps() {
switch($this->getInput('step', helper::FILTER_INT)) {
// Préparation
case 1:
$success = true;
// RAZ la mise à jour auto
$this->setData(['core','updateAvailable', false]);
// Backup du dossier Data
helper::autoBackup(self::BACKUP_DIR,['backup','tmp','file']);
// Sauvegarde htaccess
if ($this->getData(['config','autoUpdateHtaccess'])) {
$success = copy('.htaccess', '.htaccess' . '.bak');
}
// Nettoyage des fichiers d'installation précédents
if(file_exists(self::TEMP_DIR.'update.tar.gz') && $success) {
$success = unlink(self::TEMP_DIR.'update.tar.gz');
}
if(file_exists(self::TEMP_DIR.'update.tar') && $success) {
$success = unlink(self::TEMP_DIR.'update.tar');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => null
]
]);
break;
// Téléchargement
case 2:
// Téléchargement depuis le serveur de Zwii
//$success = (file_put_contents(self::TEMP_DIR.'update.tar.gz', helper::urlGetContents('https://zwiicms.fr/update/' . common::DELTA_UPDATE_CHANNEL . '/update.tar.gz')) !== false);
// URL sur le git
//$newVersion = helper::urlGetContents('https://zwiicms.fr/update/' . common::DELTA_UPDATE_CHANNEL . '/version');
$success = (file_put_contents(self::TEMP_DIR.'update.tar.gz', helper::urlGetContents(common::DELTA_UPDATE_URL . common::DELTA_UPDATE_CHANNEL . '/update.tar.gz')) !== false);
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => null
]
]);
break;
// Installation
case 3:
$success = true;
// Check la réécriture d'URL avant d'écraser les fichiers
$rewrite = helper::checkRewrite();
// Décompression et installation
try {
// Décompression dans le dossier de fichier temporaires
$pharData = new PharData(self::TEMP_DIR.'update.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$success = $e->getMessage();
}
// Nettoyage du dossier
if(file_exists(self::TEMP_DIR.'update.tar.gz')) {
unlink(self::TEMP_DIR.'update.tar.gz');
}
if(file_exists(self::TEMP_DIR.'update.tar')) {
unlink(self::TEMP_DIR.'update.tar');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => $rewrite
]
]);
break;
// Configuration
case 4:
$success = true;
$rewrite = $this->getInput('data');
// Réécriture d'URL
if ($rewrite === "true") {
$success = (file_put_contents(
'.htaccess',
PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>',
FILE_APPEND
) !== false);
}
// Recopie htaccess
if ($this->getData(['config','autoUpdateHtaccess']) &&
$success && file_exists( '.htaccess.bak')
) {
// L'écraser avec le backup
$success = copy( '.htaccess.bak' ,'.htaccess' );
// Effacer l ebackup
unlink('.htaccess.bak');
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => null
]
]);
break;
}
}
/**
* Mise à jour
*/
public function update() {
// Nouvelle version
self::$newVersion = helper::urlGetContents(common::DELTA_UPDATE_URL . common::DELTA_UPDATE_CHANNEL . '/version');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => 'Mise à jour',
'view' => 'update'
]);
}
}

View File

@ -0,0 +1,10 @@
# Bloque l'accès aux données
<Files *.json>
Order deny,allow
Deny from all
</Files>
# Bloque l'accès htaccess
<Files .htaccess>
Order deny,allow
Deny from all
</Files>

View File

@ -0,0 +1,878 @@
<?php
class init extends common {
public static $defaultData = [
'config' => [
'analyticsId' => '',
'autoBackup' => true,
'autoUpdate' => true,
'autoUpdateHtaccess' => false,
'favicon' => 'favicon.ico',
'faviconDark' => 'faviconDark.ico',
'maintenance' => false,
'cookieConsent' => true,
'social' => [
'facebookId' => '',
'instagramId' => '',
'pinterestId' => '',
'twitterId' => '',
'youtubeId' => '',
'youtubeUserId' => '',
'githubId' => ''
],
'timezone' => 'Europe/Paris',
'proxyUrl' => '',
'proxyPort' => '',
'proxyType' => 'tcp://',
'smtp' => [
'enable' => false,
],
'seo' => [
'robots' => true
],
'connect' => [
'timeout' => 600,
'attempt' => 3,
'log' => false,
'anonymousIp' => 2,
'captcha' => true,
'captchaStrong' => false,
"captchaType" => 'num',
'autoDisconnect' => true
],
'i18n' => [
'enable'=> true,
'scriptGoogle'=> false,
'showCredits'=> false,
'autoDetect'=> false,
'admin'=> false,
'fr'=> 'none',
'de'=> 'none',
'en'=> 'none',
'es'=> 'none',
'it'=> 'none',
'nl'=> 'none',
'pt'=> 'none'
]
],
'core' => [
'dataVersion' => 3101,
'lastBackup' => 0,
'lastClearTmp' => 0,
'lastAutoUpdate' => 0,
'updateAvailable' => false,
'baseUrl' => ''
],
'locale' => [
'homePageId' => 'accueil',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'DeltaCMS est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Avec DeltaCMS installez votre site en quelques clics !',
'cookies' => [
'cookiesDeltaText' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'cookiesExtText' => '',
'cookiesTitleText' => 'Gérer les cookies',
'cookiesLinkMlText' => 'Consulter les mentions légales',
'cookiesCheckboxExtText' => '',
'cookiesFooterText' => 'Cookies',
'cookiesButtonText' => 'J\'ai compris'
]
],
'page' => [
'accueil' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'accueil.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
]
],
'module' => [],
'user' => [],
'theme' => [
'body' => [
'backgroundColor' => 'rgba(103, 127, 163, 1)',
'image' => '',
'imageAttachment' => 'scroll',
'imageRepeat' => 'no-repeat',
'imagePosition' => 'top center',
'imageSize' => 'auto',
'toTopbackgroundColor' => 'rgba(33, 34, 35, .8)',
'toTopColor' => 'rgba(255, 255, 255, 1)'
],
'footer' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)',
'font' => 'Open+Sans',
'fontSize' => '.8em',
'fontWeight' => 'normal',
'height' => '5px',
'loginLink' => true,
'margin' => true,
'position' => 'site',
'textColor' => 'rgba(33, 34, 35, 1)',
'copyrightPosition' => 'right',
'copyrightAlign' => 'right',
'text' => '<p>Pied de page personnalisé</p>',
'textPosition' => 'left',
'textAlign' => 'left',
'textTransform' => 'none',
'socialsPosition' => 'center',
'socialsAlign' => 'center',
'displayVersion' => true,
'displaySiteMap' => true,
'displayCopyright' => false,
'displayCookie' => false,
'displayLegal' => false,
'displaySearch' => false,
'displayMemberBar' => false,
'template' => '3'
],
'header' => [
'backgroundColor' => 'rgba(32, 59, 82, 1)',
'font' => 'Oswald',
'fontSize' => '2em',
'fontWeight' => 'normal',
'height' => '200px',
'image' => 'theme/defaut/banniere_1500x200.jpg',
'imagePosition' => 'center center',
'imageRepeat' => 'no-repeat',
'margin' => false,
'position' => 'site',
'textAlign' => 'center',
'textColor' => 'rgba(255, 255, 255, 1)',
'textHide' => false,
'textTransform' => 'none',
'linkHomePage' => true,
'imageContainer' => 'auto',
'tinyHidden' => true,
'feature' => 'wallpaper',
'featureContent' => '<p>Bannière vide</p>',
'width' => 'container'
],
'menu' => [
'backgroundColor' => 'rgba(32, 59, 82, 0.85)',
'backgroundColorSub' => 'rgba(32, 59, 82, 1)',
'font' => 'Open+Sans',
'fontSize' => '1em',
'fontWeight' => 'normal',
'height' => '15px 10px',
'loginLink' => false,
'margin' => false,
'position' => 'top',
'textAlign' => 'left',
'textColor' => 'rgba(255, 255, 255, 1)',
'textTransform' => 'none',
'fixed' => true,
'activeColorAuto' => true,
'activeColor' => 'rgba(255, 255, 255, 1)',
'activeTextColor' => 'rgba(255, 255, 255, 1)',
'radius' => '0px',
'memberBar' => true,
'burgerLogo' => '',
'burgerContent' => 'title',
'width' => 'container'
],
'site' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)',
'radius' => '0px',
'shadow' => '0px 0px 0px',
'width' => '100%'
],
'block' => [
'backgroundTitleColor' => 'rgba(230, 230, 230, 1)',
'backgroundColor' => 'rgba(241, 241, 241, 1)',
'borderColor' => 'rgba(230, 230, 230, 1)',
'blockBorderRadius' => '5px',
'blockBorderShadow' => '3px 3px 6px',
],
'text' => [
'font' => 'Open+Sans',
'fontSize' => '13px',
'textColor' => 'rgba(33, 34, 35, 1)',
'linkColor' => 'rgba(74, 105, 189, 1)'
],
'title' => [
'font' => 'Oswald',
'fontWeight' => 'normal',
'textColor' => 'rgba(74, 105, 189, 1)',
'textTransform' => 'none'
],
'button' => [
'backgroundColor' => 'rgba(32, 59, 82, 1)'
],
'version' => 0
],
'admin' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)',
'fontText' => 'open+Sans',
'fontSize' => '13px',
'fontTitle' => 'Oswald',
'colorText' => 'rgba(33, 34, 35, 1)',
'colorTitle' => 'rgba(74, 105, 189, 1)',
'backgroundColorButton' => 'rgba(74, 105, 189, 1)',
'backgroundColorButtonGrey' => 'rgba(170, 180, 188, 1)',
'backgroundColorButtonRed' => 'rgba(217, 95, 78, 1)',
'backgroundColorButtonGreen' => 'rgba(162, 223, 57, 1)',
'backgroundColorButtonHelp' => 'rgba(255, 153, 0, 1)',
'backgroundBlockColor' => 'rgba(236, 239, 241, 1)',
'borderBlockColor' => 'rgba(190, 202, 209, 1)'
],
'blacklist' => []
];
public static $siteData = [
'page' => [
'accueil' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'accueil.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'enfant' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'enfant.html',
'hideTitle' => false,
'breadCrumb' => true,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => 'accueil',
'position' => 1,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Page Enfant',
'shortTitle' => 'Enfant',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'privee' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'privee.html',
'hideTitle' => false,
'breadCrumb' => true,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 2,
'group' => self::GROUP_MEMBER,
'targetBlank' => false,
'title' => 'Page privée',
'shortTitle' => 'Privée',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'mise-en-page' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'mise-en-page.html',
'hideTitle' => false,
'breadCrumb' => true,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => 'accueil',
'modulePosition' => 'bottom',
'position' => 2,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Mise en page',
'shortTitle' => 'Mise en page',
'block' => '4-8',
'barLeft' => 'barre',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'menu-lateral' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'menu-lateral.html',
'hideTitle' => false,
'breadCrumb' => true,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => 'accueil',
'modulePosition' => 'bottom',
'position' => 3,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Barre latérale avec menu',
'shortTitle' => 'Menu latéral',
'block' => '9-3',
'barLeft' => '',
'barRight' => 'barrelateraleavecmenu',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'blog' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'blog.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => 'blog',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 3,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Blog',
'shortTitle' => 'Blog',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'galeries' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'galeries.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => 'gallery',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 4,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Galeries d\'images',
'shortTitle' => 'Galeries',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'contact' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'contact.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => 'form',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 6,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Contact',
'shortTitle' => 'Contact',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'barre' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'barre.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0 ,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Barre latérale',
'shortTitle' => 'Barre latérale',
'block' => 'bar',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'barrelateraleavecmenu' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'barrelateraleavecmenu.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0 ,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Barre latérale avec menu',
'shortTitle' => 'Barre latérale avec menu',
'block' => 'bar',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'parents',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'mentions-legales' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'mentions-legales.html',
'hideTitle' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => 'Mentions Légales',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => 0,
'targetBlank' => false,
'title' => 'Mentions légales',
'shortTitle' => 'Mentions légales',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false
],
'erreur302' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'erreur302.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => '',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Maintenance en cours',
'shortTitle' => 'Maintenance en cours',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => true,
'hideMenuHead' => true,
'hideMenuChildren' => true
],
'erreur403' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'erreur403.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Erreur 403',
'shortTitle' => 'Erreur 403',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false
],
'erreur404' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'erreur404.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => 'search',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Erreur 404',
'shortTitle' => 'Erreur 404',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'recherche' => [
'typeMenu' => 'icon',
'iconUrl' => 'icones/loupe.png',
'disable' => false,
'content' => 'recherche.html',
'hideTitle' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => 'search',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 7,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Recherche dans le site',
'shortTitle' => 'Rechercher',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false
],
],
'module' => [
'blog' => [
'config' => [
'feeds' => true,
'feedsLabel' => 'Syndication RSS',
'itemsperPage' => 4
],
'posts' => [
'premier-article' => [
'closeComment' => false,
'comment' => [],
'content' => '<p>Et eodem impetu Domitianum praecipitem per scalas itidem funibus constrinxerunt, eosque coniunctos per ampla spatia civitatis acri raptavere discursu. iamque artuum et membrorum divulsa conpage superscandentes corpora mortuorum ad ultimam truncata deformitatem velut exsaturati mox abiecerunt in flumen.</p><p>Ex his quidam aeternitati se commendari posse per statuas aestimantes eas ardenter adfectant quasi plus praemii de figmentis aereis sensu carentibus adepturi, quam ex conscientia honeste recteque factorum, easque auro curant inbracteari, quod Acilio Glabrioni delatum est primo, cum consiliis armisque regem superasset Antiochum. quam autem sit pulchrum exigua haec spernentem et minima ad ascensus verae gloriae tendere longos et arduos, ut memorat vates Ascraeus, Censorius Cato monstravit. qui interrogatus quam ob rem inter multos... statuam non haberet malo inquit ambigere bonos quam ob rem id non meruerim, quam quod est gravius cur inpetraverim mussitare.</p><p>Latius iam disseminata licentia onerosus bonis omnibus Caesar nullum post haec adhibens modum orientis latera cuncta vexabat nec honoratis parcens nec urbium primatibus nec plebeiis.</p>',
'picture' => 'galerie/toctoc/b.jpg',
'picturePosition' => 'left',
'hidePicture' => false,
'pictureSize' => 20,
'picturePosition' => 'left',
'publishedOn' => 1639816735,
'state' => true,
'title' => 'Premier article',
'userId' => '', // Géré au moment de l'installation
'editConsent' => 'all',
'commentMaxlength' => '500',
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
],
'second-article' => [
'closeComment' => false,
'comment' => [],
'content' => '<p>Et prima post Osdroenam quam, ut dictum est, ab hac descriptione discrevimus, Commagena, nunc Euphratensis, clementer adsurgit, Hierapoli, vetere Nino et Samosata civitatibus amplis inlustris.</p><p>Ob haec et huius modi multa, quae cernebantur in paucis, omnibus timeri sunt coepta. et ne tot malis dissimulatis paulatimque serpentibus acervi crescerent aerumnarum, nobilitatis decreto legati mittuntur: Praetextatus ex urbi praefecto et ex vicario Venustus et ex consulari Minervius oraturi, ne delictis supplicia sint grandiora, neve senator quisquam inusitato et inlicito more tormentis exponeretur.</p><p>Sed ut tum ad senem senex de senectute, sic hoc libro ad amicum amicissimus scripsi de amicitia. Tum est Cato locutus, quo erat nemo fere senior temporibus illis, nemo prudentior; nunc Laelius et sapiens (sic enim est habitus) et amicitiae gloria excellens de amicitia loquetur. Tu velim a me animum parumper avertas, Laelium loqui ipsum putes. C. Fannius et Q. Mucius ad socerum veniunt post mortem Africani; ab his sermo oritur, respondet Laelius, cuius tota disputatio est de amicitia, quam legens te ipse cognosces.</p>',
'picture' => 'galerie/grece/port.jpg',
'hidePicture' => false,
'picturePosition' => 'right',
'pictureSize' => 40,
'picturePosition' => 'right',
'publishedOn' => 1639816823,
'state' => true,
'title' => 'Second article',
'userId' => '', // Géré au moment de l'installation
'editConsent' => 'all',
'commentMaxlength' => '500',
'commentApproved' => false,
'commentClose' => false,
'commentNotification' => false,
'commentGroupNotification' => 1
],
],
],
'galeries' => [
'content' => [
'toctoc' => [
'config' => [
'name' => 'Toctoc',
'directory' => self::FILE_DIR.'source/galerie/toctoc',
'homePicture' => 'a.jpg',
'sort' => 'SORT_ASC',
'position' => 0,
'fullscreen' => false
],
'legend' => [
'a.jpg' => '',
'b.jpg' => '',
'c.jpg' => ''
],
'positions' => []
],
'grece' => [
'config' => [
'name' => 'Grèce',
'directory' => self::FILE_DIR.'source/galerie/grece',
'homePicture' => 'philosophe.jpg',
'sort' => 'SORT_ASC',
'position' => 1,
'fullscreen' => false
],
'legend' => [
'chapiteaujpg' => 'Chapiteau',
'philosophejpg' => 'Philosophe',
'portjpg' => 'Port'
],
'positions' => []
],
],
'theme' => [
'thumbAlign' => 'center',
'thumbWidth' => '18em',
'thumbHeight' => '15em',
'thumbMargin' => '.5em',
'thumbBorder' => '.1em',
'thumbOpacity' => '.7',
'thumbBorderColor' => 'rgba(221, 221, 221, 1)',
'thumbRadius' => '.3em',
'thumbShadows' => '1px 1px 10px',
'thumbShadowsColor'=> 'rgba(125, 125, 125, 1)',
'legendHeight' => '.375em',
'legendAlign' => 'center',
'legendTextColor' => 'rgba(255, 255, 255, 1)',
'legendBgColor' => 'rgba(0, 0, 0, .6)',
'style' => 'site/data/modules/gallery/galeries.css'
],
'config' => [
'versionData' => '3.0'
],
],
'contact' => [
'config' => [
'button' => '',
'captcha' => true,
'group' => self::GROUP_ADMIN,
'pageId' => '',
'subject' => ''
],
'data' => [],
'input' => [
[
'name' => 'Adresse mail',
'position' => 1,
'required' => true,
'type' => 'mail',
'values' => ''
],
[
'name' => 'Sujet',
'position' => 2,
'required' => true,
'type' => 'text',
'values' => ''
],
[
'name' => 'Message',
'position' => 3,
'required' => true,
'type' => 'textarea',
'values' => ''
]
]
]
],
'locale' => [
'homePageId' => 'accueil',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'metaDescription' => 'DeltaCMS est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Avec DeltaCMS installez votre site en quelques clics !'
]
];
public static $siteContent = [
'accueil' => [
'content' => '<h2>Bienvenue sur votre nouveau site DeltaCMS !</h2>
<p><strong>Un email contenant le récapitulatif de votre installation vient de vous être envoyé.</strong></p>
<p>Connectez-vous dès maintenant à votre espace membre afin de créer un site à votre image ! Vous pourrez personnaliser le thème, créer des pages, ajouter des utilisateurs et bien plus encore !</p>'
],
'enfant' => [
'content' => '<p>Vous pouvez assigner des parents à vos pages afin de mieux organiser votre menu !</p>
<div class="row">
<div class="col4"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac dolor arcu. Cras dignissim finibus nisi, vulputate egestas mauris faucibus ultricies. Nullam ornare pretium eleifend. Donec placerat purus ut turpis dapibus condimentum. Fusce at leo pharetra nisl vestibulum fermentum. Maecenas feugiat justo at semper tincidunt. Integer in blandit lorem.</p></div>
<div class="col4"><p>Ergo ego senator inimicus, si ita vultis, homini, amicus esse, sicut semper fui, rei publicae debeo. Quid? si ipsas inimicitias, depono rei publicae causa, quis me tandem iure reprehendet, praesertim cum ego omnium meorum consiliorum atque factorum exempla semper ex summorum hominum consiliis atque factis mihi censuerim petenda.</p></div>
<div class="col4"><p>Principium autem unde latius se funditabat, emersit ex negotio tali. Chilo ex vicario et coniux eius Maxima nomine, questi apud Olybrium ea tempestate urbi praefectum, vitamque suam venenis petitam adseverantes inpetrarunt ut hi, quos suspectati sunt, ilico rapti conpingerentur in vincula, organarius Sericus et Asbolius palaestrita et aruspex Campensis.</p></div>
</div>'
],
'privee'=> [
'content' => '<p>Cette page n\'est visible que des membres de votre site !</p>
<div class="row">
<div class="col6"><p>Eius populus ab incunabulis primis ad usque pueritiae tempus extremum, quod annis circumcluditur fere trecentis, circummurana pertulit bella, deinde aetatem ingressus adultam post multiplices bellorum aerumnas Alpes transcendit et fretum, in iuvenem erectus et virum ex omni plaga quam orbis ambit inmensus, reportavit laureas et triumphos, iamque vergens in senium et nomine solo aliquotiens vincens ad tranquilliora vitae discessit.</p></div>
<div class="col6"><p>Exsistit autem hoc loco quaedam quaestio subdifficilis, num quando amici novi, digni amicitia, veteribus sint anteponendi, ut equis vetulis teneros anteponere solemus. Indigna homine dubitatio! Non enim debent esse amicitiarum sicut aliarum rerum satietates; veterrima quaeque, ut ea vina, quae vetustatem ferunt, esse debet suavissima; verumque illud est, quod dicitur, multos modios salis simul edendos esse, ut amicitiae munus expletum sit.</p></div>
</div>'
],
'mise-en-page' => [
'content' => '<p>Vous pouvez ajouter une ou deux barres latérales aux pages de votre site. Cette mise en page se définit dans les paramètres de page et peut s\'appliquer à l\'ensemble du site ou à certaines pages en particulier, au gré de vos désirs.</p>
<p>Pour créer une barre latérale à partir d\'une "Nouvelle page" ou transformer une page existante en barre latérale, sélectionnez l\'option dans la liste des gabarits. On peut bien sûr définir autant de barres latérales qu\'on le souhaite.</p>
<p>Cette nouvelle fonctionnalité autorise toutes sortes d\'utilisations : texte, encadrés, images, vidéos... ou simple marge blanche. Seule restriction : on ne peut pas installer un module dans une barre latérale.</p>
<p>La liste des barres disponibles et leur emplacement s\'affichent en fonction du gabarit que vous aurez choisi.'
],
'menu-lateral' => [
'content' => '<p>Cette page illustre la possibilité d\'ajouter un menu dans les barres latérales.<br>
Deux types de menus sont disponibles : l\'un reprenant les rubriques du menu principal comme celui-ci, l\'autre listant les pages d\'une même rubrique. Le choix du type de menu se fait dans la page de configuration d\'une barre latérale.</p>
<p>Pour ajouter un menu à une page, choisissez une barre latérale avec menu dans la page de configuration. Les bulles d\'aide de la rubrique "Menu" expliquent comment masquer une page.</p>'
],
'blog' => [
'content' => '<p>Cette page contient une instance du module de blog. Cliquez sur un article afin de le lire et de poster des commentaires.</p>'
],
'galeries' => [
'content' => '<p>Cette page contient une instance du module de galeries photos. Cliquez sur la galerie ci-dessous afin de voir les photos qu\'elle contient.</p>'
],
'contact' => [
'content' => '<p>Cette page contient un exemple de formulaire conçu à partir du module de génération de formulaires. Il est configuré pour envoyer les données saisies par mail aux administrateurs du site.</p>'
],
'barre' => [
'content' => '<div class="block"><h4>DeltaCMS</h4><h2>Le CMS sans base de données à l\'installation simple et rapide</h2></div>'
],
'barrelateraleavecmenu' => [
'content' => '<p>&nbsp;</p>'
],
'mentions-legales' => [
'content' => '<h1 style="text-align: center;">Conditions g&eacute;n&eacute;rales d\'utilisation</h1>
<h1 style="text-align: center;">En vigueur au 01/06/2020</h1>
<p><strong>Avertissement</strong>Cette page fictive est donn&eacute;e &agrave; titre indicatif elle a &eacute;t&eacute; r&eacute;alis&eacute;e &agrave; l\'aide d\'un g&eacute;n&eacute;rateur : <a href="https://www.legalplace.fr" target="_blank" rel="noopener">https://www.legalplace.fr</a></p>
<p justify="">Les pr&eacute;sentes conditions g&eacute;n&eacute;rales d\'utilisation (dites &laquo; CGU &raquo;) ont pour objet l\'encadrement juridique des modalit&eacute;s de mise &agrave; disposition du site et des services par et de d&eacute;finir les conditions d&rsquo;acc&egrave;s et d&rsquo;utilisation des services par &laquo; l\'Utilisateur &raquo;.</p>
<p justify="">Les pr&eacute;sentes CGU sont accessibles sur le site &agrave; la rubrique &laquo;CGU&raquo;.</p>
<p justify="">Toute inscription ou utilisation du site implique l\'acceptation sans aucune r&eacute;serve ni restriction des pr&eacute;sentes CGU par l&rsquo;utilisateur. Lors de l\'inscription sur le site via le Formulaire d&rsquo;inscription, chaque utilisateur accepte express&eacute;ment les pr&eacute;sentes CGU en cochant la case pr&eacute;c&eacute;dant le texte suivant : &laquo; Je reconnais avoir lu et compris les CGU et je les accepte &raquo;.</p>
<p justify="">En cas de non-acceptation des CGU stipul&eacute;es dans le pr&eacute;sent contrat, l\'Utilisateur se doit de renoncer &agrave; l\'acc&egrave;s des services propos&eacute;s par le site.</p>
<p justify="">www.site.com se r&eacute;serve le droit de modifier unilat&eacute;ralement et &agrave; tout moment le contenu des pr&eacute;sentes CGU.</p>
<h2>Article 1 : Les mentions l&eacute;gales</h2>
<p justify="">L&rsquo;&eacute;dition et la direction de la publication du site www.site.com est assur&eacute;e par John Doe, domicili&eacute; 1 rue de Paris - 75016 PARIS.</p>
<p justify="">Num&eacute;ro de t&eacute;l&eacute;phone est 0102030405</p>
<p justify="">Adresse e-mail john.doe@deltacms.fr.</p>
<p justify="">L\'h&eacute;bergeur du site www.site.com est la soci&eacute;t&eacute; Nom de l\'h&eacute;bergeur, dont le si&egrave;ge social est situ&eacute; au 12 rue de Lyon - 69001 Lyon, avec le num&eacute;ro de t&eacute;l&eacute;phone : 0401020305.</p>
<h2>ARTICLE 2&nbsp;: Acc&egrave;s au site</h2>
<p justify="">Le site www.site.com permet &agrave; l\'Utilisateur un acc&egrave;s gratuit aux services suivants :</p>
<p justify="">Le site internet propose les services suivants :</p>
<p justify="">Publication</p>
<p justify="">Le site est accessible gratuitement en tout lieu &agrave; tout Utilisateur ayant un acc&egrave;s &agrave; Internet. Tous les frais support&eacute;s par l\'Utilisateur pour acc&eacute;der au service (mat&eacute;riel informatique, logiciels, connexion Internet, etc.) sont &agrave; sa charge.</p>
<p justify="">L&rsquo;Utilisateur non membre n\'a pas acc&egrave;s aux services r&eacute;serv&eacute;s. Pour cela, il doit s&rsquo;inscrire en remplissant le formulaire. En acceptant de s&rsquo;inscrire aux services r&eacute;serv&eacute;s, l&rsquo;Utilisateur membre s&rsquo;engage &agrave; fournir des informations sinc&egrave;res et exactes concernant son &eacute;tat civil et ses coordonn&eacute;es, notamment son adresse email.</p>
<p justify="">Pour acc&eacute;der aux services, l&rsquo;Utilisateur doit ensuite s\'identifier &agrave; l\'aide de son identifiant et de son mot de passe qui lui seront communiqu&eacute;s apr&egrave;s son inscription.</p>
<p justify="">Tout Utilisateur membre r&eacute;guli&egrave;rement inscrit pourra &eacute;galement solliciter sa d&eacute;sinscription en se rendant &agrave; la page d&eacute;di&eacute;e sur son espace personnel. Celle-ci sera effective dans un d&eacute;lai raisonnable.</p>
<p justify="">Tout &eacute;v&eacute;nement d&ucirc; &agrave; un cas de force majeure ayant pour cons&eacute;quence un dysfonctionnement du site ou serveur et sous r&eacute;serve de toute interruption ou modification en cas de maintenance, n\'engage pas la responsabilit&eacute; de www.site.com. Dans ces cas, l&rsquo;Utilisateur accepte ainsi ne pas tenir rigueur &agrave; l&rsquo;&eacute;diteur de toute interruption ou suspension de service, m&ecirc;me sans pr&eacute;avis.</p>
<p justify="">L\'Utilisateur a la possibilit&eacute; de contacter le site par messagerie &eacute;lectronique &agrave; l&rsquo;adresse email de l&rsquo;&eacute;diteur communiqu&eacute; &agrave; l&rsquo;ARTICLE 1.</p>
<h2>ARTICLE 3 : Collecte des donn&eacute;es</h2>
<p justify="">Le site est exempt&eacute; de d&eacute;claration &agrave; la Commission Nationale Informatique et Libert&eacute;s (CNIL) dans la mesure o&ugrave; il ne collecte aucune donn&eacute;e concernant les Utilisateurs.</p>
<h2>ARTICLE 4&nbsp;: Propri&eacute;t&eacute; intellectuelle</h2>
<p>Les marques, logos, signes ainsi que tous les contenus du site (textes, images, son&hellip;) font l\'objet d\'une protection par le Code de la propri&eacute;t&eacute; intellectuelle et plus particuli&egrave;rement par le droit d\'auteur.</p>
<p>L\'Utilisateur doit solliciter l\'autorisation pr&eacute;alable du site pour toute reproduction, publication, copie des diff&eacute;rents contenus. Il s\'engage &agrave; une utilisation des contenus du site dans un cadre strictement priv&eacute;, toute utilisation &agrave; des fins commerciales et publicitaires est strictement interdite.</p>
<p>Toute repr&eacute;sentation totale ou partielle de ce site par quelque proc&eacute;d&eacute; que ce soit, sans l&rsquo;autorisation expresse de l&rsquo;exploitant du site Internet constituerait une contrefa&ccedil;on sanctionn&eacute;e par l&rsquo;article L 335-2 et suivants du Code de la propri&eacute;t&eacute; intellectuelle.</p>
<p>Il est rappel&eacute; conform&eacute;ment &agrave; l&rsquo;article L122-5 du Code de propri&eacute;t&eacute; intellectuelle que l&rsquo;Utilisateur qui reproduit, copie ou publie le contenu prot&eacute;g&eacute; doit citer l&rsquo;auteur et sa source.</p>
<h2>ARTICLE 5&nbsp;: Responsabilit&eacute;</h2>
<p justify="">Les sources des informations diffus&eacute;es sur le site www.site.com sont r&eacute;put&eacute;es fiables mais le site ne garantit pas qu&rsquo;il soit exempt de d&eacute;fauts, d&rsquo;erreurs ou d&rsquo;omissions.</p>
<p justify="">Les informations communiqu&eacute;es sont pr&eacute;sent&eacute;es &agrave; titre indicatif et g&eacute;n&eacute;ral sans valeur contractuelle. Malgr&eacute; des mises &agrave; jour r&eacute;guli&egrave;res, le site www.site.com&nbsp;ne peut &ecirc;tre tenu responsable de la modification des dispositions administratives et juridiques survenant apr&egrave;s la publication. De m&ecirc;me, le site ne peut &ecirc;tre tenue responsable de l&rsquo;utilisation et de l&rsquo;interpr&eacute;tation de l&rsquo;information contenue dans ce site.</p>
<p justify="">L\'Utilisateur s\'assure de garder son mot de passe secret. Toute divulgation du mot de passe, quelle que soit sa forme, est interdite. Il assume les risques li&eacute;s &agrave; l\'utilisation de son identifiant et mot de passe. Le site d&eacute;cline toute responsabilit&eacute;.</p>
<p justify="">Le site www.site.com&nbsp;ne peut &ecirc;tre tenu pour responsable d&rsquo;&eacute;ventuels virus qui pourraient infecter l&rsquo;ordinateur ou tout mat&eacute;riel informatique de l&rsquo;Internaute, suite &agrave; une utilisation, &agrave; l&rsquo;acc&egrave;s, ou au t&eacute;l&eacute;chargement provenant de ce site.</p>
<p justify="">La responsabilit&eacute; du site ne peut &ecirc;tre engag&eacute;e en cas de force majeure ou du fait impr&eacute;visible et insurmontable d\'un tiers.</p>
<h2>ARTICLE 6&nbsp;: Liens hypertextes</h2>
<p justify="">Des liens hypertextes peuvent &ecirc;tre pr&eacute;sents sur le site. L&rsquo;Utilisateur est inform&eacute; qu&rsquo;en cliquant sur ces liens, il sortira du site www.site.com. Ce dernier n&rsquo;a pas de contr&ocirc;le sur les pages web sur lesquelles aboutissent ces liens et ne saurait, en aucun cas, &ecirc;tre responsable de leur contenu.</p>
<h2>ARTICLE 7 : Cookies</h2>
<p justify="">L&rsquo;Utilisateur est inform&eacute; que lors de ses visites sur le site, un cookie peut s&rsquo;installer automatiquement sur son logiciel de navigation.</p>
<p justify="">Les cookies sont de petits fichiers stock&eacute;s temporairement sur le disque dur de l&rsquo;ordinateur de l&rsquo;Utilisateur par votre navigateur et qui sont n&eacute;cessaires &agrave; l&rsquo;utilisation du site www.site.com. Les cookies ne contiennent pas d&rsquo;information personnelle et ne peuvent pas &ecirc;tre utilis&eacute;s pour identifier quelqu&rsquo;un. Un cookie contient un identifiant unique, g&eacute;n&eacute;r&eacute; al&eacute;atoirement et donc anonyme. Certains cookies expirent &agrave; la fin de la visite de l&rsquo;Utilisateur, d&rsquo;autres restent.</p>
<p justify="">L&rsquo;information contenue dans les cookies est utilis&eacute;e pour am&eacute;liorer le site www.site.com.</p>
<p justify="">En naviguant sur le site, L&rsquo;Utilisateur les accepte.</p>
<p justify="">L&rsquo;Utilisateur doit toutefois donner son consentement quant &agrave; l&rsquo;utilisation de certains cookies.</p>
<p justify="">A d&eacute;faut d&rsquo;acceptation, l&rsquo;Utilisateur est inform&eacute; que certaines fonctionnalit&eacute;s ou pages risquent de lui &ecirc;tre refus&eacute;es.</p>
<p justify="">L&rsquo;Utilisateur pourra d&eacute;sactiver ces cookies par l&rsquo;interm&eacute;diaire des param&egrave;tres figurant au sein de son logiciel de navigation.</p>
<h2>ARTICLE 8&nbsp;: Droit applicable et juridiction comp&eacute;tente</h2>
<p justify="">La l&eacute;gislation fran&ccedil;aise s\'applique au pr&eacute;sent contrat. En cas d\'absence de r&eacute;solution amiable d\'un litige n&eacute; entre les parties, les tribunaux fran&ccedil;ais seront seuls comp&eacute;tents pour en conna&icirc;tre.</p>
<p justify="">Pour toute question relative &agrave; l&rsquo;application des pr&eacute;sentes CGU, vous pouvez joindre l&rsquo;&eacute;diteur aux coordonn&eacute;es inscrites &agrave; l&rsquo;ARTICLE 1.</p>'
],
'erreur302' => [
'content' =>'<p>Notre site est actuellement en maintenance. Nous sommes d&eacute;sol&eacute;s pour la g&ecirc;ne occasionn&eacute;e et faisons notre possible pour &ecirc;tre rapidement de retour.</p>
<div class="row"><div class="col4 offset8 textAlignCenter"><a href="./?user/login" id="maintenanceLogin" name="maintenanceLogin" class="button"><span class="zwiico-lock zwiico-margin-right"></span>Administration</a></div></div>'
],
'erreur403' => [
'content' => '<h2 style="text-align: center;">Vous n\'êtes pas autorisé à accéder à cette page...</h2><p style="text-align: center;">Personnalisez cette page à votre convenance sans qu\'elle apparaisse dans les menus.<p>'
],
'erreur404' => [
'content' => '<h2 style="text-align: center;">Oups ! La page demandée est introuvable...</h2><p style="text-align: center;">Personnalisez cette page à votre convenance sans qu\'elle apparaisse dans les menus.<p>'
],
'recherche' => [
'content' => '<h1>Rechercher dans le site</h1>'
]
];
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,18 @@
{
"defaut" : {
"name": "Le thème par défaut, ambiance bleue, largeur 100%",
"filename": ""
},
"montagne": {
"name": "Thème avec ambiance montagne, largeur 960px",
"filename": "theme_montagne_960px.zip"
},
"hirondelles": {
"name": "Thème avec ambiance bleue, largeur 960px",
"filename": "theme_hirondelles_960px.zip"
},
"fluide": {
"name": "Thème sans bannière avec ambiance grise, largeur 100%",
"filename": "theme_sansbanniere_fluide.zip"
}
}

View File

@ -0,0 +1 @@
/* Vide */

View File

@ -0,0 +1,40 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Affichage de l'id en simulant FILTER_ID
*/
$("#installId").on("change keydown keyup", function(event) {
var userId = $(this).val();
if(
event.keyCode !== 8 // BACKSPACE
&& event.keyCode !== 37 // LEFT
&& event.keyCode !== 39 // RIGHT
&& event.keyCode !== 46 // DELETE
&& window.getSelection().toString() !== userId // Texte sélectionné
) {
var searchReplace = {
"á": "a", "à": "a", "â": "a", "ä": "a", "ã": "a", "å": "a", "ç": "c", "é": "e", "è": "e", "ê": "e", "ë": "e", "í": "i", "ì": "i", "î": "i", "ï": "i", "ñ": "n", "ó": "o", "ò": "o", "ô": "o", "ö": "o", "õ": "o", "ú": "u", "ù": "u", "û": "u", "ü": "u", "ý": "y", "ÿ": "y",
"Á": "A", "À": "A", "Â": "A", "Ä": "A", "Ã": "A", "Å": "A", "Ç": "C", "É": "E", "È": "E", "Ê": "E", "Ë": "E", "Í": "I", "Ì": "I", "Î": "I", "Ï": "I", "Ñ": "N", "Ó": "O", "Ò": "O", "Ô": "O", "Ö": "O", "Õ": "O", "Ú": "U", "Ù": "U", "Û": "U", "Ü": "U", "Ý": "Y", "Ÿ": "Y",
"'": "-", "\"": "-", " ": "-"
};
userId = userId.replace(/[áàâäãåçéèêëíìîïñóòôöõúùûüýÿ'" ]/ig, function(match) {
return searchReplace[match];
});
userId = userId.replace(/[^a-z0-9-]/ig, "");
$(this).val(userId);
}
});

View File

@ -0,0 +1,61 @@
<p>Renseignez les champs ci-dessous pour finaliser l'installation.</p>
<?php echo template::formOpen('installForm'); ?>
<?php echo template::text('installId', [
'autocomplete' => 'off',
'label' => 'Identifiant'
]); ?>
<div class="row">
<div class="col6">
<?php echo template::password('installPassword', [
'autocomplete' => 'off',
'label' => 'Mot de passe'
]); ?>
</div>
<div class="col6">
<?php echo template::password('installConfirmPassword', [
'autocomplete' => 'off',
'label' => 'Confirmation'
]); ?>
</div>
</div>
<?php echo template::mail('installMail', [
'autocomplete' => 'off',
'label' => 'Adresse mail'
]); ?>
<div class="row">
<div class="col6">
<?php echo template::text('installFirstname', [
'autocomplete' => 'off',
'label' => 'Prénom'
]); ?>
</div>
<div class="col6">
<?php echo template::text('installLastname', [
'autocomplete' => 'off',
'label' => 'Nom'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('installTheme', $module::$themes, [
'label' => 'Thème'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::checkbox('installDefaultData',true , 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [
'checked' => false
]);
?>
</div>
</div>
<div class="row">
<div class="col3 offset9">
<?php echo template::submit('installSubmit', [
'value' => 'Installer'
]); ?>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,63 @@
/**
* Exécution des différentes étapes de mise à jour
*/
function step(i, data) {
// Affiche le texte de progression
$(".installUpdateProgressText").hide();
$(".installUpdateProgressText[data-id=" + i + "]").show();
// Requête ajax
$.ajax({
type: "POST",
url: "<?php echo helper::baseUrl(false); ?>?install/steps", // Ignore la réécriture d'URL
data: {
step: i,
data: data
},
// Succès de la requête
success: function(result) {
setTimeout(function() {
// Succès
if(result.success === true) {
// Fin de la mise à jour
if(i === 4) {
// Affiche le message de succès
$("#installUpdateSuccess").show();
// Déverrouille le bouton "Terminer"
$("#installUpdateEnd").removeClass("disabled");
// Cache le texte de progression
$("#installUpdateProgress").hide();
}
// Prochaine étape
else {
step(i + 1, result.data);
}
}
// Échec
else {
// Affiche le message d'erreur
$("#installUpdateErrorStep").text(i);
$("#installUpdateError").show();
// Déverrouille le bouton "Terminer"
$("#installUpdateEnd").removeClass("disabled");
// Cache le texte de progression
$("#installUpdateProgress").hide();
// Affiche le résultat dans la console
console.error(result);
}
}, 2000);
},
// Échec de la requête
error: function(xhr) {
// Affiche le message d'erreur
$("#installUpdateErrorStep").text(0);
$("#installUpdateError").show();
// Déverrouille le bouton "Terminer"
$("#installUpdateEnd").removeClass("disabled");
// Cache le texte de progression
$("#installUpdateProgress").hide();
// Affiche l'erreur dans la console
console.error(xhr);
}
});
}
$(window).on("load", step(1, null));

View File

@ -0,0 +1,29 @@
<p><strong>Mise à jour de Deltacms <?php echo self::DELTA_VERSION; ?> vers Deltacms <?php echo $module::$newVersion; ?>.</strong></p>
<p>Afin d'assurer le bon fonctionnement de Deltacms, veuillez ne pas fermer cette page avant la fin de l'opération.</p>
<div class="row">
<div class="col9 verticalAlignMiddle">
<div id="installUpdateProgress">
<?php echo template::ico('spin', '', true); ?>
<span class="installUpdateProgressText" data-id="1">1/4 : Préparation...</span>
<span class="installUpdateProgressText displayNone" data-id="2">2/4 : Téléchargement...</span>
<span class="installUpdateProgressText displayNone" data-id="3">3/4 : Installation...</span>
<span class="installUpdateProgressText displayNone" data-id="4">4/4 : Configuration...</span>
</div>
<div id="installUpdateError" class="colorRed displayNone">
<?php echo template::ico('cancel', ''); ?>
Une erreur est survenue lors de l'étape <span id="installUpdateErrorStep"></span>.
</div>
<div id="installUpdateSuccess" class="colorGreen displayNone">
<?php echo template::ico('check', ''); ?>
Mise à jour terminée avec succès.
</div>
</div>
<div class="col3 verticalAlignMiddle">
<?php echo template::button('installUpdateEnd', [
'value' => 'Terminer',
'href' => helper::baseUrl() . 'config',
'ico' => 'check',
'class' => 'disabled'
]); ?>
</div>
</div>

View File

@ -0,0 +1,56 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class maintenance extends common {
public static $actions = [
'index' => self::GROUP_VISITOR
];
/**
* Maintenance
*/
public function index() {
// Redirection vers l'accueil après rafraîchissement et que la maintenance est terminée.
if($this->getData(['config', 'maintenance']) == False){
header('Location:' . helper::baseUrl());
exit();
}
// Page perso définie et existante
if ($this->getData(['locale','page302']) !== 'none'
AND $this->getData(['page',$this->getData(['locale','page302'])]) ) {
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => $this->getData(['page',$this->getData(['locale','page302']),'hideTitle'])
? ''
: $this->getData(['page',$this->getData(['locale','page302']),'title']),
//'content' => $this->getdata(['page',$this->getData(['locale','page302']),'content']),
'content' => $this->getPage($this->getData(['locale','page302']), self::$i18n),
'view' => 'index'
]);
} else {
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => 'Maintenance en cours...',
'view' => 'index'
]);
}
}
}

View File

@ -0,0 +1 @@
/* vide */

View File

@ -0,0 +1,10 @@
<p>Notre site est actuellement en maintenance. Nous sommes désolés pour la gêne occasionnée et faisons notre possible pour être rapidement de retour.</p>
<div class="row">
<div class="col4 offset8 textAlignCenter">
<?php echo template::button('maintenanceLogin', [
'value' => 'Connexion',
'href' => helper::baseUrl() . 'user/login',
'ico' => 'lock'
]); ?>
</div>
</div>

514
core/module/page/page.php Normal file
View File

@ -0,0 +1,514 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class page extends common {
public static $actions = [
'add' => self::GROUP_MODERATOR,
'delete' => self::GROUP_MODERATOR,
'edit' => self::GROUP_MODERATOR,
'duplicate' => self::GROUP_MODERATOR
];
public static $pagesNoParentId = [
'' => 'Aucune'
];
public static $pagesBarId = [
'' => 'Aucune'
];
public static $moduleIds = [];
public static $typeMenu = [
'text' => 'Texte',
'icon' => 'Icône',
'icontitle' => 'Icône avec bulle de texte'
];
// Position du module
public static $modulePosition = [
'bottom' => 'En bas',
'top' => 'En haut',
'free' => 'Libre'
];
public static $pageBlocks = [
'12' => 'Page standard',
'4-8' => 'Barre 1/3 - page 2/3',
'8-4' => 'Page 2/3 - barre 1/3',
'3-9' => 'Barre 1/4 - page 3/4',
'9-3' => 'Page 3/4 - barre 1/4',
'3-6-3' => 'Barre 1/4 - page 1/2 - barre 1/4',
'2-7-3' => 'Barre 2/12 - page 7/12 - barre 3/12 ',
'3-7-2' => 'Barre 3/12 - page 7/12 - barre 2/12 ',
'bar' => 'Barre latérale'
];
public static $displayMenu = [
'none' => 'Aucun',
'parents' => 'Le menu',
'children' => 'Le sous-menu de la page parente'
];
/**
* Duplication
*/
public function duplicate() {
// Adresse sans le token
$url = explode('&',$this->getUrl(2));
// La page n'existe pas
if($this->getData(['page', $url[0]]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} // Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Suppression non autorisée'
]);
}
// Duplication de la page
$pageTitle = $this->getData(['page',$url[0],'title']);
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$pageId = helper::increment($pageId, self::$coreModuleIds);
$pageId = helper::increment($pageId, self::$moduleIds);
$data = $this->getData([
'page',
$url[0]
]);
// Ecriture
$this->setData (['page',$pageId,$data]);
$notification = 'La page a été dupliquée';
// Duplication du module présent
if ($this->getData(['page',$url[0],'moduleId'])) {
$data = $this->getData([
'module',
$url[0]
]);
// Ecriture
$this->setData (['module',$pageId,$data]);
$notification = 'La page et son module ont été dupliqués';
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification,
'state' => true
]);
}
/**
* Création
*/
public function add() {
$pageTitle = 'Nouvelle page';
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$this->setData([
'page',
$pageId,
[
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => $pageId . '.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => $pageTitle,
'shortTitle' => $pageTitle,
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => '0',
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18n . '/content')) {
mkdir(self::DATA_DIR . self::$i18n . '/content', 0755);
}
//file_put_contents(self::DATA_DIR . self::$i18n . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18n);
// Met à jour le site map
$this->createSitemap('all');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId,
'notification' => 'Nouvelle page créée',
'state' => true
]);
}
/**
* Suppression
*/
public function delete() {
// $url prend l'adresse sans le token
$url = explode('&',$this->getUrl(2));
// La page n'existe pas
if($this->getData(['page', $url[0]]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} // Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Suppression non autorisée'
]);
}
// Impossible de supprimer la page d'accueil
elseif($url[0] === $this->getData(['locale', 'homePageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page de recherche affectée
elseif($url[0] === $this->getData(['locale', 'searchPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['locale', 'legalPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['locale', 'page404'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['locale', 'page403'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['locale', 'page302'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Suppression non autorisée'
]);
}
// Impossible de supprimer une page contenant des enfants
elseif($this->getHierarchy($url[0],null)) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Impossible de supprimer une page contenant des enfants'
]);
}
// Suppression
else {
// Effacer le dossier du module
$moduleId = $this->getData(['page',$url[0],'moduleId']);
$modulesData = helper::getModules();
if (is_dir($modulesData[$moduleId]['dataDirectory']. $url[0])) {
$this->removeDir( $modulesData[$moduleId]['dataDirectory']. $url[0] );
}
// Effacer la page
$this->deleteData(['page', $url[0]]);
if (file_exists(self::DATA_DIR . self::$i18n . '/content/' . $url[0] . '.html')) {
unlink(self::DATA_DIR . self::$i18n . '/content/' . $url[0] . '.html');
}
$this->deleteData(['module', $url[0]]);
// Met à jour le site map
$this->createSitemap('all');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
'notification' => 'Page supprimée',
'state' => true
]);
}
}
/**
* Édition
*/
public function edit() {
// La page n'existe pas
if($this->getData(['page', $this->getUrl(2)]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// La page existe
else {
// Soumission du formulaire
if($this->isPost()) {
// Si le Title n'est pas vide, premier test pour positionner la notification du champ obligatoire
if( $this->getInput('pageEditTitle', helper::FILTER_ID, true) !== null && $this->getInput('pageEditTitle') !== '' ){
// Génére l'ID si le titre de la page a changé
if ( $this->getInput('pageEditTitle') !== $this->getData(['page',$this->getUrl(2),'title']) ) {
$pageId = $this->getInput('pageEditTitle', helper::FILTER_ID, true);
} else {
$pageId = $this->getUrl(2);
}
// un dossier existe du même nom (erreur en cas de redirection)
if (file_exists($pageId)) {
$pageId = uniqid($pageId);
}
// Si l'id a changée
if ($pageId !== $this->getUrl(2)) {
// Incrémente le nouvel id de la page
$pageId = helper::increment($pageId, $this->getData(['page']));
$pageId = helper::increment($pageId, self::$coreModuleIds);
$pageId = helper::increment($pageId, self::$moduleIds);
// Met à jour les enfants
foreach($this->getHierarchy($this->getUrl(2),null) as $childrenPageId) {
$this->setData(['page', $childrenPageId, 'parentPageId', $pageId]);
}
// Change l'id de page dans les données des modules
if ($this->getData(['module', $this->getUrl(2)]) !== null ) {
$this->setData(['module', $pageId, $this->getData(['module', $this->getUrl(2)])]);
$this->deleteData(['module', $this->getUrl(2)]);
// Renommer le dossier du module
$moduleId = $this->getData(['page',$this->getUrl(2),'moduleId']);
$modulesData = helper::getModules();
if (is_dir($modulesData[$moduleId]['dataDirectory']. $this->getUrl(2))) {
// Placer la feuille de style dans un dossier au nom de la nouvelle instance
mkdir( $modulesData[$moduleId]['dataDirectory']. $pageId, 0755 );
copy( $modulesData[$moduleId]['dataDirectory']. $this->getUrl(2), $modulesData[$moduleId]['dataDirectory']. $pageId);
$this->removeDir($modulesData[$moduleId]['dataDirectory']. $this->getUrl(2));
// Mettre à jour le nom de la feuille de style
$this->setData(['module',$pageId,'theme','style', $modulesData[$moduleId]['dataDirectory']. $pageId]);
}
}
// Si la page correspond à la page d'accueil, change l'id dans la configuration du site
if($this->getData(['locale', 'homePageId']) === $this->getUrl(2)) {
$this->setData(['locale', 'homePageId', $pageId]);
}
}
// Supprime les données du module en cas de changement de module
if($this->getInput('pageEditModuleId') !== $this->getData(['page', $this->getUrl(2), 'moduleId'])) {
$this->deleteData(['module', $pageId]);
}
// Supprime l'ancienne page si l'id a changée
if($pageId !== $this->getUrl(2)) {
$this->deleteData(['page', $this->getUrl(2)]);
unlink (self::DATA_DIR . self::$i18n . '/content/' . $this->getUrl(2) . '.html');
}
// Traitement des pages spéciales affectées dans la config :
if ($this->getUrl(2) === $this->getData(['locale', 'legalPageId']) ) {
$this->setData(['locale','legalPageId', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['locale', 'searchPageId']) ) {
$this->setData(['locale','searchPageId', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['locale', 'page404']) ) {
$this->setData(['locale','page404', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['locale', 'page403']) ) {
$this->setData(['locale','page403', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['locale', 'page302']) ) {
$this->setData(['locale','page302', $pageId]);
}
// Si la page est une page enfant, actualise les positions des autres enfants du parent, sinon actualise les pages sans parents
$lastPosition = 1;
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());
$position = $this->getInput('pageEditPosition', helper::FILTER_INT);
foreach($hierarchy as $hierarchyPageId) {
// Ignore la page en cours de modification
if($hierarchyPageId === $this->getUrl(2)) {
continue;
}
// Incrémente de +1 pour laisser la place à la position de la page en cours de modification
if($lastPosition === $position) {
$lastPosition++;
}
// Change la position
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition]);
// Incrémente pour la prochaine position
$lastPosition++;
}
if ($this->getinput('pageEditBlock') !== 'bar') {
$barLeft = $this->getinput('pageEditBarLeft');
$barRight = $this->getinput('pageEditBarRight');
$hideTitle = $this->getInput('pageEditHideTitle', helper::FILTER_BOOLEAN);
} else {
// Une barre ne peut pas avoir de barres
$barLeft = "";
$barRight = "";
// Une barre est masquée
$position = 0;
$hideTitle = true;
}
// Modifie la page ou en crée une nouvelle si l'id a changé
$this->setData([
'page',
$pageId,
[
'typeMenu' => $this->getinput('pageTypeMenu'),
'iconUrl' => $this->getinput('pageIconUrl'),
'disable'=> $this->getinput('pageEditDisable', helper::FILTER_BOOLEAN),
'content' => $pageId . '.html',
'hideTitle' => $hideTitle,
'breadCrumb' => $this->getInput('pageEditbreadCrumb', helper::FILTER_BOOLEAN),
'metaDescription' => $this->getInput('pageEditMetaDescription', helper::FILTER_STRING_LONG),
'metaTitle' => $this->getInput('pageEditMetaTitle'),
'moduleId' => $this->getInput('pageEditModuleId'),
'modulePosition' => $this->getInput('configModulePosition'),
'parentPageId' => $this->getInput('pageEditParentPageId'),
'position' => $position,
'group' => $this->getinput('pageEditBlock') !== 'bar' ? $this->getInput('pageEditGroup', helper::FILTER_INT) : 0,
'targetBlank' => $this->getInput('pageEditTargetBlank', helper::FILTER_BOOLEAN),
'title' => $this->getInput('pageEditTitle', helper::FILTER_STRING_SHORT),
'shortTitle' => $this->getInput('pageEditShortTitle', helper::FILTER_STRING_SHORT, true),
'block' => $this->getinput('pageEditBlock'),
'barLeft' => $barLeft,
'barRight' => $barRight,
'displayMenu' => $this->getinput('pageEditDisplayMenu'),
'hideMenuSide' => $this->getinput('pageEditHideMenuSide', helper::FILTER_BOOLEAN),
'hideMenuHead' => $this->getinput('pageEditHideMenuHead', helper::FILTER_BOOLEAN),
'hideMenuChildren' => $this->getinput('pageEditHideMenuChildren', helper::FILTER_BOOLEAN),
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18n . '/content')) {
mkdir(self::DATA_DIR . self::$i18n . '/content', 0755);
}
$content = empty($this->getInput('pageEditContent', null)) ? '<p></p>' : str_replace('<p></p>', '<p>&nbsp;</p>', $this->getInput('pageEditContent', null));
//file_put_contents( self::DATA_DIR . self::$i18n . '/content/' . $pageId . '.html' , $content );
$this->setPage($pageId , $content, self::$i18n);
// Barre renommée : changement le nom de la barre dans les pages mères
if ($this->getinput('pageEditBlock') === 'bar') {
foreach ($this->getHierarchy() as $eachPageId=>$parentId) {
if ($this->getData(['page',$eachPageId,'barRight']) === $this->getUrl(2)) {
$this->setData(['page',$eachPageId,'barRight',$pageId]);
}
if ($this->getData(['page',$eachPageId,'barLeft']) === $this->getUrl(2)) {
$this->setData(['page',$eachPageId,'barLeft',$pageId]);
}
foreach ($parentId as $childId) {
if ($this->getData(['page',$childId,'barRight']) === $this->getUrl(2)) {
$this->setData(['page',$childId,'barRight',$pageId]);
}
if ($this->getData(['page',$childId,'barLeft']) === $this->getUrl(2)) {
$this->setData(['page',$childId,'barLeft',$pageId]);
}
}
}
}
// Met à jour le site map
$this->createSitemap('all');
// Redirection vers la configuration
if($this->getInput('pageEditModuleRedirect', helper::FILTER_BOOLEAN)) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId . '/config',
'state' => true
]);
}
// Redirection vers la page
else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId,
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
}
}
self::$moduleIds = array_merge( ['' => 'Aucun'] , helper::arrayCollumn(helper::getModules(),'realName','SORT_ASC')); // Pages sans parent
foreach($this->getHierarchy() as $parentPageId => $childrenPageIds) {
if($parentPageId !== $this->getUrl(2)) {
self::$pagesNoParentId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
}
}
// Pages barre latérales
foreach($this->getHierarchy(null,false,true) as $parentPageId => $childrenPageIds) {
if($parentPageId !== $this->getUrl(2) &&
$this->getData(['page', $parentPageId, 'block']) === 'bar') {
self::$pagesBarId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
}
}
// Mise à jour de la liste des pages pour TinyMCE
$this->pages2Json();
// Valeurs en sortie
$this->addOutput([
'title' => $this->getData(['page', $this->getUrl(2), 'title']),
'vendor' => [
'tinymce'
],
'view' => 'edit'
]);
}
}
}

View File

@ -0,0 +1,19 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,590 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Confirmation de suppression
*/
$("#pageEditDelete").on("click", function() {
var _this = $(this);
return core.confirm("Confirmez-vous la suppression de cette page ?", function() {
$(location).attr("href", _this.attr("href"));
});
});
$("#pageEditModuleId").on("click", function() {
protectModule();
});
function protectModule() {
var oldModule = $("#pageEditModuleIdOld").val();
var oldModuleText = $("#pageEditModuleIdOldText").val();
var newModule = $("#pageEditModuleId").val();
if ( oldModule !== "" &&
oldModule !== newModule) {
var _this = $(this);
core.confirm("Les données du module " + oldModuleText + " seront effacées. Confirmez-vous ?",
function() {
$(location).attr("href", _this.attr("href"));
return true;
},
function() {
$("#pageEditModuleId").val(oldModule);
return false;
}
);
}
}
/**
* Paramètres par défaut au chargement
*/
$( document ).ready(function() {
/*
* Enleve le menu fixe en édition de page
*/
$("nav").removeAttr('id');
/**
* Bloque/Débloque le bouton de configuration au changement de module
* Affiche ou masque la position du module selon le call_user_func
*/
if($("#pageEditModuleId").val() === "") {
$("#pageEditModuleConfig").addClass("disabled");
$("#pageEditContentContainer").hide();
}
else {
$("#pageEditModuleConfig").removeClass("disabled");
$("#pageEditContentContainer").hide();
$("#pageEditBlock option[value='bar']").remove();
}
/**
* Masquer et affiche la sélection de position du module
*/
if( $("#pageEditModuleId").val() === "redirection" ||
$("#pageEditModuleId").val() === "" ) {
$("#configModulePositionWrapper").removeClass("disabled");
$("#configModulePositionWrapper").slideUp();
}
else {
$("#configModulePositionWrapper").addClass("disabled");
$("#configModulePositionWrapper").slideDown();
}
/**
* Masquer et démasquer le contenu pour les modules code et redirection
*/
if( $("#pageEditModuleId").val() === "redirection") {
$("#pageEditContentWrapper").removeClass("disabled");
$("#pageEditContentWrapper").slideUp();
} else {
$("#pageEditContentWrapper").addClass("disabled");
$("#pageEditContentWrapper").slideDown();
}
/**
* Masquer et démasquer le masquage du titre pour le module redirection
*/
if( $("#pageEditModuleId").val() === "redirection" ) {
$("#pageEditHideTitleWrapper").removeClass("disabled");
$("#pageEditHideTitleWrapper").hide();
$("#pageEditBlockLayout").removeClass("disabled");
$("#pageEditBlockLayout").hide();
} else {
$("#pageEditHideTitleWrapper").addClass("disabled");
$("#pageEditHideTitleWrapper").show();
$("#pageEditBlockLayout").addClass("disabled");
$("#pageEditBlockLayout").show();
}
/**
* Masquer et démasquer la sélection des barres
*/
switch ($("#pageEditBlock").val()) {
case "bar":
case "12":
$("#pageEditBarLeftWrapper").removeClass("disabled");
$("#pageEditBarLeftWrapper").slideUp();
$("#pageEditBarRightWrapper").removeClass("disabled");
$("#pageEditBarRightWrapper").slideUp();
break;
case "3-9":
case "4-8":
$("#pageEditBarLeftWrapper").addClass("disabled");
$("#pageEditBarLeftWrapper").slideDown();
$("#pageEditBarRightWrapper").removeClass("disabled");
$("#pageEditBarRightWrapper").slideUp();
break;
case "9-3":
case "8-4":
$("#pageEditBarLeftWrapper").removeClass("disabled");
$("#pageEditBarLeftWrapper").slideUp();
$("#pageEditBarRightWrapper").addClass("disabled");
$("#pageEditBarRightWrapper").slideDown();
break;
case "3-6-3":
case "2-7-3":
case "3-7-2":
$("#pageEditBarLeftWrapper").addClass("disabled");
$("#pageEditBarLeftWrapper").slideDown();
$("#pageEditBarRightWrapper").addClass("disabled");
$("#pageEditBarRightWrapper").slideDown();
break;
};
if ($("#pageEditBlock").val() === "bar") {
$("#pageEditMenu").removeClass("disabled");
$("#pageEditMenu").hide();
$("#pageEditHideTitleWrapper").removeClass("disabled");
$("#pageEditHideTitleWrapper").slideUp();
$("#pageEditbreadCrumbWrapper").removeClass("disabled");
$("#pageEditbreadCrumbWrapper").slideUp();
$("#pageEditModuleIdWrapper").removeClass("disabled");
$("#pageEditModuleIdWrapper").slideUp();
$("#pageEditModuleConfig").removeClass("disabled");
$("#pageEditModuleConfig").slideUp();
$("#pageEditDisplayMenuWrapper").addClass("disabled");
$("#pageEditDisplayMenuWrapper").slideDown();
$("#pageTypeMenuWrapper").removeClass("disabled");
$("#pageTypeMenuWrapper").slideUp();
$("#pageEditSeoWrapper").removeClass("disabled");
$("#pageEditSeoWrapper").slideUp();
$("#pageEditAdvancedWrapper").removeClass("disabled");
$("#pageEditAdvancedWrapper").slideUp();
/*
$("#pageEditBlockLayout").removeClass("col6");
$("#pageEditBlockLayout").addClass("col12");
*/
} else {
$("#pageEditDisplayMenuWrapper").removeClass("disabled");
$("#pageEditDisplayMenuWrapper").slideUp();
}
/**
* Masquer ou afficher le chemin de fer
* Quand le titre est masqué
*/
if ($("input[name=pageEditHideTitle]").is(':checked') ||
$("#pageEditParentPageId").val() === "" ) {
$("#pageEditbreadCrumbWrapper").removeClass("disabled");
$("#pageEditbreadCrumbWrapper").slideUp();
} else {
if ($("#pageEditParentPageId").val() !== "") {
$("#pageEditbreadCrumbWrapper").addClass("disabled");
$("#pageEditbreadCrumbWrapper").slideDown();
}
}
/**
* Masquer ou afficher la sélection de l'icône
*/
if ($("#pageTypeMenu").val() !== "text") {
$("#pageIconUrlWrapper").addClass("disabled");
$("#pageIconUrlWrapper").slideDown();
} else {
$("#pageIconUrlWrapper").removeClass("disabled");
$("#pageIconUrlWrapper").slideUp();
}
/**
* Cache les options de masquage dans les menus quand la page n'est pas affichée.
*/
if ($("#pageEditPosition").val() === "0" ) {
$("#pageEditHideMenuSideWrapper").removeClass("disabled");
$("#pageEditHideMenuSideWrapper").slideUp();
} else {
$("#pageEditHideMenuSideWrapper").addClass("disabled");
$("#pageEditHideMenuSideWrapper").slideDown();
}
/**
* Cache l'option de masquage des pages enfants
*/
if ($("#pageEditParentPageId").val() !== "") {
$("#pageEditHideMenuChildrenWrapper").removeClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideUp();
} else {
$("#pageEditHideMenuChildrenWrapper").addClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideDown();
}
/**
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
*/
if ($("#pageEditDisable").is(':checked') ) {
$("#pageEditHideMenuChildrenWrapper").removeClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideUp();
} else {
$("#pageEditHideMenuChildrenWrapper").addClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideDown();
}
// Animation des boutons zwiico-help lien vers la documentation
var colorButton = <?php echo "'".$this->getData(['admin', 'backgroundColorButtonHelp'])."'"; ?> ;
var blockButton = <?php echo "'".$this->getData(['admin', 'backgroundBlockColor'])."'"; ?> ;
$(".helpDisplayButton").mouseenter(function(){
$(this).css("background-color", colorButton);
});
$(".helpDisplayButton").mouseleave(function(){
$(this).css("background-color", blockButton);
});
});
/**
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
*/
var pageEditDisableDOM = $("#pageEditDisable");
pageEditDisableDOM.on("change", function() {
if ($(this).is(':checked') ) {
$("#pageEditHideMenuChildrenWrapper").removeClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideUp();
$("#pageEditHideMenuChildren").prop("checked", false);
} else {
$("#pageEditHideMenuChildrenWrapper").addClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideDown();
}
});
/**
* Cache les options de masquage dans les menus quand la page n'est pas affichée.
*/
var pageEditPositionDOM = $("#pageEditPosition");
pageEditPositionDOM.on("change", function() {
if ($(this).val() === "0" ) {
$("#pageEditHideMenuSideWrapper").removeClass("disabled");
$("#pageEditHideMenuSideWrapper").slideUp();
} else {
$("#pageEditHideMenuSideWrapper").addClass("disabled");
$("#pageEditHideMenuSideWrapper").slideDown();
}
});
/**
* Bloque/Débloque le bouton de configuration au changement de module
* Affiche ou masque la position du module selon le call_user_func
*/
var pageEditModuleIdDOM = $("#pageEditModuleId");
pageEditModuleIdDOM.on("change", function() {
if($(this).val() === "") {
$("#pageEditModuleConfig").addClass("disabled");
$("#pageEditContentContainer").slideDown();
$("#pageEditBlock").append('<option value="bar">Barre latérale</option>');
}
else {
$("#pageEditModuleConfig").removeClass("disabled");
$("#pageEditContentContainer").slideUp();
$("#pageEditBlock option[value='bar']").remove();
}
});
/**
* Masquer et affiche la sélection de position du module
*
* */
var pageEditModuleIdDOM = $("#pageEditModuleId");
pageEditModuleIdDOM.on("change", function() {
if( $(this).val() === "redirection" ||
$(this).val() === "") {
$("#configModulePositionWrapper").removeClass("disabled");
$("#configModulePositionWrapper").slideUp();
}
else {
$("#configModulePositionWrapper").addClass("disabled");
$("#configModulePositionWrapper").slideDown();
}
});
/**
* Masquer et démasquer le contenu pour les modules code et redirection
*/
var pageEditModuleIdDOM = $("#pageEditModuleId");
pageEditModuleIdDOM.on("change", function() {
if( $(this).val() === "redirection") {
$("#pageEditContentWrapper").removeClass("disabled");
$("#pageEditContentWrapper").slideUp();
}
else {
$("#pageEditContentWrapper").addClass("disabled");
$("#pageEditContentWrapper").slideDown();
}
});
/**
* Masquer et démasquer le masquage du titre pour le module redirection
*/
var pageEditModuleIdDOM = $("#pageEditModuleId");
pageEditModuleIdDOM.on("change", function() {
if( $(this).val() === "redirection") {
$("#pageEditHideTitleWrapper").removeClass("disabled");
$("#pageEditHideTitleWrapper").slideUp();
$("#pageEditBlockLayout").removeClass("disabled");
$("#pageEditBlockLayout").slideUp();
}
else {
$("#pageEditHideTitleWrapper").addClass("disabled");
$("#pageEditHideTitleWrapper").slideDown();
$("#pageEditBlockLayout").addClass("disabled");
$("#pageEditBlockLayout").slideDown();
}
});
/**
* Masquer et démasquer la sélection des barres
*/
var pageEditBlockDOM = $("#pageEditBlock");
pageEditBlockDOM.on("change", function() {
switch ($(this).val()) {
case "bar":
case "12":
$("#pageEditBarLeftWrapper").removeClass("disabled");
$("#pageEditBarLeftWrapper").slideUp();
$("#pageEditBarRightWrapper").removeClass("disabled");
$("#pageEditBarRightWrapper").slideUp();
break;
case "3-9":
case "4-8":
$("#pageEditBarLeftWrapper").addClass("disabled");
$("#pageEditBarLeftWrapper").slideDown();
$("#pageEditBarRightWrapper").removeClass("disabled");
$("#pageEditBarRightWrapper").slideUp();
break;
case "9-3":
case "8-4":
$("#pageEditBarLeftWrapper").removeClass("disabled");
$("#pageEditBarLeftWrapper").slideUp();
$("#pageEditBarRightWrapper").addClass("disabled");
$("#pageEditBarRightWrapper").slideDown();
break;
case "3-6-3":
case "2-7-3":
case "3-7-2":
$("#pageEditBarLeftWrapper").addClass("disabled");
$("#pageEditBarLeftWrapper").slideDown();
$("#pageEditBarRightWrapper").addClass("disabled");
$("#pageEditBarRightWrapper").slideDown();
break;
}
if ($(this).val() === "bar") {
$("#pageEditMenu").removeClass("disabled");
$("#pageEditMenu").hide();
$("#pageEditHideTitleWrapper").removeClass("disabled");
$("#pageEditHideTitleWrapper").slideUp();
$("#pageTypeMenuWrapper").removeClass("disabled");
$("#pageTypeMenuWrapper").slideUp();
$("#pageEditSeoWrapper").removeClass("disabled");
$("#pageEditSeoWrapper").slideUp();
$("#pageEditAdvancedWrapper").removeClass("disabled");
$("#pageEditAdvancedWrapper").slideUp();
$("#pageEditbreadCrumbWrapper").removeClass("disabled");
$("#pageEditbreadCrumbWrapper").slideUp();
$("#pageEditModuleIdWrapper").removeClass("disabled");
$("#pageEditModuleIdWrapper").slideUp();
$("#pageEditModuleConfig").removeClass("disabled");
$("#pageEditModuleConfig").slideUp();
$("#pageEditDisplayMenuWrapper").addClass("disabled");
$("#pageEditDisplayMenuWrapper").slideDown();
/*
$("#pageEditBlockLayout").removeClass("col6");
$("#pageEditBlockLayout").addClass("col12");
*/
} else {
$("#pageEditMenu").addClass("disabled");
$("#pageEditMenu").show();
$("#pageEditHideTitleWrapper").addClass("disabled");
$("#pageEditHideTitleWrapper").slideDown();
$("#pageTypeMenuWrapper").addClass("disabled");
$("#pageTypeMenuWrapper").slideDown();
$("#pageEditSeoWrapper").addClass("disabled");
$("#pageEditSeoWrapper").slideDown();
$("#pageEditAdvancedWrapper").addClass("disabled");
$("#pageEditAdvancedWrapper").slideDown();
$("#pageEditModuleIdWrapper").addClass("disabled");
$("#pageEditModuleIdWrapper").slideDown();
$("#pageEditModuleConfig").slideDown();
$("#pageEditDisplayMenuWrapper").removeClass("disabled");
$("#pageEditDisplayMenuWrapper").slideUp();
if ($("#pageEditParentPageId").val() !== "") {
$("#pageEditbreadCrumbWrapper").addClass("disabled");
$("#pageEditbreadCrumbWrapper").slideDown();
}
if ($("#pageEditModuleId").val() === "") {
$("#pageEditModuleConfig").addClass("disabled");
} else {
$("#pageEditModuleConfig").removeClass("disabled");
}
/*
$("#pageEditBlockLayout").removeClass("col12");
$("#pageEditBlockLayout").addClass("col6");
*/
}
});
/**
* Masquer ou afficher le chemin de fer
* Quand le titre est masqué
*/
var pageEditHideTitleDOM = $("#pageEditHideTitle");
pageEditHideTitleDOM.on("change", function() {
if ($("input[name=pageEditHideTitle]").is(':checked')) {
$("#pageEditbreadCrumbWrapper").removeClass("disabled");
$("#pageEditbreadCrumbWrapper").slideUp();
} else {
if ($("#pageEditParentPageId").val() !== "") {
$("#pageEditbreadCrumbWrapper").addClass("disabled");
$("#pageEditbreadCrumbWrapper").slideDown();
}
}
});
/**
* Masquer ou afficher le chemin de fer
* Quand la page n'est pas mère et que le menu n'est pas masqué
*/
var pageEditParentPageIdDOM = $("#pageEditParentPageId");
pageEditParentPageIdDOM.on("change", function() {
if ($(this).val() === "" &&
!$('input[name=pageEditHideTitle]').is(':checked') ) {
$("#pageEditbreadCrumbWrapper").removeClass("disabled");
$("#pageEditbreadCrumbWrapper").slideUp();
} else {
$("#pageEditbreadCrumbWrapper").addClass("disabled");
$("#pageEditbreadCrumbWrapper").slideDown();
}
if ($(this).val() !== "") {
$("#pageEditHideMenuChildrenWrapper").removeClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideUp();
} else {
$("#pageEditHideMenuChildrenWrapper").addClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideDown();
}
});
/**
* Masquer ou afficher la sélection de l'icône
*/
var pageTypeMenuDOM = $("#pageTypeMenu");
pageTypeMenuDOM.on("change", function() {
if ($(this).val() !== "text") {
$("#pageIconUrlWrapper").addClass("disabled");
$("#pageIconUrlWrapper").slideDown();
} else {
$("#pageIconUrlWrapper").removeClass("disabled");
$("#pageIconUrlWrapper").slideUp();
}
});
/**
* Soumission du formulaire pour éditer le module
*/
$("#pageEditModuleConfig").on("click", function() {
$("#pageEditModuleRedirect").val(1);
$("#pageEditForm").trigger("submit");
});
/**
* Affiche les pages en fonction de la page parent dans le choix de la position
*/
var hierarchy = <?php echo json_encode($this->getHierarchy()); ?>;
var pages = <?php echo json_encode($this->getData(['page'])); ?>;
// 9.0.07 corrige une mauvaise sélection d'une page orpheline avec enfant
var positionInitial = <?php echo $this->getData(['page',$this->getUrl(2),"position"]); ?>;
// 9.0.07
$("#pageEditParentPageId").on("change", function() {
var positionDOM = $("#pageEditPosition");
positionDOM.empty().append(
$("<option>").val(0).text("Ne pas afficher"),
$("<option>").val(1).text("Au début")
);
var parentSelected = $(this).val();
var positionSelected = 0;
var positionPrevious = 1;
// Aucune page parent selectionnée
if(parentSelected === "") {
// Liste des pages sans parents
for(var key in hierarchy) {
if(hierarchy.hasOwnProperty(key)) {
// Sélectionne la page avant s'il s'agit de la page courante
if(key === "<?php echo $this->getUrl(2); ?>") {
positionSelected = positionPrevious;
}
// Sinon ajoute la page à la liste
else {
// Enregistre la position de cette page afin de la sélectionner si la prochaine page de la liste est la page courante
positionPrevious++;
// Ajout à la liste
positionDOM.append(
$("<option>").val(positionPrevious).html("Après \"" + (pages[key].title) + "\"")
);
}
}
}
// 9.0.07 corrige une mauvaise sélection d'une page orpheline avec enfant
if (positionInitial === 0) {
positionSelected = 0;
}
// 9.0.07
}
// Un page parent est selectionnée
else {
// Liste des pages enfants de la page parent
for(var i = 0; i < hierarchy[parentSelected].length; i++) {
// Pour page courante sélectionne la page précédente (pas de - 1 à positionSelected à cause des options par défaut)
if(hierarchy[parentSelected][i] === "<?php echo $this->getUrl(2); ?>") {
positionSelected = positionPrevious;
}
// Sinon ajoute la page à la liste
else {
// Enregistre la position de cette page afin de la sélectionner si la prochaine page de la liste est la page courante
positionPrevious++;
// Ajout à la liste
positionDOM.append(
$("<option>").val(positionPrevious).html("Après \"" + (pages[hierarchy[parentSelected][i]].title) + "\"")
);
}
}
}
// Sélectionne la bonne position
positionDOM.val(positionSelected);
}).trigger("change");

View File

@ -0,0 +1,305 @@
<?php echo template::formOpen('pageEditForm'); ?>
<div class="row">
<div class="col2">
<?php $href = helper::baseUrl() . $this->getUrl(2); ?>
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code')$href = helper::baseUrl(); ?>
<?php echo template::button('pageEditBack', [
'class' => 'buttonGrey',
'href' => $href,
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('pageEditHelp', [
'href' => 'https://doc.deltacms.fr/edition',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset2">
<?php echo template::button('pageEditDuplicate', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
'value' => 'Dupliquer',
'ico' => 'clone'
]); ?>
</div>
<div class="col2">
<?php echo template::button('pageEditDelete', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
'value' => 'Supprimer',
'ico' => 'cancel'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('pageEditSubmit', [
'uniqueSubmission' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block" id="info">
<h4>Informations générales
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/informations-generales" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="row">
<div class="col6">
<?php echo template::text('pageEditTitle', [
'label' => 'Titre',
'value' => $this->getData(['page', $this->getUrl(2), 'title'])
]); ?>
</div>
<div class="col2">
<?php echo template::text('pageEditShortTitle', [
'label' => 'Titre Court',
'value' => $this->getData(['page', $this->getUrl(2), 'shortTitle']),
'help' => 'Le titre court est affiché dans les menus. Il peut être identique au titre de la page.'
]); ?>
</div>
<div class="col4">
<div class="row">
<div class="col9">
<?php echo template::hidden('pageEditModuleRedirect'); ?>
<?php echo template::select('pageEditModuleId', $module::$moduleIds, [
'help' => 'En cas de changement de module, les données du module précédent seront supprimées.',
'label' => 'Module',
'selected' => $this->getData(['page', $this->getUrl(2), 'moduleId'])
]); ?>
<?php echo template::hidden('pageEditModuleIdOld',['value' => $this->getData(['page', $this->getUrl(2), 'moduleId'])]); ?>
<?php echo template::hidden('pageEditModuleIdOldText',[
'value' => array_key_exists($this->getData(['page', $this->getUrl(2), 'moduleId']),$module::$moduleIds)? $module::$moduleIds[$this->getData(['page', $this->getUrl(2), 'moduleId'])] : ucfirst($this->getData(['page', $this->getUrl(2), 'moduleId']))
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<?php echo template::button('pageEditModuleConfig', [
'disabled' => (bool) $this->getData(['page', $this->getUrl(2), 'moduleId']) === false,
'uniqueSubmission' => true,
'value' => template::ico('gear')
]); ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('pageTypeMenu', $module::$typeMenu,[
'label' => 'Aspect du lien',
'selected' => $this->getData(['page', $this->getUrl(2), 'typeMenu'])
]); ?>
</div>
<div class="col4">
<?php echo template::file('pageIconUrl', [
'help' => 'Sélectionnez une image ou une icône de petite dimension',
'label' => 'Icône',
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('configModulePosition', $module::$modulePosition,[
'help' => 'En position libre ajoutez le module en plaçant [MODULE] à l\'endroit voulu dans votre page.',
'label' => 'Position du module',
'selected' => $this->getData(['page', $this->getUrl(2), 'modulePosition'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::textarea('pageEditContent', [
'class' => 'editorWysiwyg',
//'value' => file_get_contents(self::DATA_DIR . self::$i18n . '/content/' . $this->getData(['page', $this->getUrl(2), 'content']))
'value' => $this->getPage($this->getUrl(2), self::$i18n)
]); ?>
</div>
</div>
<div class="row">
<div class="col12" id="pageEditBlockLayout">
<div class="block">
<h4>Mise en page
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/mise-en-page" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="blockContainer">
<div class="row">
<div class="col6">
<div class="row">
<div class="col12">
<?php echo template::select('pageEditBlock', $module::$pageBlocks, [
'label' => 'Gabarits de page / Barre latérale',
'help' => 'Pour définir la page comme barre latérale, choisissez l\'option dans la liste.',
'selected' => $this->getData(['page', $this->getUrl(2) , 'block'])
]); ?>
</div>
</div>
</div>
<div class="col6">
<!-- Sélection des barres latérales -->
<?php if($this->getHierarchy($this->getUrl(2),false,true)): ?>
<?php echo template::hidden('pageEditBarLeft', [
'value' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
]); ?>
<?php else: ?>
<?php echo template::select('pageEditBarLeft', $module::$pagesBarId, [
'label' => 'Barre latérale gauche :',
'selected' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
]); ?>
<?php endif; ?>
<?php if($this->getHierarchy($this->getUrl(2),false,true)): ?>
<?php echo template::hidden('pageEditBarRight', [
'value' => $this->getData(['page', $this->getUrl(2), 'barRight'])
]); ?>
<?php else: ?>
<?php echo template::select('pageEditBarRight', $module::$pagesBarId, [
'label' => 'Barre latérale droite :',
'selected' => $this->getData(['page', $this->getUrl(2), 'barRight'])
]); ?>
<?php endif; ?>
<?php echo template::select('pageEditDisplayMenu', $module::$displayMenu, [
'label' => 'Contenu du menu vertical',
'selected' => $this->getData(['page', $this->getUrl(2), 'displayMenu']),
'help' => 'Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12" id="pageEditMenu">
<div class="block">
<h4>Emplacement dans le menu
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/emplacement-dans-le-menu" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="blockContainer">
<div class="row">
<div class="col6">
<?php echo template::select('pageEditPosition', [], [
'label' => 'Position',
'help' => '\'Ne pas afficher\' crée une page orpheline non accessible par le biais des menus.'
]); ?>
</div>
<div class="col6">
<?php if($this->getHierarchy($this->getUrl(2), false)): ?>
<?php echo template::hidden('pageEditParentPageId', [
'value' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
]); ?>
<?php else: ?>
<?php echo template::select('pageEditParentPageId', $module::$pagesNoParentId, [
'label' => 'Page parent',
'selected' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
]); ?>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('pageEditDisable', true, 'Désactivée', [
'checked' => $this->getData(['page', $this->getUrl(2), 'disable']),
'help' => 'Une page désactivée n\'est pas cliquable en mode déconnecté, les pages enfants sont visibles et accessibles. La page d\'accueil n\'est pas désactivable.'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('pageEditTargetBlank', true, 'Nouvel onglet', [
'checked' => $this->getData(['page', $this->getUrl(2), 'targetBlank'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('pageEditHideTitle', true, 'Titre masqué', [
'checked' => $this->getData(['page', $this->getUrl(2), 'hideTitle'])
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('pageEditbreadCrumb', true, 'Fil d\'Ariane', [
'checked' => $this->getData(['page', $this->getUrl(2), 'breadCrumb']),
'help' => 'Affiche le nom de la page parente suivi du nom de la page, le titre ne doit pas être masqué.'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<div class='row' id="pageEditAdvancedWrapper">
<div class="col12">
<div class="block">
<h4>Options d'emplacement avancées
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/options-d-emplacement-avancees" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="blockContainer">
<div class="row">
<div class="col6">
<?php echo template::checkbox('pageEditHideMenuChildren', true, 'Masquer les pages enfants dans le menu horizontal', [
'checked' => $this->getData(['page', $this->getUrl(2), 'hideMenuChildren'])
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('pageEditHideMenuSide', true, 'Masquer la page et les pages enfants dans le menu d\'une barre latérale' , [
'checked' => $this->getData(['page', $this->getUrl(2), 'hideMenuSide']),
'help' => 'La page est affichée dans un menu horizontal mais pas dans le menu vertical d\'une barre latérale.'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<div class='row' id="pageEditSeoWrapper">
<div class="col12">
<div class="block">
<h4>Permission et référencement
<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.deltacms.fr/permission-et-referencement" target="_blank">
<?php echo template::ico('help', 'left');?>
</a>
</span>
</h4>
<div class="blockContainer">
<div class="row">
<div class='col6'>
<?php echo template::select('pageEditGroup', self::$groupPublics, [
'label' => 'Groupe requis pour accéder à la page :',
'selected' => $this->getData(['page', $this->getUrl(2), 'group'])
]); ?>
</div>
<div class='col12'>
<?php echo template::text('pageEditMetaTitle', [
'label' => 'Méta-titre',
'value' => $this->getData(['page', $this->getUrl(2), 'metaTitle'])
]); ?>
<?php echo template::textarea('pageEditMetaDescription', [
'label' => 'Méta-description',
//'maxlength' => '500',
'value' => $this->getData(['page', $this->getUrl(2), 'metaDescription'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,115 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class sitemap extends common
{
public static $actions = [
'index' => self::GROUP_VISITOR
];
public static $siteMap = '';
/**
* Plan du site
*/
public function index()
{
$items = '<ul>';
foreach ($this->getHierarchy(null, true, null) as $parentId => $childIds) {
$items .= ' <li>';
if ($this->getData(['page', $parentId, 'disable']) === false && $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])) {
$pageUrl = ($parentId !== $this->getData(['locale', 'homePageId'])) ? helper::baseUrl() . $parentId : helper::baseUrl(false);
$items .= '<a href="' . $pageUrl .'">' .$this->getData(['page', $parentId, 'title']) . '</a>';
} else {
// page désactivée
$items .= $this->getData(['page', $parentId, 'title']);
}
// ou articles d'un blog
if ($this->getData(['page', $parentId, 'moduleId']) === 'blog' &&
!empty($this->getData(['module',$parentId, 'posts' ]))) {
$items .= '<ul>';
// Ids des articles par ordre de publication
$articleIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $parentId,'posts']), 'publishedOn', 'SORT_DESC');
$articleIdsStates = helper::arrayCollumn($this->getData(['module', $parentId, 'posts']), 'state', 'SORT_DESC');
$articleIds = [];
foreach ($articleIdsPublishedOns as $articleId => $articlePublishedOn) {
if ($articlePublishedOn <= time() and $articleIdsStates[$articleId]) {
$articleIds[] = $articleId;
}
}
foreach ($articleIds as $articleId => $article) {
if ($this->getData(['module',$parentId,'posts',$article,'state']) === true) {
$items .= ' <li>';
$items .= '<a href="' . helper::baseUrl() . $parentId. '/' . $article . '">' . $this->getData(['module',$parentId,'posts',$article,'title']) . '</a>';
$items .= '</li>';
}
}
$items .= '</ul>';
}
foreach ($childIds as $childId) {
$items .= '<ul>';
// Sous-page
$items .= ' <li>';
if ($this->getData(['page', $childId, 'disable']) === false && $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])) {
$pageUrl = ($childId !== $this->getData(['locale', 'homePageId'])) ? helper::baseUrl() . $childId : helper::baseUrl(false) ;
$items .= '<a href="' . $pageUrl . '">' . $this->getData(['page', $childId, 'title']) . '</a>';
} else {
// page désactivée
$items .= $this->getData(['page', $childId, 'title']);
}
$items .= '</li>';
// Articles d'une sous-page blog
if ($this->getData(['page', $childId, 'moduleId']) === 'blog' &&
!empty($this->getData(['module', $childId, 'posts' ]))) {
$items .= '<ul>';
// Ids des articles par ordre de publication
$articleIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $childId,'posts']), 'publishedOn', 'SORT_DESC');
$articleIdsStates = helper::arrayCollumn($this->getData(['module', $childId, 'posts']), 'state', 'SORT_DESC');
$articleIds = [];
foreach ($articleIdsPublishedOns as $articleId => $articlePublishedOn) {
if ($articlePublishedOn <= time() and $articleIdsStates[$articleId]) {
$articleIds[] = $articleId;
}
}
foreach ($articleIds as $articleId => $article) {
if ($this->getData(['module',$childId,'posts',$article,'state']) === true) {
$items .= ' <li>';
$items .= '<a href="' . helper::baseUrl() . $childId . '/' . $article . '">' . $this->getData(['module',$childId,'posts',$article,'title']) . '</a>';
$items .= '</li>';
}
}
$items .= '</ul>';
}
$items .= '</ul>';
}
$items .= '</li>';
}
// Fin du grand bloc
$items .= '</ul>';
self::$siteMap = $items;
// Valeurs en sortie
$this->addOutput([
'title' => 'Plan du site',
'view' => 'index'
]);
}
}

View File

@ -0,0 +1,31 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
#siteMap ul {
list-style: none ;
margin-left: .5em;
padding-left: 1em;
line-height: 1.5em;
font-size: 16px;
}
#siteMap ul > li::before {
content: "📄 ";
}
#siteMap li > ul > li::before {
content: "📃 ";
}

View File

@ -0,0 +1,4 @@
<?php
echo "<div id='siteMap'>";
echo $module::$siteMap;
echo "</div>";

View File

@ -0,0 +1,224 @@
/**
* Voici une feuille de style type, bien entendu vous pouvez ajouter
* ou supprimer des propriétés CSS en fonction de vos besoins.
*/
/**
* Éléments principaux
*/
/*
* Grille du site
* Barres et page
*/
#contentLeft {
}
#contentRight {
}
#contentSite {
}
/* Bannière */
header {
}
/* Titre de la bannière */
header span {
}
/* Menu */
nav {
}
/* Items du menu */
nav a {
}
/* Items au survol du menu */
nav a:hover {
}
/* Item courant du menu */
nav a.active {
}
/* Menu latéral */
/* aspect des puces */
ul #menuSide {
}
/* Block menu à droite */
#menuSideRight {
}
/* Block menu à gauche */
#menuSideLeft {
}
/* Bas de page */
footer {
}
footer #footersite, #footerbody {
}
/* Liens du bas de page */
footer #footersite, #footerbody a {
}
/* footer bloc gauche */
footer #footersiteLeft, #footerbodyLeft {
}
/* footer bloc central */
footer #footersiteCenter, #footerbodyCenter {
}
/* footer bloc droite */
footer #footersiteRight, #footerbodyRight {
}
/**
* Éléments de contenu
*/
/* Titres */
h1,
h2,
h3,
h4 {
}
/* Liens */
a {
}
/* Liens au survol */
a:hover {
}
/* Liens au clic */
a:active {
}
/* Boutons */
.button,
button[type='submit'],
.pagination a {
}
/* Boutons au survol */
.button:hover,
button[type='submit']:hover,
.pagination a:hover {
}
/* Boutons au clic */
.button:active,
button[type='submit']:active,
.pagination a:active {
}
/* Cases à cocher */
input[type='checkbox']:checked + label:before {
}
/* Cases à cocher au survol */
input[type='checkbox']:not(:active):checked:hover + label:before,
input[type='checkbox']:active + label:before {
}
/* Champs de formulaire */
input[type='text'],
input[type='password'],
.inputFile,
select,
textarea {
}
/* Champs de formulaire au survol */
input[type='text']:hover,
input[type='password']:hover,
.inputFile:hover,
select:hover,
textarea:hover {
}
/* Modules News et Blog */
.blogDate {
}
.blogPicture {
}
.blogPicture img {
}
.blogComment {
}
.blogTitle {
}
.blogContent {
}
.newsTitle {
/*background-color: grey;*/
}
.newsContent {
}
.newsSignature {
color: #404040;
}
/* Consentement aux cookies */
/*
#cookieConsent {
width: 80%;
color: #FFF;
background: #212223;
opacity: 0.9;
}
#cookieConsent a{
color : yellow;
}
#cookieConsent h3{
color : red;
}
#cookieConsentConfirm {
background: rgba(0,0,255,1);
color: rgba(255,255,255,1);
}
#cookieConsentConfirm:hover {
background: rgba(0,50,255,1);
color: rgba(255,255,255,1);
}
*/

906
core/module/theme/theme.php Normal file
View File

@ -0,0 +1,906 @@
<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, 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
];
public static $aligns = [
'left' => 'À gauche',
'center' => 'Au centre',
'right' => 'À droite'
];
public static $attachments = [
'scroll' => 'Standard',
'fixed' => 'Fixe'
];
public static $fonts = [
'Abril+Fatface' => 'Abril Fatface',
'Arimo' => 'Arimo',
'Arvo' => 'Arvo',
'Berkshire+Swash' => 'Berkshire Swash',
'Cabin' => 'Cabin',
'Dancing+Script' => 'Dancing Script',
'Droid+Sans' => 'Droid Sans',
'Droid+Serif' => 'Droid Serif',
'Fira+Sans' => 'Fira Sans',
'Inconsolata' => 'Inconsolata',
'Indie+Flower' => 'Indie Flower',
'Josefin+Slab' => 'Josefin Slab',
'Lobster' => 'Lobster',
'Lora' => 'Lora',
'Lato' => 'Lato',
'Marvel' => 'Marvel',
'Old+Standard+TT' => 'Old Standard TT',
'Open+Sans' => 'Open Sans',
'Oswald' => 'Oswald',
'PT+Mono' => 'PT Mono',
'PT+Serif' => 'PT Serif',
'Raleway' => 'Raleway',
'Rancho' => 'Rancho',
'Roboto' => 'Roboto',
'Signika' => 'Signika',
'Ubuntu' => 'Ubuntu',
'Vollkorn' => 'Vollkorn'
];
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 0px 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 $blockShadows = [
'0px 0px 0px' => 'Aucune',
'1px 1px 2px' => 'Très légère',
'2px 2px 4px' => 'Légère',
'3px 3px 6px' => 'Moyenne',
'5px 5px 10px' => 'Importante',
'10px 10px 20px' => 'Très importante'
];
public static $siteFontSizes = [
'12px' => '12 pixels',
'13px' => '13 pixels',
'14px' => '14 pixels',
'15px' => '15 pixels',
'16px' => '16 pixels',
'18px' => '18 pixels',
'20px' => '20 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 = [];
/**
* 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);
// Si une image est positionnée, l'arrière en transparent.
$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
]]);
// 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'
]);
}
/**
* 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'),
'backgroundTitleColor' => $this->getInput('themeBlockBackgroundTitleColor'),
'blockBorderRadius' => $this->getInput('themeBlockBorderRadius'),
'blockBorderShadow' => $this->getInput('themeBlockBorderShadow')
]]);
// 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';
$this->sauve( $modele );
}
if(
file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.json')
AND file_exists(self::TEMP_DIR . $tempFolder . '/site/data/admin.css')
) {
$modele = 'admin';
$this->sauve( $modele );
}
if (!empty($modele)
) {
// traiter l'archive
$importFolder = './site/file/import';
mkdir ($importFolder, 0755);
$success = $zip->extractTo($importFolder);
// $path = $importFolder.'/site/file/source/';
// Modifie le nom de tous les fichiers de $path et leur nom dans theme.json
// $this->changeName($path);
$this->copyDir( $importFolder, './');
$this->removeDir($importFolder);
// traitement de l'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 <b>'.$zipFilename.'</b> sauvegardée avec succès',
'redirect' => helper::baseUrl() . 'theme/manage',
'state' => true
]);
}
/**
* Sauvegarde du thème du site ou de l'administration avant application d'un nouveau thème
*/
public function sauve( $type ) {
// Make zip
$zipFilename = $this->zipTheme( $type );
// 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);
return;
}
/**
* construction du zip
* @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');
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'])
);
}
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'])
);
}
// Extraction des images de la bannière personnalisée
$images=[];
$ii=0;
if( $this->getData(['theme','header','feature'])=== 'feature') {
$tab = str_word_count($this->getData(['theme','header','featureContent']), 1, './' );
foreach( $tab as $key=>$value ){
if( $value ==='src'){
$images[$ii] = $tab [$key + 1];
$ii++;
}
}
// ajout des images dans le zip
foreach( $images as $key=>$value){
$value = str_replace( './site', 'site' , $value);
$zip->addFile( $value, $value );
}
}
break;
}
$ret = $zip->close();
}
return ($zipFilename);
}
/*
*
*/
/*
private function changeName($path = '.')
{
$ignore = array('cgi-bin', '.', '..');
if(is_dir($path)){
if($dir = opendir($path)){
while(false !== ($file = readdir($dir))) {
if(!in_array($file, $ignore)) {
if(is_dir("$path$file")) {
$this->changeName( "$path$file/");
}
else {
$oldName = $file;
$newName = date("YmdHi").$file;
rename("$path$oldName", "$path$newName");
// Modification du nom de fichier dans .../import/site/data/theme.json
$fileTheme = './site/file/import/site/data/theme.json';
if(file_exists($fileTheme)){
$json = file_get_contents($fileTheme);
$json = str_replace($oldName, $newName, $json);
file_put_contents($fileTheme,$json);
}
}
}
}
closedir($dir);
}
}
}
*/
}

View File

@ -0,0 +1,19 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,62 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Aperçu en direct
*/
$("input, select").on("change", function() {
var titleFont = $("#adminFontTitle").val();
var textFont = $("#adminFontText").val();
var css = "@import url('https://fonts.googleapis.com/css?family=" + titleFont + "|" + textFont + "');";
var colors = core.colorVariants($("#adminBackgroundColor").val());
var css = "#site{background-color:" + colors.normal + ";}";
css += "body, .row > div {font:" + $("#adminFontTextSize").val() + " '" + textFont + "', sans-serif;}";
css += "body h1, h2, h3, h4, h5, h6 {font-family:'" + titleFont + "', sans-serif; color:" + $("#adminColorTitle").val() + ";}";
css += "body:not(.editorWysiwyg),span .zwiico-help {color:" + $("#adminColorText").val() + ";}";
var colors = core.colorVariants($("#adminColorButton").val());
css += "input[type='checkbox']:checked + label::before,.speechBubble{ background-color:" + colors.normal + "; color:" + $("#adminColorButtonText").val() + ";}";
css += ".speechBubble::before {border-color:" + colors.normal + " transparent transparent transparent;}";
css += ".button {background-color:" + colors.normal + ";color:" + colors.text + ";}.button:hover {background-color:" + colors.darken + ";color:" + colors.text + ";}.button:active {background-color:" + colors.veryDarken + ";color:" + colors.text + ";}";
var colors = core.colorVariants($("#adminColorGrey").val());
css += ".button.buttonGrey {background-color: " + colors.normal + ";color:" + colors.text + ";}.button.buttonGrey:hover {background-color:" + colors.darken + ";color:" + colors.text + "}.button.buttonGrey:active {background-color:" + colors.veryDarken + ";color:" + colors.text + ";}";
var colors = core.colorVariants($("#adminColorRed").val());
css += ".button.buttonRed {background-color: " + colors.normal + ";color:" + colors.text + ";}.button.buttonRed:hover {background-color:" + colors.darken + ";color:" + colors.text + "}.button.buttonRed:active {background-color:" + colors.veryDarken + ";color:" + colors.text + "}";
var colors = core.colorVariants($("#adminColorGreen").val());
css += ".button.buttonGreen, button[type=submit] {background-color: " + colors.normal + ";color: " + ";color:" + colors.text + "}.button.buttonGreen:hover, button[type=submit]:hover {background-color: " + colors.darken + ";color:" + colors.text + ";}.button.buttonGreen:active, button[type=submit]:active {background-color:" + colors.veryDarken + ";color:" + colors.text + "}";
var colors = core.colorVariants($("#adminBackGroundBlockColor").val());
css += ".block {border: 1px solid " + $("#adminBorderBlockColor").val() + ";}.block h4 {background-color: " + colors.normal + ";color:" + colors.text + ";}";
css += "input[type=email],input[type=text],input[type=password],select:not(#barSelectPage),textarea:not(.editorWysiwyg),.inputFile{background-color: " + colors.normal + ";color:" + colors.text + ";border: 1px solid " + $("#adminBorderBlockColor").val() + ";}";
// Ajout du css au DOM
$("#themePreview").remove();
$("<style>")
.attr("type", "text/css")
.attr("id", "themePreview")
.text(css)
.appendTo("head");
});
/**
* Confirmation de réinitialisation
*/
$("#configAdminReset").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir réinitialiser à son état d'origine le thème de l\'administration ?", function() {
$(location).attr("href", _this.attr("href"));
});
});

View File

@ -0,0 +1,163 @@
<?php echo template::formOpen('configAdminForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configAdminBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeSiteHelp', [
'href' => 'https://doc.deltacms.fr/administration',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset2">
<?php echo template::button('configAdminTest', [
'value' => 'Bouton Standard'
]); ?>
</div>
<div class="col2 offset">
<?php echo template::button('configAdminReset', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'theme/reset/admin' . '&csrf=' . $_SESSION['csrf'],
'value' => 'Réinitialiser',
'ico' => 'cancel'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('configAdminSubmit',[
'value' => 'Valider',
'ico' => 'check'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Couleurs</h4>
<div class="row">
<div class="col4">
<?php echo template::text('adminBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Arrière-plan',
'value' => $this->getData(['admin', 'backgroundColor'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('adminColorTitle', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Titres',
'value' => $this->getData(['admin', 'colorTitle'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('adminColorText', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Texte',
'value' => $this->getData(['admin', 'colorText'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::text('adminBackGroundBlockColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence. La couleur du texte est automatique.',
'label' => 'Arrière-plan des champs',
'value' => $this->getData(['admin', 'backgroundBlockColor'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('adminBorderBlockColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Bordure des champs',
'value' => $this->getData(['admin', 'borderBlockColor'])
]); ?>
</div>
<div class="col3 offset1">
<?php echo template::text('adminColorHelp', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Bouton Aide',
'value' => $this->getData(['admin', 'backgroundColorButtonHelp'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::text('adminColorGrey', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Bouton retour',
'value' => $this->getData(['admin', 'backgroundColorButtonGrey'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('adminColorButton', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Bouton standard',
'value' => $this->getData(['admin', 'backgroundColorButton'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('adminColorRed', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Bouton effacement',
'value' => $this->getData(['admin', 'backgroundColorButtonRed'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('adminColorGreen', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Bouton validation',
'value' => $this->getData(['admin', 'backgroundColorButtonGreen'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Mise en forme du texte</h4>
<div class="row">
<div class="col4">
<?php echo template::select('adminFontText', $module::$fonts, [
'label' => 'Police du texte',
'selected' => $this->getData(['admin', 'fontText']),
'fonts' => true
]); ?>
</div>
<div class="col4">
<?php echo template::select('adminFontTextSize', $module::$siteFontSizes, [
'label' => 'Taille',
'selected' => $this->getData(['admin', 'fontSize'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('adminFontTitle', $module::$fonts, [
'label' => 'Police des titres',
'selected' => $this->getData(['admin', 'fontTitle']),
'fonts' => true
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,38 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Aperçu en direct
*/
$("#themeAdvancedCss").on("change keydown keyup", function() {
// Ajout du css au DOM
$("#themePreview").remove();
$("<style>")
.attr("type", "text/css")
.attr("id", "themePreview")
.text($(this).val())
.appendTo("head");
});
/**
* Confirmation de réinitialisation
*/
$("#themeAdvancedReset").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir réinitialiser à son état d'origine la personnalisation avancée ?", function() {
$(location).attr("href", _this.attr("href"));
});
});

View File

@ -0,0 +1,40 @@
<?php echo template::formOpen('themeAdvancedForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('themeAdvancedBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeSiteHelp', [
'href' => 'https://doc.deltacms.fr/editeur-css',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset4">
<?php echo template::button('themeAdvancedReset', [
'href' => helper::baseUrl() . 'theme/reset/custom' . '&csrf=' . $_SESSION['csrf'],
'class' => 'buttonRed',
'ico' => 'cancel',
'value' => 'Réinitialiser'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('themeAdvancedSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::textarea('themeAdvancedCss', [
'value' => file_get_contents(self::DATA_DIR.'custom.css'),
'class' => 'editor'
]); ?>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,25 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/
#backToTop {
display: block;
}

View File

@ -0,0 +1,67 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Affichage de l'icone de remontée et permettre l'aperçu.
*/
$(document).ready(function(){
$("#backToTop").css("display","show");
});
/**
* Aperçu en direct
*/
$("input, select").on("change", function() {
// Option fixe pour contain et cover
var themeBodyImageSize = $("#themeBodyImageSize").val();
if(themeBodyImageSize === "cover" ||
themeBodyImageSize === "contain" ) {
$("#themeBodyImageAttachment").val("fixed");
}
// Couleur du fond
var css = "html{background-color:" + $("#themeBodyBackgroundColor").val() + "}";
// Image du fond
var themeBodyImage = $("#themeBodyImage").val();
if(themeBodyImage) {
css += "html{background-image:url('<?php echo helper::baseUrl(false); ?>site/file/source/" + themeBodyImage + "');background-repeat:" + $("#themeBodyImageRepeat").val() + ";background-position:" + $("#themeBodyImagePosition").val() + ";background-attachment:" + $("#themeBodyImageAttachment").val() + ";background-size:" + $("#themeBodyImageSize").val() + "}";
css += "html{background-color:rgba(0,0,0,0);}";
}
else {
css += "html{background-image:none}";
}
css += '#backToTop {background-color:' + $("#themeBodyToTopBackground").val() + ';color:' + $("#themeBodyToTopColor").val() + ';}';
// Ajout du css au DOM
$("#themePreview").remove();
$("<style>")
.attr("type", "text/css")
.attr("id", "themePreview")
.text(css)
.appendTo("head");
});
// Affiche / Cache les options de l'image du fond
$("#themeBodyImage").on("change", function() {
if($(this).val()) {
$("#themeBodyImageOptions").slideDown();
}
else {
$("#themeBodyImageOptions").slideUp();
}
}).trigger("change");

View File

@ -0,0 +1,108 @@
<?php echo template::formOpen('themeBodyForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('themeBodyBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeBodyHelp', [
'href' => 'https://doc.deltacms.fr/personnalisation-de-l-arriere-plan',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset6">
<?php echo template::submit('themeBodySubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Couleurs</h4>
<div class="row">
<div class="col6">
<?php echo template::text('themeBodyBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
'label' => 'Arrière-plan',
'value' => $this->getData(['theme', 'body', 'backgroundColor'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::text('themeBodyToTopBackground', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Fond icône haut de page',
'value' => $this->getData(['theme', 'body', 'toTopbackgroundColor'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('themeBodyToTopColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Icône haut de page',
'value' => $this->getData(['theme', 'body', 'toTopColor'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Image</h4>
<div class="row">
<div class="col12">
<?php
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : "";
echo template::file('themeBodyImage', [
'help' => 'Sélectionner une image',
'label' => 'Arrière-plan',
'type' => 1,
'value' => $imageFile
]); ?>
</div>
</div>
<div id="themeBodyImageOptions" class="displayNone">
<div class="row">
<div class="col6">
<?php echo template::select('themeBodyImageRepeat', $module::$repeats, [
'label' => 'Répétition',
'selected' => $this->getData(['theme', 'body', 'imageRepeat'])
]); ?>
</div>
<div class="col6">
<?php echo template::select('themeBodyImagePosition', $module::$imagePositions, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'body', 'imagePosition'])
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::select('themeBodyImageAttachment', $module::$attachments, [
'label' => 'Défilement',
'selected' => $this->getData(['theme', 'body', 'imageAttachment'])
]); ?>
</div>
<div class="col6">
<?php echo template::select('themeBodyImageSize', $module::$bodySizes, [
'label' => 'Taille',
'selected' => $this->getData(['theme', 'body', 'imageSize'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,31 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/
/**
* Titre zone TinyMCE
*/
.titleWysiwygContent {
font-family: "Oswald",sans-serif;
font-weight: normal;
text-transform: none;
font-size: 1.0em;
margin: 10px;
}

View File

@ -0,0 +1,314 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Aperçu en direct
*/
$("input, select").on("change", function() {
// Import des polices de caractères
var footerFont = $("#themeFooterFont").val();
var css = "@import url('https://fonts.googleapis.com/css?family=" + footerFont + "');";
// Couleurs du pied de page
var colors = core.colorVariants($("#themeFooterBackgroundColor").val());
var textColor = $("#themeFooterTextColor").val();
var css = "footer {background-color:" + colors.normal + ";color:" + textColor + "}";
css += "footer a{color:" + textColor + "}";
// Couleur de l'éditeur
css += ".editorWysiwyg{background-color:" + colors.normal + " !important; color:" + textColor + " !important;}";
// Hauteur du pied de page
//css += "#footersiteLeft, #footersiteCenter, #footersiteRight, #footerbodyLeft, #footerbodyCenter, #footerbodyRight {margin:" + $("#themeFooterHeight").val() + " 0}";
css += "footer #footersite > div{margin:" + $("#themeFooterHeight").val() + " 0}";
css += "footer #footerbody > div{margin:" + $("#themeFooterHeight").val() + " 0}";
// Alignement du contenu
css += "#footerSocials{text-align:" + $("#themeFooterSocialsAlign").val() + "}";
css += "#footerText > p {text-align:" + $("#themeFooterTextAlign").val() + "}";
css += "#footerCopyright{text-align:" + $("#themeFooterCopyrightAlign").val() + "}";
// Taille, couleur, épaisseur et capitalisation du titre de la bannière
css += "footer span, #footerText > p {color:" + $("#themeFooterTextColor").val() + ";font-family:'" + footerFont.replace(/\+/g, " ") + "',sans-serif;font-weight:" + $("#themeFooterFontWeight").val() + ";font-size:" + $("#themeFooterFontSize").val() + ";text-transform:" + $("#themeFooterTextTransform").val() + "}";
// Marge
if($("#themeFooterMargin").is(":checked")) {
css += 'footer{padding: 0 20px;}';
}
else {
css += 'footer{padding:0}';
}
// Ajout du css au DOM
$("#themePreview").remove();
$("<style>")
.attr("type", "text/css")
.attr("id", "themePreview")
.text(css)
.appendTo("footer");
// Position du pied de page
switch($("#themeFooterPosition").val()) {
case 'hide':
$("footer").hide();
break;
case 'site':
$("footer").show().appendTo("#site");
$("footer > div:first-child").removeAttr("class");
$("footer > div:first-child").addClass("container");
break;
case 'body':
$("footer").show().appendTo("body");
$("footer > div:first-child").removeAttr("class");
$("footer > div:first-child").addClass("container-large");
break;
}
// Réduire la marge du paragraphe de la zone de texte enrichie
$("#footerText > p").css("margin-top","0");
$("#footerText > p").css("margin-bottom","0");
});
// Position dans les blocs
// Bloc texte personnalisé
$(".themeFooterContent").on("change",function() {
// Position site ou body
var footerPosition = $("#themeFooterPosition").val();
switch($("#themeFooterTextPosition").val()) {
case "hide":
$("#footerText").hide();
break;
default:
// Choix de la position du bloc
textPosition = $("#themeFooterTextPosition").val();
textPosition = textPosition.substr(0,1).toUpperCase()+textPosition.substr(1);
$("#footerText").show().appendTo("#footer" + footerPosition + textPosition);
break;
}
switch($("#themeFooterSocialsPosition").val()) {
case 'hide':
$("#footerSocials").hide();
break;
default:
// Choix de la position du bloc
socialsPosition = $("#themeFooterSocialsPosition").val();
socialsPosition = socialsPosition.substr(0,1).toUpperCase()+socialsPosition.substr(1);
$("#footerSocials").show().appendTo("#footer" + footerPosition + socialsPosition);
break;
}
switch($("#themeFooterCopyrightPosition").val()) {
case 'hide':
$("#footerCopyright").hide();
break;
default:
// Choix de la position du bloc
copyrightPosition = $("#themeFooterCopyrightPosition").val();
copyrightPosition = copyrightPosition.substr(0,1).toUpperCase()+copyrightPosition.substr(1);
$("#footerCopyright").show().appendTo("#footer" + footerPosition + copyrightPosition);
break;
}
}).trigger("change");
// Fin Position dans les blocs
// Modification dynamique de la mise en page
$("#themeFooterTemplate").on("change",function() {
// Nettoyage des sélecteurs des contenus
var newOptions = {
4: {'hide' : 'Masqué', 'left' : 'En haut', 'center' : 'Au milieu', 'right' : 'En bas'} ,
3: {'hide': 'Masqué', 'left': 'A gauche', 'center': 'Au centre', 'right': 'A droite'} ,
2: {'hide': 'Masqué', 'left': 'A gauche', 'right': 'A droite'} ,
1: {'hide': 'Masqué', 'center': 'Affiché'}
};
var $el = $(".themeFooterContent");
$el.empty();
// Eléments des position de contenus
$.each(newOptions[$("#themeFooterTemplate").val()], function(key,value) {
$el.append($("<option></option>")
.attr("value", key).text(value));
});
var position = $("#themeFooterPosition").val();
// Masquer les contenus
$("#footerCopyright").hide();
$("#footerText").hide();
$("#footerSocials").hide();
// Dimension des blocs
switch($("#themeFooterTemplate").val()) {
case "1":
$("#footer" + position + "Left").css("display","none");
$("#footer" + position + "Center").removeAttr('class').addClass("col12").css("display","");
$("#footer" + position + "Right").css("display","none");
break;
case "2":
$("#footer" + position + "Left").removeAttr('class').addClass('col6').css("display","");
$("#footer" + position + "Center").css("display","none").removeAttr('class');
$("#footer" + position + "Right").removeAttr('class').addClass('col6').css("display","");
break;
case "3":
$("#footer" + position + "Left").removeAttr('class').addClass('col4').css("display","");
$("#footer" + position + "Center").removeAttr('class').addClass('col4').css("display","");
$("#footer" + position + "Right").removeAttr('class').addClass('col4').css("display","");
break;
case "4":
$("#footer" + position + "Left").removeAttr('class').addClass('col12').css("display","");
$("#footer" + position + "Center").removeAttr('class').addClass('col12').css("display","");
$("#footer" + position + "Right").removeAttr('class').addClass('col12').css("display","");
break;
}
});
// Désactivation des sélections multiples
$("#themeFooterSocialsPosition").on("change", function() {
if ($(this).prop('selectedIndex') >= 1 ) {
if ( $("#themeFooterTextPosition").prop('selectedIndex') === $(this).prop('selectedIndex') ) {
$("#themeFooterTextPosition").prop('selectedIndex',0);
$("#footerText").hide();
}
if ( $("#themeFooterCopyrightPosition").prop('selectedIndex') === $(this).prop('selectedIndex') ) {
$("#themeFooterCopyrightPosition").prop('selectedIndex',0);
$("#footerCopyright").hide();
}
}
}).trigger("change");
$("#themeFooterTextPosition").on("change", function() {
if ($(this).prop('selectedIndex') >= 1 ) {
if ( $("#themeFooterSocialsPosition").prop('selectedIndex') === $(this).prop('selectedIndex') ) {
$("#themeFooterSocialsPosition").prop('selectedIndex',0);
$("#footerSocials").hide();
}
if ( $("#themeFooterCopyrightPosition").prop('selectedIndex') === $(this).prop('selectedIndex') ) {
$("#themeFooterCopyrightPosition").prop('selectedIndex',0);
$("#footerCopyright").hide();
}
}
}).trigger("change");
$("#themeFooterCopyrightPosition").on("change", function() {
if ($(this).prop('selectedIndex') >= 1 ) {
if ( $("#themeFooterTextPosition").prop('selectedIndex') === $(this).prop('selectedIndex') ) {
$("#themeFooterTextPosition").prop('selectedIndex',0);
$("#footerText").hide();
}
if ( $("#themeFooterSocialsPosition").prop('selectedIndex') === $(this).prop('selectedIndex') ) {
$("#themeFooterSocialsPosition").prop('selectedIndex',0);
$("#footerSocials").hide();
}
}
}).trigger("change");
// Affiche / Cache les options du footer fixe
$("#themeFooterPosition").on("change", function() {
if($(this).val() === 'body') {
$("#themeFooterPositionFixed").slideDown();
}
else {
$("#themeFooterPositionFixed").slideUp(function() {
$("#themeFooterFixed").prop("checked", false).trigger("change");
});
}
}).trigger("change");
// Lien de connexion
$("#themeFooterLoginLink").on("change", function() {
if($(this).is(":checked")) {
$("#footerLoginLink").show();
}
else {
$("#footerLoginLink").hide();
}
}).trigger("change");
// Numéro de version
$("#themefooterDisplayVersion").on("change", function() {
if($(this).is(":checked")) {
$("#footerDisplayVersion").show();
}
else {
$("#footerDisplayVersion").hide();
}
}).trigger("change");
// Numéro de version
$("#themefooterDisplayCopyright").on("change", function() {
if($(this).is(":checked")) {
$("#footerDisplayCopyright").show();
}
else {
$("#footerDisplayCopyright").hide();
}
}).trigger("change");
// Site Map
$("#themefooterDisplaySiteMap").on("change", function() {
if($(this).is(":checked")) {
$("#footerDisplaySiteMap").show();
}
else {
$("#footerDisplaySiteMap").hide();
}
}).trigger("change");
// Rechercher
$("#themeFooterDisplaySearch").on("change", function() {
if($(this).is(":checked")) {
$("#footerDisplaySearch").show();
}
else {
$("#footerDisplaySearch").hide();
}
}).trigger("change");
// Mentions légales
$("#themeFooterDisplayLegal").on("change", function() {
if($(this).is(":checked")) {
$("#footerDisplayLegal").show();
}
else {
$("#footerDisplayLegal").hide();
}
}).trigger("change");
// Pages spéciales : activation si une page est sélectionnée
$("#configLegalPageId").on("change", function() {
if ( $("#configLegalPageId option:selected").text() === 'Aucune') {
$("#themeFooterDisplayLegal").prop('checked', false);
$("#themeFooterDisplayLegal").prop( "disabled", true );
$("#footerDisplayLegal").hide();
} else {
$("#themeFooterDisplayLegal").prop( "disabled", false );
}
}).trigger("change");
$("#configSearchPageId").on("change", function() {
if ( $("#configSearchPageId option:selected").text() === 'Aucune') {
$("#themeFooterDisplaySearch").prop('checked', false);
$("#themeFooterDisplaySearch").prop( "disabled", true );
$("#footerDisplaySearch").hide();
} else {
$("#themeFooterDisplaySearch").prop( "disabled", false );
}
}).trigger("change");
/*
// Affiche / Cache les options de la position
$("#themeFooterPosition").on("change", function() {
if($(this).val() === 'site') {
$("#themeFooterPositionOptions").slideDown();
}
else {
$("#themeFooterPositionOptions").slideUp(function() {
$("#themeFooterMargin").prop("checked", false).trigger("change");
});
}
}).trigger("change");
*/

View File

@ -0,0 +1,283 @@
<?php echo template::formOpen('themeFooterForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('themeFooterBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeFooterHelp', [
'href' => 'https://doc.deltacms.fr/personnalisation-du-pied-de-page',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset6">
<?php echo template::submit('themeFooterSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres</h4>
<div class="row">
<div class="col6">
<?php echo template::select('themeFooterPosition', $module::$footerPositions, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'footer', 'position'])
]); ?>
</div>
<div class="col6">
<?php echo template::select('themeFooterHeight', $module::$footerHeights, [
'label' => 'Marges verticales',
'selected' => $this->getData(['theme', 'footer', 'height'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Couleurs</h4>
<div class="row">
<div class="col6">
<?php echo template::text('themeFooterTextColor', [
'class' => 'colorPicker',
'label' => 'Texte',
'value' => $this->getData(['theme', 'footer', 'textColor'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('themeFooterBackgroundColor', [
'class' => 'colorPicker',
'label' => 'Arrière-plan',
'value' => $this->getData(['theme', 'footer', 'backgroundColor']),
'help' => 'Quand le pied de page est dans le site, l\'arrière plan transparent montre le fond de la page. Quand le pied de page est hors du site, l\'arrière plan transparent montre le fond du site.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Contenu</h4>
<div class="row">
<div class="col3">
<?php echo template::checkbox('themefooterDisplayCopyright', true, 'Motorisé par', [
'checked' => $this->getData(['theme', 'footer','displayCopyright']),
'help' => 'Affiche cette mention devant DeltaCMS'
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('themefooterDisplayVersion', true, 'Version', [
'checked' => $this->getData(['theme', 'footer','displayVersion']),
'help' => 'Affiche le numéro de version après DeltaCMS'
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('themefooterDisplaySiteMap', true, 'Plan du site', [
'checked' => $this->getData(['theme', 'footer', 'displaySiteMap'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('themefooterDisplayCookie', true, 'Cookies', [
'checked' => $this->getData(['config', 'cookieConsent']) === true ? $this->getData(['theme', 'footer', 'displayCookie']) : false,
'help' => 'Message d\'information relatif aux cookies, disponible si l\'acceptation des cookies est activé.',
'disabled' => !$this->getData(['config', 'cookieConsent'])
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('themeFooterLoginLink', true, 'Lien de connexion', [
'checked' => $this->getData(['theme', 'footer', 'loginLink']),
'help' => 'Pour limiter les tentatives de piratage, enregistrez la page de connexion en favori et désactivez cette option.'
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('themeFooterDisplayMemberBar', true, 'Barre du membre', [
'checked' => $this->getData(['theme', 'footer', 'displayMemberBar']),
'help' => 'Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés, ne s\'applique pas aux éditeurs et administrateurs.'
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::checkbox('themeFooterDisplayLegal', true, 'Mentions légales', [
'checked' => $this->getData(['locale', 'legalPageId']) === 'none' ? false : $this->getData(['theme', 'footer', 'displayLegal']),
'disabled' => $this->getData(['locale', 'legalPageId']) === 'none' ? true : false,
'help' => 'Option active si une page a été sélectionnée.'
]); ?>
</div>
<div class="col3">
<?php echo template::select('configLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Page "Mentions légales" ' . template::flag('site', '20px'),
'selected' => $this->getData(['locale', 'legalPageId'])
]); ?>
</div>
<div class="col3">
<?php echo template::checkbox('themeFooterDisplaySearch', true, 'Rechercher', [
'checked' => $this->getData(['locale', 'searchPageId']) === 'none' ? false : $this->getData(['theme', 'footer', 'displaySearch']),
'disabled' => $this->getData(['locale', 'searchPageId']) === 'none' ? true : false,
'help' => 'Option active si une page a été sélectionnée.'
]); ?>
</div>
<div class="col3">
<?php echo template::select('configSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Page "Rechercher" ' . template::flag('site', '20px'),
'selected' => $this->getData(['locale', 'searchPageId']),
'help' => 'Options identique à la configuration du site',
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::textarea('themeFooterText', [
'label' => '<div class="titleWysiwygContent">Contenu personnalisé</div>',
'value' => $this->getData(['theme', 'footer', 'text']),
'class' => 'editorWysiwyg'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Mise en forme du texte</h4>
<div class="row">
<div class="col3">
<?php echo template::select('themeFooterFont', $module::$fonts, [
'label' => 'Police',
'selected' => $this->getData(['theme', 'footer', 'font']),
'fonts' => true
]); ?>
</div>
<div class="col3">
<?php echo template::select('themeFooterFontSize', $module::$footerFontSizes, [
'label' => 'Taille',
'help' => 'Proportionnelle à celle définie dans le site.',
'selected' => $this->getData(['theme', 'footer', 'fontSize'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('themeFooterFontWeight', $module::$fontWeights, [
'label' => 'Style',
'selected' => $this->getData(['theme', 'footer', 'fontWeight'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('themeFooterTextTransform', $module::$textTransforms, [
'label' => 'Casse',
'selected' => $this->getData(['theme', 'footer', 'textTransform'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Dispositions</h4>
<div class="row">
<div class="col4">
<?php $footerBlockPosition = is_null($this->getData(['theme', 'footer', 'template'])) ? $module::$footerblocks[3] : $module::$footerblocks [$this->getData(['theme', 'footer', 'template'])] ;?>
<?php echo template::select('themeFooterTemplate', $module::$footerTemplate, [
'label' => 'Répartition',
'selected' => is_null($this->getData(['theme', 'footer', 'template'])) ? 4 : $this->getData(['theme', 'footer', 'template'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<p><strong>Contenu personnalisé</strong></p>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterTextPosition', $footerBlockPosition, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'footer', 'textPosition']),
'class' => 'themeFooterContent'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterTextAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'textAlign'])
]); ?>
</div>
</div>
</div>
<div class="col4">
<p><strong>Réseaux sociaux</strong></p>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterSocialsPosition', $footerBlockPosition, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'footer', 'socialsPosition']),
'class' => 'themeFooterContent'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterSocialsAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'socialsAlign'])
]); ?>
</div>
</div>
</div>
<div class="col4">
<p><strong>Informations</strong></p>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterCopyrightPosition', $footerBlockPosition, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'footer', 'copyrightPosition']),
'class' => 'themeFooterContent'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterCopyrightAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'copyrightAlign'])
]); ?>
</div>
</div>
</div>
<div class="col6">
<div id="themeFooterPositionOptions">
<?php echo template::checkbox('themeFooterMargin', true, 'Alignement avec le contenu', [
'checked' => $this->getData(['theme', 'footer', 'margin'])
]); ?>
</div>
</div>
<div class="col6">
<div id="themeFooterPositionFixed" class="displayNone">
<?php echo template::checkbox('themeFooterFixed', true, 'Pied de page fixe', [
'checked' => $this->getData(['theme', 'footer', 'fixed'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,30 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/
/**
* Titre zone TinyMCE
*/
.titleWysiwygContent {
font-family: "Oswald",sans-serif;
font-weight: normal;
text-transform: none;
font-size: 1.0em;
margin: 10px;
}

View File

@ -0,0 +1,267 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
$(document).ready(function(){
$("header").css("line-height", "");
$("header").css("height", "");
});
/**
* Aperçu en direct
*/
$("input, select").on("change", function() {
var css = "";
// Contenu perso
if ($("#themeHeaderFeature").val() == "feature") {
css = "header{min-height: " + $("#themeHeaderHeight").val() + ";height:" + $("#themeHeaderHeight").val() + "; overflow:hidden; background-position:top; background-repeat: no-repeat; line-height:1.15; background-color:unset; background-image:unset; text-align:unset;}";
$("#featureContent").appendTo("header").show();
$("#themeHeaderTitle").hide();
// Modifier le texte du sélecteur de hauteur
$("#themeHeaderHeight option:eq(0)").text("Hauteur du contenu personnalisé");
}
// Couleurs, image, alignement et hauteur de la bannière
if ($("#themeHeaderFeature").val() == "wallpaper") {
// Masque le contenu perso
$("#featureContent").hide();
// Récupérer la taille de l'image
var tmpImg = new Image();
tmpImg.onload = function() {
// Informations affichées
$("#themeHeaderImageHeight").html(tmpImg.height + "px");
$("#themeHeaderImageWidth").html(tmpImg.width + "px");
$("#themeHeaderImageRatio").html(tmpImg.width / tmpImg.height);
// Limiter la hauteur à 600 px
if (tmpImg.height > 600) {
tmpImgHeight = 600;
} else {
tmpImgHeight = tmpImg.height;
}
//Modifier la dropdown liste si une image n'est pas sélectionnée
if ($("#themeHeaderImage").val() !== "" ) {
// Une image est ajoutée ou changée
if ($("#themeHeaderHeight option").length === 5) {
// Pas d'image précédemment on ajoute l'option
$("#themeHeaderHeight ").prepend('<option selected="selected" value="0"> Hauteur de l\'image sélectionnée </option>');
}
// Modifier la valeur
$("#themeHeaderHeight option:eq(0)").val(tmpImgHeight + "px");
// Modifier l'option
$("#themeHeaderHeight option:eq(0)").html("Hauteur de l\'image sélectionnée (" + tmpImgHeight + "px)");
}
};
if ($("#themeHeaderImage").val() === "" &&
$("#themeHeaderHeight option").length === 6 ) {
$("#themeHeaderHeight option:eq(0)").remove();
}
tmpImg.src= "<?php echo helper::baseUrl(false); ?>" + "site/file/source/" + $("#themeHeaderImage").val();
// Import des polices de caractères
var headerFont = $("#themeHeaderFont").val();
var css = "@import url('https://fonts.googleapis.com/css?family=" + headerFont + "');";
css += "header{text-align:" + $("#themeHeaderTextAlign").val() + ";";
if ($("#themeHeaderImage").val()) {
// Une image est sélectionnée
css += "background-image:url('<?php echo helper::baseUrl(false); ?>site/file/source/" + $("#themeHeaderImage").val() + "');background-repeat:" + $("#themeHeaderImageRepeat").val() + ";background-position:" + $("#themeHeaderImagePosition").val() + ";";
css += "background-size:" + $("#themeHeaderImageContainer").val() + ";";
// Pas d'image sélectionnée
} else {
// Désactiver l'option responsive
css += "background-image:none;";
}
css += "line-height:" + $("#themeHeaderHeight").val() + ";height:" + $("#themeHeaderHeight").val() + "}";
// Taille, couleur, épaisseur et capitalisation du titre de la bannière
css += "header span{font-family:'" + headerFont.replace(/\+/g, " ") + "',sans-serif;font-weight:" + $("#themeHeaderFontWeight").val() + ";font-size:" + $("#themeHeaderFontSize").val() + ";text-transform:" + $("#themeHeaderTextTransform").val() + ";color:" + $("#themeHeaderTextColor").val() + "}";
// Cache le titre de la bannière
if($("#themeHeaderTextHide").is(":checked")) {
$("#themeHeaderTitle").hide();
}
else {
$("#themeHeaderTitle").show();
}
}
// Couleur du fond
css += "header{background-color:" + $("#themeHeaderBackgroundColor").val() + ";}";
// Position de la bannière
var positionNav = <?php echo json_encode($this->getData(['theme', 'menu', 'position'])); ?>;
var positionHeader = $("#themeHeaderPosition").val();
switch(positionHeader) {
case 'hide':
$("header").hide();
$("nav").show().prependTo("#site");
break;
case 'site':
$("header").show().prependTo("#site");
// Position du menu
switch (positionNav) {
case "body-first":
$("nav").show().insertAfter("header");
break;
case "site-first":
$("nav").show().prependTo("#site");
// Supprime le margin en trop du menu
if(<?php echo json_encode($this->getData(['theme', 'menu', 'margin'])); ?>) {
css += 'nav{margin:0 20px}';
}
break;
case "body-second":
case "site-second":
$("nav").show().insertAfter("header");
// Supprime le margin en trop du menu
if(<?php echo json_encode($this->getData(['theme', 'menu', 'margin'])); ?>) {
css += 'nav{margin:0 20px}';
}
break;
}
break;
case 'body':
// Position du menu
switch (positionNav) {
case "top":
$("header").show().insertAfter("nav");
break;
case "site-first":
case "body-first":
$("header").show().insertAfter("#bar");
$("nav").show().insertAfter("#bar");
break;
case "site-second":
case "body-second":
$("header").show().insertAfter("#bar");
$("nav").show().insertAfter("header");
break;
}
}
// Marge dans le site
if( $("#themeHeaderMargin").is(":checked") &&
$("#themeHeaderPosition").val() === "site"
) {
css += 'header{margin:20px 20px 0 20px !important;}';
/*} else {
css += 'header{margin:0 !important;}';*/
}
// Largeur du header
switch ($("#themeHeaderWide").val()) {
case "container":
$("header").addClass("container");
break;
case "none":
$("header").removeClass("container");
break;
}
// La bannière est cachée, déplacer le menu dans le site
if (positionHeader === "hide" &&
(positionNav === "body-first" ||
positionNav === "site-first" ||
positionNav === "body-second" ||
positionNav === "site-second"
)) {
$("nav").show().prependTo("#site");
}
// Ajout du css au DOM
$("#themePreview").remove();
$("<style>")
.attr("type", "text/css")
.attr("id", "themePreview")
.text(css)
.appendTo("head");
}).trigger("change");
// Affiche / Cache les options de l'image du fond
$("#themeHeaderImage").on("change", function() {
if($(this).val()) {
$("#themeHeaderImageOptions").slideDown();
}
else {
$("#themeHeaderImageOptions").slideUp(function() {
$("#themeHeaderTextHide").prop("checked", false).trigger("change");
});
}
}).trigger("change");
// Affiche / Cache les options de la position
$("#themeHeaderPosition").on("change", function() {
if($(this).val() === 'site') {
$("#themeHeaderContainerWrapper").slideUp();
$("#themeHeaderPositionOptions").slideDown();
$("#themeHeaderWideWrapper").slideUp();
$("#themeHeaderMarginWrapper").slideDown();
}
else if ($(this).val() === 'hide') {
$("#themeHeaderContainerWrapper").slideUp();
$("#themeHeaderWideWrapper").slideUp();
$("#themeHeaderMarginWrapper").slideUp();
$("#themeHeaderMargin").prop("checked", false);
$("#themeHeaderPositionOptions").slideUp(function() {
$("#themeHeaderMargin").prop("checked", false).trigger("change");
});
} else {
$("#themeHeaderWideWrapper").slideDown();
$("#themeHeaderMarginWrapper").slideUp();
$("#themeHeaderMargin").prop("checked", false);
}
}).trigger("change");
// Affiche / Cache l'option bannière masquée en écran réduit
$("#themeHeaderPosition").on("change", function() {
if($(this).val() === 'hide') {
$("#themeHeaderSmallDisplay").slideUp();
}
else {
$("#themeHeaderSmallDisplay").slideDown();
}
}).trigger("change");
// Affiche les blocs selon le type bannière
$("#themeHeaderFeature").on("change", function() {
if($(this).val() === 'wallpaper') {
$(".wallpaperContainer").show();
$(".featureContainer").hide();
$("#themeHeaderTextColorWrapper").show();
}
if($(this).val() === 'feature') {
$(".featureContainer").show();
$(".wallpaperContainer").hide();
$("#themeHeaderTextColorWrapper").hide();
}
}).trigger("change");

View File

@ -0,0 +1,222 @@
<?php echo template::formOpen('themeHeaderForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('themeHeaderBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeHeaderHelp', [
'href' => 'https://doc.deltacms.fr/personnalisation-de-la-banniere',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset6">
<?php echo template::submit('themeHeaderSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres</h4>
<div class="row">
<div class="col4">
<?php echo template::select('themeHeaderPosition', $module::$headerPositions, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'header', 'position'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('themeHeaderFeature', $module::$headerFeatures, [
'label' => 'Nature de contenu',
'selected' => $this->getData(['theme', 'header', 'feature'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('themeHeaderHeight', $module::$headerHeights, [
'label' => 'Hauteur maximale',
'selected' => $this->getData(['theme', 'header', 'height']),
'help' => 'La hauteur maximale est de 600 pixels, même si les dimensions de l\'image sélectionnée sont supérieures. <br />Lorsque l\'adaptation est positionnée sur Responsive, la hauteur diminue proportionnellement à la largeur.'
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('themeHeaderWide', $module::$containerWides, [
'label' => 'Largeur',
'selected' => $this->getData(['theme', 'header', 'wide'])
]); ?>
</div>
<div class="col4">
<div id="themeHeaderSmallDisplay" class="displayNone">
<?php echo template::checkbox('themeHeaderTinyHidden', true, 'Masquer la bannière en écran réduit', [
'checked' => $this->getData(['theme', 'header', 'tinyHidden'])
]); ?>
</div>
</div>
<div class="col4">
<div id="themeHeaderPositionOptions" class="displayNone">
<?php echo template::checkbox('themeHeaderMargin', true, 'Aligner la bannière avec le contenu', [
'checked' => $this->getData(['theme', 'header', 'margin'])
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Couleurs</h4>
<div class="row">
<div class="col6">
<?php echo template::text('themeHeaderBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Arrière-plan',
'value' => $this->getData(['theme', 'header', 'backgroundColor'])
]); ?>
</div>
<div class="col6">
<?php echo template::text('themeHeaderTextColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Texte',
'value' => $this->getData(['theme', 'header', 'textColor'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row wallpaperContainer">
<div class="col12">
<div class="block">
<h4>Mise en forme du titre</h4>
<div class="row">
<div class="col4">
<?php echo template::checkbox('themeHeaderTextHide', true, 'Masquer le titre du site', [
'checked' => $this->getData(['theme', 'header', 'textHide'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('themeHeaderFont', $module::$fonts, [
'label' => 'Police',
'selected' => $this->getData(['theme', 'header', 'font']),
'fonts' => true
]); ?>
</div>
<div class="col4">
<?php echo template::select('themeHeaderFontSize', $module::$headerFontSizes, [
'label' => 'Taille',
'help' => 'Proportionnelle à celle définie dans le site.',
'selected' => $this->getData(['theme', 'header', 'fontSize'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('themeHeaderFontWeight', $module::$fontWeights, [
'label' => 'Style',
'selected' => $this->getData(['theme', 'header', 'fontWeight'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('themeHeaderTextTransform', $module::$textTransforms, [
'label' => 'Casse',
'selected' => $this->getData(['theme', 'header', 'textTransform'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('themeHeaderTextAlign', $module::$aligns, [
'label' => 'Alignement du contenu',
'selected' => $this->getData(['theme', 'header', 'textAlign'])
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row wallpaperContainer">
<div class="col12">
<div class="block">
<h4>Papier peint</h4>
<div class="row">
<div class="col12">
<?php
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'header', 'image'])) ?
$this->getData(['theme', 'header', 'image']) : "";
echo template::file('themeHeaderImage', [
'help' => 'Sélectionner une image aux dimensions recommandées ci-dessous :',
'label' => 'Image',
'type' => 1,
'value' => $imageFile
]); ?>
</div>
</div>
<div id="themeHeaderImageOptions" class="displayNone">
<div class="row">
<div class="col3">
<?php echo template::select('themeHeaderImageRepeat', $module::$repeats, [
'label' => 'Répétition',
'selected' => $this->getData(['theme', 'header', 'imageRepeat'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('themeHeaderImageContainer', $module::$headerWide, [
'label' => 'Adaptation',
'selected' => $this->getData(['theme', 'header', 'imageContainer']),
'help' => 'Les modes responsives permettent de conserver des dimensions proportionnelles.<br />
Cover pour une image plus grande que la bannière, Contain pour une image plus petite.
Les modes Auto et Etiré ne provoquent pas de modification de la hauteur de la bannière.'
]); ?>
</div>
<div class="col3">
<?php echo template::select('themeHeaderImagePosition', $module::$imagePositions, [
'label' => 'Position',
'selected' => $this->getData(['theme', 'header', 'imagePosition'])
]); ?>
</div>
<div id="themeHeaderShow" class="col3">
<?php echo template::checkbox('themeHeaderlinkHomePage', true, 'Bannière cliquable', [
'checked' => $this->getData(['theme', 'header', 'linkHomePage'])
]); ?>
</div>
</div>
<div class="row">
<div class="col12 textAlignCenter">
<span id="themeHeaderImage">
Largeur : <span id="themeHeaderImageWidth"></span> | Hauteur : <span id="themeHeaderImageHeight"></span> | ratio : <span id="themeHeaderImageRatio"></span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row featureContainer">
<div class="col12">
<div class="row">
<div class="col12">
<?php echo template::textarea('themeHeaderText', [
'label' => '<div class="titleWysiwygContent">Contenu personnalisé</div>',
'class' => 'editorWysiwyg',
'value' => $this->getData(['theme', 'header', 'featureContent'])
]); ?>
</div>
</div>
</div>
</div>
<div id="featureContent" class="displayNone">
<?php echo $this->getData(['theme','header','featureContent']);?>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,74 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/
#bar,
#site,
header,
nav,
section,
footer {
position: relative;
z-index: 10;
}
.footerbodyFixed {
position: relative;
z-index: 5;
}
nav li ul {
display: none;
}
#themeShowAll,
#themeHelp,
#themeBack,
#themeManage,
#themeAdmin,
#themeAdvanced {
position: relative;
z-index: 11;
}
.themeOverlay {
-webkit-transition: all .3s;
transition: all .3s;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 5;
cursor: pointer;
content: " ";
display: block;
background: transparent;
}
.themeOverlay:not(.themeOverlayHideBackground):hover,
.themeOverlayTriggerHover {
background: rgba(39, 174, 96, .5);
}
#themeOverlayBody {
position: fixed;
/* Sinon l'overlay s'arrête à la hauteur de la fenêtre et non de la page*/
}

View File

@ -0,0 +1,79 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Ajout des overlays
*/
$("<a>")
.addClass("themeOverlay")
.attr({
"id": "themeOverlayBody",
"href": "<?php echo helper::baseUrl(); ?>theme/body"
})
.appendTo("body");
$("<a>")
.addClass("themeOverlay")
.attr({
"id": "themeOverlayHeader",
"href": "<?php echo helper::baseUrl(); ?>theme/header"
})
.appendTo("header");
$("<a>")
.addClass("themeOverlay")
.attr({
"id": "themeOverlayMenu",
"href": "<?php echo helper::baseUrl(); ?>theme/menu"
})
.appendTo("nav");
$("<a>")
.addClass("themeOverlay")
.attr({
"id": "themeOverlaySite",
"href": "<?php echo helper::baseUrl(); ?>theme/site"
})
.appendTo("#site");
$("<a>")
.addClass("themeOverlay themeOverlayHideBackground")
.attr({
"id": "themeOverlaySection",
"href": "<?php echo helper::baseUrl(); ?>theme/site"
})
.appendTo("section");
$("<a>")
.addClass("themeOverlay")
.attr({
"id": "themeOverlayFooter",
"href": "<?php echo helper::baseUrl(); ?>theme/footer"
})
.appendTo("footer");
/**
* Affiche les zones cachées
*/
$("#themeShowAll").on("click", function() {
$("header.displayNone, nav.displayNone, footer.displayNone").slideToggle();
});
/**
* Simule un survole du site lors du survole de la section
*/
$("section")
.on("mouseover", function() {
$("#themeOverlaySite:not(.themeOverlayTriggerHover)").addClass("themeOverlayTriggerHover");
})
.on("mouseleave", function() {
$("#themeOverlaySite.themeOverlayTriggerHover").removeClass("themeOverlayTriggerHover");
});

View File

@ -0,0 +1,101 @@
<?php if(
$this->getData(['theme', 'header', 'position']) === 'hide'
OR $this->getData(['theme', 'menu', 'position']) === 'hide'
OR $this->getData(['theme', 'footer', 'position']) === 'hide'
): ?>
<?php echo template::speech('Cliquez sur une zone afin d\'accéder à ses options de personnalisation. Vous pouvez également afficher les zones cachées à l\'aide du bouton ci-dessous.'); ?>
<div class="row">
<div class="col2 offset3">
<?php echo template::button('themeBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
'ico' => 'home',
'value' => 'Accueil'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeHelp', [
'href' => 'https://doc.deltacms.fr/theme-2',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeShowAll', [
'ico' => 'eye',
'value' => 'Zones cachées'
]); ?>
</div>
</div>
<div class="row">
<div class="col2 offset3">
<?php echo template::button('themeManage', [
'ico' => 'cogs',
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
'value' => 'Gestion'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeAdmin', [
'ico' => 'brush',
'href' => helper::baseUrl() . $this->getUrl(0) . '/admin',
'value' => 'Administration'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeAdvanced', [
'ico' => 'code',
'href' => helper::baseUrl() . $this->getUrl(0) . '/advanced',
'value' => 'Éditeur CSS'
]); ?>
</div>
</div>
<?php else: ?>
<?php echo template::speech('Cliquez sur une zone afin d\'accéder à ses options de personnalisation.'); ?>
<div class="row">
<div class="col2 offset4">
<?php echo template::button('themeBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
'ico' => 'home',
'value' => 'Accueil'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeHelp', [
'href' => 'https://doc.deltacms.fr/theme-2',
'target' => '_blank',
'ico' => 'help',
'value' => 'Aide',
'class' => 'buttonHelp'
]); ?>
</div>
</div>
<div class="row">
<div class="col2 offset3">
<?php echo template::button('themeManage', [
'ico' => 'cogs',
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
'value' => 'Gestion'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeAdmin', [
'ico' => 'brush',
'href' => helper::baseUrl() . $this->getUrl(0) . '/admin',
'value' => 'Administration'
]); ?>
</div>
<div class="col2">
<?php echo template::button('themeAdvanced', [
'ico' => 'code',
'href' => helper::baseUrl() . $this->getUrl(0) . '/advanced',
'value' => 'Éditeur CSS'
]); ?>
</div>
</div>
<?php endif; ?>

View File

@ -0,0 +1,20 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,25 @@
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
/**
* Confirmation de réinitialisation
*/
$("#configManageReset").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir réinitialiser à son état d'origine le thème du site ?", function() {
$(location).attr("href", _this.attr("href"));
});
});

Some files were not shown because too many files have changed in this diff Show More