Merge branch '114_dev'

This commit is contained in:
Fred Tempez 2022-05-03 16:08:13 +02:00
commit 188dd6b17d
70 changed files with 3495 additions and 2318 deletions

19
.gitignore vendored
View File

@ -1,19 +0,0 @@
# Fichiers du site
site/*
# Dossiers vides dans GitHub
!.gitkeep
/.git
# PHPStorm
.idea/
# Trucs
core/vendor/tinymce/link_list.json
.vscode/*
sitemap.xml.gz
sitemap.xml
robots.txt
.DS_Store
# Service de mise à jour
gitupdate.sh

View File

@ -32,5 +32,5 @@ Options -Indexes
Options -MultiViews Options -MultiViews
</IfModule> </IfModule>
# Attention, surtout ne rien modifier ci-dessous ! # ne pas supprimer la ligne URL rewriting !
# URL rewriting # URL rewriting

View File

@ -1,5 +1,33 @@
# Changelog # Changelog
## Version 11.4.00
### Nouveautés :
- Compatibilité avec PHP 8.1
- Prise en charge des fontes Web Safe. Les fontes initiales sont transférées dans les fontes optionnelles, donc effaçables.
- Toutes les fontes en ligne sont désormais acceptées quel que soit le CDN, Google Fonte (avec preconnect), CDN Fontes ou autres.
- Désormais, les URL internes sont relatives, cela signifie qu'elles ne contiendront plus le domaine et le chemin d'accès au site. Cela permettra le déplacement d'un site d'un hébergement à un autre, d'un dossier d'hébergement à un autre, sans avoir à convertir les adresses internes. Les données d'un site mis à jour et importées d'une version antérieures sont automatiquement converties. En conséquence, le bloc de conversion de la fenêtre d'import est supprimé.
- Suppression temporaire de l'option d'installation d'un module, il faudra passer par une connexion FTP pour cela. Cette fonctionnalité a été réécrite pour la version 11.2.
### Améliorations :
- Configuration de la bannière, modalité d'affichage de la taille d'image recommandée et affichage des dimensions de l'image.
- Edition d'une page, le nom court se complète automatiquement.
- Configuration de la connexion, une option autorise l'affichage de la page de connexion lorsqu'une page de gestion du site est demandée: 'user', 'theme', 'config', 'edit', 'translate', 'addon'.
- L'option de réécriture d'URL n'est pas plus active avec le serveur Nginx.
- Galerie, version 3.5 :
- Nouvelle structure anticipée sur la version 12, le formulaire d'ajout de la galerie est séparé de la liste des galeries du module.
- Lorsque la galerie n'en contient qu'**une seule galerie**, elle peut être affichée directement, la liste des galeries étant ignorée. Pour cela, activer cette option dans les options de la galerie.
- Le contenu de la page peut désormais être affiché avec le contenu de la galerie sélectionnée. Ce paramètre ce gère au niveau de chaque galerie.
- Déplacement du bouton de retour à la liste des galeries en bas de l'écran.
### Corrections :
- URL Rewrite Apache, bug d'interprétation d'activation de la réécriture d'URL lorsque des données ont été inscrites après la ligne servant de délimiteur *# URL rewriting* dans le fichier htaccess.
- Module Galerie : correction de bugs, tri des images, erreurs d'affectation.
- Module Blog : taille recommandée de l'image erronée lorsque la largeur de l'écran est réglée sur fluide (100%).
- Gestion des pages : positionnement dans le menu accessoire ou dans le menu standard.
- Safari sur Mac, bug avec les cookies qui ne sont pas stockés.
- Nettoyage du code.
### Mise à jour :
- TableDND, script JQUERY de tri de tables utilisé par la galerie passe en version 1.0.5
- PHPMailer 6.6.0
## Version 11.3.07 ## Version 11.3.07
### Correction : ### Correction :
- Module galerie, option plein écran inopérante. - Module galerie, option plein écran inopérante.
@ -16,7 +44,6 @@
- Sauvegarde des fontes avec le thème. - Sauvegarde des fontes avec le thème.
- Une fonte Websafe remplace une fonte locale dont le fichier n'est pas disponible. - Une fonte Websafe remplace une fonte locale dont le fichier n'est pas disponible.
## Version 11.3.05 ## Version 11.3.05
### Correction : ### Correction :
- Dossier du fichier de fontes non créé empêchant la création du fichier des appels de fontes. - Dossier du fichier de fontes non créé empêchant la création du fichier des appels de fontes.

View File

@ -1,4 +1,4 @@
# ZwiiCMS 11.3.07 # ZwiiCMS 11.4.00
Zwii est un CMS sans base de données (flat-file) qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation. Zwii est un CMS sans base de données (flat-file) qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.

View File

@ -86,7 +86,7 @@ class helper {
* @param string $sort Type de tri à appliquer au tableau (SORT_ASC, SORT_DESC, ou null) * @param string $sort Type de tri à appliquer au tableau (SORT_ASC, SORT_DESC, ou null)
* @return array * @return array
*/ */
public static function arrayCollumn($array, $column, $sort = null) { public static function arrayColumn($array, $column, $sort = null) {
$newArray = []; $newArray = [];
if(empty($array) === false) { if(empty($array) === false) {
$newArray = array_map(function($element) use($column) { $newArray = array_map(function($element) use($column) {
@ -104,6 +104,14 @@ class helper {
return $newArray; return $newArray;
} }
/**
* Compatibilité avec les anciens modules
*/
public static function arrayCollumn($array, $column, $sort = null) {
return (helper::arrayColumn($array, $column, $sort));
}
/** /**
* Génère un backup des données de site * Génère un backup des données de site
@ -255,11 +263,15 @@ class helper {
* @return bool * @return bool
*/ */
public static function checkRewrite() { public static function checkRewrite() {
if(self::$rewriteStatus === null) { // N'interroge que le serveur Apache
if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0) {
self::$rewriteStatus === false;
} elseif(self::$rewriteStatus === null) {
// Ouvre et scinde le fichier .htaccess // Ouvre et scinde le fichier .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.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 // Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
self::$rewriteStatus = (empty($htaccess[1]) === false); //self::$rewriteStatus = (empty($htaccess[1]) === false);
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') > 0) ? true : false;
} }
return self::$rewriteStatus; return self::$rewriteStatus;
} }

View File

@ -31,6 +31,16 @@ class JsonDb extends \Prowebcraft\Dot
parent::__construct(); parent::__construct();
} }
/**
* Reload data from file
* @return $this
*/
public function reload()
{
$this->loadData(true);
return $this;
}
/** /**
* Set value or array of values to path * Set value or array of values to path
* *

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHPMailer Exception class. * PHPMailer Exception class.
* PHP Version 5.5. * PHP Version 5.5.
@ -9,7 +10,7 @@
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder) * @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2017 Marcus Bointon * @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@ -34,6 +35,6 @@ class Exception extends \Exception
*/ */
public function errorMessage() public function errorMessage()
{ {
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n"; return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHPMailer RFC821 SMTP email transport class. * PHPMailer RFC821 SMTP email transport class.
* PHP Version 5.5. * PHP Version 5.5.
@ -9,7 +10,7 @@
* @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder) * @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2019 Marcus Bointon * @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost * @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@ -34,7 +35,7 @@ class SMTP
* *
* @var string * @var string
*/ */
const VERSION = '6.1.5'; const VERSION = '6.6.0';
/** /**
* SMTP line break constant. * SMTP line break constant.
@ -185,6 +186,8 @@ class SMTP
'Amazon_SES' => '/[\d]{3} Ok (.*)/', 'Amazon_SES' => '/[\d]{3} Ok (.*)/',
'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', 'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
'Mailjet' => '/[\d]{3} OK queued as (.*)/',
]; ];
/** /**
@ -311,17 +314,11 @@ class SMTP
*/ */
public function connect($host, $port = null, $timeout = 30, $options = []) public function connect($host, $port = null, $timeout = 30, $options = [])
{ {
static $streamok; //Clear errors to avoid confusion
//This is enabled by default since 5.0.0 but some providers disable it
//Check this once and cache the result
if (null === $streamok) {
$streamok = function_exists('stream_socket_client');
}
// Clear errors to avoid confusion
$this->setError(''); $this->setError('');
// Make sure we are __not__ connected //Make sure we are __not__ connected
if ($this->connected()) { if ($this->connected()) {
// Already connected, generate error //Already connected, generate error
$this->setError('Already connected to a server'); $this->setError('Already connected to a server');
return false; return false;
@ -329,18 +326,66 @@ class SMTP
if (empty($port)) { if (empty($port)) {
$port = self::DEFAULT_PORT; $port = self::DEFAULT_PORT;
} }
// Connect to the SMTP server //Connect to the SMTP server
$this->edebug( $this->edebug(
"Connection: opening to $host:$port, timeout=$timeout, options=" . "Connection: opening to $host:$port, timeout=$timeout, options=" .
(count($options) > 0 ? var_export($options, true) : 'array()'), (count($options) > 0 ? var_export($options, true) : 'array()'),
self::DEBUG_CONNECTION self::DEBUG_CONNECTION
); );
$this->smtp_conn = $this->getSMTPConnection($host, $port, $timeout, $options);
if ($this->smtp_conn === false) {
//Error info already set inside `getSMTPConnection()`
return false;
}
$this->edebug('Connection: opened', self::DEBUG_CONNECTION);
//Get any announcement
$this->last_reply = $this->get_lines();
$this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
$responseCode = (int)substr($this->last_reply, 0, 3);
if ($responseCode === 220) {
return true;
}
//Anything other than a 220 response means something went wrong
//RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
//https://tools.ietf.org/html/rfc5321#section-3.1
if ($responseCode === 554) {
$this->quit();
}
//This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down)
$this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION);
$this->close();
return false;
}
/**
* Create connection to the SMTP server.
*
* @param string $host SMTP server IP or host name
* @param int $port The port number to connect to
* @param int $timeout How long to wait for the connection to open
* @param array $options An array of options for stream_context_create()
*
* @return false|resource
*/
protected function getSMTPConnection($host, $port = null, $timeout = 30, $options = [])
{
static $streamok;
//This is enabled by default since 5.0.0 but some providers disable it
//Check this once and cache the result
if (null === $streamok) {
$streamok = function_exists('stream_socket_client');
}
$errno = 0; $errno = 0;
$errstr = ''; $errstr = '';
if ($streamok) { if ($streamok) {
$socket_context = stream_context_create($options); $socket_context = stream_context_create($options);
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
$this->smtp_conn = stream_socket_client( $connection = stream_socket_client(
$host . ':' . $port, $host . ':' . $port,
$errno, $errno,
$errstr, $errstr,
@ -348,7 +393,6 @@ class SMTP
STREAM_CLIENT_CONNECT, STREAM_CLIENT_CONNECT,
$socket_context $socket_context
); );
restore_error_handler();
} else { } else {
//Fall back to fsockopen which should work in more places, but is missing some features //Fall back to fsockopen which should work in more places, but is missing some features
$this->edebug( $this->edebug(
@ -356,17 +400,18 @@ class SMTP
self::DEBUG_CONNECTION self::DEBUG_CONNECTION
); );
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
$this->smtp_conn = fsockopen( $connection = fsockopen(
$host, $host,
$port, $port,
$errno, $errno,
$errstr, $errstr,
$timeout $timeout
); );
restore_error_handler();
} }
// Verify we connected properly restore_error_handler();
if (!is_resource($this->smtp_conn)) {
//Verify we connected properly
if (!is_resource($connection)) {
$this->setError( $this->setError(
'Failed to connect to server', 'Failed to connect to server',
'', '',
@ -381,22 +426,19 @@ class SMTP
return false; return false;
} }
$this->edebug('Connection: opened', self::DEBUG_CONNECTION);
// SMTP server can take longer to respond, give longer timeout for first read //SMTP server can take longer to respond, give longer timeout for first read
// Windows does not have support for this timeout function //Windows does not have support for this timeout function
if (strpos(PHP_OS, 'WIN') !== 0) { if (strpos(PHP_OS, 'WIN') !== 0) {
$max = (int) ini_get('max_execution_time'); $max = (int)ini_get('max_execution_time');
// Don't bother if unlimited //Don't bother if unlimited, or if set_time_limit is disabled
if (0 !== $max && $timeout > $max) { if (0 !== $max && $timeout > $max && strpos(ini_get('disable_functions'), 'set_time_limit') === false) {
@set_time_limit($timeout); @set_time_limit($timeout);
} }
stream_set_timeout($this->smtp_conn, $timeout, 0); stream_set_timeout($connection, $timeout, 0);
} }
// Get any announcement
$announce = $this->get_lines();
$this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
return true; return $connection;
} }
/** /**
@ -420,7 +462,7 @@ class SMTP
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
} }
// Begin encrypted connection //Begin encrypted connection
set_error_handler([$this, 'errorHandler']); set_error_handler([$this, 'errorHandler']);
$crypto_ok = stream_socket_enable_crypto( $crypto_ok = stream_socket_enable_crypto(
$this->smtp_conn, $this->smtp_conn,
@ -441,7 +483,7 @@ class SMTP
* @param string $username The user name * @param string $username The user name
* @param string $password The password * @param string $password The password
* @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2) * @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2)
* @param OAuth $OAuth An optional OAuth instance for XOAUTH2 authentication * @param OAuthTokenProvider $OAuth An optional OAuthTokenProvider instance for XOAUTH2 authentication
* *
* @return bool True if successfully authenticated * @return bool True if successfully authenticated
*/ */
@ -458,11 +500,11 @@ class SMTP
} }
if (array_key_exists('EHLO', $this->server_caps)) { if (array_key_exists('EHLO', $this->server_caps)) {
// SMTP extensions are available; try to find a proper authentication method //SMTP extensions are available; try to find a proper authentication method
if (!array_key_exists('AUTH', $this->server_caps)) { if (!array_key_exists('AUTH', $this->server_caps)) {
$this->setError('Authentication is not allowed at this stage'); $this->setError('Authentication is not allowed at this stage');
// 'at this stage' means that auth may be allowed after the stage changes //'at this stage' means that auth may be allowed after the stage changes
// e.g. after STARTTLS //e.g. after STARTTLS
return false; return false;
} }
@ -506,22 +548,25 @@ class SMTP
} }
switch ($authtype) { switch ($authtype) {
case 'PLAIN': case 'PLAIN':
// Start authentication //Start authentication
if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
return false; return false;
} }
// Send encoded username and password //Send encoded username and password
if (!$this->sendCommand( if (
'User & Password', //Format from https://tools.ietf.org/html/rfc4616#section-2
base64_encode("\0" . $username . "\0" . $password), //We skip the first field (it's forgery), so the string starts with a null byte
235 !$this->sendCommand(
) 'User & Password',
base64_encode("\0" . $username . "\0" . $password),
235
)
) { ) {
return false; return false;
} }
break; break;
case 'LOGIN': case 'LOGIN':
// Start authentication //Start authentication
if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
return false; return false;
} }
@ -533,17 +578,17 @@ class SMTP
} }
break; break;
case 'CRAM-MD5': case 'CRAM-MD5':
// Start authentication //Start authentication
if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
return false; return false;
} }
// Get the challenge //Get the challenge
$challenge = base64_decode(substr($this->last_reply, 4)); $challenge = base64_decode(substr($this->last_reply, 4));
// Build the response //Build the response
$response = $username . ' ' . $this->hmac($challenge, $password); $response = $username . ' ' . $this->hmac($challenge, $password);
// send encoded credentials //send encoded credentials
return $this->sendCommand('Username', base64_encode($response), 235); return $this->sendCommand('Username', base64_encode($response), 235);
case 'XOAUTH2': case 'XOAUTH2':
//The OAuth instance must be set up prior to requesting auth. //The OAuth instance must be set up prior to requesting auth.
@ -552,7 +597,7 @@ class SMTP
} }
$oauth = $OAuth->getOauth64(); $oauth = $OAuth->getOauth64();
// Start authentication //Start authentication
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
return false; return false;
} }
@ -582,15 +627,15 @@ class SMTP
return hash_hmac('md5', $data, $key); return hash_hmac('md5', $data, $key);
} }
// The following borrowed from //The following borrowed from
// http://php.net/manual/en/function.mhash.php#27225 //http://php.net/manual/en/function.mhash.php#27225
// RFC 2104 HMAC implementation for php. //RFC 2104 HMAC implementation for php.
// Creates an md5 HMAC. //Creates an md5 HMAC.
// Eliminates the need to install mhash to compute a HMAC //Eliminates the need to install mhash to compute a HMAC
// by Lance Rushing //by Lance Rushing
$bytelen = 64; // byte length for md5 $bytelen = 64; //byte length for md5
if (strlen($key) > $bytelen) { if (strlen($key) > $bytelen) {
$key = pack('H*', md5($key)); $key = pack('H*', md5($key));
} }
@ -613,7 +658,7 @@ class SMTP
if (is_resource($this->smtp_conn)) { if (is_resource($this->smtp_conn)) {
$sock_status = stream_get_meta_data($this->smtp_conn); $sock_status = stream_get_meta_data($this->smtp_conn);
if ($sock_status['eof']) { if ($sock_status['eof']) {
// The socket is valid but we are not connected //The socket is valid but we are not connected
$this->edebug( $this->edebug(
'SMTP NOTICE: EOF caught while checking if connected', 'SMTP NOTICE: EOF caught while checking if connected',
self::DEBUG_CLIENT self::DEBUG_CLIENT
@ -623,7 +668,7 @@ class SMTP
return false; return false;
} }
return true; // everything looks good return true; //everything looks good
} }
return false; return false;
@ -641,7 +686,7 @@ class SMTP
$this->server_caps = null; $this->server_caps = null;
$this->helo_rply = null; $this->helo_rply = null;
if (is_resource($this->smtp_conn)) { if (is_resource($this->smtp_conn)) {
// close the connection and cleanup //Close the connection and cleanup
fclose($this->smtp_conn); fclose($this->smtp_conn);
$this->smtp_conn = null; //Makes for cleaner serialization $this->smtp_conn = null; //Makes for cleaner serialization
$this->edebug('Connection: closed', self::DEBUG_CONNECTION); $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
@ -651,7 +696,7 @@ class SMTP
/** /**
* Send an SMTP DATA command. * Send an SMTP DATA command.
* Issues a data command and sends the msg_data to the server, * Issues a data command and sends the msg_data to the server,
* finializing the mail transaction. $msg_data is the message * finalizing the mail transaction. $msg_data is the message
* that is to be send with the headers. Each header needs to be * that is to be send with the headers. Each header needs to be
* on a single line followed by a <CRLF> with the message headers * on a single line followed by a <CRLF> with the message headers
* and the message body being separated by an additional <CRLF>. * and the message body being separated by an additional <CRLF>.
@ -676,7 +721,7 @@ class SMTP
* NOTE: this does not count towards line-length limit. * NOTE: this does not count towards line-length limit.
*/ */
// Normalize line breaks before exploding //Normalize line breaks before exploding
$lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data));
/* To distinguish between a complete RFC822 message and a plain message body, we check if the first field /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
@ -722,7 +767,8 @@ class SMTP
//Send the lines to the server //Send the lines to the server
foreach ($lines_out as $line_out) { foreach ($lines_out as $line_out) {
//RFC2821 section 4.5.2 //Dot-stuffing as per RFC5321 section 4.5.2
//https://tools.ietf.org/html/rfc5321#section-4.5.2
if (!empty($line_out) && $line_out[0] === '.') { if (!empty($line_out) && $line_out[0] === '.') {
$line_out = '.' . $line_out; $line_out = '.' . $line_out;
} }
@ -756,7 +802,16 @@ class SMTP
public function hello($host = '') public function hello($host = '')
{ {
//Try extended hello first (RFC 2821) //Try extended hello first (RFC 2821)
return $this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host); if ($this->sendHello('EHLO', $host)) {
return true;
}
//Some servers shut down the SMTP service here (RFC 5321)
if (substr($this->helo_rply, 0, 3) == '421') {
return false;
}
return $this->sendHello('HELO', $host);
} }
/** /**
@ -946,12 +1001,12 @@ class SMTP
$this->client_send($commandstring . static::LE, $command); $this->client_send($commandstring . static::LE, $command);
$this->last_reply = $this->get_lines(); $this->last_reply = $this->get_lines();
// Fetch SMTP code and possible error code explanation //Fetch SMTP code and possible error code explanation
$matches = []; $matches = [];
if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) { if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) {
$code = (int) $matches[1]; $code = (int) $matches[1];
$code_ex = (count($matches) > 2 ? $matches[2] : null); $code_ex = (count($matches) > 2 ? $matches[2] : null);
// Cut off error code from each response line //Cut off error code from each response line
$detail = preg_replace( $detail = preg_replace(
"/{$code}[ -]" . "/{$code}[ -]" .
($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m', ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m',
@ -959,7 +1014,7 @@ class SMTP
$this->last_reply $this->last_reply
); );
} else { } else {
// Fall back to simple parsing if regex fails //Fall back to simple parsing if regex fails
$code = (int) substr($this->last_reply, 0, 3); $code = (int) substr($this->last_reply, 0, 3);
$code_ex = null; $code_ex = null;
$detail = substr($this->last_reply, 4); $detail = substr($this->last_reply, 4);
@ -1058,8 +1113,10 @@ class SMTP
{ {
//If SMTP transcripts are left enabled, or debug output is posted online //If SMTP transcripts are left enabled, or debug output is posted online
//it can leak credentials, so hide credentials in all but lowest level //it can leak credentials, so hide credentials in all but lowest level
if (self::DEBUG_LOWLEVEL > $this->do_debug && if (
in_array($command, ['User & Password', 'Username', 'Password'], true)) { self::DEBUG_LOWLEVEL > $this->do_debug &&
in_array($command, ['User & Password', 'Username', 'Password'], true)
) {
$this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT); $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT);
} else { } else {
$this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT); $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
@ -1113,7 +1170,7 @@ class SMTP
if (!$this->server_caps) { if (!$this->server_caps) {
$this->setError('No HELO/EHLO was sent'); $this->setError('No HELO/EHLO was sent');
return; return null;
} }
if (!array_key_exists($name, $this->server_caps)) { if (!array_key_exists($name, $this->server_caps)) {
@ -1125,7 +1182,7 @@ class SMTP
} }
$this->setError('HELO handshake was used; No information about server extensions available'); $this->setError('HELO handshake was used; No information about server extensions available');
return; return null;
} }
return $this->server_caps[$name]; return $this->server_caps[$name];
@ -1152,7 +1209,7 @@ class SMTP
*/ */
protected function get_lines() protected function get_lines()
{ {
// If the connection is bad, give up straight away //If the connection is bad, give up straight away
if (!is_resource($this->smtp_conn)) { if (!is_resource($this->smtp_conn)) {
return ''; return '';
} }
@ -1166,24 +1223,52 @@ class SMTP
$selW = null; $selW = null;
while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
//Must pass vars in here as params are by reference //Must pass vars in here as params are by reference
if (!stream_select($selR, $selW, $selW, $this->Timelimit)) { //solution for signals inspired by https://github.com/symfony/symfony/pull/6540
set_error_handler([$this, 'errorHandler']);
$n = stream_select($selR, $selW, $selW, $this->Timelimit);
restore_error_handler();
if ($n === false) {
$message = $this->getError()['detail'];
$this->edebug(
'SMTP -> get_lines(): select failed (' . $message . ')',
self::DEBUG_LOWLEVEL
);
//stream_select returns false when the `select` system call is interrupted
//by an incoming signal, try the select again
if (stripos($message, 'interrupted system call') !== false) {
$this->edebug(
'SMTP -> get_lines(): retrying stream_select',
self::DEBUG_LOWLEVEL
);
$this->setError('');
continue;
}
break;
}
if (!$n) {
$this->edebug( $this->edebug(
'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)', 'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)',
self::DEBUG_LOWLEVEL self::DEBUG_LOWLEVEL
); );
break; break;
} }
//Deliberate noise suppression - errors are handled afterwards //Deliberate noise suppression - errors are handled afterwards
$str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH); $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH);
$this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL);
$data .= $str; $data .= $str;
// If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled), //If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
// or 4th character is a space or a line break char, we are done reading, break the loop. //or 4th character is a space or a line break char, we are done reading, break the loop.
// String array access is a significant micro-optimisation over strlen //String array access is a significant micro-optimisation over strlen
if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") { if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") {
break; break;
} }
// Timed-out? Log and break //Timed-out? Log and break
$info = stream_get_meta_data($this->smtp_conn); $info = stream_get_meta_data($this->smtp_conn);
if ($info['timed_out']) { if ($info['timed_out']) {
$this->edebug( $this->edebug(
@ -1192,7 +1277,7 @@ class SMTP
); );
break; break;
} }
// Now check if reads took too long //Now check if reads took too long
if ($endtime && time() > $endtime) { if ($endtime && time() > $endtime) {
$this->edebug( $this->edebug(
'SMTP -> get_lines(): timelimit reached (' . 'SMTP -> get_lines(): timelimit reached (' .

View File

@ -0,0 +1,38 @@
<?php
/**
* French PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* Some French punctuation requires a thin non-breaking space (U+202F) character before it,
* for example before a colon or exclamation mark.
* There is one of these characters between these quotes: ""
* @see http://unicode.org/udhr/n/notes_fra.html
*/
$PHPMAILER_LANG['authenticate'] = 'Erreur SMTP: échec de lauthentification.';
$PHPMAILER_LANG['buggy_php'] = 'Votre version de PHP est affectée par un bug qui peut entraîner des messages corrompus. Pour résoudre ce problème, passez à lenvoi par SMTP, désactivez loption mail.add_x_header dans le fichier php.ini, passez à MacOS ou Linux, ou passez PHP à la version 7.0.17+ ou 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Erreur SMTP: impossible de se connecter au serveur SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erreur SMTP: données incorrectes.';
$PHPMAILER_LANG['empty_message'] = 'Corps du message vide.';
$PHPMAILER_LANG['encoding'] = 'Encodage inconnu: ';
$PHPMAILER_LANG['execute'] = 'Impossible de lancer lexécution: ';
$PHPMAILER_LANG['extension_missing'] = 'Extension manquante: ';
$PHPMAILER_LANG['file_access'] = 'Impossible daccéder au fichier: ';
$PHPMAILER_LANG['file_open'] = 'Ouverture du fichier impossible: ';
$PHPMAILER_LANG['from_failed'] = 'Ladresse dexpéditeur suivante a échoué: ';
$PHPMAILER_LANG['instantiate'] = 'Impossible dinstancier la fonction mail.';
$PHPMAILER_LANG['invalid_address'] = 'Adresse courriel non valide: ';
$PHPMAILER_LANG['invalid_header'] = 'Nom ou valeur de len-tête non valide';
$PHPMAILER_LANG['invalid_hostentry'] = 'Entrée dhôte non valide: ';
$PHPMAILER_LANG['invalid_host'] = 'Hôte non valide: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supporté.';
$PHPMAILER_LANG['provide_address'] = 'Vous devez fournir au moins une adresse de destinataire.';
$PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP:les destinataires suivants ont échoué: ';
$PHPMAILER_LANG['signing'] = 'Erreur de signature: ';
$PHPMAILER_LANG['smtp_code'] = 'Code SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Informations supplémentaires SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La fonction SMTP connect() a échouée.';
$PHPMAILER_LANG['smtp_detail'] = 'Détails: ';
$PHPMAILER_LANG['smtp_error'] = 'Erreur du serveur SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Impossible dinitialiser ou de réinitialiser une variable: ';
$PHPMAILER_LANG['extension_missing'] = 'Extension manquante: ';

View File

@ -1,6 +1,6 @@
<?php <?php
class template { class template {
/** /**
* Crée un bouton * Crée un bouton
@ -118,7 +118,7 @@ class template {
copy ('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$firstNumber] . '.png', 'site/tmp/' . $firstLetter . '.png'); 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'); copy ('core/vendor/zwiico/png/' . $attributes['type'] . '/' . $letters[$secondNumber] . '.png', 'site/tmp/' . $secondLetter . '.png');
// Début du wrapper // Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="captcha inputWrapper ' . $attributes['classWrapper'] . '">'; $html = '<div id="' . $attributes['id'] . 'Wrapper" class="captcha inputWrapper ' . $attributes['classWrapper'] . '">';
// Label // Label
@ -447,7 +447,7 @@ class template {
$lang = 'fr'; $lang = 'fr';
} }
} }
return '<img class="flag" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png" return '<img class="flag" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png"
width="' . $size .'" width="' . $size .'"
height="' . $size .'" height="' . $size .'"
title="' . $lang .'" title="' . $lang .'"
@ -612,19 +612,17 @@ class template {
'label' => '', 'label' => '',
'name' => $nameId, 'name' => $nameId,
'selected' => '', 'selected' => '',
'fonts' => false 'fonts' => []
], $attributes); ], $attributes);
// Stocker les fontes et remettre à zéro le tableau des fontes transmis pour éviter une erreur de sprintAttributes
if (empty($attributes['fonts']) === false) {
$fonts = $attributes['fonts'];
$attributes['fonts'] = [];
}
// Sauvegarde des données en cas d'erreur // Sauvegarde des données en cas d'erreur
if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) { if($attributes['before'] AND array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['selected'] = common::$inputBefore[$attributes['id']]; $attributes['selected'] = common::$inputBefore[$attributes['id']];
} }
// Liste des polices à intégrer
//var_dump(core::$fonts);
if ($attributes['fonts'] === true) {
foreach (core::$fonts as $fontId => $font) {
echo "<link href='https://fonts.cdnfonts.com/css/" . $fontId . "' rel='stylesheet' type='text/css'>\n";
}
}
// Début du wrapper // Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">'; $html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label // Label
@ -633,7 +631,7 @@ class template {
'help' => $attributes['help'] 'help' => $attributes['help']
]); ]);
} }
// Notice // Notice
$notice = ''; $notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) { if(array_key_exists($attributes['id'], common::$inputNotices)) {
$notice = common::$inputNotices[$attributes['id']]; $notice = common::$inputNotices[$attributes['id']];
@ -645,12 +643,14 @@ class template {
helper::sprintAttributes($attributes) helper::sprintAttributes($attributes)
); );
foreach($options as $value => $text) { foreach($options as $value => $text) {
$html .= $attributes['fonts'] === true ? sprintf( // Select des liste de fontes
$html .= isset($fonts) ? sprintf(
'<option value="%s"%s style="font-family: %s;">%s</option>', '<option value="%s"%s style="font-family: %s;">%s</option>',
$value, $value,
$attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string $attributes['selected'] == $value ? ' selected' : '', // Double == pour ignorer le type de variable car $_POST change les types en string
core::$fonts[$value], $fonts[$value],
$text $text
// Select standard
) : sprintf( ) : sprintf(
'<option value="%s"%s>%s</option>', '<option value="%s"%s>%s</option>',
$value, $value,

View File

@ -215,8 +215,7 @@ core.start = function() {
// Variables des cookies // Variables des cookies
var getUrl = window.location; var getUrl = window.location;
var domain = "domain=" + getUrl.host + ";"; var domain = "domain=" + getUrl.host + ";";
var path = "path=" + getUrl.pathname.split('/')[1] + ";"; //var path = "path=" + getUrl.pathname.split('/')[1] + ";";
var e = new Date(); var e = new Date();
e.setFullYear(e.getFullYear() + 1); e.setFullYear(e.getFullYear() + 1);
var expires = "expires=" + e.toUTCString(); var expires = "expires=" + e.toUTCString();
@ -225,18 +224,18 @@ core.start = function() {
var analytics = "<?php echo $this->getData(['config', 'seo', 'analyticsId']);?>"; var analytics = "<?php echo $this->getData(['config', 'seo', 'analyticsId']);?>";
// l'Id GA est défini dans la configuration, afficher la checkbox d'acceptation // l'Id GA est défini dans la configuration, afficher la checkbox d'acceptation
if( analytics.length > 0){ if( analytics.length > 0){
// Traitement du retour de la checkbox // Traitement du retour de la checkbox
if ($("#googleAnalytics").is(":checked")) { if ($("#googleAnalytics").is(":checked")) {
// L'URL du serveur faut TRUE // L'URL du serveur faut TRUE
document.cookie = "ZWII_COOKIE_GA_CONSENT=true;samesite=strict;" + domain + path + expires; document.cookie = "ZWII_COOKIE_GA_CONSENT=true;samesite=strict;" + domain + expires;
} else { } else {
document.cookie = "ZWII_COOKIE_GA_CONSENT=false;samesite=strict;" + domain + path + expires; document.cookie = "ZWII_COOKIE_GA_CONSENT=false;samesite=strict;" + domain + expires;
} }
} }
// Stocke le cookie d'acceptation // Stocke le cookie d'acceptation
document.cookie = "ZWII_COOKIE_CONSENT=true;samesite=strict;" + domain + path + expires; document.cookie = "ZWII_COOKIE_CONSENT=true;samesite=strict;" + domain + expires;
}); });

View File

@ -45,7 +45,7 @@ class common {
// Numéro de version // Numéro de version
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/update/raw/branch/master/'; const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/update/raw/branch/master/';
const ZWII_VERSION = '11.3.07'; const ZWII_VERSION = '11.4.00';
const ZWII_UPDATE_CHANNEL = "v11"; const ZWII_UPDATE_CHANNEL = "v11";
public static $actions = []; public static $actions = [];
@ -65,8 +65,8 @@ class common {
'theme', 'theme',
'config', 'config',
'edit', 'edit',
'config', 'translate',
'translate' 'addon'
]; ];
public static $accessExclude = [ public static $accessExclude = [
'login', 'login',
@ -183,39 +183,80 @@ class common {
]; ];
// Fontes public static $fontsWebSafe = [
public static $fonts = [ 'arial' => [
'abril-fatface' => 'Abril Fatface', 'name' => 'Arial',
'arimo' => 'Arimo', 'font-family' => 'Arial, Helvetica, sans-serif',
'arvo' => 'Arvo', 'resource' => 'websafe'
'berkshire-swash' => 'Berkshire Swash', ],
'dancing-script' => 'Dancing Script', 'arvo'=> [
'droid-sans-2' => 'Droid Sans', 'name' => 'Arvo',
'droid-serif-2' => 'Droid Serif', 'font-family' => 'Arvo, sans-serif',
'fira-sans' => 'Fira Sans', 'resource' => 'websafe'
'genera' => 'Genera', ],
'inconsolata-2' => 'Inconsolata', 'courrier-new' => [
'indie-flower' => 'Indie Flower', 'name' => 'Courier New',
'josefin-sans-std' => 'Josefin Sans', 'font-family' => '\'Courier New\', Courier, monospace',
'liberation-sans' => 'Liberation Sans', 'resource' => 'websafe'
'liberation-serif' => 'Liberation Serif', ],
'lobster-2' => 'Lobster', 'garamond' => [
'lora' => 'Lora', 'name' => 'Garamond',
'lato' => 'Lato', 'font-family' => 'Garamond, serif',
'montserrat-ace' => 'Montserrat Ace', 'resource' => 'websafe'
'old-standard-tt-3' => 'Old Standard TT', ],
'open-sans' => 'Open Sans', 'georgia' => [
'oswald-4' => 'Oswald', 'name' => 'Geogia',
'pt-mono' => 'PT Mono', 'font-family' => 'Georgia, serif',
'pt-serif' => 'PT Serif', 'resource' => 'websafe'
'raleway-5' => 'Raleway', ],
'rancho' => 'Rancho', 'impact' => [
'roboto' => 'Roboto', 'name' => 'Impact',
'signika' => 'Signika', 'font-family' => 'Impact, Charcoal, sans-serif',
'ubuntu' => 'Ubuntu', 'resource' => 'websafe'
'vollkorn' => 'Vollkorn' ],
'lora'=> [
'name' => 'Lora',
'font-family' => 'Lora, serif',
'resource' => 'websafe'
],
'lucida' => [
'name' => 'Lucida',
'font-family' => '\'Lucida Sans Unicode\', \'Lucida Grande\', sans-serif',
'resource' => 'websafe'
],
'roboto'=> [
'name' => 'Roboto',
'font-family' => 'Roboto, sans-serif',
'resource' => 'websafe'
],
'tahoma' => [
'name' => 'Tahoma',
'font-family' => 'Tahoma, Geneva, sans-serif',
'resource' => 'websafe'
],
'times-new-roman' => [
'name' => 'Times New Roman',
'font-family' => '\'Times New Roman\', \'Liberation Serif\', serif',
'resource' => 'websafe'
],
'trebuchet' => [
'name' => 'Trebuchet',
'font-family' => '\'Trebuchet MS\', Arial, Helvetica, sans-serif',
'resource' => 'websafe'
],
'tahoma' => [
'name' => 'Tahoma',
'font-family' => 'Tahoma, Geneva, sans-serif',
'resource' => 'websafe'
],
'verdana' => [
'name' => 'Verdana',
'font-family' => 'Verdana, Geneva, sans-serif;',
'resource' => 'websafe'
]
]; ];
/** /**
* Constructeur commun * Constructeur commun
*/ */
@ -250,7 +291,6 @@ class common {
]);; ]);;
} }
// Import version 9 // Import version 9
if (file_exists(self::DATA_DIR . 'core.json') === true && if (file_exists(self::DATA_DIR . 'core.json') === true &&
$this->getData(['core','dataVersion']) < 10000) { $this->getData(['core','dataVersion']) < 10000) {
@ -267,7 +307,9 @@ class common {
// La langue d'installation par défaut est fr // La langue d'installation par défaut est fr
foreach ($this->dataFiles as $stageId => $item) { foreach ($this->dataFiles as $stageId => $item) {
$folder = $this->dataPath ($stageId, self::$i18n); $folder = $this->dataPath ($stageId, self::$i18n);
if (file_exists($folder . $stageId .'.json') === false) { if ( file_exists($folder . $stageId .'.json') === false ||
$this->getData([$stageId]) === NULL
) {
$this->initData($stageId, self::$i18n); $this->initData($stageId, self::$i18n);
common::$coreNotices [] = $stageId ; common::$coreNotices [] = $stageId ;
} }
@ -517,7 +559,6 @@ class common {
if ( if (
$this->getData(['page', $page, 'content']) !== '' $this->getData(['page', $page, 'content']) !== ''
&& file_exists(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content'])) && file_exists(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content']))
&& is_file(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content']))
) { ) {
return file_get_contents(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content'])); return file_get_contents(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content']));
} else { } else {
@ -825,10 +866,9 @@ class common {
/** /**
* Génère un fichier json avec la liste des pages * Génère la liste des pages pour le plugin Link de TinyMCE
*
*/ */
public function pages2Json() { public function listPages() {
// Sauve la liste des pages pour TinyMCE // Sauve la liste des pages pour TinyMCE
$parents = []; $parents = [];
$rewrite = (helper::checkRewrite()) ? '' : '?'; $rewrite = (helper::checkRewrite()) ? '' : '?';
@ -914,8 +954,6 @@ class common {
public function createSitemap($command = "all") { public function createSitemap($command = "all") {
//require_once "core/vendor/sitemap/SitemapGenerator.php";
$timezone = $this->getData(['config','timezone']); $timezone = $this->getData(['config','timezone']);
$outputDir = getcwd(); $outputDir = getcwd();
$sitemap = new \Icamys\SitemapGenerator\SitemapGenerator(helper::baseurl(false),$outputDir); $sitemap = new \Icamys\SitemapGenerator\SitemapGenerator(helper::baseurl(false),$outputDir);
@ -1080,6 +1118,7 @@ class common {
$layout = ob_get_clean(); $layout = ob_get_clean();
$mail = new PHPMailer\PHPMailer\PHPMailer; $mail = new PHPMailer\PHPMailer\PHPMailer;
$mail->CharSet = 'UTF-8'; $mail->CharSet = 'UTF-8';
$mail->setLanguage('fr', 'core/class/phpmailer/phpmailer.lang-fr.php');
// Mail // Mail
try{ try{
// Paramètres SMTP // Paramètres SMTP
@ -1129,10 +1168,10 @@ class common {
else { else {
return $mail->ErrorInfo; return $mail->ErrorInfo;
} }
} catch (phpmailerException $e) {
return $e->errorMessage();
} catch (Exception $e) { } catch (Exception $e) {
return $e->getMessage(); echo $e->errorMessage();
} catch (\Exception $e) {
echo $e->getMessage();
} }
} }
@ -1254,7 +1293,7 @@ class common {
$item .= '<h3>'. $this->getData(['locale', 'cookies', 'titleLabel']) . '</h3>'; $item .= '<h3>'. $this->getData(['locale', 'cookies', 'titleLabel']) . '</h3>';
$item .= '<p>' . $this->getData(['locale', 'cookies', 'mainLabel']) . '</p>'; $item .= '<p>' . $this->getData(['locale', 'cookies', 'mainLabel']) . '</p>';
// Formulaire de réponse // Formulaire de réponse
$item .= '<form method="POST" action="" id="cookieForm">'; $item .= '<form method="POST" action="' . helper::baseUrl(false, true) . '" id="cookieForm">';
$analytics = $this->getData(['config', 'seo', 'analyticsId']); $analytics = $this->getData(['config', 'seo', 'analyticsId']);
$stateCookieGA = $this->getInput('ZWII_COOKIE_GA_CONSENT') === 'true' ? 'checked="checked"' : ''; $stateCookieGA = $this->getInput('ZWII_COOKIE_GA_CONSENT') === 'true' ? 'checked="checked"' : '';
if( $analytics !== null AND $analytics !== '' ) { if( $analytics !== null AND $analytics !== '' ) {
@ -1342,9 +1381,6 @@ class common {
*/ */
echo '<div class="'. $content . '" id="contentSite">'; echo '<div class="'. $content . '" id="contentSite">';
$this->showContent(); $this->showContent();
if (file_exists(self::DATA_DIR . 'body.inc.html')) {
include(self::DATA_DIR . 'body.inc.html');
}
echo '</div>'; echo '</div>';
/** /**
* Barre droite * Barre droite
@ -1646,7 +1682,7 @@ class common {
) { ) {
echo '<link rel="shortcut icon" media="(prefers-color-scheme:dark)" href="' . helper::baseUrl(false) . self::FILE_DIR.'source/' . $faviconDark . '">'; echo '<link rel="shortcut icon" media="(prefers-color-scheme:dark)" href="' . helper::baseUrl(false) . self::FILE_DIR.'source/' . $faviconDark . '">';
//echo '<script src="https://unpkg.com/favicon-switcher@1.2.2/dist/index.js" crossorigin="anonymous" type="application/javascript"></script>'; //echo '<script src="https://unpkg.com/favicon-switcher@1.2.2/dist/index.js" crossorigin="anonymous" type="application/javascript"></script>';
echo '<script src="' . helper::baseUrl(false) . 'core/vendor/favicon-switcher/favicon-switcher.js" crossorigin="anonymous" type="application/javascript"></script>'; echo '<script src="' . helper::baseUrl(false) . 'core/vendor/favicon-switcher/favicon-switcher.js" crossorigin="anonymous"></script>';
} }
} }
@ -2121,14 +2157,18 @@ class common {
// Import des styles liés à la page // Import des styles liés à la page
if($this->output['style']) { if($this->output['style']) {
echo '<base href="' . helper::baseUrl(true) .'">'; echo '<base href="' . helper::baseUrl(true) .'">';
// Import de la feuille de style des pages admin
if (strpos($this->output['style'], 'admin.css') >= 1 ) { if (strpos($this->output['style'], 'admin.css') >= 1 ) {
echo '<link rel="stylesheet" href="' . self::DATA_DIR . 'admin.css?' . md5_file(self::DATA_DIR .'admin.css') . '">'; echo '<link rel="stylesheet" href="' . self::DATA_DIR . 'admin.css?' . md5_file(self::DATA_DIR .'admin.css') . '">';
} }
echo '<style type="text/css">' . helper::minifyCss($this->output['style']) . '</style>'; echo '<style type="text/css">' . helper::minifyCss($this->output['style']) . '</style>';
} }
// Import des fontes liées au thème // Import des fontes
if (file_exists(self::DATA_DIR.'fonts/fonts.html')) { if ( file_exists(self::DATA_DIR . 'fonts/fonts.html') ){
include_once(self::DATA_DIR.'fonts/fonts.html'); include_once(self::DATA_DIR . 'fonts/fonts.html');
}
if ( file_exists(self::DATA_DIR . 'fonts/fonts.css') ){
echo '<link rel="stylesheet" href="' . helper::baseUrl(false) . self::DATA_DIR . 'fonts/fonts.css?' . md5_file(self::DATA_DIR .'fonts/fonts.css') . '">';
} }
} }
@ -2214,7 +2254,7 @@ class common {
} }
echo '<li>'; echo '<li>';
echo '<a href="' . helper::baseUrl() . 'translate/i18n/' . $key . '/' . $this->getData(['config', 'i18n',$key]) . '/' . $this->getUrl(0) . '"><img ' . $select . ' class="flag" alt="' . $value . '" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $key . '.png"/></a>'; echo '<a href="' . helper::baseUrl() . 'translate/i18n/' . $key . '/' . $this->getData(['config', 'i18n',$key]) . '/' . $this->getUrl(0) . '"><img ' . $select . ' alt="' . $value . '" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $key . '.png"/></a>';
echo '</li>'; echo '</li>';
} }
} }
@ -2277,17 +2317,6 @@ class core extends common {
} }
} }
// Importe les polices personnalisées
$fontsImported = $this->getData(['fonts', 'imported']);
if (is_array($fontsImported) &&
!empty ($fontsImported)
) {
// Fusionner les fonts avec les fontes installées
self::$fonts = array_merge(self::$fonts, $fontsImported);
// Tri Alphabétique
asort(self::$fonts);
}
// Crée le fichier de personnalisation avancée // Crée le fichier de personnalisation avancée
if(file_exists(self::DATA_DIR.'custom.css') === false) { if(file_exists(self::DATA_DIR.'custom.css') === false) {
file_put_contents(self::DATA_DIR.'custom.css', file_get_contents('core/module/theme/resource/custom.css')); file_put_contents(self::DATA_DIR.'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
@ -2303,6 +2332,7 @@ class core extends common {
file_put_contents(self::DATA_DIR.'admin.css', ''); file_put_contents(self::DATA_DIR.'admin.css', '');
chmod(self::DATA_DIR.'admin.css', 0755); chmod(self::DATA_DIR.'admin.css', 0755);
} }
// Check la version rafraichissement du theme // Check la version rafraichissement du theme
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR.'theme.css')); $cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR.'theme.css'));
if(empty($cssVersion[1]) OR $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) { if(empty($cssVersion[1]) OR $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) {
@ -2311,55 +2341,24 @@ class core extends common {
/** /**
* Import des polices de caractères * Import des polices de caractères
* A partir du CDN ou dans le dossier site/file/source/fonts
*/ */
$fonts = [ $this->getData(['theme', 'text', 'font']),
$this->getData(['theme', 'title', 'font']),
$this->getData(['theme', 'header', 'font']),
$this->getData(['theme', 'menu', 'font']),
$this->getData(['theme', 'footer', 'font'])
];
// Suppression des polices identiques
$fonts = array_unique($fonts);
// Lire le fichier des fontes locales
$localFonts = $this->getData(['fonts', 'files']);
/** $f ['files'] = $this->getData(['fonts', 'files']);
* Chargement des polices en ligne dans un fichier séparé $f ['imported'] = $this->getData(['fonts', 'imported']);
*/ $f ['websafe'] = self::$fontsWebSafe;
$fontFile = ''; // Construit un tableau avec leur ID et leur famille
foreach ($fonts as $fontId) { foreach(['websafe', 'imported', 'files'] as $type) {
if (!array_key_exists($fontId, $localFonts) ) { if (is_array($f[$type])) {
$fontFile .= '<link href="https://fonts.cdnfonts.com/css/' . $fontId .'" rel="stylesheet">'; foreach ($f[$type] as $fontId => $fontValue ) {
// Supprimer l'élément des fontes chargées en ligne $fonts[$fontId] = $fontValue['font-family'];
unset($fonts[$fontId]);
}
}
/**
* Fontes installées localement
*/
if ( !empty($localFonts)
) {
foreach ($localFonts as $fontId => $fontName) {
// Validité du tableau :
if ( array_key_exists($fontId, self::$fonts) ||
file_exists(self::DATA_DIR . 'fonts/' . $fontName) ) {
// Chargement de la police
$css .= '@font-face {font-family:"' . self::$fonts[$fontId] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'fonts/' . $fontName . '");}';
} else {
// Le fichier de font n'est pas disponible, fonte par défaut
$fonts [$fontId] = 'verdana';
} }
} }
} }
// Fond du body // Fond du body
$colors = helper::colorVariants($this->getData(['theme', 'body', 'backgroundColor'])); $colors = helper::colorVariants($this->getData(['theme', 'body', 'backgroundColor']));
// Body // Body
$css .= 'body{font-family:"' . self::$fonts[$this->getData(['theme', 'text', 'font'])] . '",sans-serif}'; $css .= 'body{font-family:' . $fonts[$this->getData(['theme', 'text', 'font'])] . ';}';
if($themeBodyImage = $this->getData(['theme', 'body', 'image'])) { if($themeBodyImage = $this->getData(['theme', 'body', 'image'])) {
// Image dans html pour éviter les déformations. // Image dans html pour éviter les déformations.
$css .= 'html {background-image:url("../file/source/' . $themeBodyImage . '");background-position:' . $this->getData(['theme', 'body', 'imagePosition']) . ';background-attachment:' . $this->getData(['theme', 'body', 'imageAttachment']) . ';background-size:' . $this->getData(['theme', 'body', 'imageSize']) . ';background-repeat:' . $this->getData(['theme', 'body', 'imageRepeat']) . '}'; $css .= 'html {background-image:url("../file/source/' . $themeBodyImage . '");background-position:' . $this->getData(['theme', 'body', 'imagePosition']) . ';background-attachment:' . $this->getData(['theme', 'body', 'imageAttachment']) . ';background-size:' . $this->getData(['theme', 'body', 'imageSize']) . ';background-repeat:' . $this->getData(['theme', 'body', 'imageRepeat']) . '}';
@ -2377,7 +2376,7 @@ class core extends common {
$colors = helper::colorVariants($this->getData(['theme', 'text', 'linkColor'])); $colors = helper::colorVariants($this->getData(['theme', 'text', 'linkColor']));
$css .= 'a{color:' . $colors['normal'] . '}'; $css .= 'a{color:' . $colors['normal'] . '}';
// Couleurs de site dans TinyMCe // Couleurs de site dans TinyMCe
$css .= 'div.mce-edit-area {font-family:"' . self::$fonts[$this->getData(['theme', 'text', 'font'])] . '",sans-serif}'; $css .= 'div.mce-edit-area {font-family:' . $fonts[$this->getData(['theme', 'text', 'font'])] . ';}';
// Site dans TinyMCE // Site dans TinyMCE
$css .= '.editorWysiwyg {background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}'; $css .= '.editorWysiwyg {background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}';
$css .= 'span.mce-text{background-color: unset !important;}'; $css .= 'span.mce-text{background-color: unset !important;}';
@ -2418,7 +2417,7 @@ class core extends common {
$css .= '.helpButton span:hover{color:' . $colors['darken'] . '}'; $css .= '.helpButton span:hover{color:' . $colors['darken'] . '}';
$css .= '.button:active,button[type=\'submit\']:active,.pagination a:active{background-color:' . $colors['veryDarken'] . '}'; $css .= '.button:active,button[type=\'submit\']:active,.pagination a:active{background-color:' . $colors['veryDarken'] . '}';
$colors = helper::colorVariants($this->getData(['theme', 'title', 'textColor'])); $colors = helper::colorVariants($this->getData(['theme', 'title', 'textColor']));
$css .= 'h1,h2,h3,h4,h5,h6,h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:' . $colors['normal'] . ';font-family:"' . self::$fonts[$this->getData(['theme', 'title', 'font'])] . '",sans-serif;font-weight:' . $this->getData(['theme', 'title', 'fontWeight']) . ';text-transform:' . $this->getData(['theme', 'title', 'textTransform']) . '}'; $css .= 'h1,h2,h3,h4,h5,h6,h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:' . $colors['normal'] . ';font-family:' . $fonts[$this->getData(['theme', 'title', 'font'])] . ';font-weight:' . $this->getData(['theme', 'title', 'fontWeight']) . ';text-transform:' . $this->getData(['theme', 'title', 'textTransform']) . '}';
$css .= 'h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{color:' . $colors['darken'] . '}'; $css .= 'h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{color:' . $colors['darken'] . '}';
// Les blocs // Les blocs
$colors = helper::colorVariants($this->getData(['theme', 'block', 'backgroundColor'])); $colors = helper::colorVariants($this->getData(['theme', 'block', 'backgroundColor']));
@ -2452,7 +2451,7 @@ class core extends common {
$css .= 'header{background-image:url("../file/source/' . $themeHeaderImage . '");background-position:' . $this->getData(['theme', 'header', 'imagePosition']) . ';background-repeat:' . $this->getData(['theme', 'header', 'imageRepeat']) . '}'; $css .= 'header{background-image:url("../file/source/' . $themeHeaderImage . '");background-position:' . $this->getData(['theme', 'header', 'imagePosition']) . ';background-repeat:' . $this->getData(['theme', 'header', 'imageRepeat']) . '}';
} }
$colors = helper::colorVariants($this->getData(['theme', 'header', 'textColor'])); $colors = helper::colorVariants($this->getData(['theme', 'header', 'textColor']));
$css .= 'header span{color:' . $colors['normal'] . ';font-family:"' . self::$fonts[$this->getData(['theme', 'header', 'font'])] . '",sans-serif;font-weight:' . $this->getData(['theme', 'header', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'header', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'header', 'textTransform']) . '}'; $css .= 'header span{color:' . $colors['normal'] . ';font-family:' . $fonts[$this->getData(['theme', 'header', 'font'])] . ';font-weight:' . $this->getData(['theme', 'header', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'header', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'header', 'textTransform']) . '}';
} }
// Bannière au contenu personnalisé // Bannière au contenu personnalisé
@ -2501,7 +2500,7 @@ class core extends common {
$css .= 'nav{padding:0 10px;}'; $css .= 'nav{padding:0 10px;}';
} }
$css .= '#toggle span,#menu a{padding:' . $this->getData(['theme', 'menu', 'height']) .';font-family:"' . self::$fonts[$this->getData(['theme', 'menu', 'font'])] . '",sans-serif;font-weight:' . $this->getData(['theme', 'menu', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'menu', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'menu', 'textTransform']) . '}'; $css .= '#toggle span,#menu a{padding:' . $this->getData(['theme', 'menu', 'height']) .';font-family:' . $fonts[$this->getData(['theme', 'menu', 'font'])] . ';font-weight:' . $this->getData(['theme', 'menu', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'menu', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'menu', 'textTransform']) . '}';
// Pied de page // Pied de page
$colors = helper::colorVariants($this->getData(['theme', 'footer', 'backgroundColor'])); $colors = helper::colorVariants($this->getData(['theme', 'footer', 'backgroundColor']));
@ -2511,7 +2510,7 @@ class core extends common {
$css .= 'footer{padding:0}'; $css .= 'footer{padding:0}';
} }
$css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:"' . self::$fonts[$this->getData(['theme', 'footer', 'font'])] . '",sans-serif;font-weight:' . $this->getData(['theme', 'footer', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'footer', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'footer', 'textTransform']) . '}'; $css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:' . $fonts[$this->getData(['theme', 'footer', 'font'])] . ';font-weight:' . $this->getData(['theme', 'footer', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'footer', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'footer', 'textTransform']) . '}';
$css .= 'footer {background-color:' . $colors['normal'] . ';color:' . $this->getData(['theme', 'footer', 'textColor']) . '}'; $css .= 'footer {background-color:' . $colors['normal'] . ';color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}'; $css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}'; $css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
@ -2522,12 +2521,6 @@ class core extends common {
$css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}'; $css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}';
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}'; $css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
// Enregistre les fontes
if (!is_dir(self::DATA_DIR . 'fonts')) {
mkdir(self::DATA_DIR . 'fonts');
}
file_put_contents(self::DATA_DIR . 'fonts/fonts.html', $fontFile);
// Enregistre la personnalisation // Enregistre la personnalisation
file_put_contents(self::DATA_DIR.'theme.css', $css); file_put_contents(self::DATA_DIR.'theme.css', $css);
@ -2548,52 +2541,25 @@ class core extends common {
/** /**
* Import des polices de caractères * Import des polices de caractères
* A partir du CDN ou dans le dossier site/file/source/fonts
*/ */
$fonts = [ $this->getData(['admin', 'fontText']),
$this->getData(['admin', 'fontTitle']),
];
// Suppression des polices identiques
$fonts = array_unique($fonts);
// Lire le fichier des fontes locales
$localFonts = $this->getData(['fonts', 'files']);
/** $f ['files'] = $this->getData(['fonts', 'files']);
* Chargement des polices en ligne $f ['imported'] = $this->getData(['fonts', 'imported']);
*/ $f ['websafe'] = self::$fontsWebSafe;
foreach ($fonts as $fontId) { // Construit un tableau avec leur ID et leur famille
if (!array_key_exists($fontId, $localFonts) ) { foreach(['websafe', 'imported', 'files'] as $type) {
$css .= '@import url("https://fonts.cdnfonts.com/css/' . $fontId . '");'; if (is_array($f[$type])) {
// Supprimer l'élément des fontes chargées en ligne foreach ($f[$type] as $fontId => $fontValue ) {
unset($fonts[$fontId]); $fonts[$fontId] = $fontValue['font-family'];
}
}
/**
* Fontes installées localement
*/
if ( !empty($localFonts)
) {
foreach ($localFonts as $fontId => $fontName) {
// Validité du tableau :
if ( array_key_exists($fontId, self::$fonts) ||
file_exists(self::DATA_DIR . 'fonts/' . $fontName) ) {
// Chargement de la police
$css .= '@font-face {font-family:"' . self::$fonts[$fontId] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'fonts/' . $fontName . '");}';
} else {
// Le fichier de font n'est pas disponible, fonte par défaut
$fonts [$fontId] = 'verdana';
} }
} }
} }
// Thème Administration // Thème Administration
$colors = helper::colorVariants($this->getData(['admin','backgroundColor'])); $colors = helper::colorVariants($this->getData(['admin','backgroundColor']));
$css .= '#site{background-color:' . $colors['normal']. ';}'; $css .= '#site{background-color:' . $colors['normal']. ';}';
$css .= '.row > div {font:' . $this->getData(['admin','fontSize']) . ' "' . self::$fonts[$this->getData(['admin','fontText'])] . '", sans-serif;}'; $css .= '.row > div {font:' . $fonts[$this->getData(['admin','fontText'])] . ';font-size:' . $this->getData(['admin','fontSize']) .'}';
$css .= 'body h1, h2, h3, h4 a, h5, h6 {font-family:"' . self::$fonts[$this->getData(['admin','fontTitle'])] . '", sans-serif;color:' . $this->getData(['admin','colorTitle' ]) . ';}'; $css .= 'body h1, h2, h3, h4 a, h5, h6 {font-family:' . $fonts[$this->getData(['admin','fontTitle'])] . ';color:' . $this->getData(['admin','colorTitle' ]) . ';}';
// TinyMCE // TinyMCE
$css .= 'body:not(.editorWysiwyg),span .zwiico-help {color:' . $this->getData(['admin','colorText']) . ';}'; $css .= 'body:not(.editorWysiwyg),span .zwiico-help {color:' . $this->getData(['admin','colorText']) . ';}';
@ -2921,9 +2887,9 @@ class core extends common {
]); ]);
} }
if ($output['style']) { if ($output['style']) {
$this->addOutput([ $this->addOutput([
'style' => $this->output['style'] . file_get_contents($output['style']) 'style' => $this->output['style'] . file_get_contents($output['style'])
]); ]);
} }
// JS // JS
$scriptPath = $modulePath . 'module/' . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php'; $scriptPath = $modulePath . 'module/' . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
@ -3033,15 +2999,23 @@ class core extends common {
'content' => template::speech('La page <strong>' . $accessInfo['pageId'] . '</strong> est ouverte par l\'utilisateur <strong>' . $accessInfo['userName'] . '</strong>') 'content' => template::speech('La page <strong>' . $accessInfo['pageId'] . '</strong> est ouverte par l\'utilisateur <strong>' . $accessInfo['userName'] . '</strong>')
]); ]);
} else { } else {
if ( $this->getData(['locale','page403']) !== 'none' // Redirige vers la page de connexion si page de gestion demandée
AND $this->getData(['page',$this->getData(['locale','page403'])])) if ( $this->getData(['config', 'connect', 'redirectLogin']) === true
{ && in_array($this->geturl(0), self::$accessList) ) {
header('Location:' . helper::baseUrl() . $this->getData(['locale','page403'])); http_response_code(302);
header('Location:' . helper::baseUrl() . 'user/login/');
exit();
} else { } else {
$this->addOutput([ if ( $this->getData(['locale','page403']) !== 'none'
'title' => 'Accès interdit', AND $this->getData(['page',$this->getData(['locale','page403'])]))
'content' => template::speech('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)') {
]); header('Location:' . helper::baseUrl() . $this->getData(['locale','page403']));
} else {
$this->addOutput([
'title' => 'Accès interdit',
'content' => template::speech('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)')
]);
}
} }
} }
} elseif ($this->output['content'] === '') { } elseif ($this->output['content'] === '') {

View File

@ -481,7 +481,7 @@ if ($this->getData(['core', 'dataVersion']) < 10400) {
foreach ($pageList as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
//La page est un blog //La page est un blog
if ($this->getData(['page',$parent,'moduleId']) === 'blog' ) { if ($this->getData(['page',$parent,'moduleId']) === 'blog' ) {
$articleIds = array_keys(helper::arrayCollumn($this->getData(['module', $parent, 'posts']), 'publishedOn', 'SORT_DESC')); $articleIds = array_keys(helper::arrayColumn($this->getData(['module', $parent, 'posts']), 'publishedOn', 'SORT_DESC'));
foreach ($articleIds as $key => $article) { foreach ($articleIds as $key => $article) {
// Droits les deux groupes // Droits les deux groupes
$this->setData(['module', $parent, 'posts', $article,'editConsent', 3]); $this->setData(['module', $parent, 'posts', $article,'editConsent', 3]);
@ -809,7 +809,8 @@ if ($this->getData(['core', 'dataVersion']) < 11303) {
$this->setData(['core', 'dataVersion', 11303]); $this->setData(['core', 'dataVersion', 11303]);
} }
// Version 11.3.06
// Version 11.3.06
if ($this->getData(['core', 'dataVersion']) < 11306) { if ($this->getData(['core', 'dataVersion']) < 11306) {
// Supprime les fontes déclarées en double par la version précédentes // Supprime les fontes déclarées en double par la version précédentes
@ -822,3 +823,162 @@ if ($this->getData(['core', 'dataVersion']) < 11306) {
// Mise à jour // Mise à jour
$this->setData(['core', 'dataVersion', 11306]); $this->setData(['core', 'dataVersion', 11306]);
} }
// Version 11.4.00
if ($this->getData(['core', 'dataVersion']) < 11400) {
$fonts = [
'arimo'=> [
'name' => 'Arimo',
'font-family' => 'Arimo, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/arimo'
],
'dancing-script' => [
'name' => 'Dancing Script',
'font-family' => '\'Dancing Script\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/dancing-script'
],
'droid-sans-2'=> [
'name' => 'Droid Sans',
'font-family' => '\'Droid Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-sans-2'
],
'droid-serif-2'=> [
'name' => 'Droid Serif',
'font-family' => '\'Droid Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-serif-2'
],
'indie-flower'=> [
'name' => 'Indie Flower',
'font-family' => '\'Indie Flower\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/indie-flower'
],
'fira-sans' => [
'name' => 'Fira Sans',
'font-family' => '\'Fira Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/fira-sans'
],
'liberation-sans'=> [
'name' => 'Liberation Sans',
'font-family' => '\'Liberation Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/liberation-sans'
],
'liberation-serif'=> [
'name' => 'Liberation Serif',
'font-family' => '\'Liberation Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/liberation-serif'
],
'lobster-2'=> [
'name' => 'Lobster',
'font-family' => 'Lobster, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/lobster-2'
],
'lato'=> [
'name' => 'lato',
'font-family' => 'Lato, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/lato'
],
'old-standard-tt-3'=> [
'name' => 'Old Standard TT',
'font-family' => '\'Old Standard TT\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/old-standard-tt-3'
],
'open-sans' => [
'name' => 'Open Sans',
'font-family' => '\'Open Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/open-sans'
],
'oswald-4'=> [
'name' => 'Oswald',
'font-family' => 'Oswald, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/oswald-4'
],
'pt-mono'=> [
'name' => 'PT Mono',
'font-family' => '\'PT Mono\', monospace',
'resource' => 'https://fonts.cdnfonts.com/css/pt-mono'
],
'pt-serif'=> [
'name' => 'PR Serif',
'font-family' => '\'PT Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/pt-serif'
],
'rancho'=> [
'name' => 'Rancho',
'font-family' => 'Rancho, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/rancho'
],
'ubuntu'=> [
'name' => 'Ubuntu',
'font-family' => 'Ubuntu, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/ubuntu'
],
'vollkorn'=> [
'name' => 'Vollkorn',
'font-family' => 'Vollkorn, serif',
'resource' => 'https://fonts.cdnfonts.com/css/vollkorn'
]
];
// Conversion des fontes locales
$files = $this->getData(['fonts', 'files']);
if (is_array($files)) {
foreach ($files as $fontId => $fontName) {
if ( gettype($fontName) === 'string'
&& file_exists(self::DATA_DIR . 'fonts/' . $fontName)) {
$this->setData(['fonts', 'files', $fontId, [
'name' => ucfirst($fontId),
'font-family'=> '\'' . ucfirst($fontId) . '\', sans-serif',
'resource' => $fontName
]]);
}
}
}
// Consersion des fontes importées
$imported = $this->getData(['fonts', 'imported']);
if (is_array($imported)) {
foreach ($imported as $fontId => $fontUrl) {
if ( gettype($fontUrl) === 'string' ) {
$this->setData(['fonts', 'imported', $fontId, [
'name' => ucfirst($fontId),
'font-family'=> '\'' . ucfirst($fontId) . '\', sans-serif',
'resource' => 'https:\\fonts.cdnfonts.com\css' . $fontUrl
]]);
}
}
}
// Importation des fontes exemples
$template = $fonts;
foreach ($template as $fontId => $fontValue) {
$this->setData(['fonts', 'imported', $fontId, $fontValue]);
}
// Redirection des pages d'administration vers la bannière de connexion
$this->setData(['config', 'connect', 'redirectLogin', true]);
// Transforme les URL en références relatives
/*
$baseUrl = $this->getData(['core', 'baseUrl']);
$baseUrl2 = str_replace('?', '', $baseUrl);
foreach ($this->getHierarchy(null,null,null) as $parentKey=>$parentValue) {
$pageList [] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList [] = $childKey;
}
}
foreach ($pageList as $parentKey => $parent) {
$s = $this->getPage( $parent, self::$i18n);
// Suppression des sous-dossiers
$s = str_replace ($baseUrl, './', $s);
$s = str_replace ($baseUrl2, './', $s);
$this->setPage( $parent, $s, self::$i18n);
}
*/
// Suppression de la variable URL dans core
$this->deleteData(['core', 'baseUrl']);
// Mise à jour
$this->setData(['core', 'dataVersion', 11400]);
}

View File

@ -13,7 +13,8 @@
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css"> <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); ?>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; ?>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> <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> <body>
<?php $this->showContent(); ?> <?php $this->showContent(); ?>
<?php $this->showScript(); ?> <?php $this->showScript(); ?>

View File

@ -13,6 +13,7 @@
<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); ?>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; ?>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'); ?>"> <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 --> <!-- Détection RSS -->
<?php if ( ( $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog' <?php if ( ( $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
OR $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'news' ) OR $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'news' )
@ -20,6 +21,7 @@
<link rel="alternate" type="application/rss+xml" href="'<?php echo helper::baseUrl(). $this->getUrl(0) . '/rss';?>" title="fLUX rss"> <link rel="alternate" type="application/rss+xml" href="'<?php echo helper::baseUrl(). $this->getUrl(0) . '/rss';?>" title="fLUX rss">
<?php endif; ?> <?php endif; ?>
<?php $this->showStyle(); ?> <?php $this->showStyle(); ?>
<!-- Script perso dans le header -->
<?php if (file_exists(self::DATA_DIR .'head.inc.html')) { <?php if (file_exists(self::DATA_DIR .'head.inc.html')) {
include(self::DATA_DIR .'head.inc.html'); include(self::DATA_DIR .'head.inc.html');
}?> }?>
@ -85,11 +87,10 @@
<div id="featureContent"> <div id="featureContent">
<?php echo $this->getData(['theme','header','featureContent']);?> <?php echo $this->getData(['theme','header','featureContent']);?>
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php echo ($this->getData(['theme','header','linkHomePage']) && $this->getData(['theme','header','feature']) === 'wallpaper' ) ? '</a>' : '';?>
</header> </header>
<?php echo ( $this->getData(['theme','header','linkHomePage']) && $this->getData(['theme','header','feature']) === 'wallpaper' ) ? '</a>' : ''; ?>
<?php endif; ?> <?php endif; ?>
<!-- Menu dans le fond du site après la bannière --> <!-- Menu dans le fond du site après la bannière -->
<?php if($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?> <?php if($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?>
@ -187,6 +188,10 @@
<?php $this->showCookies(); ?> <?php $this->showCookies(); ?>
<!-- Les scripts --> <!-- Les scripts -->
<?php $this->showScript();?> <?php $this->showScript();?>
<!-- Script perso dans body -->
<?php if (file_exists(self::DATA_DIR . 'body.inc.html')) {
include(self::DATA_DIR . 'body.inc.html');
}
?>
</body> </body>
</html> </html>

View File

@ -293,7 +293,7 @@ class addon extends common {
// Modules installés // Modules installés
$infoModules = helper::getModules(); $infoModules = helper::getModules();
// Clés moduleIds dans les pages // Clés moduleIds dans les pages
$inPages = helper::arrayCollumn($this->getData(['page']),'moduleId', 'SORT_DESC'); $inPages = helper::arrayColumn($this->getData(['page']),'moduleId', 'SORT_DESC');
foreach( $inPages as $key=>$value){ foreach( $inPages as $key=>$value){
$inPagesTitle[ $this->getData(['page', $key, 'title' ]) ] = $value; $inPagesTitle[ $this->getData(['page', $key, 'title' ]) ] = $value;
} }
@ -364,7 +364,7 @@ class addon extends common {
$infoModules = helper::getModules(); $infoModules = helper::getModules();
// Clés moduleIds dans les pages // Clés moduleIds dans les pages
$inPages = helper::arrayCollumn($this->getData(['page']),'moduleId', 'SORT_DESC'); $inPages = helper::arrayColumn($this->getData(['page']),'moduleId', 'SORT_DESC');
foreach( $inPages as $key=>$value){ foreach( $inPages as $key=>$value){
$inPagesTitle[ $this->getData(['page', $key, 'title' ]) ] = $value; $inPagesTitle[ $this->getData(['page', $key, 'title' ]) ] = $value;
} }
@ -430,7 +430,7 @@ class addon extends common {
mkdir($tmpFolder, 0755); mkdir($tmpFolder, 0755);
} }
// Clés moduleIds dans les pages // Clés moduleIds dans les pages
$inPages = helper::arrayCollumn($this->getData(['page']),'moduleId', 'SORT_DESC'); $inPages = helper::arrayColumn($this->getData(['page']),'moduleId', 'SORT_DESC');
// Parcourir les pages utilisant le module // Parcourir les pages utilisant le module
foreach (array_keys($inPages,$this->getUrl(2)) as $pageId) { foreach (array_keys($inPages,$this->getUrl(2)) as $pageId) {
// Export des pages hébergeant le module // Export des pages hébergeant le module

View File

@ -1,8 +0,0 @@
<h3>MODULES INSTALLES</h3>
Les modules installés sont listés dans le tableau avec leur nom usuel (alias) et leur numéro de version.
Si le module est utilisé le nom de la page ou des pages apparaît, dans le cas contraire une icône permet de le supprimer.
<h3>EXPORTER IMPORTER</h3>
<p>Exporter produit une archive au nom du module contenant les pages concernées ainsi que les données et ressources utilisées par le module dans ces pages.</p>
<p>Vous pouvez vous en servir comme d'une sauvegarde partielle ou pour transférer les pages et les données du module vers un autre site.</p>
<p>Une fois le module installé l'import permet de restaurer les pages et les données sauvegardées. Vous devrez avoir au préalable transféré le fichier zip d'un export sur votre serveur par 'Gérer les fichiers'.
Si une page de même nom existe sur votre site vous serez invité à modifier son nom.</p>

View File

@ -16,18 +16,12 @@
'class' => 'buttonHelp' 'class' => 'buttonHelp'
]); ?> ]); ?>
</div> </div>
<div class="col2 offset4"> <div class="col2 offset6">
<?php echo template::button('configModulesStore', [ <?php echo template::button('configModulesStore', [
'href' => helper::baseUrl() . 'addon/store', 'href' => helper::baseUrl() . 'addon/store',
'value' => 'Catalogue en ligne' 'value' => 'Catalogue en ligne'
]); ?> ]); ?>
</div> </div>
<div class="col2">
<?php echo template::button('configStoreUpload', [
'href' => helper::baseUrl() . 'addon/upload',
'value' => 'Installer'
]); ?>
</div>
</div> </div>
<!-- Aide à propos de la gestion des modules, view index --> <!-- Aide à propos de la gestion des modules, view index -->
<div class="helpDisplayContent"> <div class="helpDisplayContent">

View File

@ -2,7 +2,7 @@
<div class="col2"> <div class="col2">
<?php echo template::button('configStoreBack', [ <?php echo template::button('configStoreBack', [
'class' => 'buttonGrey', 'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'addon/upload', 'href' => helper::baseUrl() . 'addon',
'ico' => 'left', 'ico' => 'left',
'value' => 'Retour' 'value' => 'Retour'
]); ?> ]); ?>

View File

@ -20,7 +20,7 @@ class config extends common {
'backup' => self::GROUP_ADMIN, 'backup' => self::GROUP_ADMIN,
'copyBackups'=> self::GROUP_ADMIN, 'copyBackups'=> self::GROUP_ADMIN,
'configMetaImage' => self::GROUP_ADMIN, 'configMetaImage' => self::GROUP_ADMIN,
'generateFiles' => self::GROUP_ADMIN, 'siteMap' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN, 'index' => self::GROUP_ADMIN,
'restore' => self::GROUP_ADMIN, 'restore' => self::GROUP_ADMIN,
'updateBaseUrl' => self::GROUP_ADMIN, 'updateBaseUrl' => self::GROUP_ADMIN,
@ -28,8 +28,7 @@ class config extends common {
'logReset' => self::GROUP_ADMIN, 'logReset' => self::GROUP_ADMIN,
'logDownload'=> self::GROUP_ADMIN, 'logDownload'=> self::GROUP_ADMIN,
'blacklistReset' => self::GROUP_ADMIN, 'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN, 'blacklistDownload' => self::GROUP_ADMIN
]; ];
public static $timezones = [ public static $timezones = [
@ -203,17 +202,15 @@ class config extends common {
* Sitemap compressé et non compressé * Sitemap compressé et non compressé
* Robots.txt * Robots.txt
*/ */
public function generateFiles() { public function siteMap() {
// Mettre à jour le site map // Mettre à jour le site map
$successSitemap=$this->createSitemap(); $successSitemap=$this->createSitemap();
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
/*'title' => 'Configuration',
'view' => 'index',*/
'redirect' => helper::baseUrl() . 'config', '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', 'notification' => $successSitemap ? 'La carte du site a été mise à jour' : 'Echec d\'écriture, la carte du site n\'a pas été mise à jour',
'state' => $successSitemap 'state' => $successSitemap
]); ]);
} }
@ -279,8 +276,6 @@ class config extends common {
} }
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
/*'title' => 'Configuration',
'view' => 'index',*/
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => $success === false ? 'Service inaccessible ou erreur d\'écriture de l\'image' : 'Image générée avec succès', 'notification' => $success === false ? 'Service inaccessible ou erreur d\'écriture de l\'image' : 'Image générée avec succès',
'state' => $success === false ? false : true 'state' => $success === false ? false : true
@ -510,7 +505,8 @@ class config extends common {
'captchaStrong' => $this->getInput('connectCaptchaStrong',helper::FILTER_BOOLEAN), 'captchaStrong' => $this->getInput('connectCaptchaStrong',helper::FILTER_BOOLEAN),
'autoDisconnect' => $this->getInput('connectAutoDisconnect',helper::FILTER_BOOLEAN), 'autoDisconnect' => $this->getInput('connectAutoDisconnect',helper::FILTER_BOOLEAN),
'captchaType' => $this->getInput('connectCaptchaType'), 'captchaType' => $this->getInput('connectCaptchaType'),
'showPassword' => $this->getInput('connectShowPassword',helper::FILTER_BOOLEAN) 'showPassword' => $this->getInput('connectShowPassword',helper::FILTER_BOOLEAN),
'redirectLogin' => $this->getInput('connectRedirectLogin',helper::FILTER_BOOLEAN)
], ],
'i18n' => [ 'i18n' => [
'enable' => $this->getInput('localei18n',helper::FILTER_BOOLEAN), 'enable' => $this->getInput('localei18n',helper::FILTER_BOOLEAN),
@ -551,17 +547,21 @@ class config extends common {
AND helper::checkRewrite() === false AND helper::checkRewrite() === false
) { ) {
// Ajout des lignes dans le .htaccess // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . 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>'. PHP_EOL .
'# URL rewriting' . PHP_EOL ;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
file_put_contents( file_put_contents(
'.htaccess', '.htaccess',
PHP_EOL . $fileContent
'<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) // Change le statut de la réécriture d'URL (pour le helper::baseUrl() de la redirection)
helper::$rewriteStatus = true; helper::$rewriteStatus = true;
@ -572,16 +572,19 @@ class config extends common {
AND helper::checkRewrite() AND helper::checkRewrite()
) { ) {
// Suppression des lignes dans le .htaccess // Suppression des lignes dans le .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess')); $fileContent = file_get_contents('.htaccess');
file_put_contents('.htaccess', $htaccess[0] . '# URL rewriting'); $fileContent = explode('# URL rewriting', $fileContent);
$fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2];
file_put_contents(
'.htaccess',
$fileContent
);
// Change le statut de la réécriture d'URL (pour le helper::baseUrl() de la redirection) // Change le statut de la réécriture d'URL (pour le helper::baseUrl() de la redirection)
helper::$rewriteStatus = false; helper::$rewriteStatus = false;
} }
// Met à jour la baseUrl
$this->setData(['core', 'baseUrl', helper::baseUrl(true,false) ]);
} }
// Générer robots.txt et sitemap // Générer robots.txt et sitemap
$this->generateFiles(); $this->siteMap();
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => 'Configuration', 'title' => 'Configuration',
@ -652,59 +655,6 @@ class config extends common {
]); ]);
} }
/**
* 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);
$titre = $this->getData(['page', $parentId, 'title']);
$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 * Vider le fichier de log

View File

@ -9,39 +9,31 @@
</a> </a>
</span> </span>
</h4> </h4>
<div class="row"> <div class="row">
<div class="col3"> <div class="col4">
<?php echo template::checkbox('connectCaptcha', true, 'Captcha à la connexion', [ <?php echo template::checkbox('connectShowPassword', true, 'Dévoiler le mot de passe', [
'checked' => $this->getData(['config', 'connect','captcha']) 'checked' => $this->getData(['config', 'connect', 'showPassword']),
]); ?> 'help' => 'Le survom d\'une icône de l\'écran de connexion affiche temporairement le mot de passe.'
<?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>
<div class="col3"> <div class="col4">
<?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', [ <?php echo template::checkbox('connectAutoDisconnect', true, 'Déconnexion automatique', [
'checked' => $this->getData(['config', 'connect', 'autoDisconnect']), 'checked' => $this->getData(['config', 'connect', 'autoDisconnect']),
'help' => 'Déconnecte les sessions ouvertes précédemment sur d\'autres navigateurs ou terminaux. Activation recommandée.' 'help' => 'Déconnecte les sessions ouvertes précédemment sur d\'autres navigateurs ou terminaux. Activation recommandée.'
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col4">
<?php echo template::checkbox('connectShowPassword', true, 'Dévoiler le mot de passe', [ <?php echo template::checkbox('connectRedirectLogin', true, 'Redirection vers la connexion', [
'checked' => $this->getData(['config', 'connect', 'showPassword']), 'checked' => $this->getData(['config', 'connect', 'redirectLogin']),
'help' => 'Dans l\'écran de connexion, active une icône dont le survol affiche temporairement le mot de passe.' 'help' => 'Cette redirection ne concerne que les pages d\'administration du site.'
]); ?> ]); ?>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col3"> <div class="col3">
<?php echo template::select('connectAttempt', $module::$connectAttempt , [ <?php echo template::select('connectAttempt', $module::$connectAttempt , [
'label' => 'Connexions successives', 'label' => 'Limitation des tentatives',
'selected' => $this->getData(['config', 'connect', 'attempt']) 'selected' => $this->getData(['config', 'connect', 'attempt'])
]); ?> ]); ?>
</div> </div>
@ -73,6 +65,25 @@
]); ?> ]); ?>
</div> </div>
</div> </div>
<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>
</div> </div>
</div> </div>
</div> </div>

View File

@ -57,21 +57,21 @@
</h4> </h4>
<div class="row"> <div class="row">
<div class="col4"> <div class="col4">
<?php echo template::select('localeHomePageId', helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC'), [ <?php echo template::select('localeHomePageId', helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC'), [
'label' => 'Accueil du site', 'label' => 'Accueil du site',
'selected' =>$this->getData(['locale', 'homePageId']), 'selected' =>$this->getData(['locale', 'homePageId']),
'help' => 'La première page que vos visiteurs verront.' 'help' => 'La première page que vos visiteurs verront.'
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
<?php echo template::select('localePage403', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($module::$orphansList, 'title', 'SORT_ASC')), [ <?php echo template::select('localePage403', array_merge(['none' => 'Page par défaut'],helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Accès interdit, erreur 403', 'label' => 'Accès interdit, erreur 403',
'selected' =>$this->getData(['locale', 'page403']), 'selected' =>$this->getData(['locale', 'page403']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.' 'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
<?php echo template::select('localePage404', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($module::$orphansList, 'title', 'SORT_ASC')), [ <?php echo template::select('localePage404', array_merge(['none' => 'Page par défaut'],helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Page inexistante, erreur 404', 'label' => 'Page inexistante, erreur 404',
'selected' =>$this->getData(['locale', 'page404']), 'selected' =>$this->getData(['locale', 'page404']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.' 'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
@ -80,14 +80,14 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col4"> <div class="col4">
<?php echo template::select('localeLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [ <?php echo template::select('localeLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Mentions légales', 'label' => 'Mentions légales',
'selected' => $this->getData(['locale', 'legalPageId']), '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.' 'help' => 'Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.'
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
<?php echo template::select('localeSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [ <?php echo template::select('localeSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Recherche dans le site', 'label' => 'Recherche dans le site',
'selected' => $this->getData(['locale', 'searchPageId']), '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.' 'help' => 'Sélectionnez une page contenant le module \'Recherche\'. Une option du pied de page ajoute un lien discret vers cette page.'
@ -95,7 +95,7 @@
</div> </div>
<div class="col4"> <div class="col4">
<?php <?php
echo template::select('localePage302', array_merge(['none' => 'Page par défaut'],helper::arrayCollumn($module::$orphansList, 'title', 'SORT_ASC')), [ echo template::select('localePage302', array_merge(['none' => 'Page par défaut'],helper::arrayColumn($module::$orphansList, 'title', 'SORT_ASC')), [
'label' => 'Site en maintenance', 'label' => 'Site en maintenance',
'selected' =>$this->getData(['locale', 'page302']), 'selected' =>$this->getData(['locale', 'page302']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.' 'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'

View File

@ -38,46 +38,4 @@
</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(); ?> <?php echo template::formClose(); ?>

View File

@ -42,9 +42,10 @@
]); ?> ]); ?>
</div> </div>
<div class="col6"> <div class="col6">
<?php echo template::checkbox('configRewrite', true, 'URL intelligentes', [ <?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [
'checked' => helper::checkRewrite(), 'checked' => helper::checkRewrite(),
'help' => 'Supprime ? dans les URL et redirige sur le protocole HTTPS.' 'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web',
'disabled' => strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0 ? true : false
]); ?> ]); ?>
</div> </div>
</div> </div>

View File

@ -23,7 +23,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<?php echo template::button('socialSiteMap', [ <?php echo template::button('socialSiteMap', [
'href' => helper::baseUrl() . 'config/generateFiles', 'href' => helper::baseUrl() . 'config/siteMap',
'value' => 'Générer sitemap.xml et robots.txt' 'value' => 'Générer sitemap.xml et robots.txt'
]); ?> ]); ?>
</div> </div>

View File

@ -54,11 +54,11 @@ class install extends common {
$userLastname = $this->getInput('installLastname', helper::FILTER_STRING_SHORT, true); $userLastname = $this->getInput('installLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('installMail', helper::FILTER_MAIL, true); $userMail = $this->getInput('installMail', helper::FILTER_MAIL, true);
$userId = $this->getInput('installId', helper::FILTER_ID, true); $userId = $this->getInput('installId', helper::FILTER_ID, true);
// Création de l'utilisateur si les données sont complétées. // Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données // success retour de l'enregistrement des données
$success = $this->setData([ $success = $this->setData([
'user', 'user',
$userId, $userId,
@ -73,7 +73,7 @@ class install extends common {
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true) 'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true)
] ]
]); ]);
// Compte créé, envoi du mail et création des données du site // Compte créé, envoi du mail et création des données du site
if ($success) { // Formulaire complété envoi du mail if ($success) { // Formulaire complété envoi du mail
// Envoie le mail // Envoie le mail
@ -97,7 +97,7 @@ class install extends common {
$this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]); $this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]);
$this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]); $this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]);
$this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]); $this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]);
} }
// Images exemples livrées dans tous les cas // Images exemples livrées dans tous les cas
try { try {
// Décompression dans le dossier de fichier temporaires // Décompression dans le dossier de fichier temporaires
@ -120,11 +120,7 @@ class install extends common {
// Créer le dossier des fontes // Créer le dossier des fontes
if (!is_dir(self::DATA_DIR . 'fonts')) { if (!is_dir(self::DATA_DIR . 'fonts')) {
mkdir(self::DATA_DIR . 'fonts'); mkdir(self::DATA_DIR . 'fonts');
} }
// Stocker le dossier d'installation
$this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]);
// Créer sitemap
$this->createSitemap();
// Installation du thème sélectionné // Installation du thème sélectionné
$dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json'); $dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json');
@ -141,7 +137,7 @@ class install extends common {
} }
$this->copyDir('core/module/install/ressource/themes', 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'); unlink(self::FILE_DIR . 'source/theme/themes.json');
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl(false), 'redirect' => helper::baseUrl(false),
@ -153,8 +149,13 @@ class install extends common {
// Récupération de la liste des thèmes // Récupération de la liste des thèmes
$dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json'); $dataThemes = file_get_contents('core/module/install/ressource/themes/themes.json');
$dataThemes = json_decode($dataThemes, true); $dataThemes = json_decode($dataThemes, true);
self::$themes = helper::arrayCollumn($dataThemes, 'name'); self::$themes = helper::arrayColumn($dataThemes, 'name');
// Créer sitemap
$this->createSitemap();
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT, 'display' => self::DISPLAY_LAYOUT_LIGHT,
@ -251,19 +252,23 @@ class install extends common {
$success = true; $success = true;
$rewrite = $this->getInput('data'); $rewrite = $this->getInput('data');
// Réécriture d'URL // Réécriture d'URL
if ($rewrite === "true") { if ($rewrite === "true") { // Ajout des lignes dans le .htaccess
$success = (file_put_contents( $fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . 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>'. PHP_EOL .
'# URL rewriting' . PHP_EOL ;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
file_put_contents(
'.htaccess', '.htaccess',
PHP_EOL . $fileContent
'<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 // Recopie htaccess
if ($this->getData(['config','autoUpdateHtaccess']) && if ($this->getData(['config','autoUpdateHtaccess']) &&
@ -271,7 +276,7 @@ class install extends common {
) { ) {
// L'écraser avec le backup // L'écraser avec le backup
$success = copy( '.htaccess.bak' ,'.htaccess' ); $success = copy( '.htaccess.bak' ,'.htaccess' );
// Effacer l ebackup // Effacer le backup
unlink('.htaccess.bak'); unlink('.htaccess.bak');
} }
// Valeurs en sortie // Valeurs en sortie

View File

@ -38,7 +38,8 @@ class init extends common {
'captchaStrong' => false, 'captchaStrong' => false,
"captchaType" => 'num', "captchaType" => 'num',
'autoDisconnect' => true, 'autoDisconnect' => true,
'showPassword' => true 'showPassword' => true,
'redirectLogin' => true
], ],
'i18n' => [ 'i18n' => [
'enable'=> true, 'enable'=> true,
@ -56,12 +57,11 @@ class init extends common {
] ]
], ],
'core' => [ 'core' => [
'dataVersion' => 11300, 'dataVersion' => 11400,
'lastBackup' => 0, 'lastBackup' => 0,
'lastClearTmp' => 0, 'lastClearTmp' => 0,
'lastAutoUpdate' => 0, 'lastAutoUpdate' => 0,
'updateAvailable' => false, 'updateAvailable' => false
'baseUrl' => ''
], ],
'locale' => [ 'locale' => [
'homePageId' => 'accueil', 'homePageId' => 'accueil',
@ -87,7 +87,108 @@ class init extends common {
], ],
'fonts' => [ 'fonts' => [
'files' => [], 'files' => [],
'imported' => [] 'imported'=> [
'arimo'=> [
'name' => 'Arimo',
'font-family' => 'Arimo, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/arimo'
],
'arvo'=> [
'name' => 'Arvo',
'font-family' => 'Arvo, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/arvo'
],
'dancing-script' => [
'name' => 'Dancing Script',
'font-family' => '\'Dancing Script\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/dancing-script'
],
'droid-sans-2'=> [
'name' => 'Droid Sans',
'font-family' => '\'Droid Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-sans-2'
],
'droid-serif-2'=> [
'name' => 'Droid Serif',
'font-family' => '\'Droid Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-serif-2'
],
'indie-flower'=> [
'name' => 'Indie Flower',
'font-family' => '\'Indie Flower\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/indie-flower'
],
'liberation-sans'=> [
'name' => 'Liberation Sans',
'font-family' => '\'Liberation Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/liberation-sans'
],
'liberation-serif'=> [
'name' => 'Liberation Serif',
'font-family' => '\'Liberation Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/liberation-serif'
],
'lobster-2'=> [
'name' => 'Lobster',
'font-family' => 'Lobster, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/lobster-2'
],
'lato'=> [
'name' => 'lato',
'font-family' => 'Lato, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/lato'
],
'lora'=> [
'name' => 'Lora',
'font-family' => 'Lora, serif',
'resource' => 'https://fonts.cdnfonts.com/css/lora'
],
'old-standard-tt-3'=> [
'name' => 'Old Standard TT',
'font-family' => '\'Old Standard TT\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/old-standard-tt-3'
],
'open-sans' => [
'name' => 'Open Sans',
'font-family' => '\'Open Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/open-sans'
],
'oswald-4'=> [
'name' => 'Oswald',
'font-family' => 'Oswald, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/oswald-4'
],
'pt-mono'=> [
'name' => 'PT Mono',
'font-family' => '\'PT Mono\', monospace',
'resource' => 'https://fonts.cdnfonts.com/css/pt-mono'
],
'pt-serif'=> [
'name' => 'PR Serif',
'font-family' => '\'PT Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/pt-serif'
],
'rancho'=> [
'name' => 'Rancho',
'font-family' => 'Rancho, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/rancho'
],
'roboto'=> [
'name' => 'Roboto',
'font-family' => 'Roboto, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/roboto'
],
'ubuntu'=> [
'name' => 'Ubuntu',
'font-family' => 'Ubuntu, sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/ubuntu'
],
'vollkorn'=> [
'name' => 'Vollkorn',
'font-family' => 'Vollkorn, serif',
'resource' => 'https://fonts.cdnfonts.com/css/vollkorn'
]
]
], ],
'page' => [ 'page' => [
'accueil' => [ 'accueil' => [
@ -132,7 +233,7 @@ class init extends common {
], ],
'footer' => [ 'footer' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)', 'backgroundColor' => 'rgba(255, 255, 255, 1)',
'font' => 'open-sans', 'font' => 'georgia',
'fontSize' => '.8em', 'fontSize' => '.8em',
'fontWeight' => 'normal', 'fontWeight' => 'normal',
'height' => '5px', 'height' => '5px',
@ -159,7 +260,7 @@ class init extends common {
], ],
'header' => [ 'header' => [
'backgroundColor' => 'rgba(32, 59, 82, 1)', 'backgroundColor' => 'rgba(32, 59, 82, 1)',
'font' => 'oswald-4', 'font' => 'arial',
'fontSize' => '2em', 'fontSize' => '2em',
'fontWeight' => 'normal', 'fontWeight' => 'normal',
'height' => '150px', 'height' => '150px',
@ -182,7 +283,7 @@ class init extends common {
'menu' => [ 'menu' => [
'backgroundColor' => 'rgba(32, 59, 82, 1)', 'backgroundColor' => 'rgba(32, 59, 82, 1)',
'backgroundColorSub' => 'rgba(32, 59, 82, 1)', 'backgroundColorSub' => 'rgba(32, 59, 82, 1)',
'font' => 'open-sans', 'font' => 'arial',
'fontSize' => '1em', 'fontSize' => '1em',
'fontWeight' => 'normal', 'fontWeight' => 'normal',
'height' => '15px 10px', 'height' => '15px 10px',
@ -213,13 +314,13 @@ class init extends common {
'borderColor' => 'rgba(236, 239, 241, 1)' 'borderColor' => 'rgba(236, 239, 241, 1)'
], ],
'text' => [ 'text' => [
'font' => 'open-sans', 'font' => 'georgia',
'fontSize' => '13px', 'fontSize' => '13px',
'textColor' => 'rgba(33, 34, 35, 1)', 'textColor' => 'rgba(33, 34, 35, 1)',
'linkColor' => 'rgba(74, 105, 189, 1)' 'linkColor' => 'rgba(74, 105, 189, 1)'
], ],
'title' => [ 'title' => [
'font' => 'oswald-4', 'font' => 'arial',
'fontWeight' => 'normal', 'fontWeight' => 'normal',
'textColor' => 'rgba(74, 105, 189, 1)', 'textColor' => 'rgba(74, 105, 189, 1)',
'textTransform' => 'none' 'textTransform' => 'none'
@ -231,9 +332,9 @@ class init extends common {
], ],
'admin' => [ 'admin' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)', 'backgroundColor' => 'rgba(255, 255, 255, 1)',
'fontText' => 'open-sans', 'fontText' => 'georgia',
'fontSize' => '13px', 'fontSize' => '13px',
'fontTitle' => 'oswald-4', 'fontTitle' => 'arial',
'colorText' => 'rgba(33, 34, 35, 1)', 'colorText' => 'rgba(33, 34, 35, 1)',
'colorTitle' => 'rgba(74, 105, 189, 1)', 'colorTitle' => 'rgba(74, 105, 189, 1)',
'backgroundColorButton' => 'rgba(74, 105, 189, 1)', 'backgroundColorButton' => 'rgba(74, 105, 189, 1)',

View File

@ -146,7 +146,7 @@ class page extends common {
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'targetBlank' => false, 'targetBlank' => false,
'title' => $pageTitle, 'title' => $pageTitle,
'shortTitle' => $pageTitle, 'shortTitle' => '',
'block' => '12', 'block' => '12',
'barLeft' => '', 'barLeft' => '',
'barRight' => '', 'barRight' => '',
@ -164,6 +164,8 @@ class page extends common {
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18n); $this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18n);
// Met à jour le site map // Met à jour le site map
$this->createSitemap('all'); $this->createSitemap('all');
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . $pageId, 'redirect' => helper::baseUrl() . $pageId,
@ -289,6 +291,8 @@ class page extends common {
$this->deleteData(['module', $url[0]]); $this->deleteData(['module', $url[0]]);
// Met à jour le site map // Met à jour le site map
$this->createSitemap('all'); $this->createSitemap('all');
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl(false), 'redirect' => helper::baseUrl(false),
@ -388,19 +392,25 @@ class page extends common {
$lastPosition = 1; $lastPosition = 1;
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy()); $hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());
$position = $this->getInput('pageEditPosition', helper::FILTER_INT); $position = $this->getInput('pageEditPosition', helper::FILTER_INT);
$extraPosition = $this->getinput('pageEditExtraPosition', helper::FILTER_BOOLEAN);
foreach($hierarchy as $hierarchyPageId) { foreach($hierarchy as $hierarchyPageId) {
// Ignore la page en cours de modification
if($hierarchyPageId === $this->getUrl(2)) { // Ne traite que les pages du menu sélectionné
continue; if ($this->getData(['page', $hierarchyPageId, 'extraPosition']) === $extraPosition ) {
} // Ignore la page en cours de modification
// Incrémente de +1 pour laisser la place à la position de la page en cours de modification if($hierarchyPageId === $this->getUrl(2) ) {
if($lastPosition === $position) { 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++; $lastPosition++;
} }
// Change la position
$this->setData(['page', $hierarchyPageId, 'position', $lastPosition]);
// Incrémente pour la prochaine position
$lastPosition++;
} }
if ($this->getinput('pageEditBlock') !== 'bar') { if ($this->getinput('pageEditBlock') !== 'bar') {
$barLeft = $this->getinput('pageEditBarLeft'); $barLeft = $this->getinput('pageEditBarLeft');
@ -476,7 +486,7 @@ class page extends common {
'hideMenuSide' => $this->getinput('pageEditHideMenuSide', helper::FILTER_BOOLEAN), 'hideMenuSide' => $this->getinput('pageEditHideMenuSide', helper::FILTER_BOOLEAN),
'hideMenuHead' => $this->getinput('pageEditHideMenuHead', helper::FILTER_BOOLEAN), 'hideMenuHead' => $this->getinput('pageEditHideMenuHead', helper::FILTER_BOOLEAN),
'hideMenuChildren' => $this->getinput('pageEditHideMenuChildren', helper::FILTER_BOOLEAN), 'hideMenuChildren' => $this->getinput('pageEditHideMenuChildren', helper::FILTER_BOOLEAN),
'extraPosition' => $this->getinput('pageEditExtraPosition', helper::FILTER_BOOLEAN) 'extraPosition' => $extraPosition
] ]
]); ]);
@ -487,9 +497,11 @@ class page extends common {
$content = empty($this->getInput('pageEditContent', null)) ? '<p></p>' : str_replace('<p></p>', '<p>&nbsp;</p>', $this->getInput('pageEditContent', null)); $content = empty($this->getInput('pageEditContent', null)) ? '<p></p>' : str_replace('<p></p>', '<p>&nbsp;</p>', $this->getInput('pageEditContent', null));
$this->setPage($pageId , $content, self::$i18n); $this->setPage($pageId , $content, self::$i18n);
// Met à jour le site map // Met à jour le site map
$this->createSitemap('all'); $this->createSitemap('all');
// Mise à jour de la liste des pages pour TinyMCE
$this->listPages();
// Redirection vers la configuration // Redirection vers la configuration
if( if(
$this->getInput('pageEditModuleRedirect', helper::FILTER_BOOLEAN) $this->getInput('pageEditModuleRedirect', helper::FILTER_BOOLEAN)
@ -510,7 +522,7 @@ class page extends common {
} }
} }
} }
self::$moduleIds = array_merge( ['' => 'Aucun'] , helper::arrayCollumn(helper::getModules(),'realName','SORT_ASC')); // Pages sans parent self::$moduleIds = array_merge( ['' => 'Aucun'] , helper::arrayColumn(helper::getModules(),'realName','SORT_ASC')); // Pages sans parent
foreach($this->getHierarchy() as $parentPageId => $childrenPageIds) { foreach($this->getHierarchy() as $parentPageId => $childrenPageIds) {
if($parentPageId !== $this->getUrl(2)) { if($parentPageId !== $this->getUrl(2)) {
self::$pagesNoParentId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']); self::$pagesNoParentId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
@ -523,8 +535,6 @@ class page extends common {
self::$pagesBarId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']); self::$pagesBarId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
} }
} }
// Mise à jour de la liste des pages pour TinyMCE
$this->pages2Json();
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => $this->getData(['page', $this->getUrl(2), 'title']), 'title' => $this->getData(['page', $this->getUrl(2), 'title']),

View File

@ -514,6 +514,12 @@ pageTypeMenuDOM.on("change", function() {
} }
}); });
/**
* Duplication du champ Title dans Short title
*/
$("#pageEditTitle").on("input", function() {
$("#pageEditShortTitle").val($(this).val());
});
/** /**
* Actualise la liste de pages lorsque le menu accessoire est sélectionné * Actualise la liste de pages lorsque le menu accessoire est sélectionné

View File

@ -42,8 +42,8 @@ class sitemap extends common
!empty($this->getData(['module',$parentId, 'posts' ]))) { !empty($this->getData(['module',$parentId, 'posts' ]))) {
$items .= '<ul>'; $items .= '<ul>';
// Ids des articles par ordre de publication // Ids des articles par ordre de publication
$articleIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $parentId,'posts']), 'publishedOn', 'SORT_DESC'); $articleIdsPublishedOns = helper::arrayColumn($this->getData(['module', $parentId,'posts']), 'publishedOn', 'SORT_DESC');
$articleIdsStates = helper::arrayCollumn($this->getData(['module', $parentId, 'posts']), 'state', 'SORT_DESC'); $articleIdsStates = helper::arrayColumn($this->getData(['module', $parentId, 'posts']), 'state', 'SORT_DESC');
$articleIds = []; $articleIds = [];
foreach ($articleIdsPublishedOns as $articleId => $articlePublishedOn) { foreach ($articleIdsPublishedOns as $articleId => $articlePublishedOn) {
if ($articlePublishedOn <= time() and $articleIdsStates[$articleId]) { if ($articlePublishedOn <= time() and $articleIdsStates[$articleId]) {
@ -78,8 +78,8 @@ class sitemap extends common
!empty($this->getData(['module', $childId, 'posts' ]))) { !empty($this->getData(['module', $childId, 'posts' ]))) {
$items .= '<ul>'; $items .= '<ul>';
// Ids des articles par ordre de publication // Ids des articles par ordre de publication
$articleIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $childId,'posts']), 'publishedOn', 'SORT_DESC'); $articleIdsPublishedOns = helper::arrayColumn($this->getData(['module', $childId,'posts']), 'publishedOn', 'SORT_DESC');
$articleIdsStates = helper::arrayCollumn($this->getData(['module', $childId, 'posts']), 'state', 'SORT_DESC'); $articleIdsStates = helper::arrayColumn($this->getData(['module', $childId, 'posts']), 'state', 'SORT_DESC');
$articleIds = []; $articleIds = [];
foreach ($articleIdsPublishedOns as $articleId => $articlePublishedOn) { foreach ($articleIdsPublishedOns as $articleId => $articlePublishedOn) {
if ($articlePublishedOn <= time() and $articleIdsStates[$articleId]) { if ($articlePublishedOn <= time() and $articleIdsStates[$articleId]) {

File diff suppressed because it is too large Load Diff

View File

@ -128,10 +128,10 @@
<h4>Mise en forme du texte</h4> <h4>Mise en forme du texte</h4>
<div class="row"> <div class="row">
<div class="col4"> <div class="col4">
<?php echo template::select('adminFontText', self::$fonts, [ <?php echo template::select('adminFontText', $module::$fonts['name'], [
'label' => 'Police du texte', 'label' => 'Police du texte',
'selected' => $this->getData(['admin', 'fontText']), 'selected' => $this->getData(['admin', 'fontText']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
@ -141,10 +141,10 @@
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
<?php echo template::select('adminFontTitle', self::$fonts, [ <?php echo template::select('adminFontTitle', $module::$fonts['name'], [
'label' => 'Police des titres', 'label' => 'Police des titres',
'selected' => $this->getData(['admin', 'fontTitle']), 'selected' => $this->getData(['admin', 'fontTitle']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
</div> </div>

View File

@ -15,7 +15,8 @@
*/ */
$(document).ready(function(){ $(document).ready(function(){
$('input[name=fontAddFontImported]').prop('checked', true); $('input[name=fontAddFontImported]').prop('checked', true);
$('#fontAddFileWrapper').hide(); $('input[name=fontAddFontUrl]').prop('checked', false);
$('#containerFontAddFile').hide();
}); });
@ -28,7 +29,8 @@ $("input[name=fontAddFontImported]").on("click", function() {
} else { } else {
$('input[name=fontAddFontFile]').prop('checked', true); $('input[name=fontAddFontFile]').prop('checked', true);
} }
$('#fontAddFileWrapper').hide(); $('#containerFontAddFile').hide();
$('#containerFontAddUrl').show();
}); });
$("input[name=fontAddFontFile]").on("click", function() { $("input[name=fontAddFontFile]").on("click", function() {
@ -37,5 +39,6 @@ $("input[name=fontAddFontFile]").on("click", function() {
} else { } else {
$('input[name=fontAddFontImported]').prop('checked', true); $('input[name=fontAddFontImported]').prop('checked', true);
} }
$('#fontAddFileWrapper').show(); $('#containerFontAddFile').show();
$('#containerFontAddUrl').hide();
}); });

