album remplace gallery

This commit is contained in:
Deltacms 2023-10-06 08:34:35 +02:00
parent 8e1ae24865
commit 53a68687e1
56 changed files with 3149 additions and 452 deletions

View File

@ -5,14 +5,14 @@
- Une troisième langue d'administration est disponible : espagnol / castillan,
- Thème / Menu : le menu en petit écran (burger) dispose maintenant de ses propres paramètres,
- Modules du coeur et de page : renforcement de la sécurité,
- Module de type galerie: 'Album' remplace 'Gallery', les vignettes respectent le format des photos. Gallery est disponible en téléchargement sur https://deltacms.fr/modules,
- Langues : la traduction automatique est supprimée, ce qui parachève la dégooglisation de Deltacms,
- Edition de page / emplacement dans le menu : une page désactivée est signalée par le curseur 'not-allowed' et par une typographie italique en petit écran, son lien est inactif,
- Nouveaux gabarits pour l'éditeur Tinymce : accordéon à 3 et 4 paragraphes,
- Configuration / recherche d'une mise à jour : le serveur n'utilise plus son cache pour lire le fichier de version,
- Statislite 4.8 : comptage des liens cliqués pour lesquels la class 'clicked_link_count' a été ajoutée par l'éditeur de liens de Tinymce,
- Agenda 5.9 : la langue de l'agenda s'adapte automatiquement à la traduction rédigée,
- Blog 6.8 et News 4.7 : les dates s'adaptent automatiquement à la traduction rédigée,
- Blog 6.8 et News 4.7 : amélioration de la navigation entre les articles,
- Blog 6.8 et News 4.7 : les dates s'adaptent automatiquement à la traduction rédigée, amélioration de la navigation entre les articles,
- Theme / Footer : amélioration, 'Qui est en ligne ?' s'affiche dans la langue de rédaction du site avec les labels réglables dans Configuration / Localisation.
- Scripts : les fichiers body.inc.html et head.inc.html sont renommés body.inc.php et head.inc.php
- Correction :

View File

@ -68,62 +68,6 @@
}
}
},
"galeries": {
"content": {
"toctoc": {
"config": {
"name": "Toctoc",
"directory": "site\/file\/source\/galerie\/toctoc",
"homePicture": "a.jpg",
"sort": "SORT_ASC",
"position": 0,
"fullscreen": false
},
"legend": {
"a.jpg": "",
"b.jpg": "",
"c.jpg": ""
},
"positions": []
},
"grece": {
"config": {
"name": "Greece",
"directory": "site\/file\/source\/galerie\/grece",
"homePicture": "philosophe.jpg",
"sort": "SORT_ASC",
"position": 1,
"fullscreen": false
},
"legend": {
"chapiteaujpg": "Capital",
"philosophejpg": "Philosopher",
"portjpg": "Harbour"
},
"positions": []
}
},
"theme": {
"thumbAlign": "center",
"thumbWidth": "18em",
"thumbHeight": "15em",
"thumbMargin": ".5em",
"thumbBorder": ".1em",
"thumbOpacity": ".7",
"thumbBorderColor": "rgba(221, 221, 221, 1)",
"thumbRadius": ".3em",
"thumbShadows": "1px 1px 10px",
"thumbShadowsColor": "rgba(125, 125, 125, 1)",
"legendHeight": ".375em",
"legendAlign": "center",
"legendTextColor": "rgba(255, 255, 255, 1)",
"legendBgColor": "rgba(0, 0, 0, .6)",
"style": "site\/data\/gallery\/galeries\/theme.css"
},
"config": {
"versionData": "4.4"
}
},
"deltacms": {
"url": "https:\/\/deltacms.fr\/",
"count": 1
@ -215,6 +159,30 @@
"keywordColor": "rgba(229, 229, 1, 1)",
"style": "site\/data\/search\/erreur404\/theme.css"
}
},
"galeries": {
"greece": {
"config": {
"name": "Greece",
"directory": "site\/file\/source\/galerie\/grece",
"homePicture": null,
"sort": "SORT_ASC",
"position": 0
},
"legend": [],
"order": []
},
"knock-knock": {
"config": {
"name": "Knock knock",
"directory": "site\/file\/source\/galerie\/toctoc",
"homePicture": null,
"sort": "SORT_ASC",
"position": 2
},
"legend": [],
"order": []
}
}
}
}

View File

@ -137,7 +137,7 @@
"breadCrumb": false,
"metaDescription": "",
"metaTitle": "",
"moduleId": "gallery",
"moduleId": "album",
"modulePosition": "bottom",
"parentPageId": "",
"position": 5,
@ -151,6 +151,7 @@
"barRight": "",
"displayMenu": "none",
"hideMenuSide": false,
"hideMenuHead": false,
"hideMenuChildren": false
},
"deltacms": {

View File

@ -68,7 +68,7 @@
},
"deltacms": {
"url": "https:\/\/deltacms.fr\/",
"count": 3
"count": 4
},
"erreur404": {
"config": {
@ -159,59 +159,27 @@
"draft": ""
},
"galeria": {
"content": {
"toctoc": {
"toque-toque": {
"config": {
"name": "Toctoc",
"name": "Toque toque",
"directory": "site\/file\/source\/galerie\/toctoc",
"homePicture": "a.jpg",
"homePicture": null,
"sort": "SORT_ASC",
"position": 0,
"fullscreen": false
"position": 0
},
"legend": {
"a.jpg": "",
"b.jpg": "",
"c.jpg": ""
},
"positions": []
"legend": [],
"order": []
},
"grecia": {
"config": {
"name": "Grecia",
"directory": "site\/file\/source\/galerie\/grece",
"homePicture": "philosophe.jpg",
"homePicture": null,
"sort": "SORT_ASC",
"position": null,
"fullScreen": false
"position": 2
},
"legend": {
"chapiteaujpg": "Capitel",
"philosophejpg": "Filósofo",
"portjpg": "Puerto"
},
"positions": null
}
},
"theme": {
"thumbAlign": "center",
"thumbWidth": "18em",
"thumbHeight": "15em",
"thumbMargin": ".5em",
"thumbBorder": ".1em",
"thumbOpacity": ".7",
"thumbBorderColor": "rgba(221, 221, 221, 1)",
"thumbRadius": ".3em",
"thumbShadows": "1px 1px 10px",
"thumbShadowsColor": "rgba(125, 125, 125, 1)",
"legendHeight": ".375em",
"legendAlign": "center",
"legendTextColor": "rgba(255, 255, 255, 1)",
"legendBgColor": "rgba(0, 0, 0, .6)",
"style": "site\/data\/gallery\/galeria\/theme.css"
},
"config": {
"versionData": "4.4"
"legend": [],
"order": []
}
}
}

View File

@ -246,7 +246,7 @@
"breadCrumb": false,
"metaDescription": "",
"metaTitle": "",
"moduleId": "gallery",
"moduleId": "album",
"modulePosition": "bottom",
"parentPageId": "",
"position": 5,

View File

@ -68,62 +68,6 @@
}
}
},
"galeries": {
"content": {
"toctoc": {
"config": {
"name": "Toctoc",
"directory": "site\/file\/source\/galerie\/toctoc",
"homePicture": "a.jpg",
"sort": "SORT_ASC",
"position": 0,
"fullscreen": false
},
"legend": {
"a.jpg": "",
"b.jpg": "",
"c.jpg": ""
},
"positions": []
},
"grece": {
"config": {
"name": "Grèce",
"directory": "site\/file\/source\/galerie\/grece",
"homePicture": "philosophe.jpg",
"sort": "SORT_ASC",
"position": 1,
"fullscreen": false
},
"legend": {
"chapiteaujpg": "Chapiteau",
"philosophejpg": "Philosophe",
"portjpg": "Port"
},
"positions": []
}
},
"theme": {
"thumbAlign": "center",
"thumbWidth": "18em",
"thumbHeight": "15em",
"thumbMargin": ".5em",
"thumbBorder": ".1em",
"thumbOpacity": ".7",
"thumbBorderColor": "rgba(221, 221, 221, 1)",
"thumbRadius": ".3em",
"thumbShadows": "1px 1px 10px",
"thumbShadowsColor": "rgba(125, 125, 125, 1)",
"legendHeight": ".375em",
"legendAlign": "center",
"legendTextColor": "rgba(255, 255, 255, 1)",
"legendBgColor": "rgba(0, 0, 0, .6)",
"style": "site\/data\/gallery\/galeries\/theme.css"
},
"config": {
"versionData": "4.4"
}
},
"deltacms": {
"url": "https:\/\/deltacms.fr\/",
"count": 1
@ -198,6 +142,30 @@
"keywordColor": "rgba(229, 229, 1, 1)",
"style": "site\/data\/search\/erreur404\/theme.css"
}
},
"galeries": {
"toc-toc": {
"config": {
"name": "Toc toc",
"directory": "site\/file\/source\/galerie\/toctoc",
"homePicture": null,
"sort": "SORT_ASC",
"position": 0
},
"legend": [],
"order": []
},
"grece": {
"config": {
"name": "Grèce",
"directory": "site\/file\/source\/galerie\/grece",
"homePicture": null,
"sort": "SORT_ASC",
"position": 2
},
"legend": [],
"order": []
}
}
}
}

View File

