validation

This commit is contained in:
fredtempez 2019-01-13 17:40:46 +01:00
commit 263e0a11ee
102 changed files with 10743 additions and 15419 deletions

View File

@ -5,6 +5,15 @@
- Stockage distinct du thème et des autres données (core, config, page, module et users ) avec import des données d'une version 8
- Exporter un thème (avec les images) sous forme d'une archive ZIP à télécharger ou stocker dans Fichiers.
- Importer un thème à partir des fichiers
- Deux blocs (colonnes) à droite ou à gauche contenant des informations fixes, le paramétage est dans le thème, mais les contenus sont stockés dans les pages.
- Pas de bloc pour les écrans de configuration.
- Changement du libellé Modérateur devient Editeur
- Correction :
- Faille CSRF lors de l'effacement d'une page
- Faille CSRF lors de l'effacement d'une galerie
- Faille CSRF lors de l'effacement d'un article de blog
- Faille CSRF lors de l'effacement d'un article de news
- Faille CSRF lors de l'effacement d'un membre
## Verison 8.5.3
* Modification :
@ -12,12 +21,12 @@
* Correction :
- Appel de la génération de la capture d'écran OpenGraph quand le fichier est absent
- CSS pour le footer des blocs et non des éléments
- #footersite, #footerbody : bloc footer dans et hors site
- #footersite, #footerbody a : liens du bloc footer dans et hors site
- \#footersite, \#footerbody : bloc footer dans et hors site
- \#footersite, \#footerbody a : liens du bloc footer dans et hors site
- Bloc des colonnes dans et hors site :
- #footersiteLeft, #footerbodyLef
- #footersiteCenter, #footerbodyCenter
- #footersiteRight, #footerbodyRight
- \#footersiteLeft, \#footerbodyLef
- \#footersiteCenter, \#footerbodyCenter
- \#footersiteRight, \#footerbodyRight
## Verison 8.5.2

View File

@ -1,4 +1,4 @@
# Zwii 9 Béta
# Zwii 9 Bêta
Zwii est un CMS sans base de données (Flat-File) qui permet à ses utilisateurs de créer et gérer facilement un site web sans aucune connaissance en programmation.

View File

