commit c09d71704bbef4b40cc046bb6f8d260181b15a4b Author: Adrien RENARD Date: Fri Dec 22 00:37:04 2023 +0100 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26c941d --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +/.ssh +/.viminfo +/.bash_history +/.gitconfig +/.mysql_history diff --git a/conf/.gitignore b/conf/.gitignore new file mode 100644 index 0000000..1df6460 --- /dev/null +++ b/conf/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything +* +# But not these files... +!.gitignore +!*.php \ No newline at end of file diff --git a/conf/conf.php b/conf/conf.php new file mode 100644 index 0000000..5667c8c --- /dev/null +++ b/conf/conf.php @@ -0,0 +1,72 @@ +loadFilter('output', 'trimwhitespace'); +session_start(); +session_reset(); + +define('COMPOSER_LOADER',PHP_LIB_DIR.'composer/vendor/autoload.php'); +require_once(COMPOSER_LOADER); + +require_once(FUNCTIONS_DIR_PATH.'functions.php'); +require_once(FUNCTIONS_DIR_PATH.'dbSqlManager.php'); + +$GLOBALS['smarty']->assign('online_repo',ONLINE_REPOSITORY); + +//////////////////////////////////////////////////////////////////////// +// JS / CSS / FUNCTIONS FILES ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +// ADMIN +if($GLOBALS['admin']) { + $cssFiles = array( + PUBLIC_HTML_ADMIN.'libs/bootstrap-3.3.5/css/bootstrap.min.css', + PUBLIC_HTML_ADMIN.'libs/bootstrap_modal/bootstrap_modal.css', + PUBLIC_HTML_ADMIN.'libs/bootstrap_glyphicons/bootstrap_glyphicons.css', + PUBLIC_HTML_ADMIN.'libs/bootstrap_tooltip_popover/bootstrap_tooltip_popover.css', + PUBLIC_HTML_ADMIN.'libs/jquery-ui-bootstrap/css/custom-theme/jquery-ui-1.10.3.custom.css', + PUBLIC_HTML_ADMIN.'libs/intl-tel-input/build/css/intlTelInput.css', + PUBLIC_HTML_ADMIN.'css/admin.css' + ); + + $jsFiles = array( + PUBLIC_HTML_ADMIN.'libs/jquery/jquery-2.1.4.min.js', + PUBLIC_HTML_ADMIN.'libs/bootstrap-3.3.5/js/bootstrap.min.js', + PUBLIC_HTML_ADMIN.'libs/jquery-ui-1.11.4/jquery-ui.min.js', + PUBLIC_HTML_ADMIN.'libs/jquery.ui.autocomplete.html.js', + PUBLIC_HTML_ADMIN.'libs/moment/moment.js', + PUBLIC_HTML_ADMIN.'libs/bootstrap_modal/bootstrap_modal.js', + PUBLIC_HTML_ADMIN.'libs/bootstrap_tooltip_popover/bootstrap_tooltip_popover.js', + PUBLIC_HTML_ADMIN.'libs/intl-tel-input/build/js/intlTelInput.js', + PUBLIC_HTML_ADMIN.'js/functions.js', + PUBLIC_HTML_ADMIN.'js/navSecondBar.js' + ); + + require_once(FUNCTIONS_DIR_PATH.'functions_generals.php'); + require_once(FUNCTIONS_DIR_PATH.'functions_tmp_files.php'); +} diff --git a/conf/db_struct.php b/conf/db_struct.php new file mode 100644 index 0000000..6ab2c56 --- /dev/null +++ b/conf/db_struct.php @@ -0,0 +1,396 @@ + array( "type" => "txt", "length" => 64, "default" => "" ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getPaniersGroupesSelectBaseSQL() { + return "SELECT " + .PANIERS_GROUPES_TABLE.".`ref`," + .PANIERS_GROUPES_TABLE.".`nom`," + .PANIERS_GROUPES_TABLE.".`del`" + ." FROM ".PANIERS_GROUPES_TABLE; +} + +function buildPaniersGroupesListSearchSQL($search) { return PANIERS_GROUPES_TABLE.".`nom` LIKE '%".$search."%'"; } + +//////////////////////////////////////////////////////////////////////// +// PANIERS TYPES /////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('PANIERS_TYPES_TABLE',"paniers_types"); +define('PANIERS_TYPES_TABLE_STRUCT', array( + "groupe" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "nom" => array( "type" => "txt", "length" => 64, "default" => "" ), + "valeur" => array( "type" => "float", "min" => 0, "max" => 999.99, "default" => 0, "force_default_under_min" => true ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getPaniersTypesSelectBaseSQL() { + return "SELECT " + .PANIERS_TYPES_TABLE.".`ref`," + .PANIERS_TYPES_TABLE.".`groupe` as 'groupe_ref'," + .PANIERS_GROUPES_TABLE.".`nom` as 'groupe_nom'," + .PANIERS_TYPES_TABLE.".`nom`," + .PANIERS_TYPES_TABLE.".`valeur`" + ." FROM ".PANIERS_TYPES_TABLE + ." LEFT JOIN ".PANIERS_GROUPES_TABLE." ON ".PANIERS_TYPES_TABLE.".`groupe`=".PANIERS_GROUPES_TABLE.".`ref`"; +} + +function buildPaniersTypesListSearchSQL($search) { + $sql = "(".PANIERS_TYPES_TABLE.".`nom` LIKE '%".$search."%'"; + $sql .= " OR ".PANIERS_GROUPES_TABLE.".`nom` LIKE '%".$search."%'"; + $sql .= " OR ".PANIERS_TYPES_TABLE.".`valeur` LIKE '%".$search."%')"; + return $sql; +} + +//////////////////////////////////////////////////////////////////////// +// CLIENTS ///////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('CLIENTS_TABLE',"clients"); +define('CLIENTS_TABLE_STRUCT', array( + "nom" => array( "type" => "txt", "length" => 64, "default" => "" ), + "prenom" => array( "type" => "txt", "length" => 64, "default" => "" ), + "tel" => array( "type" => "txt", "length" => 20, "default" => "" ), + "email" => array( "type" => "txt", "length" => 128, "default" => "" ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getClientsTableSelectBaseSQL() { + return "SELECT " + .CLIENTS_TABLE.".`ref`," + .CLIENTS_TABLE.".`nom`," + .CLIENTS_TABLE.".`prenom`," + .CLIENTS_TABLE.".`tel`," + .CLIENTS_TABLE.".`email`" + ." FROM ".CLIENTS_TABLE; +} + +function buildClientsListSearchSQL($search) { + $sql = "(".CLIENTS_TABLE.".`nom` LIKE '%".$search."%'"; + $sql .= " OR ".CLIENTS_TABLE.".`prenom` LIKE '%".$search."%'"; + $sql .= " OR ".CLIENTS_TABLE.".`tel` LIKE '%".$search."%'"; + $sql .= " OR ".CLIENTS_TABLE.".`email` LIKE '%".$search."%')"; + return $sql; +} + +//////////////////////////////////////////////////////////////////////// +// CLIENTS - ABSENCES ////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('CLIENTS_ABSENCES_TABLE',"clients_absences"); +define('CLIENTS_ABSENCES_TABLE_STRUCT', array( + "client" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "debut" => array( "type" => "date", "default" => "now" ), + "fin" => array( "type" => "date", "default" => "now" ), + "remarque" => array( "type" => "txt", "length" => NULL, "default" => "" ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getClientsAbsencesTableSelectBaseSQL() { + return "SELECT " + .CLIENTS_ABSENCES_TABLE.".`ref`," + .CLIENTS_ABSENCES_TABLE.".`client` as 'client_ref'," + .CLIENTS_TABLE.".`nom` as 'client_nom'," + .CLIENTS_TABLE.".`prenom` as 'client_prenom'," + .CLIENTS_ABSENCES_TABLE.".`debut`," + .CLIENTS_ABSENCES_TABLE.".`fin`," + .CLIENTS_ABSENCES_TABLE.".`remarque`" + ." FROM ".CLIENTS_ABSENCES_TABLE + ." LEFT JOIN ".CLIENTS_TABLE." ON ".CLIENTS_ABSENCES_TABLE.".`client`=".CLIENTS_TABLE.".`ref`"; +} + +function buildClientsAbsencesListSearchSQL($search) { + $sql = "(".CLIENTS_TABLE.".`nom` LIKE '%".$search."%'"; + $sql .= " OR ".CLIENTS_TABLE.".`prenom` LIKE '%".$search."%')"; + return $sql; +} + +//////////////////////////////////////////////////////////////////////// +// CONTRATS //////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('CONTRATS_TABLE',"contrats"); +define('CONTRATS_TABLE_STRUCT', array( + "client" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "type" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "groupe" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "frequence" => array( "type" => "set", "values" => ['hebdo', 'quinz'], "default" => "hebdo" ), + "nb_paniers" => array( "type" => "int", "min" => 1, "max" => 99, "default" => 1, "force_default_under_min" => true ), + "panier_type" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "date" => array( "type" => "date", "default" => "now" ), + "quinz_groupe" => array( "type" => "set", "values" => ['A', 'B'], "default" => NULL ), + "lieu_depot" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "nb_cheque" => array( "type" => "int", "min" => 1, "max" => 99, "default" => 0, "force_default_under_min" => true ), + "np_paniers_distrib_avt_saisie" => array( "type" => "int", "min" => 1, "max" => 99, "default" => 0, "force_default_under_min" => true ), + "force_eligible" => array( "type" => "bool", "default" => 0 ), + "archive" => array( "type" => "bool", "default" => 0 ), + "force_not_archive" => array( "type" => "bool", "default" => 0 ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +define('CONTRATS_PANIERS_STATUT',"contrats_paniers_statut"); + +function getContratsTableSelectBaseSQL() { + return "SELECT " + .CONTRATS_TABLE.".`ref`," + .CONTRATS_TABLE.".`client` as 'client_ref'," + .CLIENTS_TABLE.".`nom` as 'client_nom'," + .CLIENTS_TABLE.".`prenom` as 'client_prenom'," + .CLIENTS_TABLE.".`tel` as 'client_tel'," + .CLIENTS_TABLE.".`email` as 'client_email'," + .CONTRATS_TABLE.".`type` as 'type_ref'," + .CONTRATS_TYPES_TABLE.".`nom` as 'type_nom'," + .CONTRATS_TABLE.".`groupe` as 'groupe_ref'," + .PANIERS_GROUPES_TABLE.".`nom` as 'groupe_nom'," + .CONTRATS_TABLE.".`frequence`," + .CONTRATS_TABLE.".`nb_paniers`," + .CONTRATS_PANIERS_STATUT.".`nb_paniers_livres_absolute`," + .CONTRATS_PANIERS_STATUT.".`nb_paniers_livres`," + .CONTRATS_PANIERS_STATUT.".`nb_paniers_restants`," + .CONTRATS_TABLE.".`panier_type` as 'panier_type_ref'," + .PANIERS_TYPES_TABLE.".`nom` as 'panier_type_nom'," + .CONTRATS_TABLE.".`date`," + .CONTRATS_TABLE.".`quinz_groupe`," + .CONTRATS_TABLE.".`lieu_depot` as 'lieu_depot_ref'," + .LIEUX_TABLE.".`nom` as 'lieu_depot_nom'," + .CONTRATS_TABLE.".`nb_cheque`," + .CONTRATS_TABLE.".`np_paniers_distrib_avt_saisie`," + .CONTRATS_TABLE.".`force_eligible`," + .CONTRATS_TABLE.".`archive`," + .CONTRATS_TABLE.".`del`" + ." FROM ".CONTRATS_TABLE + ." LEFT JOIN ".CLIENTS_TABLE." ON ".CONTRATS_TABLE.".`client`=".CLIENTS_TABLE.".`ref`" + ." LEFT JOIN ".CONTRATS_TYPES_TABLE." ON ".CONTRATS_TABLE.".`type`=".CONTRATS_TYPES_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_GROUPES_TABLE." ON ".CONTRATS_TABLE.".`groupe`=".PANIERS_GROUPES_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_TYPES_TABLE." ON ".CONTRATS_TABLE.".`panier_type`=".PANIERS_TYPES_TABLE.".`ref`" + ." LEFT JOIN ".LIEUX_TABLE." ON ".CONTRATS_TABLE.".`lieu_depot`=".LIEUX_TABLE.".`ref`" + ." LEFT JOIN ".CONTRATS_PANIERS_STATUT." ON ".CONTRATS_TABLE.".`ref`=".CONTRATS_PANIERS_STATUT.".`ref`"; +} + +function buildContratsListSearchSQL($search) { + $sql = "(".CLIENTS_TABLE.".`nom` LIKE '%".$search."%'"; + $sql .= " OR ".CLIENTS_TABLE.".`prenom` LIKE '%".$search."%'"; + $sql .= " OR ".PANIERS_TYPES_TABLE.".`nom` LIKE '%".$search."%'"; + $sql .= " OR ".LIEUX_TABLE.".`nom` LIKE '%".$search."%')"; + return $sql; +} + +//////////////////////////////////////////////////////////////////////// +// CONTRATS - TYPES //////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('CONTRATS_FREQUENCES',array( + "hebdo" => "hebdomadaire", + "quinz" => "quinzaine" +)); + +define('CONTRATS_TYPES_TABLE',"contrats_types"); +define('CONTRATS_TYPES_TABLE_STRUCT', array( + "groupe" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "nom" => array( "type" => "txt", "length" => 128, "default" => "" ), + "frequence" => array( "type" => "set", "values" => ['hebdo', 'quinz'], "default" => "hebdo" ), + "nb_paniers" => array( "type" => "int", "min" => 1, "max" => 99, "default" => 1, "force_default_under_min" => true ), + "panier_type" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "prix_total" => array( "type" => "float", "min" => 0.01, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getContratsTypesTableSelectBaseSQL() { + return "SELECT " + .CONTRATS_TYPES_TABLE.".`ref`," + .CONTRATS_TYPES_TABLE.".`groupe` as 'groupe_ref'," + .PANIERS_GROUPES_TABLE.".`nom` as 'groupe_nom'," + .CONTRATS_TYPES_TABLE.".`nom`," + .CONTRATS_TYPES_TABLE.".`frequence`," + .CONTRATS_TYPES_TABLE.".`panier_type` as 'panier_type_ref'," + .PANIERS_TYPES_TABLE.".`nom` as 'panier_type_nom'," + .CONTRATS_TYPES_TABLE.".`nb_paniers`," + .CONTRATS_TYPES_TABLE.".`prix_total`" + ." FROM ".CONTRATS_TYPES_TABLE + ." LEFT JOIN ".PANIERS_GROUPES_TABLE." ON ".CONTRATS_TYPES_TABLE.".`groupe`=".PANIERS_GROUPES_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_TYPES_TABLE." ON ".CONTRATS_TYPES_TABLE.".`panier_type`=".PANIERS_TYPES_TABLE.".`ref`"; +} + +//////////////////////////////////////////////////////////////////////// +// LEGUMES ///////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('LEGUMES_TABLE',"legumes"); +define('LEGUMES_TABLE_STRUCT', array( + "nom" => array( "type" => "txt", "length" => 64, "default" => "" ), + "tarif" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getLegumesTableSelectBaseSQL() { + return "SELECT " + .LEGUMES_TABLE.".`ref`," + .LEGUMES_TABLE.".`nom`," + .LEGUMES_TABLE.".`tarif` as 'tarif_ref'," + .LEGUMES_TARIFS_TABLE.".`prix` as 'tarif_prix'," + .LEGUMES_TARIFS_TABLE.".`unite` as 'tarif_unite'," + .LEGUMES_TARIFS_TABLE.".`date` as 'tarif_date'" + ." FROM ".LEGUMES_TABLE + ." LEFT JOIN ".LEGUMES_TARIFS_TABLE." ON ".LEGUMES_TABLE.".`tarif`=".LEGUMES_TARIFS_TABLE.".`ref`"; +} + +function buildLegumesListSearchSQL($search) { return LEGUMES_TABLE.".`nom` LIKE '%".$search."%'"; } + +//////////////////////////////////////////////////////////////////////// +// LEGUMES - TARIFS //////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('LEGUMES_TARIFS_UNITES',array( 'kg', 'pièce', 'botte' )); +define('LEGUMES_TARIFS_UNITES_ACRONYMES',array( 'kg' => 'kg', 'pièce' => 'pc', 'botte' => 'bt' )); + +define('LEGUMES_TARIFS_TABLE',"legumes_tarifs"); +define('LEGUMES_TARIFS_TABLE_STRUCT', array( + "legume" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "prix" => array( "type" => "float", "min" => 0, "max" => 999.99, "default" => 0, "force_default_under_min" => true ), + "unite" => array( "type" => "set", "values" => LEGUMES_TARIFS_UNITES, "default" => "poids" ), + "date" => array( "type" => "date", "default" => "today" ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getLegumesTarifsTableSelectBaseSQL() { + return "SELECT " + .LEGUMES_TARIFS_TABLE.".`ref`," + .LEGUMES_TARIFS_TABLE.".`legume` as 'legume_ref'," + .LEGUMES_TABLE.".`nom` as 'legume_nom'," + .LEGUMES_TARIFS_TABLE.".`ref` as 'tarif_ref'," + .LEGUMES_TARIFS_TABLE.".`prix` as 'tarif_prix'," + .LEGUMES_TARIFS_TABLE.".`unite` as 'tarif_unite'," + .LEGUMES_TARIFS_TABLE.".`date` as 'tarif_date'" + ." FROM ".LEGUMES_TARIFS_TABLE + ." LEFT JOIN ".LEGUMES_TABLE." ON ".LEGUMES_TARIFS_TABLE.".`legume`=".LEGUMES_TABLE.".`ref`"; +} + +//////////////////////////////////////////////////////////////////////// +// LIEUX /////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('LIEUX_TABLE',"lieux"); +define('LIEUX_TABLE_STRUCT', array( + "nom" => array( "type" => "txt", "length" => 64, "default" => "" ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getLieuxTableSelectBaseSQL() { + return "SELECT " + .LIEUX_TABLE.".`ref`," + .LIEUX_TABLE.".`nom`," + .LIEUX_TABLE.".`del`" + ." FROM ".LIEUX_TABLE; +} + +function buildLieuxSearchSQL($search) { return LIEUX_TABLE.".`nom` LIKE '%".$search."%'"; } + +//////////////////////////////////////////////////////////////////////// +// LIVRAISONS ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('LIVRAISONS_NB_PANIERS_VIEW',"livraisons_nb_paniers"); + +define('LIVRAISONS_TABLE',"livraisons"); +define('LIVRAISONS_TABLE_STRUCT', array( + "paniers_groupe" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "date" => array( "type" => "date", "default" => "today" ), + "quinz_groupe" => array( "type" => "set", "values" => ['A', 'B'], "default" => NULL ), + "archive" => array( "type" => "bool", "default" => 0 ), + "force_not_archive" => array( "type" => "bool", "default" => 0 ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getLivraisonsTableSelectBaseSQL() { + return "SELECT " + .LIVRAISONS_TABLE.".`ref`," + .LIVRAISONS_TABLE.".`paniers_groupe` as 'paniers_groupe_ref'," + .PANIERS_GROUPES_TABLE.".`nom` as 'paniers_groupe_nom'," + .LIVRAISONS_TABLE.".`date`," + .LIVRAISONS_TABLE.".`quinz_groupe`," + .LIVRAISONS_NB_PANIERS_VIEW.".`nb_paniers`," + .LIVRAISONS_TABLE.".`archive`" + ." FROM ".LIVRAISONS_TABLE + ." LEFT JOIN ".PANIERS_GROUPES_TABLE." ON ".LIVRAISONS_TABLE.".`paniers_groupe`=".PANIERS_GROUPES_TABLE.".`ref`" + ." LEFT JOIN ".LIVRAISONS_NB_PANIERS_VIEW." ON ".LIVRAISONS_TABLE.".`ref`=".LIVRAISONS_NB_PANIERS_VIEW.".`ref`"; +} + +//////////////////////////////////////////////////////////////////////// +// LIVRAISONS - LEGUMES //////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('LIVRAISONS_LEGUMES_TABLE',"livraisons_legumes"); +define('LIVRAISONS_LEGUMES_TABLE_STRUCT', array( + "livraison" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "panier_type" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "legume" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "tarif" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "quantite" => array( "type" => "float", "min" => 0, "max" => 999.99, "default" => 0, "force_default_under_min" => true ) +)); + +function getLivraisonsLegumesTableSelectBaseSQL() { + return "SELECT " + .LIVRAISONS_LEGUMES_TABLE.".`legume` as 'ref'," + .LEGUMES_TABLE.".`nom` as 'nom'," + .LIVRAISONS_LEGUMES_TABLE.".`livraison` as 'livraison_ref'," + .LIVRAISONS_TABLE.".`date` as 'livraison_date'," + .LIVRAISONS_LEGUMES_TABLE.".`panier_type` as 'panier_type_ref'," + .PANIERS_TYPES_TABLE.".`nom` as 'panier_type_nom'," + .LIVRAISONS_LEGUMES_TABLE.".`tarif` as 'tarif_ref'," + .LEGUMES_TARIFS_TABLE.".`prix` as 'tarif_prix'," + .LEGUMES_TARIFS_TABLE.".`unite` as 'tarif_unite'," + .LIVRAISONS_LEGUMES_TABLE.".`quantite`" + ." FROM ".LIVRAISONS_LEGUMES_TABLE + ." LEFT JOIN ".LIVRAISONS_TABLE." ON ".LIVRAISONS_LEGUMES_TABLE.".`livraison`=".LIVRAISONS_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_TYPES_TABLE." ON ".LIVRAISONS_LEGUMES_TABLE.".`panier_type`=".PANIERS_TYPES_TABLE.".`ref`" + ." LEFT JOIN ".LEGUMES_TABLE." ON ".LIVRAISONS_LEGUMES_TABLE.".`legume`=".LEGUMES_TABLE.".`ref`" + ." LEFT JOIN ".LEGUMES_TARIFS_TABLE." ON ".LIVRAISONS_LEGUMES_TABLE.".`tarif`=".LEGUMES_TARIFS_TABLE.".`ref`"; +} + +//////////////////////////////////////////////////////////////////////// +// LIVRAISONS - PANIERS //////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('LIVRAISONS_PANIERS_TABLE',"livraisons_paniers"); +define('LIVRAISONS_PANIERS_TABLE_STRUCT', array( + "livraison" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "contrat" => array( "type" => "int", "min" => 1, "max" => NULL, "default" => NULL, "force_default_under_min" => true ), + "del" => array( "type" => "bool", "default" => 0 ) +)); + +function getLivraisonsPaniersSelectBaseSQL() { + return "SELECT " + .LIVRAISONS_PANIERS_TABLE.".`livraison` as 'livraison_ref'," + .LIVRAISONS_TABLE.".`date` as 'livraison_date'," + .LIVRAISONS_PANIERS_TABLE.".`contrat` as 'contrat_ref'," + .CONTRATS_TABLE.".`client` as 'client_ref'," + .CLIENTS_TABLE.".`nom` as 'client_nom'," + .CLIENTS_TABLE.".`prenom` as 'client_prenom'," + .CONTRATS_TABLE.".`type`," + .CONTRATS_TABLE.".`frequence`," + .CONTRATS_TABLE.".`nb_paniers`," + .CONTRATS_TABLE.".`quinz_groupe`," + .CONTRATS_PANIERS_STATUT.".`nb_paniers_livres_absolute`," + .CONTRATS_PANIERS_STATUT.".`nb_paniers_livres`," + .CONTRATS_PANIERS_STATUT.".`nb_paniers_restants`," + .CONTRATS_TABLE.".`panier_type` as 'panier_type_ref'," + .PANIERS_TYPES_TABLE.".`nom` as 'panier_type_nom'," + .CONTRATS_TABLE.".`lieu_depot` as 'lieu_depot_ref'," + .LIEUX_TABLE.".`nom` as 'lieu_depot_nom'," + .LIVRAISONS_PANIERS_TABLE.".`del`" + ." FROM ".LIVRAISONS_PANIERS_TABLE + ." LEFT JOIN ".LIVRAISONS_TABLE." ON ".LIVRAISONS_PANIERS_TABLE.".`livraison`=".LIVRAISONS_TABLE.".`ref`" + ." LEFT JOIN ".CONTRATS_TABLE." ON ".LIVRAISONS_PANIERS_TABLE.".`contrat`=".CONTRATS_TABLE.".`ref`" + ." LEFT JOIN ".CLIENTS_TABLE." ON ".CONTRATS_TABLE.".`client`=".CLIENTS_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_TYPES_TABLE." ON ".CONTRATS_TABLE.".`panier_type`=".PANIERS_TYPES_TABLE.".`ref`" + ." LEFT JOIN ".LIEUX_TABLE." ON ".CONTRATS_TABLE.".`lieu_depot`=".LIEUX_TABLE.".`ref`" + ." LEFT JOIN ".CONTRATS_PANIERS_STATUT." ON ".CONTRATS_TABLE.".`ref`=".CONTRATS_PANIERS_STATUT.".`ref`"; +} diff --git a/conf/settings.php b/conf/settings.php new file mode 100644 index 0000000..5d81618 --- /dev/null +++ b/conf/settings.php @@ -0,0 +1,76 @@ +_Fy7<507ln3U_qTc"); + +//////////////////////////////////////////////////////////////////////// +// DEBUG & PHP ERROR SETTINGS ////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +$GLOBALS['debug'] = true; +error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING); +ini_set('display_errors', 'Off'); + +//////////////////////////////////////////////////////////////////////// +// DATE /////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('DATE_TIME_ZONE',"Europe/Paris"); +define('DATE_FORMAT',"%F"); +define('DATE_TIME_FORMAT',"%F %X"); + +date_default_timezone_set(DATE_TIME_ZONE); + +//////////////////////////////////////////////////////////////////////// +// ROOT DIR PATH & PUBLIC HTML RACINE URLS //////////////////////////// +//////////////////////////////////////////////////////////////////////// + +$GLOBALS['ONLINE_PUBLIC_HTML_URL'] = 'https://paniers.zionetrix.net/'; +$GLOBALS['ONLINE_PUBLIC_HTML_ADMIN_URL'] = 'https://admin.paniers.zionetrix.net/'; + +if(ONLINE_REPOSITORY) { + define('ROOT_DIR_PATH', '/var/www/paniers/'); + define('PUBLIC_HTML_ADMIN', $GLOBALS['ONLINE_PUBLIC_HTML_ADMIN_URL']); +} +else { + define('ROOT_DIR_PATH', '/Applications/MAMP/htdocs/paniers/'); + define('PUBLIC_HTML_ADMIN','http://localhost/paniers/public_html_admin/'); +} + +//////////////////////////////////////////////////////////////////////// +// DB CONFIG /////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +$GLOBALS['db_admin'] = array( + 'type' => "mysql", + 'db' => 'paniers', + 'user' => 'paniers_admin', + 'pwd' => 'QUyiO1hGELIa_Weq', + 'host' => 'localhost', + 'man' => false +); + +//////////////////////////////////////////////////////////////////////// +// ARCHIVE AUTO //////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('AUTO_ARCHIVE_OLD_LIVRAISONS_DELAY',5); // NB DE JOURS +define('AUTO_ARCHIVE_OLD_CONTRATS_DELAY',5); // NB DE JOURS (après le dernier panier livré) + +//////////////////////////////////////////////////////////////////////// +// WARNINGS CONTRATS /////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +define('WARNING_NB_PANIERS_HEBDO',2); +define('WARNING_NB_PANIERS_QUINZE',1); + +//////////////////////////////////////////////////////////////////////// +// LIBS //////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +if(ONLINE_REPOSITORY) define('MYSQLDUMP',"/usr/bin/mysqldump"); +else define('MYSQLDUMP',"/Applications/MAMP/Library/bin/mysqldump"); diff --git a/functions/.gitignore b/functions/.gitignore new file mode 100644 index 0000000..1df6460 --- /dev/null +++ b/functions/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything +* +# But not these files... +!.gitignore +!*.php \ No newline at end of file diff --git a/functions/dbSqlManager.php b/functions/dbSqlManager.php new file mode 100644 index 0000000..b618c67 --- /dev/null +++ b/functions/dbSqlManager.php @@ -0,0 +1,427 @@ + "SET NAMES utf8", + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + ); + + private $cnx = false; + + public function setDbConf($db_type, $db_name, $db_user=false, $db_pwd=false, $db_host='localhost', $db_opt=false) { + $availableType = array('mysql', 'sqlite', 'pgsql'); + $this->type = (in_array($db_type, $availableType)) ? $db_type : false; + $this->db = ($db_name!="") ? $db_name : false; + $this->user = ($db_user!="") ? $db_user : false; + $this->pwd = ($db_pwd!="") ? $db_pwd : false; + $this->host = ($db_host!="") ? $db_host : false; + if(is_array($db_opt)) $this->opt = $db_opt; + + $this->dns = false; + if($this->type && $this->db) { + switch($this->type) { + case 'mysql': + if(!$this->user) return "miss user"; + $this->dns = 'mysql:host='.$this->host.';dbname='.$this->db; + break; + case 'sqlite': + $this->dns = 'sqlite:'.$this->db; + break; + case 'pgsql': + if(!$this->user || $this->pwd) return "miss user & pwd"; + $this->dns = 'pgsql:host='.$this->host.';port=5432;dbname='.$this->db.';user='.$this->user.';password='.$this->pwd; + break; + default: + return "miss type"; + break; + } + + return true; + } + + return "miss type & db"; + } + + public function connect() { + if(!$this->dns) return "no conf"; + + try { + switch($this->type) { + case 'mysql': + if($this->pwd && $this->opt) $this->cnx = new PDO($this->dns,$this->user,$this->pwd,$this->opt); + else if($this->pwd) $this->cnx = new PDO($this->dns,$this->user,$this->pwd); + break; + case 'sqlite': + if(!file_exists(realpath($this->db))) throw new PDOException("the sqlite file does not exists !"); + $this->cnx = new PDO($this->dns, '', ''); + break; + case 'pgsql': + $this->cnx = new PDO($this->dns); + break; + default: return "miss type"; break; + }; + } catch ( PDOException $e ) { + return "Echec de connection à la base de donnée : ".$e->getMessage(); + } + + return true; + } + + public function disconnect() { + $this->cnx = null; + $this->cnx = false; + } + + public function getTablesList() { + $sql = "SHOW TABLES FROM ".$this->db; + + $r = $this->select($sql); + if($r['erreur']!==false) return $r; + + $result = array(); + foreach($r['datas'] as $t) { + $result[] = $t[array_key_first($t)]; + } + + return array('datas' => $result, 'erreur' => false, 'sql' => $sql); + } + + public function select($sql,$fetchFisrt=false) { + if(!$this->cnx) return array('datas' => array(), 'erreur' => 'no db connection', 'sql' => $this->cnx); + + $result = array(); + $erreur = false; + try { + $sth = $this->cnx->prepare($sql); + if(!$sth) throw new PDOException("PDO error => sth : ".$this->getReadableVar($sth)); + + $result = $sth->execute(); + + if(!$result) { + $e = $sth->errorInfo(); + $erreur = $e[2]; + } + else { + if($fetchFisrt) $result = $sth->fetch(PDO::FETCH_ASSOC); + else $result = $sth->fetchAll(PDO::FETCH_ASSOC); + } + } + catch ( PDOException $e ) { + $erreur = $e->getMessage(); + } + return array('datas' => $result, 'erreur' => $erreur, 'sql' => $sql); + } + + public function makeInsertSql($table,$infos,$quote="`") { + $sql = "INSERT INTO ".$table." ("; + $values = ") VALUES ("; + $datas = array(); + + foreach($infos as $key => $val) { + if(is_null($val)) continue; + $sql.=$quote.$key.$quote.","; + $values.=":".$key.","; + if(is_string($val)) $datas[$key] = stripslashes($val); + else $datas[$key] = $val; + } + + $sql = substr($sql,0,-1).substr($values,0,-1).")"; + + return array('sql' => $sql, 'datas' => $datas, 'print_sql' => $this->parms($sql,$datas)); + } + + public function insert($table,$infos,$quote="`") { + if(!$this->cnx) return array('result' => false, 'id' => 0, 'erreur' => 'no db connection', 'sql' => ''); + + $result = array(); + $erreur = false; + $id = false; + + // MAKE SQL + $sql_datas = $this->makeInsertSql($table,$infos,$quote); + $sql = $sql_datas['sql']; + $datas = $sql_datas['datas']; + + // EXEC SQL + try { + $sth = $this->cnx->prepare($sql); + if(!$sth) throw new PDOException("PDO error => sth : ".$this->getReadableVar($sth)); + + $this->cnx->beginTransaction(); + $result = $sth->execute($datas); + + if(!$result) { + $e = $sth->errorInfo(); + $erreur = $e[2]; + } + else { + if($this->type == "pgsql") { + $id = $sth->fetch(PDO::FETCH_ASSOC); + $id = $id['id']; + } + else $id = $this->cnx->lastInsertId(); + } + + $this->cnx->commit(); + } + catch ( PDOException $e ) { + $erreur = $e->getMessage(); + } + + return array('result' => $result, 'id' => $id, 'erreur' => $erreur, 'sql' => $this->parms($sql,$datas)); + + } + + public function makeUpdateSql($table,$infos,$conditions,$quote="`") { + $sql = "UPDATE ".$table." SET "; + $datas = array(); + + foreach($infos as $key=>$val) { + $sql.=$quote.$key.$quote."=:".$key.", "; + if(is_string($val)) $datas[$key] = stripslashes($val); + else if(is_null($val)) $datas[$key] = NULL; + else $datas[$key] = $val; + } + + $sql = substr($sql,0,-2)." ".$conditions; + + return array('sql' => $sql, 'datas' => $datas, 'print_sql' => $this->parms($sql,$datas)); + } + + public function update($table,$infos,$conditions,$quote="`") { + if(!$this->cnx) return array('result' => false, 'erreur' => 'no db connection', 'sql' => ''); + + $result = false; + $erreur = false; + + // MAKE SQL + $sql_datas = $this->makeUpdateSql($table,$infos,$conditions,$quote); + $sql = $sql_datas['sql']; + $datas = $sql_datas['datas']; + + // EXEC SQL + try { + $sth = $this->cnx->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); + if(!$sth) throw new PDOException("PDO error => sth : ".$this->getReadableVar($sth)); + + $this->cnx->beginTransaction(); + $result = $sth->execute($datas); + + if(!$result) { + $e = $sth->errorInfo(); + if(!is_null($e[2])) $erreur = $e[2]; + else if (!is_null($e[0])) $erreur = $e[0]; + else $erreur = $e; + } + + $this->cnx->commit(); + } + catch ( PDOException $e ) { + $erreur = $e->getMessage(); + } + + return array('result' => $result, 'erreur' => $erreur, 'sql' => $this->parms($sql,$datas)); + } + + public function deleteById($id,$table,$id_name_val='id',$quote="`") { + // MAKE CONDITION + $conditions = "WHERE ".$quote.$id_name_val.$quote."="; + if(is_string($id)) $conditions .= "'".stripslashes($id)."'"; + else $conditions .= $id; + + // EXEC SQL + return $this->deleteWithCondition($table,$conditions); + } + + public function deleteWithCondition($table,$conditions) { + if(!$this->cnx) return array('result' => false, 'erreur' => 'no db connection', 'sql' => ''); + + $result = false; + $erreur = false; + + // MAKE SQL + $sql = "DELETE FROM ".$table." ".$conditions; + + // EXEC SQL + try { + $sth = $this->cnx->prepare($sql); + if(!$sth) throw new PDOException("PDO error => sth : ".$this->getReadableVar($sth)); + + $this->cnx->beginTransaction(); + $result = $sth->execute(); + + if(!$result) { + $e = $sth->errorInfo(); + if(!is_null($e[2])) $erreur = $e[2]; + else if (!is_null($e[0])) $erreur = $e[0]; + else $erreur = $e; + } + + $this->cnx->commit(); + } + catch ( PDOException $e ) { + $erreur = $e->getMessage(); + } + + return array('result' => $result, 'erreur' => $erreur, 'sql' => $sql); + } + + public function execSql($sql) { + if(!$this->cnx) return array('result' => false, 'erreur' => 'no db connection', 'sql' => $sql); + + $result = false; + $erreur = false; + + try { + $this->cnx->beginTransaction(); + + $result = $this->cnx->exec($sql); + + if($result!==false) $result = true; + else { + $e = $this->cnx->errorInfo(); + throw new PDOException("PDO error => ".$e[2]); + } + + $this->cnx->commit(); + } + catch ( PDOException $e ) { + $erreur = $e->getMessage(); + } + + return array('result' => $result, 'erreur' => $erreur, 'sql' => $sql); + } + + public function executeSql($sql) { + if(!$this->cnx) return array('result' => false, 'erreur' => 'no db connection', 'sql' => $sql); + + $result = false; + $erreur = false; + + try { + $sth = $this->cnx->prepare($sql); + if(!$sth) throw new PDOException("PDO error => sth : ".$this->getReadableVar($sth)); + + $this->cnx->beginTransaction(); + $result = $sth->execute(); + + if(!$result) { + $e = $sth->errorInfo(); + if(!is_null($e[2])) $erreur = $e[2]; + else if (!is_null($e[0])) $erreur = $e[0]; + else $erreur = $e; + } + + $this->cnx->commit(); + } + catch ( PDOException $e ) { + $erreur = $e->getMessage(); + } + + return array('result' => $result, 'erreur' => $erreur, 'sql' => $sql); + } + + public function quote($value) { + if(!$this->cnx) return false; + return $this->cnx->quote($value); + } + + private function parms($string,$data) { + $indexed=$data==array_values($data); + foreach($data as $k=>$v) { + if(is_string($v)) $v="'$v'"; + if($indexed) $string=preg_replace('/\?/',$v,$string,1); + else $string=str_replace(":$k",$v,$string); + } + return $string; + } + + private function afficheArray($array,$echo=false,$indent=20) { + if(!is_array($array)) return "NOT AN ARRAY !".(($echo) ? "
" : ""); + + $htmlTxt = "array("; + if(count($array)==0) return "array()"; + foreach($array as $key => $val) { + $htmlTxt.="
"; + $htmlTxt.= (is_string($key)) ? "'".$key."'" : $key; + $htmlTxt.= " = "; + $htmlTxt.= (is_array($val)) ? $this->afficheArray($val, false, ($indent+20), false) : $this->getReadableVar($val); + $htmlTxt.= ","; + } + $htmlTxt = substr($htmlTxt,0,-8).'
'; + $htmlTxt.=")"; + + if($echo) { + echo($htmlTxt."
"); + return; + } + + return $htmlTxt; + } + + private function getReadableVar($var) { + if(is_array($var)) return $this->afficheArray($var,false,20); + elseif(is_bool($var)) return ($var) ? 'true' : false; + elseif(is_string($var) && $var=='') return "Ø (empty string)"; + elseif(is_string($var)) return "'".$var."'"; + elseif(is_null($var)) return 'NULL'; + elseif($var instanceof DateTime) return $var->format('d/m/Y - H:i:s'); + else return print_r($var,1); + } + + public function dump($destFile) { + if($this->type!="mysql") return "Wrong type => ".$this->type; + + if(!$this->pwd) $command = MYSQLDUMP." -u ".$this->user." ".$this->db." > ".$destFile; + else $command = MYSQLDUMP." -u ".$this->user." -p".$this->pwd." ".$this->db." > ".$destFile; + + die($command); + + $result = array(); + $returnCode = 0; + + $result = system($command,$returnCode); + + if($returnCode==0) return true; + else return "Une erreur est survenue durant la création dump de la base de données ! (error code : ".$returnCode." - command : ".$command." - result : ".$this->getReadableVar($result).")"; + } + + public function getSqliteTablesList($ignore=true) { + $list = array(); + + $sql = "SELECT `name` FROM sqlite_master WHERE `type`='table'"; + + $r = $this->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $t) { + if(($t['name']!="sqlite_sequence" && $ignore) || !$ignore) $list[] = $t['name']; + } + } + else { + $er = "
sql: ".$sql."
error: ".$this->getReadableVar($r['erreur']); + return "Une erreur est survenue durant la récupération de la liste tables de le base de données !".$er; + } + + return $list; + } +} + +function dumpSQL($db,$user,$pwd,$destFile) { + $command = MYSQLDUMP." -u ".$user." -p".$pwd." ".$db." > ".$destFile; + $result = array(); + $returnCode = 0; + + $result = system($command,$returnCode); + + if($returnCode==0) return true; + else return "Une erreur est survenue durant la création dump de la base de données ! (error code : ".$returnCode." - command : ".$command." - result : ".$result.")"; +} +?> \ No newline at end of file diff --git a/functions/functions.php b/functions/functions.php new file mode 100644 index 0000000..08d907f --- /dev/null +++ b/functions/functions.php @@ -0,0 +1,2621 @@ + assign('prefixe',isset($GLOBALS['prefixe']) ? $GLOBALS['prefixe'] : ""); + $GLOBALS['smarty'] -> assign('publicHTML',PUBLIC_HTML); + $GLOBALS['smarty'] -> assign('publicHTMLadmin',PUBLIC_HTML_ADMIN); + $GLOBALS['smarty'] -> assign('racine',isset($GLOBALS['racine']) ? $GLOBALS['racine'] : ""); + $GLOBALS['smarty'] -> assign('frameDisplay',isset($GLOBALS['frameDisplay']) ? $GLOBALS['frameDisplay'] : false); + $GLOBALS['smarty'] -> assign('noMenu',isset($GLOBALS['noMenu']) ? $GLOBALS['noMenu'] : false); + $GLOBALS['smarty'] -> assign('debug',isset($GLOBALS['debug']) ? $GLOBALS['debug'] : false); + $GLOBALS['smarty'] -> assign('errors',isset($GLOBALS['errors']) ? $GLOBALS['errors'] : false); + $GLOBALS['smarty'] -> assign('user',isset($_SESSION['user']) ? $_SESSION['user'] : false); + $GLOBALS['smarty'] -> assign('gitVS',getGitVersion()); + + if(isset($GLOBALS['frameDisplay']) && $GLOBALS['frameDisplay']) { + $datas = array( + 'content' => $GLOBALS['smarty'] -> fetch('msg.tpl').$GLOBALS['smarty'] -> fetch($GLOBALS['template']), + 'page' => $GLOBALS['smarty']->getTemplateVars('page'), + 'jsFiles' => $GLOBALS['jsFiles'], + 'cssFiles' => $GLOBALS['cssFiles'] + ); + die(json_encode($datas)); + } + else { + $GLOBALS['smarty'] -> assign('jsFiles',$GLOBALS['jsFiles']); + $GLOBALS['smarty'] -> assign('cssFiles',$GLOBALS['cssFiles']); + + $GLOBALS['smarty'] -> display($GLOBALS['template']); + die(); + } +} + +// DEBUG & ERRORS // + +$GLOBALS['debug'] = array(); + +function addDebug($var,$label='') { + $txt = ''; + if($label!='') { + $txt = $label.' : '; + } + + if(is_array($var)) { + $GLOBALS['debug'][] = $txt.afficheArray($var); + } + elseif(is_bool($var)) { + if($var) { + $GLOBALS['debug'][] = $txt.'true'; + } + else { + $GLOBALS['debug'][] = $txt.'false'; + } + } + else { + $GLOBALS['debug'][] = $txt.print_r($var,1); + } +} + +$GLOBALS['errors'] = array(); + +function afficheArray($array,$echo=false,$indent=20,$displayType=false) { + if(!is_array($array)) return "NOT AN ARRAY !".(($echo) ? "
" : ""); + + $htmlTxt = "array("; + if(count($array)==0) return "array()"; + foreach($array as $key => $val) { + $htmlTxt.="
"; + $htmlTxt.= (is_string($key)) ? "'".$key."'" : $key; + $htmlTxt.= " = "; + $htmlTxt.= (is_array($val)) ? afficheArray($val, false, ($indent+20), false) : getReadableVar($val,$displayType); + $htmlTxt.= ","; + } + $htmlTxt = substr($htmlTxt,0,-8).'
'; + $htmlTxt.=")"; + + if($echo) { + echo($htmlTxt."
"); + return; + } + + return $htmlTxt; +} + +function getReadableVar($var,$displayType=false) { + $ret = ""; + $type = ""; + + if(is_array($var)) { $type = "array"; $ret = afficheArray($var,false,20); } + elseif(is_bool($var)) { $type = "bool"; $ret = ($var) ? 'true' : 'false'; } + elseif(is_string($var) && $var=='') { $type = "string"; $ret = "Ø (empty string)"; } + elseif(is_string($var)) { $type = "string"; $ret = '"'.$var.'"'; } + elseif(is_null($var)) { $type = "null"; $ret = 'NULL'; } + elseif($var instanceof DateTime) { $type = "datetime"; $ret = $var->format('d/m/Y - H:i:s'); } + else { $type = gettype($var); $ret = print_r($var,1); } + + if($displayType) return "[".$type."] : ".$ret; + return $ret; +} + +function getGitVersion() { + exec('git describe --always',$version_mini_hash); + exec('git rev-list HEAD | wc -l',$version_number); + exec('git log -1',$line); + $version['short'] = "v1.".trim($version_number[0]).".".$version_mini_hash[0]; + $version['full'] = "v1.".trim($version_number[0]).".$version_mini_hash[0] (".str_replace('commit ','',$line[0]).")"; + return $version; +} + +// IMPORT EXCEL FILE + +function uploadExcelFile($uploadFileName = 'csv_file') { + if(file_exists($_FILES[$uploadFileName]['tmp_name'])) { + $allow_mime_type=array('application/octet-stream',"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + if (in_array($_FILES[$uploadFileName]['type'],$allow_mime_type)) { + $tmp = DOCS_TMP_DIR.'/tmp_'.time().'.xlsx'; + if(move_uploaded_file($_FILES[$uploadFileName]['tmp_name'], $tmp)) { // Déplace dans le dossier tmp + return $tmp; + } + } + else { + $GLOBALS['errors'][] = "ERREUR : Le fichier chargé n'est pas un fichier Excel ! (".$_FILES[$uploadFileName]['type'].')
'; + } + } + else { + $GLOBALS['errors'][] = "ERREUR : Aucun fichier uplaodé !"; + } + + return false; +} + +function parseExcelFile($file, $sheetName, $vals, $deleteIfNull=array(), $correctPhoneNum=array(), $correctNL2BR=array()) { + if(isset($GLOBALS['prefixe'])) require_once $GLOBALS['prefixe'].'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + else require_once 'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + + if(!file_exists($file)) return "ERREUR : le fichier n'éxiste pas !"; + + // LOAD FILE + try { + $objPHPExcel = PHPExcel_IOFactory::load($file); + } + catch ( Exception $e ) { + return "ERREUR : ".$e->getMessage(); + } + + // LOAD SHEET + + $sheet = $objPHPExcel->getSheetByName($sheetName); + if(!$sheet) { + return "ERREUR : la feuille '".$sheetName."' est introuvable !
feuilles disponible : ".afficheArray($objPHPExcel->getSheetNames()); + } + + // LOAD SHEETDATAS + $sheetDatas = $sheet->toArray(null,true,true,true); + + // FIND LINKS + $linkValsCols = array(); + $cols = $sheetDatas[1]; + foreach ($cols as $key => $val) { + if($val !="" && in_array($val, $vals)) { + $linkValsCols[ array_search($val,$vals) ] = $key; // + } + } + + if(count($linkValsCols) != count($vals)) { + $er = "ERREUR : les valeurs suivantes sont introuvables dans le fichier importé !"; + return $er; + } + + // GET ROWS + $liste = array(); + for($i=2;$i<=count($sheetDatas);$i++) { + $row = array(); + foreach($linkValsCols as $val => $key) { + $row[$val] = $sheetDatas[$i][$key]; + } + $liste[] = $row; + } + + $objPHPExcel->disconnectWorksheets(); + unset($objPHPExcel); + + + $checkNull = (count($deleteIfNull)>0); + $newListe = array(); + for($i=0;$i $val) { + if(!((string)$liste[$i][$key]!="")) $liste[$i][$key] = ""; + } + $newListe[] = $liste[$i]; + } + } + + return $newListe; + +} + +// EXPORT EXCEL FILE + +function createExcelObj($title,$subject,$desc) { + if(isset($GLOBALS['prefixe'])) require_once $GLOBALS['prefixe'].'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + else require_once 'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + + // CREATE OBJ + try { + + // CREATION DE L'OBJECT EXCEL + $objPHPExcel = new PHPExcel(); + + $objPHPExcel->getProperties()->setCreator("ERP - alabama"); + $objPHPExcel->getProperties()->setLastModifiedBy("ERP"); + $objPHPExcel->getProperties()->setTitle($title); + $objPHPExcel->getProperties()->setSubject($subject); + $objPHPExcel->getProperties()->setDescription($desc); + + return $objPHPExcel; + } + catch ( Exception $e ) { + return "ERREUR : ".$e->getMessage(); + } +} + +function writeSheetInExcelObj($objPHPExcel, $sheetIndex, $sheetName, $vals, $datas, $colSizes=array() ,$colAlign=array(), $correctNL2R=array()) { + if(isset($GLOBALS['prefixe'])) require_once $GLOBALS['prefixe'].'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + else require_once 'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + + // ON CREER LA FEUILLE + if($sheetIndex>0) { + $objPHPExcel->createSheet($sheetIndex); + $objPHPExcel->setActiveSheetIndex($sheetIndex); + } + $sheet=$objPHPExcel->getActiveSheet(); + $sheet->setTitle($sheetName); + + // ON CREER LES TITRES DE COLONNES + $styleArrayTitre = array( + 'font' => array( + 'name' => 'Arial', + 'bold' => true, + 'size' => 14 + ), + 'alignment' => array( + 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + 'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER, + 'wrapText' => true + ), + 'borders' => array( + 'top' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + 'left' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + 'right' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + 'bottom' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + ), + 'fill' => array( + 'type' => PHPExcel_Style_Fill::FILL_SOLID, + 'startcolor' => array( + 'argb' => 'FFC1C1C1', + ), + ) + ); + $col = 0; + $sheet->getRowDimension(1)->setRowHeight(30); + $lastCol = "A"; + foreach($vals as $k => $v) { + $cell = $sheet->getCellByColumnAndRow($col, 1); + $crd = $cell->getCoordinate(); + $lastCol = $cell->getColumn(); + + $cell->setValue($v); + $sheet->getStyle($crd)->applyFromArray($styleArrayTitre); + $sheet->getStyle($crd)->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + + // LARGEUR DE COLONNE + if(array_key_exists($k,$colSizes)) $sheet->getColumnDimension($cell->getColumn())->setWidth($colSizes[$k]); + + // ALIGNEMENT + if(array_key_exists($k,$colAlign)) { + if($colAlign[$k]=="center") + $sheet->getStyle($lastCol)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); + else if($colAlign[$k]=="right") + $sheet->getStyle($lastCol)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + else + $sheet->getStyle($lastCol)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); + } + + $col++; + } + + // ON CREER LES LIGNES DE VALEURS + $styleArrayValPair = array( + 'font' => array( + 'name' => 'Arial', + 'bold' => false, + 'size' => 12 + ), + 'alignment' => array( + 'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER, + 'wrapText' => true + ), + 'borders' => array( + 'top' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + 'left' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + 'right' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + 'bottom' => array( + 'style' => PHPExcel_Style_Border::BORDER_THIN, + ), + ), + ); + + $styleArrayValImpair = $styleArrayValPair; + $styleArrayValImpair['fill'] = array( + 'type' => PHPExcel_Style_Fill::FILL_SOLID, + 'startcolor' => array( + 'argb' => 'FFADE9FF' + ) + ); + $row = 2; + foreach($datas as $l) { + // APPLY FORMAT + if($row%2 == 1) $sheet->getStyle("A".$row.":".$lastCol.$row)->applyFromArray($styleArrayValImpair); + else $sheet->getStyle("A".$row.":".$lastCol.$row)->applyFromArray($styleArrayValPair); + $sheet->getRowDimension($row)->setRowHeight(50); + + $col = 0; + foreach($vals as $k => $v) { + $cell = $sheet->getCellByColumnAndRow($col, $row); + $crd = $cell->getCoordinate(); + + if(in_array($k,$correctNL2R)) { + $val = str_replace(array("
","\n"),"\r",$l[$v]); + $sheet->getStyle($crd)->getAlignment()->setWrapText(true); + } + else $val = str_replace(array("
","\n"),"",$l[$v]); + + $cell->setValue($val); + + $col++; + } + $row++; + } + return $objPHPExcel; +} + +function downloadExcelObj($objPHPExcel, $fileName) { + if(isset($GLOBALS['prefixe'])) require_once $GLOBALS['prefixe'].'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + else require_once 'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + + // SAVE FILE + try { + $objPHPExcel->setActiveSheetIndex(0); + + $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); + $objWriter->setIncludeCharts(true); + + ini_set('zlib.output_compression', 0); + + $date = gmdate(DATE_RFC1123); + + header('Pragma: public'); + header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0'); + + header('Content-Tranfer-Encoding: none'); + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; name="'.$fileName.'"'); + header('Content-Disposition: inline; filename="'.$fileName.'"'); + + $objWriter->save('php://output'); + exit(); + } + catch ( Exception $e ) { + return "ERREUR : ".$e->getMessage(); + } +} + +function htmlDisplayExcelObj($objPHPExcel) { + if(isset($GLOBALS['prefixe'])) require_once $GLOBALS['prefixe'].'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + else require_once 'libs/PHPExcel_1.8.0_doc/Classes/PHPExcel/IOFactory.php'; + + // DISPLAY OBJ + try { + $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML'); + $objWriter->save('php://output'); + + return true; + } + catch ( Exception $e ) { + return "ERREUR : ".$e->getMessage(); + } +} + +// FORMAT + +function br2nl($string) { + return preg_replace('/\/i', "", $string); +} + +function orderListByKey($list, $key, $sens='ASC', $sort_type=SORT_REGULAR) { + $keyList = array(); + $itemList = array(); + + foreach($list as $k => $i) { + $keyList[] = $k; + $itemList[] = $i[$key]; + } + + $sort_sens = ($sens=="ASC") ? SORT_ASC : SORT_DESC; + + array_multisort($itemList, $sort_sens, $sort_type, $keyList); + + $newList = array(); + + foreach($keyList as $k) { + $newList[] = $list[$k]; + } + + return $newList; +} + +function strtoupperFirstLetter($str) { + if(strlen($str)==0) return $str; + return strtoupper(substr($str,0,1)).substr($str,1); +} +// DATE + +function getTime($date,$moment='start',$format=DATE_FORMAT) { // Retourne un timestamp à partir d'une date jj/mm/aaaa + $infos = strptime($date,$format); + if (is_array($infos)) { + if ($moment=='start') { + return mktime( + '0', + '0', + '0', + ($infos['tm_mon']+1), + $infos['tm_mday'], + (1900+$infos['tm_year']) + ); + } + elseif ($moment=='end') { + return mktime( + '23', + '59', + '59', + ($infos['tm_mon']+1), + $infos['tm_mday'], + (1900+$infos['tm_year']) + ); + } + return mktime( + $infos['tm_hour'], + $infos['tm_min'], + $infos['tm_sec'], + ($infos['tm_mon']+1), + $infos['tm_mday'], + (1900+$infos['tm_year']) + ); + } + return NULL; +} + +function getDateTxt($timestamp,$format=DATE_FORMAT) { + if ($timestamp==0) { + return ''; + } + return strftime($format,(int)$timestamp); +} + +$GLOBALS['PRINT_MOIS_COURT'] = array( + 1 => 'janv.', + 2 => 'fév.', + 3 => 'mars', + 4 => 'avril', + 5 => 'mai', + 6 => 'juin', + 7 => 'juil.', + 8 => 'août', + 9 => 'sept.', + 10 => 'oct.', + 11 => 'nov.', + 12 => 'déc.' +); +$GLOBALS['PRINT_MOIS'] = array( + 1 => 'janvier', + 2 => 'février', + 3 => 'mars', + 4 => 'avril', + 5 => 'mai', + 6 => 'juin', + 7 => 'juillet', + 8 => 'août', + 9 => 'septembre', + 10 => 'octobre', + 11 => 'novembre', + 12 => 'décembre' +); + +$GLOBALS['PRINT_JOUR_INI'] = array( + 0 => 'D.', + 1 => 'L.', + 2 => 'Ma.', + 3 => 'Me.', + 4 => 'J.', + 5 => 'V.', + 6 => 'S.' +); + +$GLOBALS['PRINT_JOUR_COURT'] = array( + 0 => 'dim.', + 1 => 'lun.', + 2 => 'mar.', + 3 => 'mer.', + 4 => 'jeu.', + 5 => 'ven.', + 6 => 'sam.' +); +$GLOBALS['PRINT_JOUR'] = array( + 0 => 'dimanche', + 1 => 'lundi', + 2 => 'mardi', + 3 => 'mercredi', + 4 => 'jeudi', + 5=> 'vendredi', + 6 => 'samedi' +); + +function checkDateFormat($date, $format = 'mysql_datetime', $default = NULL) { + if($default == "now") $default = formatDate('', $format); + return isValidDate($date, $format) ? $date : $default; +} + +function isValidDate($date, $format = 'mysql_datetime') { + $f = "Y-m-d"; + switch($format) { + case 'date': $f = "d/m/Y"; break; + case 'datetime': $f = "d/m/Y - H:i"; break; + case 'mysql_date': $f = "Y-m-d"; break; + case 'mysql_datetime': $f = "Y-m-d H:i:s"; break; + case 'strdatetime': $f = "Y-m-d_H.i.s"; break; + default; $f = "Y-m-d"; + } + $d = DateTime::createFromFormat($f, $date); + if($d && $d->format($f) == $date) return true; + return false; +} + +function getRequestDate($name, $format="mysql_date") { + if(isset($_REQUEST[$name]) && $_REQUEST[$name]!="") return checkDateFormat($_REQUEST[$name], $format); + return NULL; +} + +function buildDate($day = 0, $month = 0, $year = 0, $forceBuild = false, $default = NULL) { + $date = $default; + + if((int)$year>0) { + $date = $year; + if((int)$month>0 && (int)$month<13) { + $date .= "-".sprintf("%02d", $month); + $nbJ = cal_days_in_month(CAL_GREGORIAN, $month, $year); + if((int)$day>0 && (int)$day<($nbJ+1)) { + $date .= "-".sprintf("%02d", $day); + } + else if($forceBuild) $date .= "-1"; + } + else if($forceBuild) $date .= "-1-1"; + } + return $date; +} + +function buildDatePrint ($day = 0, $month = 0, $year = 0, $default = ".") { + $date = $default; + if((int)$year>0) { + $date = $year; + if((int)$month>0 && (int)$month<13) { + $date = $GLOBALS['PRINT_MOIS'][$month]." ".$date; + $nbJ = cal_days_in_month(CAL_GREGORIAN, $month, $year); + if((int)$day>0 && (int)$day<($nbJ+1)) { + $d = $year."-".sprintf("%02d", $month)."-".sprintf("%02d", $day); + $date = formatDate($d, 'mysql_date', 'print_date_with_day'); + } + } + } + return $date; +} + +function buildDatePrintShort ($day = 0, $month = 0, $year = 0, $default = ".") { + $date = $default; + if((int)$year>0) { + $date = $year; + if((int)$month>0 && (int)$month<13) { + $date = $GLOBALS['PRINT_MOIS'][$month]." ".$date; + $nbJ = cal_days_in_month(CAL_GREGORIAN, $month, $year); + if((int)$day>0 && (int)$day<($nbJ+1)) { + $d = $year."-".sprintf("%02d", $month)."-".sprintf("%02d", $day); + $date = formatDate($d, 'mysql_date', 'date'); + } + } + } + return $date; +} + +function checkExplodeDate($day = 0, $month = 0, $year = 0, $default = NULL) { + $r = array( + "day" => $default, + "month" => $default, + "year" => $default, + "date" => $default + ); + + if((int)$year>0 && $year<2101) { + $r["year"] = $year; + if((int)$month>0 && (int)$month<13) { + $r["month"] = $month; + $nbJ = cal_days_in_month(CAL_GREGORIAN, $month, $year); + if((int)$day>0 && (int)$day<($nbJ+1)) $r["day"] = $day; + } + } + + $r['date'] = buildDate($r["day"], $r["month"], $r["year"], true); + + return $r; +} + +function formatDate($original='', $originalFormat="mysql_datetime", $destinationFormat="datetime", $moment=false) { + $infos = false; + if($original!='' && intVal($original)!=0) { + switch($originalFormat) { + case 'date': + $originalFormat = "%d/%m/%Y"; + $infos = strptime($original,$originalFormat); + break; + case 'datetime': + $originalFormat = "%d/%m/%Y - %H:%M"; + $infos = strptime($original,$originalFormat); + break; + case 'mysql_date': + $originalFormat = "%Y-%m-%d"; + $infos = strptime($original,$originalFormat); + break; + case 'mysql_datetime': + $originalFormat = "%Y-%m-%d %H:%M:%S"; + $infos = strptime($original,$originalFormat); + break; + case 'strdatetime': + $originalFormat = "%Y-%m-%d_%H.%M.%S"; + $infos['tm_mday_week'] = sprintf("%02d", $infos['tm_mday']); + break; + case 'timestamp': + $infos = array( + 'tm_hour' => date('G',$original), + 'tm_min' => intval( date('i',$original) ), + 'tm_sec' => intval( date('s',$original) ), + 'tm_mday' => date('j',$original), + 'tm_wday' => date('N',$original), + 'tm_mon' => date('n',$original)-1, + 'tm_year' => date('Y',$original)-1900 + ); + if($infos["tm_wday"]==7) $infos["tm_wday"] = 0; + //echo($original.' : '.$infos['tm_year'].' '); + break; + default; + $infos = strptime(strftime("%c"),"%c"); + } + + if($originalFormat=="date" || $originalFormat=="mysql_date" || ($moment=="start" || $moment=="end")) { + if($moment=="start") { + $infos['tm_hour'] = 0; + $infos['tm_min'] = 0; + $infos['tm_sec'] = 0; + } + else { + $infos['tm_hour'] = 23; + $infos['tm_min'] = 59; + $infos['tm_sec'] = 59; + } + } + } + else { + $infos = strptime(strftime("%c"),"%c"); + } + $infos['tm_hour'] = sprintf("%02d", $infos['tm_hour']); + $infos['tm_min'] = sprintf("%02d", $infos['tm_min']); + $infos['tm_sec'] = sprintf("%02d", $infos['tm_sec']); + $infos['tm_mday'] = sprintf("%02d", $infos['tm_mday']); + $infos['tm_mon'] = sprintf("%02d", ($infos['tm_mon']+1)); + $infos['tm_year'] = (1900+$infos['tm_year']); + + //echo($original.' : '.$infos['tm_year'].' '); + + switch($destinationFormat) { + case 'date': // "%d/%m/%Y" + return $infos['tm_mday']."/".$infos['tm_mon']."/".$infos['tm_year']; + break; + case 'time': // "%d/%m/%Y" + return $infos['tm_hour'].":".$infos['tm_min']; + break; + case '%m-%d': + return $infos['tm_mon']."-".$infos['tm_mday']; + break; + case 'strdate': // "%Y-%m-%d" + return $infos['tm_year']."-".$infos['tm_mon']."-".$infos['tm_mday']; + break; + case 'strdatetime': // "%Y-%m-%d_%H.%M.%S" + return $infos['tm_year']."-".$infos['tm_mon']."-".$infos['tm_mday']."_".$infos['tm_hour'].".".$infos['tm_min'].".".$infos['tm_sec']; + break; + case 'datetime': // "%d/%m/%Y - %H:%M" + return $infos['tm_mday']."/".$infos['tm_mon']."/".$infos['tm_year']." - ".$infos['tm_hour'].":".$infos['tm_min']; + break; + case 'print_date': // "j mois annee" + return $infos['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infos['tm_mon'])]." ".$infos['tm_year']; + break; + case 'print_date_with_day': // "jour j mois annee" + return $GLOBALS['PRINT_JOUR'][$infos['tm_wday']]." ".$infos['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infos['tm_mon'])]." ".$infos['tm_year']; + break; + case 'print_datetime': // "j mois annee à heure h min" + return $infos['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infos['tm_mon'])]." ".$infos['tm_year']." à ".$infos['tm_hour']."h".$infos['tm_min']; + break; + case 'mysql_date': // "%Y-%m-%d" + return $infos['tm_year']."-".$infos['tm_mon']."-".$infos['tm_mday']; + break; + case 'mysql_datetime': //"%Y-%m-%d %H:%M:%S" + return $infos['tm_year']."-".$infos['tm_mon']."-".$infos['tm_mday']." ".$infos['tm_hour'].":".$infos['tm_min'].":".$infos['tm_sec']; + break; + case 'timestamp': //timestamp + return mktime(intval($infos['tm_hour']),intval($infos['tm_min']),intval($infos['tm_sec']),intval($infos['tm_mon']),intval($infos['tm_mday']),intval($infos['tm_year'])); + break; + default; + return ""; + } +} + +function formatPeriode($originalDeb='', $originalFin='', $originalFormat="mysql_datetime", $time=true) { + // DEBUT + $infosDeb = false; + if($originalDeb!='' && intVal($originalDeb)!=0) { + switch($originalFormat) { + case 'date': + $infosDeb = strptime($originalDeb,"%d/%m/%Y"); + break; + case 'datetime': + $infosDeb = strptime($originalDeb,"%d/%m/%Y - %H:%M"); + break; + case 'mysql_date': + $infosDeb = strptime($originalDeb,"%Y-%m-%d"); + break; + case 'mysql_datetime': + $infosDeb = strptime($originalDeb,"%Y-%m-%d %H:%M:%S"); + break; + case 'timestamp': + $infosDeb = array( + 'tm_hour' => date('G',$originalDeb), + 'tm_min' => intval( date('i',$originalDeb) ), + 'tm_sec' => intval( date('s',$originalDeb) ), + 'tm_mday' => date('j',$originalDeb), + 'tm_mon' => date('n',$originalDeb)-1, + 'tm_year' => date('Y',$originalDeb)-1900 + ); + break; + default; + $infosDeb = strptime(strftime("%c"),"%c"); + } + + if($originalFormat=="date" || $originalFormat=="mysql_date") { + $infosDeb['tm_hour'] = 0; + $infosDeb['tm_min'] = 0; + $infosDeb['tm_sec'] = 0; + } + } + else { + $infosDeb = strptime(strftime("%c"),"%c"); + } + + $infosDeb['tm_hour'] = sprintf("%02d", $infosDeb['tm_hour']); + $infosDeb['tm_min'] = sprintf("%02d", $infosDeb['tm_min']); + $infosDeb['tm_sec'] = sprintf("%02d", $infosDeb['tm_sec']); + $infosDeb['tm_mday'] = sprintf("%02d", $infosDeb['tm_mday']); + $infosDeb['tm_mon'] = sprintf("%02d", ($infosDeb['tm_mon']+1)); + $infosDeb['tm_year'] = (1900+$infosDeb['tm_year']); + + // FIN + $infosFin = false; + if($originalFin && ($originalFin!='' && intVal($originalFin)!=0)) { + switch($originalFormat) { + case 'date': + $infosFin = strptime($originalFin,"%d/%m/%Y"); + break; + case 'datetime': + $infosFin = strptime($originalFin,"%d/%m/%Y - %H:%M"); + break; + case 'mysql_date': + $infosFin = strptime($originalFin,"%Y-%m-%d"); + break; + case 'mysql_datetime': + $infosFin = strptime($originalFin,"%Y-%m-%d %H:%M:%S"); + break; + case 'timestamp': + $infosFin = array( + 'tm_hour' => date('G',$originalFin), + 'tm_min' => intval( date('i',$originalFin) ), + 'tm_sec' => intval( date('s',$originalFin) ), + 'tm_mday' => date('j',$originalFin), + 'tm_mon' => date('n',$originalFin)-1, + 'tm_year' => date('Y',$originalFin)-1900 + ); + break; + default; + $infosFin = strptime(strftime("%c"),"%c"); + } + + if($originalFormat=="date" || $originalFormat=="mysql_date") { + $infosFin['tm_hour'] = 0; + $infosFin['tm_min'] = 0; + $infosFin['tm_sec'] = 0; + } + } + + if(!$infosFin) { + if($time && ($originalFormat!="date" && $originalFormat!="mysql_date")) return 'le '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." ".$infosDeb['tm_year']." à ".$infosDeb['tm_hour']."h".$infosDeb['tm_min']; + else return 'le '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." ".$infosDeb['tm_year']; + } + else { + $infosFin['tm_hour'] = sprintf("%02d", $infosFin['tm_hour']); + $infosFin['tm_min'] = sprintf("%02d", $infosFin['tm_min']); + $infosFin['tm_sec'] = sprintf("%02d", $infosFin['tm_sec']); + $infosFin['tm_mday'] = sprintf("%02d", $infosFin['tm_mday']); + $infosFin['tm_mon'] = sprintf("%02d", ($infosFin['tm_mon']+1)); + $infosFin['tm_year'] = (1900+$infosFin['tm_year']); + + if($time && ($originalFormat!="date" && $originalFormat!="mysql_date")) { + if($infosDeb['tm_hour']==$infosFin['tm_hour'] + && $infosDeb['tm_min']==$infosFin['tm_min'] + && $infosDeb['tm_mday']==$infosFin['tm_mday'] + && $infosDeb['tm_mon']==$infosFin['tm_mon'] + && $infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME JOUR, MEME HEURE + return 'le '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." ".$infosDeb['tm_year']." à ".$infosDeb['tm_hour']."h".$infosDeb['tm_min']; + } + elseif($infosDeb['tm_mday']==$infosFin['tm_mday'] + && $infosDeb['tm_mon']==$infosFin['tm_mon'] + && $infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME JOUR, HEURE DIFF + return 'le '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." ".$infosDeb['tm_year']." de ".$infosDeb['tm_hour']."h".$infosDeb['tm_min']." à ".$infosFin['tm_hour']."h".$infosFin['tm_min']; + } + elseif($infosDeb['tm_mon']==$infosFin['tm_mon'] + && $infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME MOIS, JOUR & HEURE DIFF + return 'du '.$infosDeb['tm_mday']." à ".$infosDeb['tm_hour']."h".$infosDeb['tm_min']." au ".$infosFin['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']." à ".$infosFin['tm_hour']."h".$infosFin['tm_min']; + } + elseif($infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME ANNEE, JOUR/MOIS & HEURE DIFF + return 'du '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." à ".$infosDeb['tm_hour']."h".$infosDeb['tm_min']." au ".$infosFin['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']." à ".$infosFin['tm_hour']."h".$infosFin['tm_min']; + } + else { + return 'du '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." ".$infosDeb['tm_year']." à ".$infosDeb['tm_hour']."h".$infosDeb['tm_min']." au ".$infosFin['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']." à ".$infosFin['tm_hour']."h".$infosFin['tm_min']; + } + + } + else { + if($infosDeb['tm_mday']==$infosFin['tm_mday'] + && $infosDeb['tm_mon']==$infosFin['tm_mon'] + && $infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME JOUR + return 'le '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']; + } + elseif($infosDeb['tm_mon']==$infosFin['tm_mon'] + && $infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME MOIS, JOUR DIFF + return 'du '.$infosDeb['tm_mday']." au ".$infosFin['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']; + } + elseif($infosDeb['tm_year']==$infosFin['tm_year']) { + // MEME ANNEE, JOUR/MOIS + return 'du '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." au ".$infosFin['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']; + } + else { + return 'du '.$infosDeb['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosDeb['tm_mon'])]." ".$infosDeb['tm_year']." au ".$infosFin['tm_mday']." ".$GLOBALS['PRINT_MOIS_COURT'][intVal($infosFin['tm_mon'])]." ".$infosFin['tm_year']; + } + } + } +} + +function getPeriode($target=false,$duree="3m") { + if(!$target) $target=strftime("%d/%m/%Y"); + + $targetDT = new DateTime(formatDate($target,"date","mysql_datetime"), new DateTimeZone(DATE_TIME_ZONE)); + + $limit1 = new DateTime("now", new DateTimeZone(DATE_TIME_ZONE)); + $limit1->setDate($targetDT->format("Y"), $targetDT->format("m"), 0); + $limit1->setTime(0,0,0); + + $limit2 = new DateTime("now", new DateTimeZone(DATE_TIME_ZONE)); + $limit2->setDate($targetDT->format("Y"), $targetDT->format("m"), $targetDT->format("t")); + $limit2->setTime(23,59,59); + + $int = new DateInterval('P0M'); + + switch($_SESSION['periode_view']) { + case "1m": + $int = new DateInterval('P1M'); + break; + case "3m": + $int = new DateInterval('P3M'); + break; + case "6m": + $int = new DateInterval('P6M'); + break; + case "1y": + $int = new DateInterval('P1Y'); + break; + } + + $limit1->sub($int); + $limit2->add($int); + + return array( + "start" => array( + 'datetime' => $limit1, + 'mysql_date' => $limit1->format('Y-m-d H:i:s') + ), + "end" => array( + 'datetime' => $limit2, + 'mysql_date' => $limit2->format('Y-m-d H:i:s') + ) + ); +} + +function getPeriodeJoursFeries($debut,$fin,$format="Y-m-d") { + $liste = array(); + + $dt = new DateTime($debut, new DateTimeZone("Europe/Paris")); + $dt->setTime(0, 0, 0); + $ft = new DateTime($fin, new DateTimeZone("Europe/Paris")); + $ft->setTime(23,59, 59); + + $ndt = clone $dt; + while($ndt < $ft) { + $jf = getYearJoursFeries($ndt->format('Y'),$format); + foreach($jf as $k => $j) { + if( $j['datetime'] >= $dt && $j['datetime'] <= $ft ) $liste[$k] = $j; + } + $ndt->add( new DateInterval('P1Y') ); + $ndt->setDate((int)$ndt->format('Y'),1,1); + } + + ksort($liste); + + return $liste; +} + +function getYearJoursFeries($year=false,$format="Y-m-d") { + if(!$year) $year = intval(date('Y')); + $liste = array(); + + $date = new DateTime(); + $date->setTimezone(new DateTimeZone('Europe/Paris')); + $date->setTime(0,0,0); + + $easter_date = new DateTime('@' . easter_date($year)); + $easter_date->setTimezone(new DateTimeZone('Europe/Paris')); + $easter_date->setTime(0,0,0); + + // Jour de l'an - 1er janvier + $date->setDate($year, 1, 1); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Jour de l'An" + ); + // Fête du travail - 1er mai + $date->setDate($year, 5, 1); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Fête du Travail" + ); + // Victoire des alliés - 8 mai 1945 + $date->setDate($year, 5, 8); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Victoire des Alliés - 8 mai 1945" + ); + // Fête nationale - 14 juillet + $date->setDate($year, 7, 14); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Fête Nationale" + ); + // Assomption - 15 août + $date->setDate($year, 8, 15); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Assomption" + ); + // Toussaint - 1er novembre + $date->setDate($year, 11, 1); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Toussaint" + ); + // Armistice 1ère Guerre Mondiale - 11 novembre + $date->setDate($year, 11, 11); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Armistice 1ère Guerre Mondiale" + ); + // Noël - 25 décembre + $date->setDate($year, 12, 25); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Noël" + ); + // Lundi de Pâques - lendemain du dimanche de Pâques + $date = clone $easter_date; + $date->add(new DateInterval('P1D')); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Lundi de Pâques" + ); + // Jeudi de l'ascension - 10 jours avant le Dimanche de Pentecôte + $date = clone $easter_date; + $date->add(new DateInterval('P39D')); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Jeudi de l'Ascension" + ); + // Lundi de Pentecôte - lendemain de la Pentecôte - 7 semaines après le lundi de pâque + $date = clone $easter_date; + $date->add(new DateInterval('P50D')); + $liste[ $date->format($format) ] = array( + 'datetime' => clone $date, + 'description' => "Lundi de Pentecôte" + ); + return $liste; +} + +function getHeadCol($target=false,$start=false,$end=false) { + if(!$start && !$end) { + if(!$target) $target=strftime("%d/%m/%Y"); + $target = getTime($target,"start","%d/%m/%Y"); + + switch($_SESSION['periode_view']) { + case "m": + return getYearHeadCol(date('Y',$target),date('n',$target),date('n',$target)); + break; + case "1m": + $mois = array(); + + if(date('n',$target)>1) $mois[] = getMonthHeadCol(date('Y',$target),date('n',$target)-1); + else $mois[] = getMonthHeadCol((date('Y',$target)-1),12); + + $mois[] = getMonthHeadCol(date('Y',$target),date('n',$target)); + + if(date('n',$target)<12) $mois[] = getMonthHeadCol(date('Y',$target),date('n',$target)+1); + else $mois[] = getMonthHeadCol((date('Y',$target)+1),1); + + return $mois; + break; + case "3m": + $mois = array(); + + if(date('n',$target)>3) $mois = getYearHeadCol(date('Y',$target),(date('n',$target)-3),date('n',$target)); + else { + $mois = getYearHeadCol((date('Y',$target)-1),(date('n',$target)-3+12),12); + + $ms = getYearHeadCol(date('Y',$target),1,date('n',$target)); + foreach($ms as $m) array_push($mois, $m); + } + + if(date('n',$target)<10) { + $ms = getYearHeadCol(date('Y',$target),(date('n',$target)+1),(date('n',$target)+3)); + foreach($ms as $m) array_push($mois, $m); + } + else { + $ms = getYearHeadCol(date('Y',$target),(date('n',$target)+1),12); + foreach($ms as $m) array_push($mois, $m); + + $ms = getYearHeadCol((date('Y',$target)+1),1,(date('n',$target)+3-12)); + foreach($ms as $m) array_push($mois, $m); + } + + return $mois; + break; + case "6m": + $mois = array(); + + if(date('n',$target)>6) $mois = getYearHeadCol(date('Y',$target),(date('n',$target)-6),date('m',$target)); + else { + $mois = getYearHeadCol((date('Y',$target)-1),(date('n',$target)-6+12),12); + + $ms = getYearHeadCol(date('Y',$target),1,date('n',$target)); + foreach($ms as $m) array_push($mois, $m); + } + + if(date('n',$target)<7) { + $ms = getYearHeadCol(date('Y',$target),(date('n',$target)+1),(date('n',$target)+6)); + foreach($ms as $m) array_push($mois, $m); + } + else { + $ms = getYearHeadCol(date('Y',$target),(date('n',$target)+1),12); + foreach($ms as $m) array_push($mois, $m); + + $ms = getYearHeadCol((date('Y',$target)+1),1,(date('n',$target)+6-12)); + foreach($ms as $m) array_push($mois, $m); + } + + return $mois; + break; + case "1y": + $year = array(date('Y',$target)-1, date('Y',$target), date('Y',$target)+1); + $mois = array(); + + foreach($year as $y) { + $ms = getYearHeadCol($y); + + foreach($ms as $m) { + array_push($mois, $m); + } + } + + return $mois; + break; + default : + return getYearHeadCol(date('Y',$target),date('n',$target),date('n',$target)); + break; + } + } + else { + $start = getTime($start,'start',"%Y-%m-%d"); + $end = getTime($end,'start',"%Y-%m-%d"); + + $mois = array(); + + $t = $start; + while($t<$end) { + $j = date('j',$t); + $m = date('n',$t); + $mNbj = date('t',$t); + $y = date('Y',$t); + $mEnd = mktime('0','0','0',$m,$mNbj,$y); + + if($mEnd < $end) { + // Mois en cours jusqu'à la fin du mois + $mois[] = getMonthHeadCol($y,$m,$j,$mNbj); + $t = $mEnd + 86400; + } + else { + // Mois en cours jusqu'à la date de fin + $mois[] = getMonthHeadCol($y,$m,$j,date('j',$end)); + $t = $end; + } + } + return $mois; + } +} + +function getOpeHeadCol($debut,$fin) { + $mois = array(); + + // CREATION DES JOURS + $edt = new DateTime($debut, new DateTimeZone("Europe/Paris")); + $edt->setTime(0, 0, 0); + $eft = new DateTime($fin, new DateTimeZone("Europe/Paris")); + $eft->setTime(23,59, 59); + + foreach (new DatePeriod($edt, new DateInterval('P1D'), $eft) as $dt) { + $dt->setTime(0, 0, 0); + + $j = intval($dt->format('d')); + $m = $dt->format('Y-m'); + $im = intval($dt->format('m')); + $y = intval($dt->format('Y')); + + if(!isset($mois[$m])) { + $mois[$m] = array( + 'num' => $im, + 'nom' => $GLOBALS['PRINT_MOIS'][$im], + 'nom_court' => $GLOBALS['PRINT_MOIS_COURT'][$im], + 'annee' => $y, + 'nb_jours' => 0, + 'jours' => array() + ); + } + + $t = mktime('0', '0', '0', $im, $j, $y); + $ind = strftime('%w',$t); + + $mois[$m]['jours'][$j] = array( + 'num' => $j, + 'jour' => $GLOBALS['PRINT_JOUR'][$ind], + 'jour_court' => $GLOBALS['PRINT_JOUR_COURT'][$ind], + 'ind' => $ind, + 'date' => $dt->format('d/m/Y'),strftime('%d/%m/%Y',$t), + 'date_link' => $dt->format('Y-m-d'), + 'time' => $t + ); + $mois[$m]['nb_jours']++; + } + return $mois; +} + +function getYearHeadCol($year,$startM=1,$endM=12) { + //addDebug("de ".$GLOBALS['PRINT_MOIS_COURT'][$startM]." à ".$GLOBALS['PRINT_MOIS_COURT'][$endM]." ".$year,"getYearHeadCol"); + $mois = array(); + for($i=$startM;$i<=$endM;$i++) { + $mois[$i] = array( + 'num' => $i, + 'nom' => $GLOBALS['PRINT_MOIS'][$i], + 'nom_court' => $GLOBALS['PRINT_MOIS_COURT'][$i], + 'annee' => $year, + 'nb_jours' => cal_days_in_month(CAL_GREGORIAN, $i, $year), + 'jours' => array() + ); + + for($j=1 ; $j<=cal_days_in_month(CAL_GREGORIAN, $i, $year) ; $j++) { + $t = mktime('0', '0', '0', $i, $j, $year); + $ind = strftime('%w',$t); + $mois[$i]['jours'][$j] = array( + 'num' => $j, + 'jour' => $GLOBALS['PRINT_JOUR'][$ind], + 'jour_court' => $GLOBALS['PRINT_JOUR_COURT'][$ind], + 'ind' => $ind, + 'date' => strftime('%d/%m/%Y',$t), + 'date_link' => strftime('%Y-%m-%d',$t), + 'time' => $t + ); + } + + } + return $mois; +} + +function getMonthHeadCol($year,$m,$startJ=false,$endJ=false) { + //addDebug($GLOBALS['PRINT_MOIS_COURT'][$m]." ".$year ,"getMonthHeadCol"); + $mois = array( + 'num' => $m, + 'nom' => $GLOBALS['PRINT_MOIS'][$m], + 'nom_court' => $GLOBALS['PRINT_MOIS_COURT'][$m], + 'annee' => $year, + 'nb_jours' => cal_days_in_month(CAL_GREGORIAN, $m, $year), + 'jours' => array() + ); + + $nbj = cal_days_in_month(CAL_GREGORIAN, $m, $year); + if(!$startJ || $startJ>$nbj || (int)$startJ==0) $startJ = 1; + + if(!$endJ || $endJ>$nbj || (int)$endJ==0) $endJ = $nbj; + + for($j=$startJ ; $j<=$endJ ; $j++) { + $t = mktime('0', '0', '0', $m, $j, $year); + $ind = strftime('%w',$t); + $mois['jours'][$j] = array( + 'num' => $j, + 'jour' => $GLOBALS['PRINT_JOUR'][$ind], + 'jour_court' => $GLOBALS['PRINT_JOUR_COURT'][$ind], + 'ind' => $ind, + 'date' => strftime('%d/%m/%Y',$t), + 'date_link' => strftime('%Y-%m-%d',$t), + 'time' => $t + ); + } + + return $mois; +} + +function diffNbJours($debut, $fin,$format='date') { + //60 secondes X 60 minutes X 24 heures dans une journée + $nbSecondes= 60*60*24; + + $debut_s = formatDate($debut,$format,'strdate'); + $fin_s = formatDate($fin,$format,'strdate'); + + $debut_ts = strtotime($debut_s); + $fin_ts = strtotime($fin_s); + + $diff = $fin_ts - $debut_ts; + + return floor($diff / $nbSecondes)+1; +} + +function diffNbJours2($debut, $fin) { + $dt1 = new DateTime($debut); + $dt1->setTime(0, 0, 0); + $dt2 = new DateTime($fin); + $dt2->setTime(23,59, 59); + $itv = date_diff($dt1, $dt2); + return intval($itv->format('%a'))+1; +} + +function getNbOpenDays($date_start, $date_end) { + // $date_depart && $date_end au format YYYY-MM-DD + + $dtd = date_create($date_start); + $dtd->setTime(0, 0, 0); + $dtf = date_create($date_end); + $dtf->setTime(0, 0, 0); + $dtf->modify( '+1 day' ); + + $arr_bank_holidays = array(); // Tableau des jours feriés + + // On boucle dans le cas où l'année de départ serait différente de l'année d'arrivée + $diff_year = $dtf->format('Y') - $dtd->format('Y'); + for ($i = 0; $i <= $diff_year; $i++) { + $year = (int)$dtd->format('Y') + $i; + // Liste des jours feriés + $arr_bank_holidays[] = '1_1_'.$year; // Jour de l'an + $arr_bank_holidays[] = '1_5_'.$year; // Fete du travail + $arr_bank_holidays[] = '8_5_'.$year; // Victoire 1945 + $arr_bank_holidays[] = '14_7_'.$year; // Fete nationale + $arr_bank_holidays[] = '15_8_'.$year; // Assomption + $arr_bank_holidays[] = '1_11_'.$year; // Toussaint + $arr_bank_holidays[] = '11_11_'.$year; // Armistice 1918 + $arr_bank_holidays[] = '25_12_'.$year; // Noel + + // Récupération de paques. Permet ensuite d'obtenir le jour de l'ascension et celui de la pentecote + $easter = easter_date($year); + $arr_bank_holidays[] = date('j_n_'.$year, $easter + 86400); // Paques + $arr_bank_holidays[] = date('j_n_'.$year, $easter + (86400*39)); // Ascension + $arr_bank_holidays[] = date('j_n_'.$year, $easter + (86400*50)); // Pentecote + } + + $nb_days_open = 0; + + foreach (new DatePeriod($dtd, new DateInterval('P1D'), $dtf) as $dt) { + $dt = new DateTime($dt->format('Y-m-d'), new DateTimeZone("Europe/Paris")); + // Si le jour suivant n'est ni un dimanche (0) ou un samedi (6), ni un jour férié, on incrémente les jours ouvrés + if (!in_array($dt->format('w'), array(0, 6)) && !in_array($dt->format('j_n_Y'), $arr_bank_holidays)) $nb_days_open++; + } + + return $nb_days_open; +} + +function replaceSymboles($string){ + $replaceSymboles = Array( + " " => "_", + "/" => "-", + '"' => "", + "'" => "", + ":" => "_", + "&" => "_", + "+" => "_", + "à" => "a", + "á" => "a", + "â" => "a", + "ã" => "a", + "ä" => "a", + "ç" => "c", + "è" => "e", + "é" => "e", + "ê" => "e", + "ë" => "e", + "ì" => "i", + "í" => "i", + "î" => "i", + "ï" => "i", + "ñ" => "n", + "ò" => "o", + "ó" => "o", + "ô" => "o", + "õ" => "o", + "ö" => "o", + "ù" => "u", + "ú" => "u", + "û" => "u", + "ü" => "u", + "ý" => "y", + "ÿ" => "y", + "À" => "A", + "Á" => "A", + "Â" => "A", + "Ã" => "A", + "Ä" => "A", + "Ç" => "C", + "È" => "E", + "É" => "E", + "Ê" => "E", + "Ë" => "E", + "Ì" => "I", + "Í" => "I", + "Î" => "I", + "Ï" => "I", + "Ñ" => "N", + "Ò" => "O", + "Ó" => "O", + "Ô" => "O", + "Õ" => "O", + "Ö" => "O", + "Ù" => "U", + "Ú" => "U", + "Û" => "U", + "Ü" => "U", + "Ý" => "Y" + ); + return strtr($string,$replaceSymboles); +} + +/*** REFUSE TOUTE CONNECTION AUTRE QUE AJAX ***/ + +function preventDirectAccess() { + // prevent direct access + $isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND + strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'; + if(!$isAjax) { + $user_error = 'Access denied - not an AJAX request...'; + trigger_error($user_error, E_USER_ERROR); + return; + } + return true; +} + +/*** AUTO COMPLETE HIGHLIGHT ***/ + +/** + * mb_stripos all occurences + * based on http://www.php.net/manual/en/function.strpos.php#87061 + * + * Find all occurrences of a needle in a haystack + * + * @param string $haystack + * @param string $needle + * @return array or false + */ +function mb_stripos_all($haystack, $needle) { + + $s = 0; + $i = 0; + + while(is_integer($i)) { + + $i = mb_stripos($haystack, $needle, $s); + + if(is_integer($i)) { + $aStrPos[] = $i; + $s = $i + mb_strlen($needle); + } + } + + if(isset($aStrPos)) { + return $aStrPos; + } else { + return false; + } +} + +/** + * Apply highlight to row label + * + * @param string $a_json json data + * @param array $parts strings to search + * @return array + */ +function apply_highlight($a_json, $parts) { + error_reporting(0); + $p = count($parts); + $rows = count($a_json); + + for($row = 0; $row < $rows; $row++) { + + $label = $a_json[$row]["label"]; + $a_label_match = array(); + + for($i = 0; $i < $p; $i++) { + + $part_len = mb_strlen($parts[$i]); + $a_match_start = mb_stripos_all($label, $parts[$i]); + + foreach($a_match_start as $part_pos) { + + $overlap = false; + foreach($a_label_match as $pos => $len) { + if($part_pos - $pos >= 0 && $part_pos - $pos < $len) { + $overlap = true; + break; + } + } + if(!$overlap) { + $a_label_match[$part_pos] = $part_len; + } + + } + + } + + if(count($a_label_match) > 0) { + ksort($a_label_match); + + $label_highlight = ''; + $start = 0; + $label_len = mb_strlen($label); + + foreach($a_label_match as $pos => $len) { + if($pos - $start > 0) { + $no_highlight = mb_substr($label, $start, $pos - $start); + $label_highlight .= $no_highlight; + } + $highlight = '' . mb_substr($label, $pos, $len) . ''; + $label_highlight .= $highlight; + $start = $pos + $len; + } + + if($label_len - $start > 0) { + $no_highlight = mb_substr($label, $start); + $label_highlight .= $no_highlight; + } + + $a_json[$row]["label"] = $label_highlight; + } + + } + + return $a_json; + +} + +// HCARD +function makeHCard( + $type="contact", + $nom="", + $prenom="", + $societe="", + $adresse="", + $cp="", + $ville="", + $pays="" +) { + $hcard = ""; + + // HEADER + if($type=="contact") { + $txt = ""; + + if($nom!="" && $prenom!="") $txt = $prenom." ".$nom; + else if($nom!="") $txt = $nom; + else if($prenom!="") $txt = $prenom; + $hcard = '
'; + + if($nom!="" || $prenom!="") { + $hcard .= ""; + if($prenom!="") $hcard .= ''.$prenom.''; + if($nom!="") $hcard .= ''.$nom.''; + $hcard.= ''; + } + if($societe!="") $hcard .= '
'.$societe.'
'; + } + else if($type=="societe") { + $hcard = '
'; + $hcard .= '
'.$societe.'
'; + + if($nom!="" || $prenom!="") { + $hcard .= ""; + $hcard.= "à l'attention de"; + if($prenom!="") $hcard .= ''.$prenom.''; + if($nom!="") $hcard .= ''.$nom.''; + $hcard.= ''; + } + } + else { + $hcard = '
'; + } + + // ADRESSE + $hcard .= '
'; + $hcard .= '
'.nl2br($adresse).'
'; + $hcard .= ''.$cp.''; + $hcard .= ''.$ville.''; + $hcard .= ''.$pays.''; + $hcard .= '
'; + + $hcard.="
"; + return $hcard; +} + +function msleep($time) { + usleep($time * 1000); +} + +// FICHIERS + +function parseDir($url_dir, $ignore=false, $recursive=false) { + if($url_dir=="") return array(); + + $lastChar = substr($url_dir, -1); + if($lastChar == '\\' || $lastChar == '/') $url_dir = substr($url_dir, 0, -1); + + $dir = opendir($url_dir); + $files= array(); + while($element = readdir($dir)) { + if(!$ignore && $element != '.' && $element != '..') { + if($recursive) $files[strval($element)] = $element; + else $files[] = $element; + } + elseif ($ignore && $element != '.' && $element != '..' && $element != '.DS_Store' && $element != '.gitignore') { + if($recursive) { + $file_url = $url_dir."/".$element; + if(is_dir($file_url)) $files[strval($element)] = parseDir($file_url, $ignore, $recursive); + else $files[strval($element)] = $element; + } + else $files[] = $element; + } + } + closedir($dir); + if(!$recursive) sort($files); + return $files; +} + +function copyRecusive($srcPath, $dirDest) { + if(!file_exists($srcPath) || !is_dir($srcPath)) return "Le dossier source est invalide ! (".$srcPath.')'; + if(!file_exists($dirDest) || !is_dir($dirDest)) return "Le dossier de destination est invalide ! (".$srcPath.')'; + + mkdir($dirDest, 0755); + + foreach ($iterator = new \RecursiveIteratorIterator ( + new \RecursiveDirectoryIterator($srcPath, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST) as $item ) { + if ($item->isDir()) { + mkdir($dirDest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } + else { + copy($item, $dirDest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } + } + return true; +} + +function truncateDir($dir_path) { + if(!file_exists($dir_path)) return "Dossier Introuvable ! (".$dir_path.')'; + else if(!is_dir($dir_path)) return "Le path transmis pointe sur un fichier... (".$dir_path.')'; + + $dir = opendir($dir_path); + $files = readdir($dir); + while($files = readdir($dir)) { + if($files != "..") { + $filepath = $dir_path."/".$files; + if(is_dir($filepath)) rmRecursive($filepath); + else unlink( $dir_path."/".$files ); + } + } + closedir($dir); +} + +function rmRecursive($path) { + if(!file_exists($path)) return "Fichier Introuvable ! (".$path.')'; + + if(is_dir($path)) { // DOSSIER + $dir = scandir($path, SCANDIR_SORT_DESCENDING); + if(count($dir)>2) { // LE DOSSIER N'EST PAS VIDE (en tenant compte de '.' && '..') + foreach($dir as $file_in_dir){ + if($file_in_dir == '.' or $file_in_dir == '..') break; // on sort de boucle : il n'y aura rien d'autre + $r = rmRecursive("$path/$file_in_dir"); + if(!( is_bool($r) && $r)) return $r; + } + } + + $r = rmdir($path); + if(!$r) return "Un problème est survenu à la supression d'un dossier ! (".$path.')'; + } + else { // FICHIER + $r = unlink($path); + if(!$r) return "Un problème est survenu à la supression d'un fichier ! (".$path.')'; + } + + return true; +} + +function rmLocalDir($path,$secondTry=false) { + if(!file_exists($path)) return "Fichier/Dossier Introuvable ! (".$path.')'; + + $outputs = array(); + $result = 0; + $r = exec('rm -rf '.realpath($path), $outputs, $result); + + msleep(200); + + if(!file_exists($path)) return true; + else if(!secondTry) rmLocalDir($path,true); + else return "Un problème est survenu à la supression du dossier ! (".$path.')'; +} + +function copyLocalDir($srcPath, $destDir, $destName=false) { + if(!file_exists($srcPath)) return "Le fichier source n'éxiste pas ! (".$srcPath.')'; + if(!file_exists($destDir)) return "Le dossier de destination est invalide ! (".$destDir.')'; + + if($destName==false) $destName = basename($srcPath); + + $destPath = realpath($destDir)."/".$destName; + + $cmd = 'cp -R '.realpath($srcPath)." ".$destPath; + + $r = shell_exec($cmd); + + if(file_exists($destPath)) return true; + else return "Un problème est survenu à la copie du dossier ! (".$cmd.')'; +} + +function syncLocalDir($srcPath, $destDir) { + if(!file_exists($srcPath)) return "Le dossier source est invalide ! (".$srcPath.')'; + if(!file_exists($destDir)) return "Le dossier de destination est invalide ! (".$destDir.')'; + $destPath = $destDir."/".basename($srcPath); + if(!file_exists($destPath)) return "Le dossier de synchronisation à destination n'éxistes pas ! (".$destPath.')'; + + $cmd = 'rsync -r -q --ignore-existing '.realpath($srcPath)." ".realpath($destDir); + $r = shell_exec($cmd); + + if(file_exists($destPath)) return true; + else return "Un problème est survenu à la synchronisation du dossier ! (".$cmd.')'; +} + +function getFileType($path) { + if(!(file_exists($path) && is_file($path))) return "Fichier Introuvable ! (".$path.')'; + + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mt = finfo_file($finfo, $path); + $type = explode('/',$mt); + $type = $type[0]; + + $pinfos = pathinfo($path); + + // PDF + if ($mt == 'application/pdf') { + $pdf = true; + $type = 'pdf'; + } + else $pdf = false; + + // VIDEO + $mvt = array('video/x-flv','video/mp4','application/x-mpegURL','video/MP2T','video/3gpp','video/quicktime','video/x-msvideo','video/x-ms-wmv'); + if (in_array($mt,$mvt)) { + $video = true; + $type = 'video'; + } + else $video = false; + + // AUDIO + $mat = array('audio/basic','auido/L24','audio/mid','audio/mpeg','audio/mp4','audio/x-aiff','audio/x-mpegurl','audio/vnd.rn-realaudio','audio/ogg','audio/vorbis','audio/vnd.wav'); + if (in_array($mt,$mat)) { + $audio = true; + $type = 'audio'; + } + else $audio = false; + + // DMG + $mdt = array('application/octet-stream', 'application/x-apple-diskimage', 'application/x-diskcopy', 'application/x-bzip2'); + if(in_array($mt,$mdt) && $pinfos['extension']=="dmg") { + $type = "dmg"; + } + + // EXE + $met = array('application/octet-stream', 'application/x-msdownload', 'application/exe', 'application/x-exe', 'application/dos-exe', 'vms/exe', 'application/x-winexe', 'application/msdos-windows', 'application/x-msdos-program','application/x-dosexec'); + if(in_array($mt,$met) && $pinfos['extension']=="exe") { + $type = "exe"; + } + + //echo($path." => ".$mt." - ".$type."
"); + + // BROWSER SUPPORT + $browser_support = ($type=='image' XOR $pdf XOR $audio XOR $video); + + return array('type' => $type, 'browser_support' => $browser_support); +} + +function forceDownloadFile($f,$file_name=false,$unlink=false) { + if(file_exists($f)) { + if(!$file_name || $file_name=="") $file_name = basename($f); + + session_write_close(); + + set_time_limit(0); + ignore_user_abort(false); + ini_set('output_buffering', 0); + ini_set('zlib.output_compression', 0); + + $date = gmdate(DATE_RFC1123); + + header('Pragma: public'); + header('Content-Description: File Transfer'); + header('Set-Cookie: fileDownload=true; path=/'); + header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0'); + + header('Content-Tranfer-Encoding: none'); + header('Content-Length: '.filesize($f)); + header('Content-MD5: '.base64_encode(md5_file($f))); + header('Content-Type: application/octetstream;'); + header('Content-Disposition: attachment; filename="'.$file_name.'"'); + + header('Date: '.$date); + header('Expires: '.gmdate(DATE_RFC1123, time()+1)); + header('Last-Modified: '.gmdate(DATE_RFC1123, filemtime($f))); + + ob_end_clean(); + flush(); + + $chunk = 10 * 1024 * 1024; // bytes per chunk (10 MB) + $fh = fopen($f, "rb"); + while (!feof($fh)) { + echo fread($fh, $chunk); + ob_flush(); // flush output + flush(); + if (connection_status()!=0) { + @fclose($fh); + die(); + } + } + + if($unlink) unlink($f); + + exit; + } + else return('ERREUR : Impossible de trouver le fichier à télécharger ! ("'.$f.'")'); + + return; +} + +function downloadFile($f,$file_name=false,$unlink=false) { + if(file_exists($f)) { + if(!$file_name || $file_name=="") $file_name = basename($f); + + session_write_close(); + + set_time_limit(0); + ignore_user_abort(false); + ini_set('output_buffering', 0); + ini_set('zlib.output_compression', 0); + + $date = gmdate(DATE_RFC1123); + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $type= finfo_file($finfo, $f); + + header('Pragma: public'); + header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0'); + + header('Content-Tranfer-Encoding: none'); + header('Content-Length: '.filesize($f)); + header('Content-MD5: '.base64_encode(md5_file($f))); + header('Content-Type: '.$type.'; name="'.$file_name.'"'); + header('Content-Disposition: inline; filename="'.$file_name.'"'); + + header('Date: '.$date); + header('Expires: '.gmdate(DATE_RFC1123, time()+1)); + header('Last-Modified: '.gmdate(DATE_RFC1123, filemtime($f))); + + ob_end_clean(); + flush(); + + $chunk = 10 * 1024 * 1024; // bytes per chunk (10 MB) + $fh = fopen($f, "rb"); + while (!feof($fh)) { + echo fread($fh, $chunk); + ob_flush(); // flush output + flush(); + if (connection_status()!=0) { + @fclose($fh); + die(); + } + } + + if($unlink) unlink($f); + + exit; + } + else return('ERREUR : Impossible de trouver le fichier à télécharger ! ("'.$f.'")'); + + return; +} + +function downloadFileAlt($f,$file_name=false,$force=false) { + if(!$file_name || $file_name=="") $file_name = basename($f); + + if(is_readable($f)) { + $fd = fopen($f, "rb"); + if ($fd) { + $date = gmdate(DATE_RFC1123); + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $type= finfo_file($finfo, $f); + + header('Pragma: public'); + header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0'); + + header('Content-Length: '.filesize($f)); + header('Content-MD5: '.base64_encode(md5_file($f))); + header('Content-Type: '.$type.'; name="'.$file_name.'"'); + + if($force) header("Content-Disposition: attachment; filename=\"".$file_name."\""); + else header('Content-Disposition: inline; filename="'.$file_name.'"'); + + while(!feof($fd)) { + $buffer = fread($fd, 1*(1024*1024)); + echo $buffer; + ob_flush(); + flush(); + } + } + else echo "Error opening file"; + fclose($fd); + } + + exit(); +} + +function formatFileSize($s, $decimals = 2) { + $units = array("o", "ko", "Mo", "Go", "To", "Po"); + $factor = floor((strlen($s) - 1) / 3); + return sprintf("%.{$decimals}f", intval($s) / pow(1024, $factor))." ".$units[$factor]; +} + +function addFilesInZipDir($srcDir, $zip, $zipDir) { + $files = parseDir($srcDir,1); + //afficheArray($files,1); + foreach($files as $f) { + if(is_dir($srcDir.'/'.$f)) { + $newDir = $zipDir.'/'.$f; + //echo("AJOUT DIR : ".$newDir.'
'); + $zip->addEmptyDir($newDir); + $zip = addFilesInZipDir($srcDir.'/'.$f, $zip, $newDir); + } + else { + //echo("AJOUT FICHIERS : ".$zipDir.'/'.$f.'
'); + $zip->addFile($srcDir.'/'.$f,$zipDir.'/'.$f); + } + } + return $zip; +} + +function file_upload_max_size($format=true) { + static $max_size = -1; + + if ($max_size < 0) { + // Start with post_max_size. + $max_size = parse_size(ini_get('post_max_size')); + + // If upload_max_size is less, then reduce. Except if upload_max_size is + // zero, which indicates no limit. + $upload_max = parse_size(ini_get('upload_max_filesize')); + if ($upload_max > 0 && $upload_max < $max_size) $max_size = $upload_max; + } + + return ($format) ? formatFileSize($max_size) : $max_size; +} + +function parse_size($size) { + $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size. + $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size. + if ($unit) { + // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by. + return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); + } + else return round($size); +} + +function exec_command($command) { + exec($command,$output, $exit_code); + + $result = array( + 'command' => $command, + 'output' => $output, + 'exit_code' => $exit_code, + 'error' => false + ); + + if($exit_code==0) return $result; + else if($exit_code==1) $result['error'] = "Une erreur général s'est produite durant l'execution de la commande"; + else if($exit_code==2) $result['error'] = "Détournement de fonction shell"; + else if($exit_code==126) $result['error'] = "La commande invoquée ne peut être exécutée. (Problème de permission ou de commande non-exécutable...)"; + else if($exit_code==127) $result['error'] = "La commande invoquée est introuvalbe !"; + else if($exit_code==128) $result['error'] = "L'argument de sortie est invalide ! (ce doit être un entier compirs entre 0 & 255)"; + else if($exit_code==130) $result['error'] = "La commande à été interrompu manuellement"; + else if($exit_code>128 && $exit_code<255) $result['error'] = "Erreur fatale (code = ".($exit_code-128).")"; + + return $result; +} + +// REMOTE FILE + +# setup a global file pointer +$remoteFileHandler = null; + +function saveRemoteFile($url, $file_output_path, $post_datas = false, $progressCallbackFct="", $auth = false, $ssl_disable=false) { + global $remoteFileHandler; + + set_time_limit(0); + + # Open the file for writing... + if(file_exists($file_output_path)) return "ERROR : file output already exists !"; + $remoteFileHandler = fopen($file_output_path, 'w+'); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FILE, $remoteFileHandler); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"); //Make this valid if possible + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); # optional + curl_setopt($ch, CURLOPT_TIMEOUT, -1); # optional: -1 = unlimited, 3600 = 1 hour + curl_setopt($ch, CURLOPT_VERBOSE, false); # Set to true to see all the innards + + // AUTH FORMAT : 'user:password' + if($auth){ + curl_setopt($ch, CURLOPT_USERPWD, "$auth"); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + + // POST DATAS + if($post_datas){ + $post_fields = http_build_query($post_datas); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); + } + + # Only if you need to bypass SSL certificate validation + if($ssl_disable) { + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + } + + # Assign a callback function to the CURL Write-Function + curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'saveRemoteFileHandler'); + + # Assign a callback function to the CURL Download Progression + if($progressCallbackFct!="" && function_exists($progressCallbackFct)) { + curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, $progressCallbackFct); + curl_setopt($ch, CURLOPT_NOPROGRESS, false); + } + else if($progressCallbackFct=="default") { + curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'saveRemoteFileProgression'); + curl_setopt($ch, CURLOPT_NOPROGRESS, false); + } + + # Execute the download - note we DO NOT put the result into a variable! + curl_exec($ch); + + # ERROR ? + if(curl_errno($ch)) return curl_error($ch); + + # HTTP CODE + $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + # Close CURL + curl_close($ch); + + # Close the file pointer + fclose($remoteFileHandler); + + # Return HTTP Code + return (is_int($httpcode) && $httpcode<400); +} + +function saveRemoteFileHandler($cp, $data) { + global $remoteFileHandler; + $len = fwrite($remoteFileHandler, $data); + return $len; +} + +function saveRemoteFileProgression($resource,$download_size, $downloaded, $upload_size, $uploaded) { + if($download_size > 0) echo floor($downloaded / $download_size * 100)."%
"; +} + +function getRemoteFileContent($url, $post_datas = false, $progressCallbackFct="", $auth = false, $ssl_disable=false) { + set_time_limit(0); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FILE, $remoteFileHandler); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"); //Make this valid if possible + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); # optional + curl_setopt($ch, CURLOPT_TIMEOUT, -1); # optional: -1 = unlimited, 3600 = 1 hour + curl_setopt($ch, CURLOPT_VERBOSE, false); # Set to true to see all the innards + curl_setopt($ch, CURLOPT_FAILONERROR, true); + + // AUTH FORMAT : 'user:password' + if($auth){ + curl_setopt($ch, CURLOPT_USERPWD, "$auth"); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + + // POST DATAS + if($post_datas){ + $post_fields = http_build_query($post_datas); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); + } + + # Only if you need to bypass SSL certificate validation + if($ssl_disable) { + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + } + + # Assign a callback function to the CURL Download Progression + if($progressCallbackFct!="" && function_exists($progressCallbackFct)) { + curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, $progressCallbackFct); + curl_setopt($ch, CURLOPT_NOPROGRESS, false); + } + + $ret = array("response" => false, "error" => false, "httpcode" => 0, "success" => false); + + # Execute the download + $ret["response"] = curl_exec($ch); + + # ERROR ? + if(curl_errno($ch)) $ret["error"] = curl_error($ch); + + # HTTP CODE + $ret["httpcode"] = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $ret["success"] = (is_int($ret["httpcode"]) && $ret["httpcode"]<400); + + # Close CURL + curl_close($ch); + + return $ret; +} + +// GENERATION MOT DE PASSE +function makeNewPassword($nb_car, $chaine = 'azertyuiopqsdfghjklmwxcvbn123456789') { + $nb_lettres = strlen($chaine) - 1; + $generation = ''; + for($i=0; $i < $nb_car; $i++) + { + $pos = mt_rand(0, $nb_lettres); + $car = $chaine[$pos]; + $generation .= $car; + } + return $generation; +} + +// ENVOIE EMAIL + +function sendHTMLemail($dest, $subject, $msg, $from=false, $replyTo=false) { + // DESTINATAIRE + if(is_string($dest) && $dest!="") { + $mailTo = $dest; + } + else return "WRONG DEST : "+$dest; + + if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $mailTo)) $br = "\r\n"; + else $br = "\n"; + + // SUBJECT + if($subject=="") return "WRONG SUBJECT"; + + // MESSAGE + if($msg=="") return "WRONG MSG"; + + // FROM & REPLY TO + if(!$from || $from!="") $from = "taeki "; + if(!$replyTo || $replyTo!="") $replyTo = "taeki "; + + //=====Création des headers de l'e-mail + $headers = "From: ".$from.$br; + $headers .= "Reply-to: ".$replyTo.$br; + $headers .= "MIME-Version: 1.0".$br; + $headers .= "Content-type: text/html; charset=utf-8".$br; + $headers .= "Content-Transfer-Encoding: 8bit".$br; + //========== + + // Envoi + return mail($mailTo, $subject, $msg, $headers); +} + +// IMAGE + +function redimg($img_src,$img_dst,$dst_w,$dst_h,$destroy=false,$constant_aspect_ratio=true,$crop=false,$ext=false) { + // EXTENSION + if(!$ext) $ext = getImgExtFromMimeType($img_src); + + // CHARGEMENT IMAGE + $img_orig = loadImage($img_src, $ext); + + if(!$img_orig) return; + + // IMAGE SIZE + $src_w = imagesx($img_orig); + $src_h = imagesy($img_orig); + + // SIMPLE COPIE DU FICHIER SI L'IMAGE D'ORIGINE EST PLUS PETITE QUE L'IMAGE SOUHAITEE + if($src_w<$dst_w && $src_h<$dst_h) saveImage($img_orig, $ext, $img_dst); + else { + $sx = 0; + $sy = 0; + + // CALCUL DE LA TAILLE DE LA NOUVELLE IMAGE + if($constant_aspect_ratio) { + // CROP + if($crop && $dst_w>0 && $dst_h>0 && $src_w>0 && $src_h>0) { + // on calcul les dimensions d'origine en concervant le ratio finale + $test_w = round(($dst_w * $src_h) / $dst_h); + $test_h = round(($dst_h * $src_w) / $dst_w); + + if($test_h < $src_h) { // ON CROP EN HAUT ET EN BAS + $src_dif = $src_h - $test_h; + $sy = round( $src_dif /2 ); + $src_h = $src_h - $src_dif; + } + else { // ON CROP A GAUCHE ET A DROITE + $src_dif = $src_w - $test_w; + $sx = round( $src_dif /2 ); + $src_w = $src_w - $src_dif; + } + } + // REDUIT DEST SIZE + else { + // on calcul les dimensions final en concervant le ratio + $test_h = round(($dst_w / $src_w) * $src_h); + $test_w = round(($dst_h / $src_h) * $src_w); + + // Si Height final non précisé (0) => on réduit la hauteur finale + if(!$dst_h) $dst_h = $test_h; + // Sinon si Width final non précisé (0) => on réduit la largeur finale + elseif(!$dst_w) $dst_w = $test_w; + // Sinon teste quel redimensionnement tient dans la zone + elseif($test_h>$dst_h) $dst_w = $test_w; // => on réduit la largeur finale + else $dst_h = $test_h; // => on réduit la hauteur finale + } + } + + // CREATION DE LA NOUVELLE IMAGE + $img_new = imagecreatetruecolor($dst_w, $dst_h); + + // CONSERVE LA TRANSPARENCE + if(in_array($ext, array("png", "gif", "webp"))) { + $transparency = imagecolortransparent($img_orig); + if($transparency >= 0) { + $transparent_color = imagecolorsforindex($img_orig, $tIdx); + $transparency = imagecolorallocate($img_new, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']); + imagefill($img_new, 0, 0, $transparency); + imagecolortransparent($img_new, $transparency); + } + else if(in_array($ext, array("png", "webp"))) { + imagealphablending($img_new, false); + imagefill($img_new, 0, 0, imagecolorallocatealpha($img_new, 0, 0, 0, 127)); + imagesavealpha($img_new, true); + } + } + + imagecopyresampled($img_new,$img_orig,0,0,$sx,$sy,$dst_w,$dst_h,$src_w,$src_h); // Redimenssionnement et écriture de l'image dans l'image vierge en cache + imagedestroy($img_orig); // Efface image originale + + if($destroy && file_exists($img_src)) unlink($img_src); // Suppression de l'image d'origine + + // SAVE IMAGE + saveImage($img_new, $ext, $img_dst); + if(is_resource($img_new)) imagedestroy($img_new); + } + + if($destroy && file_exists($img_src)) unlink($img_src); // Suppression de l'image d'origine +} + +function loadImage($img_path, $ext=false) { + if(!$ext) { $ext = getImgExtFromMimeType($img_path); } + + $img = false; + switch($ext) { + case "png": $img = imagecreatefrompng($img_path); break; + case "webp": $img = imagecreatefromwebp($img_path); break; + case "bmp": $img = imagecreatefrombmp($img_path); break; + case "gif": $img = imagecreatefromgif($img_path); break; + case "jpg": $img = imagecreatefromjpegexif($img_path); break; + } + + return $img; +} + +function imagecreatefromjpegexif($filename) { + $img = imagecreatefromjpeg($filename); + $exif = exif_read_data($filename); + if ($img && $exif && isset($exif['Orientation'])) + { + $ort = $exif['Orientation']; + + if ($ort == 6 || $ort == 5) + $img = imagerotate($img, 270, null); + if ($ort == 3 || $ort == 4) + $img = imagerotate($img, 180, null); + if ($ort == 8 || $ort == 7) + $img = imagerotate($img, 90, null); + + if ($ort == 5 || $ort == 4 || $ort == 7) + imageflip($img, IMG_FLIP_HORIZONTAL); + } + return $img; +} + +function getImgSize($img_src) { + $size = GetImageSize($img_src); + return array('width' => $size[0], 'height' => $size[1]); +} + +function getImgExtFromMimeType($path) { + $ext = false; + if(file_exists($path)) { + $mt = mime_content_type($path); + switch($mt) { + case "image/png" : + case "image/x-png": + $ext = "png"; + break; + case "image/pjpeg": + case "image/jpeg" : + case "image/jpg" : + $ext = "jpg"; + break; + case "image/gif" : $ext = "gif"; break; + case "image/bmp" : $ext = "bmp"; break; + case "image/svg+xml" : $ext = "svg"; break; + case "image/tiff" : $ext = "tiff"; break; + case "image/webp" : $ext = "webp"; break; + default: $ext = false; + } + } + return $ext; +} + +function getImgMimeTypeFromExt($ext) { + $mt = false; + switch($ext) { + case "png" : $mt = "image/png"; break; + case "jpg" : $mt = "image/jpg"; break; + case "gif" : $mt = "image/gif"; break; + case "bmp" : $mt = "image/bmp"; break; + case "svg" : $mt = "image/svg+xml"; break; + case "tiff" : $mt = "image/tiff"; break; + case "webp" : $mt = "image/webp"; break; + default: $mt = false; + } + return $mt; +} + +function saveImage($img, $ext, $path=false) { + if($path==false) { + $mt = getImgMimeTypeFromExt($ext); + header('Content-Type: '.$mt); + } + else if($path!="" && file_exists($path)) unlink($path); + + if($ext == 'png') imagepng($img,$path,5); + else if($ext == 'gif') imagegif($img,$path); + else if($ext == 'bmp') imagebmp($img,$path,true); + else if($ext == 'webp') imagewebp($img,$path,90); + else imagejpeg($img,$path,90); + + imagedestroy($img); // Efface l'image en cache + + if($path==false) die(); + return file_exists($path); +} + +// MANAGE TABLE DATAS + +function getRequestTableDatas($table_structure, $force_default_values=false) { + $ret = array(); + + foreach($table_structure as $key => $infos) { + switch($infos["type"]) { + + // INTEGER + case "int": + if(isset($_REQUEST[$key])) { + $val = intval($_REQUEST[$key]); + // TEST MIN + if(is_int($infos["min"])) { + if($val < $infos["min"]) $val = (isset($infos["force_default_under_min"]) && $infos["force_default_under_min"] == true) ? $infos["default"] : $infos["min"]; + } + // TEST MAX + if(is_int($infos["max"])) { + if($val > $infos["max"]) $val = (isset($infos["force_default_upper_max"]) && $infos["force_default_upper_max"] == true) ? $infos["default"] : $infos["max"]; + } + $ret[$key] = $val; + } + else if($force_default_values) $ret[$key] = $infos["default"]; + break; + // FLOAT + case "float": + if(isset($_REQUEST[$key])) { + $val = floatval($_REQUEST[$key]); + // TEST MIN + if(is_float($infos["min"])) { + if($val < $infos["min"]) $val = (isset($infos["force_default_under_min"]) && $infos["force_default_under_min"] == true) ? $infos["default"] : $infos["min"]; + } + // TEST MAX + if(is_float($infos["max"])) { + if($val > $infos["max"]) $val = (isset($infos["force_default_upper_max"]) && $infos["force_default_upper_max"] == true) ? $infos["default"] : $infos["max"]; + } + $ret[$key] = $val; + } + else if($force_default_values) $ret[$key] = $infos["default"]; + break; + // BOOL + case "bool": + if(isset($_REQUEST[$key])) { + $ret[$key] = is_bool($_REQUEST[$key]) ? $_REQUEST[$key] : (intval($_REQUEST[$key]) > 0); + } + else if($force_default_values) $ret[$key] = $infos["default"]; + break; + // DATE + case "date": + if(isset($_REQUEST[$key])) $ret[$key] = checkDateFormat($_REQUEST[$key], 'mysql_date', $infos["default"]); + else if($force_default_values) $ret[$key] = $infos["default"]; + break; + // SET + case "set": + if(isset($_REQUEST[$key])) $ret[$key] = in_array($_REQUEST[$key], $infos["values"]) ? strval($_REQUEST[$key]) : $infos["default"]; + else if($force_default_values) $ret[$key] = $infos["default"]; + break; + // TEXT + default: + if(isset($_REQUEST[$key])) { + $val = strval($_REQUEST[$key]); + // TEST LENGTH + if(strlen($val) == 0) $val = $infos["default"]; + else if(isset($infos["length"]) && is_int($infos["length"]) && strlen($val) > $infos["length"]) $val = substr($val, 0, $infos["length"]); + $ret[$key] = $val; + } + else if($force_default_values) $ret[$key] = $infos["default"]; + } + } + + return $ret; +} + +function buildTableDatas($table_structure, $datas, $force_default_values=false) { + $ret = array(); + foreach($table_structure as $key => $infos) { + if(array_key_exists($key, $datas)) { + switch($infos["type"]) { + // INTEGER + case "int": $ret[$key] = is_null($datas[$key]) ? NULL : intval( $datas[$key] ); break; + // FLOAT + case "float": $ret[$key] = is_null($datas[$key]) ? NULL : floatval( $datas[$key] ); break; + // BOOL + case "bool": $ret[$key] = is_null($datas[$key]) ? NULL : ($datas[$key] ? 1 : 0); break; + // DATE + case "date": $ret[$key] = is_null($datas[$key]) ? NULL : $datas[$key]; break; + // SET + case "set": $ret[$key] = is_null($datas[$key]) ? NULL : strval($datas[$key]); break; + // TEXT + default: $ret[$key] = is_null($datas[$key]) ? NULL : strval($datas[$key]); + } + } + else if($force_default_values) $ret[$key] = $infos["default"]; + } + return $ret; +} + +function addDatasInTable($db_manager, $table_name, $table_structure, $datas, $error_str="de l'information") { + $infos = buildTableDatas($table_structure, $datas, true); + + $r = $db_manager->insert($table_name,$infos); + + if($r["result"] && !$r["error"]) return ((int)$r['id']>0) ? $r['id'] : true; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur'])."
insert id: ".getReadableVar($r['id']); + return "ERREUR : Une erreur est survenue durant l'enregistrement ".$error_str." dans la base de données ! ".$er; + } +} + +function updateDatasInTable($db_manager, $table_name, $table_structure, $id, $datas, $null_str="à la fiche", $error_str="de l'information") { + $infos = buildTableDatas($table_structure, $datas, false); + if(count($infos)==0) return "ERREUR : aucune modification à apporter ".$null_str." !"; + + $r = $db_manager->update($table_name,$infos,"WHERE ref=".intVal($id)); + + if($r && !$r['erreur']) return 1; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur']); + return "ERREUR : Une erreur est survenue durant l'enregistrement des modifications ".$error_str." dans la base de données ! ".$er; + } +} + +function updateDatasInTableByCondition($db_manager, $table_name, $table_structure, $condition, $datas, $null_str="à la fiche", $error_str="de l'information") { + $infos = buildTableDatas($table_structure, $datas, false); + if(count($infos)==0) return "ERREUR : aucune modification à apporter ".$null_str." !"; + + $r = $db_manager->update($table_name,$infos,$condition); + + if($r && !$r['erreur']) return 1; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur']); + return "ERREUR : Une erreur est survenue durant l'enregistrement des modifications ".$error_str." dans la base de données ! ".$er; + } +} + +function deleteItemInTable($db_manager, $table_name, $id, $error_str="de l'information") { + $infos = array("del" => 1); + + $r = $db_manager->update($table_name,$infos,"WHERE ref=".intVal($id)); + + if($r && !$r['erreur']) return 1; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur']); + return "ERREUR : Une erreur est survenue durant la suppression ".$error_str." dans la base de données ! ".$er; + } +} + +function deleteItemInTableByCondition($db_manager, $table_name, $condition, $error_str="de l'information") { + $infos = array("del" => 1); + + $r = $db_manager->update($table_name,$infos,$condition); + + if($r && !$r['erreur']) return 1; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur']); + return "ERREUR : Une erreur est survenue durant la suppression ".$error_str." dans la base de données ! ".$er; + } +} + +function eraseItemInTable($db_manager, $table_name, $id, $error_str="de l'information") { + $r = $db_manager->deleteWithCondition($table_name,"WHERE ref=".intVal($id)); + + if($r && !$r['erreur']) return 1; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur']); + return "ERREUR : Une erreur est survenue durant la suppression définitive ".$error_str." dans la base de données ! ".$er; + } +} + +function eraseItemInTableByCondition($db_manager, $table_name, $condition, $error_str="de l'information") { + $r = $db_manager->deleteWithCondition($table_name,$condition); + + if($r && !$r['erreur']) return 1; + else { + $er = "
sql: ".$r['sql']."
result: ".getReadableVar($r['result'])."
error: ".getReadableVar($r['erreur']); + return "ERREUR : Une erreur est survenue durant la suppression définitive ".$error_str." dans la base de données ! ".$er; + } +} + +if(!function_exists("array_key_first")) { + function array_key_first($array) { + reset($array); + return key($array); + } +} + +// PHP OUTPUT CACHE + +function disablePHPoutputCache() { + session_write_close(); + set_time_limit(0); + ini_set('output_buffering', 'off'); // Turn off output buffering + ini_set('zlib.output_compression', false); // Turn off PHP output compression + ini_set('implicit_flush', true); // Implicitly flush the buffer(s) + ob_implicit_flush(true); + ob_end_flush(); + // Clear, and turn off output buffering + while (ob_get_level() > 0) { + $level = ob_get_level(); // Get the curent level + ob_end_clean(); // End the buffering + // If the current level has not changed, abort + if (ob_get_level() == $level) break; + } + // Disable apache output buffering/compression + if (function_exists('apache_setenv')) { + apache_setenv('no-gzip', '1'); + apache_setenv('dont-vary', '1'); + } +} + +function disablePHPoutputBuffering() { + disablePHPoutputCache(); + return; + + session_write_close(); + + ini_set('output_buffering', 0); // Turn off output buffering + ini_set('zlib.output_compression', 0); // Turn off PHP output compression + ini_set('implicit_flush', true); // Implicitly flush the buffer(s) + + // Disable apache output buffering/compression + if (function_exists('apache_setenv')) { + apache_setenv('no-gzip', '1'); + apache_setenv('dont-vary', '1'); + } + + set_time_limit(0); +} + +?> diff --git a/functions/functions_clients.php b/functions/functions_clients.php new file mode 100644 index 0000000..24fdf95 --- /dev/null +++ b/functions/functions_clients.php @@ -0,0 +1,337 @@ + "réf.", + 'nom' => "nom", + 'prenom' => "prénom", + 'tel' => "téléphone", + 'email' => "email" +); + +function getClientsList($order='nom',$sens='ASC',$simple=false,$search=false) { + $list = array(); + + $sql = getClientsTableSelectBaseSQL()." WHERE ".CLIENTS_TABLE.".`del`=0"; + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildClientsListSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= CLIENTS_TABLE.".`ref`"; + else if($order=='nom') $sql .= CLIENTS_TABLE.".`nom`"; + else if($order=='prenom') $sql .= CLIENTS_TABLE.".`prenom`"; + else if($order=='tel') $sql .= CLIENTS_TABLE.".`tel`"; + else if($order=='email') $sql .= CLIENTS_TABLE.".`email`"; + else $sql .= CLIENTS_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + if($simple) $list[$i['ref']] = $i['prenom']." ".$i['nom']; + else $list[$i['ref']] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des clients dans le base de données !".$er; + } + + return $list; +} + +function getClientsAutocompleteList() { + $sql = getClientsTableSelectBaseSQL()." WHERE ".CLIENTS_TABLE.".`del`=0"; + + // get what user typed in autocomplete input + $term = trim($_REQUEST['search']); + + $a_json = array(); + $a_json_row = array(); + $a_json_invalid = array(array("id" => "#", "value" => $term, "label" => "Only letters and digits are permitted...")); + + // replace multiple spaces with one + $term = preg_replace('/\s+/', ' ', $term); + + $parts = explode(' ', $term); + $p = count($parts); + + for($i = 0; $i < $p; $i++) { + $sql .= ' AND ('.CLIENTS_TABLE.'.`nom` LIKE "%'.$parts[$i].'%" OR '.CLIENTS_TABLE.'.`prenom` LIKE "%'.$parts[$i].'%")'; + } + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $c) { + $a_json_row["id"] = $c['ref']; + $a_json_row["ref"] = $c['ref']; + $value = $c['prenom']." ".$c['nom']; + $a_json_row["value"] = $value; + $a_json_row["label"] = $value; + + array_push($a_json, $a_json_row); + } + + // highlight search results + $a_json = apply_highlight($a_json, $parts); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des client !".$er; + } + return $a_json; +} + +// GET DATAS + +function getClientDatas($id) { + $i = array(); + + $sql = getClientsTableSelectBaseSQL()." WHERE ".CLIENTS_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + + // CONTRATS + $i["contrats"] = getClientContrats($id); + + // ABSENCES + $i["absences"] = getClientAbsences($id); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du client dans le base de données !".$er; + } + + return $i; +} + +function getClientContrats($id) { return getContratsList("date","DESC", array("client" => $id)); } +function getClientAbsences($id) { return getClientAbsencesList("fin", "DESC", $id); } + +// ADD / UPDATE DATAS + +function getClientDatasFromRequest() { return getRequestTableDatas(CLIENTS_TABLE_STRUCT); } + +function addClient($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_TABLE, // TABLE NAME + CLIENTS_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du client" // ERROR STRING + ); +} + +function updateClient($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_TABLE, // TABLE NAME + CLIENTS_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au client", // NULL STRING + "du client" // ERROR STRING + ); +} + +function deleteClient($id) { + $datas = array("del" => 1); + return updateClient($id, $datas); +} + +function eraseClient($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_TABLE, // TABLE NAME + $id, // ID + "du client" // ERROR STRING + ); +} + +//////////////////////////////////////////////////////////////////////// +// CLIENTS - ABSENCES ////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +$allowClientsAbsencesListOrder = array( + 'ref' => "réf.", + 'nom' => "nom", + 'prenom' => "prénom", + 'debut' => "début", + 'fin' => "fin (incluse)" +); + +function getClientAbsencesList($order='id',$sens='ASC',$client=0, $search=false) { + $list = array(); + + $sql = getClientsAbsencesTableSelectBaseSQL()." WHERE ".CLIENTS_ABSENCES_TABLE.".`del`=0"; + + if($client>0) $sql .= " AND ".CLIENTS_ABSENCES_TABLE.".`client`=".intval($client); + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildClientsAbsencesListSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= CLIENTS_ABSENCES_TABLE.".`ref`"; + else if($order=='nom') $sql .= CLIENTS_TABLE.".`nom`"; + else if($order=='prenom') $sql .= CLIENTS_TABLE.".`prenom`"; + else if($order=='debut') $sql .= CLIENTS_ABSENCES_TABLE.".`debut`"; + else if($order=='fin') $sql .= CLIENTS_ABSENCES_TABLE.".`fin`"; + else $sql .= CLIENTS_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i["debut_print"] = formatDate($i["debut"], "mysql_date", "date"); + $i["fin_print"] = formatDate($i["fin"], "mysql_date", "date"); + $i["periode"] = formatPeriode($i["debut"], $i["fin"], "mysql_date"); + $list[$i["ref"]] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des absences clients dans le base de données !".$er; + } + + return $list; +} + +// GET DATAS + +function getClientAbsenceDatas($id) { + $i = array(); + + $sql = getClientsAbsencesTableSelectBaseSQL()." WHERE ".CLIENTS_ABSENCES_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + $i["debut_print"] = formatDate($i["debut"], "mysql_date", "date"); + $i["fin_print"] = formatDate($i["fin"], "mysql_date", "date"); + $i["periode"] = formatPeriode($i["debut"], $i["fin"], "mysql_date"); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations de l'absences client dans le base de données !".$er; + } + + return $i; +} + +function getClientAbsenceAtDate($client, $date) { + $date_checked = checkDateFormat($date, 'mysql_date', NULL); + if(is_null($date_checked)) { + $GLOBALS['errors'][] = "Aucune date transmis !"; + return false; + } + + $abs = false; + + $sql = getClientsAbsencesTableSelectBaseSQL() + ." WHERE ".CLIENTS_ABSENCES_TABLE.".`client`=".intval($client) + ." AND ".CLIENTS_ABSENCES_TABLE.".`debut`<='".$date_checked."'" + ." AND ".CLIENTS_ABSENCES_TABLE.".`fin`>='".$date_checked."'" + ." ORDER BY ".CLIENTS_ABSENCES_TABLE.".`fin` DESC LIMIT 0,1"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + if(count($r['datas'])>0) { + $abs = $r['datas'][0]; + $abs["debut_print"] = formatDate($abs["debut"], "mysql_date", "date"); + $abs["fin_print"] = formatDate($abs["fin"], "mysql_date", "date"); + $abs["periode"] = formatPeriode($abs["debut"], $abs["fin"], "mysql_date"); + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant l'interogation date dans le base de données sur une éventuelle absence client !".$er; + } + + return $abs; +} + +// ADD / UPDATE DATAS + +function getClientAbsenceDatasFromRequest() { return getRequestTableDatas(CLIENTS_ABSENCES_TABLE_STRUCT); } + +function addClientAbsence($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_ABSENCES_TABLE, // TABLE NAME + CLIENTS_ABSENCES_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "de l'absence client" // ERROR STRING + ); +} + +function updateClientAbsence($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_ABSENCES_TABLE, // TABLE NAME + CLIENTS_ABSENCES_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "à l'absence client", // NULL STRING + "de l'absence client" // ERROR STRING + ); +} + +function deleteClientAbsence($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_ABSENCES_TABLE, // TABLE NAME + $id, // ID + "de l'absence client" // ERROR STRING + ); +} + +function eraseClientAbsence($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CLIENTS_ABSENCES_TABLE, // TABLE NAME + $id, // ID + "de l'absence client" // ERROR STRING + ); +} diff --git a/functions/functions_contrats.php b/functions/functions_contrats.php new file mode 100644 index 0000000..f0057ba --- /dev/null +++ b/functions/functions_contrats.php @@ -0,0 +1,259 @@ + "réf.", + 'groupe' => "groupe", + 'type' => 'type de contrat', + 'nom' => "nom", + 'prenom' => "prénom", + 'date' => "début de contrat", + 'frequence' => "fréquence", + 'panier_type' => "type de panier", + 'nb_paniers_livre' => "nb. de paniers livrés", + 'nb_paniers_restant' => "nb. de paniers restant", + 'lieu_depot' => "lieu de dépôt" +); + +function getContratsList($order='id',$sens='ASC', $filtres=array(), $search=false) { + // ARCHIVES OLD CONTRATS + archiveOldContrat(); + + // LIST + $list = array(); + + $sql = getContratsTableSelectBaseSQL()." WHERE ".CONTRATS_TABLE.".`del`=0"; + + // FILTRES + if(array_key_exists('client', $filtres) && (int)$filtres['client']>0) $sql.=" AND ".CONTRATS_TABLE.".`client`=".intval($filtres['client']); + if(array_key_exists('groupe', $filtres) && (int)$filtres['groupe']>0) $sql.=" AND ".CONTRATS_TABLE.".`groupe`=".intval($filtres['groupe']); + if(array_key_exists('frequence', $filtres) && $filtres['frequence']!="") { + switch($filtres['frequence']) { + case 'hebdo' : $sql.=" AND ".CONTRATS_TABLE.".`frequence`='hebdo'"; break; + case 'quinz' : $sql.=" AND ".CONTRATS_TABLE.".`frequence`='quinz'"; break; + case 'quinz_A' : $sql.=" AND ".CONTRATS_TABLE.".`frequence`='quinz' AND ".CONTRATS_TABLE.".`quinz_groupe`='A'"; break; + case 'quinz_B' : $sql.=" AND ".CONTRATS_TABLE.".`frequence`='quinz' AND ".CONTRATS_TABLE.".`quinz_groupe`='B'"; break; + } + } + if(array_key_exists('panier', $filtres) && (int)$filtres['panier']>0) $sql.=" AND ".CONTRATS_TABLE.".`panier_type`=".intval($filtres['panier']); + if(array_key_exists('lieu', $filtres) && (int)$filtres['lieu']>0) $sql.=" AND ".CONTRATS_TABLE.".`lieu_depot`=".intval($filtres['lieu']); + if(array_key_exists('archive', $filtres) && (int)$filtres['archive']>=0) $sql.=" AND ".CONTRATS_TABLE.".`archive`=".intval($filtres['archive']); + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildContratsListSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= CONTRATS_TABLE.".`ref`"; + else if($order=='groupe') $sql .= CONTRATS_TABLE.".`groupe`"; + else if($order=='type') $sql .= CONTRATS_TYPES_TABLE.".`nom`"; + else if($order=='nom') $sql .= CLIENTS_TABLE.".`nom`"; + else if($order=='prenom') $sql .= CLIENTS_TABLE.".`prenom`"; + else if($order=='date') $sql .= CONTRATS_TABLE.".`date`"; + else if($order=='frequence') $sql .= CONTRATS_TABLE.".`frequence`"; + else if($order=='panier_type') $sql .= PANIERS_TYPES_TABLE.".`nom`"; + else if($order=='nb_paniers_livre') $sql .= CONTRATS_PANIERS_STATUT.".`nb_paniers_livres`"; + else if($order=='nb_paniers_restant') $sql .= CONTRATS_PANIERS_STATUT.".`nb_paniers_restants`"; + else if($order=='lieu_depot') $sql .= LIEUX_TABLE.".`nom`"; + else $sql .= CLIENTS_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + if(!$i["type_ref"]>0) $i["type_nom"] = "personnalisé (".$i["groupe_nom"]." - ".$i["nb_paniers"]." x ".$i["panier_type_nom"]." - ".CONTRATS_FREQUENCES[$i["frequence"]].")"; + + $i["date_print"] = formatDate($i["date"], "mysql_date", "date"); + + $i["frequence_print"] = CONTRATS_FREQUENCES[$i["frequence"]]; + if($i["frequence"] == "quinz") $i["frequence_print"] .= " (groupe ".$i["quinz_groupe"].')'; + + $i["warning_nb_paniers"] = ($i["frequence"]=="hebdo" && $i["nb_paniers_restants"]<=WARNING_NB_PANIERS_HEBDO) + || ($i["frequence"]=="quinz" && $i["nb_paniers_restants"]<=WARNING_NB_PANIERS_QUINZE); + + $list[$i['ref']] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des contrats dans le base de données !".$er; + } + + return $list; +} + +// GET DATAS + +function getContratDatas($id) { + $i = array(); + + $sql = getContratsTableSelectBaseSQL()." WHERE ".CONTRATS_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + + if(!$i["type_ref"]>0) $i["type_nom"] = "personnalisé (".$i["groupe_nom"]." - ".$i["nb_paniers"]." x ".$i["panier_type_nom"]." - ".CONTRATS_FREQUENCES[$i["frequence"]].")"; + + $i["date_print"] = formatDate($i["date"], "mysql_date", "date"); + + $i["frequence_print"] = CONTRATS_FREQUENCES[$i["frequence"]]; + if($i["frequence"] == "quinz") $i["frequence_print"] .= " (groupe ".$i["quinz_groupe"].')'; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du contrat dans le base de données !".$er; + } + + return $i; +} + +function getContratLastPanier($id) { + $i = false; + + $sql = getLivraisonsPaniersSelectBaseSQL()." WHERE ".CONTRATS_TABLE.".`ref`=$id ORDER BY ".LIVRAISONS_TABLE.".`date` ASC LIMIT 0,1"; + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + if(count($r['datas'])>0) { + $i = $r['datas'][0]; + + $i["livraison_date_print"] = formatDate($i["livraison_date"], "mysql_date", "date"); + + $i["frequence_print"] = CONTRATS_FREQUENCES[$i["frequence"]]; + if($i["frequence"] == "quinz") $i["frequence_print"] .= " (groupe ".$i["quinz_groupe"].')'; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du contrat dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getContratDatasFromRequest() { return getRequestTableDatas(CONTRATS_TABLE_STRUCT); } + +function addContrat($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TABLE, // TABLE NAME + CONTRATS_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du contrat" // ERROR STRING + ); +} + +function updateContrat($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TABLE, // TABLE NAME + CONTRATS_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au contrat", // NULL STRING + "du contrat" // ERROR STRING + ); +} + +function archiveContrat($id, $state) { + $datas = array( + "archive" => ($state == true) ? 1 : 0, + "force_not_archive" => ($state == true) ? 0 : 1, + ); + $r = updateContrat($id, $datas); + if(!(int)$r>0) { + $er = "ERREUR : une erreur est survenue "; + $er.= ($state == true) ? "à l'archivage" : "au désarchivage"; + $er = " du contrat ! ($r)"; + return $er; + } + return 1; +} + +function archiveOldContrat() { + $refs = "0"; + + $sql = "SELECT ".CONTRATS_TABLE.".`ref` FROM ".CONTRATS_TABLE + ." LEFT JOIN ".CONTRATS_PANIERS_STATUT." ON ".CONTRATS_TABLE.".`ref`=".CONTRATS_PANIERS_STATUT.".`ref`" + ." WHERE ".CONTRATS_PANIERS_STATUT.".`nb_paniers_restants`<=0" + ." AND ".CONTRATS_TABLE.".`force_eligible`=0" + ." AND ".CONTRATS_TABLE.".`archive`=0"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + if(count($r['datas']>0)) { + $date = new DateTime(DATE_TIME_ZONE); + $dateInt = new DateInterval( "P".AUTO_ARCHIVE_OLD_CONTRATS_DELAY."D" ); + $date->sub( $dateInt ); + + foreach($r['datas'] as $i) { + $lastPanier = getContratLastPanier($i['ref']); + if($lastPanier) { + $lastDate = DateTime::createFromFormat("Y-m-d", $lastPanier["livraison_date"], new DateTimeZone(DATE_TIME_ZONE)); + if($lastDate < $date) $refs .= ",".$i['ref']; + } + } + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des contrats expirés dans le base de données !".$er; + return; + } + + if($refs != "0") { + $r = updateDatasInTableByCondition( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TABLE, // TABLE NAME + CONTRATS_TABLE_STRUCT, // TABLE STRUCTURE + "WHERE ref IN ($refs)", // CONDITION + array("archive" => 1), // DATAS + "au contrat", // NULL STRING + "du contrat" // ERROR STRING + ); + if(!$r>0) $GLOBALS['errors'][] = "ERREUR : une erreur est survenue durant l'archivage automatique des anciens contrats...
($r)"; +// else addDebug($refs, "ARCHIVE OLD CONTRATS DONE !"); + } +} + +function deleteContrat($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TABLE, // TABLE NAME + $id, // ID + "du contrat" // ERROR STRING + ); +} + +function eraseContrat($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TABLE, // TABLE NAME + $id, // ID + "du contrat" // ERROR STRING + ); +} diff --git a/functions/functions_contrats_types.php b/functions/functions_contrats_types.php new file mode 100644 index 0000000..11dccfb --- /dev/null +++ b/functions/functions_contrats_types.php @@ -0,0 +1,115 @@ + "réf.", + 'groupe' => "groupe", + 'nom' => "nom", + 'frequence' => "fréquence", + 'panier_type' => "type de panier", + 'nb_panier' => 'nb. de panier', + 'prix_total' => 'prix total' +); + +function getContratsTypesList($order='id',$sens='ASC', $search=false) { + $list = array(); + + $sql = getContratsTypesTableSelectBaseSQL()." WHERE ".CONTRATS_TYPES_TABLE.".`del`=0"; + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= CONTRATS_TYPES_TABLE.".`ref`"; + else if($order=='groupe') $sql .= PANIERS_GROUPES_TABLE.".`nom`"; + else if($order=='nom') $sql .= CONTRATS_TYPES_TABLE.".`nom`"; + else if($order=='frequence') $sql .= CONTRATS_TYPES_TABLE.".`frequence`"; + else if($order=='panier_type') $sql .= PANIER_TYPES_TABLE.".`nom`"; + else if($order=='nb_panier') $sql .= CONTRATS_TYPES_TABLE.".`nb_panier`"; + else if($order=='prix_total') $sql .= CONTRATS_TYPES_TABLE.".`prix_total`"; + else $sql .= CONTRATS_TYPES_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) $list[$i['ref']] = $i; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des types de contrats dans le base de données !".$er; + } + + return $list; +} + +// GET DATAS + +function getContratsTypeDatas($id) { + $i = array(); + + $sql = getContratsTypesTableSelectBaseSQL()." WHERE ".CONTRATS_TYPES_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du type de contrats dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getContratsTypeDatasFromRequest() { return getRequestTableDatas(CONTRATS_TYPES_TABLE_STRUCT); } + +function addContratsType($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TYPES_TABLE, // TABLE NAME + CONTRATS_TYPES_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du type de contrat" // ERROR STRING + ); +} + +function updateContratsType($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TYPES_TABLE, // TABLE NAME + CONTRATS_TYPES_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au type de contrat", // NULL STRING + "du type de contrat" // ERROR STRING + ); +} + +function deleteContratsType($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TYPES_TABLE, // TABLE NAME + $id, // ID + "du type de contrat" // ERROR STRING + ); +} + +function eraseContratsType($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + CONTRATS_TYPES_TABLE, // TABLE NAME + $id, // ID + "du type de contrat" // ERROR STRING + ); +} \ No newline at end of file diff --git a/functions/functions_generals.php b/functions/functions_generals.php new file mode 100644 index 0000000..6137043 --- /dev/null +++ b/functions/functions_generals.php @@ -0,0 +1,141 @@ + assign(strval($smartyName),$val); + + return $val; +} + +function convertValTo($val, $type) { + switch(type) { + case "int": $val = intval($val); break; + case "float": $val = floatval($val); break; + case "bool": $val = ($val || (int)$val==1); break; + case "string": $val = strval($val); break; + } + return $val; +} + +function getSessionListFiltre($filtre, $list, $default=0, $intVal=true) { + $val = $default; + + if(isset($_SESSION[$filtre])) { + // INT VAL + if($intVal) { + if((int)$_SESSION[$filtre]>0 && array_key_exists($_SESSION[$filtre],$list)) $val = intval($_SESSION[$filtre]); + else if((int)$_SESSION[$filtre] == $default) $val = $default; + } + // TEXT VAL + else { + if(array_key_exists($_SESSION[$filtre],$list)) $val = $_SESSION[$filtre]; + else if($_SESSION[$filtre] == $default) $val = $default; + } + } + + return $val; +} + +function getListFiltre($filtre, $list, $default=0, $intVal=true) { + // SESSION VAL + $val = getSessionListFiltre($filtre, $list, $default, $intVal); + + // REQUEST VAL + if(isset($_REQUEST[$filtre])) { + // INT VAL + if($intVal) { + if((int)$_REQUEST[$filtre]>0 && array_key_exists($_REQUEST[$filtre],$list)) $val = intval($_REQUEST[$filtre]); + else if((int)$_REQUEST[$filtre] == $default) $val = $default; + } + // TEXT VAL + else { + if(array_key_exists($_REQUEST[$filtre],$list)) $val = $_REQUEST[$filtre]; + else if($_REQUEST[$filtre] == $default) $val = $default; + } + } + + // ASSIGN & SAVE + $_SESSION[$filtre] = $val; + $GLOBALS['smarty'] -> assign($filtre, $val); + + return $val; +} + +// SEARCH + +function getSearch($session_search) { + $search = false; + + // SESSION VAL + if(isset($_SESSION[$session_search])) $search = $_SESSION[$session_search]; + + // REQUEST VAL + if(isset($_REQUEST["search"]) && $_REQUEST["search"]!="") $search = $_REQUEST["search"]; + + // CLEAR VAL + if(isset($_REQUEST["clearSearch"])) $search = false; + + // ASSIGN & SAVE + $_SESSION[$session_search] = $search; + $GLOBALS['smarty'] -> assign("search", $search); + + return $search; +} + +// ORDER + +function getListOrder($session_order_var, $session_sens_var, $allowOrder, $defaultOrder = 'ref', $defaultSens = "ASC") { + /*** ORDER ***/ + $order = $defaultOrder; + + // SESSION VAL + if(isset($_SESSION[$session_order_var]) && array_key_exists($_SESSION[$session_order_var],$allowOrder)) $order = $_SESSION[$session_order_var]; + + // REQUEST VAL + if(isset($_REQUEST['order']) && array_key_exists($_REQUEST['order'],$allowOrder)) $order = $_REQUEST['order']; + + // SAVE & ASSIGN VAL + $_SESSION[$session_order_var] = $order; + $GLOBALS['smarty'] -> assign('order',$order); + $GLOBALS['smarty'] -> assign('allowOrder',$allowOrder); + + /*** SENS ***/ + $sens = $defaultSens; + + // SESSION VAL + if(isset($_SESSION[$session_sens_var]) && ($_SESSION[$session_sens_var]=='ASC' || $_SESSION[$session_sens_var]=='DESC')) $sens = $_SESSION[$session_sens_var]; + + // REQUEST VAL + if(isset($_REQUEST['sens']) && ($_REQUEST['sens']=='ASC' || $_REQUEST['sens']=='DESC')) $sens = $_REQUEST['sens']; + + // SAVE & ASSIGN VAL + $_SESSION[$session_sens_var] = $sens; + $GLOBALS['smarty'] -> assign('sens',$sens); + + return array("order" => $order, "sens" => $sens); +} \ No newline at end of file diff --git a/functions/functions_legumes.php b/functions/functions_legumes.php new file mode 100644 index 0000000..cb4b2de --- /dev/null +++ b/functions/functions_legumes.php @@ -0,0 +1,241 @@ + "réf.", + 'nom' => "nom", + 'tarif' => "tarif", + 'date' => "date" +); + +function getLegumesList($order='nom',$sens='ASC', $search=false) { + $list = array(); + + $sql = getLegumesTableSelectBaseSQL()." WHERE ".LEGUMES_TABLE.".`del`=0"; + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildLegumesListSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= LEGUMES_TABLE.".`ref`"; + else if($order=='nom') $sql .= LEGUMES_TABLE.".`nom`"; + else if($order=='tarif') $sql .= LEGUMES_TARIFS_TABLE.".`prix`"; + else if($order=='date') $sql .= LEGUMES_TARIFS_TABLE.".`date`"; + else $sql .= LEGUMES_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i["tarif_print"] = $i["tarif_prix"]." €/".$i["tarif_unite"]; + $i["tarif_date_print"] = formatDate($i["tarif_date"], "mysql_date", "print_date"); + + $list[$i['ref']] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des légumes dans le base de données !".$er; + } + + return $list; +} + +function getLegumesAutocompleteList() { + $list = array(); + + $term = trim($_REQUEST['search']); // get user autocomplete input + $term = preg_replace('/\s+/', ' ', $term); // replace multiple spaces by one + $parts = explode(' ', $term); + + $sql = getLegumesTableSelectBaseSQL()." WHERE ".LEGUMES_TABLE.".`del`=0"; + foreach($parts as $p) $sql .= " AND (".buildLegumesListSearchSQL($p).")"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $l) { + $row = array( + "id" => $l['ref'], + "value" => $l['nom'], + "label" => $l['nom'], + + "ref" => $l['ref'], + "tarif_ref" => $l['tarif_ref'], + "tarif_prix" => $l['tarif_prix'], + "tarif_unite" => $l['tarif_unite'] + ); + array_push($list, $row); + } + + $a_json = apply_highlight($list, $parts); // highlight search parts + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des légumes !".$er; + } + return $list; +} + +// GET DATAS + +function getLegumeDatas($id) { + $i = array(); + + $sql = getLegumesTableSelectBaseSQL()." WHERE ".LEGUMES_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + + $i["tarif_print"] = $i["tarif_prix"]." €/".$i["tarif_unite"]; + $i["tarif_date_print"] = formatDate($i["tarif_date"], "mysql_date", "print_date"); + + $i["historique_tarif"] = getLegumeTarifHistorique($id, $i["tarif_ref"]); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du légume dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getLegumeDatasFromRequest() { + $datas = getRequestTableDatas(LEGUMES_TABLE_STRUCT); + + // NEW TARIF + if(isset($_REQUEST["tarif_ref"]) && $_REQUEST["tarif_ref"] == "new" && isset($_REQUEST["tarif_prix"]) && isset($_REQUEST["tarif_unite"])) { + $date = formatDate('', 'mysql_date'); + if(isset($_REQUEST["tarif_date"])) $date = checkDateFormat($_REQUEST["tarif_date"], 'mysql_date', "now"); + $datas["new_tarif"] = array( + "prix" => floatval($_REQUEST["tarif_prix"]), + "unite" => in_array($_REQUEST["tarif_unite"], LEGUMES_TARIFS_UNITES) ? $_REQUEST["tarif_unite"] : "kg", + "date" => $date + ); + } + + return $datas; +} + +function addLegume($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LEGUMES_TABLE, // TABLE NAME + LEGUMES_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du légume" // ERROR STRING + ); +} + +function updateLegume($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LEGUMES_TABLE, // TABLE NAME + LEGUMES_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au légume", // NULL STRING + "du légume" // ERROR STRING + ); +} + +function deleteLegume($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LEGUMES_TABLE, // TABLE NAME + $id, // ID + "du légume" // ERROR STRING + ); +} + +function eraseLegume($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LEGUMES_TABLE, // TABLE NAME + $id, // ID + "du légume" // ERROR STRING + ); +} + +//////////////////////////////////////////////////////////////////////// +// LEGUMES - TARIFS //////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +function addLegumeTarif($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LEGUMES_TARIFS_TABLE, // TABLE NAME + LEGUMES_TARIFS_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du tarif" // ERROR STRING + ); +} + +function deleteLegumeTarif($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LEGUMES_TARIFS_TABLE, // TABLE NAME + $id, // ID + "du tarif" // ERROR STRING + ); +} + +function getLegumeTarifHistorique($id, $current = 0) { + $list = array(); + + $sql = getLegumesTarifsTableSelectBaseSQL() + ." WHERE ".LEGUMES_TARIFS_TABLE.".legume=".intval($id) + ." AND ".LEGUMES_TARIFS_TABLE.".del=0"; + + // ORDRE + $sql.=" ORDER BY ".LEGUMES_TARIFS_TABLE.".date DESC"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + $last_date = ""; + foreach($r['datas'] as $i) { + $i["tarif_print"] = $i["tarif_prix"]." €/".$i["tarif_unite"]; + $i["tarif_date_print"] = formatDate($i["tarif_date"], "mysql_date", "print_date"); + $i["tarif_end_date"] = ($last_date!="") ? $last_date : NULL; + $i["tarif_end_date_print"] = ($last_date!="") ? formatDate($last_date, "mysql_date", "print_date") : NULL; + + $i["tarif_periode"] = (is_null($i["tarif_end_date"]) ? "depuis le " : "du ").$i["tarif_date_print"]; + if(!is_null($i["tarif_end_date"])) $id["tarif_periode"] .= " au ".$i["tarif_end_date_print"]; + + if($i['ref'] != $current) $list[] = $i; + + $last_date = $i["tarif_date"]; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de l'historique de tarif du légume dans le base de données !".$er; + } + + return $list; +} \ No newline at end of file diff --git a/functions/functions_lieux.php b/functions/functions_lieux.php new file mode 100644 index 0000000..5923ff2 --- /dev/null +++ b/functions/functions_lieux.php @@ -0,0 +1,115 @@ + "réf.", + 'nom' => "nom" +); + +function getLieuxList($order='id',$sens='ASC', $search=false) { + $list = array(); + + $sql = getLieuxTableSelectBaseSQL()." WHERE ".LIEUX_TABLE.".`del`=0"; + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildLieuxSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= LIEUX_TABLE.".`ref`"; + else if($order=='nom') $sql .= LIEUX_TABLE.".`nom`"; + else $sql .= LIEUX_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) $list[$i['ref']] = $i; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des lieux de dépôt dans le base de données !".$er; + } + + return $list; +} + +// GET DATAS + +function getLieuDatas($id) { + $i = array(); + + $sql = getLieuxTableSelectBaseSQL()." WHERE ".LIEUX_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) $i = $r['datas']; + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du lieu de dépôt dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getLieuDatasFromRequest() { return getRequestTableDatas(LIEUX_TABLE_STRUCT); } + +function addLieu($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIEUX_TABLE, // TABLE NAME + LIEUX_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du lieu de dépôt" // ERROR STRING + ); +} + +function updateLieu($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIEUX_TABLE, // TABLE NAME + LIEUX_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au lieu de dépôt", // NULL STRING + "du lieu de dépôt" // ERROR STRING + ); +} + +function deleteLieu($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIEUX_TABLE, // TABLE NAME + $id, // ID + "du lieu de dépôt" // ERROR STRING + ); +} + +function eraseLieu($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIEUX_TABLE, // TABLE NAME + $id, // ID + "du lieu de dépôt" // ERROR STRING + ); +} \ No newline at end of file diff --git a/functions/functions_livraisons.php b/functions/functions_livraisons.php new file mode 100644 index 0000000..66e53d2 --- /dev/null +++ b/functions/functions_livraisons.php @@ -0,0 +1,578 @@ + "réf.", + 'paniers_groupe' => "groupe de paniers", + 'date' => "date", + 'quinz_groupe' => "groupe quinzaine", + 'nb_paniers' => "nb. de paniers" +); + +function getLivraisonsList($order='id',$sens='ASC', $groupe=0, $archive=0) { + // ARCHIVES OLD LIVRAISONS + archiveOldLivraison(); + + // LIST + $list = array(); + + $sql = getLivraisonsTableSelectBaseSQL()." WHERE ".LIVRAISONS_TABLE.".`del`=0"; + + if((int)$groupe>0) $sql.=" AND ".LIVRAISONS_TABLE.".`paniers_groupe`=".intval($groupe); + + if((int)$archive>=0) $sql.=" AND ".LIVRAISONS_TABLE.".`archive`=".intval($archive); + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= LIVRAISONS_TABLE.".`ref`"; + else if($order=='paniers_groupe') $sql .= LIVRAISONS_TABLE.".`paniers_groupe`"; + else if($order=='date') $sql .= LIVRAISONS_TABLE.".`date`"; + else if($order=='quinz_groupe') $sql .= LIVRAISONS_TABLE.".`quinz_groupe`"; + else if($order=='nb_paniers') $sql .= LIVRAISONS_NB_PANIERS_VIEW.".`nb_paniers`"; + else $sql .= LIVRAISONS_TABLE.".`date`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i["date_print"] = formatDate($i["date"], "mysql_date", "date"); + + $i["nb_paniers"] = intval($i["nb_paniers"]); + + $list[$i['ref']] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des livraisons dans le base de données !".$er; + } + + return $list; +} + +function getLivraisonLastQuinzGroupeAtDate($groupe, $date) { + $grp = NULL; + + $sql = "SELECT ".LIVRAISONS_TABLE.".`quinz_groupe` FROM ".LIVRAISONS_TABLE + ." WHERE ".LIVRAISONS_TABLE.".del=0" + ." AND ".LIVRAISONS_TABLE.".paniers_groupe=".intval($groupe) + ." AND ".LIVRAISONS_TABLE.".date<='".$date."'" + ." ORDER BY ".LIVRAISONS_TABLE.".date DESC LIMIT 0,1"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + if(count($r['datas'])>0) $grp = $r['datas'][0]["quinz_groupe"]; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération du groupe de la dernière livraison dans le base de données !".$er; + } + + return $grp; +} + +// GET DATAS + +function getLivraisonDatas($id) { + $i = array(); + + $sql = getLivraisonsTableSelectBaseSQL()." WHERE ".LIVRAISONS_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + + $i["date_print"] = formatDate($i["date"], "mysql_date", "date"); + $i["date_long_print"] = formatDate($i["date"], "mysql_date", "print_date_with_day"); + + $i["nb_paniers"] = intval($i["nb_paniers"]); + + $i["lieux"] = getLivraisonLieux($id); + $i["paniers"] = getLivraisonPaniers($id); + $i["paniers_contrats"] = getLivraisonPaniersContratsList($id); + $i["nb_paniers"] = getLivraisonNbPaniers($id); + $i["legumes"] = getLivraisonLegumes($id, $i["nb_paniers"]); + $i["total_legumes"] = calcLivraisonTotalLegumes($i["legumes"]); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations de la livraison dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getLivraisonDatasFromRequest() { + $datas = getRequestTableDatas(LIVRAISONS_TABLE_STRUCT); + + // PANIERS + $datas['paniers'] = array(); + if(isset($_REQUEST['paniers'])) $datas['paniers'] = json_decode($_REQUEST['paniers'], true); + + // PANIERS COMPO + $datas['paniers_compo'] = array(); + if(isset($_REQUEST['paniersCompo'])) $datas['paniers_compo'] = json_decode($_REQUEST['paniersCompo'], true); + + return $datas; +} + +function addLivraison($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_TABLE, // TABLE NAME + LIVRAISONS_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "de la livraison" // ERROR STRING + ); +} + +function updateLivraison($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_TABLE, // TABLE NAME + LIVRAISONS_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "à la livraison", // NULL STRING + "de la livraison" // ERROR STRING + ); +} + +function archiveLivraison($id, $state) { + $datas = array( + "archive" => ($state == true) ? 1 : 0, + "force_not_archive" => ($state == true) ? 0 : 1, + ); + $r = updateLivraison($id, $datas); + if(!(int)$r>0) { + $er = "ERREUR : une erreur est survenue "; + $er.= ($state == true) ? "à l'archivage" : "au désarchivage"; + $er = " de la livraison ! ($r)"; + return $er; + } + return 1; +} + +function archiveOldLivraison() { + $date = new DateTime(DATE_TIME_ZONE); + $dateInt = new DateInterval( "P".AUTO_ARCHIVE_OLD_LIVRAISONS_DELAY."D" ); + $date->sub( $dateInt ); + $condition = "WHERE date < '".$date->format("Y-m-d")."' AND force_not_archive=0"; + + $r = updateDatasInTableByCondition( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_TABLE, // TABLE NAME + LIVRAISONS_TABLE_STRUCT, // TABLE STRUCTURE + $condition, // CONDITION + array("archive" => 1), // DATAS + "aux livraisons", // NULL STRING + "des livraisons" // ERROR STRING + ); + + if(!$r>0) $GLOBALS['errors'][] = "ERREUR : une erreur est survenue durant l'archivage automatique des anciennes livraisons...
($r)"; +// else addDebug("ARCHIVE OLD LIVRAISONS DONE !"); +} + +function deleteLivraison($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_TABLE, // TABLE NAME + $id, // ID + "de la livraison" // ERROR STRING + ); +} + +function eraseLivraison($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_TABLE, // TABLE NAME + $id, // ID + "de la livraison" // ERROR STRING + ); +} + +//////////////////////////////////////////////////////////////////////// +// LIVRAISONS - LIEUX ////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +function getLivraisonLieux($livraison) { + $list = array(); + + $sql = "SELECT " + .CONTRATS_TABLE.".`lieu_depot` as 'ref'," + .LIEUX_TABLE.".`nom` as 'nom'," + ."count(*) as 'nb_paniers'" + ." FROM ".LIVRAISONS_PANIERS_TABLE + ." LEFT JOIN ".CONTRATS_TABLE." ON ".LIVRAISONS_PANIERS_TABLE.".`contrat`=".CONTRATS_TABLE.".`ref`" + ." LEFT JOIN ".LIEUX_TABLE." ON ".CONTRATS_TABLE.".`lieu_depot`=".LIEUX_TABLE.".`ref`" + ." WHERE ".LIVRAISONS_PANIERS_TABLE.".`livraison`=".intval($livraison) + ." GROUP BY ".CONTRATS_TABLE.".`lieu_depot`"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i['ref'] = intval($i['ref']); + $i['nb_paniers'] = intval($i['nb_paniers']); + $i['paniers'] = getLivraisonPaniers($livraison, $i['ref']); + $list[$i['ref']] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des lieux de livraison dans le base de données !".$er; + } + + return $list; +} + +//////////////////////////////////////////////////////////////////////// +// LIVRAISONS - PANIERS //////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +function getLivraisonPaniersEligibles($paniers_groupe, $date, $quinz_groupe) { + $list = array(); + + $sql = "SELECT " + .CONTRATS_TABLE.".`ref` as 'contrat_ref'," + .CONTRATS_TABLE.".`client` as 'client_ref'," + .CLIENTS_TABLE.".`nom` as 'client_nom'," + .CLIENTS_TABLE.".`prenom` as 'client_prenom'," + .CONTRATS_TABLE.".`panier_type` as 'panier_type_ref'," + .PANIERS_TYPES_TABLE.".`nom` as 'panier_type_nom'," + .CONTRATS_TABLE.".`frequence`," + .CONTRATS_TABLE.".`quinz_groupe`," + .CONTRATS_TABLE.".`nb_paniers`," + .CONTRATS_TABLE.".`lieu_depot` as 'lieu_depot_ref'," + .LIEUX_TABLE.".`nom` as 'lieu_depot_nom'," + .CONTRATS_TABLE.".`np_paniers_distrib_avt_saisie`," + .CONTRATS_TABLE.".`force_eligible`" + ." FROM ".CONTRATS_TABLE + ." LEFT JOIN ".CLIENTS_TABLE." ON ".CONTRATS_TABLE.".`client`=".CLIENTS_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_TYPES_TABLE." ON ".CONTRATS_TABLE.".`panier_type`=".PANIERS_TYPES_TABLE.".`ref`" + ." LEFT JOIN ".LIEUX_TABLE." ON ".CONTRATS_TABLE.".`lieu_depot`=".LIEUX_TABLE.".`ref`" + ." WHERE ".CONTRATS_TABLE.".`del`=0" + ." AND ".CONTRATS_TABLE.".`groupe`=".intval($paniers_groupe) + ." AND ".CONTRATS_TABLE.".`date`<='".$date."'" + ." AND (".CONTRATS_TABLE.".`frequence`='hebdo' OR (".CONTRATS_TABLE.".`frequence`='quinz' AND ".CONTRATS_TABLE.".`quinz_groupe`='".$quinz_groupe."'))" + ." ORDER BY ".CLIENTS_TABLE.".`nom` ASC"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i["nb_paniers_livres"] = getNbLivraisonForContratAtDate($i['ref'], $date) + intval($i["np_paniers_distrib_avt_saisie"]); + $i["nb_paniers_restants"] = intval($i["nb_paniers"])-$i["nb_paniers_livres"]; + $i["frequence_print"] = CONTRATS_FREQUENCES[$i["frequence"]]; + if($i["frequence"] == "quinz") $i["frequence_print"] .= " (groupe ".$i["quinz_groupe"].")"; + $i["absence"] = getClientAbsenceAtDate($i["client_ref"], $date); + + if($i["nb_paniers_restants"]>0 || (int)$i['force_eligible']>0) { + // GROUP BY - LIEU & TYPE DE PANNIER + $lieu = intval($i['lieu_depot_ref']); + $pType = intval($i['panier_type_ref']); + + // CREATION DU LIEU + if(!array_key_exists($lieu, $list)) { + $list[$lieu] = array( + "ref" => $lieu, + "nom" => $i['lieu_depot_nom'], + "nb_paniers" => 0, + "paniers" => array() + ); + } + + // CREATION DU TYPE DE PANIER + if(!array_key_exists($pType, $list[$lieu]["paniers"])) { + $list[$lieu]["paniers"][$pType] = array( + "type_ref" => $pType, + "type_nom" => $i['panier_type_nom'], + "paniers" => array() + ); + } + + // AJOUT + $list[$lieu]["paniers"][$pType]["paniers"][] = $i; + } + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des paniers de la livraison dans le base de données !".$er; + } + + // ORDER + $list = orderListByKey($list, "nom", "ASC"); + for($i =0; $iselect($sql,1); + + if(!$r['erreur']) $nb = intval($r['datas']['nb']); + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération du nombre de livraison du contrat dans le base de données !".$er; + } + + return $i; + +} + +function getLivraisonPaniers($livraison, $lieu=0) { + $list = array(); + + $sql = getLivraisonsPaniersSelectBaseSQL(); + $sql.=" WHERE ".LIVRAISONS_PANIERS_TABLE.".`livraison`=".intval($livraison); + if($lieu>0) $sql.=" AND ".CONTRATS_TABLE.".`lieu_depot`=".intval($lieu); + $sql.=" ORDER BY ".CLIENTS_TABLE.".`nom` ASC"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i["frequence_print"] = CONTRATS_FREQUENCES[$i["frequence"]]; + if($i["frequence"] == "quinz") $i["frequence_print"] .= " (groupe ".$i["quinz_groupe"].')'; + + // GROUPE PAR TYPE DE PANIER + if(!array_key_exists($i["panier_type_ref"], $list)) { + $list[$i["panier_type_ref"]] = array( + "type_ref" => $i["panier_type_ref"], + "type_nom" => $i["panier_type_nom"], + "paniers" => array() + ); + } + $list[$i["panier_type_ref"]]["paniers"][] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des paniers de la livraison dans le base de données !".$er; + } + + $list = orderListByKey($list, "type_nom", "ASC"); + + return $list; +} + +function getLivraisonPaniersContratsList($livraison) { + $list = array(); + + $sql = "SELECT `contrat` FROM ".LIVRAISONS_PANIERS_TABLE." WHERE `livraison`=".intval($livraison); + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) $list[] = intval($i['contrat']); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des contrats de paniers de la livraison dans le base de données !".$er; + } + + return $list; +} + +function getLivraisonNbPaniers($livraison) { + $list = array(); + + $sql = "SELECT " + .CONTRATS_TABLE.".`panier_type` as 'ref', " + .PANIERS_TYPES_TABLE.".`nom` as 'nom', " + ."count(*) as 'nb'" + ." FROM ".LIVRAISONS_PANIERS_TABLE + ." LEFT JOIN ".CONTRATS_TABLE." ON ".LIVRAISONS_PANIERS_TABLE.".`contrat`=".CONTRATS_TABLE.".`ref`" + ." LEFT JOIN ".PANIERS_TYPES_TABLE." ON ".CONTRATS_TABLE.".`panier_type`=".PANIERS_TYPES_TABLE.".`ref`" + ." WHERE ".LIVRAISONS_PANIERS_TABLE.".`livraison`=".intval($livraison) + ." GROUP BY ".CONTRATS_TABLE.".`panier_type`"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i['ref'] = intval($i['ref']); + $i['nb'] = intval($i['nb']); + $list[$i['ref']] = $i; + } + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération du nombre de paniers de la livraison dans le base de données !".$er; + } + + return $list; +} + +function addLivraisonPanier($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_PANIERS_TABLE, // TABLE NAME + LIVRAISONS_PANIERS_TABLE_STRUCT,// TABLE STRUCTURE + $datas, // DATAS + "du panier de la livraison" // ERROR STRING + ); +} + +function deleteLivraisonPaniers($livraison) { + return deleteItemInTableByCondition( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_PANIERS_TABLE, // TABLE NAME + "WHERE livraison=".intval($livraison), // CONDITION + "des paniers de la livraison" // ERROR STRING + ); +} + +function clearLivraisonPaniers($livraison) { + return eraseItemInTableByCondition( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_PANIERS_TABLE, // TABLE NAME + "WHERE livraison=".intval($livraison), // CONDITION + "des paniers de la livraison" // ERROR STRING + ); +} + +//////////////////////////////////////////////////////////////////////// +// LIVRAISONS - LEGUMES //////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +function getLivraisonLegumes($livraison, $nbPaniers=[]) { + $list = array(); + + $sql = getLivraisonsLegumesTableSelectBaseSQL(); + $sql.=" WHERE ".LIVRAISONS_LEGUMES_TABLE.".`livraison`=".intval($livraison); + $sql.=" ORDER BY ".LEGUMES_TABLE.".`nom` ASC"; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) { + $i['tarif_unite_acro'] = LEGUMES_TARIFS_UNITES_ACRONYMES[$i['tarif_unite']]; + + // GROUPE PAR TYPE DE PANIER + if(!array_key_exists($i["panier_type_ref"], $list)) { + $list[$i["panier_type_ref"]] = array( + "ref" => $i["panier_type_ref"], + "nom" => $i["panier_type_nom"], + "nb" => 0, + "montant" => 0.0, + "legumes" => array() + ); + + if(array_key_exists($i["panier_type_ref"], $nbPaniers)) $list[$i["panier_type_ref"]]['nb'] = $nbPaniers[$i["panier_type_ref"]]['nb']; + } + $list[$i["panier_type_ref"]]["legumes"][] = $i; + $list[$i["panier_type_ref"]]["montant"] += floatval($i["quantite"]) * floatval($i["tarif_prix"]); + } + + $list = orderListByKey($list, "nom", "ASC"); + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des légumes de la livraison dans le base de données !".$er; + } + + return $list; +} + +function calcLivraisonTotalLegumes($legumes) { + $tot = array( + "montant" => 0.0, + "legumes" => array() + ); + + foreach($legumes as $p) { + foreach($p["legumes"] as $l) { + if(!array_key_exists($l['ref'], $tot["legumes"])) { + $tot["legumes"][$l['ref']] = $l; + $tot["legumes"][$l['ref']]["quantite"] = 0.0; + $tot["legumes"][$l['ref']]["montant"] = 0.0; + } + $tot["legumes"][$l['ref']]["quantite"] += floatval($l["quantite"]) * floatval($p['nb']); + $tot["legumes"][$l['ref']]["montant"] += floatval($l["tarif_prix"]) * floatval($l["quantite"]) * floatval($p['nb']); + + $tot["montant"] += floatval($l["tarif_prix"]) * floatval($l["quantite"]) * floatval($p['nb']); + } + } + + return $tot; +} + +function addLivraisonLegume($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_LEGUMES_TABLE, // TABLE NAME + LIVRAISONS_LEGUMES_TABLE_STRUCT,// TABLE STRUCTURE + $datas, // DATAS + "du légume" // ERROR STRING + ); +} + +function deleteLivraisonLegumes($livraison) { + return deleteItemInTableByCondition( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_LEGUMES_TABLE, // TABLE NAME + "WHERE livraison=".intval($livraison), // CONDITION + "des légumes de la livraison" // ERROR STRING + ); +} + +function clearLivraisonLegumes($livraison) { + return eraseItemInTableByCondition( + $GLOBALS['db_admin']['man'], // DB MANAGER + LIVRAISONS_LEGUMES_TABLE, // TABLE NAME + "WHERE livraison=".intval($livraison), // CONDITION + "des légumes de la livraison" // ERROR STRING + ); +} + +//////////////////////////////////////////////////////////////////////// +// PRINTS ////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +function exportLivraisonTemplateToPDF($templateFile, $outputFileName) { + $GLOBALS['smarty'] -> assign('logo', PUBLIC_HTML_ADMIN.'img/logo.png'); + + $cssFiles = array( + PUBLIC_HTML_ADMIN.'css/bootstrap_print_light.css', + PUBLIC_HTML_ADMIN.'css/livraisons.css' + ); + $GLOBALS['smarty'] -> assign('cssFiles',$cssFiles); + + $html = $GLOBALS['smarty']->fetch($templateFile); +// die($html); + + $dompdf = new Dompdf\Dompdf(); + $dompdf->loadHtml($html); + $dompdf->setPaper('A4', 'portrait'); + $options = $dompdf->getOptions(); + $options->setIsRemoteEnabled(true); + $dompdf->setOptions($options); + + $dompdf->render(); + $dompdf->stream($outputFileName); + + die(); +} \ No newline at end of file diff --git a/functions/functions_paniers_groupes.php b/functions/functions_paniers_groupes.php new file mode 100644 index 0000000..efce23d --- /dev/null +++ b/functions/functions_paniers_groupes.php @@ -0,0 +1,117 @@ + "réf.", + 'nom' => "nom" +); + +function getPaniersGroupesList($order='nom',$sens='ASC', $search=false) { + $list = array(); + + $sql = getPaniersGroupesSelectBaseSQL()." WHERE ".PANIERS_GROUPES_TABLE.".`ref`>0"; + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildPaniersGroupesListSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= PANIERS_GROUPES_TABLE.".`ref`"; + else if($order=='nom') $sql .= PANIERS_GROUPES_TABLE.".`nom`"; + else $sql .= PANIERS_GROUPES_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) $list[$i['ref']] = $i; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des groupes de paniers dans le base de données !".$er; + } + + return $list; +} + +// GET DATAS + +function getPaniersGroupeDatas($id) { + $i = array(); + + $sql = getPaniersGroupesSelectBaseSQL()." WHERE ".PANIERS_GROUPES_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du groupe de paniers dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getPaniersGroupeDatasFromRequest() { return getRequestTableDatas(PANIERS_GROUPES_TABLE_STRUCT); } + +function addPaniersGroupe($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_GROUPES_TABLE, // TABLE NAME + PANIERS_GROUPES_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du groupe de panier" // ERROR STRING + ); +} + +function updatePaniersGroupe($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_GROUPES_TABLE, // TABLE NAME + PANIERS_GROUPES_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au groupe de panier", // NULL STRING + "du groupe de panier" // ERROR STRING + ); +} + +function deletePaniersGroupe($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_GROUPES_TABLE, // TABLE NAME + $id, // ID + "du groupe de panier" // ERROR STRING + ); +} + +function erasePaniersGroupe($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_GROUPES_TABLE, // TABLE NAME + $id, // ID + "du groupe de panier" // ERROR STRING + ); +} \ No newline at end of file diff --git a/functions/functions_paniers_types.php b/functions/functions_paniers_types.php new file mode 100644 index 0000000..0a72db0 --- /dev/null +++ b/functions/functions_paniers_types.php @@ -0,0 +1,124 @@ + "réf.", + 'groupe' => "groupe", + 'nom' => "nom", + 'valeur' => 'valeur' +); + +function getPaniersTypesList($order='nom',$sens='ASC', $search=false, $groupe=0) { + $list = array(); + + $sql = getPaniersTypesSelectBaseSQL()." WHERE ".PANIERS_TYPES_TABLE.".`ref`>0"; + + // SEARCH + if($search && $search!="") { + $parts = explode(" ", $search); + if(is_array($parts) && count($parts>0)) { + $search_sql = ""; + foreach($parts as $p) { + if($p!="") $search_sql .= (($search_sql!="") ? " OR " : "").buildPaniersTypesListSearchSQL($p); + } + if($search_sql!="") $sql .= " AND (".$search_sql.")"; + } + } + + // GROUPE + if($groupe>0) $sql .= " AND ".PANIERS_TYPES_TABLE.".`groupe`=".intval($groupe); + + // ORDRE + $sql.=" ORDER BY "; + + if($order=='ref') $sql .= PANIERS_TYPES_TABLE.".`ref`"; + else if($order=='groupe') $sql .= PANIERS_GROUPES_TABLE.".`nom`"; + else if($order=='nom') $sql .= PANIERS_TYPES_TABLE.".`nom`"; + else if($order=='valeur') $sql .= PANIERS_TYPES_TABLE.".`valeur`"; + else $sql .= PANIERS_TYPES_TABLE.".`nom`"; + + // SENS + if($sens=='DESC') $sql .= ' DESC'; + else $sql .= ' ASC'; + + $r = $GLOBALS['db_admin']['man']->select($sql); + + if(!$r['erreur']) { + foreach($r['datas'] as $i) $list[$i['ref']] = $i; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération de la liste des types de paniers dans le base de données !".$er; + } + + return $list; +} + +// GET DATAS + +function getPaniersTypeDatas($id) { + $i = array(); + + $sql = getPaniersTypesSelectBaseSQL()." WHERE ".PANIERS_TYPES_TABLE.".`ref`=".intval($id); + + $r = $GLOBALS['db_admin']['man']->select($sql,1); + + if(!$r['erreur']) { + $i = $r['datas']; + } + else { + $er = "
sql: ".$sql."
error: ".getReadableVar($r['erreur']); + $GLOBALS['errors'][] = "Une erreur est survenue durant la récupération des informations du type de paniers dans le base de données !".$er; + } + + return $i; +} + +// ADD / UPDATE DATAS + +function getPaniersTypeDatasFromRequest() { return getRequestTableDatas(PANIERS_TYPES_TABLE_STRUCT); } + +function addPaniersType($datas) { + return addDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_TYPES_TABLE, // TABLE NAME + PANIERS_TYPES_TABLE_STRUCT, // TABLE STRUCTURE + $datas, // DATAS + "du type de panier" // ERROR STRING + ); +} + +function updatePaniersType($id, $datas) { + return updateDatasInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_TYPES_TABLE, // TABLE NAME + PANIERS_TYPES_TABLE_STRUCT, // TABLE STRUCTURE + $id, // ID + $datas, // DATAS + "au type de panier", // NULL STRING + "du type de panier" // ERROR STRING + ); +} + +function deletePaniersType($id) { + return deleteItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_TYPES_TABLE, // TABLE NAME + $id, // ID + "du type de panier" // ERROR STRING + ); +} + +function erasePaniersType($id) { + return eraseItemInTable( + $GLOBALS['db_admin']['man'], // DB MANAGER + PANIERS_TYPES_TABLE, // TABLE NAME + $id, // ID + "du type de panier" // ERROR STRING + ); +} \ No newline at end of file diff --git a/functions/functions_tmp_files.php b/functions/functions_tmp_files.php new file mode 100644 index 0000000..92fd348 --- /dev/null +++ b/functions/functions_tmp_files.php @@ -0,0 +1,153 @@ + "", // NOM (AVEC EXTENSION) DU FICHIER TEMPORAIRE + 'dir' => TMP_DIR, // DOSSIER DU FICHIER TEMPORAIRE (AVEC / DE FIN) + 'nom' => "", // NOM DU FICHIER D'ORIGINE (SANS EXTENSION) + 'size' => "", // TAILLE DU FICHIER TEMPORAIRE (NON FORMATEE) + 'prw' => "", // URL PREVIEW ICON FILE + 'ext' => "", // EXTENSION DU FICHIER D'ORIGINE (SANS LE POINT) + 'erreur' => false, + 'erreur_desc' => "" + ); + + if($fichier_tmp['tmp_name']!='') { + // RECUPERATION DE L'EXTENSION DU FICHIER EXISTANT + $r["ext"] = pathinfo($fichier_tmp['name'], PATHINFO_EXTENSION); + $r["nom"] = pathinfo($fichier_tmp['name'], PATHINFO_FILENAME ); + + // CREATION DU NOM DU FICHIER TEMPORAIRE + $r["tmp"] = replaceSymboles($r["nom"]).'-|_'.time().'.'.$r["ext"]; + + if(move_uploaded_file($fichier_tmp['tmp_name'], TMP_DIR.$r["tmp"])) { + // AJOUT DU FICHIER A L'HISTORIQUE D'UPLOAD TMP + if(isset($_SESSION['tmpUpload'])) $_SESSION['tmpUpload'] = array(); + $_SESSION['tmpUpload'][] = TMP_DIR.$r["tmp"]; + + $r["prw"] = "index.php?action=get_tmp_file&file=".$r["tmp"]; + $r["size"] = filesize(TMP_DIR.$r["tmp"]); + } + else { + $r['erreur'] = true; + $r['erreur'] = "ERREUR : une erreur est survenus durant l'enregistrement du fichier temporaire...' "; + } + } + else { + $r['erreur'] = true; + $r['erreur'] = "ERREUR : nom de fichier temporaire inconnu...' "; + } + + return $r; +} + +function saveTmpPhoto($tmp,$dest_dir,$dest_name=false,$rotate=0) { + if(file_exists(TMP_DIR.$tmp)) { + // RECUPERATION DU TYPE D'IMAGE + $ext = getImgExtFromMimeType(TMP_DIR.$tmp); + + // DEST + $filename = $tmp; + if($dest_name!="") $filename = $dest_name.'.'.$ext; + if($dest_dir != "" && substr($dest_dir,-1) != "/") $dest_dir .= "/"; + $dest = $dest_dir.$filename; + + // REDIM & SAVE + redimg(TMP_DIR.$tmp, $dest, PHOTOS_SIZE, PHOTOS_SIZE, true, true, false, $ext); + + // COPY + copy(TMP_DIR.$tmp,$dest); + + // ROTATE + if($rotate==90 || $rotate==180 || $rotate==270) rotatePhoto($dest, $rotate, true); + + return array('file' => $dest, 'filename' => $filename); + } + else { + return "nofile"; + } +} + +function clearTmpUpload() { + if(isset($_SESSION['tmpUpload']) && is_array($_SESSION['tmpUpload'])) { + foreach($_SESSION['tmpUpload'] as $k => $f) if(file_exists(TMP_DIR.$f)) unlink(TMP_DIR.$f); + $_SESSION['tmpUpload'] = array(); + } +} + +function makePhotoPath($file) { + if(is_null($file) || $file=="") return NULL; + $path = PHOTOS_DIR.$file; + return file_exists($path) ? $path : NULL; +} + +function makeThumbnailPath($file) { + if(is_null($file) || $file=="") return NULL; + + $thumb_path = THUMBNAIL_DIR.$file; + if(file_exists($thumb_path)) return $thumb_path; + + $photo_path = PHOTOS_DIR.$file; + if(!file_exists($photo_path)) return NULL; + + // MAKE THUMBNAIL + $ext = getImgExtFromMimeType($photo_path); + if($ext == "jpg" || $ext == "png" || $ext == "webp") redimg($photo_path, $thumb_path, 400, 400, false, true, false, $ext); + + return file_exists($thumb_path) ? $thumb_path : NULL; +} + +function rotatePhoto($filepath, $angle, $save = false) { + $ext = (strtolower(substr($filepath,-3))=="png") ? "png" : "jpg"; + $angle = 360-$angle; + if(!file_exists($filepath) || !is_file($filepath)) return false; + + // PNG + if($ext == "png") { + $img = imagecreatefrompng($filepath); + imageAlphaBlending($img, true); + imageSaveAlpha($img, true); + $img = imagerotate($img, $angle, 0); + // DISPLAY + if(!$save) { + header("Content-type: image/png"); + imagepng($img); + imagedestroy($img); + die(); + } + // SAVE + else { + $dest = $save; + if($save == true) $dest = $filepath; + if(file_exists($dest) && is_file($dest)) unlink($dest); + imagepng($img, $dest); + imagedestroy($img); + return file_exists($dest); + } + } + // JPG + else { + $img = imagecreatefromjpeg($filepath); + $img = imagerotate($img, $angle, 0); + // DISPLAY + if(!$save) { + header('Content-Type: image/jpeg'); + imagejpeg($img); + imagedestroy($img); + die(); + } + // SAVE + else { + $dest = $save; + if($save == true) $dest = $filepath; + if(file_exists($dest) && is_file($dest)) unlink($dest); + imagejpeg($img, $dest); + imagedestroy($img); + return file_exists($dest); + } + + } +} + +?> \ No newline at end of file diff --git a/paniers.sql b/paniers.sql new file mode 100644 index 0000000..5f4f315 --- /dev/null +++ b/paniers.sql @@ -0,0 +1,287 @@ +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `paniers_groupes` +-- -------------------------------------------------------- + +CREATE TABLE `paniers_groupes` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `nom` varchar(64) NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `paniers_types` +-- -------------------------------------------------------- + +CREATE TABLE `paniers_types` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `groupe` smallint(5) UNSIGNED NOT NULL, + `nom` varchar(64) NOT NULL, + `valeur` float(5,2) UNSIGNED NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + CONSTRAINT `paniers_types_groupe_fk` FOREIGN KEY (`groupe`) REFERENCES `paniers_groupes`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `lieux` +-- -------------------------------------------------------- + +CREATE TABLE `lieux` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `nom` varchar(64) NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `clients` +-- -------------------------------------------------------- + +CREATE TABLE `clients` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `nom` varchar(64) NOT NULL, + `prenom` varchar(64) NOT NULL, + `tel` varchar(20) NULL DEFAULT NULL, + `email` varchar(128) NULL DEFAULT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `clients_absences` +-- -------------------------------------------------------- + +CREATE TABLE `clients_absences` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT , + `client` smallint(5) UNSIGNED NOT NULL , + `debut` DATE NOT NULL , + `fin` DATE NOT NULL , + `remarque` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + CONSTRAINT `clients_absences_client_fk` FOREIGN KEY (`client`) REFERENCES `clients`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`del`) +) +ENGINE = InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `contrats_types` +-- -------------------------------------------------------- + +CREATE TABLE `contrats_types` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `groupe` smallint(5) UNSIGNED NOT NULL, + `nom` varchar(128) NOT NULL, + `frequence` set('hebdo','quinz') NOT NULL, + `panier_type` smallint(5) UNSIGNED NOT NULL, + `nb_paniers` smallint(2) UNSIGNED NOT NULL, + `prix_total` float(6,2) UNSIGNED NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + CONSTRAINT `contrats_types_groupe_fk` FOREIGN KEY (`groupe`) REFERENCES `paniers_groupes`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX(`frequence`), + CONSTRAINT `contrats_types_panier_type_fk` FOREIGN KEY (`panier_type`) REFERENCES `paniers_types`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `contrats` +-- -------------------------------------------------------- + +CREATE TABLE `contrats` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `client` smallint(5) UNSIGNED NOT NULL, + `type` smallint(5) UNSIGNED NULL DEFAULT NULL, + `groupe` smallint(5) UNSIGNED NOT NULL, + `frequence` set('hebdo','quinz') NOT NULL, + `panier_type` smallint(5) UNSIGNED NOT NULL, + `nb_paniers` smallint(2) UNSIGNED NOT NULL, + `date` date NOT NULL, + `quinz_groupe` set('A','B') NULL DEFAULT NULL, + `lieu_depot` smallint(5) UNSIGNED NOT NULL, + `nb_cheque` int(2) UNSIGNED NOT NULL DEFAULT '0', + `np_paniers_distrib_avt_saisie` int(2) UNSIGNED NOT NULL DEFAULT '0', + `force_eligible` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + `force_not_archive` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + `archive` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + CONSTRAINT `contrats_client_fk` FOREIGN KEY (`client`) REFERENCES `clients`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `contrats_type_fk` FOREIGN KEY (`type`) REFERENCES `contrats_types`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `paniers_groupe_fk` FOREIGN KEY (`groupe`) REFERENCES `paniers_groupes`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX(`frequence`), + CONSTRAINT `contrats_panier_type_fk` FOREIGN KEY (`panier_type`) REFERENCES `paniers_types`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX(`quinz_groupe`), + CONSTRAINT `contrats_lieu_depot_fk` FOREIGN KEY (`lieu_depot`) REFERENCES `lieux`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX(`archive`), + INDEX (`force_not_archive`), + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `legumes` +-- -------------------------------------------------------- + +CREATE TABLE `legumes` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `nom` varchar(64) NOT NULL, + `tarif` smallint(5) UNSIGNED NULL DEFAULT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + INDEX (`tarif`), + INDEX (`del`) +) +ENGINE = InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `legume_tarifs` +-- -------------------------------------------------------- + +CREATE TABLE `legumes_tarifs` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `legume` smallint(5) UNSIGNED NOT NULL, + `prix` float(5,2) UNSIGNED NOT NULL, + `unite` set('kg','pièce','botte') NOT NULL DEFAULT 'kg', + `date` date NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + CONSTRAINT `legumes_tarifs_legume_fk` FOREIGN KEY (`legume`) REFERENCES `legumes`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `livraisons` +-- -------------------------------------------------------- + +CREATE TABLE `livraisons` ( + `ref` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `paniers_groupe` smallint(5) UNSIGNED NOT NULL, + `date` date NOT NULL, + `quinz_groupe` set('A','B') NOT NULL, + `archive` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + `force_not_archive` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`ref`), + CONSTRAINT `livraisons_paniers_groupe_fk` FOREIGN KEY (`paniers_groupe`) REFERENCES `paniers_groupes`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`archive`), + INDEX (`force_not_archive`), + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `livraisons_legumes` +-- -------------------------------------------------------- + +CREATE TABLE `livraisons_legumes` ( + `livraison` smallint(5) UNSIGNED NOT NULL, + `legume` smallint(5) UNSIGNED NOT NULL, + `panier_type` smallint(5) UNSIGNED NOT NULL, + `tarif` smallint(5) UNSIGNED NOT NULL, + `quantite` float(5,2) UNSIGNED NOT NULL, + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + UNIQUE (`livraison`, `legume`, `panier_type`), + CONSTRAINT `livraisons_legumes_livraison_fk` FOREIGN KEY (`livraison`) REFERENCES `livraisons`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `livraisons_legumes_panier_type_fk` FOREIGN KEY (`panier_type`) REFERENCES `paniers_types`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `livraisons_legumes_legume_fk` FOREIGN KEY (`legume`) REFERENCES `legumes`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `livraisons_legumes_tarif_fk` FOREIGN KEY (`tarif`) REFERENCES `legumes_tarifs`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA TABLE `livraisons_paniers` +-- -------------------------------------------------------- + +CREATE TABLE `livraisons_paniers` ( + `livraison` smallint(5) UNSIGNED NOT NULL, + `contrat` smallint(5) UNSIGNED NOT NULL, + `force_not_archive` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + `del` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', + UNIQUE (`livraison`, `contrat`), + CONSTRAINT `livraisons_paniers_livraison_fk` FOREIGN KEY (`livraison`) REFERENCES `livraisons`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + CONSTRAINT `livraisons_paniers_contrat_fk` FOREIGN KEY (`contrat`) REFERENCES `contrats`(`ref`) ON DELETE RESTRICT ON UPDATE RESTRICT, + INDEX (`del`) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8; + +-- ######################################################## +-- ### SQL VIEWS ########################################## +-- ######################################################## + +-- -------------------------------------------------------- +-- STRUCTURE DE LA VIEW `contrats_nb_paniers_livres` +-- -------------------------------------------------------- + +CREATE VIEW `contrats_count_nb_paniers_livres` AS + SELECT + `contrats`.ref, + COUNT(*) as 'nb_paniers_livres' + FROM `livraisons_paniers` + LEFT JOIN contrats ON livraisons_paniers.contrat = contrats.ref + WHERE `livraisons_paniers`.`del`=0 + GROUP BY `contrat`; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA VIEW `contrats_nb_paniers_statut` +-- -------------------------------------------------------- + +CREATE VIEW `contrats_paniers_statut` AS + SELECT + contrats.ref, + contrats.nb_paniers, + CASE WHEN ISNULL(contrats_count_nb_paniers_livres.nb_paniers_livres) + THEN 0 + ELSE contrats_count_nb_paniers_livres.nb_paniers_livres + END as 'nb_paniers_livres_absolute', + CASE WHEN ISNULL(contrats_count_nb_paniers_livres.nb_paniers_livres) + THEN contrats.np_paniers_distrib_avt_saisie + ELSE contrats.np_paniers_distrib_avt_saisie + contrats_count_nb_paniers_livres.nb_paniers_livres + END as 'nb_paniers_livres', + CASE WHEN ISNULL(contrats_count_nb_paniers_livres.nb_paniers_livres) + THEN CAST(contrats.nb_paniers AS signed) - CAST(contrats.np_paniers_distrib_avt_saisie AS signed) + ELSE CAST(contrats.nb_paniers AS signed) - CAST(contrats.np_paniers_distrib_avt_saisie AS signed) - CAST(contrats_count_nb_paniers_livres.nb_paniers_livres AS signed) + END as 'nb_paniers_restants' + FROM contrats + LEFT JOIN contrats_count_nb_paniers_livres ON contrats.ref = contrats_count_nb_paniers_livres.ref; + +-- -------------------------------------------------------- +-- STRUCTURE DE LA VIEW `livraisons_nb_paniers` +-- -------------------------------------------------------- + +CREATE VIEW `livraisons_nb_paniers` AS + SELECT + `livraisons_paniers`.`livraison` as 'ref', + COUNT(*) as 'nb_paniers' + FROM `livraisons_paniers` + GROUP BY `livraisons_paniers`.`livraison`; + +COMMIT; diff --git a/php_libs/composer/.gitignore b/php_libs/composer/.gitignore new file mode 100644 index 0000000..22d0d82 --- /dev/null +++ b/php_libs/composer/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/php_libs/composer/composer.json b/php_libs/composer/composer.json new file mode 100644 index 0000000..0d2f9b4 --- /dev/null +++ b/php_libs/composer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "dompdf/dompdf": "^2.0" + } +} diff --git a/php_libs/composer/composer.lock b/php_libs/composer/composer.lock new file mode 100644 index 0000000..007b517 --- /dev/null +++ b/php_libs/composer/composer.lock @@ -0,0 +1,291 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "f0205c0fedf4b0bac3e0aa4c567cb1ec", + "packages": [ + { + "name": "dompdf/dompdf", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "093f2d9739cec57428e39ddadedfd4f3ae862c0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/093f2d9739cec57428e39ddadedfd4f3ae862c0f", + "reference": "093f2d9739cec57428e39ddadedfd4f3ae862c0f", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "masterminds/html5": "^2.0", + "phenx/php-font-lib": ">=0.5.4 <1.0.0", + "phenx/php-svg-lib": ">=0.3.3 <1.0.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "ext-json": "*", + "ext-zip": "*", + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "The Dompdf Community", + "homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/v2.0.4" + }, + "time": "2023-12-12T20:19:39+00:00" + }, + { + "name": "masterminds/html5", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + }, + "time": "2023-05-10T11:58:31+00:00" + }, + { + "name": "phenx/php-font-lib", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-font-lib.git", + "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/dd448ad1ce34c63d09baccd05415e361300c35b4", + "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4", + "shasum": "" + }, + "require": { + "ext-mbstring": "*" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3 || ^4 || ^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/0.5.4" + }, + "time": "2021-12-17T19:44:54+00:00" + }, + { + "name": "phenx/php-svg-lib", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-svg-lib.git", + "reference": "8a8a1ebcf6aea861ef30197999f096f7bd4b4456" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/8a8a1ebcf6aea861ef30197999f096f7bd4b4456", + "reference": "8a8a1ebcf6aea861ef30197999f096f7bd4b4456", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabberworm/php-css-parser": "^8.4" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/0.5.1" + }, + "time": "2023-12-11T20:56:08+00:00" + }, + { + "name": "sabberworm/php-css-parser", + "version": "8.4.0", + "source": { + "type": "git", + "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", + "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/e41d2140031d533348b2192a83f02d8dd8a71d30", + "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=5.6.20" + }, + "require-dev": { + "codacy/coverage": "^1.4", + "phpunit/phpunit": "^4.8.36" + }, + "suggest": { + "ext-mbstring": "for parsing UTF-8 CSS" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabberworm\\CSS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Raphael Schweikert" + } + ], + "description": "Parser for CSS Files written in PHP", + "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ], + "support": { + "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", + "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + }, + "time": "2021-12-11T13:40:54+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/php_libs/smarty-3.1.33/COMPOSER_RELEASE_NOTES.txt b/php_libs/smarty-3.1.33/COMPOSER_RELEASE_NOTES.txt new file mode 100755 index 0000000..0644719 --- /dev/null +++ b/php_libs/smarty-3.1.33/COMPOSER_RELEASE_NOTES.txt @@ -0,0 +1,31 @@ + + +Starting with Smarty 3.1.21 Composer has been configured to load the packages from github. + +******************************************************************************* +* * +* NOTE: Because of this change you must clear your local composer cache with * +* the "composer clearcache" command * +* * +******************************************************************************* + +To get the latest stable version use + "require": { + "smarty/smarty": "~3.1" + } +in your composer.json file. + +To get the trunk version use + "require": { + "smarty/smarty": "~3.1@dev" + } + +The "smarty/smarty" package will start at libs/.... subfolder. + +To retrieve the development and documentation folders add + "require-dev": { + "smarty/smarty-dev": "~3.1@dev" + } + +If you are using (include) the composer generated autoloader.php which is located +in the /vendor folder it is no longer needed to require the Smarty.class.php file. \ No newline at end of file diff --git a/php_libs/smarty-3.1.33/INHERITANCE_RELEASE_NOTES.txt b/php_libs/smarty-3.1.33/INHERITANCE_RELEASE_NOTES.txt new file mode 100755 index 0000000..67936a8 --- /dev/null +++ b/php_libs/smarty-3.1.33/INHERITANCE_RELEASE_NOTES.txt @@ -0,0 +1,91 @@ +3.1.3" +New tags for inheritance parent and chilD +{parent} == {$smarty.block.parent} +{child} == {$smarty.block.child} +Both tags support the assign attribute like +{child assign=foo} + +3.1.31 +New tags for inheritance parent and child +{block_parent} == {$smarty.block.parent} +{block_child} == {$smarty.block.child} + +Since 3.1.28 you can mix inheritance by extends resource with the {extends} tag. +A template called by extends resource can extend a subtemplate or chain buy the {extends} tag. +Since 3.1.31 this feature can be turned off by setting the new Smarty property Smarty::$extends_recursion to false. + +3.1.28 +Starting with version 3.1.28 template inheritance is no longer a compile time process. +All {block} tag parent/child relations are resolved at run time. +This does resolve all known existing restrictions (see below). + +The $smarty::$inheritance_merge_compiled_includes property has been removed. +Any access to it is ignored. + +New features: + +Any code outside root {block} tags in child templates is now executed but any output will be ignored. + + {extends 'foo.tpl'} + {$bar = 'on'} // assigns variable $bar seen in parent templates + {block 'buh'}{/block} + + {extends 'foo.tpl'} + {$bar} // the output of variable bar is ignored + {block 'buh'}{/block} + +{block} tags can be dynamically en/disabled by conditions. + + {block 'root'} + {if $foo} + {block 'v1'} + .... + {/block} + {else} + {block 'v1'} + .... + {/block} + {/if} + {/block} + +{block} tags can have variable names. + + {block $foo} + .... + {/block} + +Starting with 3.1.28 you can mix inheritance by extends resource with the {extends} tag. +A template called by extends resource can extend a subtemplate or chain buy the {extends} tag. + +NOTE There is a BC break. If you used the extends resource {extends} tags have been ignored. + +THE FOLLOWING RESTRICTIONS ARE NO LONGER EXISTING: +In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags +is done at compile time and the parent and child templates are compiled in a single compiled template. +{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because +it could be used in other context where the {block} extended with a different result. For that reasion +the compiled code of {include} subtemplates gets also merged in compiled inheritance template. + +Merging the code into a single compile template has some drawbacks. +1. You could not use variable file names in {include} Smarty would use the {include} of compilation time. +2. You could not use individual compile_id in {include} +3. Separate caching of subtemplate was not possible +4. Any change of the template directory structure between calls was not necessarily seen. + +Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out +that a couple of users did use some of above and now got exceptions. + +To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes. +For most backward compatibility its default setting is true. +With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases +could be rejected by exception. + + +If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged.You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option. +{include file='foo.bar' inline} + +1. In case of a variable file name like {include file=$foo inline} you must use the variable in a compile_id $smarty->compile_id = $foo; +2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the global compile_id as well $smarty->compile_id = $bar; +3. If call templates with different template_dir configurations and a parent could same named child template from different folders + you must make the folder name part of the compile_id. + diff --git a/php_libs/smarty-3.1.33/LICENSE b/php_libs/smarty-3.1.33/LICENSE new file mode 100755 index 0000000..fb8ca6c --- /dev/null +++ b/php_libs/smarty-3.1.33/LICENSE @@ -0,0 +1,179 @@ +Smarty: the PHP compiling template engine + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU Lesser General Public License below for more details. + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/php_libs/smarty-3.1.33/NEW_FEATURES.txt b/php_libs/smarty-3.1.33/NEW_FEATURES.txt new file mode 100755 index 0000000..b3289df --- /dev/null +++ b/php_libs/smarty-3.1.33/NEW_FEATURES.txt @@ -0,0 +1,291 @@ + + +This file contains a brief description of new features which have been added to Smarty 3.1 + +Smarty 3.1.33-dev + Variable capture name in Smarty special variable + ================================================ + {$smarty.capture.$foo} can now be used to access the content of a named + capture block + +Smarty 3.1.32 + New tags for inheritance parent and child + ========================================= + {parent} == {$smarty.block.parent} + {child} == {$smarty.block.child} + Both tags support the assign attribute like + {child assign=foo} + + Deprecate functions Smarty::muteExpectedErrors() and Smarty::unmuteExpectedErrors() + =================================================================================== + These functions to start a special error handler are no longer needed as Smarty does + no longer use error suppression like @filemtime(). + For backward compatibility the functions still can be called. + + Using literals containing Smarty's left and right delimiter + =========================================================== + New Methods + $smarty->setLiterals(array $literals) + $smarty->addLiterals(array $literals) + to define literals containing Smarty delimiter. This can avoid the need for extreme usage + of {literal} {/literal} tags. + A) Treat '{{' and '}}' as literal + If Smarty::$auto_literal is enabled + {{ foo }} + will be treated now as literal. (This does apply for any number of delimiter repeatations). + However {{foo}} is not an literal but will be interpreted as a recursive Smarty tag. + If you use + $smarty->setLiteral(array('{{','}}')); + {{foo}} is now a literal as well. + NOTE: In the last example nested Smarty tags starting with '{{' or ending with '}}' will not + work any longer, but this should be very very raw occouring restriction. + B) Example 2 + Assume your delimiter are '<-' , '->' and '<--' , '-->' shall be literals + $smarty->setLiteral(array('<--','-->')); + + + The capture buffers can now be accessed as array + ================================================ + {capture name='foo'} + bah + {\capture} + {capture name='buh'} + blar + {\capture} + {foreach $smarty.capture as $name => $buffer} + .... + {/foreach} + +Smarty 3.1.31 + New tags for inheritance parent and child + ========================================= + {block_parent} == {$smarty.block.parent} + {block_child} == {$smarty.block.child} + +Smarty 3.1.30 + + Loop optimization {foreach} and {section} + ========================================= + Smarty does optimize the {foreach} and {section} loops by removing code for not needed loop + properties. + The compiler collects needed properties by scanning the current template for $item@property, + $smarty.foreach.name.property and $smarty.section.name.property. + The compiler does not know if additional properties will be needed outside the current template scope. + Additional properties can be generated by adding them with the property attribute. + + Example: + index.tpl + {foreach $from as $item properties=[iteration, index]} + {include 'sub.tpl'} + {$item.total} + {/foreach} + + sub.tpl + {$item.index} {$item.iteration} {$item.total} + + In above example code for the 'total' property is automatically generated as $item.total is used in + index.tpl. Code for 'iteration' and 'index' must be added with properties=[iteration, index]. + + New tag {make_nocache} + ====================== + Syntax: {make_nocache $foo} + + This tag makes a variable which does exists normally only while rendering the compiled template + available in the cached template for use in not cached expressions. + + Expample: + {foreach from=$list item=item} +
  • {$item.name} {make_nocache $item}{if $current==$item.id} ACTIVE{/if}
  • + {/foreach} + + The {foreach} loop is rendered while processing the compiled template, but $current is a nocache + variable. Normally the {if $current==$item.id} would fail as the $item variable is unknown in the cached template. {make_nocache $item} does make the current $item value known in thee cached template. + + {make_nocache} is ignored when caching is disabled or the variable does exists as nocache variable. + + NOTE: if the variable value does contain objects these must have the __set_state method implemented. + + + Scope Attributes + ================ + The scope handling has been updated to cover all cases of variable assignments in templates. + + The tags {assign}, {append} direct assignments like {$foo = ...}, {$foo[...]= ...} support + the following optional scope attributes: + scope='parent' - the variable will be assigned in the current template and if the template + was included by {include} the calling template + scope='tpl_root' - the variable will be assigned in the outermost root template called by $smarty->display() + or $smarty->fetch() and is bubbled up all {include} sub-templates to the current template. + scope='smarty' - the variable will be assigned in the Smarty object and is bubbled up all {include} sub-templates + to the current template. + scope='global' - the variable will be assigned as Smarty object global variable and is bubbled up all {include} + sub-templates to the current template. + scope='root' - the variable will be assigned if a data object was used for variable definitions in the data + object or in the Smarty object otherwise and is bubbled up all {include} sub-templates to the + current template. + scope='local' - this scope has only a meaning if the tag is called within a template {function}. + The variable will be assigned in the local scope of the template function and the + template which did call the template function. + + + The {config_load} tag supports all of the above except the global scope. + + The scope attribute can be used also with the {include} tag. + Supported scope are parent, tpl_root, smarty, global and root. + A scope used together with the {include} tag will cause that with some exceptions any variable + assignment within that sub-template will update/assign the variable in other scopes according + to the above rules. It does include also variables assigned by plugins, tags supporting the assign=foo attribute and direct assignments in {if} and {while} like {if $foo=$bar}. + Excluded are the key and value variables of {foreach}, {for} loop variables , variables passed by attributes + in {include} and direct increments/decrements like {$foo++}, {$foo--} + + Note: The scopes should be used only to the extend really need. If a variable value assigned in an included + sub-template should be returned to the calling sub-template just use {$foo='bar' scope='parent'}. + Use scopes only with variables for which it's realy needed. Avoid general scope settings with the + {include} tag as it can have a performance impact. + + The {assign}, {append}, {config_load} and {$foo...=...} tags have a new option flag 'noscope'.Thi + Example: {$foo='bar' noscope} This will assign $foo only in the current template and any scope settings + at {include} is ignored. + + + Caching + ======= + Caching does now observe the template_dir setting and will create separate cache files if required + + Compiled Templates + ================== + The template_dir setting is now encoded in the uid of the file name. + The content of the compiled template may depend on the template_dir search order + {include .... inline} is used or $smarty->merge_compiled_includes is enabled + + APC + === + If APC is enabled force an apc_compile_file() when compiled or cached template was updated + +Smarty 3.1.28 + + OPCACHE + ======= + Smarty does now invalidate automatically updated and cleared compiled or cached template files in OPCACHE. + Correct operation is no longer dependent on OPCACHE configuration settings. + + Template inheritance + ==================== + Template inheritance is now processed in run time. + See the INHERITANCE_RELEASE_NOTES + + Modifier regex_replace + ====================== + An optional limit parameter was added + + fetch() and display() + ===================== + The fetch() and display() methods of the template object accept now optionally the same parameter + as the corresponding Smarty methods to get the content of another template. + Example: + $template->display(); Does display template of template object + $template->display('foo.tpl'); Does display template 'foo.bar' + + File: resource + ============== + Multiple template_dir entries can now be selected by a comma separated list of indices. + The template_dir array is searched in the order of the indices. (Could be used to change the default search order) + Example: + $smarty->display('[1],[0]foo.bar'); + + Filter support + ============== + Optional filter names + An optional filter name was added to $smarty->registerFilter(). It can be used to unregister a filter by name. + - $smarty->registerFilter('output', $callback, 'name'); + $smarty->unregister('output', 'name'); + + Closures + $smarty->registerFilter() does now accept closures. + - $smarty->registerFilter('pre', function($source) {return $source;}); + If no optional filter name was specified it gets the default name 'closure'. + If you register multiple closures register each with a unique filter name. + - $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_1'); + - $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_2'); + + +Smarty 3.1.22 + + Namespace support within templates + ================================== + Within templates you can now use namespace specifications on: + - Constants like foo\bar\FOO + - Class names like foo\bar\Baz::FOO, foo\bar\Baz::$foo, foo\bar\Baz::foo() + - PHP function names like foo\bar\baz() + + Security + ======== + - disable special $smarty variable - + The Smarty_Security class has the new property $disabled_special_smarty_vars. + It's an array which can be loaded with the $smarty special variable names like + 'template_object', 'template', 'current_dir' and others which will be disabled. + Note: That this security check is performed at compile time. + + - limit template nesting - + Property $max_template_nesting of Smarty_Security does set the maximum template nesting level. + The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded + an Exception will be thrown. The default setting is 0 which does disable this check. + + - trusted static methods - + The Smarty_Security class has the new property $trusted_static_methods to restrict access to static methods. + It's an nested array of trusted class and method names. + Format: + array ( + 'class_1' => array('method_1', 'method_2'), // allowed methods + 'class_2' => array(), // all methods of class allowed + ) + To disable access for all methods of all classes set $trusted_static_methods = null; + The default value is an empty array() which does enables all methods of all classes, but for backward compatibility + the setting of $static_classes will be checked. + Note: That this security check is performed at compile time. + + - trusted static properties - + The Smarty_Security class has the new property $trusted_static_properties to restrict access to static properties. + It's an nested array of trusted class and property names. + Format: + array ( + 'class_1' => array('prop_1', 'prop_2'), // allowed properties listed + 'class_2' => array(), // all properties of class allowed + } + To disable access for all properties of all classes set $trusted_static_properties = null; + The default value is an empty array() which does enables all properties of all classes, but for backward compatibility + the setting of $static_classes will be checked. + Note: That this security check is performed at compile time. + + - trusted constants . + The Smarty_Security class has the new property $trusted_constants to restrict access to constants. + It's an array of trusted constant names. + Format: + array ( + 'SMARTY_DIR' , // allowed constant + } + If the array is empty (default) the usage of constants can be controlled with the + Smarty_Security::$allow_constants property (default true) + + + + Compiled Templates + ================== + Smarty does now automatically detects a change of the $merge_compiled_includes and $escape_html + property and creates different compiled templates files depending on the setting. + + Same applies to config files and the $config_overwrite, $config_booleanize and + $config_read_hidden properties. + + Debugging + ========= + The layout of the debug window has been changed for better readability + + New class constants + Smarty::DEBUG_OFF + Smarty::DEBUG_ON + Smarty::DEBUG_INDIVIDUAL + have been introduced for setting the $debugging property. + + Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual debug window. + diff --git a/php_libs/smarty-3.1.33/README b/php_libs/smarty-3.1.33/README new file mode 100755 index 0000000..9a71519 --- /dev/null +++ b/php_libs/smarty-3.1.33/README @@ -0,0 +1,575 @@ +Smarty 3.x + +Author: Monte Ohrt +Author: Uwe Tews + +AN INTRODUCTION TO SMARTY 3 + +NOTICE FOR 3.1 release: + +Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution. + +NOTICE for 3.0.5 release: + +Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior: + +$smarty->error_reporting = E_ALL & ~E_NOTICE; + +NOTICE for 3.0 release: + +IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release. +We felt it is better to make these now instead of after a 3.0 release, then have to +immediately deprecate APIs in 3.1. Online documentation has been updated +to reflect these changes. Specifically: + +---- API CHANGES RC4 -> 3.0 ---- + +$smarty->register->* +$smarty->unregister->* +$smarty->utility->* +$samrty->cache->* + +Have all been changed to local method calls such as: + +$smarty->clearAllCache() +$smarty->registerFoo() +$smarty->unregisterFoo() +$smarty->testInstall() +etc. + +Registration of function, block, compiler, and modifier plugins have been +consolidated under two API calls: + +$smarty->registerPlugin(...) +$smarty->unregisterPlugin(...) + +Registration of pre, post, output and variable filters have been +consolidated under two API calls: + +$smarty->registerFilter(...) +$smarty->unregisterFilter(...) + +Please refer to the online documentation for all specific changes: + +http://www.smarty.net/documentation + +---- + +The Smarty 3 API has been refactored to a syntax geared +for consistency and modularity. The Smarty 2 API syntax is still supported, but +will throw a deprecation notice. You can disable the notices, but it is highly +recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run +through an extra rerouting wrapper. + +Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also, +all Smarty properties now have getters and setters. So for example, the property +$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be +retrieved with $smarty->getCacheDir(). + +Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were +just duplicate functions of the now available "get*" methods. + +Here is a rundown of the Smarty 3 API: + +$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null) +$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null) +$smarty->isCached($template, $cache_id = null, $compile_id = null) +$smarty->createData($parent = null) +$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null) +$smarty->enableSecurity() +$smarty->disableSecurity() +$smarty->setTemplateDir($template_dir) +$smarty->addTemplateDir($template_dir) +$smarty->templateExists($resource_name) +$smarty->loadPlugin($plugin_name, $check = true) +$smarty->loadFilter($type, $name) +$smarty->setExceptionHandler($handler) +$smarty->addPluginsDir($plugins_dir) +$smarty->getGlobal($varname = null) +$smarty->getRegisteredObject($name) +$smarty->getDebugTemplate() +$smarty->setDebugTemplate($tpl_name) +$smarty->assign($tpl_var, $value = null, $nocache = false) +$smarty->assignGlobal($varname, $value = null, $nocache = false) +$smarty->assignByRef($tpl_var, &$value, $nocache = false) +$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false) +$smarty->appendByRef($tpl_var, &$value, $merge = false) +$smarty->clearAssign($tpl_var) +$smarty->clearAllAssign() +$smarty->configLoad($config_file, $sections = null) +$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true) +$smarty->getConfigVariable($variable) +$smarty->getStreamVariable($variable) +$smarty->getConfigVars($varname = null) +$smarty->clearConfig($varname = null) +$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true) +$smarty->clearAllCache($exp_time = null, $type = null) +$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) + +$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array()) + +$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + +$smarty->registerFilter($type, $function_name) +$smarty->registerResource($resource_type, $function_names) +$smarty->registerDefaultPluginHandler($function_name) +$smarty->registerDefaultTemplateHandler($function_name) + +$smarty->unregisterPlugin($type, $tag) +$smarty->unregisterObject($object_name) +$smarty->unregisterFilter($type, $function_name) +$smarty->unregisterResource($resource_type) + +$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) +$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) +$smarty->testInstall() + +// then all the getters/setters, available for all properties. Here are a few: + +$caching = $smarty->getCaching(); // get $smarty->caching +$smarty->setCaching(true); // set $smarty->caching +$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices +$smarty->setCacheId($id); // set $smarty->cache_id +$debugging = $smarty->getDebugging(); // get $smarty->debugging + + +FILE STRUCTURE + +The Smarty 3 file structure is similar to Smarty 2: + +/libs/ + Smarty.class.php +/libs/sysplugins/ + internal.* +/libs/plugins/ + function.mailto.php + modifier.escape.php + ... + +A lot of Smarty 3 core functionality lies in the sysplugins directory; you do +not need to change any files here. The /libs/plugins/ folder is where Smarty +plugins are located. You can add your own here, or create a separate plugin +directory, just the same as Smarty 2. You will still need to create your own +/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and +/templates_c/ are writable. + +The typical way to use Smarty 3 should also look familiar: + +require('Smarty.class.php'); +$smarty = new Smarty; +$smarty->assign('foo','bar'); +$smarty->display('index.tpl'); + + +However, Smarty 3 works completely different on the inside. Smarty 3 is mostly +backward compatible with Smarty 2, except for the following items: + +*) Smarty 3 is PHP 5 only. It will not work with PHP 4. +*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true. +*) Delimiters surrounded by whitespace are no longer treated as Smarty tags. + Therefore, { foo } will not compile as a tag, you must use {foo}. This change + Makes Javascript/CSS easier to work with, eliminating the need for {literal}. + This can be disabled by setting $smarty->auto_literal = false; +*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated + but still work. You will want to update your calls to Smarty 3 for maximum + efficiency. + + +There are many things that are new to Smarty 3. Here are the notable items: + +LEXER/PARSER +============ + +Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this +means Smarty has some syntax additions that make life easier such as in-template +math, shorter/intuitive function parameter options, infinite function recursion, +more accurate error handling, etc. + + +WHAT IS NEW IN SMARTY TEMPLATE SYNTAX +===================================== + +Smarty 3 allows expressions almost anywhere. Expressions can include PHP +functions as long as they are not disabled by the security policy, object +methods and properties, etc. The {math} plugin is no longer necessary but +is still supported for BC. + +Examples: +{$x+$y} will output the sum of x and y. +{$foo = strlen($bar)} function in assignment +{assign var=foo value= $x+$y} in attributes +{$foo = myfunct( ($x+$y)*3 )} as function parameter +{$foo[$x+3]} as array index + +Smarty tags can be used as values within other tags. +Example: {$foo={counter}+3} + +Smarty tags can also be used inside double quoted strings. +Example: {$foo="this is message {counter}"} + +You can define arrays within templates. +Examples: +{assign var=foo value=[1,2,3]} +{assign var=foo value=['y'=>'yellow','b'=>'blue']} +Arrays can be nested. +{assign var=foo value=[1,[9,8],3]} + +There is a new short syntax supported for assigning variables. +Example: {$foo=$bar+2} + +You can assign a value to a specific array element. If the variable exists but +is not an array, it is converted to an array before the new values are assigned. +Examples: +{$foo['bar']=1} +{$foo['bar']['blar']=1} + +You can append values to an array. If the variable exists but is not an array, +it is converted to an array before the new values are assigned. +Example: {$foo[]=1} + +You can use a PHP-like syntax for accessing array elements, as well as the +original "dot" notation. +Examples: +{$foo[1]} normal access +{$foo['bar']} +{$foo['bar'][1]} +{$foo[$x+$x]} index may contain any expression +{$foo[$bar[1]]} nested index +{$foo[section_name]} smarty section access, not array access! + +The original "dot" notation stays, and with improvements. +Examples: +{$foo.a.b.c} => $foo['a']['b']['c'] +{$foo.a.$b.c} => $foo['a'][$b]['c'] with variable index +{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] with expression as index +{$foo.a.{$b.c}} => $foo['a'][$b['c']] with nested index + +note that { and } are used to address ambiguties when nesting the dot syntax. + +Variable names themselves can be variable and contain expressions. +Examples: +$foo normal variable +$foo_{$bar} variable name containing other variable +$foo_{$x+$y} variable name containing expressions +$foo_{$bar}_buh_{$blar} variable name with multiple segments +{$foo_{$x}} will output the variable $foo_1 if $x has a value of 1. + +Object method chaining is implemented. +Example: {$object->method1($x)->method2($y)} + +{for} tag added for looping (replacement for {section} tag): +{for $x=0, $y=count($foo); $x<$y; $x++} .... {/for} +Any number of statements can be used separated by comma as the first +initial expression at {for}. + +{for $x = $start to $end step $step} ... {/for}is in the SVN now . +You can use also +{for $x = $start to $end} ... {/for} +In this case the step value will be automatically 1 or -1 depending on the start and end values. +Instead of $start and $end you can use any valid expression. +Inside the loop the following special vars can be accessed: +$x@iteration = number of iteration +$x@total = total number of iterations +$x@first = true on first iteration +$x@last = true on last iteration + + +The Smarty 2 {section} syntax is still supported. + +New shorter {foreach} syntax to loop over an array. +Example: {foreach $myarray as $var}...{/foreach} + +Within the foreach loop, properties are access via: + +$var@key foreach $var array key +$var@iteration foreach current iteration count (1,2,3...) +$var@index foreach current index count (0,1,2...) +$var@total foreach $var array total +$var@first true on first iteration +$var@last true on last iteration + +The Smarty 2 {foreach} tag syntax is still supported. + +NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo. +If you want to access an array element with index foo, you must use quotes +such as {$bar['foo']}, or use the dot syntax {$bar.foo}. + +while block tag is now implemented: +{while $foo}...{/while} +{while $x lt 10}...{/while} + +Direct access to PHP functions: +Just as you can use PHP functions as modifiers directly, you can now access +PHP functions directly, provided they are permitted by security settings: +{time()} + +There is a new {function}...{/function} block tag to implement a template function. +This enables reuse of code sequences like a plugin function. It can call itself recursively. +Template function must be called with the new {call name=foo...} tag. + +Example: + +Template file: +{function name=menu level=0} +
      + {foreach $data as $entry} + {if is_array($entry)} +
    • {$entry@key}
    • + {call name=menu data=$entry level=$level+1} + {else} +
    • {$entry}
    • + {/if} + {/foreach} +
    +{/function} + +{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' => + ['item3-3-1','item3-3-2']],'item4']} + +{call name=menu data=$menu} + + +Generated output: + * item1 + * item2 + * item3 + o item3-1 + o item3-2 + o item3-3 + + item3-3-1 + + item3-3-2 + * item4 + +The function tag itself must have the "name" attribute. This name is the tag +name when calling the function. The function tag may have any number of +additional attributes. These will be default settings for local variables. + +New {nocache} block function: +{nocache}...{/nocache} will declare a section of the template to be non-cached +when template caching is enabled. + +New nocache attribute: +You can declare variable/function output as non-cached with the nocache attribute. +Examples: + +{$foo nocache=true} +{$foo nocache} /* same */ + +{foo bar="baz" nocache=true} +{foo bar="baz" nocache} /* same */ + +{time() nocache=true} +{time() nocache} /* same */ + +Or you can also assign the variable in your script as nocache: +$smarty->assign('foo',$something,true); // third param is nocache setting +{$foo} /* non-cached */ + +$smarty.current_dir returns the directory name of the current template. + +You can use strings directly as templates with the "string" resource type. +Examples: +$smarty->display('string:This is my template, {$foo}!'); // php +{include file="string:This is my template, {$foo}!"} // template + + + +VARIABLE SCOPE / VARIABLE STORAGE +================================= + +In Smarty 2, all assigned variables were stored within the Smarty object. +Therefore, all variables assigned in PHP were accessible by all subsequent +fetch and display template calls. + +In Smarty 3, we have the choice to assign variables to the main Smarty object, +to user-created data objects, and to user-created template objects. +These objects can be chained. The object at the end of a chain can access all +variables belonging to that template and all variables within the parent objects. +The Smarty object can only be the root of a chain, but a chain can be isolated +from the Smarty object. + +All known Smarty assignment interfaces will work on the data and template objects. + +Besides the above mentioned objects, there is also a special storage area for +global variables. + +A Smarty data object can be created as follows: +$data = $smarty->createData(); // create root data object +$data->assign('foo','bar'); // assign variables as usual +$data->config_load('my.conf'); // load config file + +$data= $smarty->createData($smarty); // create data object having a parent link to +the Smarty object + +$data2= $smarty->createData($data); // create data object having a parent link to +the $data data object + +A template object can be created by using the createTemplate method. It has the +same parameter assignments as the fetch() or display() method. +Function definition: +function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null) + +The first parameter can be a template name, a smarty object or a data object. + +Examples: +$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent +$tpl->assign('foo','bar'); // directly assign variables +$tpl->config_load('my.conf'); // load config file + +$tpl = $smarty->createTemplate('mytpl.tpl',$smarty); // create template having a parent link to the Smarty object +$tpl = $smarty->createTemplate('mytpl.tpl',$data); // create template having a parent link to the $data object + +The standard fetch() and display() methods will implicitly create a template object. +If the $parent parameter is not specified in these method calls, the template object +is will link back to the Smarty object as it's parent. + +If a template is called by an {include...} tag from another template, the +subtemplate links back to the calling template as it's parent. + +All variables assigned locally or from a parent template are accessible. If the +template creates or modifies a variable by using the {assign var=foo...} or +{$foo=...} tags, these new values are only known locally (local scope). When the +template exits, none of the new variables or modifications can be seen in the +parent template(s). This is same behavior as in Smarty 2. + +With Smarty 3, we can assign variables with a scope attribute which allows the +availablility of these new variables or modifications globally (ie in the parent +templates.) + +Possible scopes are local, parent, root and global. +Examples: +{assign var=foo value='bar'} // no scope is specified, the default 'local' +{$foo='bar'} // same, local scope +{assign var=foo value='bar' scope='local'} // same, local scope + +{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object +{$foo='bar' scope='parent'} // (normally the calling template) + +{assign var=foo value='bar' scope='root'} // Values will be exported up to the root object, so they can +{$foo='bar' scope='root'} // be seen from all templates using the same root. + +{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage, +{$foo='bar' scope='global'} // they are available to any and all templates. + + +The scope attribute can also be attached to the {include...} tag. In this case, +the specified scope will be the default scope for all assignments within the +included template. + + +PLUGINS +======= + +Smarty 3 plugins follow the same coding rules as in Smarty 2. +The main difference is that the template object is now passed in place of the smarty object. +The smarty object can be still be accessed through $template->smarty. + +smarty_plugintype_name (array $params, Smarty_Internal_Template $template) + +The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty 2 internals. + + +TEMPLATE INHERITANCE: +===================== + +With template inheritance you can define blocks, which are areas that can be +overridden by child templates, so your templates could look like this: + +parent.tpl: + + + {block name='title'}My site name{/block} + + +

    {block name='page-title'}Default page title{/block}

    +
    + {block name='content'} + Default content + {/block} +
    + + + +child.tpl: +{extends file='parent.tpl'} +{block name='title'} +Child title +{/block} + +grandchild.tpl: +{extends file='child.tpl'} +{block name='title'}Home - {$smarty.block.parent}{/block} +{block name='page-title'}My home{/block} +{block name='content'} + {foreach $images as $img} + {$img.description} + {/foreach} +{/block} + +We redefined all the blocks here, however in the title block we used {$smarty.block.parent}, +which tells Smarty to insert the default content from the parent template in its place. +The content block was overridden to display the image files, and page-title has also be +overridden to display a completely different title. + +If we render grandchild.tpl we will get this: + + + Home - Child title + + +

    My home

    +
    + image + image + image +
    + + + +NOTE: In the child templates everything outside the {extends} or {block} tag sections +is ignored. + +The inheritance tree can be as big as you want (meaning you can extend a file that +extends another one that extends another one and so on..), but be aware that all files +have to be checked for modifications at runtime so the more inheritance the more overhead you add. + +Instead of defining the parent/child relationships with the {extends} tag in the child template you +can use the resource as follow: + +$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl'); + +Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content +is appended or prepended to the child block content. + +{block name='title' append} My title {/block} + + +PHP STREAMS: +============ + +(see online documentation) + +VARIBLE FILTERS: +================ + +(see online documentation) + + +STATIC CLASS ACCESS AND NAMESPACE SUPPORT +========================================= + +You can register a class with optional namespace for the use in the template like: + +$smarty->register->templateClass('foo','name\name2\myclass'); + +In the template you can use it like this: +{foo::method()} etc. + + +======================= + +Please look through it and send any questions/suggestions/etc to the forums. + +http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168 + +Monte and Uwe diff --git a/php_libs/smarty-3.1.33/README.md b/php_libs/smarty-3.1.33/README.md new file mode 100755 index 0000000..24baae4 --- /dev/null +++ b/php_libs/smarty-3.1.33/README.md @@ -0,0 +1,72 @@ +# Smarty 3 template engine +[smarty.net](https://www.smarty.net/) + +## Documentation + +For documentation see +[www.smarty.net/docs/en/](https://www.smarty.net/docs/en/) + +## Distribution repository + +> Smarty 3.1.28 introduces run time template inheritance + +> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality + +Smarty versions 3.1.11 or later are now on github and can be installed with Composer. + + +The "smarty/smarty" package will start at libs/.... subfolder. + +To get the latest stable version of Smarty 3.1 use: + +```json +"require": { + "smarty/smarty": "~3.1" +} +``` + +in your composer.json file. + +To get the trunk version use: + +```json +"require": { + "smarty/smarty": "~3.1@dev" +} +``` + +For a specific version use something like: + +```json +"require": { + "smarty/smarty": "3.1.19" +} +``` + +PHPUnit test can be installed by corresponding composer entries like: + +```json +"require": { + "smarty/smarty-phpunit": "3.1.19" +} +``` + +Similar applies for the lexer/parser generator. + +```json +"require": { + "smarty/smarty-lexer": "3.1.19" +} +``` + +Or you could use: + +```json +"require": { + "smarty/smarty-dev": "3.1.19" +} +``` + +Which is a wrapper to install all 3 packages. + +Composer can also be used for Smarty2 versions 2.6.24 to 2.6.30. diff --git a/php_libs/smarty-3.1.33/SMARTY_2_BC_NOTES.txt b/php_libs/smarty-3.1.33/SMARTY_2_BC_NOTES.txt new file mode 100755 index 0000000..fd36bd3 --- /dev/null +++ b/php_libs/smarty-3.1.33/SMARTY_2_BC_NOTES.txt @@ -0,0 +1,109 @@ += Known incompatibilities with Smarty 2 = + +== Syntax == + +Smarty 3 API has a new syntax. Much of the Smarty 2 syntax is supported +by a wrapper but deprecated. See the README that comes with Smarty 3 for more +information. + +The {$array|@mod} syntax has always been a bit confusing, where an "@" is required +to apply a modifier to an array instead of the individual elements. Normally you +always want the modifier to apply to the variable regardless of its type. In Smarty 3, +{$array|mod} and {$array|@mod} behave identical. It is safe to drop the "@" and the +modifier will still apply to the array. If you really want the modifier to apply to +each array element, you must loop the array in-template, or use a custom modifier that +supports array iteration. Most smarty functions already escape values where necessary +such as {html_options} + +== PHP Version == +Smarty 3 is PHP 5 only. It will not work with PHP 4. + +== {php} Tag == +The {php} tag is disabled by default. The use of {php} tags is +deprecated. It can be enabled with $smarty->allow_php_tag=true. + +But if you scatter PHP code which belongs together into several +{php} tags it may not work any longer. + +== Delimiters and whitespace == +Delimiters surrounded by whitespace are no longer treated as Smarty tags. +Therefore, { foo } will not compile as a tag, you must use {foo}. This change +Makes Javascript/CSS easier to work with, eliminating the need for {literal}. +This can be disabled by setting $smarty->auto_literal = false; + +== Unquoted Strings == +Smarty 2 was a bit more forgiving (and ambiguous) when it comes to unquoted strings +in parameters. Smarty3 is more restrictive. You can still pass strings without quotes +so long as they contain no special characters. (anything outside of A-Za-z0-9_) + +For example filename strings must be quoted + +{include file='path/foo.tpl'} + + +== Extending the Smarty class == +Smarty 3 makes use of the __construct method for initialization. If you are extending +the Smarty class, its constructor is not called implicitly if the your child class defines +its own constructor. In order to run Smarty's constructor, a call to parent::__construct() +within your child constructor is required. + + +class MySmarty extends Smarty { + function __construct() { + parent::__construct(); + + // your initialization code goes here + + } +} + + +== Autoloader == +Smarty 3 does register its own autoloader with spl_autoload_register. If your code has +an existing __autoload function then this function must be explicitly registered on +the __autoload stack. See http://us3.php.net/manual/en/function.spl-autoload-register.php +for further details. + +== Plugin Filenames == +Smarty 3 optionally supports the PHP spl_autoloader. The autoloader requires filenames +to be lower case. Because of this, Smarty plugin file names must also be lowercase. +In Smarty 2, mixed case file names did work. + +== Scope of Special Smarty Variables == +In Smarty 2 the special Smarty variables $smarty.section... and $smarty.foreach... +had global scope. If you had loops with the same name in subtemplates you could accidentally +overwrite values of parent template. + +In Smarty 3 these special Smarty variable have only local scope in the template which +is defining the loop. If you need their value in a subtemplate you have to pass them +as parameter. + +{include file='path/foo.tpl' index=$smarty.section.foo.index} + + +== SMARTY_RESOURCE_CHAR_SET == +Smarty 3 sets the constant SMARTY_RESOURCE_CHAR_SET to utf-8 as default template charset. +This is now used also on modifiers like escape as default charset. If your templates use +other charsets make sure that you define the constant accordingly. Otherwise you may not +get any output. + +== newline at {if} tags == +A \n was added to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source. +If one of the {if} tags is at the line end you will now get a newline in the HTML output. + +== trigger_error() == +The API function trigger_error() has been removed because it did just map to PHP trigger_error. +However it's still included in the Smarty2 API wrapper. + +== Smarty constants == +The constants +SMARTY_PHP_PASSTHRU +SMARTY_PHP_QUOTE +SMARTY_PHP_REMOVE +SMARTY_PHP_ALLOW +have been replaced with class constants +Smarty::PHP_PASSTHRU +Smarty::PHP_QUOTE +Smarty::PHP_REMOVE +Smarty::PHP_ALLOW + diff --git a/php_libs/smarty-3.1.33/SMARTY_3.0_BC_NOTES.txt b/php_libs/smarty-3.1.33/SMARTY_3.0_BC_NOTES.txt new file mode 100755 index 0000000..24bdec6 --- /dev/null +++ b/php_libs/smarty-3.1.33/SMARTY_3.0_BC_NOTES.txt @@ -0,0 +1,24 @@ +== Smarty2 backward compatibility == +All Smarty2 specific API functions and deprecated functionality has been moved +to the SmartyBC class. + +== {php} Tag == +The {php} tag is no longer available in the standard Smarty calls. +The use of {php} tags is deprecated and only available in the SmartyBC class. + +== {include_php} Tag == +The {include_php} tag is no longer available in the standard Smarty calls. +The use of {include_php} tags is deprecated and only available in the SmartyBC class. + +== php template resource == +The support of the php template resource is removed. + +== $cache_dir, $compile_dir, $config_dir, $template_dir access == +The mentioned properties can't be accessed directly any longer. You must use +corresponding getter/setters like addConfigDir(), setConfigDir(), getConfigDir() + +== obsolete Smarty class properties == +The following no longer used properties are removed: +$allow_php_tag +$allow_php_template +$deprecation_notices \ No newline at end of file diff --git a/php_libs/smarty-3.1.33/SMARTY_3.1_NOTES.txt b/php_libs/smarty-3.1.33/SMARTY_3.1_NOTES.txt new file mode 100755 index 0000000..d7c23cc --- /dev/null +++ b/php_libs/smarty-3.1.33/SMARTY_3.1_NOTES.txt @@ -0,0 +1,306 @@ +Smarty 3.1 Notes +================ + +Smarty 3.1 is a departure from 2.0 compatibility. Most notably, all +backward compatibility has been moved to a separate class file named +SmartyBC.class.php. If you require compatibility with 2.0, you will +need to use this class. + +Some differences from 3.0 are also present. 3.1 begins the journey of +requiring setters/getters for property access. So far this is only +implemented on the five directory properties: template_dir, +plugins_dir, configs_dir, compile_dir and cache_dir. These properties +are now protected, it is required to use the setters/getters instead. +That said, direct property access will still work, however slightly +slower since they will now fall through __set() and __get() and in +turn passed through the setter/getter methods. 3.2 will exhibit a full +list of setter/getter methods for all (currently) public properties, +so code-completion in your IDE will work as expected. + +There is absolutely no PHP allowed in templates any more. All +deprecated features of Smarty 2.0 are gone. Again, use the SmartyBC +class if you need any backward compatibility. + +Internal Changes + + Full UTF-8 Compatibility + +The plugins shipped with Smarty 3.1 have been rewritten to fully +support UTF-8 strings if Multibyte String is available. Without +MBString UTF-8 cannot be handled properly. For those rare cases where +templates themselves have to juggle encodings, the new modifiers +to_charset and from_charset may come in handy. + + Plugin API and Performance + +All Plugins (modifiers, functions, blocks, resources, +default_template_handlers, etc) are now receiving the +Smarty_Internal_Template instance, where they were supplied with the +Smarty instance in Smarty 3.0. *. As The Smarty_Internal_Template +mimics the behavior of Smarty, this API simplification should not +require any changes to custom plugins. + +The plugins shipped with Smarty 3.1 have been rewritten for better +performance. Most notably {html_select_date} and {html_select_time} +have been improved vastly. Performance aside, plugins have also been +reviewed and generalized in their API. {html_select_date} and +{html_select_time} now share almost all available options. + +The escape modifier now knows the $double_encode option, which will +prevent entities from being encoded again. + +The capitalize modifier now know the $lc_rest option, which makes sure +all letters following a capital letter are lower-cased. + +The count_sentences modifier now accepts (.?!) as +legitimate endings of a sentence - previously only (.) was +accepted + +The new unescape modifier is there to reverse the effects of the +escape modifier. This applies to the escape formats html, htmlall and +entity. + + default_template_handler_func + +The invocation of $smarty->$default_template_handler_func had to be +altered. Instead of a Smarty_Internal_Template, the fifth argument is +now provided with the Smarty instance. New footprint: + + +/** + * Default Template Handler + * + * called when Smarty's file: resource is unable to load a requested file + * + * @param string $type resource type (e.g. "file", "string", "eval", "resource") + * @param string $name resource name (e.g. "foo/bar.tpl") + * @param string &$content template's content + * @param integer &$modified template's modification time + * @param Smarty $smarty Smarty instance + * @return string|boolean path to file or boolean true if $content and $modified + * have been filled, boolean false if no default template + * could be loaded + */ +function default_template_handler_func($type, $name, &$content, &$modified, Smarty $smarty) { + if (false) { + // return corrected filepath + return "/tmp/some/foobar.tpl"; + } elseif (false) { + // return a template directly + $content = "the template source"; + $modified = time(); + return true; + } else { + // tell smarty that we failed + return false; + } +} + + Stuff done to the compiler + +Many performance improvements have happened internally. One notable +improvement is that all compiled templates are now handled as PHP +functions. This speeds up repeated templates tremendously, as each one +calls an (in-memory) PHP function instead of performing another file +include/scan. + +New Features + + Template syntax + + {block}..{/block} + +The {block} tag has a new hide option flag. It does suppress the block +content if no corresponding child block exists. +EXAMPLE: +parent.tpl +{block name=body hide} child content "{$smarty.block.child}" was +inserted {block} +In the above example the whole block will be suppressed if no child +block "body" is existing. + + {setfilter}..{/setfilter} + +The new {setfilter} block tag allows the definition of filters which +run on variable output. +SYNTAX: +{setfilter filter1|filter2|filter3....} +Smarty3 will lookup up matching filters in the following search order: +1. variable filter plugin in plugins_dir. +2. a valid modifier. A modifier specification will also accept +additional parameter like filter2:'foo' +3. a PHP function +{/setfilter} will turn previous filter setting off again. +{setfilter} tags can be nested. +EXAMPLE: +{setfilter filter1} + {$foo} + {setfilter filter2} + {$bar} + {/setfilter} + {$buh} +{/setfilter} +{$blar} +In the above example filter1 will run on the output of $foo, filter2 +on $bar, filter1 again on $buh and no filter on $blar. +NOTES: +- {$foo nofilter} will suppress the filters +- These filters will run in addition to filters defined by +registerFilter('variable',...), autoLoadFilter('variable',...) and +defined default modifier. +- {setfilter} will effect only the current template, not included +subtemplates. + + Resource API + +Smarty 3.1 features a new approach to resource management. The +Smarty_Resource API allows simple, yet powerful integration of custom +resources for templates and configuration files. It offers simple +functions for loading data from a custom resource (e.g. database) as +well as define new template types adhering to the special +non-compiling (e,g, plain php) and non-compile-caching (e.g. eval: +resource type) resources. + +See demo/plugins/resource.mysql.php for an example custom database +resource. + +Note that old-fashioned registration of callbacks for resource +management has been deprecated but is still possible with SmartyBC. + + CacheResource API + +In line with the Resource API, the CacheResource API offers a more +comfortable handling of output-cache data. With the +Smarty_CacheResource_Custom accessing databases is made simple. With +the introduction of Smarty_CacheResource_KeyValueStore the +implementation of resources like memcache or APC became a no-brainer; +simple hash-based storage systems are now supporting hierarchical +output-caches. + +See demo/plugins/cacheresource.mysql.php for an example custom +database CacheResource. +See demo/plugins/cacheresource.memcache.php for an example custom +memcache CacheResource using the KeyValueStore helper. + +Note that old-fashioned registration of $cache_handler is not possible +anymore. As the functionality had not been ported to Smarty 3.0.x +properly, it has been dropped from 3.1 completely. + +Locking facilities have been implemented to avoid concurrent cache +generation. Enable cache locking by setting +$smarty->cache_locking = true; + + Relative Paths in Templates (File-Resource) + +As of Smarty 3.1 {include file="../foo.tpl"} and {include +file="./foo.tpl"} will resolve relative to the template they're in. +Relative paths are available with {include file="..."} and +{extends file="..."}. As $smarty->fetch('../foo.tpl') and +$smarty->fetch('./foo.tpl') cannot be relative to a template, an +exception is thrown. + + Addressing a specific $template_dir + +Smarty 3.1 introduces the $template_dir index notation. +$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"} +require the template bar.tpl to be loaded from $template_dir['foo']; +Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to +define indexes along with the actual directories. + + Mixing Resources in extends-Resource + +Taking the php extends: template resource one step further, it is now +possible to mix resources within an extends: call like +$smarty->fetch("extends:file:foo.tpl|db:bar.tpl"); + +To make eval: and string: resources available to the inheritance +chain, eval:base64:TPL_STRING and eval:urlencode:TPL_STRING have been +introduced. Supplying the base64 or urlencode flags will trigger +decoding the TPL_STRING in with either base64_decode() or urldecode(). + + extends-Resource in template inheritance + +Template based inheritance may now inherit from php's extends: +resource like {extends file="extends:foo.tpl|db:bar.tpl"}. + + New Smarty property escape_html + +$smarty->escape_html = true will autoescape all template variable +output by calling htmlspecialchars({$output}, ENT_QUOTES, +SMARTY_RESOURCE_CHAR_SET). +NOTE: +This is a compile time option. If you change the setting you must make +sure that the templates get recompiled. + + New option at Smarty property compile_check + +The automatic recompilation of modified templates can now be +controlled by the following settings: +$smarty->compile_check = COMPILECHECK_OFF (false) - template files +will not be checked +$smarty->compile_check = COMPILECHECK_ON (true) - template files will +always be checked +$smarty->compile_check = COMPILECHECK_CACHEMISS - template files will +be checked if caching is enabled and there is no existing cache file +or it has expired + + Automatic recompilation on Smarty version change + +Templates will now be automatically recompiled on Smarty version +changes to avoide incompatibillities in the compiled code. Compiled +template checked against the current setting of the SMARTY_VERSION +constant. + + default_config_handler_func() + +Analogous to the default_template_handler_func() +default_config_handler_func() has been introduced. + + default_plugin_handler_func() + +An optional default_plugin_handler_func() can be defined which gets called +by the compiler on tags which can't be resolved internally or by plugins. +The default_plugin_handler() can map tags to plugins on the fly. + +New getters/setters + +The following setters/getters will be part of the official +documentation, and will be strongly recommended. Direct property +access will still work for the foreseeable future... it will be +transparently routed through the setters/getters, and consequently a +bit slower. + +array|string getTemplateDir( [string $index] ) +replaces $smarty->template_dir; and $smarty->template_dir[$index]; +Smarty setTemplateDir( array|string $path ) +replaces $smarty->template_dir = "foo"; and $smarty->template_dir = +array("foo", "bar"); +Smarty addTemplateDir( array|string $path, [string $index]) +replaces $smarty->template_dir[] = "bar"; and +$smarty->template_dir[$index] = "bar"; + +array|string getConfigDir( [string $index] ) +replaces $smarty->config_dir; and $smarty->config_dir[$index]; +Smarty setConfigDir( array|string $path ) +replaces $smarty->config_dir = "foo"; and $smarty->config_dir = +array("foo", "bar"); +Smarty addConfigDir( array|string $path, [string $index]) +replaces $smarty->config_dir[] = "bar"; and +$smarty->config_dir[$index] = "bar"; + +array getPluginsDir() +replaces $smarty->plugins_dir; +Smarty setPluginsDir( array|string $path ) +replaces $smarty->plugins_dir = "foo"; +Smarty addPluginsDir( array|string $path ) +replaces $smarty->plugins_dir[] = "bar"; + +string getCompileDir() +replaces $smarty->compile_dir; +Smarty setCompileDir( string $path ) +replaces $smarty->compile_dir = "foo"; + +string getCacheDir() +replaces $smarty->cache_dir; +Smarty setCacheDir( string $path ) +replaces $smarty->cache_dir; diff --git a/php_libs/smarty-3.1.33/change_log.txt b/php_libs/smarty-3.1.33/change_log.txt new file mode 100755 index 0000000..70762ed --- /dev/null +++ b/php_libs/smarty-3.1.33/change_log.txt @@ -0,0 +1,3384 @@ +===== 3.1.33 release ===== 12.09.2018 +===== 3.1.33-dev-12 ===== +03.09.2018 + - bugfix {foreach} using new style property access like {$item@property} on + Smarty 2 style named foreach loop could produce errors https://github.com/smarty-php/smarty/issues/484 + +31.08.2018 + - bugfix some custom left and right delimiters like '{^' '^}' did not work + https://github.com/smarty-php/smarty/issues/450 https://github.com/smarty-php/smarty/pull/482 + + - reformating for PSR-2 coding standards https://github.com/smarty-php/smarty/pull/483 + + - bugfix on Windows absolute filepathes did fail if the drive letter was followed by a linux DIRECTORY_SEPARATOR + like C:/ at Smarty > 3.1.33-dev-5 https://github.com/smarty-php/smarty/issues/451 + + - PSR-2 code style fixes for config and template file Lexer/Parser generated with + the Smarty Lexer/Parser generator from https://github.com/smarty-php/smarty-lexer + https://github.com/smarty-php/smarty/pull/483 + +26.08.2018 + - bugfix/enhancement {capture} allow variable as capture block name in Smarty special variable + like $smarty.capture.$foo https://github.com/smarty-php/smarty/issues/478 https://github.com/smarty-php/smarty/pull/481 + +===== 3.1.33-dev-6 ===== +19.08.2018 + - fix PSR-2 coding standards and PHPDoc blocks https://github.com/smarty-php/smarty/pull/452 + https://github.com/smarty-php/smarty/pull/475 + https://github.com/smarty-php/smarty/pull/473 + - bugfix PHP5.2 compatibility https://github.com/smarty-php/smarty/pull/472 + +===== 3.1.33-dev-4 ===== +17.05.2018 + - bugfix strip-block produces different output in Smarty v3.1.32 https://github.com/smarty-php/smarty/issues/436 + - bugfix Smarty::compileAllTemplates ignores `$extension` parameter https://github.com/smarty-php/smarty/issues/437 + https://github.com/smarty-php/smarty/pull/438 + - improvement do not compute total property in {foreach} if not needed https://github.com/smarty-php/smarty/issues/443 + - bugfix plugins may not be loaded when setMergeCompiledIncludes is true https://github.com/smarty-php/smarty/issues/435 + +26.04.2018 + - bugfix regarding Security Vulnerability did not solve the problem under Linux. + Security issue CVE-2018-16831 + +===== 3.1.32 ===== (24.04.2018) +24.04.2018 + - bugfix possible Security Vulnerability in Smarty_Security class. + +26.03.2018 + - bugfix plugins may not be loaded if {function} or {block} tags are executed in nocache mode + https://github.com/smarty-php/smarty/issues/371 + +26.03.2018 + - new feature {parent} = {$smarty.block.parent} {child} = {$smarty.block.child} + +23.03.2018 + - bugfix preg_replace could fail on large content resulting in a blank page https://github.com/smarty-php/smarty/issues/417 + +21.03.2018 + - bugfix {$smarty.section...} used outside {section}{/section} showed incorrect values if {section}{/section} was called inside + another loop https://github.com/smarty-php/smarty/issues/422 + - bugfix short form of {section} attributes did not work https://github.com/smarty-php/smarty/issues/428 + +17.03.2018 + - improvement Smarty::compileAllTemplates() exit with a non-zero status code if max errors is reached https://github.com/smarty-php/smarty/pull/402 + +16.03.2018 + - bugfix extends resource did not work with user defined left/right delimiter https://github.com/smarty-php/smarty/issues/419 + +22.11.2017 + - bugfix {break} and {continue} could fail if {foreach}{/foreach} did contain other + looping tags like {for}, {section} and {while} https://github.com/smarty-php/smarty/issues/323 + +20.11.2017 + - bugfix rework of newline spacing between tag code and template text. + now again identical with Smarty2 (forum topic 26878) + - replacement of " by ' + +05.11.2017 + - lexer/parser optimization + - code cleanup and optimizations + - bugfix {$smarty.section.name.loop} used together with {$smarty.section.name.total} could produce + wrong results (forum topic 27041) + +26.10.2017 + - bugfix Smarty version was not filled in header comment of compiled and cached files + - optimization replace internal Smarty::$ds property by DIRECTORY_SEPARATOR + - deprecate functions Smarty::muteExpectedErrors() and Smarty::unmuteExpectedErrors() + as Smarty does no longer use error suppression like @filemtime(). + for backward compatibility code is moved from Smarty class to an external class and still can be + called. + - correction of PHPDoc blocks + - minor code cleanup + +21.10.2017 + - bugfix custom delimiters could fail since modification of version 3.1.32-dev-23 + https://github.com/smarty-php/smarty/issues/394 + +18.10.2017 + - bugfix fix implementation of unclosed block tag in double quoted string of 12.10.2017 + https://github.com/smarty-php/smarty/issues/396 https://github.com/smarty-php/smarty/issues/397 + https://github.com/smarty-php/smarty/issues/391 https://github.com/smarty-php/smarty/issues/392 + +12.10.2017 + - bugfix $smarty.block.child and $smarty.block.parent could not be used like any + $smarty special variable https://github.com/smarty-php/smarty/issues/393 + - unclosed block tag in double quoted string must throw compiler exception. + https://github.com/smarty-php/smarty/issues/391 https://github.com/smarty-php/smarty/issues/392 + +07.10.2017 + - bugfix modification of 9.8.2017 did fail on some recursive + tag nesting. https://github.com/smarty-php/smarty/issues/389 + +26.8.2017 + - bugfix chained modifier failed when last modifier parameter is a signed value + https://github.com/smarty-php/smarty/issues/327 + - bugfix templates filepath with multibyte characters did not work + https://github.com/smarty-php/smarty/issues/385 + - bugfix {make_nocache} did display code if the template did not contain other nocache code + https://github.com/smarty-php/smarty/issues/369 + +09.8.2017 + - improvement repeated delimiter like {{ and }} will be treated as literal + https://groups.google.com/forum/#!topic/smarty-developers/h9r82Bx4KZw + +05.8.2017 + - bugfix wordwrap modifier could fail if used in nocache code. + converted plugin file shared.mb_wordwrap.php into modifier.mb_wordwrap.php + - cleanup of _getSmartyObj() + +31.7.2017 + - Call clearstatcache() after mkdir() failure https://github.com/smarty-php/smarty/pull/379 + +30.7.2017 + - rewrite mkdir() bugfix to retry automatically see https://github.com/smarty-php/smarty/pull/377 + https://github.com/smarty-php/smarty/pull/379 + +21.7.2017 + - security possible PHP code injection on custom resources at display() or fetch() + calls if the resource does not sanitize the template name + - bugfix fix 'mkdir(): File exists' error on create directory from parallel + processes https://github.com/smarty-php/smarty/pull/377 + - bugfix solve preg_match() hhvm parameter problem https://github.com/smarty-php/smarty/pull/372 + +27.5.2017 + - bugfix change compiled code for registered function and modifiers to called as callable to allow closures + https://github.com/smarty-php/smarty/pull/368, https://github.com/smarty-php/smarty/issues/273 + - bugfix https://github.com/smarty-php/smarty/pull/368 did break the default plugin handler + - improvement replace phpversion() by PHP_VERSION constant. + https://github.com/smarty-php/smarty/pull/363 + +21.5.2017 + - performance store flag for already required shared plugin functions in static variable or + Smarty's $_cache to improve performance when plugins are often called + https://github.com/smarty-php/smarty/commit/51e0d5cd405d764a4ea257d1bac1fb1205f74528#commitcomment-22280086 + - bugfix remove special treatment of classes implementing ArrayAccess in {foreach} + https://github.com/smarty-php/smarty/issues/332 + - bugfix remove deleted files by clear_cache() and clear_compiled_template() from + ACP cache if present, add some is_file() checks to avoid possible warnings on filemtime() + caused by above functions. + https://github.com/smarty-php/smarty/issues/341 + - bugfix version 3.1.31 did fail under PHP 5.2 + https://github.com/smarty-php/smarty/issues/365 + +19.5.2017 + - change properties $accessMap and $obsoleteProperties from private to protected + https://github.com/smarty-php/smarty/issues/351 + - new feature The named capture buffers can now be accessed also as array + See NEWS_FEATURES.txt https://github.com/smarty-php/smarty/issues/366 + - improvement check if ini_get() and ini_set() not disabled + https://github.com/smarty-php/smarty/pull/362 + +24.4.2017 + - fix spelling https://github.com/smarty-php/smarty/commit/e3eda8a5f5653d8abb960eb1bc47e3eca679b1b4#commitcomment-21803095 + +17.4.2017 + - correct generated code on empty() and isset() call, observe change PHP behaviour since PHP 5.5 + https://github.com/smarty-php/smarty/issues/347 + +14.4.2017 + - merge pull requests https://github.com/smarty-php/smarty/pull/349, https://github.com/smarty-php/smarty/pull/322 and https://github.com/smarty-php/smarty/pull/337 to fix spelling and annotation + +13.4.2017 + - bugfix array_merge() parameter should be checked https://github.com/smarty-php/smarty/issues/350 + +===== 3.1.31 ===== (14.12.2016) + 23.11.2016 + - move template object cache into static variables + + 19.11.2016 + - bugfix inheritance root child templates containing nested {block}{/block} could call sub-bock content from parent + template https://github.com/smarty-php/smarty/issues/317 + - change version checking + + 11.11.2016 + - bugfix when Smarty is using a cached template object on Smarty::fetch() or Smarty::isCached() the inheritance data + must be removed https://github.com/smarty-php/smarty/issues/312 + - smaller speed optimization + + 08.11.2016 + - add bootstrap file to load and register Smarty_Autoloader. Change composer.json to make it known to composer + + 07.11.2016 + - optimization of lexer speed https://github.com/smarty-php/smarty/issues/311 + + 27.10.2016 + - bugfix template function definitions array has not been cached between Smarty::fetch() and Smarty::display() calls + https://github.com/smarty-php/smarty/issues/301 + + 23.10.2016 + - improvement/bugfix when Smarty::fetch() is called on a template object the inheritance and tplFunctions property + should be copied to the called template object + + 21.10.2016 + - bugfix for compile locking touched timestamp of old compiled file was not restored on compilation error https://github.com/smarty-php/smarty/issues/308 + + 20.10.2016 + - bugfix nocache code was not removed in cache file when subtemplate did contain PHP short tags in text but no other + nocache code https://github.com/smarty-php/smarty/issues/300 + + 19.10.2016 + - bugfix {make_nocache $var} did fail when variable value did contain '\' https://github.com/smarty-php/smarty/issues/305 + - bugfix {make_nocache $var} remove spaces from variable value https://github.com/smarty-php/smarty/issues/304 + + 12.10.2016 + - bugfix {include} with template names including variable or constants could fail after bugfix from + 28.09.2016 https://github.com/smarty-php/smarty/issues/302 + + 08.10.2016 + - optimization move runtime extension for template functions into Smarty objects + + 29.09.2016 + - improvement new Smarty::$extends_recursion property to disable execution of {extends} in templates called by extends resource + https://github.com/smarty-php/smarty/issues/296 + + 28.09.2016 + - bugfix the generated code for calling a subtemplate must pass the template resource name in single quotes https://github.com/smarty-php/smarty/issues/299 + - bugfix nocache hash was not removed for tags in subtemplates https://github.com/smarty-php/smarty/issues/300 + + 27.09.2016 + - bugfix when Smarty does use an internally cached template object on Smarty::fetch() calls + the template and config variables must be cleared https://github.com/smarty-php/smarty/issues/297 + + 20.09.2016 + - bugfix some $smarty special template variables are no longer accessed as real variable. + using them on calls like {if isset($smarty.foo)} or {if empty($smarty.foo)} will fail + http://www.smarty.net/forums/viewtopic.php?t=26222 + - temporary fix for https://github.com/smarty-php/smarty/issues/293 main reason still under investigation + - improvement new tags {block_parent} {block_child} in template inheritance + + 19.09.2016 + - optimization clear compiled and cached folder completely on detected version change + - cleanup convert cache resource file method clear into runtime extension + + 15.09.2016 + - bugfix assigning a variable in if condition by function like {if $value = array_shift($array)} the function got called twice https://github.com/smarty-php/smarty/issues/291 + - bugfix function plugins called with assign attribute like {foo assign='bar'} did not output returned content because + because assumption was made that it was assigned to a variable https://github.com/smarty-php/smarty/issues/292 + - bugfix calling $smarty->isCached() on a not existing cache file with $smarty->cache_locking = true; could cause a 10 second delay http://www.smarty.net/forums/viewtopic.php?t=26282 + - improvement make Smarty::clearCompiledTemplate() on custom resource independent from changes of templateId computation + + 11.09.2016 + - improvement {math} misleading E_USER_WARNING messages when parameter value = null https://github.com/smarty-php/smarty/issues/288 + - improvement move often used code snippets into methods + - performance Smarty::configLoad() did load unneeded template source object + + 09.09.2016 + - bugfix/optimization {foreach} did not execute the {foreachelse} when iterating empty objects https://github.com/smarty-php/smarty/pull/287 + - bugfix {foreach} must keep the @properties when restoring a saved $item variable as the properties might be used outside {foreach} https://github.com/smarty-php/smarty/issues/267 + - improvement {foreach} observe {break n} and {continue n} nesting levels when restoring saved $item and $key variables + + 08.09.2016 + - bugfix implement wrapper for removed method getConfigVariable() https://github.com/smarty-php/smarty/issues/286 + + 07.09.2016 + - bugfix using nocache like attribute with value true like {plugin nocache=true} did not work https://github.com/smarty-php/smarty/issues/285 + - bugfix uppercase TRUE, FALSE and NULL did not work when security was enabled https://github.com/smarty-php/smarty/issues/282 + - bugfix when {foreach} was looping over an object the total property like {$item@total} did always return 1 https://github.com/smarty-php/smarty/issues/281 + - bugfix {capture}{/capture} did add in 3.1.30 unintended additional blank lines https://github.com/smarty-php/smarty/issues/268 + + 01.09.2016 + - performance require_once should be called only once for shared plugins https://github.com/smarty-php/smarty/issues/280 + + 26.08.2016 + - bugfix change of 23.08.2016 failed on linux when use_include_path = true + + 23.08.2016 + - bugfix remove constant DS as shortcut for DIRECTORY_SEPARATOR as the user may have defined it to something else https://github.com/smarty-php/smarty/issues/277 + + 20.08-2016 + - bugfix {config_load ... scope="global"} shall not throw an arror but fallback to scope="smarty" https://github.com/smarty-php/smarty/issues/274 + - bugfix {make_nocache} failed when using composer autoloader https://github.com/smarty-php/smarty/issues/275 + + 14.08.2016 + - bugfix $smarty_>debugging = true; did E_NOTICE messages when {eval} tag was used https://github.com/smarty-php/smarty/issues/266 + - bugfix Class 'Smarty_Internal_Runtime_ValidateCompiled' not found when upgrading from some older Smarty versions with existing + compiled or cached template files https://github.com/smarty-php/smarty/issues/269 + - optimization remove unneeded call to update acopes when {assign} scope and template scope was local (default) + +===== 3.1.30 ===== (07.08.2016) + + 07.08.2016 + - bugfix update of 04.08.2016 was incomplete + + 05.08.2016 + - bugfix compiling of templates failed when the Smarty delimiter did contain '/' https://github.com/smarty-php/smarty/issues/264 + - updated error checking at template and config default handler + + 04.08.2016 + - improvement move template function source parameter into extension + + 26.07.2016 + - optimization unneeded loading of compiled resource + + 24.07.2016 + - regression this->addPluginsDir('/abs/path/to/dir') adding absolute path without trailing '/' did fail https://github.com/smarty-php/smarty/issues/260 + + 23.07.2016 + - bugfix setTemplateDir('/') and setTemplateDir('') did create wrong absolute filepath https://github.com/smarty-php/smarty/issues/245 + - optimization of filepath normalization + - improvement remove double function declaration in plugin shared.escape_special_cars.php https://github.com/smarty-php/smarty/issues/229 + + 19.07.2016 + - bugfix multiple {include} with relative filepath within {block}{/block} could fail https://github.com/smarty-php/smarty/issues/246 + - bugfix {math} shell injection vulnerability patch provided by Tim Weber + + 18.07.2016 + - bugfix {foreach} if key variable and item@key attribute have been used both the key variable was not updated https://github.com/smarty-php/smarty/issues/254 + - bugfix modifier on plugins like {plugin|modifier ... } did fail when the plugin does return an array https://github.com/smarty-php/smarty/issues/228 + - bugfix avoid opcache_invalidate to result in ErrorException when opcache.restrict_api is not empty https://github.com/smarty-php/smarty/pull/244 + - bugfix multiple {include} with relative filepath within {block}{/block} could fail https://github.com/smarty-php/smarty/issues/246 + + 14.07.2016 + - bugfix wrong parameter on compileAllTemplates() and compileAllConfig() https://github.com/smarty-php/smarty/issues/231 + + 13.07.2016 + - bugfix PHP 7 compatibility on registered compiler plugins https://github.com/smarty-php/smarty/issues/241 + - update testInstall() https://github.com/smarty-php/smarty/issues/248https://github.com/smarty-php/smarty/issues/248 + - bugfix enable debugging could fail when template objects did already exists https://github.com/smarty-php/smarty/issues/237 + - bugfix template function data should be merged when loading subtemplate https://github.com/smarty-php/smarty/issues/240 + - bugfix wrong parameter on compileAllTemplates() https://github.com/smarty-php/smarty/issues/231 + + 12.07.2016 + - bugfix {foreach} item variable must be created also on empty from array https://github.com/smarty-php/smarty/issues/238 and https://github.com/smarty-php/smarty/issues/239 + - bugfix enableSecurity() must init cache flags https://github.com/smarty-php/smarty/issues/247 + + 27.05.2016 + - bugfix/improvement of compileAlltemplates() follow symlinks in template folder (PHP >= 5.3.1) https://github.com/smarty-php/smarty/issues/224 + clear internal cache and expension handler for each template to avoid possible conflicts https://github.com/smarty-php/smarty/issues/231 + + 16.05.2016 + - optimization {foreach} compiler and processing + - broken PHP 5.3 and 5.4 compatibility + + 15.05.2016 + - optimization and cleanup of resource code + + 10.05.2016 + - optimization of inheritance processing + + 07.05.2016 + -bugfix Only variables should be assigned by reference https://github.com/smarty-php/smarty/issues/227 + + 02.05.2016 + - enhancement {block} tag names can now be variable https://github.com/smarty-php/smarty/issues/221 + + 01.05.2016 + - bugfix same relative filepath at {include} called from template in different folders could display wrong sub-template + + 29.04.2016 + - bugfix {strip} remove space on linebreak between html tags https://github.com/smarty-php/smarty/issues/213 + + 24.04.2016 + - bugfix nested {include} with relative file path could fail when called in {block} ... {/block} https://github.com/smarty-php/smarty/issues/218 + + 14.04.2016 + - bugfix special variable {$smarty.capture.name} was not case sensitive on name https://github.com/smarty-php/smarty/issues/210 + - bugfix the default template handler must calculate the source uid https://github.com/smarty-php/smarty/issues/205 + + 13.04.2016 + - bugfix template inheritance status must be saved when calling sub-templates https://github.com/smarty-php/smarty/issues/215 + + 27.03.2016 + - bugfix change of 11.03.2016 cause again {capture} data could not been seen in other templates with {$smarty.capture.name} https://github.com/smarty-php/smarty/issues/153 + + 11.03.2016 + - optimization of capture and security handling + - improvement $smarty->clearCompiledTemplate() should return on recompiled or uncompiled resources + + 10.03.2016 + - optimization of resource processing + + 09.03.2016 + - improvement rework of 'scope' attribute handling see see NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/194 + https://github.com/smarty-php/smarty/issues/186 https://github.com/smarty-php/smarty/issues/179 + - bugfix correct Autoloader update of 2.3.2014 https://github.com/smarty-php/smarty/issues/199 + + 04.03.2016 + - bugfix change from 01.03.2016 will cause $smarty->isCached(..) failure if called multiple time for same template + (forum topic 25935) + + 02.03.2016 + - revert autoloader optimizations because of unexplainable warning when using plugins https://github.com/smarty-php/smarty/issues/199 + + 01.03.2016 + - bugfix template objects must be cached on $smarty->fetch('foo.tpl) calls incase the template is fetched + multiple times (forum topic 25909) + + 25.02.2016 + - bugfix wrong _realpath with 4 or more parent-directories https://github.com/smarty-php/smarty/issues/190 + - optimization of _realpath + - bugfix instanceof expression in template code must be treated as value https://github.com/smarty-php/smarty/issues/191 + + 20.02.2016 + - bugfix {strip} must keep space between hmtl tags. Broken by changes of 10.2.2016 https://github.com/smarty-php/smarty/issues/184 + - new feature/bugfix {foreach}{section} add 'properties' attribute to force compilation of loop properties + see NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/189 + + 19.02.2016 + - revert output buffer flushing on display, echo content again because possible problems when PHP files had + characters (newline} after ?> at file end https://github.com/smarty-php/smarty/issues/187 + + 14.02.2016 + - new tag {make_nocache} read NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/110 + - optimization of sub-template processing + - bugfix using extendsall as default resource and {include} inside {block} tags could produce unexpected results https://github.com/smarty-php/smarty/issues/183 + - optimization of tag attribute compiling + - optimization make compiler tag object cache static for higher compilation speed + + 11.02.2016 + - improvement added KnockoutJS comments to trimwhitespace outputfilter https://github.com/smarty-php/smarty/issues/82 + https://github.com/smarty-php/smarty/pull/181 + + 10.02.2016 + - bugfix {strip} must keep space on output creating smarty tags within html tags https://github.com/smarty-php/smarty/issues/177 + - bugfix wrong precedence on special if conditions like '$foo is ... by $bar' could cause wrong code https://github.com/smarty-php/smarty/issues/178 + - improvement because of ambiguities the inline constant support has been removed from the $foo.bar syntax https://github.com/smarty-php/smarty/issues/149 + - bugfix other {strip} error with output tags between hmtl https://github.com/smarty-php/smarty/issues/180 + + 09.02.2016 + - move some code from parser into compiler + - reformat all code for unique style + - update/bugfix scope attribute handling reworked. Read the newfeatures.txt file + + 05.02.2016 + - improvement internal compiler changes + + 01.02.2016 + - bugfix {foreach} compilation failed when $smarty->merge_compiled_includes = true and pre-filters are used. + + 29.01.2016 + - bugfix implement replacement code for _tag_stack property https://github.com/smarty-php/smarty/issues/151 + + 28.01.2016 + - bugfix allow windows network filepath or wrapper (forum topic 25876) https://github.com/smarty-php/smarty/issues/170 + - bugfix if fetch('foo.tpl') is called on a template object the $parent parameter should default to the calling template object https://github.com/smarty-php/smarty/issues/152 + + 27.01.2016 + - revert bugfix compiling {section} did create warning + - bugfix {$smarty.section.customer.loop} did throw compiler error https://github.com/smarty-php/smarty/issues/161 + update of yesterdays fix + - bugfix string resource could inject code at {block} or inline subtemplates through PHP comments https://github.com/smarty-php/smarty/issues/157 + - bugfix output filters did not observe nocache code flhttps://github.com/smarty-php/smarty/issues/154g https://github.com/smarty-php/smarty/issues/160 + - bugfix {extends} with relative file path did not work https://github.com/smarty-php/smarty/issues/154 + https://github.com/smarty-php/smarty/issues/158 + - bugfix {capture} data could not been seen in other templates with {$smarty.capture.name} https://github.com/smarty-php/smarty/issues/153 + + 26.01.2016 + - improvement observe Smarty::$_CHARSET in debugging console https://github.com/smarty-php/smarty/issues/169 + - bugfix compiling {section} did create warning + - bugfix {$smarty.section.customer.loop} did throw compiler error https://github.com/smarty-php/smarty/issues/161 + + 02.01.2016 + - update scope handling + - optimize block plugin compiler + - improvement runtime checks if registered block plugins are callable + + 01.01.2016 + - remove Smarty::$resource_cache_mode property + + 31.12.2015 + - optimization of {assign}, {if} and {while} compiled code + + 30.12.2015 + - bugfix plugin names starting with "php" did not compile https://github.com/smarty-php/smarty/issues/147 + + 29.12.2015 + - bugfix Smarty::error_reporting was not observed when display() or fetch() was called on template objects https://github.com/smarty-php/smarty/issues/145 + + 28.12.2015 + - optimization of {foreach} code size and processing + + 27.12.2015 + - improve inheritance code + - update external methods + - code fixes + - PHPdoc updates + + 25.12.2015 + - compile {block} tag code and its processing into classes + - optimization replace hhvm extension by inline code + - new feature If ACP is enabled force an apc_compile_file() when compiled or cached template was updated + + 24.12.2015 + - new feature Compiler does now observe the template_dir setting and will create separate compiled files if required + - bugfix post filter did fail on template inheritance https://github.com/smarty-php/smarty/issues/144 + + 23.12.2015 + - optimization move internal method decodeProperties back into template object + - optimization move subtemplate processing back into template object + - new feature Caching does now observe the template_dir setting and will create separate cache files if required + + 22.12.2015 + - change $xxx_dir properties from private to protected in case Smarty class gets extended + - code optimizations + + 21.12.2015 + - bugfix a filepath starting with '/' or '\' on windows should normalize to the root dir + of current working drive https://github.com/smarty-php/smarty/issues/134 + - optimization of filepath normalization + - bugfix {strip} must remove all blanks between html tags https://github.com/smarty-php/smarty/issues/136 + + ===== 3.1.29 ===== (21.12.2015) + 21.12.2015 + - optimization improve speed of filetime checks on extends and extendsall resource + + 20.12.2015 + - bugfix failure when the default resource type was set to 'extendsall' https://github.com/smarty-php/smarty/issues/123 + - update compilation of Smarty special variables + - bugfix add addition check for OS type on normalization of file path https://github.com/smarty-php/smarty/issues/134 + - bugfix the source uid of the extendsall resource must contain $template_dir settings https://github.com/smarty-php/smarty/issues/123 + + 19.12.2015 + - bugfix using $smarty.capture.foo in expressions could fail https://github.com/smarty-php/smarty/pull/138 + - bugfix broken PHP 5.2 compatibility https://github.com/smarty-php/smarty/issues/139 + - remove no longer used code + - improvement make sure that compiled and cache templates never can contain a trailing '?>? + + 18.12.2015 + - bugfix regression when modifier parameter was followed by math https://github.com/smarty-php/smarty/issues/132 + + 17.12.2015 + - bugfix {$smarty.capture.nameFail} did lowercase capture name https://github.com/smarty-php/smarty/issues/135 + - bugfix using {block append/prepend} on same block in multiple levels of inheritance templates could fail (forum topic 25827) + - bugfix text content consisting of just a single '0' like in {if true}0{/if} was suppressed (forum topic 25834) + + 16.12.2015 + - bugfix {foreach} did fail if from atrribute is a Generator class https://github.com/smarty-php/smarty/issues/128 + - bugfix direct access $smarty->template_dir = 'foo'; should call Smarty::setTemplateDir() https://github.com/smarty-php/smarty/issues/121 + + 15.12.2015 + - bugfix {$smarty.cookies.foo} did return the $_COOKIE array not the 'foo' value https://github.com/smarty-php/smarty/issues/122 + - bugfix a call to clearAllCache() and other should clear all internal template object caches (forum topic 25828) + + 14.12.2015 + - bugfix {$smarty.config.foo} broken in 3.1.28 https://github.com/smarty-php/smarty/issues/120 + - bugfix multiple calls of {section} with same name droped E_NOTICE error https://github.com/smarty-php/smarty/issues/118 + + ===== 3.1.28 ===== (13.12.2015) + 13.12.2015 + - bugfix {foreach} and {section} with uppercase characters in name attribute did not work (forum topic 25819) + - bugfix $smarty->debugging_ctrl = 'URL' did not work (forum topic 25811) + - bugfix Debug Console could display incorrect data when using subtemplates + + 09.12.2015 + - bugfix Smarty did fail under PHP 7.0.0 with use_include_path = true; + + 09.12.2015 + - bugfix {strip} should exclude some html tags from stripping, related to fix for https://github.com/smarty-php/smarty/issues/111 + + 08.12.2015 + - bugfix internal template function data got stored in wrong compiled file https://github.com/smarty-php/smarty/issues/114 + + 05.12.2015 + -bugfix {strip} should insert a single space https://github.com/smarty-php/smarty/issues/111 + + 25.11.2015 + -bugfix a left delimter like '[%' did fail on [%$var_[%$variable%]%] (forum topic 25798) + + 02.11.2015 + - bugfix {include} with variable file name like {include file="foo_`$bar`.tpl"} did fail in 3.1.28-dev https://github.com/smarty-php/smarty/issues/102 + + 01.11.2015 + - update config file processing + + 31.10.2015 + - bugfix add missing $trusted_dir property to SmartyBC class (forum topic 25751) + + 29.10.2015 + - improve template scope handling + + 24.10.2015 + - more optimizations of template processing + - bugfix Error when using {include} within {capture} https://github.com/smarty-php/smarty/issues/100 + + 21.10.2015 + - move some code into runtime extensions + + 18.10.2015 + - optimize filepath normalization + - rework of template inheritance + - speed and size optimizations + - bugfix under HHVM temporary cache file must only be created when caches template was updated + - fix compiled code for new {block} assign attribute + - update code generated by template function call handler + + 18.09.2015 + - bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92 + + 17.09.2015 + - bugfix {foreach} first attribute was not correctly reset since commit 05a8fa2 of 02.08.2015 https://github.com/smarty-php/smarty/issues/90 + + 16.09.2015 + - update compiler by moving no longer needed properties, code optimizations and other + + 14.09.2015 + - optimize autoloader + - optimize subtemplate handling + - update template inheritance processing + - move code of {call} processing back into Smarty_Internal_Template class + - improvement invalidate OPCACHE for cleared compiled and cached template files (forum topic 25557) + - bugfix unintended multiple debug windows (forum topic 25699) + + 30.08.2015 + - size optimization move some runtime functions into extension + - optimize inline template processing + - optimization merge inheritance child and parent templates into one compiled template file + + 29.08.2015 + - improvement convert template inheritance into runtime processing + - bugfix {$smarty.block.parent} did always reference the root parent block https://github.com/smarty-php/smarty/issues/68 + + 23.08.2015 + - introduce Smarty::$resource_cache_mode and cache template object of {include} inside loop + - load seldom used Smarty API methods dynamically to reduce memory footprint + - cache template object of {include} if same template is included several times + - convert debug console processing to object + - use output buffers for better performance and less memory usage + - optimize nocache hash processing + - remove not really needed properties + - optimize rendering + - move caching to Smarty::_cache + - remove properties with redundant content + - optimize Smarty::templateExists() + - optimize use_include_path processing + - relocate properties for size optimization + - remove redundant code + - bugfix compiling super globals like {$smarty.get.foo} did fail in the master branch https://github.com/smarty-php/smarty/issues/77 + + 06.08.2015 + - avoid possible circular object references caused by parser/lexer objects + - rewrite compileAll... utility methods + - commit several internal improvements + - bugfix Smarty failed when compile_id did contain "|" + + 03.08.2015 + - rework clear cache methods + - bugfix compileAllConfig() was broken since 3.1.22 because of the changes in config file processing + - improve getIncludePath() to return directory if no file was given + + 02.08.2015 + - optimization and code cleanup of {foreach} and {section} compiler + - rework {capture} compiler + + 01.08.2015 + - update DateTime object can be instance of DateTimeImmutable since PHP5.5 https://github.com/smarty-php/smarty/pull/75 + - improvement show resource type and start of template source instead of uid on eval: and string: resource (forum topic 25630) + + 31.07.2015 + - optimize {foreach} and {section} compiler + + 29.07.2015 + - optimize {section} compiler for speed and size of compiled code + + 28.07.2015 + - update for PHP 7 compatibility + + 26.07.2015 + - improvement impement workaround for HHVM PHP incompatibillity https://github.com/facebook/hhvm/issues/4797 + + 25.07.2015 + - bugfix parser did hang on text starting fetch('foo.tpl') https://github.com/smarty-php/smarty/issues/70 + - improvement Added $limit parameter to regex_replace modifier #71 + - new feature multiple indices on file: resource + + 06.07.2015 + - optimize {block} compilation + - optimization get rid of __get and __set in source object + + 01.07.2015 + - optimize compile check handling + - update {foreach} compiler + - bugfix debugging console did not display string values containing \n, \r or \t correctly https://github.com/smarty-php/smarty/issues/66 + - optimize source resources + + 28.06.2015 + - move $smarty->enableSecurity() into Smarty_Security class + - optimize security isTrustedResourceDir() + - move auto load filter methods into extension + - move $smarty->getTemplateVars() into extension + - move getStreamVariable() into extension + - move $smarty->append() and $smarty->appendByRef() into extension + - optimize autoloader + - optimize file path normalization + - bugfix PATH_SEPARATOR was replaced by mistake in autoloader + - remove redundant code + + 27.06.2015 + - bugfix resolve naming conflict between custom Smarty delimiter '<%' and PHP ASP tags https://github.com/smarty-php/smarty/issues/64 + - update $smarty->_realpath for relative path not starting with './' + - update Smarty security with new realpath handling + - update {include_php} with new realpath handling + - move $smarty->loadPlugin() into extension + - minor compiler optimizations + - bugfix allow function plugins with name ending with 'close' https://github.com/smarty-php/smarty/issues/52 + - rework of $smarty->clearCompiledTemplate() and move it to its own extension + + 19.06.2015 + - improvement allow closures as callback at $smarty->registerFilter() https://github.com/smarty-php/smarty/issues/59 + + ===== 3.1.27===== (18.06.2015) + 18.06.2015 + - bugfix another update on file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56 + + ===== 3.1.26===== (18.06.2015) + 18.06.2015 + - bugfix file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56 + + 17.06.2015 + - bugfix calling a plugin with nocache option but no other attributes like {foo nocache} caused call to undefined function https://github.com/smarty-php/smarty/issues/55 + + ===== 3.1.25===== (15.06.2015) + 15.06.2015 + - optimization of smarty_cachereource_keyvaluestore.php code + + 14.06.2015 + - bugfix a relative sub template path could fail if template_dir path did contain /../ https://github.com/smarty-php/smarty/issues/50 + - optimization rework of path normalization + - bugfix an output tag with variable, modifier followed by an operator like {$foo|modifier+1} did fail https://github.com/smarty-php/smarty/issues/53 + + 13.06.2015 + - bugfix a custom cache resource using smarty_cachereource_keyvaluestore.php did fail if php.ini mbstring.func_overload = 2 (forum topic 25568) + + 11.06.2015 + - bugfix the lexer could hang on very large quoted strings (forum topic 25570) + + 08.06.2015 + - bugfix using {$foo} as array index like $bar.{$foo} or in double quoted string like "some {$foo} thing" failed https://github.com/smarty-php/smarty/issues/49 + + 04.06.2015 + - bugfix possible error message on unset() while compiling {block} tags https://github.com/smarty-php/smarty/issues/46 + + 01.06.2015 + - bugfix including template variables broken since 3.1.22 https://github.com/smarty-php/smarty/issues/47 + + 27.05.2015 + - bugfix {include} with variable file name must not create by default individual cache file (since 3.1.22) https://github.com/smarty-php/smarty/issues/43 + + 24.05.2015 + - bugfix if condition string 'neq' broken due to a typo https://github.com/smarty-php/smarty/issues/42 + + ===== 3.1.24===== (23.05.2015) + 23.05.2015 + - improvement on php_handling to allow very large PHP sections, better error handling + - improvement allow extreme large comment sections (forum 25538) + + 21.05.2015 + - bugfix broken PHP 5.2 compatibility when compiling 1 did compile into wrong code https://github.com/smarty-php/smarty/issues/41 + + 19.05.2015 + - bugfix compiler did overwrite existing variable value when setting the nocache attribute https://github.com/smarty-php/smarty/issues/39 + - bugfix output filter trimwhitespace could run into the pcre.backtrack_limit on large output (code.google issue 220) + - bugfix compiler could run into the pcre.backtrack_limit on larger comment or {php} tag sections (forum 25538) + + 18.05.2015 + - improvement introduce shortcuts in lexer/parser rules for most frequent terms for higher + compilation speed + + 16.05.2015 + - bugfix {php}{/php} did work just for single lines https://github.com/smarty-php/smarty/issues/33 + - improvement remove not needed ?> handling from parser to new compiler module + + 05.05.2015 + - bugfix code could be messed up when {tags} are used in multiple attributes https://github.com/smarty-php/smarty/issues/23 + + 04.05.2015 + - bugfix Smarty_Resource::parseResourceName incompatible with Google AppEngine (https://github.com/smarty-php/smarty/issues/22) + - improvement use is_file() checks to avoid errors suppressed by @ which could still cause problems (https://github.com/smarty-php/smarty/issues/24) + + 28.04.2015 + - bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508) 2nd fix + + 28.04.2015 + - bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508) + + 23.04.2015 + - bugfix a nocache template variable used as parameter at {insert} was by mistake cached + + 20.04.2015 + - bugfix at a template function containing nocache code a parmeter could overwrite a template variable of same name + + 27.03.2015 + - bugfix Smarty_Security->allow_constants=false; did also disable true, false and null (change of 16.03.2015) + - improvement added a whitelist for trusted constants to security Smarty_Security::$trusted_constants (forum topic 25471) + + 20.03.2015 + - bugfix make sure that function properties get saved only in compiled files containing the fuction definition {forum topic 25452} + - bugfix correct update of global variable values on exit of template functions. (reported under Smarty Developers) + + 16.03.2015 + - bugfix problems with {function}{/function} and {call} tags in different subtemplate cache files {forum topic 25452} + - bugfix Smarty_Security->allow_constants=false; did not disallow direct usage of defined constants like {SMARTY_DIR} {forum topic 25457} + - bugfix {block}{/block} tags did not work inside double quoted strings https://github.com/smarty-php/smarty/issues/18 + + + 15.03.2015 + - bugfix $smarty->compile_check must be restored before rendering of a just updated cache file {forum 25452} + + 14.03.2015 + - bugfix {nocache} {/nocache} tags corrupted code when used within a nocache section caused by a nocache template variable. + + - bugfix template functions defined with {function} in an included subtemplate could not be called in nocache + mode with {call... nocache} if the subtemplate had it's own cache file {forum 25452} + + 10.03.2015 + - bugfix {include ... nocache} whith variable file or compile_id attribute was not executed in nocache mode. + + 12.02.2015 + - bugfix multiple Smarty::fetch() of same template when $smarty->merge_compiled_includes = true; could cause function already defined error + + 11.02.2015 + - bugfix recursive {includes} did create E_NOTICE message when $smarty->merge_compiled_includes = true; (github issue #16) + + 22.01.2015 + - new feature security can now control access to static methods and properties + see also NEW_FEATURES.txt + + 21.01.2015 + - bugfix clearCompiledTemplates(), clearAll() and clear() could try to delete whole drive at wrong path permissions because realpath() fail (forum 25397) + - bugfix 'self::' and 'parent::' was interpreted in template syntax as static class + + 04.01.2015 + - push last weeks changes to github + + - different optimizations + - improvement automatically create different versions of compiled templates and config files depending + on property settings. + - optimization restructure template processing by moving code into classes it better belongs to + - optimization restructure config file processing + + 31.12.2014 + - bugfix use function_exists('mb_get_info') for setting Smarty::$_MBSTRING. + Function mb_split could be overloaded depending on php.ini mbstring.func_overload + + + 29.12.2014 + - new feature security can now limit the template nesting level by property $max_template_nesting + see also NEW_FEATURES.txt (forum 25370) + + 29.12.2014 + - new feature security can now disable special $smarty variables listed in property $disabled_special_smarty_vars + see also NEW_FEATURES.txt (forum 25370) + + 27.12.2014 + - bugfix clear internal _is_file_cache when plugins_dir was modified + + 13.12.2014 + - improvement optimization of lexer and parser resulting in a up to 30% higher compiling speed + + 11.12.2014 + - bugfix resolve parser ambiguity between constant print tag {CONST} and other smarty tags after change of 09.12.2014 + + 09.12.2014 + - bugfix variables $null, $true and $false did not work after the change of 12.11.2014 (forum 25342) + - bugfix call of template function by a variable name did not work after latest changes (forum 25342) + + 23.11.2014 + - bugfix a plugin with attached modifier could fail if the tag was immediately followed by another Smarty tag (since 3.1.21) (forum 25326) + + 13.11.2014 + - improvement move autoload code into Autoloader.php. Use Composer autoloader when possible + + 12.11.2014 + - new feature added support of namespaces to template code + + 08.11.2014 - 10.11.2014 + - bugfix subtemplate called in nocache mode could be called with wrong compile_id when it did change on one of the calling templates + - improvement add code of template functions called in nocache mode dynamically to cache file (related to bugfix of 01.11.2014) + - bugfix Debug Console did not include all data from merged compiled subtemplates + + 04.11.2014 + - new feature $smarty->debugging = true; => overwrite existing Debug Console window (old behaviour) + $smarty->debugging = 2; => individual Debug Console window by template name + + 03.11.2014 + - bugfix Debug Console did not show included subtemplates since 3.1.17 (forum 25301) + - bugfix Modifier debug_print_var did not limit recursion or prevent recursive object display at Debug Console + (ATTENTION: parameter order has changed to be able to specify maximum recursion) + - bugfix Debug consol did not include subtemplate information with $smarty->merge_compiled_includes = true + - improvement The template variables are no longer displayed as objects on the Debug Console + - improvement $smarty->createData($parent = null, $name = null) new optional name parameter for display at Debug Console + - addition of some hooks for future extension of Debug Console + + 01.11.2014 + - bugfix and enhancement on subtemplate {include} and template {function} tags. + * Calling a template which has a nocache section could fail if it was called from a cached and a not cached subtemplate. + * Calling the same subtemplate cached and not cached with the $smarty->merge_compiled_includes enabled could cause problems + * Many smaller related changes + + 30.10.2014 + - bugfix access to class constant by object like {$object::CONST} or variable class name {$class::CONST} did not work (forum 25301) + + 26.10.2014 + - bugfix E_NOTICE message was created during compilation when ASP tags '<%' or '%>' are in template source text + - bugfix merge_compiled_includes option failed when caching enables and same subtemplate was included cached and not cached + + ===== 3.1.21 ===== (18.10.2014) + 18.10.2014 + - composer moved to github + + 17.10.2014 + - bugfix on $php_handling security and optimization of smarty_internal_parsetree (Thue Kristensen) + + 16.10.2014 + - bugfix composer.json update + + 15.10.2014 + - bugfix calling a new created cache file with fetch() and Smarty::CACHING_LIFETIME_SAVED multiple times did fail (forum 22350) + + 14.10.2014 + - bugfix any tag placed within " diff --git a/php_libs/smarty-3.1.33/libs/plugins/block.textformat.php b/php_libs/smarty-3.1.33/libs/plugins/block.textformat.php new file mode 100755 index 0000000..5e49463 --- /dev/null +++ b/php_libs/smarty-3.1.33/libs/plugins/block.textformat.php @@ -0,0 +1,121 @@ + + * @throws \SmartyException + */ +function smarty_block_textformat($params, $content, Smarty_Internal_Template $template, &$repeat) +{ + if (is_null($content)) { + return; + } + if (Smarty::$_MBSTRING) { + $template->_checkPlugins( + array( + array( + 'function' => 'smarty_modifier_mb_wordwrap', + 'file' => SMARTY_PLUGINS_DIR . 'modifier.mb_wordwrap.php' + ) + ) + ); + } + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string)$_val; + break; + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int)$_val; + break; + case 'wrap_cut': + $$_key = (bool)$_val; + break; + default: + trigger_error("textformat: unknown attribute '{$_key}'"); + } + } + if ($style === 'email') { + $wrap = 72; + } + // split into paragraphs + $_paragraphs = preg_split('![\r\n]{2}!', $content); + foreach ($_paragraphs as &$_paragraph) { + if (!$_paragraph) { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraph = + preg_replace( + array( + '!\s+!' . Smarty::$_UTF8_MODIFIER, + '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER + ), + array( + ' ', + '' + ), + $_paragraph + ); + // indent first line + if ($indent_first > 0) { + $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph; + } + // wordwrap sentences + if (Smarty::$_MBSTRING) { + $_paragraph = smarty_modifier_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } else { + $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } + // indent lines + if ($indent > 0) { + $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + if ($assign) { + $template->assign($assign, $_output); + } else { + return $_output; + } +} diff --git a/php_libs/smarty-3.1.33/libs/plugins/function.counter.php b/php_libs/smarty-3.1.33/libs/plugins/function.counter.php new file mode 100755 index 0000000..a4129e7 --- /dev/null +++ b/php_libs/smarty-3.1.33/libs/plugins/function.counter.php @@ -0,0 +1,62 @@ + + * @link http://www.smarty.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @return string|null + */ +function smarty_function_counter($params, $template) +{ + static $counters = array(); + $name = (isset($params[ 'name' ])) ? $params[ 'name' ] : 'default'; + if (!isset($counters[ $name ])) { + $counters[ $name ] = array('start' => 1, 'skip' => 1, 'direction' => 'up', 'count' => 1); + } + $counter =& $counters[ $name ]; + if (isset($params[ 'start' ])) { + $counter[ 'start' ] = $counter[ 'count' ] = (int)$params[ 'start' ]; + } + if (!empty($params[ 'assign' ])) { + $counter[ 'assign' ] = $params[ 'assign' ]; + } + if (isset($counter[ 'assign' ])) { + $template->assign($counter[ 'assign' ], $counter[ 'count' ]); + } + if (isset($params[ 'print' ])) { + $print = (bool)$params[ 'print' ]; + } else { + $print = empty($counter[ 'assign' ]); + } + if ($print) { + $retval = $counter[ 'count' ]; + } else { + $retval = null; + } + if (isset($params[ 'skip' ])) { + $counter[ 'skip' ] = $params[ 'skip' ]; + } + if (isset($params[ 'direction' ])) { + $counter[ 'direction' ] = $params[ 'direction' ]; + } + if ($counter[ 'direction' ] === 'down') { + $counter[ 'count' ] -= $counter[ 'skip' ]; + } else { + $counter[ 'count' ] += $counter[ 'skip' ]; + } + return $retval; +} diff --git a/php_libs/smarty-3.1.33/libs/plugins/function.cycle.php b/php_libs/smarty-3.1.33/libs/plugins/function.cycle.php new file mode 100755 index 0000000..07ffcc5 --- /dev/null +++ b/php_libs/smarty-3.1.33/libs/plugins/function.cycle.php @@ -0,0 +1,92 @@ + + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat + * @version 1.3 + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @return string|null + */ +function smarty_function_cycle($params, $template) +{ + static $cycle_vars; + $name = (empty($params[ 'name' ])) ? 'default' : $params[ 'name' ]; + $print = (isset($params[ 'print' ])) ? (bool)$params[ 'print' ] : true; + $advance = (isset($params[ 'advance' ])) ? (bool)$params[ 'advance' ] : true; + $reset = (isset($params[ 'reset' ])) ? (bool)$params[ 'reset' ] : false; + if (!isset($params[ 'values' ])) { + if (!isset($cycle_vars[ $name ][ 'values' ])) { + trigger_error('cycle: missing \'values\' parameter'); + return; + } + } else { + if (isset($cycle_vars[ $name ][ 'values' ]) && $cycle_vars[ $name ][ 'values' ] !== $params[ 'values' ]) { + $cycle_vars[ $name ][ 'index' ] = 0; + } + $cycle_vars[ $name ][ 'values' ] = $params[ 'values' ]; + } + if (isset($params[ 'delimiter' ])) { + $cycle_vars[ $name ][ 'delimiter' ] = $params[ 'delimiter' ]; + } elseif (!isset($cycle_vars[ $name ][ 'delimiter' ])) { + $cycle_vars[ $name ][ 'delimiter' ] = ','; + } + if (is_array($cycle_vars[ $name ][ 'values' ])) { + $cycle_array = $cycle_vars[ $name ][ 'values' ]; + } else { + $cycle_array = explode($cycle_vars[ $name ][ 'delimiter' ], $cycle_vars[ $name ][ 'values' ]); + } + if (!isset($cycle_vars[ $name ][ 'index' ]) || $reset) { + $cycle_vars[ $name ][ 'index' ] = 0; + } + if (isset($params[ 'assign' ])) { + $print = false; + $template->assign($params[ 'assign' ], $cycle_array[ $cycle_vars[ $name ][ 'index' ] ]); + } + if ($print) { + $retval = $cycle_array[ $cycle_vars[ $name ][ 'index' ] ]; + } else { + $retval = null; + } + if ($advance) { + if ($cycle_vars[ $name ][ 'index' ] >= count($cycle_array) - 1) { + $cycle_vars[ $name ][ 'index' ] = 0; + } else { + $cycle_vars[ $name ][ 'index' ]++; + } + } + return $retval; +} diff --git a/php_libs/smarty-3.1.33/libs/plugins/function.fetch.php b/php_libs/smarty-3.1.33/libs/plugins/function.fetch.php new file mode 100755 index 0000000..768761b --- /dev/null +++ b/php_libs/smarty-3.1.33/libs/plugins/function.fetch.php @@ -0,0 +1,204 @@ + + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @throws SmartyException + * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable + */ +function smarty_function_fetch($params, $template) +{ + if (empty($params[ 'file' ])) { + trigger_error('[plugin] fetch parameter \'file\' cannot be empty', E_USER_NOTICE); + return; + } + // strip file protocol + if (stripos($params[ 'file' ], 'file://') === 0) { + $params[ 'file' ] = substr($params[ 'file' ], 7); + } + $protocol = strpos($params[ 'file' ], '://'); + if ($protocol !== false) { + $protocol = strtolower(substr($params[ 'file' ], 0, $protocol)); + } + if (isset($template->smarty->security_policy)) { + if ($protocol) { + // remote resource (or php stream, …) + if (!$template->smarty->security_policy->isTrustedUri($params[ 'file' ])) { + return; + } + } else { + // local file + if (!$template->smarty->security_policy->isTrustedResourceDir($params[ 'file' ])) { + return; + } + } + } + $content = ''; + if ($protocol === 'http') { + // http fetch + if ($uri_parts = parse_url($params[ 'file' ])) { + // set defaults + $host = $server_name = $uri_parts[ 'host' ]; + $timeout = 30; + $accept = 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*'; + $agent = 'Smarty Template Engine ' . Smarty::SMARTY_VERSION; + $referer = ''; + $uri = !empty($uri_parts[ 'path' ]) ? $uri_parts[ 'path' ] : '/'; + $uri .= !empty($uri_parts[ 'query' ]) ? '?' . $uri_parts[ 'query' ] : ''; + $_is_proxy = false; + if (empty($uri_parts[ 'port' ])) { + $port = 80; + } else { + $port = $uri_parts[ 'port' ]; + } + if (!empty($uri_parts[ 'user' ])) { + $user = $uri_parts[ 'user' ]; + } + if (!empty($uri_parts[ 'pass' ])) { + $pass = $uri_parts[ 'pass' ]; + } + // loop through parameters, setup headers + foreach ($params as $param_key => $param_value) { + switch ($param_key) { + case 'file': + case 'assign': + case 'assign_headers': + break; + case 'user': + if (!empty($param_value)) { + $user = $param_value; + } + break; + case 'pass': + if (!empty($param_value)) { + $pass = $param_value; + } + break; + case 'accept': + if (!empty($param_value)) { + $accept = $param_value; + } + break; + case 'header': + if (!empty($param_value)) { + if (!preg_match('![\w\d-]+: .+!', $param_value)) { + trigger_error("[plugin] invalid header format '{$param_value}'", E_USER_NOTICE); + return; + } else { + $extra_headers[] = $param_value; + } + } + break; + case 'proxy_host': + if (!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case 'proxy_port': + if (!preg_match('!\D!', $param_value)) { + $proxy_port = (int)$param_value; + } else { + trigger_error("[plugin] invalid value for attribute '{$param_key }'", E_USER_NOTICE); + return; + } + break; + case 'agent': + if (!empty($param_value)) { + $agent = $param_value; + } + break; + case 'referer': + if (!empty($param_value)) { + $referer = $param_value; + } + break; + case 'timeout': + if (!preg_match('!\D!', $param_value)) { + $timeout = (int)$param_value; + } else { + trigger_error("[plugin] invalid value for attribute '{$param_key}'", E_USER_NOTICE); + return; + } + break; + default: + trigger_error("[plugin] unrecognized attribute '{$param_key}'", E_USER_NOTICE); + return; + } + } + if (!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout); + } else { + $fp = fsockopen($server_name, $port, $errno, $errstr, $timeout); + } + if (!$fp) { + trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE); + return; + } else { + if ($_is_proxy) { + fputs($fp, 'GET ' . $params[ 'file' ] . " HTTP/1.0\r\n"); + } else { + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if (!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if (!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if (!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if (!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if (isset($extra_headers) && is_array($extra_headers)) { + foreach ($extra_headers as $curr_header) { + fputs($fp, $curr_header . "\r\n"); + } + } + if (!empty($user) && !empty($pass)) { + fputs($fp, 'Authorization: BASIC ' . base64_encode("$user:$pass") . "\r\n"); + } + fputs($fp, "\r\n"); + while (!feof($fp)) { + $content .= fgets($fp, 4096); + } + fclose($fp); + $csplit = preg_split("!\r\n\r\n!", $content, 2); + $content = $csplit[ 1 ]; + if (!empty($params[ 'assign_headers' ])) { + $template->assign($params[ 'assign_headers' ], preg_split("!\r\n!", $csplit[ 0 ])); + } + } + } else { + trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE); + return; + } + } else { + $content = @file_get_contents($params[ 'file' ]); + if ($content === false) { + throw new SmartyException("{fetch} cannot read resource '" . $params[ 'file' ] . "'"); + } + } + if (!empty($params[ 'assign' ])) { + $template->assign($params[ 'assign' ], $content); + } else { + return $content; + } +} diff --git a/php_libs/smarty-3.1.33/libs/plugins/function.html_checkboxes.php b/php_libs/smarty-3.1.33/libs/plugins/function.html_checkboxes.php new file mode 100755 index 0000000..302358e --- /dev/null +++ b/php_libs/smarty-3.1.33/libs/plugins/function.html_checkboxes.php @@ -0,0 +1,286 @@ +' output=$names} + * {html_checkboxes values=$ids checked=$checked separator='
    ' output=$names} + * + * Params: + * + * - name (optional) - string default "checkbox" + * - values (required) - array + * - options (optional) - associative array + * - checked (optional) - array default not set + * - separator (optional) - ie
    or   + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * - escape (optional) - escape the content (not value), defaults to true + * + * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt + * @version 1.0 + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @return string + * @uses smarty_function_escape_special_chars() + * @throws \SmartyException + */ +function smarty_function_html_checkboxes($params, Smarty_Internal_Template $template) +{ + $template->_checkPlugins( + array( + array( + 'function' => 'smarty_function_escape_special_chars', + 'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php' + ) + ) + ); + $name = 'checkbox'; + $values = null; + $options = null; + $selected = array(); + $separator = ''; + $escape = true; + $labels = true; + $label_ids = false; + $output = null; + $extra = ''; + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'name': + case 'separator': + $$_key = (string)$_val; + break; + case 'escape': + case 'labels': + case 'label_ids': + $$_key = (bool)$_val; + break; + case 'options': + $$_key = (array)$_val; + break; + case 'values': + case 'output': + $$_key = array_values((array)$_val); + break; + case 'checked': + case 'selected': + if (is_array($_val)) { + $selected = array(); + foreach ($_val as $_sel) { + if (is_object($_sel)) { + if (method_exists($_sel, '__toString')) { + $_sel = smarty_function_escape_special_chars((string)$_sel->__toString()); + } else { + trigger_error( + 'html_checkboxes: selected attribute contains an object of class \'' . + get_class($_sel) . '\' without __toString() method', + E_USER_NOTICE + ); + continue; + } + } else { + $_sel = smarty_function_escape_special_chars((string)$_sel); + } + $selected[ $_sel ] = true; + } + } elseif (is_object($_val)) { + if (method_exists($_val, '__toString')) { + $selected = smarty_function_escape_special_chars((string)$_val->__toString()); + } else { + trigger_error( + 'html_checkboxes: selected attribute is an object of class \'' . get_class($_val) . + '\' without __toString() method', + E_USER_NOTICE + ); + } + } else { + $selected = smarty_function_escape_special_chars((string)$_val); + } + break; + case 'checkboxes': + trigger_error( + 'html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', + E_USER_WARNING + ); + $options = (array)$_val; + break; + case 'assign': + break; + case 'strict': + break; + case 'disabled': + case 'readonly': + if (!empty($params[ 'strict' ])) { + if (!is_scalar($_val)) { + trigger_error( + "html_options: {$_key} attribute must be a scalar, only boolean true or string '{$_key}' will actually add the attribute", + E_USER_NOTICE + ); + } + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + break; + } + // omit break; to fall through! + // no break + default: + if (!is_array($_val)) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; + } else { + trigger_error("html_checkboxes: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE); + } + break; + } + } + if (!isset($options) && !isset($values)) { + return ''; + } /* raise error here? */ + $_html_result = array(); + if (isset($options)) { + foreach ($options as $_key => $_val) { + $_html_result[] = + smarty_function_html_checkboxes_output( + $name, + $_key, + $_val, + $selected, + $extra, + $separator, + $labels, + $label_ids, + $escape + ); + } + } else { + foreach ($values as $_i => $_key) { + $_val = isset($output[ $_i ]) ? $output[ $_i ] : ''; + $_html_result[] = + smarty_function_html_checkboxes_output( + $name, + $_key, + $_val, + $selected, + $extra, + $separator, + $labels, + $label_ids, + $escape + ); + } + } + if (!empty($params[ 'assign' ])) { + $template->assign($params[ 'assign' ], $_html_result); + } else { + return implode("\n", $_html_result); + } +} + +/** + * @param $name + * @param $value + * @param $output + * @param $selected + * @param $extra + * @param $separator + * @param $labels + * @param $label_ids + * @param bool $escape + * + * @return string + */ +function smarty_function_html_checkboxes_output( + $name, + $value, + $output, + $selected, + $extra, + $separator, + $labels, + $label_ids, + $escape = true +) { + $_output = ''; + if (is_object($value)) { + if (method_exists($value, '__toString')) { + $value = (string)$value->__toString(); + } else { + trigger_error( + 'html_options: value is an object of class \'' . get_class($value) . + '\' without __toString() method', + E_USER_NOTICE + ); + return ''; + } + } else { + $value = (string)$value; + } + if (is_object($output)) { + if (method_exists($output, '__toString')) { + $output = (string)$output->__toString(); + } else { + trigger_error( + 'html_options: output is an object of class \'' . get_class($output) . + '\' without __toString() method', + E_USER_NOTICE + ); + return ''; + } + } else { + $output = (string)$output; + } + if ($labels) { + if ($label_ids) { + $_id = smarty_function_escape_special_chars( + preg_replace( + '![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, + '_', + $name . '_' . $value + ) + ); + $_output .= '