@ -2,7 +2,7 @@
define ( 'DEFAULT_TITLE' , 'Mon panier bio' );
define ( 'SUPPLIER_REGEX' , '[A-Za-z]\w{0,31}' );
define ( 'SUPPLIER_REGEX' , '[A-Za-z]\w{0,31}(-\w+)? ' );
define ( 'EVENT_REGEX' , '\d{4}\-[01]\d\-[0123]\d' );
define ( 'EVENT_FORMAT' , 'Y-m-d' );
define ( 'REQUEST_REGEX' , '/^https?:\/\/.+\/(?<supplier>' . SUPPLIER_REGEX . ')\/?(?<event>' . EVENT_REGEX . ')?\/?$/' );
@ -52,15 +52,16 @@ function generatePassword($length = 20) {
range ( '0' , '9' ),
[ '!' , '?' , '~' , '@' , '#' , '$' , '%' , '*' , ';' , ':' , '-' , '+' , '=' , ',' , '.' , '_' ]
);
$value = '' ;
while ( $length -- > 0 )
$value .= $chars [ mt_rand ( 0 , count ( $chars ) - 1 )];
return $value ;
}
function generateUrl ( $supplier = null , $event = null ) {
function generateUrl ( $supplier = null , $event = null , $iframe = null ) {
global $requestUrl , $inIframe ;
$queryString = $inIframe ? '?iframe' : '' ;
$queryString = ( $inIframe or ! is_null ( $iframe )) ? '?iframe' : '' ;
if ( is_null ( $supplier ))
return $requestUrl . $queryString ;
@ -113,271 +114,299 @@ define('DATA_FILE', __DIR__ . DIRECTORY_SEPARATOR . 'data.php');
if ( file_exists ( CONFIG_FILE )) require_once CONFIG_FILE ;
if ( ! isset ( $config )) $config = [];
$availableLocations = [];
foreach ( array_keys ( $config ) as $supplier ) {
$hasLocation = (( $pos = strpos ( $supplier , '-' )) !== false );
if ( ! $hasLocation )
continue ;
$locationKey = substr ( $supplier , ( $pos + 1 ));
$shortSupplier = substr ( $supplier , 0 , $pos );
$locationValue = empty ( $config [ $supplier ][ 'location' ]) ? $locationKey : $config [ $supplier ][ 'location' ];
$availableLocations [ $shortSupplier ][ $locationKey ] = $locationValue ;
}
$inIframe = isset ( $_REQUEST [ 'iframe' ]);
$action = ( isset ( $_REQUEST [ 'action' ]) and preg_match ( ACTION_REGEX , $_REQUEST [ 'action' ])) ? $_REQUEST [ 'action' ] : null ;
$supplier = array_key_exists ( 'supplier' , $_REQUEST ) ? $_REQUEST [ 'supplier' ] : $requestSupplier ;
$hasLocation = (( $pos = strpos ( $supplier , '-' )) !== false );
if ( $hasLocation ) {
$location = substr ( $supplier , ( $pos + 1 ));
}
$hasSupplier = is_string ( $supplier ) and preg_match ( '/^' . SUPPLIER_REGEX . '$/' , $supplier );
$excludesFormatter = new \IntlDateFormatter ( 'fr_FR.UTF8' , \IntlDateFormatter :: SHORT , \IntlDateFormatter :: NONE , 'Europe/Paris' );
$supplierIsNew = false ;
if ( $hasSupplier ) {
if ( ! isset ( $config [ $supplier ])) {
$config [ $supplier ] = [];
$supplierIsNew = true ;
}
$config [ $supplier ] = array_merge (
[
'title' => '' ,
'subtitle' => '<small class="%color% text-nowrap d-block d-sm-inline">%date% (%ago%)</small>' ,
'description' => '' ,
'choices' => [],
'start' => 'now 00:00:00' ,
'end' => '+1 year 23:59:59' ,
'frequency' => '1 day' ,
'password' => '' ,
'excludes' => [],
],
$config [ $supplier ]
);
$hasPassword = ! empty ( $config [ $supplier ][ 'password' ]);
if ( $action === 'config' ) {
if ( $hasPassword ) {
if ( ! isset ( $_SERVER [ 'PHP_AUTH_USER' ])) {
header ( sprintf ( 'WWW-Authenticate: Basic realm="Configuration de mon panier bio pour %s"' , $supplier ));
header ( 'HTTP/1.0 401 Unauthorized' );
printf ( 'Cette configuration est protégée par mot de passe !' );
exit ;
} elseif (
( $_SERVER [ 'PHP_AUTH_USER' ] !== $supplier )
or ( $_SERVER [ 'PHP_AUTH_PW' ] !== $config [ $supplier ][ 'password' ])
) {
header ( 'HTTP/1.0 403 Forbidden' );
printf ( 'Cette configuration est protégée par mot de passe !' );
exit ;
}
}
foreach ( array_keys ( $config [ $supplier ]) as $key )
if ( isset ( $_REQUEST [ $key ]))
$config [ $supplier ][ $key ] = ( ! in_array ( $key , [ 'title' , 'subtitle' , 'description' ]) ? filter_var ( $_REQUEST [ $key ], FILTER_SANITIZE_STRING ) : $_REQUEST [ $key ]);
}
if ( empty ( $config [ $supplier ][ 'start' ]))
$config [ $supplier ][ 'start' ] = 'now 00:00:00' ;
foreach ([ 'choices' , 'excludes' ] as $key ) {
if ( is_string ( $config [ $supplier ][ $key ]))
$config [ $supplier ][ $key ] = explode ( PHP_EOL , $config [ $supplier ][ $key ]);
if ( ! is_array ( $config [ $supplier ][ $key ]))
$config [ $supplier ][ $key ] = [];
$config [ $supplier ][ $key ] = array_filter (
$config [ $supplier ][ $key ],
function ( $choice ) {
return is_string ( $choice ) and ! empty ( trim ( $choice ));
}
);
$config [ $supplier ][ $key ] = array_map ( 'trim' , $config [ $supplier ][ $key ]);
}
$config [ $supplier ][ 'excludes' ] = array_filter (
array_map (
function ( $value ) use ( $excludesFormatter ) {
if ( preg_match ( '/^\d{4}-\d{2}-\d{2}$/' , $value ))
return $value ;
$timestamp = $excludesFormatter -> parse ( $value , $offset );
if ( $timestamp !== false )
return ( new \DateTimeImmutable ( '@' . $timestamp , new \DateTimeZone ( 'Europe/Paris' ))) -> format ( 'Y-m-d' );
try {
return ( new \DateTimeImmutable ( $value , new \DateTimeZone ( 'Europe/Paris' ))) -> format ( 'Y-m-d' );
} catch ( \Exception $exception ) {
return null ;
}
},
$config [ $supplier ][ 'excludes' ]
),
function ( $value ) {
return ! is_null ( $value );
}
);
}
$isConfig = false ;
if ( $action === 'config' ) {
$output = fopen ( CONFIG_FILE , 'w+' );
if ( $output ) {
if ( flock ( $output , LOCK_EX )) {
fwrite ( $output , '<?php' . PHP_EOL );
fprintf (
$output ,
'$config = %s;' . PHP_EOL ,
var_export ( $config , true )
);
flock ( $output , LOCK_UN );
}
fclose ( $output );
}
$isConfig = true ;
}
$suppliers = array_keys ( $config );
sort ( $suppliers );
try {
$event = array_key_exists ( 'event' , $_REQUEST ) ? $_REQUEST [ 'event' ] : $requestEvent ;
$hasEvent = (
is_string ( $event )
and preg_match ( '/^' . EVENT_REGEX . '$/' , $event )
and (( new \DateTimeImmutable ( $event )) instanceof \DateTimeImmutable )
);
} catch ( \Exception $exception ) {
$hasEvent = false ;
}
if ( ! $isConfig and ! $supplierIsNew and $hasSupplier ) {
$start = new \DateTime ( $config [ $supplier ][ 'start' ]);
if ( ! $hasEvent ) {
$next = findNext ( $start , $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], true );
$nextEvent = $next -> format ( 'Y-m-d' );
header ( 'Location: ' . generateUrl ( $supplier , $nextEvent ));
die ();
} else {
$current = new \DateTime ( $event );
$previous = findPrevious ( $current , $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], false );
$previousEvent = $previous -> format ( 'Y-m-d' );
if ( false and ! array_key_exists ( $previousEvent , $data [ $supplier ]))
unset ( $previousEvent );
$first = new \DateTime ( $config [ $supplier ][ 'start' ]);
if ( true and ( $previous -> getTimestamp () < $first -> getTimestamp ()))
unset ( $previousEvent );
$next = findNext ( $current , $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], false );
$nextEvent = $next -> format ( 'Y-m-d' );
if ( false and ! array_key_exists ( $nextEvent , $data [ $supplier ]))
unset ( $nextEvent );
$last = new \DateTime ( $config [ $supplier ][ 'end' ]);
if ( true and ( $next -> getTimestamp () > $last -> getTimestamp ()))
unset ( $nextEvent );
}
switch ( $action ) {
case 'insert' :
case 'delete' :
$item = [];
foreach ([ 'name' , 'choice' , 'action' ] as $field )
$item [ $field ] = filter_var ( $_REQUEST [ $field ], FILTER_SANITIZE_STRING );
$item [ 'timestamp' ] = time ();
$hash = md5 ( implode ([ trim ( $item [ 'name' ]), $item [ 'choice' ], ]));
$item [ 'hash' ] = $hash ;
$isBeginning = ( ! file_exists ( DATA_FILE ) or in_array ( filesize ( DATA_FILE ), [ false , 0 ]));
$output = fopen ( DATA_FILE , 'a+' );
if ( ! $output ) break ;
if ( ! flock ( $output , LOCK_EX )) break ;
if ( $isBeginning )
fwrite ( $output , '<?php' . PHP_EOL );
fprintf (
$output ,
'$data[%s][%s][] = %s;' . PHP_EOL ,
var_export ( $supplier , true ),
var_export ( $event , true ),
str_replace ( PHP_EOL , '' , var_export ( $item , true ))
);
flock ( $output , LOCK_UN );
fclose ( $output );
header ( 'Location: ' . generateUrl ( $supplier , $event ));
die ();
}
if ( ! isset ( $data )) $data = [];
if ( file_exists ( DATA_FILE )) include DATA_FILE ;
$items = [];
$allItems = isset ( $data [ $supplier ][ $event ]) ? $data [ $supplier ][ $event ] : [];
usort ( $allItems , function ( $a , $b ) {
$a = intval ( $a [ 'timestamp' ]);
$b = intval ( $b [ 'timestamp' ]);
if ( $a === $b )
return 0 ;
return ( $a < $b ) ? - 1 : 1 ;
});
foreach ( $allItems as $item ) {
if ( $item [ 'action' ] === 'insert' ) {
$alreadyInserted = false ;
foreach ( $items as $index => $prevItem )
if ( $prevItem [ 'hash' ] === $item [ 'hash' ])
$alreadyInserted = true ;
if ( ! $alreadyInserted )
$items [] = $item ;
} elseif ( $item [ 'action' ] === 'delete' ) {
foreach ( $items as $index => $prevItem )
if ( $prevItem [ 'hash' ] === $item [ 'hash' ])
unset ( $items [ $index ]);
}
}
$date = ( new \IntlDateFormatter ( 'fr_FR.UTF8' , \IntlDateFormatter :: FULL , \IntlDateFormatter :: NONE , 'Europe/Paris' )) -> format ( new \DateTime ( $event ));
$ago = ago ( new \DateTimeImmutable ( $event ));
$color = isInPast ( $event ) ? 'text-danger' : 'text-muted' ;
$currentEvent = findNext ( new \DateTime ( $config [ $supplier ][ 'start' ]), $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], true );
$currentDate = ( new \IntlDateFormatter ( 'fr_FR.UTF8' , \IntlDateFormatter :: FULL , \IntlDateFormatter :: NONE , 'Europe/Paris' )) -> format ( $currentEvent );
$currentAgo = ago ( $currentEvent );
foreach ([ 'title' , 'subtitle' , 'description' ] as $key ) {
while ( preg_match ( '/%([^%]+)%/i' , $config [ $supplier ][ $key ], $match ))
$config [ $supplier ][ $key ] = str_replace (
$match [ 0 ],
$ { $match [ 1 ]},
$config [ $supplier ][ $key ]
);
}
if ( empty ( $config [ $supplier ][ 'title' ]))
$config [ $supplier ][ 'title' ] = $supplier ;
$stats = [];
foreach ( $items as $item )
if ( ! empty ( $item [ 'choice' ]))
$stats [ $item [ 'choice' ]] += 1 ;
}
if ( $supplierIsNew and ! empty ( $suppliers )) {
$closestSuppliers = array_filter (
array_map (
function ( $other ) use ( $supplier ) {
return [
'supplier' => $other ,
'score' => levenshtein ( $supplier , $other ),
];
},
$suppliers
),
function ( $item ) {
return $item [ 'score' ] > 0 ;
}
);
usort ( $closestSuppliers , function ( $a , $b ) {
if ( $a [ 'score' ] == $b [ 'score' ]) {
return 0 ;
}
return ( $a [ 'score' ] < $b [ 'score' ]) ? - 1 : 1 ;
});
if (
$hasSupplier
and ! isset ( $config [ $supplier ])
and ! $hasLocation
and is_array ( $availableLocations [ $supplier ])
and ! empty ( $availableLocations [ $supplier ])
) {
$supplierNeedLocation = true ;
} else {
$supplierNeedLocation = false ;
$supplierIsNew = false ;
if ( $hasSupplier ) {
if ( ! isset ( $config [ $supplier ])) {
$config [ $supplier ] = [];
$supplierIsNew = true ;
}
$config [ $supplier ] = array_merge (
[
'title' => '' ,
'subtitle' => '<small class="%color% text-nowrap d-block d-sm-inline">%date% (%ago%)</small>' ,
'location' => '' ,
'description' => '' ,
'choices' => [],
'start' => 'now 00:00:00' ,
'end' => '+1 year 23:59:59' ,
'frequency' => '1 day' ,
'password' => '' ,
'excludes' => [],
],
$config [ $supplier ]
);
$hasPassword = ! empty ( $config [ $supplier ][ 'password' ]);
if ( $action === 'config' ) {
if ( $hasPassword ) {
if ( ! isset ( $_SERVER [ 'PHP_AUTH_USER' ])) {
header ( sprintf ( 'WWW-Authenticate: Basic realm="Configuration de mon panier bio pour %s"' , $supplier ));
header ( 'HTTP/1.0 401 Unauthorized' );
printf ( 'Cette configuration est protégée par mot de passe !' );
exit ;
} elseif (
( $_SERVER [ 'PHP_AUTH_USER' ] !== $supplier )
or ( $_SERVER [ 'PHP_AUTH_PW' ] !== $config [ $supplier ][ 'password' ])
) {
header ( 'HTTP/1.0 403 Forbidden' );
printf ( 'Cette configuration est protégée par mot de passe !' );
exit ;
}
}
foreach ( array_keys ( $config [ $supplier ]) as $key )
if ( isset ( $_REQUEST [ $key ]))
$config [ $supplier ][ $key ] = ( ! in_array ( $key , [ 'title' , 'subtitle' , 'description' ]) ? filter_var ( $_REQUEST [ $key ], FILTER_SANITIZE_STRING ) : $_REQUEST [ $key ]);
}
if ( empty ( $config [ $supplier ][ 'start' ]))
$config [ $supplier ][ 'start' ] = 'now 00:00:00' ;
foreach ([ 'choices' , 'excludes' ] as $key ) {
if ( is_string ( $config [ $supplier ][ $key ]))
$config [ $supplier ][ $key ] = explode ( PHP_EOL , $config [ $supplier ][ $key ]);
if ( ! is_array ( $config [ $supplier ][ $key ]))
$config [ $supplier ][ $key ] = [];
$config [ $supplier ][ $key ] = array_filter (
$config [ $supplier ][ $key ],
function ( $choice ) {
return is_string ( $choice ) and ! empty ( trim ( $choice ));
}
);
$config [ $supplier ][ $key ] = array_map ( 'trim' , $config [ $supplier ][ $key ]);
}
$config [ $supplier ][ 'excludes' ] = array_filter (
array_map (
function ( $value ) use ( $excludesFormatter ) {
if ( preg_match ( '/^\d{4}-\d{2}-\d{2}$/' , $value ))
return $value ;
$timestamp = $excludesFormatter -> parse ( $value , $offset );
if ( $timestamp !== false )
return ( new \DateTimeImmutable ( '@' . $timestamp , new \DateTimeZone ( 'Europe/Paris' ))) -> format ( 'Y-m-d' );
try {
return ( new \DateTimeImmutable ( $value , new \DateTimeZone ( 'Europe/Paris' ))) -> format ( 'Y-m-d' );
} catch ( \Exception $exception ) {
return null ;
}
},
$config [ $supplier ][ 'excludes' ]
),
function ( $value ) {
return ! is_null ( $value );
}
);
}
$isConfig = false ;
if ( $action === 'config' ) {
$output = fopen ( CONFIG_FILE , 'w+' );
if ( $output ) {
if ( flock ( $output , LOCK_EX )) {
fwrite ( $output , '<?php' . PHP_EOL );
fprintf (
$output ,
'$config = %s;' . PHP_EOL ,
var_export ( $config , true )
);
flock ( $output , LOCK_UN );
}
fclose ( $output );
}
$isConfig = true ;
}
$suppliers = array_keys ( $config );
sort ( $suppliers );
try {
$event = array_key_exists ( 'event' , $_REQUEST ) ? $_REQUEST [ 'event' ] : $requestEvent ;
$hasEvent = (
is_string ( $event )
and preg_match ( '/^' . EVENT_REGEX . '$/' , $event )
and (( new \DateTimeImmutable ( $event )) instanceof \DateTimeImmutable )
);
} catch ( \Exception $exception ) {
$hasEvent = false ;
}
if ( ! $isConfig and ! $supplierIsNew and $hasSupplier ) {
$start = new \DateTime ( $config [ $supplier ][ 'start' ]);
if ( ! $hasEvent ) {
$next = findNext ( $start , $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], true );
$nextEvent = $next -> format ( 'Y-m-d' );
header ( 'Location: ' . generateUrl ( $supplier , $nextEvent ));
die ();
} else {
$current = new \DateTime ( $event );
$previous = findPrevious ( $current , $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], false );
$previousEvent = $previous -> format ( 'Y-m-d' );
if ( false and ! array_key_exists ( $previousEvent , $data [ $supplier ]))
unset ( $previousEvent );
$first = new \DateTime ( $config [ $supplier ][ 'start' ]);
if ( true and ( $previous -> getTimestamp () < $first -> getTimestamp ()))
unset ( $previousEvent );
$next = findNext ( $current , $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], false );
$nextEvent = $next -> format ( 'Y-m-d' );
if ( false and ! array_key_exists ( $nextEvent , $data [ $supplier ]))
unset ( $nextEvent );
$last = new \DateTime ( $config [ $supplier ][ 'end' ]);
if ( true and ( $next -> getTimestamp () > $last -> getTimestamp ()))
unset ( $nextEvent );
}
switch ( $action ) {
case 'insert' :
case 'delete' :
$item = [];
foreach ([ 'name' , 'choice' , 'action' ] as $field )
$item [ $field ] = filter_var ( $_REQUEST [ $field ], FILTER_SANITIZE_STRING );
$item [ 'timestamp' ] = time ();
$hash = md5 ( implode ([ trim ( $item [ 'name' ]), $item [ 'choice' ], ]));
$item [ 'hash' ] = $hash ;
$isBeginning = ( ! file_exists ( DATA_FILE ) or in_array ( filesize ( DATA_FILE ), [ false , 0 ]));
$output = fopen ( DATA_FILE , 'a+' );
if ( ! $output ) break ;
if ( ! flock ( $output , LOCK_EX )) break ;
if ( $isBeginning )
fwrite ( $output , '<?php' . PHP_EOL );
fprintf (
$output ,
'$data[%s][%s][] = %s;' . PHP_EOL ,
var_export ( $supplier , true ),
var_export ( $event , true ),
str_replace ( PHP_EOL , '' , var_export ( $item , true ))
);
flock ( $output , LOCK_UN );
fclose ( $output );
header ( 'Location: ' . generateUrl ( $supplier , $event ));
die ();
}
if ( ! isset ( $data )) $data = [];
if ( file_exists ( DATA_FILE )) include DATA_FILE ;
$items = [];
$allItems = isset ( $data [ $supplier ][ $event ]) ? $data [ $supplier ][ $event ] : [];
usort ( $allItems , function ( $a , $b ) {
$a = intval ( $a [ 'timestamp' ]);
$b = intval ( $b [ 'timestamp' ]);
if ( $a === $b )
return 0 ;
return ( $a < $b ) ? - 1 : 1 ;
});
foreach ( $allItems as $item ) {
if ( $item [ 'action' ] === 'insert' ) {
$alreadyInserted = false ;
foreach ( $items as $index => $prevItem )
if ( $prevItem [ 'hash' ] === $item [ 'hash' ])
$alreadyInserted = true ;
if ( ! $alreadyInserted )
$items [] = $item ;
} elseif ( $item [ 'action' ] === 'delete' ) {
foreach ( $items as $index => $prevItem )
if ( $prevItem [ 'hash' ] === $item [ 'hash' ])
unset ( $items [ $index ]);
}
}
$date = ( new \IntlDateFormatter ( 'fr_FR.UTF8' , \IntlDateFormatter :: FULL , \IntlDateFormatter :: NONE , 'Europe/Paris' )) -> format ( new \DateTime ( $event ));
$ago = ago ( new \DateTimeImmutable ( $event ));
$color = isInPast ( $event ) ? 'text-danger' : 'text-muted' ;
$currentEvent = findNext ( new \DateTime ( $config [ $supplier ][ 'start' ]), $config [ $supplier ][ 'frequency' ], $config [ $supplier ][ 'excludes' ], true );
$currentDate = ( new \IntlDateFormatter ( 'fr_FR.UTF8' , \IntlDateFormatter :: FULL , \IntlDateFormatter :: NONE , 'Europe/Paris' )) -> format ( $currentEvent );
$currentAgo = ago ( $currentEvent );
foreach ([ 'title' , 'subtitle' , 'description' ] as $key ) {
while ( preg_match ( '/%([^%]+)%/i' , $config [ $supplier ][ $key ], $match ))
$config [ $supplier ][ $key ] = str_replace (
$match [ 0 ],
$ { $match [ 1 ]},
$config [ $supplier ][ $key ]
);
}
if ( empty ( $config [ $supplier ][ 'title' ]))
$config [ $supplier ][ 'title' ] = $supplier ;
$stats = [];
foreach ( $items as $item )
if ( ! empty ( $item [ 'choice' ]))
$stats [ $item [ 'choice' ]] += 1 ;
}
if ( $supplierIsNew and ! empty ( $suppliers )) {
$closestSuppliers = array_filter (
array_map (
function ( $other ) use ( $supplier ) {
return [
'supplier' => $other ,
'score' => levenshtein ( $supplier , $other ),
];
},
$suppliers
),
function ( $item ) {
return $item [ 'score' ] > 0 ;
}
);
usort ( $closestSuppliers , function ( $a , $b ) {
if ( $a [ 'score' ] == $b [ 'score' ]) {
return 0 ;
}
return ( $a [ 'score' ] < $b [ 'score' ]) ? - 1 : 1 ;
});
}
}
$linkUrl = ! $hasSupplier ? generateUrl () : ( ! $hasEvent ? generateUrl ( $supplier ) : generateUrl ( $supplier , $event ));
@ -429,7 +458,19 @@ $linkUrl = !$hasSupplier ? generateUrl() : (!$hasEvent ? generateUrl($supplier)
</ header >
< ? php endif ; // !$inIframe ?>
< main >
< ? php if ( ! $hasSupplier ) : ?>
< ? php if ( $supplierNeedLocation ) : ?>
< section class = " container-fluid pt-3 " >
< div class = " alert alert-info alert-dismissible mb-3 " role = " alert " >
Il existe plusieurs possibilités pour commander , merci d ' en choisir une parmi celles proposées ci - dessous .
< button type = " button " class = " btn-close " data - bs - dismiss = " alert " aria - label = " Fermer " ></ button >
</ div >
< div class = " d-grid gap-2 col-xs-12 col-sm-6 mx-auto " >
< ? php foreach ( $availableLocations [ $supplier ] as $locationKey => $locationValue ) : ?>
< a class = " btn btn-primary " href = " <?php echo generateUrl( $supplier . '-' . $locationKey ); ?> " >< ? php echo $locationValue ; ?> </a>
< ? php endforeach ; ?>
</ div >
</ section >
< ? php elseif ( ! $hasSupplier ) : ?>
< section class = " container-fluid pt-3 " >
< div class = " alert alert-danger alert-dismissible mb-3 " role = " alert " >
⚠ Pas de fournisseur !
@ -465,7 +506,7 @@ $linkUrl = !$hasSupplier ? generateUrl() : (!$hasEvent ? generateUrl($supplier)
</ div >
</ div >
</ section >
< ? php else : ?>
< ? php else : /* $hasSupplier */ ?>
< ? php if ( $isConfig ) : ?>
< section class = " container-fluid " >
< div class = " row my-3 g-3 " >
@ -486,6 +527,13 @@ $linkUrl = !$hasSupplier ? generateUrl() : (!$hasEvent ? generateUrl($supplier)
</ div >
</ div >
< div class = " row mb-3 " >
< label for = " location " class = " col-sm-2 col-form-label " > Emplacement </ label >
< div class = " col-sm-10 " >
< input class = " form-control " type = " text " name = " location " value = " <?php echo htmlspecialchars( $config[$supplier] ['location']); ?> " placeholder = " Emplacement " />
< div class = " form-text " > L 'emplacement de la commande. N' est vraiement utile que s 'il y a plusieurs emplacements différents. Par convention c' est le cas quand il y a un tiret ( < tt >-</ tt > ) dans le nom du fournisseur .</ div >
</ div >
</ div >
< div class = " row mb-3 " >
< label for = " description " class = " col-sm-2 col-form-label " > Description </ label >
< div class = " col-sm-10 " >
< textarea class = " form-control js-ckeditor " name = " description " rows = " 20 " >< ? php echo $config [ $supplier ][ 'description' ]; ?> </textarea>
@ -746,7 +794,7 @@ $linkUrl = !$hasSupplier ? generateUrl() : (!$hasEvent ? generateUrl($supplier)
</ section >
< ? php endif ; /* $supplierIsNew */ ?>
< ? php endif ; /* $isConfig*/ ?>
< ? php endif ; ?>
< ? php endif ; /* $hasSupplier */ ?>
</ main >
< div class = " modal fade " id = " linkModal " tabindex = " -1 " aria - hidden = " true " >
@ -777,7 +825,7 @@ $linkUrl = !$hasSupplier ? generateUrl() : (!$hasEvent ? generateUrl($supplier)
</ div >
< div class = " col-12 text-center " >
< pre id = " iframeCode " >< ? php ob_start (); ?>
< iframe src = " <?php echo generateUrl( $supplier ); ?> " >
< iframe src = " <?php echo generateUrl( $supplier , null, true ); ?>" >
</ iframe >
< ? php echo htmlentities ( ob_get_clean ()); ?> </pre>
< button class = " btn btn-outline-dark js-clipboard " type = " button " role = " button " data - clipboard - target = " #iframeCode " data - bs - toggle = " tooltip " data - bs - trigger = " manual " >