@ -176,6 +176,38 @@ class common {
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Contact'
],
'blockRight' => [
'typeMenu' => '',
'iconUrl' => '',
'disable' => false,
'content' => '<p>Bloc à droite du site</p>',
'hideTitle' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => '',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'blockRight'
],
'blockLeft' => [
'typeMenu' => '',
'iconUrl' => '',
'disable' => false,
'content' => '<p>Bloc à gauche du site</p>',
'hideTitle' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => '',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'blockLeft'
]
],
'module' => [
@ -349,7 +381,8 @@ class common {
'backgroundColor' => 'rgba(255, 255, 255, 1)',
'radius' => '0',
'shadow' => '0',
'width' => '1170px'
'width' => '960px',
'blocks' => '100'
],
'text' => [
'font' => 'Open+Sans',
@ -407,24 +440,24 @@ class common {
self::GROUP_BANNED => 'Banni',
self::GROUP_VISITOR => 'Visiteur',
self::GROUP_MEMBER => 'Membre',
self::GROUP_MODERATOR => 'Modérateur',
self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur'
];
public static $groupEdits = [
self::GROUP_BANNED => 'Banni',
self::GROUP_MEMBER => 'Membre',
self::GROUP_MODERATOR => 'Modérateur',
self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur'
];
public static $groupNews = [
self::GROUP_MEMBER => 'Membre',
self::GROUP_MODERATOR => 'Modérateur',
self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur'
];
public static $groupPublics = [
self::GROUP_VISITOR => 'Visiteur',
self::GROUP_MEMBER => 'Membre',
self::GROUP_MODERATOR => 'Modérateur',
self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur'
];
public static $timezone;
@ -994,7 +1027,7 @@ class common {
}
// Version 9.0.0
if($this->getData(['core', 'dataVersion']) < 900) {
$this->setData(['theme', 'site', 'blocks','100']);
$this->setData(['core', 'dataVersion', 900]);
$this->SaveData();
}
@ -1898,25 +1931,25 @@ class layout extends common {
echo $this->core->output['content'];
}
/**
* Affiche le coyright
*/
public function showCopyright() {
$items = '<div id="footerCopyright">';
$items .= 'Motorisé par <a href="http://zwiicms.com/" onclick="window.open(this.href);return false" title="Zwii CMS sans base de données, très léger et performant">Zwii</a>';
$items .= ' | <a href="' . helper::baseUrl() . 'sitemap" title="Plan du site" >Plan du site</a>';
if(
(
$this->getData(['theme', 'footer', 'loginLink'])
AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
)
OR $this->getUrl(0) === 'theme'
) {
$items .= '<span id="footerLoginLink" ' . ($this->getUrl(0) === 'theme' ? 'class="displayNone"' : '') . '> | <a href="' . helper::baseUrl() . 'user/login/' . str_replace('/', '_', $this->getUrl()) . '" title="Connexion à l\'administration" >Connexion</a></span>';
}
$items .= '</div>';
echo $items;
}
/**
* Affiche le copyright
*/
public function showCopyright() {
$items = '<div id="footerCopyright">';
$items .= 'Motorisé&nbsp;par&nbsp;<a href="http://zwiicms.com/" onclick="window.open(this.href);return false" title="Zwii CMS sans base de données, très léger et performant">Zwii</a>';
$items .= '&nbsp;|&nbsp;<a href="' . helper::baseUrl() . 'sitemap" title="Plan du site" >Plan&nbsp;du&nbsp;site</a>';
if(
(
$this->getData(['theme', 'footer', 'loginLink'])
AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
)
OR $this->getUrl(0) === 'theme'
) {
$items .= '<span id="footerLoginLink" ' . ($this->getUrl(0) === 'theme' ? 'class="displayNone"' : '') . '>&nbsp;|&nbsp;<a href="' . helper::baseUrl() . 'user/login/' . str_replace('/', '_', $this->getUrl()) . '" title="Connexion à l\'administration" >Connexion</a></span>';
}
$items .= '</div>';
echo $items;
}
/**
* Affiche le favicon
@ -1999,8 +2032,6 @@ class layout extends common {
$targetBlank = $this->getData(['page', $childKey, 'targetBlank']) ? ' target="_blank"' : '';
// Mise en page du sous-item
// Menu Image
if ( $this->getData(['page',$childKey,'disable']) === true
AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') )
@ -2131,13 +2162,17 @@ class layout extends common {
if($this->getUser('group') >= self::GROUP_MODERATOR) {
$leftItems .= '<li><select id="barSelectPage">';
$leftItems .= '<option value="">Choisissez une page</option>';
$currentPageId = $this->getData(['page', $this->getUrl(0)]) ? $this->getUrl(0) : $this->getUrl(2);
$currentPageId = $this->getData(['page', $this->getUrl(0)]) ? $this->getUrl(0) : $this->getUrl(2);
foreach($this->getHierarchy(null, false) as $parentPageId => $childrenPageIds) {
if ($parentPageId === 'blockLeft'
OR $parentPageId === 'blockRight') { continue; }
$leftItems .= '<option value="' . helper::baseUrl() . $parentPageId . '"' . ($parentPageId === $currentPageId ? ' selected' : false) . '>' . $this->getData(['page', $parentPageId, 'title']) . '</option>';
foreach($childrenPageIds as $childKey) {
$leftItems .= '<option value="' . helper::baseUrl() . $childKey . '"' . ($childKey === $currentPageId ? ' selected' : false) . '>&nbsp;&nbsp;&nbsp;&nbsp;' . $this->getData(['page', $childKey, 'title']) . '</option>';
}
}
$leftItems .= '<option value="">-------------------</option>';
$leftItems .= '<option value="' . helper::baseUrl() . 'page/block">&Eacute;dition des blocs</option>';
$leftItems .= '</select></li>';
$leftItems .= '<li><a href="' . helper::baseUrl() . 'page/add" title="Créer une page">' . template::ico('plus') . '</a></li>';
if(

View File

@ -423,6 +423,15 @@ footer .col4 {
footer #footerSocials {
font-size: 1.0em;
}
footer #footerSocials {
font-size: 1.0em;
}
footer #footerCopyright, #footerText {
font-size: 0.8em;
}
footer #footerSocials span {
color: #FFF;
padding: 9px;

View File

@ -33,11 +33,9 @@
<?php if($this->getData(['theme', 'header', 'position']) === 'body'): ?>
<!-- Bannière dans le fond du site -->
<!-- menu image -->
<?php
if ($this->getData(['theme','header','linkHome'])){
echo "<a href='" . helper::baseUrl(false) . "'>" ;} ?>
<!-- menu image -->
<header>
<?php if(
@ -45,22 +43,16 @@
// Affiche toujours le titre de la bannière pour l'édition du thème
OR ($this->getUrl(0) === 'theme' AND $this->getUrl(1) === 'header')
): ?>
<div class="container">
<span><?php echo $this->getData(['config', 'title']); ?></span>
</div>
<?php endif; ?>
</header>
<!-- menu image -->
</header>
<?php
if ($this->getData(['theme','header','linkHome'])){echo "</a>";}
?>
<!-- menu image -->
?>
<?php endif; ?>
<?php if($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?>
<!-- Menu dans le fond du site après la bannière -->
<nav>
@ -90,12 +82,9 @@
)
): ?>
<!-- Bannière dans le site -->
<!-- menu image -->
<?php
if ($this->getData(['theme','header','linkHome'])){
echo "<a href='" . helper::baseUrl(false) . "'>" ;} ?>
<!-- menu image -->
<header <?php if($this->getData(['theme', 'header', 'position']) === 'hide'): ?>class="displayNone"<?php endif; ?>>
<?php if(
$this->getData(['theme', 'header', 'textHide']) === false
@ -126,8 +115,49 @@
</div>
</nav>
<?php endif; ?>
<!-- Corps -->
<section><?php $layout->showContent(); ?></section>
<?php
// Multi colonne uniquement pour les pages du site hors config, theme etc..
if (
$this->getUrl(0) === 'user' OR
$this->getUrl(0) === 'theme' OR
$this->getUrl(0) === 'config' OR
$this->getUrl(0) === 'page' OR
$this->getUrl(1) === 'config' OR
$this->getUrl(1) === 'edit'
) { ?>
<section><?php $layout->showContent(); ?></section>
<?php } else {
// multi-colonnes
$blocks = explode('-',$this->getData(['theme','site','blocks']));
$blockleft=$blockright="";
switch (sizeof($blocks)) {
case 1 : // une colonne
$content = 'col'. $blocks[0] ;
break;
case 2 : // 2 blocks
if ($blocks[0] < $blocks[1]) { // détermine la position de la colonne
$blockleft = 'col'. $blocks[0];
$content = 'col'. $blocks[1] ;
} else {
$content = 'col' . $blocks[0];
$blockright = 'col' . $blocks[1];
}
break;
case 3 : // 3 blocks
$blockleft = 'col' . $blocks[0];
$content = 'col' . $blocks[1];
$blockright = 'col' . $blocks[2];
}
?>
<section>
<div class="row">
<?php if ($blockleft !== "") :?> <div class="<?php echo $blockleft; ?>" id="contentleft"><?php echo $this->getData(['page','blockLeft','content']);?></div> <?php endif; ?>
<div class="<?php echo $content; ?>" id="contentsite"><?php $layout->showContent(); ?></div>
<?php if ($blockright !== "") :?> <div class="<?php echo $blockright; ?>" id="contentright"><?php echo $this->getData(['page','blockRight','content']);?></div> <?php endif; ?>
</div>
</section>
<?php } ?>
<!-- footer -->
<?php if(
$this->getData(['theme', 'footer', 'position']) === 'site'
// Affiche toujours le pied de page pour l'édition du thème

View File

@ -17,26 +17,26 @@ class page extends common {
public static $actions = [
'add' => self::GROUP_MODERATOR,
'delete' => self::GROUP_MODERATOR,
'edit' => self::GROUP_MODERATOR
'edit' => self::GROUP_MODERATOR,
'block' => self::GROUP_ADMIN
];
public static $pagesNoParentId = [
'' => 'Aucune'
];
public static $moduleIds = [];
// Menu image
public static $typeMenu = [
'text' => 'Texte',
'icon' => 'Icône',
'icontitle' => 'Icône et bulle'
];
// menu image
// Position du module
public static $modulePosition = [
'bottom' => 'En bas',
'top' => 'En haut',
'free' => 'Libre'
'bottom' => 'En bas',
'top' => 'En haut',
'free' => 'Libre'
];
/**
* Création
*/
@ -46,12 +46,10 @@ class page extends common {
$this->setData([
'page',
$pageId,
[
// Menu icon
[
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
// Menu icon
'disable' => false,
'content' => 'Contenu de votre nouvelle page.',
'hideTitle' => false,
'metaDescription' => '',
@ -77,33 +75,50 @@ class page extends common {
* Suppression
*/
public function delete() {
// $url prend l'adresse sans le token
$url = explode('&',$this->getUrl(2));
// La page n'existe pas
if($this->getData(['page', $this->getUrl(2)]) === null) {
if($this->getData(['page', $url[0]]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Impossible de supprimer la page d'accueil
elseif($this->getUrl(2) === $this->getData(['config', 'homePageId'])) {
elseif($url[0] === $this->getData(['config', 'homePageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Impossible de supprimer la page d\'accueil'
]);
}
// Impossible de supprimer une page contenant des enfants
elseif($this->getHierarchy($this->getUrl(2))) {
// Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Suppression non autorisée'
]);
}
// Impossible de supprimer une page contenant des enfants
elseif($this->getHierarchy($url[0])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Impossible de supprimer une page contenant des enfants'
]);
}
// Suppression
else {
$this->deleteData(['page', $this->getUrl(2)]);
$this->deleteData(['module', $this->getUrl(2)]);
$this->deleteData(['page', $url[0]]);
$this->deleteData(['module', $url[0]]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
@ -113,6 +128,65 @@ class page extends common {
}
}
/**
* Édition des blocs
*/
public function block () {
if($this->isPost()) {
$this->setData([
'page',
'blockLeft', [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => true,
'hideTitle' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'blockLeft',
'content' => (empty($this->getInput('pageBlockLeftContent', null)) ? "<p></p>" : $this->getInput('pageBlockLeftContent', null))]
]);
$this->setData([
'page',
'blockRight', [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => true,
'hideTitle' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'blockRight',
'content' => (empty($this->getInput('pageBlockRightContent', null)) ? "<p></p>" : $this->getInput('pageBlockRightContent', null))]
]);
$this->addOutput([
'redirect' => helper::baseUrl(),
'notification' => 'Modifications enregistrées',
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => 'Édition des blocs',
'vendor' => [
'tinymce'
],
'view' => 'block'
]);
}
/**
* Édition
*/

View File

@ -0,0 +1,102 @@
/**
* 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
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
*/
/**
* Confirmation de suppression
*/
$("#pageEditDelete").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette page ?", function() {
$(location).attr("href", _this.attr("href"));
});
});
/**
* Bloque/Débloque le bouton de configuration au changement de module
*/
var pageEditModuleIdDOM = $("#pageEditModuleId");
pageEditModuleIdDOM.on("change", function() {
if($(this).val() === "") {
$("#pageEditModuleConfig").addClass("disabled");
$("#pageEditContentContainer").slideDown();
}
else {
$("#pageEditModuleConfig").removeClass("disabled");
$("#pageEditContentContainer").slideUp();
}
});
/**
* Soumission du formulaire pour éditer le module
*/
$("#pageEditModuleConfig").on("click", function() {
$("#pageEditModuleRedirect").val(1);
$("#pageEditForm").trigger("submit");
});
/**
* Affiche les pages en fonction de la page parent dans le choix de la position
*/
var hierarchy = <?php echo json_encode($this->getHierarchy()); ?>;
var pages = <?php echo json_encode($this->getData(['page'])); ?>;
$("#pageEditParentPageId").on("change", function() {
var positionDOM = $("#pageEditPosition");
positionDOM.empty().append(
$("<option>").val(0).text("Ne pas afficher"),
$("<option>").val(1).text("Au début")
);
var parentSelected = $(this).val();
var positionSelected = 0;
var positionPrevious = 1;
// Aucune page parent selectionnée
if(parentSelected === "") {
// Liste des pages sans parents
for(var key in hierarchy) {
if(hierarchy.hasOwnProperty(key)) {
// Sélectionne la page avant si il s'agit de la page courante
if(key === "<?php echo $this->getUrl(2); ?>") {
positionSelected = positionPrevious;
}
// Sinon ajoute la page à la liste
else {
// Enregistre la position de cette page afin de la sélectionner si la prochaine page de la liste est la page courante
positionPrevious++;
// Ajout à la liste
positionDOM.append(
$("<option>").val(positionPrevious).text("Après \"" + pages[key].title + "\"")
);
}
}
}
}
// Un page parent est selectionnée
else {
// Liste des pages enfants de la page parent
for(var i = 0; i < hierarchy[parentSelected].length; i++) {
// Pour page courante sélectionne la page précédente (pas de - 1 à positionSelected à cause des options par défaut)
if(hierarchy[parentSelected][i] === "<?php echo $this->getUrl(2); ?>") {
positionSelected = positionPrevious;
}
// Sinon ajoute la page à la liste
else {
// Enregistre la position de cette page afin de la sélectionner si la prochaine page de la liste est la page courante
positionPrevious++;
// Ajout à la liste
positionDOM.append(
$("<option>").val(positionPrevious).text("Après \"" + pages[hierarchy[parentSelected][i]].title + "\"")
);
}
}
}
// Sélectionne la bonne position
positionDOM.val(positionSelected);
}).trigger("change");

View File

@ -0,0 +1,33 @@
<?php echo template::formOpen('pageblockEditForm'); ?>
<div class="row">
<div class="col2">
<?php $href = helper::baseUrl() . $this->getUrl(2); ?>
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection')$href = helper::baseUrl(); ?>
<?php echo template::button('pageblockEditBack', [
'class' => 'buttonGrey',
'href' => $href,
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('pageblockEditSubmit'); ?>
</div>
</div>
<div class='row'>
<div class="col6">
<?php echo template::textarea('pageBlockLeftContent', [
'label' => 'Contenu du bloc à gauche :',
'class' => 'editorWysiwyg',
'value' => $this->getData(['page','blockLeft', 'content'])
]); ?>
</div>
<div class="col6">
<?php echo template::textarea('pageBlockRightContent', [
'label' => 'Contenu du bloc à droite :',
'class' => 'editorWysiwyg',
'value' => $this->getData(['page','blockRight', 'content'])
]); ?>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -13,7 +13,7 @@
<div class="col2 offset6">
<?php echo template::button('pageEditDelete', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2),
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
'value' => 'Supprimer',
'ico' => 'cancel'
]); ?>
@ -55,8 +55,7 @@
</div>
</div>
<div class="row">
<div class="col6">
<div class="col6">
<?php echo template::select('pageTypeMenu', $module::$typeMenu,[
'help' => 'Sélectionnez le type de menu.',
'label' => 'Type de menu',
@ -64,7 +63,6 @@
]); ?>
</div>
<div class="col6">
<?php echo template::file('pageIconUrl', [
'label' => 'Icône',
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])

View File

@ -15,6 +15,14 @@ body {
#site {
}
/* Blocs dans le site */
#contentleft {
}
#contentright {
}
#contentsite {
}
/* Bannière */
header {
}
@ -40,23 +48,26 @@ nav a.active {
}
/* Bas de page */
#footersite, #footerbody {
footer {
}
footer #footersite, #footerbody {
}
/* Liens du bas de page */
#footersite, #footerbody a {
footer #footersite, #footerbody a {
}
/* footer bloc gauche */
#footersiteLeft, #footerbodyLeft {
footer #footersiteLeft, #footerbodyLeft {
}
/* footer bloc central */
#footersiteCenter, #footerbodyCenter {
footer #footersiteCenter, #footerbodyCenter {
}
/* footer bloc droite */
#footersiteRight, #footerbodyRight {
footer #footersiteRight, #footerbodyRight {
}
/**

View File

@ -201,9 +201,18 @@ class theme extends common {
'contain' => 'Image entière',
'cover' => 'Largeur adaptée au fond',
'100% 100%' => 'Taille adaptée au fond'
];
public static $siteBlocks = [
'12' => 'Un seul bloc, uniquement le site',
'4-8' => 'Deux blocs : 1/3 - 2/3',
'8-4' => 'Deux blocs : 2/3 - 1/3',
'3-9' => 'Deux blocs : 1/4 - 3/4',
'9-3' => 'Deux blocs : 3/4 - 1/2',
'3-6-3' => 'Trois blocs : 1/4 - 1/2 - 1/4'
];
/**
* Mode avancé
*/
@ -424,7 +433,8 @@ class theme extends common {
'backgroundColor' => $this->getInput('themeSiteBackgroundColor'),
'radius' => $this->getInput('themeSiteRadius'),
'shadow' => $this->getInput('themeSiteShadow'),
'width' => $this->getInput('themeSiteWidth')
'width' => $this->getInput('themeSiteWidth'),
'blocks' => $this->getInput('themeSiteBlocks')
]]);
// Valeurs en sortie
$this->addOutput([
@ -437,7 +447,8 @@ class theme extends common {
$this->addOutput([
'title' => 'Personnalisation du site',
'vendor' => [
'tinycolorpicker'
'tinycolorpicker',
'tinymce'
],
'view' => 'site'
]);

View File

@ -5,7 +5,7 @@
): ?>
<?php echo template::speech('Cliquez sur une zone afin d\'accéder à ses options de personnalisation. Vous pouvez également afficher les zones cachées à l\'aide du bouton ci-dessous.'); ?>
<div class="row">
<div class="col3">
<div class="col2 offset2">
<?php echo template::button('themeBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
@ -13,21 +13,21 @@
'value' => 'Accueil'
]); ?>
</div>
<div class="col3">
<div class="col2">
<?php echo template::button('themeManage', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
'ico' => 'download',
'value' => 'Gestion des thèmes'
]); ?>
</div>
<div class="col3">
<div class="col2">
<?php echo template::button('themeAdvanced', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/advanced',
'value' => 'Mode avancé',
'ico' => 'code'
]); ?>
</div>
<div class="col3">
<div class="col2">
<?php echo template::button('themeShowAll', [
'ico' => 'eye',
'value' => 'Zones cachées'
@ -37,7 +37,7 @@
<?php else: ?>
<?php echo template::speech('Cliquez sur une zone afin d\'accéder à ses options de personnalisation.'); ?>
<div class="row">
<div class="col3 offset2">
<div class="col2 offset3">
<?php echo template::button('themeBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
@ -45,14 +45,14 @@
'value' => 'Accueil'
]); ?>
</div>
<div class="col3">
<div class="col2">
<?php echo template::button('themeManage', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/manage',
'ico' => 'download',
'value' => 'Gestion des thèmes'
]); ?>
</div>
<div class="col3">
<div class="col2">
<?php echo template::button('themeAdvanced', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/advanced',
'value' => 'Mode avancé',

View File

@ -40,7 +40,7 @@
</div>
</div>
<div class="row">
<div class="col4">
<div class="col4 offset2">
<?php echo template::text('themeButtonBackgroundColor', [
'class' => 'colorPicker',
'label' => 'Boutons',
@ -82,6 +82,15 @@
]); ?>
</div>
</div>
<div class='row'>
<div class="col4 offset4">
<?php echo template::select('themeSiteBlocks', $module::$siteBlocks, [
'label' => 'Répartition des blocs :',
'help' => 'Pour éditer le contenu des blocs, sélectionnez \'Édition des blocs\' dans la liste des pages.',
'selected' => $this->getData(['theme', 'site', 'blocks'])
]); ?>
</div>
</div>
</div>
</div>
</div>

View File

@ -88,10 +88,13 @@ class user extends common {
* Suppression
*/
public function delete() {
//
// $url prend l'adresse sans le token
$url = explode('&',$this->getUrl(2));
// Accès refusé
if(
// L'utilisateur n'existe pas
$this->getData(['user', $this->getUrl(2)]) === null
$this->getData(['user', $url[0]]) === null
// Groupe insuffisant
AND ($this->getUrl('group') < self::GROUP_MODERATOR)
) {
@ -100,8 +103,23 @@ class user extends common {
'access' => false
]);
}
// Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => 'Suppression non autorisée'
]);
}
// Bloque la suppression de son propre compte
elseif($this->getUser('id') === $this->getUrl(2)) {
elseif($this->getUser('id') === $url[0]) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
@ -110,7 +128,7 @@ class user extends common {
}
// Suppression
else {
$this->deleteData(['user', $this->getUrl(2)]);
$this->deleteData(['user', $url[0]]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
@ -280,7 +298,7 @@ class user extends common {
]),
template::button('userDelete' . $userId, [
'class' => 'userDelete buttonRed',
'href' => helper::baseUrl() . 'user/delete/' . $userId,
'href' => helper::baseUrl() . 'user/delete/' . $userId. '&csrf=' . $_SESSION['csrf'],
'value' => template::ico('cancel')
])
];

View File

@ -43,7 +43,7 @@
<li>Accès aux pages privées membres</li>
</ul>
<ul id="userAddGroupDescription<?php echo self::GROUP_MODERATOR; ?>" class="userAddGroupDescription displayNone">
<li>Accès aux pages privées membres et modérateurs</li>
<li>Accès aux pages privées membres et éditeurs</li>
<li>Ajout / Édition / Suppression de pages</li>
<li>Ajout / Édition / Suppression de fichiers</li>
</ul>

View File

@ -58,7 +58,7 @@
<li>Accès aux pages privées membres</li>
</ul>
<ul id="userEditGroupDescription<?php echo self::GROUP_MODERATOR; ?>" class="userEditGroupDescription displayNone">
<li>Accès aux pages privées membres et modérateurs</li>
<li>Accès aux pages privées membres et éditeurs</li>
<li>Ajout / Édition / Suppression de pages</li>
<li>Ajout / Édition / Suppression de fichiers</li>
</ul>

View File

@ -380,6 +380,10 @@ class UploadHandler
$file->error = $this->get_error_message('accept_file_types');
return false;
}
if (preg_match($this->options['image_file_types'], $file->name) && function_exists('exif_imagetype') && !@exif_imagetype($uploaded_file)) {
$file->error = $this->get_error_message('accept_file_types');
return false;
}
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
$file_size = $this->get_file_size($uploaded_file);
} else {
@ -519,7 +523,7 @@ class UploadHandler
// Remove path information and dots around the filename, to prevent uploading
// into different directories or replacing hidden system files.
// Also remove control characters and spaces (\x00..\x20) around the filename:
$name = trim($this->basename(stripslashes($name)), ".\x00..\x20");
$name = trim($this->basename(stripslashes($name)), "\x00..\x20");
// Use a timestamp for empty filenames:
if (!$name) {
$name = str_replace('.', '-', microtime(true));
@ -1330,6 +1334,11 @@ class UploadHandler
'',
$content_disposition_header
)) : null;
// TODO check
// if (isset($content_disposition_header) && !empty($content_disposition_header) ) {
// $file_name = str_replace('attachment; filename=&#34;', '', $content_disposition_header);
// $file_name = str_replace('&#34;', '', $file_name);
// }
// Parse the Content-Range header, which has the following form:
// Content-Range: bytes 0-524287/2000000
$content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE');