@ -111,7 +111,7 @@
"breadCrumb": false,
"metaDescription": "",
"metaTitle": "",
"moduleId": "gallery",
"moduleId": "album",
"modulePosition": "bottom",
"parentPageId": "",
"position": 6,
@ -125,6 +125,7 @@
"barRight": "",
"displayMenu": "none",
"hideMenuSide": false,
"hideMenuHead": false,
"hideMenuChildren": false
},
"deltacms": {

664
module/album/album.php Normal file
View File

@ -0,0 +1,664 @@
<?php
/**
* @license GNU General Public License, version 3
* @Lionel Croquefer 2019
*/
setlocale(LC_NUMERIC,'English','en_US','en_US.UTF-8');
class album extends common {
const VERSION = '2.1';
const REALNAME = 'Album Photo';
const DELETE = true;
const UPDATE = '0.0';
const DATADIRECTORY = '';
const SORT_ASC = 'SORT_ASC';
const SORT_DSC = 'SORT_DSC';
const SORT_HAND = 'SORT_HAND';
public static $directories = [];
public static $firstPictures = [];
public static $galleries = [];
public static $galleriesId = [];
public static $pictures = [];
public static $picturesId = [];
public static $actions = [
'config' => self::GROUP_EDITOR,
'delete' => self::GROUP_MODERATOR,
'dirs' => self::GROUP_EDITOR,
'sortGalleries' => self::GROUP_EDITOR,
'sortPictures' => self::GROUP_EDITOR,
'edit' => self::GROUP_EDITOR,
'index' => self::GROUP_VISITOR
];
/**
* Tri de la liste des galeries sans bouton
*/
public function sortGalleries () {
// Autorisation
$group = $this->getUser('group');
if ($group === false ) $group = 0;
if( $group < album::$actions['sortGalleries'] ) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
if($_POST['response']) {
$data = explode('&',$_POST['response']);
$data = str_replace('galleryTable%5B%5D=','',$data);
for($i=0;$i<count($data);$i++) {
$this->setData(['module', $this->getUrl(0), $data[$i], [
'config' => [
'name' => $this->getData(['module',$this->getUrl(0),$data[$i],'config','name']),
'directory' => $this->getData(['module',$this->getUrl(0),$data[$i],'config','directory']),
'homePicture' => $this->getData(['module',$this->getUrl(0),$data[$i],'config','homePicture']),
'sort' => $this->getData(['module',$this->getUrl(0),$data[$i],'config','sort']),
'position' => $i
],
'legend' => $this->getData(['module',$this->getUrl(0),$data[$i],'legend']),
'order' => $this->getData(['module',$this->getUrl(0),$data[$i],'order'])
]]);
}
}
}
}
/**
* Tri de la liste des images
*
*/
public function sortPictures() {
// Autorisation
$group = $this->getUser('group');
if ($group === false ) $group = 0;
if( $group < album::$actions['sortPictures'] ) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
if($_POST['response']) {
$galleryName = $_POST['gallery'];
$data = explode('&',$_POST['response']);
$data = str_replace('galleryTable%5B%5D=','',$data);
// Sauvegarder
$this->setData(['module', $this->getUrl(0), $galleryName, [
'config' => [
'name' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','name']),
'directory' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','directory']),
'homePicture' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','homePicture']),
'sort' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','sort']),
'position' => $this->getData(['module',$this->getUrl(0),$galleryName,'config','position'])
],
'legend' => $this->getData(['module',$this->getUrl(0),$galleryName,'legend']),
'order' => array_flip($data)
]]);
}
}
}
/**
* Configuration
*/
public function config() {
// Autorisation
$group = $this->getUser('group');
if ($group === false ) $group = 0;
if( $group < album::$actions['config'] ) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Lexique
$param = '';
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
//Affichage de l'album triée
$g = $this->getData(['module', $this->getUrl(0)]);
$p = helper::arrayCollumn(helper::arrayCollumn($g,'config'),'position');
asort($p,SORT_NUMERIC);
$galleries = [];
foreach ($p as $positionId => $item) {
$galleries [$positionId] = $g[$positionId];
}
// Traitement de l'affichage
if($galleries) {
foreach($galleries as $galleryId => $gallery) {
// Erreur dossier vide
if(is_dir($gallery['config']['directory'])) {
if(count(scandir($gallery['config']['directory'])) === 2) {
$gallery['config']['directory'] = '<span class="galleryConfigError">' . $gallery['config']['directory'] . $text['gallery']['config'][0].'</span>';
}
}
// Erreur dossier supprimé
else {
$gallery['config']['directory'] = '<span class="galleryConfigError">' . $gallery['config']['directory'] . $text['gallery']['config'][1].'</span>';
}
// Met en forme le tableau
self::$galleries[] = [
template::ico('sort'),
$gallery['config']['name'],
str_replace('site/file/source/','',$gallery['config']['directory']),
template::button('galleryConfigEdit' . $galleryId , [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $galleryId . '/' . $_SESSION['csrf'],
'value' => template::ico('pencil')
]),
template::button('galleryConfigDelete' . $galleryId, [
'class' => 'galleryConfigDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $galleryId . '/' . $_SESSION['csrf'],
'value' => template::ico('cancel'),
'disabled' => $this->getUser('group') >= self::GROUP_MODERATOR ? false : true
])
];
// Tableau des id des galleries pour le drag and drop
self::$galleriesId[] = $galleryId;
}
}
// Soumission du formulaire d'ajout d'un album
if($this->isPost()) {
if (!$this->getInput('galleryConfigFilterResponse')) {
$galleryId = helper::increment($this->getInput('galleryConfigName', helper::FILTER_ID, true), (array) $this->getData(['module', $this->getUrl(0)]));
$this->setData(['module', $this->getUrl(0), $galleryId, [
'config' => [
'name' => $this->getInput('galleryConfigName'),
'directory' => $this->getInput('galleryConfigDirectory', helper::FILTER_STRING_SHORT, true),
'homePicture' => NULL, // homePicture non préalablement définie
'sort' => self::SORT_ASC,
'position' => $this->getData(['module',$this->getUrl(0)]) !== null ? count($this->getData(['module',$this->getUrl(0)])) + 1 : 0
],
'legend' => [],
'order' => []
]]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(),
'notification' => $text['gallery']['config'][2],
'state' => true
]);
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $text['gallery']['config'][3],
'view' => 'config',
'vendor' => [
'tablednd'
]
]);
}
}
/**
* Suppression
*/
public function delete() {
// Autorisation
$group = $this->getUser('group');
if ($group === false ) $group = 0;
if( $group < album::$actions['delete'] ) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Lexique
$param = '';
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
// $url prend l'adresse sans le token
// La galerie n'existe pas
if($this->getData(['module', $this->getUrl(0), $this->getUrl(2)]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config',
'notification' => $text['gallery']['delete'][0]
]);
}
// Suppression
else {
$this->deleteData(['module', $this->getUrl(0), $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config',
'notification' => $text['gallery']['delete'][1],
'state' => true
]);
}
}
}
/**
* Liste des dossiers
*/
public function dirs() {
// Autorisation
$group = $this->getUser('group');
if ($group === false ) $group = 0;
if( $group < album::$actions['dirs'] ) {
$this->addOutput([
'access' => false
]);
} else {
// Valeurs en sortie
$filter = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => helper::scanDir(self::FILE_DIR.'source', $filter)
]);
}
}
/**
* Édition
*/
public function edit() {
// Autorisation
$group = $this->getUser('group');
if ($group === false ) $group = 0;
if( $group < album::$actions['edit'] ) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Lexique
$param = '';
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/config',
'notification' => $text['gallery']['edit'][0]
]);
}
// La galerie n'existe pas
if($this->getData(['module', $this->getUrl(0), $this->getUrl(2)]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// La galerie existe
else {
// Soumission du formulaire
if($this->isPost()) {
// Si l'id a changée
$galleryId = !empty($this->getInput('galleryEditName')) ? $this->getInput('galleryEditName', helper::FILTER_ID, true) : $this->getUrl(2);
if($galleryId !== $this->getUrl(2)) {
// Incrémente le nouvel id de la galerie
$galleryId = helper::increment($galleryId, $this->getData(['module', $this->getUrl(0)]));
// Transférer la position des images
$oldorder = $this->getData(['module',$this->getUrl(0), $this->getUrl(2),'order']);
// Supprime l'ancienne galerie
$this->deleteData(['module', $this->getUrl(0), $this->getUrl(2)]);
}
// légendes
$legends = [];
foreach((array) $this->getInput('legend', null) as $file => $legend) {
// Image de couverture par défaut si non définie
$homePicture = $file;
$file = str_replace('.','',$file);
$legends[$file] = helper::filter($legend, helper::FILTER_STRING_SHORT);
}
// Photo de la page de garde de l'album définie dans form
if (is_array($this->getInput('homePicture', null)) ) {
$d = array_keys($this->getInput('homePicture', null));
$homePicture = $d[0];
}
// Sauvegarder
if ($this->getInput('galleryEditName')) {
$this->setData(['module', $this->getUrl(0), $galleryId, [
'config' => [
'name' => $this->getInput('galleryEditName', helper::FILTER_STRING_SHORT, true),
'directory' => $this->getInput('galleryEditDirectory', helper::FILTER_STRING_SHORT, true),
'homePicture' => $homePicture,
// pas d'ordre, on active le tri alpha
'sort' => $this->getInput('galleryEditSort'),
'position' => $this->getData(['module', $this->getUrl(0), $galleryId,'config','position'])
],
'legend' => $legends,
'order' => empty($oldorder) ? $this->getdata(['module', $this->getUrl(0), $galleryId, 'order']) : $oldorder
]]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $galleryId . '/' . $_SESSION['csrf'] ,
'notification' => $text['gallery']['edit'][1],
'state' => true
]);
}
// Met en forme le tableau
$directory = $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'config', 'directory']);
if(is_dir($directory)) {
$iterator = new DirectoryIterator($directory);
foreach($iterator as $fileInfos) {
if($fileInfos->isDot() === false AND $fileInfos->isFile() AND substr(mime_content_type($fileInfos->getPathname()), 0, 5) == 'image') {
self::$pictures[str_replace('.','',$fileInfos->getFilename())] = [
template::ico('sort'),
$fileInfos->getFilename(),
template::checkbox( 'homePicture[' . $fileInfos->getFilename() . ']', true, '', [
'checked' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2),'config', 'homePicture']) === $fileInfos->getFilename() ? true : false,
'class' => 'homePicture'
]),
template::text('legend[' . $fileInfos->getFilename() . ']', [
'value' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'legend', str_replace('.','',$fileInfos->getFilename())])
]),
'<a href="'.$fileInfos->getPathname().'" rel="data-lity"><img class="config" src="'.helper::baseUrl(false).'module/album/plugins/thumbnailer.php?img='.$fileInfos->getPathname().'" alt="miniature"></a>'
];
self::$picturesId [] = str_replace('.','',$fileInfos->getFilename());
}
}
// Tri des images
switch ($this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'config', 'sort'])) {
case self::SORT_HAND:
$order = $this->getdata(['module',$this->getUrl(0), $this->getUrl(2),'order']);
if ($order) {
foreach ($order as $key => $value) {
if (array_key_exists($key,self::$pictures)) {
$tempPictures[$key] = self::$pictures[$key];
$tempPicturesId [] = $key;
}
}
// Images ayant été ajoutées dans le dossier mais non triées
foreach (self::$pictures as $key => $value) {
if (!array_key_exists($key,$tempPictures)) {
$tempPictures[$key] = self::$pictures[$key];
$tempPicturesId [] = $key;
}
}
self::$pictures = $tempPictures;
self::$picturesId = $tempPicturesId;
}
break;
case self::SORT_ASC:
ksort(self::$pictures,SORT_NATURAL);
sort(self::$picturesId,SORT_NATURAL);
break;
case self::SORT_DSC:
krsort(self::$pictures,SORT_NATURAL);
rsort(self::$picturesId,SORT_NATURAL);
break;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'config', 'name']),
'view' => 'edit',
'vendor' => [
'tablednd'
]
]);
}
}
}
/**
* Accueil (deux affichages en un pour éviter une url à rallonge)
*/
public function index() {
// Images d'une galerie
if($this->getUrl(1)) {
// La galerie n'existe pas
if($this->getData(['module', $this->getUrl(0), $this->getUrl(1)]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// La galerie existe
else {
// Images de la galerie
$directory = $this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'config', 'directory']);
if(is_dir($directory)) {
$iterator = new DirectoryIterator($directory);
foreach($iterator as $fileInfos) {
if($fileInfos->isDot() === false AND $fileInfos->isFile() AND substr(mime_content_type($fileInfos->getPathname()), 0, 5) == 'image') {
// contrôle et traite éventuellement les images affichées dans la galerie
$imgalerie = str_replace('\\','/',$fileInfos->getPathname());
albumHelper::controle($imgalerie);
self::$pictures[$directory . '/' . $fileInfos->getFilename()] = $this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'legend', str_replace('.','',$fileInfos->getFilename())]);
$picturesSort[$directory . '/' . $fileInfos->getFilename()] = $this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'order', str_replace('.','',$fileInfos->getFilename())]);
}
}
// Tri des images par ordre alphabétique
switch ($this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'config', 'sort'])) {
case self::SORT_HAND:
asort($picturesSort);
if ($picturesSort) {
foreach ($picturesSort as $name => $position) {
$temp[$name] = self::$pictures[$name];
}
self::$pictures = $temp;
break;
}
case self::SORT_DSC:
krsort(self::$pictures,SORT_NATURAL);
break;
case self::SORT_ASC:
default:
ksort(self::$pictures,SORT_NATURAL);
break;
}
}
// Affichage du template
if(self::$pictures) {
// Valeurs en sortie
$this->addOutput([
'showBarEditButton' => true,
'title' => $this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'config', 'name']),
'vendor' => ['js'],
'view' => 'gallery'
]);
}
// Pas d'image dans la galerie
else {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
}
}
// Liste des galeries
else {
// Tri des galeries suivant l'ordre défini
$g = $this->getData(['module', $this->getUrl(0)]);
$p = helper::arrayCollumn(helper::arrayCollumn($g,'config'),'position');
asort($p,SORT_NUMERIC);
$galleries = [];
foreach ($p as $positionId => $item) {
$galleries [$positionId] = $g[$positionId];
}
// Construire le tableau
foreach((array) $galleries as $galleryId => $gallery) {
if(is_dir($gallery['config']['directory'])) {
$iterator = new DirectoryIterator($gallery['config']['directory']);
foreach($iterator as $fileInfos) {
if($fileInfos->isDot() === false AND $fileInfos->isFile() AND substr(mime_content_type($fileInfos->getPathname()), 0, 5) == 'image') {
// contrôle et traite éventuellement les images affichées dans l'index de la galerie
$imgalerie = str_replace('\\','/',$fileInfos->getPathname());
albumHelper::controle($imgalerie);
self::$galleries[$galleryId] = $gallery;
self::$firstPictures[$galleryId] = $gallery['config']['directory'] . '/' . $fileInfos->getFilename();
continue(2);
}
}
}
}
// Valeurs en sortie
$this->addOutput([
'showBarEditButton' => true,
'showPageContent' => true,
'vendor' => ['js'],
'view' => 'index'
]);
}
}
}
class albumHelper extends helper {
// dossier backup
public static function makeDir($rep) {
if (is_dir($rep)) {
return true;
} else {
if (mkdir($rep)) { return true; }
else { return false; }
}
}
// relevés exif gps des photos
public static function gps_exif($foto) {
if (!preg_match('/(\.jpe?g)$/i', $foto)) {
return null;
}
if (function_exists('exif_read_data')) {
$exif = @exif_read_data($foto, 0, true);
if ($exif && @$exif['GPS']['GPSLongitude'][0]) {
$latitude = self::gps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
$longitude = self::gps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
$altitude = 0;
if (!empty($exif['GPS']['GPSAltitude'])) {
$alt = explode('/',$exif['GPS']['GPSAltitude']);
if (($alt[0] > 0) && ($alt[1] > 0)) {
$altitude = round($alt[0] / $alt[1]);
}
}
if ( (!isset($latitude) || !isset($longitude)) || (($latitude == 0) && ($longitude == 0)) ) {
return null; }
else {
return ($latitude.'¤'.$longitude.'¤'.$altitude);
}
}
}
}
public static function gps($coordinate, $hemisphere) {
if (is_string($coordinate)) {
$coordinate = array_map('trim', explode(',', $coordinate));
}
for ($i = 0; $i < 3; $i++) {
$part = explode('/', $coordinate[$i]);
if (count($part) == 1) {
$coordinate[$i] = $part[0];
} elseif ( (count($part) == 2) && ($part[1] > 0) ) {
$coordinate[$i] = floatval($part[0])/floatval($part[1]);
} else {
$coordinate[$i] = 0;
}
}
list($degrees, $minutes, $seconds) = $coordinate;
$sign = ($hemisphere == 'W' || $hemisphere == 'S') ? -1 : 1;
return $sign * ($degrees + $minutes/60 + $seconds/3600);
}
// formatage light des noms d'images
public static function formate($foto) {
$foto = trim($foto);
$foto = preg_replace('/[^[:alnum:]_.\-\/]/', '', $foto);
return $foto;
}
// reorientation
public static function reorientation($foto) {
$size = @getimagesize($foto);
$mime = $size['mime'];
if ((function_exists('exif_read_data')) && ($mime == 'image/jpeg'))
{
$exif = @exif_read_data($foto);
$image = imagecreatefromstring(file_get_contents($foto));
if ($image !== false) {
$orientation = isset($exif['Orientation']) === true ? $exif['Orientation'] : '';
if ( (!empty($orientation)) && ($orientation != 1) )
{
switch($orientation)
{
case 3:
$image = imagerotate($image,180,0);
break;
case 6:
$image = imagerotate($image,-90,0);
break;
case 8:
$image = imagerotate($image,90,0);
break;
}
imagejpeg($image, $foto, 90);
}
}
}
}
// redimension
public static function redimension($foto) {
$max_size = 960;// ex1280 dimension du plus petit côté
$infoto = @getimagesize($foto);
$large = $infoto[0];
$haut = $infoto[1];
$type = $infoto[2];
// seules les images/jpeg sont redimensionnées
if (($type == 2) && ($large > $max_size) && ($haut > $max_size)) {
$imar = substr(strrchr($foto, '/'), 1);
$urlimar = str_replace($imar,'',$foto);
$backup = $urlimar.'backup';
self::makeDir($backup);
$extension = strrchr($imar,'.');
$namimar = str_replace($extension,'',$imar);
$redimg = $urlimar.$namimar.'_t960.jpg';
$backimg = $backup.'/'.strtolower(str_replace('.jpeg','.jpg',$imar));
$src = imagecreatefromjpeg($foto);
imageinterlace($src, true);
if ($large > $haut) {
$im = imagecreatetruecolor(round(($max_size/$haut)*$large), $max_size);
imagecopyresampled($im, $src, 0, 0, 0, 0, round(($max_size/$haut)*$large), $max_size, $large, $haut);
} else {
$im = imagecreatetruecolor($max_size, round(($max_size/$large)*$haut));
imagecopyresampled($im, $src, 0, 0, 0, 0, $max_size, round($haut*($max_size/$large)), $large, $haut);
}
imagejpeg($im, $redimg, 80);
imagedestroy($im);
rename($foto,$backimg);
echo '<script>document.location.reload(false);</script>';
exit(0);
}
}
// contrôle des photos
public static function controle($foto) {
$tn_tmp = substr(strrchr($foto, '/'), 1);
$url_picture = str_replace('/'.$tn_tmp,'',$foto);
$minidos = substr(strrchr($url_picture, '/'), 1);
$mini = 'site/file/cache/'.$minidos.'/'.$tn_tmp;
if (!file_exists($mini)) {
$valid = array('-', '_','.');
if (!ctype_alnum(str_replace($valid, '', $tn_tmp))) {
$nommage = self::formate($foto);
$foto = rename($foto,$nommage);
echo '<script>document.location.reload(false);</script>';
exit(0);
} else {
self::reorientation($foto);
self::redimension($foto);
}
}
return $foto;
clearstatcache();
}
}