View File

@ -1,23 +1,21 @@
<?php echo template::formOpen('fontAddForm'); ?> <?php echo template::formOpen('fontAddForm'); ?>
<div class="row"> <div class="row">
<div class="col2"> <div class="col1">
<?php echo template::button('fontAddBack', [ <?php echo template::button('fontAddBack', [
'class' => 'buttonGrey', 'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme/fonts', 'href' => helper::baseUrl() . 'theme/fonts',
'ico' => 'left', 'value' => template::ico('left')
'value' => 'Retour'
]); ?> ]); ?>
</div> </div>
<div class="col2"> <div class="col1">
<?php echo template::button('pageEditHelp', [ <?php echo template::button('fontAddHelp', [
'href' => 'https://doc.zwiicms.fr/fontes#add', 'href' => 'https://doc.zwiicms.fr/fontes#add',
'target' => '_blank', 'target' => '_blank',
'ico' => 'help', 'value' => template::ico('help'),
'value' => 'Aide',
'class' => 'buttonHelp' 'class' => 'buttonHelp'
]); ?> ]); ?>
</div> </div>
<div class="col2 offset6"> <div class="col2 offset8">
<?php echo template::submit('fontAddPublish', [ <?php echo template::submit('fontAddPublish', [
'value' => 'Valider', 'value' => 'Valider',
'uniqueSubmission' => true 'uniqueSubmission' => true
@ -30,14 +28,10 @@
<h4>Identité de la fonte</h4> <h4>Identité de la fonte</h4>
<div class="row"> <div class="row">
<div class="col6"> <div class="col6">
<?php echo template::checkbox('fontAddFontImported', true, 'Fonte téléchargée sur <a href="https://cdnfonts.com" target="_blank">cdnFonts</a>', [ <?php echo template::checkbox('fontAddFontImported', true, 'Fonte en ligne', []); ?>
'help' => 'Police utilisée en ligne, se connecter sur cdnFonts pour récupérer les informations nécessaires.'
]); ?>
</div> </div>
<div class="col6"> <div class="col6">
<?php echo template::checkbox('fontAddFontFile', true,'Fonte installée', [ <?php echo template::checkbox('fontAddFontFile', true,'Fonte installée', []); ?>
'help' => 'Sélectionnez un fichier de fonte au format WOFF.'
]); ?>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -45,7 +39,7 @@
<?php echo template::text('fontAddFontId', [ <?php echo template::text('fontAddFontId', [
'autocomplete' => 'off', 'autocomplete' => 'off',
'label' => 'Identifiant (sans espace ni majuscule)', 'label' => 'Identifiant (sans espace ni majuscule)',
'placeholder' => 'perry-gothic' 'placeholder' => 'big-marker-extrude'
]); ?> ]); ?>
</div> </div>
@ -58,10 +52,26 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col12">
<?php echo template::text('fontAddFontFamilyName', [
'autocomplete' => 'off',
'label' => 'Famille',
'placeholder' => "'Big Marker Extrude', sans-serif"
]); ?>
</div>
</div>
<div class="row" id="containerFontAddFile">
<div class="col12"> <div class="col12">
<?php echo template::file('fontAddFile', [ <?php echo template::file('fontAddFile', [
'label' => 'Fichier de police (Format WOFF)', 'label' => 'Fichier de fonte (Format WOFF)'
'placeholder' => 'https://fonts.cdnfonts.com/s/7896/PERRYGOT.woff' ]); ?>
</div>
</div>
<div class="row" id="containerFontAddUrl">
<div class="col12">
<?php echo template::text('fontAddUrl', [
'label' => 'Url du fichier de fonte',
'placeholder' => 'https://fonts.cdnfonts.com/css/big-marker-extrude'
]); ?> ]); ?>
</div> </div>
</div> </div>

View File

@ -0,0 +1,18 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @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-2022, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,59 @@
/**
* This file is part of Zwii.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2022, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.fr/
*/
/**
* Option par défaut du sélecteur de mode
*/
$(document).ready(function(){
if( $('input[name=fontEditFontImported]').is(':checked') ){
$('#containerfontEditFile').hide();
$('#containerfontEditUrl').show();
$('#fontEditFontFileWrapper').hide();
$('input[name=fontEditFontImported]').attr('disabled', 'disabled');
}
if( $('input[name=fontEditFontFile]').is(':checked') ){
$('#containerfontEditFile').show();
$('#containerfontEditUrl').hide();
$('#fontEditFontImportedWrapper').hide();
$('input[name=fontEditFontFile]').attr('disabled', 'disabled');
}
});
/**
* Mode téléchargement en ligne de la fonte ou installation locale
$("input, select").on("change", function() {
if( $('input[name=fontEditFontImported]').is(':checked') ){
$('input[name=fontEditFontFile]').prop('checked', false);
$('#containerfontEditFile').hide();
$('#containerfontEditUrl').show();
} else {
}
if( $('input[name=fontEditFontFile]').is(':checked') ){
$('input[name=fontEditFontImported]').prop('checked', false);
$('#containerfontEditFile').show();
$('#containerfontEditUrl').hide();
} else {
$('input[name=fontEditFontImported]').prop('checked', true);
}
});
*/

View File

@ -0,0 +1,85 @@
<?php echo template::formOpen('fontEditForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('fontEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme/fonts',
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">
<?php echo template::button('fontEditHelp', [
'href' => 'https://doc.zwiicms.fr/fontes#add',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('fontEditPublish', [
'value' => 'Valider',
'uniqueSubmission' => true
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Identité de la fonte</h4>
<div class="row">
<div class="col6">
<?php echo template::checkbox('fontEditFontImported', true, 'Fonte en ligne', [
'checked' => $this->getUrl(2) === 'imported' ? true : false
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('fontEditFontFile', true,'Fonte installée', [
'checked' => $this->getUrl(2) === 'files' ? true : false
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::text('fontEditFontId', [
'autocomplete' => 'off',
'label' => 'Identifiant (sans espace ni majuscule)',
'value' => $this->getUrl(3)
]); ?>
</div>
<div class="col6">
<?php echo template::text('fontEditFontName', [
'autocomplete' => 'off',
'label' => 'Nom',
'value' => $this->getData(['fonts', $this->getUrl(2), $this->getUrl(3), 'name'])
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::text('fontEditFontFamilyName', [
'autocomplete' => 'off',
'label' => 'Famille',
'value' => stripslashes($this->getData(['fonts', $this->getUrl(2), $this->getUrl(3), 'font-family']))
]); ?>
</div>
</div>
<div class="row" id="containerfontEditFile">
<div class="col12">
<?php echo template::file('fontEditFile', [
'label' => 'Fichier de fonte (Format WOFF)',
'value' => $this->getUrl(2) === 'files' ? $this->getData(['fonts', $this->getUrl(2), $this->getUrl(3), 'resource']) : ''
]); ?>
</div>
</div>
<div class="row" id="containerfontEditUrl">
<div class="col12">
<?php echo template::text('fontEditUrl', [
'label' => 'Url du fichier de fonte',
'value' => $this->getUrl(2) === 'imported' ? $this->getData(['fonts', $this->getUrl(2), $this->getUrl(3), 'resource']) : ''
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -1,22 +1,20 @@
<div class="row"> <div class="row">
<div class="col2"> <div class="col1">
<?php echo template::button('themeFontBack', [ <?php echo template::button('themeFontBack', [
'class' => 'buttonGrey', 'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme', 'href' => helper::baseUrl() . 'theme',
'ico' => 'left', 'value' => template::ico('left')
'value' => 'Retour'
]); ?> ]); ?>
</div> </div>
<div class="col2"> <div class="col1">
<?php echo template::button('pageEditHelp', [ <?php echo template::button('pageEditHelp', [
'href' => 'https://doc.zwiicms.fr/fontes', 'href' => 'https://doc.zwiicms.fr/fontes',
'target' => '_blank', 'target' => '_blank',
'ico' => 'help', 'value' => template::ico('help'),
'value' => 'Aide',
'class' => 'buttonHelp' 'class' => 'buttonHelp'
]); ?> ]); ?>
</div> </div>
<div class="col2 offset6"> <div class="col2 offset8">
<?php echo template::button('themeFontAdd', [ <?php echo template::button('themeFontAdd', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/fontAdd', 'href' => helper::baseUrl() . $this->getUrl(0) . '/fontAdd',
'ico' => 'plus', 'ico' => 'plus',
@ -24,8 +22,8 @@
]); ?> ]); ?>
</div> </div>
</div> </div>
<?php if($module::$fontsList): ?> <?php if($module::$fontsDetail): ?>
<?php echo template::table([3, 3, 3, 3, 1], $module::$fontsList, ['Family Name', 'Font Id', 'Affectation', 'Ressource', 'Effacer']); ?> <?php echo template::table([2, 2, 3, 2, 1, 1, 1], $module::$fontsDetail, ['FontId', 'Nom', 'Famille', 'Affectation', 'Origine', '', '']); ?>
<?php else: ?> <?php else: ?>
<?php echo template::speech('Aucune fonte !'); ?> <?php echo template::speech('Aucune fonte !'); ?>
<?php endif; ?> <?php endif; ?>

View File

@ -133,7 +133,7 @@
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col3">
<?php echo template::select('configLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [ <?php echo template::select('configLegalPageId', array_merge(['none' => 'Aucune'] , helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Page "Mentions légales" ' . template::flag('site', '20px'), 'label' => 'Page "Mentions légales" ' . template::flag('site', '20px'),
'selected' => $this->getData(['locale', 'legalPageId']) 'selected' => $this->getData(['locale', 'legalPageId'])
]); ?> ]); ?>
@ -147,7 +147,7 @@
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col3">
<?php echo template::select('configSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayCollumn($module::$pagesList, 'title', 'SORT_ASC') ) , [ <?php echo template::select('configSearchPageId', array_merge(['none' => 'Aucune'] , helper::arrayColumn($module::$pagesList, 'title', 'SORT_ASC') ) , [
'label' => 'Page "Rechercher" ' . template::flag('site', '20px'), 'label' => 'Page "Rechercher" ' . template::flag('site', '20px'),
'selected' => $this->getData(['locale', 'searchPageId']) 'selected' => $this->getData(['locale', 'searchPageId'])
]); ?> ]); ?>
@ -171,10 +171,10 @@
<h4>Mise en forme du texte</h4> <h4>Mise en forme du texte</h4>
<div class="row"> <div class="row">
<div class="col3"> <div class="col3">
<?php echo template::select('themeFooterFont', self::$fonts, [ <?php echo template::select('themeFooterFont', $module::$fonts['name'], [
'label' => 'Police', 'label' => 'Fonte',
'selected' => $this->getData(['theme', 'footer', 'font']), 'selected' => $this->getData(['theme', 'footer', 'font']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col3">

View File

@ -47,9 +47,9 @@ $("input, select").on("change", function() {
var tmpImg = new Image(); var tmpImg = new Image();
tmpImg.onload = function() { tmpImg.onload = function() {
// Informations affichées // Informations affichées
$("#themeHeaderImageHeight").val(tmpImg.height + " px"); $("#themeHeaderImageHeight").html(tmpImg.height + "px");
$("#themeHeaderImageWidth").val(tmpImg.width + " px"); $("#themeHeaderImageWidth").html(tmpImg.width + "px");
$("#themeHeaderImageRatio").val(tmpImg.width / tmpImg.height); $("#themeHeaderImageRatio").html(tmpImg.width / tmpImg.height);
// Limiter la hauteur à 600 px // Limiter la hauteur à 600 px
if (tmpImg.height > 600) { if (tmpImg.height > 600) {
@ -69,6 +69,9 @@ $("input, select").on("change", function() {
$("#themeHeaderHeight option:eq(0)").val(tmpImgHeight + "px"); $("#themeHeaderHeight option:eq(0)").val(tmpImgHeight + "px");
// Modifier l'option // Modifier l'option
$("#themeHeaderHeight option:eq(0)").html("Hauteur de l\'image sélectionnée (" + tmpImgHeight + "px)"); $("#themeHeaderHeight option:eq(0)").html("Hauteur de l\'image sélectionnée (" + tmpImgHeight + "px)");
$("#themeHeaderImageInfo").show();
} else {
$("#themeHeaderImageInfo").hide();
} }
}; };
@ -207,10 +210,10 @@ $("input, select").on("change", function() {
// Affiche / Cache les options de l'image du fond // Affiche / Cache les options de l'image du fond
$("#themeHeaderImage").on("change", function() { $("#themeHeaderImage").on("change", function() {
if($(this).val()) { if($(this).val()) {
$("#themeHeaderImageOptions").slideDown(); $(".themeHeaderImageOptions").slideDown();
} }
else { else {
$("#themeHeaderImageOptions").slideUp(function() { $(".themeHeaderImageOptions").slideUp(function() {
$("#themeHeaderTextHide").prop("checked", false).trigger("change"); $("#themeHeaderTextHide").prop("checked", false).trigger("change");
}); });
} }

View File

@ -106,10 +106,10 @@
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
<?php echo template::select('themeHeaderFont', self::$fonts, [ <?php echo template::select('themeHeaderFont', $module::$fonts['name'], [
'label' => 'Police', 'label' => 'Fonte',
'selected' => $this->getData(['theme', 'header', 'font']), 'selected' => $this->getData(['theme', 'header', 'font']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
@ -154,40 +154,20 @@
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'header', 'image'])) ? $imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'header', 'image'])) ?
$this->getData(['theme', 'header', 'image']) : ""; $this->getData(['theme', 'header', 'image']) : "";
echo template::file('themeHeaderImage', [ echo template::file('themeHeaderImage', [
'help' => 'Sélectionner une image aux dimensions recommandées ci-dessous :',
'label' => 'Image', 'label' => 'Image',
'type' => 1, 'type' => 1,
'value' => $imageFile 'value' => $imageFile
]); ?> ]); ?>
<span class="themeHeaderImageOptions displayNone" id="themeHeaderImageInfo">
Largeur de l'image : <span id="themeHeaderImageWidth"></span> (largeur de site : <?php echo $this->getData(['theme', 'site', 'width']); ?>)
-
Hauteur de l'image : <span id="themeHeaderImageHeight"></span>
-
Ratio : <span id="themeHeaderImageRatio"></span>
</span>
</div> </div>
</div> </div>
<div class="row"> <div class="themeHeaderImageOptions" class="displayNone">
<div class="col3 textAlignRight">
Informations sur l'image :
</div>
<div class="col2">
<?php echo template::text('themeHeaderImageWidth', [
'label' => 'Largeur',
'class' => 'textAlignCenter',
'disable' => true
]); ?>
</div>
<div class="col2">
<?php echo template::text('themeHeaderImageHeight', [
'label' => 'Hauteur',
'class' => 'textAlignCenter',
'disable' => true
]); ?>
</div>
<div class="col2">
<?php echo template::text('themeHeaderImageRatio', [
'label' => 'Ratio (L/H)',
'class' => 'textAlignCenter',
'disable' => true
]); ?>
</div>
</div>
<div id="themeHeaderImageOptions" class="displayNone">
<div class="row"> <div class="row">
<div class="col3"> <div class="col3">
<?php echo template::select('themeHeaderImageRepeat', $module::$repeats, [ <?php echo template::select('themeHeaderImageRepeat', $module::$repeats, [

View File

@ -15,7 +15,7 @@
</div> </div>
<div class="col2"> <div class="col2">
<?php echo template::button('themeHelp', [ <?php echo template::button('themeHelp', [
'href' => 'https://doc.zwiicms.fr/theme-2', 'href' => 'https://doc.zwiicms.fr/gestion-du-theme',
'target' => '_blank', 'target' => '_blank',
'ico' => 'help', 'ico' => 'help',
'value' => 'Aide', 'value' => 'Aide',
@ -73,7 +73,7 @@
</div> </div>
<div class="col2"> <div class="col2">
<?php echo template::button('themeHelp', [ <?php echo template::button('themeHelp', [
'href' => 'https://doc.zwiicms.fr/theme-2', 'href' => 'https://doc.zwiicms.fr/gestion-du-theme',
'target' => '_blank', 'target' => '_blank',
'ico' => 'help', 'ico' => 'help',
'value' => 'Aide', 'value' => 'Aide',

View File

@ -183,10 +183,10 @@
<h4>Mise en forme du texte</h4> <h4>Mise en forme du texte</h4>
<div class="row"> <div class="row">
<div class="col6"> <div class="col6">
<?php echo template::select('themeMenuFont', self::$fonts, [ <?php echo template::select('themeMenuFont', $module::$fonts['name'], [
'label' => 'Police', 'label' => 'Fonte',
'selected' => $this->getData(['theme', 'menu', 'font']), 'selected' => $this->getData(['theme', 'menu', 'font']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col6"> <div class="col6">

View File

@ -11,8 +11,6 @@
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
/** /**
* Aperçu en direct * Aperçu en direct
*/ */
@ -28,21 +26,19 @@ $("input, select").on("change",function() {
$("#themeSiteMarginWrapper").show(); $("#themeSiteMarginWrapper").show();
} }
/** /**
* Aperçu dans la boîte * Aperçu dans la boîte
*/ */
// Import des polices de caractères // Import des polices de caractères pour l'aperçu en temps réel
var titleFont = $("#themeTitleFont :selected").val(); var titleFont = $("#themeTitleFont :selected").val();
var titleFontText = $("#themeTitleFont :selected").text(); var titleFontText = $("#themeTitleFont :selected").text();
var textFont = $("#themeTextFont :selected").val(); var textFont = $("#themeTextFont :selected").val();
var textFontText = $("#themeTextFont :selected").text(); var textFontText = $("#themeTextFont :selected").text();
console.log(textFontText);
var css = "@import url('https://fonts.cdnfonts.com/css/" + titleFont + "');";
var css = "@import url('https://fonts.cdnfonts.com/css/" + textFont + "');";
// Couleurs des boutons // Couleurs des boutons
var colors = core.colorVariants($("#themeButtonBackgroundColor").val()); var colors = core.colorVariants($("#themeButtonBackgroundColor").val());
css += ".button.buttonSubmitPreview{background-color:" + colors.normal + ";}"; var css = ".button.buttonSubmitPreview{background-color:" + colors.normal + ";}";
css += ".button.buttonSubmitPreview:hover{background-color:" + colors.darken + "}"; css += ".button.buttonSubmitPreview:hover{background-color:" + colors.darken + "}";
css += ".button.buttonSubmitPreview{color:" + colors.text + ";}"; css += ".button.buttonSubmitPreview{color:" + colors.text + ";}";
@ -114,5 +110,4 @@ $("input, select").on("change",function() {
.attr("id", "themePreview") .attr("id", "themePreview")
.text(css) .text(css)
.appendTo("head"); .appendTo("head");
}).trigger("change"); }).trigger("change");

View File

@ -141,7 +141,8 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block preview"> <div class="block preview">
<h4 class="preview">Bloc</h4> <p class="textPreview">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> <h4 class="preview">Bloc</h4>
<p class="textPreview">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p><a href="#" class="urlPreview">Lorem ipsum dolor sit amet.</a></p> <p><a href="#" class="urlPreview">Lorem ipsum dolor sit amet.</a></p>
</div> </div>
</div> </div>
@ -158,10 +159,11 @@
<h4>Mise en forme du texte</h4> <h4>Mise en forme du texte</h4>
<div class="row"> <div class="row">
<div class="col6"> <div class="col6">
<?php echo template::select('themeTextFont', self::$fonts, [ <?php
'label' => 'Police', echo template::select('themeTextFont', $module::$fonts['name'], [
'label' => 'Fonte',
'selected' => $this->getData(['theme', 'text', 'font']), 'selected' => $this->getData(['theme', 'text', 'font']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col6"> <div class="col6">
@ -179,10 +181,10 @@
<h4>Mise en forme des titres</h4> <h4>Mise en forme des titres</h4>
<div class="row"> <div class="row">
<div class="col4"> <div class="col4">
<?php echo template::select('themeTitleFont', self::$fonts, [ <?php echo template::select('themeTitleFont', $module::$fonts['name'] , [
'label' => 'Police', 'label' => 'Fonte',
'selected' => $this->getData(['theme', 'title', 'font']), 'selected' => $this->getData(['theme', 'title', 'font']),
'fonts' => true 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">

View File

@ -336,7 +336,7 @@ class user extends common {
* Liste des utilisateurs * Liste des utilisateurs
*/ */
public function index() { public function index() {
$userIdsFirstnames = helper::arrayCollumn($this->getData(['user']), 'firstname'); $userIdsFirstnames = helper::arrayColumn($this->getData(['user']), 'firstname');
ksort($userIdsFirstnames); ksort($userIdsFirstnames);
foreach($userIdsFirstnames as $userId => $userFirstname) { foreach($userIdsFirstnames as $userId => $userFirstname) {
if ($this->getData(['user', $userId, 'group'])) { if ($this->getData(['user', $userId, 'group'])) {
@ -397,7 +397,7 @@ class user extends common {
] ]
]); ]);
// Verrouillage des IP // Verrouillage des IP
$ipBlackList = helper::arrayCollumn($this->getData(['blacklist']), 'ip'); $ipBlackList = helper::arrayColumn($this->getData(['blacklist']), 'ip');
if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt']) if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt'])
AND in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) { AND in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) {
$logStatus = 'Compte inconnu verrouillé'; $logStatus = 'Compte inconnu verrouillé';

View File

@ -3,8 +3,8 @@ $version = "9.14.0";
if (session_id() == '') session_start(); if (session_id() == '') session_start();
mb_internal_encoding('UTF-8'); mb_internal_encoding('UTF-8');
mb_http_output('UTF-8'); mb_http_output();
mb_http_input('UTF-8'); mb_http_input();
mb_language('uni'); mb_language('uni');
if (function_exists('mb_regex_encoding')) { if (function_exists('mb_regex_encoding')) {
mb_regex_encoding('UTF-8'); mb_regex_encoding('UTF-8');

View File

@ -114,7 +114,7 @@ tinymce.init({
// Active l'onglet avancé lors de l'ajout d'une image // Active l'onglet avancé lors de l'ajout d'une image
image_advtab: true, image_advtab: true,
// Urls absolues // Urls absolues
relative_urls: false, relative_urls: true,
// Url de base // Url de base
document_base_url: baseUrl, document_base_url: baseUrl,
// Gestionnaire de fichiers // Gestionnaire de fichiers
@ -294,7 +294,7 @@ tinymce.init({
// Active l'onglet avancé lors de l'ajout d'une image // Active l'onglet avancé lors de l'ajout d'une image
image_advtab: true, image_advtab: true,
// Urls absolues // Urls absolues
relative_urls: false, relative_urls: true,
// Url de base // Url de base
document_base_url: baseUrl, document_base_url: baseUrl,
// Contenu du bouton formats // Contenu du bouton formats

View File

@ -140,8 +140,8 @@ class blog extends common {
$feeds->setDate(date('r',time())); $feeds->setDate(date('r',time()));
$feeds->addGenerator(); $feeds->addGenerator();
// Corps des articles // Corps des articles
$articleIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC'); $articleIdsPublishedOns = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC');
$articleIdsStates = helper::arrayCollumn($this->getData(['module', $this->getUrl(0),'posts']), 'state', 'SORT_DESC'); $articleIdsStates = helper::arrayColumn($this->getData(['module', $this->getUrl(0),'posts']), 'state', 'SORT_DESC');
foreach( $articleIdsPublishedOns as $articleId => $articlePublishedOn ) { foreach( $articleIdsPublishedOns as $articleId => $articlePublishedOn ) {
if( $articlePublishedOn <= time() AND $articleIdsStates[$articleId] ) { if( $articlePublishedOn <= time() AND $articleIdsStates[$articleId] ) {
// Miniature // Miniature
@ -230,7 +230,7 @@ class blog extends common {
]); ]);
} }
// Liste des utilisateurs // Liste des utilisateurs
self::$users = helper::arrayCollumn($this->getData(['user']), 'firstname'); self::$users = helper::arrayColumn($this->getData(['user']), 'firstname');
ksort(self::$users); ksort(self::$users);
foreach(self::$users as $userId => &$userFirstname) { foreach(self::$users as $userId => &$userFirstname) {
$userFirstname = $userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']); $userFirstname = $userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']);
@ -259,7 +259,7 @@ class blog extends common {
'value' => 'Tout effacer' 'value' => 'Tout effacer'
]); ]);
// Ids des commentaires par ordre de création // Ids des commentaires par ordre de création
$commentIds = array_keys(helper::arrayCollumn($comments, 'createdOn', 'SORT_DESC')); $commentIds = array_keys(helper::arrayColumn($comments, 'createdOn', 'SORT_DESC'));
// Pagination // Pagination
$pagination = helper::pagination($commentIds, $this->getUrl(),$this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage']) ); $pagination = helper::pagination($commentIds, $this->getUrl(),$this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage']) );
// Liste des pages // Liste des pages
@ -416,7 +416,7 @@ class blog extends common {
]); ]);
} else { } else {
// Ids des articles par ordre de publication // Ids des articles par ordre de publication
$articleIds = array_keys(helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC')); $articleIds = array_keys(helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC'));
// Gestion des droits d'accès // Gestion des droits d'accès
$filterData=[]; $filterData=[];
foreach ($articleIds as $key => $value) { foreach ($articleIds as $key => $value) {
@ -448,7 +448,7 @@ class blog extends common {
// Articles en fonction de la pagination // Articles en fonction de la pagination
for($i = $pagination['first']; $i < $pagination['last']; $i++) { for($i = $pagination['first']; $i < $pagination['last']; $i++) {
// Nombre de commentaires à approuver et approuvés // Nombre de commentaires à approuver et approuvés
$approvals = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'comment' ]),'approval', 'SORT_DESC'); $approvals = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts', $articleIds[$i], 'comment' ]),'approval', 'SORT_DESC');
if ( is_array($approvals) ) { if ( is_array($approvals) ) {
$a = array_values($approvals); $a = array_values($approvals);
$toApprove = count(array_keys($a,false)); $toApprove = count(array_keys($a,false));
@ -595,7 +595,7 @@ class blog extends common {
]); ]);
} }
// Liste des utilisateurs // Liste des utilisateurs
self::$users = helper::arrayCollumn($this->getData(['user']), 'firstname'); self::$users = helper::arrayColumn($this->getData(['user']), 'firstname');
ksort(self::$users); ksort(self::$users);
foreach(self::$users as $userId => &$userFirstname) { foreach(self::$users as $userId => &$userFirstname) {
// Les membres ne sont pas éditeurs, les exclure de la liste // Les membres ne sont pas éditeurs, les exclure de la liste
@ -709,7 +709,7 @@ class blog extends common {
// Ligne suivante si affichage du nombre total de commentaires approuvés sous l'article // Ligne suivante si affichage du nombre total de commentaires approuvés sous l'article
self::$nbCommentsApproved = count($commentsApproved); self::$nbCommentsApproved = count($commentsApproved);
} }
$commentIds = array_keys(helper::arrayCollumn($commentsApproved, 'createdOn', 'SORT_DESC')); $commentIds = array_keys(helper::arrayColumn($commentsApproved, 'createdOn', 'SORT_DESC'));
// Pagination // Pagination
$pagination = helper::pagination($commentIds, $this->getUrl(), $this->getData(['module', $this->getUrl(0),'config', 'itemsperPage']),'#comment'); $pagination = helper::pagination($commentIds, $this->getUrl(), $this->getData(['module', $this->getUrl(0),'config', 'itemsperPage']),'#comment');
// Liste des pages // Liste des pages
@ -749,8 +749,8 @@ class blog extends common {
// Liste des articles // Liste des articles
else { else {
// Ids des articles par ordre de publication // Ids des articles par ordre de publication
$articleIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $this->getUrl(0),'posts']), 'publishedOn', 'SORT_DESC'); $articleIdsPublishedOns = helper::arrayColumn($this->getData(['module', $this->getUrl(0),'posts']), 'publishedOn', 'SORT_DESC');
$articleIdsStates = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'state', 'SORT_DESC'); $articleIdsStates = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'state', 'SORT_DESC');
$articleIds = []; $articleIds = [];
foreach($articleIdsPublishedOns as $articleId => $articlePublishedOn) { foreach($articleIdsPublishedOns as $articleId => $articlePublishedOn) {
if($articlePublishedOn <= time() AND $articleIdsStates[$articleId]) { if($articlePublishedOn <= time() AND $articleIdsStates[$articleId]) {

View File

@ -20,7 +20,7 @@
<div class="col2"> <div class="col2">
<?php echo template::submit('blogEditSubmit', [ <?php echo template::submit('blogEditSubmit', [
'value' => 'Publier', 'value' => 'Publier',
'uniqueSubmission' => true, 'uniqueSubmission' => true
]); ?> ]); ?>
</div> </div>
</div> </div>
@ -39,7 +39,7 @@
<div class="row"> <div class="row">
<div class="col6"> <div class="col6">
<?php echo template::file('blogEditPicture', [ <?php echo template::file('blogEditPicture', [
'help' => 'Taille optimale de l\'image de couverture : ' . ((int) substr($this->getData(['theme', 'site', 'width']), 0, -2) - (20 * 2)) . ' x 350 pixels.', 'help' => $this->getData(['theme', 'site', 'width']) !== '100%' ? 'Taille optimale de l\'image de couverture : ' . ((int) substr($this->getData(['theme', 'site', 'width']), 0, -2) - (20 * 2)) . ' x 350 pixels.' : '',
'label' => 'Image de couverture', 'label' => 'Image de couverture',
'type' => 1, 'type' => 1,
'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picture']) 'value' => $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(2), 'picture'])

View File

@ -80,7 +80,7 @@ class form extends common {
*/ */
public function config() { public function config() {
// Liste des utilisateurs // Liste des utilisateurs
$userIdsFirstnames = helper::arrayCollumn($this->getData(['user']), 'firstname'); $userIdsFirstnames = helper::arrayColumn($this->getData(['user']), 'firstname');
ksort($userIdsFirstnames); ksort($userIdsFirstnames);
self::$listUsers [] = ''; self::$listUsers [] = '';
foreach($userIdsFirstnames as $userId => $userFirstname) { foreach($userIdsFirstnames as $userId => $userFirstname) {

View File

@ -69,7 +69,7 @@ function position() {
var inputUid = 0; var inputUid = 0;
var inputs = <?php echo json_encode($this->getData(['module', $this->getUrl(0), 'input'])); ?>; var inputs = <?php echo json_encode($this->getData(['module', $this->getUrl(0), 'input'])); ?>;
if(inputs) { if(inputs) {
var inputsPerPosition = <?php echo json_encode(helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'input']), 'position', 'SORT_ASC')); ?>; var inputsPerPosition = <?php echo json_encode(helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'input']), 'position', 'SORT_ASC')); ?>;
$.each(inputsPerPosition, function(id) { $.each(inputsPerPosition, function(id) {
add(inputUid, inputs[id]); add(inputUid, inputs[id]);
inputUid++; inputUid++;

View File

@ -17,7 +17,7 @@
class gallery extends common { class gallery extends common {
const VERSION = '3.4'; const VERSION = '3.5';
const REALNAME = 'Galerie'; const REALNAME = 'Galerie';
const DELETE = true; const DELETE = true;
const UPDATE = '0.0'; const UPDATE = '0.0';
@ -51,7 +51,9 @@ class gallery extends common {
'sortGalleries' => self::GROUP_MODERATOR, 'sortGalleries' => self::GROUP_MODERATOR,
'sortPictures' => self::GROUP_MODERATOR, 'sortPictures' => self::GROUP_MODERATOR,
'edit' => self::GROUP_MODERATOR, 'edit' => self::GROUP_MODERATOR,
'add' => self::GROUP_MODERATOR,
'theme' => self::GROUP_MODERATOR, 'theme' => self::GROUP_MODERATOR,
'option' => self::GROUP_MODERATOR,
'index' => self::GROUP_VISITOR 'index' => self::GROUP_VISITOR
]; ];
@ -151,7 +153,6 @@ class gallery extends common {
*/ */
private function update() { private function update() {
// Initialisation du module, créer les données si elles sont manquantes. // Initialisation du module, créer les données si elles sont manquantes.
$this->init(); $this->init();
@ -264,7 +265,7 @@ class gallery extends common {
* *
*/ */
public function sortGalleries() { public function sortGalleries() {
if($_POST['response']) { if( isset($_POST['response']) ){
$data = explode('&',$_POST['response']); $data = explode('&',$_POST['response']);
$data = str_replace('galleryTable%5B%5D=','',$data); $data = str_replace('galleryTable%5B%5D=','',$data);
for($i=0;$i<count($data);$i++) { for($i=0;$i<count($data);$i++) {
@ -275,7 +276,8 @@ class gallery extends common {
'homePicture' => $this->getData(['module',$this->getUrl(0), 'content', $data[$i],'config','homePicture']), 'homePicture' => $this->getData(['module',$this->getUrl(0), 'content', $data[$i],'config','homePicture']),
'sort' => $this->getData(['module',$this->getUrl(0), 'content', $data[$i],'config','sort']), 'sort' => $this->getData(['module',$this->getUrl(0), 'content', $data[$i],'config','sort']),
'position'=> $i, 'position'=> $i,
'fullScreen' => $this->getData(['module',$this->getUrl(0), 'content',$data[$i],'config','fullScreen']) 'fullScreen' => $this->getData(['module',$this->getUrl(0), 'content',$data[$i],'config','fullScreen']),
'showPageContent' => $this->getData(['module',$this->getUrl(0), 'content',$data[$i],'config','showPageContent'])
], ],
'legend' => $this->getData(['module',$this->getUrl(0), 'content', $data[$i],'legend']), 'legend' => $this->getData(['module',$this->getUrl(0), 'content', $data[$i],'legend']),
@ -290,22 +292,22 @@ class gallery extends common {
* *
*/ */
public function sortPictures() { public function sortPictures() {
if($_POST['response']) { if( isset($_POST['response']) ) {
$galleryName = $_POST['gallery']; $galleryName = $_POST['gallery'];
$data = explode('&',$_POST['response']); $data = explode('&',$_POST['response']);
$data = str_replace('galleryTable%5B%5D=','',$data); $data = str_replace('galleryTable%5B%5D=','',$data);
// Sauvegarder // Sauvegarder
$this->setData(['module', $this->getUrl(0), 'content', $galleryName, [ $this->setData(['module', $this->getUrl(0), 'content', $galleryName, [
'config' => [ 'config' => [
'name' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','name']), 'name' => $this->getData(['module',$this->getUrl(0), 'content', $galleryName,'config','name']),
'directory' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','directory']), 'directory' => $this->getData(['module',$this->getUrl(0),'content',$galleryName,'config','directory']),
'homePicture' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','homePicture']), 'homePicture' => $this->getData(['module',$this->getUrl(0),'content',$galleryName,'config','homePicture']),
'sort' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','sort']), 'sort' => $this->getData(['module',$this->getUrl(0),'content',$galleryName,'config','sort']),
'position' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','position']), 'position' => $this->getData(['module',$this->getUrl(0),'content',$galleryName,'config','position']),
'fullScreen' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','fullScreen']) 'fullScreen' => $this->getData(['module',$this->getUrl(0),'content',$galleryName,'config','fullScreen'])
], ],
'legend' => $this->getData(['module',$this->getUrl(0),$galleryName,'legend']), 'legend' => $this->getData(['module',$this->getUrl(0), 'content', $galleryName,'legend']),
'positions' => array_flip($data) 'positions' => array_flip($data)
]]); ]]);
} }
@ -322,7 +324,7 @@ class gallery extends common {
//Affichage de la galerie triée //Affichage de la galerie triée
$g = $this->getData(['module', $this->getUrl(0), 'content']); $g = $this->getData(['module', $this->getUrl(0), 'content']);
$p = helper::arrayCollumn(helper::arrayCollumn($g,'config'),'position'); $p = helper::arrayColumn(helper::arrayColumn($g,'config'),'position');
asort($p,SORT_NUMERIC); asort($p,SORT_NUMERIC);
$galleries = []; $galleries = [];
foreach ($p as $positionId => $item) { foreach ($p as $positionId => $item) {
@ -343,7 +345,7 @@ class gallery extends common {
} }
// Met en forme le tableau // Met en forme le tableau
self::$galleries[] = [ self::$galleries[] = [
template::ico('sort'), $gallery['config']['position'] + 1,
$gallery['config']['name'], $gallery['config']['name'],
$gallery['config']['directory'], $gallery['config']['directory'],
template::button('galleryConfigEdit' . $galleryId , [ template::button('galleryConfigEdit' . $galleryId , [
@ -385,9 +387,10 @@ class gallery extends common {
'name' => $this->getInput('galleryConfigName'), 'name' => $this->getInput('galleryConfigName'),
'directory' => $this->getInput('galleryConfigDirectory', helper::FILTER_STRING_SHORT, true), 'directory' => $this->getInput('galleryConfigDirectory', helper::FILTER_STRING_SHORT, true),
'homePicture' => $homePicture, 'homePicture' => $homePicture,
'sort' => self::SORT_ASC, 'sort' => $this->getInput('galleryConfigSort'),
'position' => $this->getData(['module', $this->getUrl(0), 'content', $galleryId,'config','position']), 'position' => count($this->getData(['module', $this->getUrl(0), 'content'])) + 1,
'fullScreen' => false 'fullScreen' => $this->getInput('galleryConfigFullscreen', helper::FILTER_BOOLEAN),
'showPageContent' => $this->getInput('galleryConfigShowPageContent', helper::FILTER_BOOLEAN)
], ],
'legend' => [], 'legend' => [],
'positions' => [] 'positions' => []
@ -410,6 +413,58 @@ class gallery extends common {
]); ]);
} }
/**
* Ajout d'une galerie
*/
public function add() {
// Soumission du formulaire d'ajout d'une galerie
if($this->isPost()) {
if (!$this->getInput('galleryAddFilterResponse')) {
$galleryId = helper::increment($this->getInput('galleryAddName', helper::FILTER_ID, true), (array) $this->getData(['module', $this->getUrl(0), 'content']));
// définir une vignette par défaut
$directory = $this->getInput('galleryAddDirectory', helper::FILTER_STRING_SHORT, true);
$iterator = new DirectoryIterator($directory);
foreach($iterator as $fileInfos) {
if($fileInfos->isDot() === false AND $fileInfos->isFile() AND @getimagesize($fileInfos->getPathname())) {
// Créer la miniature si manquante
if (!file_exists( str_replace('source','thumb',$fileInfos->getPath()) . '/' . self::THUMBS_SEPARATOR . strtolower($fileInfos->getFilename()))) {
$this->makeThumb($fileInfos->getPathname(),
str_replace('source','thumb',$fileInfos->getPath()) . '/' . self::THUMBS_SEPARATOR . strtolower($fileInfos->getFilename()),
self::THUMBS_WIDTH);
}
// Miniatures
$homePicture = strtolower($fileInfos->getFilename());
break;
}
}
$this->setData(['module', $this->getUrl(0), 'content', $galleryId, [
'config' => [
'name' => $this->getInput('galleryAddName'),
'directory' => $this->getInput('galleryAddDirectory', helper::FILTER_STRING_SHORT, true),
'homePicture' => $homePicture,
'sort' => $this->getInput('galleryAddSort'),
'position' => count($this->getData(['module', $this->getUrl(0), 'content'])) + 1,
'fullScreen' => $this->getInput('galleryAddFullscreen', helper::FILTER_BOOLEAN),
'showPageContent' => $this->getInput('galleryAddShowPageContent', helper::FILTER_BOOLEAN)
],
'legend' => [],
'positions' => []
]]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config', // '#galleryAddForm'*/,
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
} else {
// Valeurs en sortie
$this->addOutput([
'title' => 'Ajout d\'une galerie',
'view' => 'add'
]);
}
}
/** /**
* Suppression * Suppression
*/ */
@ -510,11 +565,12 @@ class gallery extends common {
// pas de positions, on active le tri alpha // pas de positions, on active le tri alpha
'sort' => $this->getInput('galleryEditSort'), 'sort' => $this->getInput('galleryEditSort'),
'position' => $this->getData(['module', $this->getUrl(0), 'content', $galleryId,'config','position']), 'position' => $this->getData(['module', $this->getUrl(0), 'content', $galleryId,'config','position']),
'fullScreen' => $this->getInput('galleryEditFullscreen', helper::FILTER_BOOLEAN) 'fullScreen' => $this->getInput('galleryEditFullscreen', helper::FILTER_BOOLEAN),
'showPageContent' => $this->getInput('galleryEditShowPageContent', helper::FILTER_BOOLEAN)
], ],
'legend' => $legends, 'legend' => $legends,
'positions' => empty($oldPositions) ? $this->getdata(['module', $this->getUrl(0), 'content', $galleryId, 'positions']) : $oldPositions 'positions' => empty($oldPositions) ? $this->getData(['module', $this->getUrl(0), 'content', $galleryId, 'positions']) : $oldPositions
]]); ]]);
} }
// Valeurs en sortie // Valeurs en sortie
@ -528,7 +584,6 @@ class gallery extends common {
$directory = $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'directory']); $directory = $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'directory']);
if(is_dir($directory)) { if(is_dir($directory)) {
$iterator = new DirectoryIterator($directory); $iterator = new DirectoryIterator($directory);
foreach($iterator as $fileInfos) { foreach($iterator as $fileInfos) {
if($fileInfos->isDot() === false AND $fileInfos->isFile() AND @getimagesize($fileInfos->getPathname())) { if($fileInfos->isDot() === false AND $fileInfos->isFile() AND @getimagesize($fileInfos->getPathname())) {
// Créer la miniature RFM si manquante // Créer la miniature RFM si manquante
@ -538,7 +593,7 @@ class gallery extends common {
122); 122);
} }
self::$pictures[str_replace('.','',$fileInfos->getFilename())] = [ self::$pictures[str_replace('.','',$fileInfos->getFilename())] = [
template::ico('sort'), $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'positions', str_replace('.','',$fileInfos->getFilename())]) + 1,
$fileInfos->getFilename(), $fileInfos->getFilename(),
template::checkbox( 'homePicture[' . $fileInfos->getFilename() . ']', true, '', [ template::checkbox( 'homePicture[' . $fileInfos->getFilename() . ']', true, '', [
'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2),'config', 'homePicture']) === $fileInfos->getFilename() ? true : false, 'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2),'config', 'homePicture']) === $fileInfos->getFilename() ? true : false,
@ -555,7 +610,7 @@ class gallery extends common {
// Tri des images // Tri des images
switch ($this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'sort'])) { switch ($this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'sort'])) {
case self::SORT_HAND: case self::SORT_HAND:
$positions = $this->getdata(['module',$this->getUrl(0), $this->getUrl(2),'positions']); $positions = $this->getData(['module',$this->getUrl(0),'content', $this->getUrl(2),'positions']);
if ($positions) { if ($positions) {
foreach ($positions as $key => $value) { foreach ($positions as $key => $value) {
if (array_key_exists($key,self::$pictures)) { if (array_key_exists($key,self::$pictures)) {
@ -603,9 +658,10 @@ class gallery extends common {
// Mise à jour des données de module // Mise à jour des données de module
$this->update(); $this->update();
// Une seule galerie, bifurquer sur celle-ci // Une seule galerie, bifurquer sur celle-ci
$gallery = count($this->getData(['module', $this->getUrl(0), 'content'])) === 1 $gallery = $this->getData(['module', $this->getUrl(0), 'theme', 'showUniqueGallery']) === true &&
? array_key_first($this->getData(['module', $this->getUrl(0), 'content'])) count($this->getData(['module', $this->getUrl(0), 'content'])) === 1
: $this->getUrl(1); ? array_key_first($this->getData(['module', $this->getUrl(0), 'content']))
: $this->getUrl(1);
// Images d'une galerie // Images d'une galerie
if($gallery) { if($gallery) {
// La galerie n'existe pas // La galerie n'existe pas
@ -669,7 +725,8 @@ class gallery extends common {
'showBarEditButton' => true, 'showBarEditButton' => true,
'title' => $this->getData(['module', $this->getUrl(0), 'content', $gallery, 'config', 'name']), 'title' => $this->getData(['module', $this->getUrl(0), 'content', $gallery, 'config', 'name']),
'view' => 'gallery', 'view' => 'gallery',
'style' => $this->getData(['module', $this->getUrl(0), 'theme', 'style']) 'style' => $this->getData(['module', $this->getUrl(0), 'theme', 'style']),
'showPageContent' => $this->getData(['module', $this->getUrl(0), 'content', $gallery, 'config', 'showPageContent']),
]); ]);
} }
// Pas d'image dans la galerie // Pas d'image dans la galerie
@ -686,7 +743,7 @@ class gallery extends common {
else { else {
// Tri des galeries suivant l'ordre défini // Tri des galeries suivant l'ordre défini
$g = $this->getData(['module', $this->getUrl(0), 'content']); $g = $this->getData(['module', $this->getUrl(0), 'content']);
$p = helper::arrayCollumn(helper::arrayCollumn($g,'config'),'position'); $p = helper::arrayColumn(helper::arrayColumn($g,'config'),'position');
asort($p,SORT_NUMERIC); asort($p,SORT_NUMERIC);
$galleries = []; $galleries = [];
foreach ($p as $positionId => $item) { foreach ($p as $positionId => $item) {
@ -732,7 +789,9 @@ class gallery extends common {
'showBarEditButton' => true, 'showBarEditButton' => true,
'showPageContent' => true, 'showPageContent' => true,
'view' => 'index', 'view' => 'index',
'style' => $this->getData(['module', $this->getUrl(0), 'theme', 'style']) 'style' => file_exists($this->getData(['module', $this->getUrl(0), 'theme', 'style']))
? $this->getData(['module', $this->getUrl(0), 'theme', 'style'])
: ''
]); ]);
} }
} }
@ -770,7 +829,8 @@ class gallery extends common {
'legendAlign' => $this->getinput('galleryThemeLegendAlign', helper::FILTER_STRING_SHORT), 'legendAlign' => $this->getinput('galleryThemeLegendAlign', helper::FILTER_STRING_SHORT),
'legendTextColor' => $this->getinput('galleryThemeLegendTextColor', helper::FILTER_STRING_SHORT), 'legendTextColor' => $this->getinput('galleryThemeLegendTextColor', helper::FILTER_STRING_SHORT),
'legendBgColor' => $this->getinput('galleryThemeLegendBgColor', helper::FILTER_STRING_SHORT), 'legendBgColor' => $this->getinput('galleryThemeLegendBgColor', helper::FILTER_STRING_SHORT),
'style' => self::DATADIRECTORY . $this->getUrl(0) . '/theme.css' 'showUniqueGallery' => $this->getinput('galleryThemeShowUniqueGallery', helper::FILTER_BOOLEAN),
'style' => self::DATADIRECTORY . $this->getUrl(0) . '/theme.css',
]]); ]]);
// Création des fichiers CSS // Création des fichiers CSS
$content = file_get_contents('module/gallery/ressource/vartheme.css'); $content = file_get_contents('module/gallery/ressource/vartheme.css');
@ -808,6 +868,41 @@ class gallery extends common {
]); ]);
} }
/**
* Option de configuration de la galerie
*/
public function option() {
// Jeton incorrect
if ($this->getUrl(2) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config',
'notification' => 'Action non autorisée'
]);
}
// Soumission du formulaire
if($this->isPost()) {
// Dossier de l'instance
if (!is_dir(self::DATADIRECTORY . $this->getUrl(0) )) {
mkdir (self::DATADIRECTORY . $this->getUrl(0), 0755, true);
}
$this->setData(['module', $this->getUrl(0), 'config', [
'showUniqueGallery' => $this->getinput('galleriesOptionShowUniqueGallery', helper::FILTER_BOOLEAN)
]]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl() . '/option',
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => "Options",
'view' => 'option'
]);
}
} }
class galleriesHelper extends helper { class galleriesHelper extends helper {

View File

@ -0,0 +1,22 @@
Copyright (c) Denis Howlett <denish@isocra.com>
Copyright 2012 Nick Lombard - nickl- and other contributors
https://github.com/isocra/TableDnD
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1 +1,2 @@
https://github.com/isocra/TableDnD https://github.com/isocra/TableDnD
Version 1.0.5

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @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-2022, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -0,0 +1,87 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @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-2022, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.fr/
*/
$( document ).ready(function() {
/**
* Tri de la galerie avec drag and drop
*/
$("#galleryTable").tableDnD({
onDrop: function(table, row) {
$("#galleryAddFilterResponse").val($.tableDnD.serialize());
},
onDragStop : function(table, row) {
// Affiche le bouton de tri après un déplacement
//$(":input[type='submit']").prop('disabled', false);
// Sauvegarde le tri
sortGalleries();
},
// Supprime le tiret des séparateurs
serializeRegexp: ""
});
/**
* Confirmation de suppression
*/
$(".galleryAddDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette galerie ?", function() {
$(location).attr("href", _this.attr("href"));
});
});
});
/**
* Liste des dossiers
*/
var oldResult = [];
var directoryDOM = $("#galleryAddDirectory");
var directoryOldDOM = $("#galleryAddDirectoryOld");
function dirs() {
$.ajax({
type: "POST",
url: "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/dirs",
success: function(result) {
if($(result).not(oldResult).length !== 0 || $(oldResult).not(result).length !== 0) {
directoryDOM.empty();
for(var i = 0; i < result.length; i++) {
directoryDOM.append(function(i) {
var option = $("<option>").val(result[i]).text(result[i]);
if(directoryOldDOM.val() === result[i]) {
option.prop("selected", true);
}
return option;
}(i))
}
oldResult = result;
}
}
});
}
dirs();
// Actualise la liste des dossiers toutes les trois secondes
setInterval(function() {
dirs();
}, 3000);
/**
* Stock le dossier choisi pour le re-sélectionner en cas d'actualisation ajax de la liste des dossiers
*/
directoryDOM.on("change", function() {
directoryOldDOM.val($(this).val());
});

View File

@ -0,0 +1,68 @@
<?php echo template::formOpen('galleryAddForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('galleryAddBack', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config' ,
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('galleryAddSubmit', [
'ico' => 'plus',
'value' => ' Ajouter',
'class' => 'gallerySubmit'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Ajouter une galerie</h4>
<div class="row">
<div class="col6">
<?php echo template::text('galleryAddName', [
'label' => 'Nom'
]); ?>
</div>
<div class="col5">
<?php echo template::hidden('galleryAddDirectoryOld', [
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
<?php echo template::select('galleryAddDirectory', [], [
'label' => 'Dossier cible',
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::select('galleryAddSort', $module::$sort, [
'selected' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'sort']),
'label' => 'Tri des images',
'help' => 'Tri manuel : déplacez le images dans le tableau ci-dessous. L\'ordre est sauvegardé automatiquement.'
]); ?>
</div>
<div class="col7 verticalAlignBottom">
<div class="row">
<div class="col12">
<?php echo template::checkbox('galleryAddFullscreen', true, 'Mode plein écran automatique' , [
'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'fullScreen']),
'help' => 'A l\'ouverture de la galerie, la première image est affichée en plein écran.'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::checkbox('galleryAddShowPageContent', true, 'Afficher le contenu de la page avec la galerie' , [
'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'showPageContent']),
'help' => 'Le contenu de la page est toujours affiché dans la liste des galeries. Quand une seule galerie est disponible, il est possible de l\'afficher directement, cette option est utile dans ce cas précis.'
]); ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -17,73 +17,16 @@ $( document ).ready(function() {
/** /**
* Tri de la galerie avec drag and drop * Tri de la galerie avec drag and drop
*/ */
$("#galleryTable").tableDnD({ $("#galleryTable").tableDnD({
onDrop: function(table, row) { onDrop: function(table, row) {
$("#galleryConfigFilterResponse").val($.tableDnD.serialize()); $("#galleryConfigFilterResponse").val($.tableDnD.serialize());
},
onDragStop : function(table, row) {
// Affiche le bouton de tri après un déplacement
//$(":input[type='submit']").prop('disabled', false);
// Sauvegarde le tri
sortGalleries(); sortGalleries();
location.reload();
}, },
// Supprime le tiret des séparateurs // Supprime le tiret des séparateurs
serializeRegexp: "" serializeRegexp: ""
}); });
/**
* Confirmation de suppression
*/
$(".galleryConfigDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette galerie ?", function() {
$(location).attr("href", _this.attr("href"));
});
});
});
/**
* Liste des dossiers
*/
var oldResult = [];
var directoryDOM = $("#galleryConfigDirectory");
var directoryOldDOM = $("#galleryConfigDirectoryOld");
function dirs() {
$.ajax({
type: "POST",
url: "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/dirs",
success: function(result) {
if($(result).not(oldResult).length !== 0 || $(oldResult).not(result).length !== 0) {
directoryDOM.empty();
for(var i = 0; i < result.length; i++) {
directoryDOM.append(function(i) {
var option = $("<option>").val(result[i]).text(result[i]);
if(directoryOldDOM.val() === result[i]) {
option.prop("selected", true);
}
return option;
}(i))
}
oldResult = result;
}
}
});
}
dirs();
// Actualise la liste des dossiers toutes les trois secondes
setInterval(function() {
dirs();
}, 3000);
/**
* Stock le dossier choisi pour le re-sélectionner en cas d'actualisation ajax de la liste des dossiers
*/
directoryDOM.on("change", function() {
directoryOldDOM.val($(this).val());
}); });
@ -93,7 +36,7 @@ directoryDOM.on("change", function() {
function sortGalleries() { function sortGalleries() {
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/sortGalleries"; var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/sortGalleries";
var data = $("#galleryConfigFilterResponse").val(); var data = $("#galleryConfigFilterResponse").val();
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: url , url: url ,

View File

@ -1,61 +1,40 @@
<?php echo template::formOpen('galleryConfigForm'); ?> <?php echo template::formOpen('galleryConfigForm'); ?>
<div class="row"> <div class="row">
<div class="col2"> <div class="col2">
<?php echo template::button('galleryConfigBack', [ <?php echo template::button('galleryConfigBack', [
'class' => 'buttonGrey', 'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0), 'ico' => 'left',
'ico' => 'left', 'value' => 'Retour'
'value' => 'Retour' ]); ?>
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::button('galleryConfigBack', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/theme/' . $_SESSION['csrf'],
'value' => template::ico('brush','right') . 'Thème'
]); ?>
</div>
</div> </div>
<div class="row"> <div class="col1 offset7">
<div class="col12"> <?php echo template::button('galleryConfigOption', [
<div class="block"> 'href' => helper::baseUrl() . $this->getUrl(0) . '/option/' . $_SESSION['csrf'],
<h4>Ajouter une galerie</h4> 'value' => template::ico('sliders')
<div class="row"> ]); ?>
<div class="col6">
<?php echo template::text('galleryConfigName', [
'label' => 'Nom'
]); ?>
</div>
<div class="col5">
<?php echo template::hidden('galleryConfigDirectoryOld', [
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
<?php echo template::select('galleryConfigDirectory', [], [
'label' => 'Dossier cible',
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
</div>
<div class="col1 verticalAlignBottom">
<?php echo template::submit('galleryConfigSubmit', [
'ico' => '',
'value' => template::ico('plus'),
'class' => 'gallerySubmit'
]); ?>
</div>
</div>
</div>
</div>
</div> </div>
<div class="col1">
<?php echo template::button('galleryConfigTheme', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/theme/' . $_SESSION['csrf'],
'value' => template::ico('brush')
]); ?>
</div>
<div class="col1">
<?php echo template::button('galleryAdd', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/add/',
'value' => template::ico('plus')
]); ?>
</div>
</div>
<?php echo template::formClose(); ?> <?php echo template::formClose(); ?>
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <?php if($module::$galleries): ?>
<h4>Galeries installées</h4> <?php echo template::table([1, 4, 5, 1, 1], $module::$galleries, ['#','Nom', 'Dossier cible', '', ''], ['id' => 'galleryTable'],$module::$galleriesId); ?>
<?php if($module::$galleries): ?> <?php echo template::hidden('galleryConfigFilterResponse'); ?>
<?php echo template::table([1, 4, 5, 1, 1], $module::$galleries, ['','Nom', 'Dossier cible', '', ''], ['id' => 'galleryTable'],$module::$galleriesId); ?> <?php else: ?>
<?php echo template::hidden('galleryConfigFilterResponse'); ?> <?php echo template::speech('Aucune galerie.'); ?>
<?php else: ?> <?php endif; ?>
<?php echo template::speech('Aucune galerie.'); ?>
<?php endif; ?>
</div> </div>
<div class="moduleVersion">Version <div class="moduleVersion">Version
<?php echo $module::VERSION; ?> <?php echo $module::VERSION; ?>

View File

@ -51,7 +51,7 @@ directoryDOM.on("change", function() {
directoryOldDOM.val($(this).val()); directoryOldDOM.val($(this).val());
}); });
$('.homePicture').click(function(){ $('.homePicture').click(function(){
$('.homePicture').prop('checked', false); $('.homePicture').prop('checked', false);
$(this).prop('checked', true); $(this).prop('checked', true);
}); });
@ -62,14 +62,10 @@ $('.homePicture').click(function(){
$( document ).ready(function() { $( document ).ready(function() {
$("#galleryTable").tableDnD({ $("#galleryTable").tableDnD({
onDrop: function(table, row) { onDrop: function(table, row) {
$("#galleryEditFormResponse").val($.tableDnD.serialize()); $("#galleryEditFormResponse").val($.tableDnD.serialize());
},
onDragStop : function(table, row) {
// Sauvegarde le tri
sortPictures(); sortPictures();
$("#galleryEditFormResponse").val("");
}, },
serializeRegexp: "" serializeRegexp: ""
}); });
@ -103,16 +99,20 @@ $("#galleryEditSort").change(function() {
*/ */
function sortPictures() { function sortPictures() {
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/sortPictures"; var url = "<?php echo helper::baseUrl(true,true) . $this->getUrl(0); ?>/sortPictures";
var d1 = $("#galleryEditFormResponse").val(); var d1 = $("#galleryEditFormResponse").val();
var d2 = $("#galleryEditFormGalleryName").val(); var d2 = $("#galleryEditFormGalleryName").val();
//var data = $('#galleryEditForm').serialize();
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: url , url: url ,
data: { data: {
response : d1, response : d1,
gallery: d2 gallery: d2
} },/*
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
*/
}); });
} }

View File

@ -2,7 +2,6 @@
<div class="row"> <div class="row">
<div class="col2"> <div class="col2">
<?php echo template::button('galleryEditBack', [ <?php echo template::button('galleryEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config', 'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'ico' => 'left', 'ico' => 'left',
'value' => 'Retour' 'value' => 'Retour'
@ -15,55 +14,67 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4>Paramètre des images</h4> <h4>Paramètres de la galerie</h4>
<div class="row"> <div class="row">
<div class="col5"> <div class="col6">
<?php echo template::text('galleryEditName', [ <?php echo template::text('galleryEditName', [
'label' => 'Nom', 'label' => 'Nom',
'value' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'name']) 'value' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'name'])
]); ?> ]); ?>
</div>
<div class="col6">
<?php echo template::hidden('galleryEditDirectoryOld', [
'value' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'directory']),
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
<?php echo template::select('galleryEditDirectory', [], [
'label' => 'Dossier cible',
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
</div>
</div>
<div class="row">
<div class="col3">
<?php echo template::select('galleryEditSort', $module::$sort, [
'selected' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'sort']),
'label' => 'Tri des images',
'help' => 'Tri manuel : déplacez le images dans le tableau ci-dessous. L\'ordre est sauvegardé automatiquement.'
]); ?>
</div>
<div class="col7 verticalAlignBottom">
<div class="row">
<div class="col12">
<?php echo template::checkbox('galleryEditFullscreen', true, 'Mode plein écran automatique' , [
'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'fullScreen']),
'help' => 'A l\'ouverture de la galerie, la première image est affichée en plein écran.'
]); ?>
</div>
</div> </div>
<div class="col4"> <div class="row">
<?php echo template::hidden('galleryEditDirectoryOld', [ <div class="col12">
'value' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'directory']), <?php echo template::checkbox('galleryEditShowPageContent', true, 'Afficher le contenu de la page avec la galerie' , [
'noDirty' => true // Désactivé à cause des modifications en ajax 'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'showPageContent']),
]); ?> 'help' => 'Le contenu de la page est toujours affiché dans la liste des galeries. Quand une seule galerie est disponible, il est possible de l\'afficher directement, cette option est utile dans ce cas précis.'
<?php echo template::select('galleryEditDirectory', [], [ ]); ?>
'label' => 'Dossier cible', </div>
'noDirty' => true // Désactivé à cause des modifications en ajax </div>
]); ?>
</div>
<div class="col3">
<?php echo template::select('galleryEditSort', $module::$sort, [
'selected' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'sort']),
'label' => 'Tri des images',
'help' => 'Tri manuel : déplacez le images dans le tableau ci-dessous. L\'ordre est sauvegardé automatiquement.'
]); ?>
</div>
<div clas="row">
<div class="col12">
<?php echo template::checkbox('galleryEditFullscreen', true, 'Mode plein écran automatique' , [
'checked' => $this->getData(['module', $this->getUrl(0), 'content', $this->getUrl(2), 'config', 'fullScreen']),
'help' => 'A l\'ouverture de la galerie, la première image est affichée en plein écran.'
]); ?>
</div> </div>
</div> </div>
<div class="row"> </div>
<div class="col12"> <div class="row">
<?php if($module::$pictures): ?> <div class="col12">
<?php echo template::table([1, 4, 1, 5, 1], $module::$pictures, ['','Image', 'Couverture','Légende',''],['id' => 'galleryTable'], $module::$picturesId ); ?> <?php if($module::$pictures): ?>
<?php echo template::hidden('galleryEditFormResponse'); ?> <?php echo template::table([1, 4, 1, 5, 1], $module::$pictures, ['#','Image', 'Couverture','Légende',''],['id' => 'galleryTable'], $module::$picturesId ); ?>
<?php echo template::hidden('galleryEditFormGalleryName',['value' => $this->getUrl(2)]); ?> <?php echo template::hidden('galleryEditFormResponse'); ?>
<?php else: ?> <?php echo template::hidden('galleryEditFormGalleryName',['value' => $this->getUrl(2)]); ?>
<?php echo template::speech('Aucune image.'); ?> <?php else: ?>
<?php endif; ?> <?php echo template::speech('Aucune image.'); ?>
</div> <?php endif; ?>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="moduleVersion">Version
<div class="moduleVersion">Version <?php echo $module::VERSION; ?>
<?php echo $module::VERSION; ?> </div>
</div>
<?php echo template::formClose(); ?> <?php echo template::formClose(); ?>

View File

@ -16,7 +16,7 @@
* Galerie d'image * Galerie d'image
* SLB est activé pour tout le site * SLB est activé pour tout le site
*/ */
var b = new SimpleLightbox('.galleryGalleryPicture', { var b = new SimpleLightbox('.galleryGalleryPicture', {
captionSelector: "self", captionSelector: "self",
captionType: "data", captionType: "data",
captionsData: "caption", captionsData: "caption",
@ -24,7 +24,7 @@ var b = new SimpleLightbox('.galleryGalleryPicture', {
}); });
$( document ).ready(function() { $( document ).ready(function() {
// Démarre en mode plein écran // Démarre en mode plein écran
if ( $("#pictureContainer").hasClass("fullScreen") ) { if ( $("#pictureContainer").hasClass("fullScreen") ) {
$('a#homePicture')[0].click(); $('a#homePicture')[0].click();
} }

View File

@ -1,16 +1,3 @@
<?php if ( $module::$config['mono'] !== true): ?>
<div class="row">
<div class="col2">
<?php echo template::button('galleryGalleryBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0),
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
</div>
<?php endif; ?>
<div id="pictureContainer" class="row galleryRow <?php echo ($module::$config['fullScreen']);?> "> <div id="pictureContainer" class="row galleryRow <?php echo ($module::$config['fullScreen']);?> ">
<?php foreach($module::$pictures as $picture => $legend): ?> <?php foreach($module::$pictures as $picture => $legend): ?>
<div class="colPicture"> <div class="colPicture">
@ -27,4 +14,15 @@
</a> </a>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<?php if ( $module::$config['mono'] !== true): ?>
<div class="row">
<div class="col2">
<?php echo template::button('galleryGalleryBack', [
'href' => helper::baseUrl() . $this->getUrl(0),
'ico' => 'left',
'value' => ''
]); ?>
</div>
</div>
<?php endif; ?>

View File

@ -0,0 +1,39 @@
<?php echo template::formOpen('galleriesOptionForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('galleriesOptionBack', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('galleriesOptionSubmit'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Galerie unique</h4>
<div class="row">
<div class="col12 verticalAlignBottom">
<?php echo template::checkbox('galleriesOptionShowUniqueGallery', true, 'Masquer l\'index des galeries lorsque le module ne contient qu\'une galerie' , [
'checked' => count($this->getData(['module', $this->getUrl(0), 'content'])) === 1
? $this->getData(['module', $this->getUrl(0), 'theme', 'showUniqueGallery'])
: false,
'disabled' => count($this->getData(['module', $this->getUrl(0), 'content'])) > 1,
'help' => 'Cette option est active lorsque le module ne contient qu\'une seule galerie, elle permet d\'éviter la page listant toutes les galeries et affiche directement la galerie'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>
<div class="row">
<div class="col12">
<div class="moduleVersion">Version
<?php echo $module::VERSION; ?>
</div>
</div>
</div>

View File

@ -0,0 +1,18 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @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-2022, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -1,140 +1,137 @@
<?php echo template::formOpen('galleryThemeForm'); ?> <?php echo template::formOpen('galleryThemeForm'); ?>
<div class="row">
<div class="row"> <div class="col2">
<div class="col2"> <?php echo template::button('galleryThemeBack', [
<?php echo template::button('galleryThemeBack', [ 'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'class' => 'buttonGrey', 'ico' => 'left',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config', 'value' => 'Retour'
'ico' => 'left', ]); ?>
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('galleryThemeBack'); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Vignettes
<?php
echo template::help('Les paramètres du thème sont communs aux modules du même type.');
?>
</h4>
<div class="row">
<div class="col3">
<?php echo template::select('galleryThemeThumbWidth', $module::$galleryThemeSizeWidth, [
'label' => 'Largeur',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbWidth'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('galleryThemeThumbHeight', $module::$galleryThemeSizeHeight, [
'label' => 'Hauteur',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbHeight'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('galleryThemeThumbAlign', $module::$galleryThemeFlexAlign, [
'label' => 'Alignement',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbAlign'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('galleryThemeThumbMargin', $module::$galleryThemeMargin, [
'label' => 'Marge',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbMargin'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('galleryThemeThumbBorder', $module::$galleryThemeBorder, [
'label' => 'Bordure',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbBorder'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('galleryThemeThumbBorderColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de la bordure',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','thumbBorderColor'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('galleryThemeThumbRadius', $module::$galleryThemeRadius, [
'label' => 'Arrondi des angles',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbRadius'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('galleryThemeThumbShadows', $module::$galleryThemeShadows, [
'label' => 'Ombre',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbShadows'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('galleryThemeThumbShadowsColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de l\'ombre',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','thumbShadowsColor'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('galleryThemeThumbOpacity', $module::$galleryThemeOpacity, [
'label' => 'Opacité au survol',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbOpacity'])
]); ?>
</div>
</div>
</div>
</div>
</div> </div>
<div class="row"> <div class="col2 offset8">
<div class="col12"> <?php echo template::submit('galleryThemeBack'); ?>
<div class="block"> </div>
<h4>Légendes </div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Vignettes
<?php <?php
echo template::help('Les paramètres du thème sont communs aux modules du même type.'); echo template::help('Les paramètres du thème sont communs aux modules du même type.');
?> ?>
</h4> </h4>
<div class="row"> <div class="row">
<div class="col3"> <div class="col3">
<?php echo template::text('galleryThemeLegendTextColor', [ <?php echo template::select('galleryThemeThumbWidth', $module::$galleryThemeSizeWidth, [
'class' => 'colorPicker', 'label' => 'Largeur',
'help' => 'Le curseur horizontal règle le niveau de transparence.', 'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbWidth'])
'label' => 'Texte',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','legendTextColor'])
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col3">
<?php echo template::text('galleryThemeLegendBgColor', [ <?php echo template::select('galleryThemeThumbHeight', $module::$galleryThemeSizeHeight, [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Arrière-plan',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','legendBgColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('galleryThemeLegendHeight', $module::$galleryThemeLegendHeight, [
'label' => 'Hauteur', 'label' => 'Hauteur',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','legendHeight']) 'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbHeight'])
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col4">
<?php echo template::select('galleryThemeLegendAlign', $module::$galleryThemeAlign, [ <?php echo template::select('galleryThemeThumbAlign', $module::$galleryThemeFlexAlign, [
'label' => 'Alignement', 'label' => 'Alignement',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','legendAlign']) 'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbAlign'])
]); ?>
</div>
<div class="col2">
<?php echo template::select('galleryThemeThumbMargin', $module::$galleryThemeMargin, [
'label' => 'Marge',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbMargin'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('galleryThemeThumbBorder', $module::$galleryThemeBorder, [
'label' => 'Bordure',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbBorder'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('galleryThemeThumbBorderColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de la bordure',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','thumbBorderColor'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('galleryThemeThumbRadius', $module::$galleryThemeRadius, [
'label' => 'Arrondi des angles',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbRadius'])
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php echo template::select('galleryThemeThumbShadows', $module::$galleryThemeShadows, [
'label' => 'Ombre',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbShadows'])
]); ?>
</div>
<div class="col4">
<?php echo template::text('galleryThemeThumbShadowsColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur de l\'ombre',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','thumbShadowsColor'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('galleryThemeThumbOpacity', $module::$galleryThemeOpacity, [
'label' => 'Opacité au survol',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','thumbOpacity'])
]); ?> ]); ?>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Légendes
<?php
echo template::help('Les paramètres du thème sont communs aux modules du même type.');
?>
</h4>
<div class="row">
<div class="col3">
<?php echo template::text('galleryThemeLegendTextColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Texte',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','legendTextColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('galleryThemeLegendBgColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Arrière-plan',
'value' => $this->getData(['module', $this->getUrl(0), 'theme','legendBgColor'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('galleryThemeLegendHeight', $module::$galleryThemeLegendHeight, [
'label' => 'Hauteur',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','legendHeight'])
]); ?>
</div>
<div class="col3">
<?php echo template::select('galleryThemeLegendAlign', $module::$galleryThemeAlign, [
'label' => 'Alignement',
'selected' => $this->getData(['module', $this->getUrl(0), 'theme','legendAlign'])
]); ?>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?> <?php echo template::formClose(); ?>
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">

View File

@ -112,8 +112,8 @@ class news extends common {
$feeds->setDate(date('r',time())); $feeds->setDate(date('r',time()));
$feeds->addGenerator(); $feeds->addGenerator();
// Corps des articles // Corps des articles
$newsIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC'); $newsIdsPublishedOns = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC');
$newsIdsStates = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'state', 'SORT_DESC'); $newsIdsStates = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'state', 'SORT_DESC');
foreach($newsIdsPublishedOns as $newsId => $newsPublishedOn) { foreach($newsIdsPublishedOns as $newsId => $newsPublishedOn) {
if($newsPublishedOn <= time() AND $newsIdsStates[$newsId]) { if($newsPublishedOn <= time() AND $newsIdsStates[$newsId]) {
$newsArticle = $feeds->createNewItem(); $newsArticle = $feeds->createNewItem();
@ -164,7 +164,7 @@ class news extends common {
]); ]);
} }
// Liste des utilisateurs // Liste des utilisateurs
self::$users = helper::arrayCollumn($this->getData(['user']), 'firstname'); self::$users = helper::arrayColumn($this->getData(['user']), 'firstname');
ksort(self::$users); ksort(self::$users);
foreach(self::$users as $userId => &$userFirstname) { foreach(self::$users as $userId => &$userFirstname) {
$userFirstname = $userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']); $userFirstname = $userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']);
@ -234,7 +234,7 @@ class news extends common {
]); ]);
} else { } else {
// Ids des news par ordre de publication // Ids des news par ordre de publication
$newsIds = array_keys(helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC')); $newsIds = array_keys(helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC'));
// Pagination // Pagination
$pagination = helper::pagination($newsIds, $this->getUrl(),$this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage']) ); $pagination = helper::pagination($newsIds, $this->getUrl(),$this->getData(['module', $this->getUrl(0), 'config', 'itemsperPage']) );
// Liste des pages // Liste des pages
@ -367,7 +367,7 @@ class news extends common {
]); ]);
} }
// Liste des utilisateurs // Liste des utilisateurs
self::$users = helper::arrayCollumn($this->getData(['user']), 'firstname'); self::$users = helper::arrayColumn($this->getData(['user']), 'firstname');
ksort(self::$users); ksort(self::$users);
foreach(self::$users as $userId => &$userFirstname) { foreach(self::$users as $userId => &$userFirstname) {
$userFirstname = $userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']); $userFirstname = $userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']);
@ -420,8 +420,8 @@ class news extends common {
} else { } else {
// Affichage index // Affichage index
// Ids des news par ordre de publication // Ids des news par ordre de publication
$newsIdsPublishedOns = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC'); $newsIdsPublishedOns = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'publishedOn', 'SORT_DESC');
$newsIdsStates = helper::arrayCollumn($this->getData(['module', $this->getUrl(0), 'posts']), 'state', 'SORT_DESC'); $newsIdsStates = helper::arrayColumn($this->getData(['module', $this->getUrl(0), 'posts']), 'state', 'SORT_DESC');
$newsIds = []; $newsIds = [];
foreach($newsIdsPublishedOns as $newsId => $newsPublishedOn) { foreach($newsIdsPublishedOns as $newsId => $newsPublishedOn) {
$newsIdsPublishedOff = $this->getData(['module', $this->getUrl(0), 'posts', $newsId, 'publishedOff']); $newsIdsPublishedOff = $this->getData(['module', $this->getUrl(0), 'posts', $newsId, 'publishedOff']);