View File

@ -1,8 +1,6 @@
<?php
$config = include 'config/config.php';
//TODO switch to array
extract($config, EXTR_OVERWRITE);
require_once 'include/utils.php';
@ -25,6 +23,21 @@ if (isset($_SESSION['RF']['language']) && file_exists('lang/' . basename($_SESSI
response(trans('Lang_Not_Found').AddErrorLocation())->send();
exit;
}
//check $_GET['file']
if(isset($_GET['file']) && !checkRelativePath($_GET['file'])) {
response(trans('wrong path').AddErrorLocation())->send();
exit;
}
//check $_POST['file']
if(isset($_POST['path']) && !checkRelativePath($_POST['path'])) {
response(trans('wrong path').AddErrorLocation())->send();
exit;
}
$ftp = ftp_con($config);
if(isset($_GET['action']))
@ -52,7 +65,7 @@ if(isset($_GET['action']))
case 'filter':
if (isset($_GET['type']))
{
if (isset($remember_text_filter) && $remember_text_filter)
if (isset($config['remember_text_filter']) && $config['remember_text_filter'])
{
$_SESSION['RF']["filter"] = $_GET['type'];
}
@ -73,24 +86,10 @@ if(isset($_GET['action']))
$_SESSION['RF']["descending"] = $_GET['descending'];
}
break;
case 'image_size': // not used
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false)
{
$info = getimagesize(substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir)));
response($info)->send();
exit;
}
break;
case 'save_img':
$info = pathinfo($_POST['name']);
if (
strpos($_POST['path'], '/') === 0
|| strpos($_POST['path'], '../') !== false
|| strpos($_POST['path'], '..\\') !== false
|| strpos($_POST['path'], './') === 0
|| (strpos($_POST['url'], 'http://s3.amazonaws.com/feather') !== 0 && strpos($_POST['url'], 'https://s3.amazonaws.com/feather') !== 0)
if ((strpos($_POST['url'], 'http://s3.amazonaws.com/feather') !== 0 && strpos($_POST['url'], 'https://s3.amazonaws.com/feather') !== 0)
|| $_POST['name'] != fix_filename($_POST['name'], $config)
|| ! in_array(strtolower($info['extension']), array( 'jpg', 'jpeg', 'png' ))
)
@ -106,7 +105,7 @@ if(isset($_GET['action']))
}
if (!checkresultingsize(strlen($image_data))) {
response(sprintf(trans('max_size_reached'),$MaxSizeTotal).AddErrorLocation())->send();
response(sprintf(trans('max_size_reached'),$config['MaxSizeTotal']).AddErrorLocation())->send();
exit;
}
if($ftp){
@ -116,42 +115,36 @@ if(isset($_GET['action']))
$temp .=".".substr(strrchr($_POST['url'],'.'),1);
file_put_contents($temp,$image_data);
$ftp->put($ftp_base_folder.$upload_dir . $_POST['path'] . $_POST['name'], $temp, FTP_BINARY);
$ftp->put($config['ftp_base_folder'].$config['upload_dir'] . $_POST['path'] . $_POST['name'], $temp, FTP_BINARY);
create_img($temp,$temp,122,91);
$ftp->put($ftp_base_folder.$ftp_thumbs_dir. $_POST['path'] . $_POST['name'], $temp, FTP_BINARY);
$ftp->put($config['ftp_base_folder'].$config['ftp_thumbs_dir']. $_POST['path'] . $_POST['name'], $temp, FTP_BINARY);
unlink($temp);
}else{
file_put_contents($current_path . $_POST['path'] . $_POST['name'],$image_data);
create_img($current_path . $_POST['path'] . $_POST['name'], $thumbs_base_path.$_POST['path'].$_POST['name'], 122, 91);
file_put_contents($config['current_path'] . $_POST['path'] . $_POST['name'],$image_data);
create_img($config['current_path'] . $_POST['path'] . $_POST['name'], $config['thumbs_base_path'].$_POST['path'].$_POST['name'], 122, 91);
// TODO something with this function cause its blowing my mind
new_thumbnails_creation(
$current_path.$_POST['path'],
$current_path.$_POST['path'].$_POST['name'],
$config['current_path'].$_POST['path'],
$config['current_path'].$_POST['path'].$_POST['name'],
$_POST['name'],
$current_path,
$config['current_path'],
$config
);
}
break;
case 'extract':
if ( strpos($_POST['path'], '/') === 0
|| strpos($_POST['path'], '../') !== false
|| strpos($_POST['path'], '..\\') !== false
|| strpos($_POST['path'], './') === 0)
{
response(trans('wrong path'.AddErrorLocation()))->send();
exit;
if(!$config['extract_files']){
response(trans('wrong action').AddErrorLocation())->send();
}
if($ftp){
$path = $ftp_base_url.$upload_dir . $_POST['path'];
$base_folder = $ftp_base_url.$upload_dir . fix_dirname($_POST['path']) . "/";
$path = $config['ftp_base_url'].$config['upload_dir'] . $_POST['path'];
$base_folder = $config['ftp_base_url'].$config['upload_dir'] . fix_dirname($_POST['path']) . "/";
}else{
$path = $current_path . $_POST['path'];
$base_folder = $current_path . fix_dirname($_POST['path']) . "/";
$path = $config['current_path'] . $_POST['path'];
$base_folder = $config['current_path'] . fix_dirname($_POST['path']) . "/";
}
$info = pathinfo($path);
@ -184,32 +177,28 @@ if(isset($_GET['action']))
$sizeTotalFinal += $aStat['size'];
}
if (!checkresultingsize($sizeTotalFinal)) {
response(sprintf(trans('max_size_reached'),$MaxSizeTotal).AddErrorLocation())->send();
response(sprintf(trans('max_size_reached'),$config['MaxSizeTotal']).AddErrorLocation())->send();
exit;
}
//make all the folders
//make all the folders and unzip into the folders
for ($i = 0; $i < $zip->numFiles; $i++)
{
$OnlyFileName = $zip->getNameIndex($i);
$FullFileName = $zip->statIndex($i);
if (substr($FullFileName['name'], -1, 1) == "/")
{
create_folder($base_folder . $FullFileName['name']);
}
}
//unzip into the folders
for ($i = 0; $i < $zip->numFiles; $i++)
{
$OnlyFileName = $zip->getNameIndex($i);
$FullFileName = $zip->statIndex($i);
if ( ! (substr($FullFileName['name'], -1, 1) == "/"))
{
$fileinfo = pathinfo($OnlyFileName);
if (in_array(strtolower($fileinfo['extension']), $ext))
if(checkRelativePath($FullFileName['name'])){
if (substr($FullFileName['name'], -1, 1) == "/")
{
copy('zip://' . $path . '#' . $OnlyFileName, $base_folder . $FullFileName['name']);
create_folder($base_folder . $FullFileName['name']);
}
if ( ! (substr($FullFileName['name'], -1, 1) == "/"))
{
$fileinfo = pathinfo($FullFileName['name']);
if (in_array(strtolower($fileinfo['extension']), $config['ext']))
{
copy('zip://' . $path . '#' . $FullFileName['name'], $base_folder . $FullFileName['name']);
}
}
}
}
@ -234,7 +223,7 @@ if(isset($_GET['action']))
$phar = new PharData($path);
$phar->decompressFiles();
$files = array();
check_files_extensions_on_phar($phar, $files, '', $ext);
check_files_extensions_on_phar($phar, $files, '', $config);
$phar->extractTo($base_folder, $files, true);
break;
@ -246,22 +235,28 @@ if(isset($_GET['action']))
if($ftp){
unlink($path);
$ftp->putAll($base_folder, "/".$ftp_base_folder . $upload_dir . fix_dirname($_POST['path']), FTP_BINARY);
$ftp->putAll($base_folder, "/".$config['ftp_base_folder'] . $config['upload_dir'] . fix_dirname($_POST['path']), FTP_BINARY);
deleteDir($base_folder);
}
break;
case 'media_preview':
if(isset($_GET['file'])){
$_GET['file'] = sanitize($_GET['file']);
}
if(isset($_GET['title'])){
$_GET['title'] = sanitize($_GET['title']);
}
if($ftp){
$preview_file = $ftp_base_url.$upload_dir . $_GET['file'];
$preview_file = $config['ftp_base_url'].$config['upload_dir'] . $_GET['file'];
}else{
$preview_file = $current_path . $_GET["file"];
$preview_file = $config['current_path'] . $_GET["file"];
}
$info = pathinfo($preview_file);
ob_start();
?>
<div id="jp_container_1" class="jp-video " style="margin:0 auto;">
<div id="jp_container_1" class="jp-video" style="margin:0 auto;">
<div class="jp-type-single">
<div id="jquery_jplayer_1" class="jp-jplayer"></div>
<div class="jp-gui">
@ -308,7 +303,7 @@ if(isset($_GET['action']))
</div>
</div>
</div>
<?php if(in_array(strtolower($info['extension']), $ext_music)): ?>
<?php if(in_array(strtolower($info['extension']), $config['ext_music'])): ?>
<script type="text/javascript">
$(document).ready(function(){
@ -332,7 +327,7 @@ if(isset($_GET['action']))
});
</script>
<?php elseif(in_array(strtolower($info['extension']), $ext_video)): ?>
<?php elseif(in_array(strtolower($info['extension']), $config['ext_video'])): ?>
<script type="text/javascript">
$(document).ready(function(){
@ -371,15 +366,6 @@ if(isset($_GET['action']))
exit;
}
if (strpos($_POST['path'],'../') !== FALSE
|| strpos($_POST['path'],'./') !== FALSE
|| strpos($_POST['path'],'..\\') !== FALSE
|| strpos($_POST['path'],'.\\') !== FALSE )
{
response(trans('wrong path'.AddErrorLocation()))->send();
exit;
}
if (trim($_POST['path']) == '')
{
response(trans('no path').AddErrorLocation())->send();
@ -387,12 +373,12 @@ if(isset($_GET['action']))
}
$msg_sub_action = ($_POST['sub_action'] == 'copy' ? trans('Copy') : trans('Cut'));
$path = $current_path . $_POST['path'];
$path = $config['current_path'] . $_POST['path'];
if (is_dir($path))
{
// can't copy/cut dirs
if ($copy_cut_dirs === false)
if ($config['copy_cut_dirs'] === false)
{
response(sprintf(trans('Copy_Cut_Not_Allowed'), $msg_sub_action, trans('Folders')).AddErrorLocation())->send();
exit;
@ -400,30 +386,30 @@ if(isset($_GET['action']))
list($sizeFolderToCopy,$fileNum,$foldersCount) = folder_info($path,false);
// size over limit
if ($copy_cut_max_size !== false && is_int($copy_cut_max_size)) {
if (($copy_cut_max_size * 1024 * 1024) < $sizeFolderToCopy) {
response(sprintf(trans('Copy_Cut_Size_Limit'), $msg_sub_action, $copy_cut_max_size).AddErrorLocation())->send();
if ($config['copy_cut_max_size'] !== false && is_int($config['copy_cut_max_size'])) {
if (($config['copy_cut_max_size'] * 1024 * 1024) < $sizeFolderToCopy) {
response(sprintf(trans('Copy_Cut_Size_Limit'), $msg_sub_action, $config['copy_cut_max_size']).AddErrorLocation())->send();
exit;
}
}
// file count over limit
if ($copy_cut_max_count !== false && is_int($copy_cut_max_count))