View File

@ -0,0 +1,48 @@
<?php
// Lexique du module album en anglais
$text['album_view']['config'][0] = 'Back';
$text['album_view']['config'][1] = 'Help';
$text['album_view']['config'][2] = 'New Album';
$text['album_view']['config'][3] = 'Name';
$text['album_view']['config'][4] = 'Target folder';
$text['album_view']['config'][5] = 'Installed albums';
$text['album_view']['config'][6] = "Are you sure you want to delete this album ?";
$text['album_view']['config'][7] = 'No galleries';
$text['album_view']['config'][8] = 'Version no.';
$text['album_view']['edit'][0] = 'Back';
$text['album_view']['edit'][1] = 'Save';
$text['album_view']['edit'][2] = 'Image setting';
$text['album_view']['edit'][3] = 'Name';
$text['album_view']['edit'][4] = 'Target folder';
$text['album_view']['edit'][5] = 'Sort images';
$text['album_view']['edit'][6] = 'Manual sort: move the images into the table below. The order is saved automatically';
$text['album_view']['edit'][7] = 'Image';
$text['album_view']['edit'][8] = 'Cover';
$text['album_view']['edit'][9] = 'Caption';
$text['album_view']['edit'][10] = 'No image';
$text['album_view']['edit'][11] = 'Version No.';
$text['album_view']['gallery'][0] = 'Back';
$text['album_view']['gallery'][1] = 'Geolocation';
$text['album_view']['index'][0] = 'No album.';
$text['gallery']['config'][0] = ' (empty folder)';
$text['gallery']['config'][1] = ' (folder not found)';
$text['gallery']['config'][2] = 'Saved changes';
$text['gallery']['config'][3] = 'Module configuration';
$text['gallery']['delete'][0] = 'Unauthorized deletion';
$text['gallery']['delete'][1] = 'Album deleted';
$text['gallery']['edit'][0] = 'Unauthorised action';
$text['gallery']['edit'][1] = 'Changes saved';
//Selects
if($param === "album_view"){
$sort = [
$module::SORT_ASC => 'Alphabetical',
$module::SORT_DSC => 'Reverse Alphabetic',
$module::SORT_HAND => 'Manual'
];
}
?>

View File

@ -0,0 +1,48 @@
<?php
// Lexique du module álbum en espagnol
$text['album_view']['config'][0] = 'Atrás';
$text['album_view']['config'][1] = 'Ayuda';
$text['album_view']['config'][2] = 'Nuevo álbum';
$text['album_view']['config'][3] = 'Nombre';
$text['album_view']['config'][4] = 'Carpeta de destino';
$text['album_view']['config'][5] = 'Albums instalados';
$text['album_view']['config'][6] = "¿Está seguro de que desea eliminar este álbum?";
$text['album_view']['config'][7] = 'Sin galería';
$text['album_view']['config'][8] = 'Número de versión';
$text['album_view']['edit'][0] = 'Volver';
$text['album_view']['edit'][1] = 'Guardar';
$text['album_view']['edit'][2] = 'Configuración de imagen';
$text['album_view']['edit'][3] = 'Nombre';
$text['album_view']['edit'][4] = 'Carpeta de destino';
$text['album_view']['edit'][5] = 'Ordenación de imágenes';
$text['album_view']['edit'][6] = 'Ordenación manual: mueva las imágenes en la tabla de abajo. El pedido se guarda automáticamente.';
$text['album_view']['edit'][7] = 'Imagen';
$text['album_view']['edit'][8] = 'Portada';
$text['album_view']['edit'][9] = 'Título';
$text['album_view']['edit'][10] = 'Sin imagen.';
$text['album_view']['edit'][11] = 'Número de versión';
$text['album_view']['gallery'][0] = 'Atrás';
$text['album_view']['gallery'][1] = 'Geolocalización';
$text['album_view']['index'][0] = 'Sin álbum.';
$text['gallery']['config'][0] = '(carpeta vacía)';
$text['gallery']['config'][1] = '(carpeta no encontrada)';
$text['gallery']['config'][2] = 'Cambios guardados';
$text['gallery']['config'][3] = 'Configuración del módulo';
$text['gallery']['delete'][0] = 'Borrar no permitido';
$text['gallery']['delete'][1] = 'Album eliminado';
$text['gallery']['edit'][0] = 'Acción no permitida';
$text['gallery']['edit'][1] = 'Ediciones guardadas';
//Selects
if($param === "album_view"){
$sort = [
$module::SORT_ASC => 'Alfabético',
$module::SORT_DSC => 'Alfabético inverso',
$module::SORT_HAND => 'Manual'
];
}
?>

View File

@ -0,0 +1,48 @@
<?php
// Lexique du module album en français
$text['album_view']['config'][0] = 'Retour';
$text['album_view']['config'][1] = 'Aide';
$text['album_view']['config'][2] = 'Nouvel Album';
$text['album_view']['config'][3] = 'Nom';
$text['album_view']['config'][4] = 'Dossier cible';
$text['album_view']['config'][5] = 'Albums installés';
$text['album_view']['config'][6] = "Êtes-vous sûr de vouloir supprimer cet album ?";
$text['album_view']['config'][7] = 'Aucune galerie.';
$text['album_view']['config'][8] = 'Version n°';
$text['album_view']['edit'][0] = 'Retour';
$text['album_view']['edit'][1] = 'Enregistrer';
$text['album_view']['edit'][2] = 'Paramètre des images';
$text['album_view']['edit'][3] = 'Nom';
$text['album_view']['edit'][4] = 'Dossier cible';
$text['album_view']['edit'][5] = 'Tri des images';
$text['album_view']['edit'][6] = 'Tri manuel : déplacez le images dans le tableau ci-dessous. L\'ordre est sauvegardé automatiquement.';
$text['album_view']['edit'][7] = 'Image';
$text['album_view']['edit'][8] = 'Couverture';
$text['album_view']['edit'][9] = 'Légende';
$text['album_view']['edit'][10] = 'Aucune image.';
$text['album_view']['edit'][11] = 'Version n°';
$text['album_view']['gallery'][0] = 'Retour';
$text['album_view']['gallery'][1] = 'Géolocalisation';
$text['album_view']['index'][0] = 'Aucun album.';
$text['gallery']['config'][0] = ' (dossier vide)';
$text['gallery']['config'][1] = ' (dossier introuvable)';
$text['gallery']['config'][2] = 'Modifications enregistrées';
$text['gallery']['config'][3] = 'Configuration du module';
$text['gallery']['delete'][0] = 'Suppression non autorisée';
$text['gallery']['delete'][1] = 'Album supprimé';
$text['gallery']['edit'][0] = 'Action non autorisée';
$text['gallery']['edit'][1] = 'Modifications enregistrées';
//Selects
if($param === "album_view"){
$sort = [
$module::SORT_ASC => 'Alphabétique ',
$module::SORT_DSC => 'Alphabétique inverse',
$module::SORT_HAND => 'Manuel'
];
}
?>

View File

@ -0,0 +1,10 @@
.fullscreen-icon { background-image: url(icon-fullscreen.svg); background-size:26px 52px; }
.fullscreen-icon.leaflet-fullscreen-on { background-position:0 -26px; }
.leaflet-touch .fullscreen-icon { background-position: 2px 2px; }
.leaflet-touch .fullscreen-icon.leaflet-fullscreen-on { background-position: 2px -24px; }
/* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */
.leaflet-container:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
.leaflet-container:-ms-fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
.leaflet-container:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
.leaflet-container:fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
.leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; }

View File

@ -0,0 +1,345 @@
/*!
* Based on package 'screenfull'
* v5.2.0 - 2021-11-03
* (c) Sindre Sorhus; MIT License
* Added definition for using screenfull as an amd module
* Must be placed before the definition of leaflet.fullscreen
* as it is required by that
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define('screenfull', factory);
} else if (typeof module === 'object' && module.exports) {
module.exports.screenfull = factory();
} else {
// Save 'screenfull' into global window variable
root.screenfull = factory();
}
}(typeof self !== 'undefined' ? self : this, function () {
'use strict';
var document = typeof window !== 'undefined' && typeof window.document !== 'undefined' ? window.document : {};
var fn = (function () {
var val;
var fnMap = [
[
'requestFullscreen',
'exitFullscreen',
'fullscreenElement',
'fullscreenEnabled',
'fullscreenchange',
'fullscreenerror'
],
// New WebKit
[
'webkitRequestFullscreen',
'webkitExitFullscreen',
'webkitFullscreenElement',
'webkitFullscreenEnabled',
'webkitfullscreenchange',
'webkitfullscreenerror'
],
// Old WebKit
[
'webkitRequestFullScreen',
'webkitCancelFullScreen',
'webkitCurrentFullScreenElement',
'webkitCancelFullScreen',
'webkitfullscreenchange',
'webkitfullscreenerror'
],
[
'mozRequestFullScreen',
'mozCancelFullScreen',
'mozFullScreenElement',
'mozFullScreenEnabled',
'mozfullscreenchange',
'mozfullscreenerror'
],
[
'msRequestFullscreen',
'msExitFullscreen',
'msFullscreenElement',
'msFullscreenEnabled',
'MSFullscreenChange',
'MSFullscreenError'
]
];
var i = 0;
var l = fnMap.length;
var ret = {};
for (; i < l; i++) {
val = fnMap[i];
if (val && val[1] in document) {
for (i = 0; i < val.length; i++) {
ret[fnMap[0][i]] = val[i];
}
return ret;
}
}
return false;
})();
var eventNameMap = {
change: fn.fullscreenchange,
error: fn.fullscreenerror
};
var screenfull = {
request: function (element, options) {
return new Promise(function (resolve, reject) {
var onFullScreenEntered = function () {
this.off('change', onFullScreenEntered);
resolve();
}.bind(this);
this.on('change', onFullScreenEntered);
element = element || document.documentElement;
var returnPromise = element[fn.requestFullscreen](options);
if (returnPromise instanceof Promise) {
returnPromise.then(onFullScreenEntered).catch(reject);
}
}.bind(this));
},
exit: function () {
return new Promise(function (resolve, reject) {
if (!this.isFullscreen) {
resolve();
return;
}
var onFullScreenExit = function () {
this.off('change', onFullScreenExit);
resolve();
}.bind(this);
this.on('change', onFullScreenExit);
var returnPromise = document[fn.exitFullscreen]();
if (returnPromise instanceof Promise) {
returnPromise.then(onFullScreenExit).catch(reject);
}
}.bind(this));
},
toggle: function (element, options) {
return this.isFullscreen ? this.exit() : this.request(element, options);
},
onchange: function (callback) {
this.on('change', callback);
},
onerror: function (callback) {
this.on('error', callback);
},
on: function (event, callback) {
var eventName = eventNameMap[event];
if (eventName) {
document.addEventListener(eventName, callback, false);
}
},
off: function (event, callback) {
var eventName = eventNameMap[event];
if (eventName) {
document.removeEventListener(eventName, callback, false);
}
},
raw: fn
};
if (!fn) {
return {isEnabled: false};
} else {
Object.defineProperties(screenfull, {
isFullscreen: {
get: function () {
return Boolean(document[fn.fullscreenElement]);
}
},
element: {
enumerable: true,
get: function () {
return document[fn.fullscreenElement];
}
},
isEnabled: {
enumerable: true,
get: function () {
// Coerce to boolean in case of old WebKit
return Boolean(document[fn.fullscreenEnabled]);
}
}
});
return screenfull;
}
}));
/*!
* leaflet.fullscreen
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// define an AMD module that requires 'leaflet' and 'screenfull'
// and resolve to an object containing leaflet and screenfull
define('leafletFullScreen', ['leaflet', 'screenfull'], factory);
} else if (typeof module === 'object' && module.exports) {
// define a CommonJS module that requires 'leaflet' and 'screenfull'
module.exports = factory(require('leaflet'), require('screenfull'));
} else {
// Assume 'leaflet' and 'screenfull' are loaded into global variable already
factory(root.L, root.screenfull);
}
}(typeof self !== 'undefined' ? self : this, function (leaflet, screenfull) {
'use strict';
leaflet.Control.FullScreen = leaflet.Control.extend({
options: {
position: 'topleft',
title: 'Full Screen',
titleCancel: 'Exit Full Screen',
forceSeparateButton: false,
forcePseudoFullscreen: false,
fullscreenElement: false
},
_screenfull: screenfull,
onAdd: function (map) {
var className = 'leaflet-control-zoom-fullscreen', container, content = '';
if (map.zoomControl && !this.options.forceSeparateButton) {
container = map.zoomControl._container;
} else {
container = leaflet.DomUtil.create('div', 'leaflet-bar');
}
if (this.options.content) {
content = this.options.content;
} else {
className += ' fullscreen-icon';
}
this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this);
this._map.fullscreenControl = this;
this._map.on('enterFullscreen exitFullscreen', this._toggleState, this);
return container;
},
onRemove: function () {
leaflet.DomEvent
.off(this.link, 'click', leaflet.DomEvent.stop)
.off(this.link, 'click', this.toggleFullScreen, this);
if (this._screenfull.isEnabled) {
leaflet.DomEvent
.off(this._container, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
.off(this._container, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, this);
leaflet.DomEvent
.off(document, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
.off(document, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, this);
}
},
_createButton: function (title, className, content, container, fn, context) {
this.link = leaflet.DomUtil.create('a', className, container);
this.link.href = '#';
this.link.title = title;
this.link.innerHTML = content;
this.link.setAttribute('role', 'button');
this.link.setAttribute('aria-label', title);
L.DomEvent.disableClickPropagation(container);
leaflet.DomEvent
.on(this.link, 'click', leaflet.DomEvent.stop)
.on(this.link, 'click', fn, context);
if (this._screenfull.isEnabled) {
leaflet.DomEvent
.on(container, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
.on(container, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, context);
leaflet.DomEvent
.on(document, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
.on(document, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, context);
}
return this.link;
},
toggleFullScreen: function () {
var map = this._map;
map._exitFired = false;
if (map._isFullscreen) {
if (this._screenfull.isEnabled && !this.options.forcePseudoFullscreen) {
this._screenfull.exit();
} else {
leaflet.DomUtil.removeClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
map.invalidateSize();
}
map.fire('exitFullscreen');
map._exitFired = true;
map._isFullscreen = false;
}
else {
if (this._screenfull.isEnabled && !this.options.forcePseudoFullscreen) {
this._screenfull.request(this.options.fullscreenElement ? this.options.fullscreenElement : map._container);
} else {
leaflet.DomUtil.addClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
map.invalidateSize();
}
map.fire('enterFullscreen');
map._isFullscreen = true;
}
},
_toggleState: function () {
this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel;
this._map._isFullscreen ? L.DomUtil.removeClass(this.link, 'leaflet-fullscreen-on') : L.DomUtil.addClass(this.link, 'leaflet-fullscreen-on');
},
_handleFullscreenChange: function () {
var map = this._map;
map.invalidateSize();
if (!this._screenfull.isFullscreen && !map._exitFired) {
map.fire('exitFullscreen');
map._exitFired = true;
map._isFullscreen = false;
}
}
});
leaflet.Map.include({
toggleFullscreen: function () {
this.fullscreenControl.toggleFullScreen();
}
});
leaflet.Map.addInitHook(function () {
if (this.options.fullscreenControl) {
this.addControl(leaflet.control.fullscreen(this.options.fullscreenControlOptions));
}
});
leaflet.control.fullscreen = function (options) {
return new leaflet.Control.FullScreen(options);
};
// must return an object containing also screenfull to make screenfull
// available outside of this package, if used as an amd module,
// as webpack cannot handle amd define with moduleid
return {leaflet: leaflet, screenfull: screenfull};
}));

View File

@ -0,0 +1 @@
<svg viewBox="0 0 26 52" xmlns="http://www.w3.org/2000/svg"><path d="M20.6 36.7H16a.9.9 0 0 1-.8-.8v-4.5c0-.2.2-.4.4-.4h1.4c.3 0 .5.2.5.4v3h3c.2 0 .4.2.4.5v1.4c0 .2-.2.4-.4.4zm-9.9-.8v-4.5c0-.2-.2-.4-.4-.4H8.9c-.3 0-.5.2-.5.4v3h-3c-.2 0-.4.2-.4.5v1.4c0 .2.2.4.4.4H10c.4 0 .8-.4.8-.8zm0 10.7V42c0-.4-.4-.8-.8-.8H5.4c-.2 0-.4.2-.4.4v1.4c0 .3.2.5.4.5h3v3c0 .2.2.4.5.4h1.4c.2 0 .4-.2.4-.4zm6.9 0v-3h3c.2 0 .4-.2.4-.5v-1.4c0-.2-.2-.4-.4-.4H16c-.4 0-.8.4-.8.8v4.5c0 .2.2.4.4.4h1.4c.3 0 .5-.2.5-.4zM5 10.3V5.9c0-.5.4-.9.9-.9h4.4c.2 0 .4.2.4.4V7c0 .2-.2.4-.4.4h-3v3c0 .2-.2.4-.4.4H5.4a.4.4 0 0 1-.4-.4zm10.3-4.9V7c0 .2.2.4.4.4h3v3c0 .2.2.4.4.4h1.5c.2 0 .4-.2.4-.4V5.9c0-.5-.4-.9-.9-.9h-4.4c-.2 0-.4.2-.4.4zm5.3 9.9H19c-.2 0-.4.2-.4.4v3h-3c-.2 0-.4.2-.4.4v1.5c0 .2.2.4.4.4h4.4c.5 0 .9-.4.9-.9v-4.4c0-.2-.2-.4-.4-.4zm-9.9 5.3V19c0-.2-.2-.4-.4-.4h-3v-3c0-.2-.2-.4-.4-.4H5.4c-.2 0-.4.2-.4.4v4.4c0 .5.4.9.9.9h4.4c.2 0 .4-.2.4-.4z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

View File

@ -0,0 +1,657 @@
/* required styles */
.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
image-rendering: -webkit-optimize-contrast;
}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
width: 1600px;
height: 1600px;
-webkit-transform-origin: 0 0;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
max-width: none !important;
max-height: none !important;
}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
max-width: none !important;
max-height: none !important;
width: auto;
padding: 0;
}
.leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y;
}
.leaflet-container.leaflet-touch-drag {
-ms-touch-action: pinch-zoom;
/* Fallback for FF which doesn't support pinch-zoom */
touch-action: none;
touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
-ms-touch-action: none;
touch-action: none;
}
.leaflet-container {
-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
z-index: 800;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-pane { z-index: 400; }
.leaflet-tile-pane { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane { z-index: 500; }
.leaflet-marker-pane { z-index: 600; }
.leaflet-tooltip-pane { z-index: 650; }
.leaflet-popup-pane { z-index: 700; }
.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg { z-index: 200; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 800;
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-animated {
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
}
svg.leaflet-zoom-animated {
will-change: transform;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
-webkit-transition: none;
-moz-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-interactive {
cursor: pointer;
}
.leaflet-grab {
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
cursor: crosshair;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
cursor: grabbing;
}
/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
pointer-events: none;
}
.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline-offset: 1px;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
font-size: 12px;
font-size: 0.75rem;
line-height: 1.5;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
.leaflet-touch .leaflet-bar a:first-child {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.leaflet-touch .leaflet-bar a:last-child {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
font-size: 22px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-scrollbar {
overflow-y: scroll;
overflow-x: hidden;
padding-right: 5px;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
font-size: 13px;
font-size: 1.08333em;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
background-image: url(images/marker-icon.png);
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.8);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
line-height: 1.4;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
text-decoration: underline;
}
.leaflet-control-attribution svg {
display: inline !important;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
white-space: nowrap;
overflow: hidden;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: #fff;
background: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
margin-bottom: 20px;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 24px 13px 20px;
line-height: 1.3;
font-size: 13px;
font-size: 1.08333em;
min-height: 1px;
}
.leaflet-popup-content p {
margin: 17px 0;
margin: 1.3em 0;
}
.leaflet-popup-tip-container {
width: 40px;
height: 20px;
position: absolute;
left: 50%;
margin-top: -1px;
margin-left: -20px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
pointer-events: auto;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
color: #333;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
border: none;
text-align: center;
width: 24px;
height: 24px;
font: 16px/24px Tahoma, Verdana, sans-serif;
color: #757575;
text-decoration: none;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
color: #585858;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
-ms-zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
position: absolute;
padding: 6px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 3px;
color: #222;
white-space: nowrap;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.leaflet-tooltip.leaflet-interactive {
cursor: pointer;
pointer-events: auto;
}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
position: absolute;
pointer-events: none;
border: 6px solid transparent;
background: transparent;
content: "";
}
/* Directions */
.leaflet-tooltip-bottom {
margin-top: 6px;
}
.leaflet-tooltip-top {
margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
left: 50%;
margin-left: -6px;
}
.leaflet-tooltip-top:before {
bottom: 0;
margin-bottom: -12px;
border-top-color: #fff;
}
.leaflet-tooltip-bottom:before {
top: 0;
margin-top: -12px;
margin-left: -6px;
border-bottom-color: #fff;
}
.leaflet-tooltip-left {
margin-left: -6px;
}
.leaflet-tooltip-right {
margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
top: 50%;
margin-top: -6px;
}
.leaflet-tooltip-left:before {
right: 0;
margin-right: -12px;
border-left-color: #fff;
}
.leaflet-tooltip-right:before {
left: 0;
margin-left: -12px;
border-right-color: #fff;
}
/* Printing */
@media print {
/* Prevent printers from removing background-images of controls. */
.leaflet-control {
-webkit-print-color-adjust: exact;
color-adjust: exact;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
Ajout de la license
#mapid css != galeriegps

View File

@ -0,0 +1,91 @@
<?php
/* @license GNU General Public License, version 3
* création @Lionel Croquefer 2019
* Version du 17 septembre 2023
*/
$lat = $_GET['lat'];
$lon = $_GET['lon'];
$altitude = $_GET['alt'];
if ($altitude > 0) { $alt = $altitude; }
else {
$alt = "'indéterminée ou 0'";
}
$zoom = $_GET['zoom'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Mapop</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="leaflet/leaflet.css">
<link rel="stylesheet" href="leaflet/Control.FullScreen.css">
<script src="leaflet/leaflet.js"></script>
<script src="leaflet/Control.FullScreen.js"></script>
<style>
html, body{
width: 100vw;
height: 100%;
}
body {
padding: 0;
margin: 0;
}
#mapid {
width: 100%;
height: 95vh;
}
@media (max-width: 768px) {
#mapid {
height: 100vh;
}
}
</style>
</head>
<body>
<div id="mapid"> </div>
<script>
var mymap = L.map('mapid',{
fullscreenControl: true,
fullscreenControlOptions: {
position: 'topleft'
}}).setView([<?=$lat?>, <?=$lon?>], <?=$zoom?>);
var baselayers = {
"OpenTopoMap": L.tileLayer("https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png", {
maxZoom: 17,
attribution: '&copy; <a href="//opentopomap.org/about" target="_blank">OpenTopoMap</a> | SRTM (CC-BY-SA)'
}),
"OpenStreetMap": L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: '&copy; <a href="//www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>'
}),
"MapsRefugesInfo": L.tileLayer("https://maps.refuges.info/hiking/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: '&copy; <a href="//wiki.openstreetmap.org/wiki/Hiking/mri" target="_blank">sly</a> | <a href="//www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>'
}),
"Satellite" : L.tileLayer("https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", {
maxZoom: 18,
attribution: '&copy; <a href="//www.esri.com/fr-fr/" target="_blank">Esri</a> ArcGIS'
})
};
var marker = L.marker([<?=$lat?>, <?=$lon?>]).addTo(mymap)
.bindPopup('altitude = '+ <?=$alt?> +' m')
.openPopup();
var layerControl = L.control.layers(baselayers).addTo(mymap);
baselayers.Satellite.addTo(mymap);
L.control.layers(baselayers, overlayMaps).addTo(mymap);
// detect fullscreen toggling
mymap.on('enterFullscreen', function(){
if(window.console) window.console.log('enterFullscreen');
});
mymap.on('exitFullscreen', function(){
if(window.console) window.console.log('exitFullscreen');
});
</script>
</body>
</html>

View File

@ -0,0 +1,69 @@
<?php
/* création @Lionel 2019
Version du 16 juillet 2022 */
$lat = $_GET['lat'];
$lon = $_GET['lon'];
$altitude = $_GET['alt'];
if ($altitude > 0) { $alt = $altitude; }
else {
$alt = "'indéterminée ou 0'";
}
$zoom = $_GET['zoom'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Mapop</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="leaflet/leaflet.css">
<link rel="stylesheet" href="leaflet/Control.FullScreen.css">
<script src="leaflet/leaflet.js"></script>
<script src="leaflet/Control.FullScreen.js"></script>
<style>
html, body{
width: 100vw;
height: 100%;
}
body {
padding: 0;
margin: 0;
}
#mapid {
width: 100%;
height: 95vh;
}
@media (max-width: 768px) {
#mapid {
height: 100vh;
}
}
</style>
</head>
<body>
<div id="mapid"> </div>
<script>
var mymap = L.map('mapid',{
fullscreenControl: true,
fullscreenControlOptions: {
position: 'topleft'
}}).setView([<?=$lat?>, <?=$lon?>], <?=$zoom?>);
L.tileLayer('https://wxs.ign.fr/cartes/geoportail/wmts?LAYER=GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2&EXCEPTIONS=text/xml&FORMAT=image/png&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE=normal&TILEMATRIXSET=PM&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}', {
maxZoom: 20,
maxNativeZoom: 18,
attribution: '&copy;IGN <a href="https://www.geoportail.gouv.fr/" target="_blank" rel="noopener">Geoportail</a> <a href="https://www.geoportail.gouv.fr/mentions-legales" target="_blank" rel="noopener">Terms of Service</a>'
}).addTo(mymap);
var marker = L.marker([<?=$lat?>, <?=$lon?>]).addTo(mymap)
.bindPopup('altitude = '+ <?=$alt?> +' m')
.openPopup();
// detect fullscreen toggling
mymap.on('enterFullscreen', function(){
if(window.console) window.console.log('enterFullscreen');
});
mymap.on('exitFullscreen', function(){
if(window.console) window.console.log('exitFullscreen');
});
</script>
</body>
</html>

View File

@ -0,0 +1,68 @@
<?php
/* création des miniatures par @Lionel 2019
* vignettes en webp le 15 janv. 2023
*/
if (!isset($_GET['img']))
{
exit(0);
}
function makeDir($dir) {
if ( (is_dir($dir))||(file_exists($dir)) ) { return true; }
else {
if (mkdir($dir,0755)) { return true; }
else { return false; }
}
}
$ratio = 200;
$img = '../../../'.$_GET['img'];
$dossiercache = '../../../site/file/cache';
makeDir($dossiercache);
$par = substr(strrchr($img, '/'), 1);
$url_par = str_replace('/'.$par,'',$img);
$cache = substr(strrchr($url_par, '/'), 1);
makeDir($dossiercache.'/'.$cache);
$extension = strrchr($par,'.');
$vignette = str_replace($extension,'',$par);
$miniature = $dossiercache.'/'.$cache.'/'.$vignette.'.webp';
if(!file_exists($miniature))
{
$imginfo = getimagesize($img);
$largeur = $imginfo[0];
$hauteur = $imginfo[1];
$type = $imginfo[2];
if($type == 1)
{
$src = imagecreatefromgif($img);
}
elseif($type == 2)
{
$src = imagecreatefromjpeg($img);
}
elseif($type == 3)
{
$src = imagecreatefrompng($img);
}
elseif($type == 18)
{
$src = imagecreatefromwebp($img);
}
imageinterlace($src, true);
if ($largeur > $hauteur)
{
$im = imagecreatetruecolor(round(($ratio/$hauteur)*$largeur), $ratio);
imagecopyresampled($im, $src, 0, 0, 0, 0, round(($ratio/$hauteur)*$largeur), $ratio, $largeur, $hauteur);
}
else
{
$im = imagecreatetruecolor($ratio, round(($ratio/$largeur)*$hauteur));
imagecopyresampled($im, $src, 0, 0, 0, 0, $ratio, round($hauteur*($ratio/$largeur)), $largeur, $hauteur);
}
imagewebp($im, $miniature, 80);
imagedestroy($im);
}
header('Content-Type: image/webp');
$data = file_get_contents($miniature);
echo $data;
clearstatcache();
?>

3
module/album/vendor/js/inc.json vendored Normal file
View File

@ -0,0 +1,3 @@
[
]

View File

@ -0,0 +1,3 @@
[
"size.js"
]

View File

@ -0,0 +1,3 @@
[
"size.js"
]

29
module/album/vendor/js/size.js vendored Normal file
View File

@ -0,0 +1,29 @@
$(function () {
// @Lionel 2019
//var taille = getComputedStyle(site).width;//#site en px
var taille = $('.container').css('max-width');//taille .container en px
switch(taille)
{
case '75vw':
$('a.galleryPicture').css('height', '165px');//view/index
$('a.galleryGalleryPicture').css('height', '110px');//view/gallery
$('div.galleryGalleryName').css('font-size', '0.8em');//view/gallery
break;
case '85vw':
$('a.galleryPicture').css('height', '200px');
$('a.galleryGalleryPicture').css('height', '135px');
$('div.galleryGalleryName').css('font-size', '0.85em');
break;
case '95vw':
$('a.galleryPicture').css('height', '235px');
$('a.galleryGalleryPicture').css('height', '160px');
$('div.galleryGalleryName').css('font-size', '0.9em');
break;
default:
$('a.galleryPicture').css('height', '250px');
$('a.galleryGalleryPicture').css('height', '185px');
$('div.galleryGalleryName').css('font-size', '1em');
break;
}//*/
});

27
module/album/vendor/js/size.js.backup vendored Normal file
View File

@ -0,0 +1,27 @@
$(function () {
// @Lionel 2019
var taille = getComputedStyle(site).width;
switch(taille)
{
case '750px':
$('a.galleryPicture').css('height', '165px');
$('a.galleryGalleryPicture').css('height', '110px');
$('div.galleryGalleryName').css('font-size', '0.8em');
break;
case '960px':
$('a.galleryPicture').css('height', '200px');
$('a.galleryGalleryPicture').css('height', '135px');
$('div.galleryGalleryName').css('font-size', '0.85em');
break;
case '1170px':
$('a.galleryPicture').css('height', '235px');
$('a.galleryGalleryPicture').css('height', '160px');
$('div.galleryGalleryName').css('font-size', '0.9em');
break;
default:
$('a.galleryPicture').css('height', '250px');
$('a.galleryGalleryPicture').css('height', '185px');
$('div.galleryGalleryName').css('font-size', '1em');
break;
}
});

36
module/album/vendor/js/size.js.php vendored Normal file
View File

@ -0,0 +1,36 @@
<?php
echo '</script>';
$largeur_site = $this->getData(['theme', 'site', 'width' ]);
echo '<script>';
?>
$(function () {
// @Lionel 2019
var taille = '<?=$largeur_site?>';
switch(taille)
{
case '75vw':
$('a.galleryPicture').css('height', '165px');//view/index
$('a.galleryGalleryPicture').css('height', '110px');//view/gallery
$('div.galleryGalleryName').css('font-size', '0.8em');//view/gallery
break;
case '85vw':
$('a.galleryPicture').css('height', '200px');
$('a.galleryGalleryPicture').css('height', '135px');
$('div.galleryGalleryName').css('font-size', '0.85em');
break;
case '95vw':
$('a.galleryPicture').css('height', '235px');
$('a.galleryGalleryPicture').css('height', '160px');
$('div.galleryGalleryName').css('font-size', '0.9em');
break;
default:
$('a.galleryPicture').css('height', '250px');
$('a.galleryGalleryPicture').css('height', '185px');
$('div.galleryGalleryName').css('font-size', '1em');
break;
}//*/
});

3
module/album/vendor/tablednd/inc.json vendored Normal file
View File

@ -0,0 +1,3 @@
[
"tablednd.min.js"
]

View File

@ -0,0 +1,3 @@
[
"tablednd.min.js"
]

View File

@ -0,0 +1 @@
https://github.com/isocra/TableDnD

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
/*admin.css*/
.galleryConfigError {
color: #F3674A;
font-weight: bold;
}

View File

@ -0,0 +1,95 @@
/**
* This file is part of DeltaCMS.
*/
$( document ).ready(function() {
/**
* Tri de la galerie avec drag and drop
*/
$("#galleryTable").tableDnD({
onDrop: function(table, row) {
$("#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();
},
// Supprime le tiret des séparateurs
serializeRegexp: ""
});
/**
* Confirmation de suppression
*/
$(".galleryConfigDelete").on("click", function() {
var _this = $(this);
return core.confirm(textConfirm, 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 textshort = result[i];
textshort = textshort.replace("site/file/source/","");
var option = $("<option>").val(result[i]).text(textshort);
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());
});
/**
* Tri dynamique des galeries
*/
function sortGalleries() {
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/sortGalleries";
var data = $("#galleryConfigFilterResponse").val();
$.ajax({
type: "POST",
url: url ,
data: {
response : data
}
});
}

View File

@ -0,0 +1,65 @@
<?php
// Lexique
$param = '';
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
echo template::formOpen('galleryConfigForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('galleryConfigBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'ico' => 'left',
'value' => $text['album_view']['config'][0]
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<div class="blockTitle"><?php echo $text['album_view']['config'][2]; ?></div>
<div class="row">
<div class="col6">
<?php echo template::text('galleryConfigName', [
'label' => $text['album_view']['config'][3]
]); ?>
</div>
<div class="col5">
<?php echo template::hidden('galleryConfigDirectoryOld', [
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
<?php echo template::select('galleryConfigDirectory', [], [
'label' => $text['album_view']['config'][4],
'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>
<?php echo template::formClose(); ?>
<div class="row">
<div class="col12">
<div class="block">
<div class="blockTitle"><?php echo $text['album_view']['config'][5]; ?></div>
<?php if($module::$galleries): ?>
<?php echo template::table([1, 4, 5, 1, 1], $module::$galleries, ['',$text['album_view']['config'][3], $text['album_view']['config'][4], '', ''], ['id' => 'galleryTable'],$module::$galleriesId); ?>
<?php echo template::hidden('galleryConfigFilterResponse'); ?>
<?php else: ?>
<?php echo template::speech($text['album_view']['config'][7]); ?>
<?php endif; ?>
</div>
<div class="moduleVersion">
<?php echo $text['album_view']['config'][8]; echo $module::VERSION; ?>
</div>
</div>
<script>
var textConfirm = <?php echo '"'.$text['album_view']['config'][6].'"'; ?>;
</script>

View File

@ -0,0 +1,7 @@
/*admin.css*/
td.col1 {
text-align: center;
}
.config {
max-height: 60px;
}

View File

@ -0,0 +1,107 @@
/**
* This file is part of DeltaCMS.
*/
/**
* Liste des dossiers
*/
var oldResult = [];
var directoryDOM = $("#galleryEditDirectory");
var directoryOldDOM = $("#galleryEditDirectoryOld");
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 textshort = result[i];
textshort = textshort.replace("site/file/source/","");
var option = $("<option>").val(result[i]).text(textshort);
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());
});
$('.homePicture').click(function(){
$('.homePicture').prop('checked', false);
$(this).prop('checked', true);
});
/**
* Tri dynamique de la galerie
*/
$( document ).ready(function() {
$("#galleryTable").tableDnD({
onDrop: function(table, row) {
$("#galleryEditFormResponse").val($.tableDnD.serialize());
sortPictures();
},
serializeRegexp: ""
});
if ($("#galleryEditSort").val() !== "SORT_HAND") {
$("#galleryTable tr").addClass("nodrag nodrop");
$(".zwiico-sort").hide();
$("#galleryTable").tableDnDUpdate();
} else {
$("#galleryTable tr").removeClass("nodrag nodrop");
$(".zwiico-sort").show();
$("#galleryTable").tableDnDUpdate();
}
});
$("#galleryEditSort").change(function() {
if ($("#galleryEditSort").val() !== "SORT_HAND") {
$("#galleryTable tr").addClass("nodrag nodrop");
$(".zwiico-sort").hide();
$("#galleryTable").tableDnDUpdate();
} else {
$("#galleryTable tr").removeClass("nodrag nodrop");
$(".zwiico-sort").show();
$("#galleryTable").tableDnDUpdate();
}
});
/**
* Tri dynamique des images
*/
function sortPictures() {
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/sortPictures";
var d1 = $("#galleryEditFormResponse").val();
var d2 = $("#galleryEditFormGalleryName").val();
//var data = $('#galleryEditForm').serialize();
$.ajax({
type: "POST",
url: url ,
data: {
response : d1,
gallery: d2
}
});
}

View File

@ -0,0 +1,70 @@
<?php
// Lexique
$param = "album_view";
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
echo template::formOpen('galleryEditForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('galleryEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
'ico' => 'left',
'value' => $text['album_view']['edit'][0]
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('galleryEditSubmit',[
'value' => $text['album_view']['edit'][1]
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<div class="blockTitle"><?php echo $text['album_view']['edit'][2]; ?></div>
<div class="row">
<div class="col5">
<?php echo template::text('galleryEditName', [
'label' => $text['album_view']['edit'][3],
'value' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'config', 'name']),
'readonly' => $this->getUser('group') >= self::GROUP_MODERATOR ? false : true
]); ?>
</div>
<div class="col4 <?php if($this->getUser('group') < self::GROUP_MODERATOR) echo 'displayNone'; ?>">
<?php echo template::hidden('galleryEditDirectoryOld', [
'value' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'config', 'directory']),
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
<?php echo template::select('galleryEditDirectory', [], [
'label' => $text['album_view']['edit'][4],
'noDirty' => true // Désactivé à cause des modifications en ajax
]); ?>
</div>
<div class="col3">
<?php echo template::select('galleryEditSort', $sort, [
'selected' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'config', 'sort']),
'label' => $text['album_view']['edit'][5],
'help' => $text['album_view']['edit'][6]
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php if($module::$pictures): ?>
<?php echo template::table([1, 4, 1, 5, 1], $module::$pictures, ['',$text['album_view']['edit'][7], $text['album_view']['edit'][8],$text['album_view']['edit'][9],''],['id' => 'galleryTable'], $module::$picturesId ); ?>
<?php echo template::hidden('galleryEditFormResponse'); ?>
<?php echo template::hidden('galleryEditFormGalleryName',['value' => $this->getUrl(2)]); ?>
<?php else: ?>
<?php echo template::speech($text['album_view']['edit'][10]); ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<div class="moduleVersion">
<?php echo $text['album_view']['edit'][11]; echo $module::VERSION; ?>
</div>
<?php echo template::formClose(); ?>

View File

@ -0,0 +1,74 @@
.gallery {
padding: 5px;
position: relative;
}
.galleryGalleryPicture {
display: flex;
align-items: center;
justify-content: center;
position: relative;
height: 185px;/*fluide*/
max-height: 36vmin;
text-align: center;
background-color: rgba(230, 230, 230, 0.7);
border: 1px solid #ddd;
border-radius: 6px;
transition: background-color 1.3s ease;
}
.galleryGalleryPicture:hover {
background-color: rgb(192, 192, 192);
}
.galleryGalleryName {
position: absolute;
left: 0;
right: 0;
bottom: 0;
line-height: 1.2;
color: #000;
overflow: hidden;
font-size: 0.85em;
}
.galleryGalleryPicture img {
max-height: 80%;
max-width: 95%;
}
.picResized {
color: crimson;
}
.osm {
position: absolute;
left:10px;
bottom:10px;
}
/* adaptation */
@media (max-width: 1281px) {
.galleryGalleryPicture {
height: 160px;
}
}
@media (max-width: 1025px) {
.galleryGalleryPicture {
height: 135px;
}
.galleryGalleryName {
font-size: 0.75em;
}
}
@media (max-width: 813px) {
.galleryGalleryPicture {
height: 120px;
}
}
@media (max-width: 799px) {
section > .row:not(.back) {
display: flex;
flex-wrap: wrap;
padding: 0 10px;
}
.gallery {
flex: 0 0 33.3333%;
}
.col2:not(.gallery) {
width: inherit;
}
}

View File

@ -0,0 +1,13 @@
/**
* This file is part of DeltaCMS.
*/
/**
* Galerie d'image
*/
$(".galleryGalleryPicture").simpleLightbox({
captionSelector: "self",
captionType: "data",
captionsData: "caption",
closeText: "&times;"
});

View File

@ -0,0 +1,78 @@
<?php
// Lexique
$param = '';
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
?>
<div class="row back">
<div class="col2">
<?php echo template::button('galleryGalleryBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(0),
'ico' => 'left',
'value' => $text['album_view']['gallery'][0]
]); ?>
</div>
</div>
<?php
$i = 1;
$picturesNb = count($module::$pictures);
foreach($module::$pictures as $picture => $legend):
// détermination des photos redimensionnées et originales
$photo = basename($picture);
$url_photo = dirname($picture);
$photo_960 = strpos($photo, 't960.');
$original = str_replace('_t960','',$photo);
$urloriginal = $url_photo.'/backup/'.strtolower($original);
$urlback = (isset($urloriginal)) ? $urloriginal : 0;
if (file_exists($urloriginal)) {
$get_location = albumHelper::gps_exif($urloriginal);
}
else {
$get_location = albumHelper::gps_exif($picture);
}
?>
<?php if($i % 6 === 1): ?>
<div class="row">
<?php endif; ?>
<div class="col2 gallery">
<a href="<?php echo helper::baseUrl(false) . $picture; ?>" class="galleryGalleryPicture" data-caption="<?php echo $legend; ?>">
<img src="<?php echo helper::baseUrl(false) ?>module/album/plugins/thumbnailer.php?img=<?php echo $picture; ?>" alt="<?php echo $legend; ?>">
<?php if ($photo_960 !== false): ?>
<div class="galleryGalleryName picResized" onclick="window.open('<?=helper::baseUrl(false).$urlback?>');" data-tippy-content="image originale">
<?php else: ?>
<div class="galleryGalleryName">
<?php endif;
if (!empty($legend)):
echo $legend;
// nettoyage et affichage du nom des images
else:
$separe = array('_','-','t960');
$picname = str_replace($separe, ' ', $photo);
$picname = preg_replace('/(\.jpe?g|\.png|\.gif|\.webp)$/i', '', $picname);
echo substr($picname,0,25);
endif;
?>
</div>
</a>
<?php
// ajout du marqueur aux images contenant des données exif gps
$data = (isset($get_location)) ? $get_location : NULL;
$lis = explode('¤',$data);
if ( ! isset($lis[1])) { $lis[1] = null; }
else {
$altitude = '';
if ( (isset($lis[2])) && (is_int($lis[2]) !== false) && ($lis[2] > 0) ) {
$alt = $lis[2];
}
$exif_data = "lat=".$lis[0]."&lon=".$lis[1]."&alt=".$lis[2]."&zoom=15";
?>
<div class="osm"><a href="<?=helper::baseUrl(false)?>module/album/plugins/map.php?<?=$exif_data?>" rel="data-lity" title="<?=$text['album_view']['gallery'][1]?>"><img src="<?=helper::baseUrl(false)?>module/album/plugins/leaflet/images/marker-icon.png" style="width: 20px; height: auto;" alt="GPS"></a></div>
<?php } ?>
</div>
<?php if($i % 6 === 0 OR $i === $picturesNb): ?>
</div>
<?php
endif;
$i++;
endforeach;
?>

View File

@ -0,0 +1,76 @@
.col3 {
padding: 5px;
}
.galleryPicture {
display: flex;
align-items: center;
justify-content: center;
position: relative;
height: 220px;
max-height: 50vmin;
text-align: center;
background-color: rgba(230, 230, 230, 0.7);
border: 1px solid #ddd;
border-radius: 6px;
transition: background-color 1.3s ease;
}
.galleryPicture:hover {
background-color: rgb(192, 192, 192);
}
.galleryName {
position: absolute;
left: 0;
right: 0;
bottom: 0;
line-height: 1.5;
color: #000;
font-size: 0.85em;
}
.galleryPicture img {
max-height: 80%;
max-width: 95%;
}
/* adaptation */
@media (max-width: 1281px) {
.galleryPicture {
height: 210px;
}
}
@media (max-width: 1025px) {
.galleryPicture {
height: 180px;
}
.galleryName {
font-size: 0.75em;
}
}
@media (max-width: 961px) {
.galleryPicture {
height: 165px;
}
}
@media (max-width: 799px) {
section > .row {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
}
section > .row > .col3 {
max-width: 50%;
}
}
@media (max-width: 799px) and (orientation: portrait) {
.galleryPicture {
max-height: 45vmin;
}
}
@media (min-width: 768px) and (max-width: 799px) and (orientation: portrait) {
section > .row {
display: flex;
flex-wrap: wrap;
justify-content: start;
}
.col3 {
flex: 0 0 25%;
}
}

View File

@ -0,0 +1,34 @@
<!-- version <?php echo $module::VERSION; ?> de l'album -->
<?php
// Lexique
$param = '';
include('./module/album/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_album.php');
if($module::$galleries):
$i = 1;
$galleriesNb = count($module::$galleries);
foreach($module::$galleries as $galleryId => $gallery):
if($i % 4 === 1):
?>
<div class="row">
<?php endif; ?>
<div class="col3">
<a href="<?php echo helper::baseUrl() . $this->getUrl(0); ?>/<?php echo $galleryId; ?>" class="galleryPicture">
<img src="<?php if ($this->getData(['module', $this->getUrl(0), $galleryId, 'config', 'homePicture']) === null ) {
echo helper::baseUrl(false) . 'module/album/plugins/thumbnailer.php?img=' . $module::$firstPictures[$galleryId]; }
else {
echo helper::baseUrl(false) . 'module/album/plugins/thumbnailer.php?img=' . $this->getData(['module', $this->getUrl(0), $galleryId, 'config', 'directory']) . '/' . $this->getData(['module', $this->getUrl(0), $galleryId, 'config', 'homePicture']);
} ?>" alt="<?php echo $gallery['config']['name']; ?>">
<div class="galleryName"><?php echo $gallery['config']['name']; ?></div>
</a>
</div>
<?php if($i % 4 === 0 OR $i === $galleriesNb): ?>
</div>
<?php
endif;
$i++;
endforeach;
else:
echo template::speech($text['album_view']['index'][0]);
endif;
?>