<?php

	#########################################################
	/*
	~~~~~~ LIST OF FUNCTIONS ~~~~~~
		getTableList() -- returns an associative array (tableName => tableData, tableData is array(tableCaption, tableDescription, tableIcon)) of tables accessible by current user
		get_table_groups() -- returns an associative array (table_group => tables_array)
		logInMember() -- checks POST login. If not valid, redirects to index.php, else returns TRUE
		getTablePermissions($tn) -- returns an array of permissions allowed for logged member to given table (allowAccess, allowInsert, allowView, allowEdit, allowDelete) -- allowAccess is set to true if any access level is allowed
		get_sql_fields($tn) -- returns the SELECT part of the table view query
		get_sql_from($tn[, true, [, false]]) -- returns the FROM part of the table view query, with full joins (unless third paramaeter is set to true), optionally skipping permissions if true passed as 2nd param.
		get_joined_record($table, $id[, true]) -- returns assoc array of record values for given PK value of given table, with full joins, optionally skipping permissions if true passed as 3rd param.
		get_defaults($table) -- returns assoc array of table fields as array keys and default values (or empty), excluding automatic values as array values
		htmlUserBar() -- returns html code for displaying user login status to be used on top of pages.
		showNotifications($msg, $class) -- returns html code for displaying a notification. If no parameters provided, processes the GET request for possible notifications.
		parseMySQLDate(a, b) -- returns a if valid mysql date, or b if valid mysql date, or today if b is true, or empty if b is false.
		parseCode(code) -- calculates and returns special values to be inserted in automatic fields.
		addFilter(i, filterAnd, filterField, filterOperator, filterValue) -- enforce a filter over data
		clearFilters() -- clear all filters
		loadView($view, $data) -- passes $data to templates/{$view}.php and returns the output
		loadTable($table, $data) -- loads table template, passing $data to it
		filterDropdownBy($filterable, $filterers, $parentFilterers, $parentPKField, $parentCaption, $parentTable, &$filterableCombo) -- applies cascading drop-downs for a lookup field, returns js code to be inserted into the page
		br2nl($text) -- replaces all variations of HTML <br> tags with a new line character
		htmlspecialchars_decode($text) -- inverse of htmlspecialchars()
		entitiesToUTF8($text) -- convert unicode entities (e.g. &#1234;) to actual UTF8 characters, requires multibyte string PHP extension
		func_get_args_byref() -- returns an array of arguments passed to a function, by reference
		permissions_sql($table, $level) -- returns an array containing the FROM and WHERE additions for applying permissions to an SQL query
		error_message($msg[, $back_url]) -- returns html code for a styled error message .. pass explicit false in second param to suppress back button
		toMySQLDate($formattedDate, $sep = datalist_date_separator, $ord = datalist_date_format)
		reIndex(&$arr) -- returns a copy of the given array, with keys replaced by 1-based numeric indices, and values replaced by original keys
		get_embed($provider, $url[, $width, $height, $retrieve]) -- returns embed code for a given url (supported providers: youtube, googlemap)
		check_record_permission($table, $id, $perm = 'view') -- returns true if current user has the specified permission $perm ('view', 'edit' or 'delete') for the given recors, false otherwise
		NavMenus($options) -- returns the HTML code for the top navigation menus. $options is not implemented currently.
		StyleSheet() -- returns the HTML code for included style sheet files to be placed in the <head> section.
		getUploadDir($dir) -- if dir is empty, returns upload dir configured in defaultLang.php, else returns $dir.
		PrepareUploadedFile($FieldName, $MaxSize, $FileTypes='jpg|jpeg|gif|png', $NoRename=false, $dir="") -- validates and moves uploaded file for given $FieldName into the given $dir (or the default one if empty)
		get_home_links($homeLinks, $default_classes, $tgroup) -- process $homeLinks array and return custom links for homepage. Applies $default_classes to links if links have classes defined, and filters links by $tgroup (using '*' matches all table_group values)
		quick_search_html($search_term, $label, $separate_dv = true) -- returns HTML code for the quick search box.
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	*/

	#########################################################

	function getTableList($skip_authentication = false) {
		$arrAccessTables = array();
		$arrTables = array(
			/* 'table_name' => ['table caption', 'homepage description', 'icon', 'table group name'] */   
			'entete' => array('ENTETE', '', 'resources/table_icons/marega.png', 'OPTIONS'),
			'personnels' => array('GESTION DU PERSONNEL', '', 'resources/table_icons/client_account_template.png', 'GESTION RH'),
			'clients' => array('GESTION DES CLIENTS', '', 'resources/table_icons/clients.png', 'CLIENTS'),
			'suivi_client' => array('SUIVI CLIENTS', '', 'resources/table_icons/client_account_template.png', 'CLIENTS'),
			'rendez_vous' => array('RENDEZ-VOUS', '', 'resources/table_icons/clock_history_frame.png', 'GESTION RH'),
			'partenaires' => array('GESTION DES PARTENAIRES', '', 'resources/table_icons/client.png', 'CLIENTS'),
			'packages' => array('PACKAGES', '', 'resources/table_icons/kaaba.png', 'HAJJ / OUMRAH'),
			'oumrah' => array('OUMRAH', '', 'resources/table_icons/kaaba.png', 'HAJJ / OUMRAH'),
			'hajj_oumrah' => array('HAJJ', '', 'resources/table_icons/kaaba.png', 'HAJJ / OUMRAH'),
			'souscriptions' => array('SOUSCRIPTIONS', '', 'resources/table_icons/kaaba.png', 'HAJJ / OUMRAH'),
			'entrees' => array('GESTION', '', 'resources/table_icons/kaaba.png', 'HAJJ / OUMRAH'),
			'sorties' => array('VERSEMENTS', '', 'resources/table_icons/kaaba.png', 'HAJJ / OUMRAH'),
			'agences' => array('GESTION DES AGENCES', '', 'resources/table_icons/bank.png', 'OPTIONS'),
			'gestion_transactions' => array('TRANSACTIONS', '', 'resources/table_icons/price_comparison.png', 'TRANSACTIONS'),
			'billeteries' => array('SUIVI DES TRANSACTIONS', '', 'resources/table_icons/document_copies.png', 'FINANCES'),
			'gestion_changes' => array('CHANGES', '', 'resources/table_icons/conversion_of_currency.png', 'TRANSACTIONS'),
			'changes' => array('SUIVI DES CHANGES', '', 'resources/table_icons/document_copies.png', 'FINANCES'),
			'partages' => array('FICHIERS PARTAG&#201;S', '', 'resources/table_icons/folder_star.png', 'TRANSACTIONS'),
			'type_compagnie' => array('TYPE DE COMPAGNIE', '', 'resources/table_icons/gei (30).png', 'OPTIONS'),
			'compagnies' => array('COMPAGNIES AERIENNES', '', 'resources/table_icons/gei (45).png', 'OPTIONS'),
			'produits_services' => array('PRODUITS & SERVICES', '', 'resources/table_icons/color_management.png', 'OPTIONS'),
			'banques' => array('BANQUES', '', 'resources/table_icons/bank.png', 'OPTIONS'),
			'pays' => array('PAYS', '', 'resources/table_icons/pays.png', 'OPTIONS'),
			'villes' => array('VILLES', '', 'resources/table_icons/villes.png', 'OPTIONS'),
			'items' => array('PARCOURS', '', 'resources/table_icons/advanced_data_grid.png', 'OPTIONS'),
			'type_client' => array('TYPE DE CLIENT', '', 'resources/table_icons/color_wheel.png', 'OPTIONS'),
			'fonctions' => array('FONCTIONS', '', 'resources/table_icons/chair.png', 'OPTIONS'),
			'activites' => array('ACTIVITES', '', 'resources/table_icons/fonction.png', 'OPTIONS'),
			'postes' => array('POSTES', '', 'resources/table_icons/chair.png', 'OPTIONS'),
			'annees' => array('ANNEES', '', 'resources/table_icons/timeline_marker.png', 'OPTIONS'),
			'gds' => array('GDS', '', 'resources/table_icons/gei (31).png', 'OPTIONS'),
			'objets' => array('OBJETS', '', 'resources/table_icons/clipboard_empty.png', 'OPTIONS'),
			'type_rapport' => array('TYPE DE RAPPORTS', '', 'resources/table_icons/application_edit.png', 'OPTIONS'),
			'fidelite' => array('CARTE FIDELITE', '', 'resources/table_icons/award_star_silver_3.png', 'OPTIONS'),
			'pointages' => array('POINTAGES', '', 'resources/table_icons/timesheet.png', 'GESTION RH'),
			'note_de_service' => array('NOTE DE SERVICE', '', 'resources/table_icons/clipboard_empty.png', 'GESTION RH'),
			'redactions' => array('REDACTIONS', '', 'resources/table_icons/document_check_compatibility.png', 'GESTION RH'),
			'rapports_activite' => array('RAPPORT D\'ACTIVIT&#201;', '', 'resources/table_icons/document_prepare.png', 'GESTION RH'),
			'gestion_comptes' => array('COMPTES MV', '', 'resources/table_icons/application_from_storage.png', 'FINANCES'),
			'gestion_comptes_1' => array('COMPTES TIERS', '', 'resources/table_icons/application_from_storage.png', 'FINANCES'),
			'type_comptes' => array('TYPE DE COMPTES', '', 'resources/table_icons/column_four.png', 'FINANCES'),
			'journal' => array('JOURNAL', '', 'resources/table_icons/book_edit.png', 'FINANCES'),
			'liens' => array('LIENS', '', 'resources/table_icons/layout_link.png', 'OPTIONS'),
			'courrier_entrant' => array('COURRIER ENTRANT', '', 'resources/table_icons/documents_email.png', 'COURRIERS'),
			'courrier_sortant' => array('COURRIER SORTANT', '', 'resources/table_icons/email_to_friend.png', 'COURRIERS'),
			'vitae' => array('CURRICULUM VITAE', '', 'resources/table_icons/client_account_template.png', 'GESTION RH'),
			'reunions' => array('GESTION DES REUNIONS', '', 'resources/table_icons/calendar_view_day.png', 'GESTION RH'),
			'item_reunions' => array('SUIVI DES REUNIONS', '', 'resources/table_icons/calendar_edit.png', 'GESTION RH'),
			'statut_partage' => array('STATUT PARTAGES', '', 'resources/table_icons/color_wheel.png', 'OPTIONS'),
			'chequiers' => array('CHEQUIERS', '', 'resources/table_icons/cheque.png', 'FINANCES'),
			'cheques' => array('CHEQUES', '', 'resources/table_icons/cheque.png', 'FINANCES'),
			'gestion_banques' => array('BANQUES', '', 'resources/table_icons/card_bank.png', 'FINANCES'),
			'suivi_banques' => array('BANK STATEMENT', '', 'resources/table_icons/table_money.png', 'FINANCES'),
			'charges_fixe' => array('CHARGES FIXE', '', 'resources/table_icons/table_money.png', 'FINANCES'),
			'caisse' => array('CAISSE', '', 'resources/table_icons/caisse-2.png', 'FINANCES'),
			'type_visa' => array('TYPE VISA', '', 'resources/table_icons/visa-1.png', 'OPTIONS'),
			'libelle_charges_fixe' => array('LIBELLE CHARGES FIXE', '', 'resources/table_icons/align_middle.png', 'OPTIONS'),
			'desc_suivi_banque' => array('DESCRIPTION', '', 'resources/table_icons/align_right.png', 'OPTIONS')
		);
		if($skip_authentication || getLoggedAdmin()) return $arrTables;

		if(is_array($arrTables)) {
			foreach($arrTables as $tn => $tc) {
				$arrPerm = getTablePermissions($tn);
				if($arrPerm[0]) {
					$arrAccessTables[$tn] = $tc;
				}
			}
		}

		return $arrAccessTables;
	}

	#########################################################

	function get_table_groups($skip_authentication = false) {
		$tables = getTableList($skip_authentication);
		$all_groups = array('CLIENTS', 'TRANSACTIONS', 'FINANCES', 'GESTION RH', 'HAJJ / OUMRAH', 'COURRIERS', 'OPTIONS');

		$groups = array();
		foreach($all_groups as $grp) {
			foreach($tables as $tn => $td) {
				if($td[3] && $td[3] == $grp) $groups[$grp][] = $tn;
				if(!$td[3]) $groups[0][] = $tn;
			}
		}

		return $groups;
	}

	#########################################################

	function getTablePermissions($tn) {
		static $table_permissions = array();
		if(isset($table_permissions[$tn])) return $table_permissions[$tn];

		$groupID = getLoggedGroupID();
		$memberID = makeSafe(getLoggedMemberID());
		$res_group = sql("select tableName, allowInsert, allowView, allowEdit, allowDelete from membership_grouppermissions where groupID='{$groupID}'", $eo);
		$res_user = sql("select tableName, allowInsert, allowView, allowEdit, allowDelete from membership_userpermissions where lcase(memberID)='{$memberID}'", $eo);

		while($row = db_fetch_assoc($res_group)) {
			$table_permissions[$row['tableName']] = array(
				1 => intval($row['allowInsert']),
				2 => intval($row['allowView']),
				3 => intval($row['allowEdit']),
				4 => intval($row['allowDelete']),
				'insert' => intval($row['allowInsert']),
				'view' => intval($row['allowView']),
				'edit' => intval($row['allowEdit']),
				'delete' => intval($row['allowDelete'])
			);
		}

		// user-specific permissions, if specified, overwrite his group permissions
		while($row = db_fetch_assoc($res_user)) {
			$table_permissions[$row['tableName']] = array(
				1 => intval($row['allowInsert']),
				2 => intval($row['allowView']),
				3 => intval($row['allowEdit']),
				4 => intval($row['allowDelete']),
				'insert' => intval($row['allowInsert']),
				'view' => intval($row['allowView']),
				'edit' => intval($row['allowEdit']),
				'delete' => intval($row['allowDelete'])
			);
		}

		// if user has any type of access, set 'access' flag
		foreach($table_permissions as $t => $p) {
			$table_permissions[$t]['access'] = $table_permissions[$t][0] = false;

			if($p['insert'] || $p['view'] || $p['edit'] || $p['delete']) {
				$table_permissions[$t]['access'] = $table_permissions[$t][0] = true;
			}
		}

		return $table_permissions[$tn];
	}

	#########################################################

	function get_sql_fields($table_name) {
		$sql_fields = array(
			'entete' => "`entete`.`identete` as 'identete', `entete`.`link_in` as 'link_in', `entete`.`nom` as 'nom', `entete`.`raison_sociale` as 'raison_sociale', `entete`.`description` as 'description', `entete`.`adresse` as 'adresse', `entete`.`telephone` as 'telephone', `entete`.`whatsapp` as 'whatsapp', `entete`.`email` as 'email', `entete`.`site_web` as 'site_web', `entete`.`bp` as 'bp', `entete`.`footer` as 'footer', `entete`.`footer_1` as 'footer_1', `entete`.`footer_2` as 'footer_2', `entete`.`footer_3` as 'footer_3', `entete`.`logo` as 'logo', `entete`.`logop` as 'logop', `entete`.`notice` as 'notice', `entete`.`devise` as 'devise', `entete`.`signataire` as 'signataire', `entete`.`observations` as 'observations', `entete`.`groupe` as 'groupe', `entete`.`agent` as 'agent'",
			'personnels' => "`personnels`.`idpersonnel` as 'idpersonnel', `personnels`.`matricule` as 'matricule', if(`personnels`.`date_recrutement`,date_format(`personnels`.`date_recrutement`,'%d/%m/%Y'),'') as 'date_recrutement', `personnels`.`nom` as 'nom', `personnels`.`prenom` as 'prenom', IF(    CHAR_LENGTH(`pays1`.`pays`), CONCAT_WS('',   `pays1`.`pays`), '') as 'nationalite', `personnels`.`cin` as 'cin', `personnels`.`adresse` as 'adresse', `personnels`.`telephone` as 'telephone', `personnels`.`whatsapp` as 'whatsapp', `personnels`.`email` as 'email', IF(    CHAR_LENGTH(`agences1`.`agence`), CONCAT_WS('',   `agences1`.`agence`), '') as 'agence', IF(    CHAR_LENGTH(`fonctions1`.`fonction`), CONCAT_WS('',   `fonctions1`.`fonction`), '') as 'fonction', IF(    CHAR_LENGTH(`produits_services1`.`produit_service`), CONCAT_WS('',   `produits_services1`.`produit_service`), '') as 'service', IF(    CHAR_LENGTH(`postes1`.`poste`), CONCAT_WS('',   `postes1`.`poste`), '') as 'poste', `personnels`.`photo` as 'photo', `personnels`.`cv` as 'cv', `personnels`.`dossier` as 'dossier', `personnels`.`observations` as 'observations', `personnels`.`groupe` as 'groupe', `personnels`.`agent` as 'agent'",
			'clients' => "`clients`.`idclient` as 'idclient', `clients`.`matricule` as 'matricule', `clients`.`agent` as 'agent', if(`clients`.`date_en`,date_format(`clients`.`date_en`,'%d/%m/%Y %H:%i'),'') as 'date_en', IF(    CHAR_LENGTH(`type_client1`.`type_client`), CONCAT_WS('',   `type_client1`.`type_client`), '') as 'type_client', `clients`.`raison_sociale` as 'raison_sociale', `clients`.`personne_contact` as 'personne_contact', `clients`.`email_pc` as 'email_pc', `clients`.`phone_pc` as 'phone_pc', `clients`.`ninea` as 'ninea', `clients`.`rc` as 'rc', `clients`.`genre` as 'genre', `clients`.`prenom` as 'prenom', `clients`.`nom` as 'nom', `clients`.`cin` as 'cin', IF(    CHAR_LENGTH(`agences1`.`agence`), CONCAT_WS('',   `agences1`.`agence`), '') as 'agence', IF(    CHAR_LENGTH(`pays1`.`pays`), CONCAT_WS('',   `pays1`.`pays`), '') as 'nationalite', IF(    CHAR_LENGTH(`produits_services1`.`produit_service`), CONCAT_WS('',   `produits_services1`.`produit_service`), '') as 'categorie', IF(    CHAR_LENGTH(`fonctions1`.`fonction`), CONCAT_WS('',   `fonctions1`.`fonction`), '') as 'fonction', IF(    CHAR_LENGTH(`activites1`.`activite`), CONCAT_WS('',   `activites1`.`activite`), '') as 'activite', if(`clients`.`date_naissance`,date_format(`clients`.`date_naissance`,'%d/%m/%Y %H:%i'),'') as 'date_naissance', `clients`.`age` as 'age', `clients`.`passport` as 'passport', if(`clients`.`delivre_le`,date_format(`clients`.`delivre_le`,'%d/%m/%Y %H:%i'),'') as 'delivre_le', if(`clients`.`expire_le`,date_format(`clients`.`expire_le`,'%d/%m/%Y %H:%i'),'') as 'expire_le', IF(    CHAR_LENGTH(`pays2`.`pays`), CONCAT_WS('',   `pays2`.`pays`), '') as 'lieu', `clients`.`validite` as 'validite', `clients`.`adresse` as 'adresse', `clients`.`telephone` as 'telephone', `clients`.`whatsapp` as 'whatsapp', `clients`.`urgence` as 'urgence', `clients`.`email` as 'email', `clients`.`compte` as 'compte', IF(    CHAR_LENGTH(`banques1`.`banque`), CONCAT_WS('',   `banques1`.`banque`), '') as 'banque', IF(    CHAR_LENGTH(`fidelite1`.`carte_fidelite`), CONCAT_WS('',   `fidelite1`.`carte_fidelite`), '') as 'carte_fidelite', `clients`.`num_carte` as 'num_carte', `clients`.`signature` as 'signature', `clients`.`photo` as 'photo', `clients`.`dossier` as 'dossier', `clients`.`observations` as 'observations', `clients`.`groupe` as 'groupe'",
			'suivi_client' => "`suivi_client`.`idsuivi_client` as 'idsuivi_client', `suivi_client`.`num_dossier` as 'num_dossier', IF(    CHAR_LENGTH(`clients1`.`nom`), CONCAT_WS('',   `clients1`.`nom`), '') as 'nom', IF(    CHAR_LENGTH(`clients1`.`prenom`), CONCAT_WS('',   `clients1`.`prenom`), '') as 'prenom', IF(    CHAR_LENGTH(`clients1`.`raison_sociale`), CONCAT_WS('',   `clients1`.`raison_sociale`), '') as 'raison_sociale', IF(    CHAR_LENGTH(`clients1`.`telephone`), CONCAT_WS('',   `clients1`.`telephone`), '') as 'telephone', IF(    CHAR_LENGTH(`clients1`.`email`), CONCAT_WS('',   `clients1`.`email`), '') as 'email', IF(    CHAR_LENGTH(`clients1`.`whatsapp`), CONCAT_WS('',   `clients1`.`whatsapp`), '') as 'whatsapp', IF(    CHAR_LENGTH(`produits_services1`.`produit_service`), CONCAT_WS('',   `produits_services1`.`produit_service`), '') as 'service_demande', if(`suivi_client`.`date_demande`,date_format(`suivi_client`.`date_demande`,'%d/%m/%Y'),'') as 'date_demande', `suivi_client`.`statut_service` as 'statut_service', `suivi_client`.`num_visa` as 'num_visa', if(`suivi_client`.`date_debut_visa`,date_format(`suivi_client`.`date_debut_visa`,'%d/%m/%Y'),'') as 'date_debut_visa', if(`suivi_client`.`date_fin_visa`,date_format(`suivi_client`.`date_fin_visa`,'%d/%m/%Y'),'') as 'date_fin_visa', IF(    CHAR_LENGTH(`type_visa1`.`type_visa`), CONCAT_WS('',   `type_visa1`.`type_visa`), '') as 'type_de_visa', `suivi_client`.`observations` as 'observations', `suivi_client`.`groupe` as 'groupe', `suivi_client`.`agent` as 'agent'",
			'rendez_vous' => "`rendez_vous`.`idrv` as 'idrv', `rendez_vous`.`objet` as 'objet', IF(    CHAR_LENGTH(`annees1`.`annee`), CONCAT_WS('',   `annees1`.`annee`), '') as 'annee', `rendez_vous`.`mois` as 'mois', `rendez_vous`.`jour` as 'jour', `rendez_vous`.`heure` as 'heure', `rendez_vous`.`rvs` as 'rvs', `rendez_vous`.`observations` as 'observations', `rendez_vous`.`cree_le` as 'cree_le', `rendez_vous`.`modifie_le` as 'modifie_le', `rendez_vous`.`statut` as 'statut', `rendez_vous`.`groupe` as 'groupe', `rendez_vous`.`agent` as 'agent'",
			'partenaires' => "`partenaires`.`idpartenaires` as 'idpartenaires', if(`partenaires`.`date`,date_format(`partenaires`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`clients1`.`prenom`) || CHAR_LENGTH(`clients1`.`nom`), CONCAT_WS('',   `clients1`.`prenom`, '   ', `clients1`.`nom`), '') as 'nom_prenom', IF(    CHAR_LENGTH(`fonctions1`.`fonction`), CONCAT_WS('',   `fonctions1`.`fonction`), '') as 'fonction', IF(    CHAR_LENGTH(`clients1`.`adresse`), CONCAT_WS('',   `clients1`.`adresse`), '') as 'adresse', IF(    CHAR_LENGTH(`clients1`.`telephone`), CONCAT_WS('',   `clients1`.`telephone`), '') as 'telephone', IF(    CHAR_LENGTH(`clients1`.`email`), CONCAT_WS('',   `clients1`.`email`), '') as 'email', `partenaires`.`observations` as 'observations', `partenaires`.`groupe` as 'groupe', `partenaires`.`agent` as 'agent'",
			'packages' => "`packages`.`idpackage` as 'idpackage', `packages`.`nom` as 'nom', REPLACE(FORMAT(`packages`.`prix`, 0), ',', ' ') as 'prix', `packages`.`observations` as 'observations', `packages`.`groupe` as 'groupe', `packages`.`agent` as 'agent'",
			'oumrah' => "`oumrah`.`idoumrah` as 'idoumrah', IF(    CHAR_LENGTH(`annees1`.`annee`), CONCAT_WS('',   `annees1`.`annee`), '') as 'Pelerinage', `oumrah`.`Prenom` as 'Prenom', `oumrah`.`Nom` as 'Nom', if(`oumrah`.`Datedenaissance`,date_format(`oumrah`.`Datedenaissance`,'%d/%m/%Y'),'') as 'Datedenaissance', `oumrah`.`Lieudenaissance` as 'Lieudenaissance', `oumrah`.`Adresse` as 'Adresse', `oumrah`.`Sexe` as 'Sexe', `oumrah`.`Numropasseport` as 'Numropasseport', `oumrah`.`Remarque` as 'Remarque', `oumrah`.`Tlphoneplerin` as 'Tlphoneplerin', `oumrah`.`Tlphonefamille` as 'Tlphonefamille', `oumrah`.`Personnecontacter` as 'Personnecontacter', `oumrah`.`Squence` as 'Squence', `oumrah`.`Profession` as 'Profession', `oumrah`.`Ethnie` as 'Ethnie', `oumrah`.`Region` as 'Region', REPLACE(FORMAT(`oumrah`.`total_entree`, 0), ',', ' ') as 'total_entree', REPLACE(FORMAT(`oumrah`.`total_sortie`, 0), ',', ' ') as 'total_sortie', REPLACE(FORMAT(`oumrah`.`solde`, 0), ',', ' ') as 'solde', `oumrah`.`groupe` as 'groupe', `oumrah`.`agent` as 'agent'",
			'hajj_oumrah' => "`hajj_oumrah`.`idhajjoumrah` as 'idhajjoumrah', `hajj_oumrah`.`Pelerinage` as 'Pelerinage', `hajj_oumrah`.`Prenom` as 'Prenom', `hajj_oumrah`.`Nom` as 'Nom', if(`hajj_oumrah`.`Datedenaissance`,date_format(`hajj_oumrah`.`Datedenaissance`,'%d/%m/%Y'),'') as 'Datedenaissance', `hajj_oumrah`.`Lieudenaissance` as 'Lieudenaissance', `hajj_oumrah`.`Adresse` as 'Adresse', `hajj_oumrah`.`Sexe` as 'Sexe', `hajj_oumrah`.`Numropasseport` as 'Numropasseport', `hajj_oumrah`.`Remarque` as 'Remarque', `hajj_oumrah`.`Tlphoneplerin` as 'Tlphoneplerin', `hajj_oumrah`.`Tlphonefamille` as 'Tlphonefamille', `hajj_oumrah`.`Personnecontacter` as 'Personnecontacter', `hajj_oumrah`.`Squence` as 'Squence', `hajj_oumrah`.`Profession` as 'Profession', `hajj_oumrah`.`Ethnie` as 'Ethnie', `hajj_oumrah`.`Region` as 'Region', REPLACE(FORMAT(`hajj_oumrah`.`total_entree`, 0), ',', ' ') as 'total_entree', REPLACE(FORMAT(`hajj_oumrah`.`total_sortie`, 0), ',', ' ') as 'total_sortie', REPLACE(FORMAT(`hajj_oumrah`.`solde`, 0), ',', ' ') as 'solde', `hajj_oumrah`.`groupe` as 'groupe', `hajj_oumrah`.`agent` as 'agent'",
			'souscriptions' => "`souscriptions`.`idsouscription` as 'idsouscription', if(`souscriptions`.`date_enr`,date_format(`souscriptions`.`date_enr`,'%d/%m/%Y'),'') as 'date_enr', IF(    CHAR_LENGTH(`hajj_oumrah1`.`Prenom`) || CHAR_LENGTH(`hajj_oumrah1`.`Nom`), CONCAT_WS('',   `hajj_oumrah1`.`Prenom`, '   ', `hajj_oumrah1`.`Nom`), '') as 'pelerin', IF(    CHAR_LENGTH(`oumrah1`.`Prenom`) || CHAR_LENGTH(`oumrah1`.`Nom`), CONCAT_WS('',   `oumrah1`.`Prenom`, '   ', `oumrah1`.`Nom`), '') as 'oumrah', IF(    CHAR_LENGTH(`packages1`.`nom`), CONCAT_WS('',   `packages1`.`nom`), '') as 'package', REPLACE(FORMAT(`souscriptions`.`prix`, 0), ',', ' ') as 'prix', REPLACE(FORMAT(`souscriptions`.`remise`, 0), ',', ' ') as 'remise', REPLACE(FORMAT(`souscriptions`.`net_a_payer`, 0), ',', ' ') as 'net_a_payer', `souscriptions`.`observations` as 'observations', `souscriptions`.`groupe` as 'groupe', `souscriptions`.`agent` as 'agent'",
			'entrees' => "`entrees`.`identrees` as 'identrees', if(`entrees`.`date_entree`,date_format(`entrees`.`date_entree`,'%d/%m/%Y'),'') as 'date_entree', IF(    CHAR_LENGTH(`hajj_oumrah1`.`Prenom`) || CHAR_LENGTH(`hajj_oumrah1`.`Nom`), CONCAT_WS('',   `hajj_oumrah1`.`Prenom`, '   ', `hajj_oumrah1`.`Nom`), '') as 'client', IF(    CHAR_LENGTH(`oumrah1`.`Prenom`) || CHAR_LENGTH(`oumrah1`.`Nom`), CONCAT_WS('',   `oumrah1`.`Prenom`, '   ', `oumrah1`.`Nom`), '') as 'oumrah', IF(    CHAR_LENGTH(`packages1`.`nom`), CONCAT_WS('',   `packages1`.`nom`), '') as 'description', REPLACE(FORMAT(`entrees`.`montant`, 0), ',', ' ') as 'montant', `entrees`.`observations` as 'observations', `entrees`.`groupe` as 'groupe', `entrees`.`agent` as 'agent'",
			'sorties' => "`sorties`.`idsorties` as 'idsorties', if(`sorties`.`date_sortie`,date_format(`sorties`.`date_sortie`,'%d/%m/%Y'),'') as 'date_sortie', IF(    CHAR_LENGTH(`hajj_oumrah1`.`Prenom`) || CHAR_LENGTH(`hajj_oumrah1`.`Nom`), CONCAT_WS('',   `hajj_oumrah1`.`Prenom`, '   ', `hajj_oumrah1`.`Nom`), '') as 'client', IF(    CHAR_LENGTH(`oumrah1`.`Prenom`) || CHAR_LENGTH(`oumrah1`.`Nom`), CONCAT_WS('',   `oumrah1`.`Prenom`, '   ', `oumrah1`.`Nom`), '') as 'oumrah', REPLACE(FORMAT(`sorties`.`montant`, 0), ',', ' ') as 'montant', `sorties`.`observations` as 'observations', `sorties`.`groupe` as 'groupe', `sorties`.`agent` as 'agent'",
			'agences' => "`agences`.`idagence` as 'idagence', `agences`.`agence` as 'agence', `agences`.`adresse` as 'adresse', `agences`.`responsable` as 'responsable', `agences`.`telephone` as 'telephone', `agences`.`observations` as 'observations', `agences`.`groupe` as 'groupe', `agences`.`agent` as 'agent'",
			'gestion_transactions' => "`gestion_transactions`.`idgtransaction` as 'idgtransaction', `gestion_transactions`.`link_in` as 'link_in', `gestion_transactions`.`agent_init` as 'agent_init', `gestion_transactions`.`agent` as 'agent', IF(    CHAR_LENGTH(`clients1`.`matricule`), CONCAT_WS('',   `clients1`.`matricule`), '') as 'matricule', `gestion_transactions`.`numero` as 'numero', if(`gestion_transactions`.`date`,date_format(`gestion_transactions`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`entete1`.`nom`), CONCAT_WS('',   `entete1`.`nom`), '') as 'avec_entete', IF(    CHAR_LENGTH(`entete1`.`raison_sociale`), CONCAT_WS('',   `entete1`.`raison_sociale`), '') as 'rs', `gestion_transactions`.`type` as 'type', IF(    CHAR_LENGTH(`clients1`.`prenom`) || CHAR_LENGTH(`clients1`.`nom`), CONCAT_WS('',   `clients1`.`prenom`, '   ', `clients1`.`nom`), '') as 'nom_prenom', IF(    CHAR_LENGTH(`clients1`.`adresse`), CONCAT_WS('',   `clients1`.`adresse`), '') as 'adclient', IF(    CHAR_LENGTH(`clients1`.`telephone`), CONCAT_WS('',   `clients1`.`telephone`), '') as 'telclient', IF(    CHAR_LENGTH(`clients1`.`email`), CONCAT_WS('',   `clients1`.`email`), '') as 'emclient', IF(    CHAR_LENGTH(`clients1`.`raison_sociale`), CONCAT_WS('',   `clients1`.`raison_sociale`), '') as 'raison_sociale', `gestion_transactions`.`termes` as 'termes', `gestion_transactions`.`fpdf` as 'fpdf', `gestion_transactions`.`fzip` as 'fzip', IF(    CHAR_LENGTH(`entete1`.`devise`), CONCAT_WS('',   `entete1`.`devise`), '') as 'devise', IF(    CHAR_LENGTH(`entete1`.`logo`), CONCAT_WS('',   `entete1`.`logo`), '') as 'logo', IF(    CHAR_LENGTH(`entete1`.`description`), CONCAT_WS('',   `entete1`.`description`), '') as 'description', IF(    CHAR_LENGTH(`entete1`.`adresse`), CONCAT_WS('',   `entete1`.`adresse`), '') as 'adresse', IF(    CHAR_LENGTH(`entete1`.`telephone`), CONCAT_WS('',   `entete1`.`telephone`), '') as 'telephone', IF(    CHAR_LENGTH(`entete1`.`whatsapp`), CONCAT_WS('',   `entete1`.`whatsapp`), '') as 'whatsapp', IF(    CHAR_LENGTH(`entete1`.`email`), CONCAT_WS('',   `entete1`.`email`), '') as 'email', IF(    CHAR_LENGTH(`entete1`.`site_web`), CONCAT_WS('',   `entete1`.`site_web`), '') as 'site_web', IF(    CHAR_LENGTH(`entete1`.`bp`), CONCAT_WS('',   `entete1`.`bp`), '') as 'bp', IF(    CHAR_LENGTH(`entete1`.`footer_3`), CONCAT_WS('',   `entete1`.`footer_3`), '') as 'footer_3', IF(    CHAR_LENGTH(`entete1`.`notice`), CONCAT_WS('',   `entete1`.`notice`), '') as 'notice', IF(    CHAR_LENGTH(`entete1`.`signataire`), CONCAT_WS('',   `entete1`.`signataire`), '') as 'signataire', `gestion_transactions`.`groupe` as 'groupe'",
			'billeteries' => "`billeteries`.`idbilleterie` as 'idbilleterie', IF(    CHAR_LENGTH(`gestion_transactions1`.`link_in`), CONCAT_WS('',   `gestion_transactions1`.`link_in`), '') as 'link_out', `billeteries`.`facture` as 'facture', if(`billeteries`.`date`,date_format(`billeteries`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`produits_services1`.`produit_service`), CONCAT_WS('',   `produits_services1`.`produit_service`), '') as 'service', IF(    CHAR_LENGTH(`clients1`.`prenom`) || CHAR_LENGTH(`clients1`.`nom`), CONCAT_WS('',   `clients1`.`prenom`, '   ', `clients1`.`nom`), '') as 'passager', IF(    CHAR_LENGTH(`gds1`.`gds`), CONCAT_WS('',   `gds1`.`gds`), '') as 'gds', IF(    CHAR_LENGTH(`compagnies1`.`nom_compagnie`) || CHAR_LENGTH(`type_compagnie1`.`type_compangie`), CONCAT_WS('',   `compagnies1`.`nom_compagnie`, '   |   ', `type_compagnie1`.`type_compangie`), '') as 'compagnie', IF(    CHAR_LENGTH(`items1`.`item`), CONCAT_WS('',   `items1`.`item`), '') as 'parcours', IF(    CHAR_LENGTH(`produits_services2`.`produit_service`), CONCAT_WS('',   `produits_services2`.`produit_service`), '') as 'nature_transaction', `billeteries`.`billet` as 'billet', `billeteries`.`dossier` as 'dossier', REPLACE(FORMAT(`billeteries`.`prix_achat`, 0), ',', ' ') as 'prix_achat', REPLACE(FORMAT(`billeteries`.`prix_vente`, 0), ',', ' ') as 'prix_vente', `billeteries`.`qts` as 'qts', REPLACE(FORMAT(`billeteries`.`commission`, 0), ',', ' ') as 'commission', REPLACE(FORMAT(`billeteries`.`frais_service`, 0), ',', ' ') as 'frais_service', REPLACE(FORMAT(`billeteries`.`frais_assurance`, 0), ',', ' ') as 'frais_assurance', `billeteries`.`mtva` as 'mtva', `billeteries`.`tva` as 'tva', `billeteries`.`tht` as 'tht', REPLACE(FORMAT(`billeteries`.`net_compagnie`, 0), ',', ' ') as 'net_compagnie', `billeteries`.`net_a_payer` as 'net_a_payer', `billeteries`.`account` as 'account', `billeteries`.`reste_a_payer` as 'reste_a_payer', `billeteries`.`agent` as 'agent', `billeteries`.`groupe` as 'groupe', `billeteries`.`observations` as 'observations'",
			'gestion_changes' => "`gestion_changes`.`idgchange` as 'idgchange', `gestion_changes`.`link_in` as 'link_in', `gestion_changes`.`agent_init` as 'agent_init', `gestion_changes`.`agent` as 'agent', IF(    CHAR_LENGTH(`clients1`.`matricule`), CONCAT_WS('',   `clients1`.`matricule`), '') as 'matricule', `gestion_changes`.`numero` as 'numero', if(`gestion_changes`.`date`,date_format(`gestion_changes`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`entete1`.`nom`), CONCAT_WS('',   `entete1`.`nom`), '') as 'avec_entete', IF(    CHAR_LENGTH(`entete1`.`raison_sociale`), CONCAT_WS('',   `entete1`.`raison_sociale`), '') as 'rs', `gestion_changes`.`type` as 'type', IF(    CHAR_LENGTH(`clients1`.`prenom`) || CHAR_LENGTH(`clients1`.`nom`), CONCAT_WS('',   `clients1`.`prenom`, '   ', `clients1`.`nom`), '') as 'nom_prenom', IF(    CHAR_LENGTH(`pays1`.`pays`), CONCAT_WS('',   `pays1`.`pays`), '') as 'nationalite', IF(    CHAR_LENGTH(`fonctions1`.`fonction`), CONCAT_WS('',   `fonctions1`.`fonction`), '') as 'profession', IF(    CHAR_LENGTH(`clients1`.`adresse`), CONCAT_WS('',   `clients1`.`adresse`), '') as 'adclient', IF(    CHAR_LENGTH(`clients1`.`telephone`), CONCAT_WS('',   `clients1`.`telephone`), '') as 'telclient', IF(    CHAR_LENGTH(`clients1`.`email`), CONCAT_WS('',   `clients1`.`email`), '') as 'emclient', IF(    CHAR_LENGTH(`clients1`.`raison_sociale`), CONCAT_WS('',   `clients1`.`raison_sociale`), '') as 'raison_sociale', `gestion_changes`.`termes` as 'termes', `gestion_changes`.`fpdf` as 'fpdf', `gestion_changes`.`fzip` as 'fzip', IF(    CHAR_LENGTH(`entete1`.`devise`), CONCAT_WS('',   `entete1`.`devise`), '') as 'devise', IF(    CHAR_LENGTH(`entete1`.`logo`), CONCAT_WS('',   `entete1`.`logo`), '') as 'logo', IF(    CHAR_LENGTH(`entete1`.`description`), CONCAT_WS('',   `entete1`.`description`), '') as 'description', IF(    CHAR_LENGTH(`entete1`.`adresse`), CONCAT_WS('',   `entete1`.`adresse`), '') as 'adresse', IF(    CHAR_LENGTH(`entete1`.`telephone`), CONCAT_WS('',   `entete1`.`telephone`), '') as 'telephone', IF(    CHAR_LENGTH(`entete1`.`whatsapp`), CONCAT_WS('',   `entete1`.`whatsapp`), '') as 'whatsapp', IF(    CHAR_LENGTH(`entete1`.`email`), CONCAT_WS('',   `entete1`.`email`), '') as 'email', IF(    CHAR_LENGTH(`entete1`.`site_web`), CONCAT_WS('',   `entete1`.`site_web`), '') as 'site_web', IF(    CHAR_LENGTH(`entete1`.`bp`), CONCAT_WS('',   `entete1`.`bp`), '') as 'bp', IF(    CHAR_LENGTH(`entete1`.`footer_3`), CONCAT_WS('',   `entete1`.`footer_3`), '') as 'footer_3', IF(    CHAR_LENGTH(`entete1`.`notice`), CONCAT_WS('',   `entete1`.`notice`), '') as 'notice', IF(    CHAR_LENGTH(`entete1`.`signataire`), CONCAT_WS('',   `entete1`.`signataire`), '') as 'signataire', `gestion_changes`.`groupe` as 'groupe'",
			'changes' => "`changes`.`idchange` as 'idchange', IF(    CHAR_LENGTH(`gestion_changes1`.`link_in`), CONCAT_WS('',   `gestion_changes1`.`link_in`), '') as 'link_out', `changes`.`facture` as 'facture', if(`changes`.`date`,date_format(`changes`.`date`,'%d/%m/%Y'),'') as 'date', `changes`.`nature_transaction` as 'nature_transaction', `changes`.`billet` as 'billet', `changes`.`dossier` as 'dossier', REPLACE(FORMAT(`changes`.`prix_achat`, 0), ',', ' ') as 'prix_achat', `changes`.`mtva` as 'mtva', `changes`.`net_a_payer` as 'net_a_payer', REPLACE(FORMAT(`changes`.`net_compagnie`, 0), ',', ' ') as 'net_compagnie', REPLACE(FORMAT(`changes`.`prix_vente`, 0), ',', ' ') as 'prix_vente', `changes`.`qts` as 'qts', REPLACE(FORMAT(`changes`.`commission`, 0), ',', ' ') as 'commission', REPLACE(FORMAT(`changes`.`frais_service`, 0), ',', ' ') as 'frais_service', REPLACE(FORMAT(`changes`.`frais_assurance`, 0), ',', ' ') as 'frais_assurance', `changes`.`tva` as 'tva', `changes`.`tht` as 'tht', `changes`.`account` as 'account', `changes`.`reste_a_payer` as 'reste_a_payer', `changes`.`observations` as 'observations', `changes`.`groupe` as 'groupe', `changes`.`agent` as 'agent'",
			'partages' => "`partages`.`idpartage` as 'idpartage', `partages`.`agent` as 'agent', if(`partages`.`date`,date_format(`partages`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`statut_partage1`.`statut`), CONCAT_WS('',   `statut_partage1`.`statut`), '') as 'statut', IF(    CHAR_LENGTH(`clients1`.`prenom`) || CHAR_LENGTH(`clients1`.`nom`), CONCAT_WS('',   `clients1`.`prenom`, '   ', `clients1`.`nom`), '') as 'client', `partages`.`image` as 'image', `partages`.`word` as 'word', `partages`.`document` as 'document', `partages`.`compresse` as 'compresse', `partages`.`commentaire` as 'commentaire', `partages`.`groupe` as 'groupe'",
			'type_compagnie' => "`type_compagnie`.`idtypecompagnie` as 'idtypecompagnie', `type_compagnie`.`type_compangie` as 'type_compangie', `type_compagnie`.`observations` as 'observations'",
			'compagnies' => "`compagnies`.`idcompagnie` as 'idcompagnie', `compagnies`.`nom_compagnie` as 'nom_compagnie', `compagnies`.`adresse` as 'adresse', `compagnies`.`contact` as 'contact', IF(    CHAR_LENGTH(`type_compagnie1`.`type_compangie`), CONCAT_WS('',   `type_compagnie1`.`type_compangie`), '') as 'type', `compagnies`.`observations` as 'observations'",
			'produits_services' => "`produits_services`.`idps` as 'idps', `produits_services`.`produit_service` as 'produit_service', `produits_services`.`observations` as 'observations'",
			'banques' => "`banques`.`idbanque` as 'idbanque', `banques`.`banque` as 'banque', `banques`.`adresse` as 'adresse', `banques`.`telephone` as 'telephone', `banques`.`email` as 'email', `banques`.`contact` as 'contact', `banques`.`observations` as 'observations'",
			'pays' => "`pays`.`idpays` as 'idpays', `pays`.`pays` as 'pays'",
			'villes' => "`villes`.`idville` as 'idville', `villes`.`ville` as 'ville'",
			'items' => "`items`.`iditem` as 'iditem', `items`.`item` as 'item', `items`.`observation` as 'observation'",
			'type_client' => "`type_client`.`idtype_client` as 'idtype_client', `type_client`.`type_client` as 'type_client', `type_client`.`observation` as 'observation'",
			'fonctions' => "`fonctions`.`idfonction` as 'idfonction', `fonctions`.`fonction` as 'fonction', `fonctions`.`observations` as 'observations'",
			'activites' => "`activites`.`idactivite` as 'idactivite', `activites`.`activite` as 'activite', `activites`.`observations` as 'observations'",
			'postes' => "`postes`.`idposte` as 'idposte', `postes`.`poste` as 'poste', `postes`.`observations` as 'observations'",
			'annees' => "`annees`.`idannee` as 'idannee', `annees`.`annee` as 'annee'",
			'gds' => "`gds`.`idgds` as 'idgds', `gds`.`gds` as 'gds', `gds`.`observations` as 'observations'",
			'objets' => "`objets`.`idobjet` as 'idobjet', `objets`.`objet` as 'objet', `objets`.`obs` as 'obs'",
			'type_rapport' => "`type_rapport`.`idtrpt` as 'idtrpt', `type_rapport`.`type_rapport` as 'type_rapport', `type_rapport`.`obs` as 'obs'",
			'fidelite' => "`fidelite`.`idfidelite` as 'idfidelite', `fidelite`.`carte_fidelite` as 'carte_fidelite', `fidelite`.`observations` as 'observations'",
			'pointages' => "`pointages`.`idpointage` as 'idpointage', if(`pointages`.`date`,date_format(`pointages`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`personnels1`.`nom`) || CHAR_LENGTH(`personnels1`.`prenom`), CONCAT_WS('',   `personnels1`.`nom`, '   ', `personnels1`.`prenom`), '') as 'nom_prenom', IF(    CHAR_LENGTH(`agences1`.`agence`), CONCAT_WS('',   `agences1`.`agence`), '') as 'agence', IF(    CHAR_LENGTH(`fonctions1`.`fonction`), CONCAT_WS('',   `fonctions1`.`fonction`), '') as 'fonction', `pointages`.`arrivee` as 'arrivee', `pointages`.`depart` as 'depart', `pointages`.`obs` as 'obs', `pointages`.`groupe` as 'groupe', `pointages`.`agent` as 'agent'",
			'note_de_service' => "`note_de_service`.`idnote_service` as 'idnote_service', if(`note_de_service`.`date`,date_format(`note_de_service`.`date`,'%d/%m/%Y'),'') as 'date', `note_de_service`.`objet` as 'objet', `note_de_service`.`texte` as 'texte', `note_de_service`.`groupe` as 'groupe', `note_de_service`.`agent` as 'agent'",
			'redactions' => "`redactions`.`idredaction` as 'idredaction', if(`redactions`.`date`,date_format(`redactions`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`objets1`.`objet`), CONCAT_WS('',   `objets1`.`objet`), '') as 'objet', `redactions`.`agent` as 'agent', `redactions`.`redaction` as 'redaction', `redactions`.`obs` as 'obs', `redactions`.`groupe` as 'groupe'",
			'rapports_activite' => "`rapports_activite`.`idrapport` as 'idrapport', if(`rapports_activite`.`date`,date_format(`rapports_activite`.`date`,'%d/%m/%Y'),'') as 'date', `rapports_activite`.`nom_prenom` as 'nom_prenom', IF(    CHAR_LENGTH(`objets1`.`objet`), CONCAT_WS('',   `objets1`.`objet`), '') as 'objet', IF(    CHAR_LENGTH(`type_rapport1`.`type_rapport`), CONCAT_WS('',   `type_rapport1`.`type_rapport`), '') as 'type_rapport', `rapports_activite`.`rapport` as 'rapport', `rapports_activite`.`obs` as 'obs', `rapports_activite`.`groupe` as 'groupe', `rapports_activite`.`agent` as 'agent'",
			'gestion_comptes' => "`gestion_comptes`.`idgestioncompte` as 'idgestioncompte', `gestion_comptes`.`nom_compte` as 'nom_compte', `gestion_comptes`.`num_compte` as 'num_compte', IF(    CHAR_LENGTH(`banques1`.`banque`), CONCAT_WS('',   `banques1`.`banque`), '') as 'banque', IF(    CHAR_LENGTH(`type_comptes1`.`type_compte`), CONCAT_WS('',   `type_comptes1`.`type_compte`), '') as 'type_compte', `gestion_comptes`.`observations` as 'observations', `gestion_comptes`.`groupe` as 'groupe', `gestion_comptes`.`agent` as 'agent'",
			'gestion_comptes_1' => "`gestion_comptes_1`.`idgestioncompte` as 'idgestioncompte', `gestion_comptes_1`.`nom_compte` as 'nom_compte', `gestion_comptes_1`.`num_compte` as 'num_compte', IF(    CHAR_LENGTH(`banques1`.`banque`), CONCAT_WS('',   `banques1`.`banque`), '') as 'banque', IF(    CHAR_LENGTH(`type_comptes1`.`type_compte`), CONCAT_WS('',   `type_comptes1`.`type_compte`), '') as 'type_compte', `gestion_comptes_1`.`observations` as 'observations', `gestion_comptes_1`.`groupe` as 'groupe', `gestion_comptes_1`.`agent` as 'agent'",
			'type_comptes' => "`type_comptes`.`idtypecompte` as 'idtypecompte', `type_comptes`.`type_compte` as 'type_compte', `type_comptes`.`observations` as 'observations'",
			'journal' => "`journal`.`idjournal` as 'idjournal', if(`journal`.`date`,date_format(`journal`.`date`,'%d/%m/%Y'),'') as 'date', `journal`.`libelle` as 'libelle', IF(    CHAR_LENGTH(`gestion_comptes1`.`num_compte`) || CHAR_LENGTH(`gestion_comptes1`.`nom_compte`), CONCAT_WS('',   `gestion_comptes1`.`num_compte`, ' - ', `gestion_comptes1`.`nom_compte`), '') as 'compte_debit', IF(    CHAR_LENGTH(`gestion_comptes2`.`num_compte`) || CHAR_LENGTH(`gestion_comptes2`.`nom_compte`), CONCAT_WS('',   `gestion_comptes2`.`num_compte`, ' - ', `gestion_comptes2`.`nom_compte`), '') as 'compte_credit', REPLACE(FORMAT(`journal`.`tht`, 0), ',', ' ') as 'tht', `journal`.`tva` as 'tva', REPLACE(FORMAT(`journal`.`tva2`, 0), ',', ' ') as 'tva2', REPLACE(FORMAT(`journal`.`ttc`, 0), ',', ' ') as 'ttc', `journal`.`remarques` as 'remarques', `journal`.`groupe` as 'groupe', `journal`.`agent` as 'agent'",
			'liens' => "`liens`.`idlien` as 'idlien', `liens`.`logo` as 'logo', `liens`.`description` as 'description', `liens`.`lien` as 'lien', `liens`.`observations` as 'observations'",
			'courrier_entrant' => "`courrier_entrant`.`idcentrant` as 'idcentrant', if(`courrier_entrant`.`date`,date_format(`courrier_entrant`.`date`,'%d/%m/%Y'),'') as 'date', `courrier_entrant`.`expediteur` as 'expediteur', `courrier_entrant`.`objet` as 'objet', `courrier_entrant`.`destinataire` as 'destinataire', `courrier_entrant`.`piece_jointe` as 'piece_jointe', `courrier_entrant`.`statut` as 'statut', `courrier_entrant`.`remarques` as 'remarques', `courrier_entrant`.`groupe` as 'groupe', `courrier_entrant`.`agent` as 'agent'",
			'courrier_sortant' => "`courrier_sortant`.`idcsortant` as 'idcsortant', if(`courrier_sortant`.`date`,date_format(`courrier_sortant`.`date`,'%d/%m/%Y'),'') as 'date', `courrier_sortant`.`expediteur` as 'expediteur', `courrier_sortant`.`objet` as 'objet', `courrier_sortant`.`destinataire` as 'destinataire', `courrier_sortant`.`piece_jointe` as 'piece_jointe', `courrier_sortant`.`statut` as 'statut', `courrier_sortant`.`remarques` as 'remarques', `courrier_sortant`.`groupe` as 'groupe', `courrier_sortant`.`agent` as 'agent'",
			'vitae' => "`vitae`.`idvitae` as 'idvitae', if(`vitae`.`date`,date_format(`vitae`.`date`,'%d/%m/%Y'),'') as 'date', `vitae`.`candidat` as 'candidat', `vitae`.`domaine` as 'domaine', `vitae`.`dossier` as 'dossier', `vitae`.`statut` as 'statut', `vitae`.`photo` as 'photo', `vitae`.`observations` as 'observations', `vitae`.`groupe` as 'groupe', `vitae`.`agent` as 'agent'",
			'reunions' => "`reunions`.`idreunion` as 'idreunion', `reunions`.`link_in` as 'link_in', IF(    CHAR_LENGTH(`entete1`.`nom`), CONCAT_WS('',   `entete1`.`nom`), '') as 'avec_entete', `reunions`.`ordre_jour` as 'ordre_jour', if(`reunions`.`date`,date_format(`reunions`.`date`,'%d/%m/%Y'),'') as 'date', `reunions`.`temps` as 'temps', `reunions`.`duree` as 'duree', `reunions`.`lieu` as 'lieu', `reunions`.`objectif` as 'objectif', `reunions`.`fpdf` as 'fpdf', `reunions`.`fzip` as 'fzip', IF(    CHAR_LENGTH(`entete1`.`raison_sociale`), CONCAT_WS('',   `entete1`.`raison_sociale`), '') as 'rs', IF(    CHAR_LENGTH(`entete1`.`devise`), CONCAT_WS('',   `entete1`.`devise`), '') as 'devise', IF(    CHAR_LENGTH(`entete1`.`logo`), CONCAT_WS('',   `entete1`.`logo`), '') as 'logo', IF(    CHAR_LENGTH(`entete1`.`description`), CONCAT_WS('',   `entete1`.`description`), '') as 'description', IF(    CHAR_LENGTH(`entete1`.`adresse`), CONCAT_WS('',   `entete1`.`adresse`), '') as 'adresse', IF(    CHAR_LENGTH(`entete1`.`telephone`), CONCAT_WS('',   `entete1`.`telephone`), '') as 'telephone', IF(    CHAR_LENGTH(`entete1`.`whatsapp`), CONCAT_WS('',   `entete1`.`whatsapp`), '') as 'whatsapp', IF(    CHAR_LENGTH(`entete1`.`email`), CONCAT_WS('',   `entete1`.`email`), '') as 'email', IF(    CHAR_LENGTH(`entete1`.`site_web`), CONCAT_WS('',   `entete1`.`site_web`), '') as 'site_web', IF(    CHAR_LENGTH(`entete1`.`bp`), CONCAT_WS('',   `entete1`.`bp`), '') as 'bp', IF(    CHAR_LENGTH(`entete1`.`footer_3`), CONCAT_WS('',   `entete1`.`footer_3`), '') as 'footer_3', IF(    CHAR_LENGTH(`entete1`.`notice`), CONCAT_WS('',   `entete1`.`notice`), '') as 'notice', IF(    CHAR_LENGTH(`entete1`.`signataire`), CONCAT_WS('',   `entete1`.`signataire`), '') as 'signataire', `reunions`.`groupe` as 'groupe', `reunions`.`agent` as 'agent'",
			'item_reunions' => "`item_reunions`.`iditemreunion` as 'iditemreunion', IF(    CHAR_LENGTH(`reunions1`.`link_in`), CONCAT_WS('',   `reunions1`.`link_in`), '') as 'link_out', `item_reunions`.`activite` as 'activite', `item_reunions`.`temps` as 'temps', `item_reunions`.`responsable` as 'responsable', `item_reunions`.`objectif` as 'objectif', `item_reunions`.`observations` as 'observations'",
			'statut_partage' => "`statut_partage`.`idstatutpartage` as 'idstatutpartage', `statut_partage`.`statut` as 'statut', `statut_partage`.`observations` as 'observations'",
			'chequiers' => "`chequiers`.`idchequier` as 'idchequier', if(`chequiers`.`date`,date_format(`chequiers`.`date`,'%d/%m/%Y'),'') as 'date', `chequiers`.`lot_num` as 'lot_num', `chequiers`.`lot_qts` as 'lot_qts', IF(    CHAR_LENGTH(`gestion_comptes1`.`num_compte`), CONCAT_WS('',   `gestion_comptes1`.`num_compte`), '') as 'compte', IF(    CHAR_LENGTH(`banques1`.`banque`), CONCAT_WS('',   `banques1`.`banque`), '') as 'banque', `chequiers`.`groupe` as 'groupe', `chequiers`.`agent` as 'agent'",
			'cheques' => "`cheques`.`idcheque` as 'idcheque', `cheques`.`num` as 'num', IF(    CHAR_LENGTH(`chequiers1`.`idchequier`), CONCAT_WS('',   `chequiers1`.`idchequier`), '') as 'chequier', `cheques`.`groupe` as 'groupe', `cheques`.`agent` as 'agent'",
			'gestion_banques' => "`gestion_banques`.`idgestion_banque` as 'idgestion_banque', if(`gestion_banques`.`date`,date_format(`gestion_banques`.`date`,'%d/%m/%Y'),'') as 'date', `gestion_banques`.`mouvement` as 'mouvement', `gestion_banques`.`libelle` as 'libelle', IF(    CHAR_LENGTH(`gestion_comptes_11`.`nom_compte`), CONCAT_WS('',   `gestion_comptes_11`.`nom_compte`), '') as 'compte_emetteur', IF(    CHAR_LENGTH(`gestion_comptes_11`.`num_compte`), CONCAT_WS('',   `gestion_comptes_11`.`num_compte`), '') as 'numero', IF(    CHAR_LENGTH(`banques1`.`banque`), CONCAT_WS('',   `banques1`.`banque`), '') as 'banque', IF(    CHAR_LENGTH(`gestion_comptes1`.`nom_compte`), CONCAT_WS('',   `gestion_comptes1`.`nom_compte`), '') as 'compte_beneficiaire', IF(    CHAR_LENGTH(`gestion_comptes1`.`num_compte`), CONCAT_WS('',   `gestion_comptes1`.`num_compte`), '') as 'numero_cb', IF(    CHAR_LENGTH(`banques2`.`banque`), CONCAT_WS('',   `banques2`.`banque`), '') as 'banque_cb', IF(    CHAR_LENGTH(`cheques1`.`num`), CONCAT_WS('',   `cheques1`.`num`), '') as 'cheque_mv', `gestion_banques`.`cheque_ce` as 'cheque_ce', REPLACE(FORMAT(`gestion_banques`.`depense`, 0), ',', ' ') as 'depense', REPLACE(FORMAT(`gestion_banques`.`recette`, 0), ',', ' ') as 'recette', REPLACE(FORMAT(`gestion_banques`.`solde`, 0), ',', ' ') as 'solde', `gestion_banques`.`cheque` as 'cheque', `gestion_banques`.`observations` as 'observations', `gestion_banques`.`groupe` as 'groupe', `gestion_banques`.`agent` as 'agent'",
			'suivi_banques' => "`suivi_banques`.`idsb` as 'idsb', if(`suivi_banques`.`date`,date_format(`suivi_banques`.`date`,'%d/%m/%Y'),'') as 'date', `suivi_banques`.`mouvement` as 'mouvement', IF(    CHAR_LENGTH(`desc_suivi_banque1`.`description`), CONCAT_WS('',   `desc_suivi_banque1`.`description`), '') as 'description', `suivi_banques`.`reference` as 'reference', REPLACE(FORMAT(`suivi_banques`.`debits`, 0), ',', ' ') as 'debits', REPLACE(FORMAT(`suivi_banques`.`credits`, 0), ',', ' ') as 'credits', REPLACE(FORMAT(`suivi_banques`.`balance`, 0), ',', ' ') as 'balance', `suivi_banques`.`observations` as 'observations', `suivi_banques`.`groupe` as 'groupe', `suivi_banques`.`agent` as 'agent'",
			'charges_fixe' => "`charges_fixe`.`idcf` as 'idcf', if(`charges_fixe`.`date`,date_format(`charges_fixe`.`date`,'%d/%m/%Y'),'') as 'date', IF(    CHAR_LENGTH(`libelle_charges_fixe1`.`libelle`), CONCAT_WS('',   `libelle_charges_fixe1`.`libelle`), '') as 'libelle', `charges_fixe`.`mouvement` as 'mouvement', `charges_fixe`.`piece` as 'piece', `charges_fixe`.`beneficiaire` as 'beneficiaire', REPLACE(FORMAT(`charges_fixe`.`montant`, 0), ',', ' ') as 'montant', `charges_fixe`.`observations` as 'observations', `charges_fixe`.`groupe` as 'groupe', `charges_fixe`.`agent` as 'agent'",
			'caisse' => "`caisse`.`idcaisse` as 'idcaisse', if(`caisse`.`date`,date_format(`caisse`.`date`,'%d/%m/%Y'),'') as 'date', `caisse`.`mouvement` as 'mouvement', `caisse`.`libelle` as 'libelle', REPLACE(FORMAT(`caisse`.`recette`, 0), ',', ' ') as 'recette', REPLACE(FORMAT(`caisse`.`depense`, 0), ',', ' ') as 'depense', REPLACE(FORMAT(`caisse`.`solde`, 0), ',', ' ') as 'solde', `caisse`.`observations` as 'observations', `caisse`.`groupe` as 'groupe', `caisse`.`agent` as 'agent'",
			'type_visa' => "`type_visa`.`idtype_visa` as 'idtype_visa', `type_visa`.`type_visa` as 'type_visa'",
			'libelle_charges_fixe' => "`libelle_charges_fixe`.`idlcf` as 'idlcf', `libelle_charges_fixe`.`libelle` as 'libelle'",
			'desc_suivi_banque' => "`desc_suivi_banque`.`iddsb` as 'iddsb', `desc_suivi_banque`.`description` as 'description'",
		);

		if(isset($sql_fields[$table_name])) {
			return $sql_fields[$table_name];
		}

		return false;
	}

	#########################################################

	function get_sql_from($table_name, $skip_permissions = false, $skip_joins = false) {
		$sql_from = array(
			'entete' => "`entete` ",
			'personnels' => "`personnels` LEFT JOIN `pays` as pays1 ON `pays1`.`idpays`=`personnels`.`nationalite` LEFT JOIN `agences` as agences1 ON `agences1`.`idagence`=`personnels`.`agence` LEFT JOIN `fonctions` as fonctions1 ON `fonctions1`.`idfonction`=`personnels`.`fonction` LEFT JOIN `produits_services` as produits_services1 ON `produits_services1`.`idps`=`personnels`.`service` LEFT JOIN `postes` as postes1 ON `postes1`.`idposte`=`personnels`.`poste` ",
			'clients' => "`clients` LEFT JOIN `type_client` as type_client1 ON `type_client1`.`idtype_client`=`clients`.`type_client` LEFT JOIN `agences` as agences1 ON `agences1`.`idagence`=`clients`.`agence` LEFT JOIN `pays` as pays1 ON `pays1`.`idpays`=`clients`.`nationalite` LEFT JOIN `produits_services` as produits_services1 ON `produits_services1`.`idps`=`clients`.`categorie` LEFT JOIN `fonctions` as fonctions1 ON `fonctions1`.`idfonction`=`clients`.`fonction` LEFT JOIN `activites` as activites1 ON `activites1`.`idactivite`=`clients`.`activite` LEFT JOIN `pays` as pays2 ON `pays2`.`idpays`=`clients`.`lieu` LEFT JOIN `banques` as banques1 ON `banques1`.`idbanque`=`clients`.`banque` LEFT JOIN `fidelite` as fidelite1 ON `fidelite1`.`idfidelite`=`clients`.`carte_fidelite` ",
			'suivi_client' => "`suivi_client` LEFT JOIN `clients` as clients1 ON `clients1`.`idclient`=`suivi_client`.`nom` LEFT JOIN `produits_services` as produits_services1 ON `produits_services1`.`idps`=`suivi_client`.`service_demande` LEFT JOIN `type_visa` as type_visa1 ON `type_visa1`.`idtype_visa`=`suivi_client`.`type_de_visa` ",
			'rendez_vous' => "`rendez_vous` LEFT JOIN `annees` as annees1 ON `annees1`.`idannee`=`rendez_vous`.`annee` ",
			'partenaires' => "`partenaires` LEFT JOIN `clients` as clients1 ON `clients1`.`idclient`=`partenaires`.`nom_prenom` LEFT JOIN `fonctions` as fonctions1 ON `fonctions1`.`idfonction`=`clients1`.`fonction` ",
			'packages' => "`packages` ",
			'oumrah' => "`oumrah` LEFT JOIN `annees` as annees1 ON `annees1`.`idannee`=`oumrah`.`Pelerinage` ",
			'hajj_oumrah' => "`hajj_oumrah` ",
			'souscriptions' => "`souscriptions` LEFT JOIN `hajj_oumrah` as hajj_oumrah1 ON `hajj_oumrah1`.`idhajjoumrah`=`souscriptions`.`pelerin` LEFT JOIN `oumrah` as oumrah1 ON `oumrah1`.`idoumrah`=`souscriptions`.`oumrah` LEFT JOIN `packages` as packages1 ON `packages1`.`idpackage`=`souscriptions`.`package` ",
			'entrees' => "`entrees` LEFT JOIN `hajj_oumrah` as hajj_oumrah1 ON `hajj_oumrah1`.`idhajjoumrah`=`entrees`.`client` LEFT JOIN `oumrah` as oumrah1 ON `oumrah1`.`idoumrah`=`entrees`.`oumrah` LEFT JOIN `packages` as packages1 ON `packages1`.`idpackage`=`entrees`.`description` ",
			'sorties' => "`sorties` LEFT JOIN `hajj_oumrah` as hajj_oumrah1 ON `hajj_oumrah1`.`idhajjoumrah`=`sorties`.`client` LEFT JOIN `oumrah` as oumrah1 ON `oumrah1`.`idoumrah`=`sorties`.`oumrah` ",
			'agences' => "`agences` ",
			'gestion_transactions' => "`gestion_transactions` LEFT JOIN `entete` as entete1 ON `entete1`.`identete`=`gestion_transactions`.`avec_entete` LEFT JOIN `clients` as clients1 ON `clients1`.`idclient`=`gestion_transactions`.`nom_prenom` ",
			'billeteries' => "`billeteries` LEFT JOIN `gestion_transactions` as gestion_transactions1 ON `gestion_transactions1`.`idgtransaction`=`billeteries`.`link_out` LEFT JOIN `produits_services` as produits_services1 ON `produits_services1`.`idps`=`billeteries`.`service` LEFT JOIN `clients` as clients1 ON `clients1`.`idclient`=`billeteries`.`passager` LEFT JOIN `gds` as gds1 ON `gds1`.`idgds`=`billeteries`.`gds` LEFT JOIN `compagnies` as compagnies1 ON `compagnies1`.`idcompagnie`=`billeteries`.`compagnie` LEFT JOIN `type_compagnie` as type_compagnie1 ON `type_compagnie1`.`idtypecompagnie`=`compagnies1`.`type` LEFT JOIN `items` as items1 ON `items1`.`iditem`=`billeteries`.`parcours` LEFT JOIN `produits_services` as produits_services2 ON `produits_services2`.`idps`=`billeteries`.`nature_transaction` ",
			'gestion_changes' => "`gestion_changes` LEFT JOIN `entete` as entete1 ON `entete1`.`identete`=`gestion_changes`.`avec_entete` LEFT JOIN `clients` as clients1 ON `clients1`.`idclient`=`gestion_changes`.`nom_prenom` LEFT JOIN `pays` as pays1 ON `pays1`.`idpays`=`clients1`.`nationalite` LEFT JOIN `fonctions` as fonctions1 ON `fonctions1`.`idfonction`=`clients1`.`fonction` ",
			'changes' => "`changes` LEFT JOIN `gestion_changes` as gestion_changes1 ON `gestion_changes1`.`idgchange`=`changes`.`link_out` ",
			'partages' => "`partages` LEFT JOIN `statut_partage` as statut_partage1 ON `statut_partage1`.`idstatutpartage`=`partages`.`statut` LEFT JOIN `clients` as clients1 ON `clients1`.`idclient`=`partages`.`client` ",
			'type_compagnie' => "`type_compagnie` ",
			'compagnies' => "`compagnies` LEFT JOIN `type_compagnie` as type_compagnie1 ON `type_compagnie1`.`idtypecompagnie`=`compagnies`.`type` ",
			'produits_services' => "`produits_services` ",
			'banques' => "`banques` ",
			'pays' => "`pays` ",
			'villes' => "`villes` ",
			'items' => "`items` ",
			'type_client' => "`type_client` ",
			'fonctions' => "`fonctions` ",
			'activites' => "`activites` ",
			'postes' => "`postes` ",
			'annees' => "`annees` ",
			'gds' => "`gds` ",
			'objets' => "`objets` ",
			'type_rapport' => "`type_rapport` ",
			'fidelite' => "`fidelite` ",
			'pointages' => "`pointages` LEFT JOIN `personnels` as personnels1 ON `personnels1`.`idpersonnel`=`pointages`.`nom_prenom` LEFT JOIN `agences` as agences1 ON `agences1`.`idagence`=`personnels1`.`agence` LEFT JOIN `fonctions` as fonctions1 ON `fonctions1`.`idfonction`=`personnels1`.`fonction` ",
			'note_de_service' => "`note_de_service` ",
			'redactions' => "`redactions` LEFT JOIN `objets` as objets1 ON `objets1`.`idobjet`=`redactions`.`objet` ",
			'rapports_activite' => "`rapports_activite` LEFT JOIN `objets` as objets1 ON `objets1`.`idobjet`=`rapports_activite`.`objet` LEFT JOIN `type_rapport` as type_rapport1 ON `type_rapport1`.`idtrpt`=`rapports_activite`.`type_rapport` ",
			'gestion_comptes' => "`gestion_comptes` LEFT JOIN `banques` as banques1 ON `banques1`.`idbanque`=`gestion_comptes`.`banque` LEFT JOIN `type_comptes` as type_comptes1 ON `type_comptes1`.`idtypecompte`=`gestion_comptes`.`type_compte` ",
			'gestion_comptes_1' => "`gestion_comptes_1` LEFT JOIN `banques` as banques1 ON `banques1`.`idbanque`=`gestion_comptes_1`.`banque` LEFT JOIN `type_comptes` as type_comptes1 ON `type_comptes1`.`idtypecompte`=`gestion_comptes_1`.`type_compte` ",
			'type_comptes' => "`type_comptes` ",
			'journal' => "`journal` LEFT JOIN `gestion_comptes` as gestion_comptes1 ON `gestion_comptes1`.`idgestioncompte`=`journal`.`compte_debit` LEFT JOIN `gestion_comptes` as gestion_comptes2 ON `gestion_comptes2`.`idgestioncompte`=`journal`.`compte_credit` ",
			'liens' => "`liens` ",
			'courrier_entrant' => "`courrier_entrant` ",
			'courrier_sortant' => "`courrier_sortant` ",
			'vitae' => "`vitae` ",
			'reunions' => "`reunions` LEFT JOIN `entete` as entete1 ON `entete1`.`identete`=`reunions`.`avec_entete` ",
			'item_reunions' => "`item_reunions` LEFT JOIN `reunions` as reunions1 ON `reunions1`.`idreunion`=`item_reunions`.`link_out` ",
			'statut_partage' => "`statut_partage` ",
			'chequiers' => "`chequiers` LEFT JOIN `gestion_comptes` as gestion_comptes1 ON `gestion_comptes1`.`idgestioncompte`=`chequiers`.`compte` LEFT JOIN `banques` as banques1 ON `banques1`.`idbanque`=`gestion_comptes1`.`banque` ",
			'cheques' => "`cheques` LEFT JOIN `chequiers` as chequiers1 ON `chequiers1`.`idchequier`=`cheques`.`chequier` ",
			'gestion_banques' => "`gestion_banques` LEFT JOIN `gestion_comptes_1` as gestion_comptes_11 ON `gestion_comptes_11`.`idgestioncompte`=`gestion_banques`.`compte_emetteur` LEFT JOIN `gestion_comptes` as gestion_comptes1 ON `gestion_comptes1`.`idgestioncompte`=`gestion_banques`.`compte_beneficiaire` LEFT JOIN `cheques` as cheques1 ON `cheques1`.`idcheque`=`gestion_banques`.`cheque_mv` LEFT JOIN `banques` as banques1 ON `banques1`.`idbanque`=`gestion_comptes_11`.`banque` LEFT JOIN `banques` as banques2 ON `banques2`.`idbanque`=`gestion_comptes1`.`banque` ",
			'suivi_banques' => "`suivi_banques` LEFT JOIN `desc_suivi_banque` as desc_suivi_banque1 ON `desc_suivi_banque1`.`iddsb`=`suivi_banques`.`description` ",
			'charges_fixe' => "`charges_fixe` LEFT JOIN `libelle_charges_fixe` as libelle_charges_fixe1 ON `libelle_charges_fixe1`.`idlcf`=`charges_fixe`.`libelle` ",
			'caisse' => "`caisse` ",
			'type_visa' => "`type_visa` ",
			'libelle_charges_fixe' => "`libelle_charges_fixe` ",
			'desc_suivi_banque' => "`desc_suivi_banque` ",
		);

		$pkey = array(
			'entete' => 'identete',
			'personnels' => 'idpersonnel',
			'clients' => 'idclient',
			'suivi_client' => 'idsuivi_client',
			'rendez_vous' => 'idrv',
			'partenaires' => 'idpartenaires',
			'packages' => 'idpackage',
			'oumrah' => 'idoumrah',
			'hajj_oumrah' => 'idhajjoumrah',
			'souscriptions' => 'idsouscription',
			'entrees' => 'identrees',
			'sorties' => 'idsorties',
			'agences' => 'idagence',
			'gestion_transactions' => 'idgtransaction',
			'billeteries' => 'idbilleterie',
			'gestion_changes' => 'idgchange',
			'changes' => 'idchange',
			'partages' => 'idpartage',
			'type_compagnie' => 'idtypecompagnie',
			'compagnies' => 'idcompagnie',
			'produits_services' => 'idps',
			'banques' => 'idbanque',
			'pays' => 'idpays',
			'villes' => 'idville',
			'items' => 'iditem',
			'type_client' => 'idtype_client',
			'fonctions' => 'idfonction',
			'activites' => 'idactivite',
			'postes' => 'idposte',
			'annees' => 'idannee',
			'gds' => 'idgds',
			'objets' => 'idobjet',
			'type_rapport' => 'idtrpt',
			'fidelite' => 'idfidelite',
			'pointages' => 'idpointage',
			'note_de_service' => 'idnote_service',
			'redactions' => 'idredaction',
			'rapports_activite' => 'idrapport',
			'gestion_comptes' => 'idgestioncompte',
			'gestion_comptes_1' => 'idgestioncompte',
			'type_comptes' => 'idtypecompte',
			'journal' => 'idjournal',
			'liens' => 'idlien',
			'courrier_entrant' => 'idcentrant',
			'courrier_sortant' => 'idcsortant',
			'vitae' => 'idvitae',
			'reunions' => 'idreunion',
			'item_reunions' => 'iditemreunion',
			'statut_partage' => 'idstatutpartage',
			'chequiers' => 'idchequier',
			'cheques' => 'idcheque',
			'gestion_banques' => 'idgestion_banque',
			'suivi_banques' => 'idsb',
			'charges_fixe' => 'idcf',
			'caisse' => 'idcaisse',
			'type_visa' => 'idtype_visa',
			'libelle_charges_fixe' => 'idlcf',
			'desc_suivi_banque' => 'iddsb',
		);

		if(!isset($sql_from[$table_name])) return false;

		$from = ($skip_joins ? "`{$table_name}`" : $sql_from[$table_name]);

		if($skip_permissions) return $from . ' WHERE 1=1';

		// mm: build the query based on current member's permissions
		$perm = getTablePermissions($table_name);
		if($perm[2] == 1) { // view owner only
			$from .= ", membership_userrecords WHERE `{$table_name}`.`{$pkey[$table_name]}`=membership_userrecords.pkValue and membership_userrecords.tableName='{$table_name}' and lcase(membership_userrecords.memberID)='" . getLoggedMemberID() . "'";
		}elseif($perm[2] == 2) { // view group only
			$from .= ", membership_userrecords WHERE `{$table_name}`.`{$pkey[$table_name]}`=membership_userrecords.pkValue and membership_userrecords.tableName='{$table_name}' and membership_userrecords.groupID='" . getLoggedGroupID() . "'";
		}elseif($perm[2] == 3) { // view all
			$from .= ' WHERE 1=1';
		}else{ // view none
			return false;
		}

		return $from;
	}

	#########################################################

	function get_joined_record($table, $id, $skip_permissions = false) {
		$sql_fields = get_sql_fields($table);
		$sql_from = get_sql_from($table, $skip_permissions);

		if(!$sql_fields || !$sql_from) return false;

		$pk = getPKFieldName($table);
		if(!$pk) return false;

		$safe_id = makeSafe($id, false);
		$sql = "SELECT {$sql_fields} FROM {$sql_from} AND `{$table}`.`{$pk}`='{$safe_id}'";
		$eo['silentErrors'] = true;
		$res = sql($sql, $eo);
		if($row = db_fetch_assoc($res)) return $row;

		return false;
	}

	#########################################################

	function get_defaults($table) {
		/* array of tables and their fields, with default values (or empty), excluding automatic values */
		$defaults = array(
			'entete' => array(
				'identete' => '',
				'link_in' => '',
				'nom' => '',
				'raison_sociale' => '',
				'description' => '',
				'adresse' => '',
				'telephone' => '',
				'whatsapp' => '',
				'email' => '',
				'site_web' => '',
				'bp' => '',
				'footer' => '',
				'footer_1' => '',
				'footer_2' => '',
				'footer_3' => '',
				'logo' => '',
				'logop' => '',
				'notice' => '',
				'devise' => '',
				'signataire' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'personnels' => array(
				'idpersonnel' => '',
				'matricule' => '',
				'date_recrutement' => '',
				'nom' => '',
				'prenom' => '',
				'nationalite' => '',
				'cin' => '',
				'adresse' => '',
				'telephone' => '',
				'whatsapp' => '',
				'email' => '',
				'agence' => '',
				'fonction' => '',
				'service' => '',
				'poste' => '',
				'photo' => '',
				'cv' => '',
				'dossier' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'clients' => array(
				'idclient' => '',
				'matricule' => '',
				'agent' => '',
				'date_en' => '',
				'type_client' => '',
				'raison_sociale' => '',
				'personne_contact' => '',
				'email_pc' => '',
				'phone_pc' => '',
				'ninea' => '',
				'rc' => '',
				'genre' => '',
				'prenom' => '',
				'nom' => '',
				'cin' => '',
				'agence' => '',
				'nationalite' => '',
				'categorie' => '',
				'fonction' => '',
				'activite' => '',
				'date_naissance' => '',
				'age' => '',
				'passport' => '',
				'delivre_le' => '',
				'expire_le' => '',
				'lieu' => '',
				'validite' => '',
				'adresse' => '',
				'telephone' => '',
				'whatsapp' => '',
				'urgence' => '',
				'email' => '',
				'compte' => '',
				'banque' => '',
				'carte_fidelite' => '',
				'num_carte' => '',
				'signature' => '',
				'photo' => '',
				'dossier' => '',
				'observations' => '',
				'groupe' => ''
			),
			'suivi_client' => array(
				'idsuivi_client' => '',
				'num_dossier' => '',
				'nom' => '',
				'prenom' => '',
				'raison_sociale' => '',
				'telephone' => '',
				'email' => '',
				'whatsapp' => '',
				'service_demande' => '',
				'date_demande' => '1',
				'statut_service' => '',
				'num_visa' => '',
				'date_debut_visa' => '',
				'date_fin_visa' => '',
				'type_de_visa' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'rendez_vous' => array(
				'idrv' => '',
				'objet' => '',
				'annee' => '',
				'mois' => '',
				'jour' => '',
				'heure' => '',
				'rvs' => '',
				'observations' => '',
				'cree_le' => '',
				'modifie_le' => '',
				'statut' => '',
				'groupe' => '',
				'agent' => ''
			),
			'partenaires' => array(
				'idpartenaires' => '',
				'date' => '1',
				'nom_prenom' => '',
				'fonction' => '',
				'adresse' => '',
				'telephone' => '',
				'email' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'packages' => array(
				'idpackage' => '',
				'nom' => '',
				'prix' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'oumrah' => array(
				'idoumrah' => '',
				'Pelerinage' => '',
				'Prenom' => '',
				'Nom' => '',
				'Datedenaissance' => '',
				'Lieudenaissance' => '',
				'Adresse' => '',
				'Sexe' => '',
				'Numropasseport' => '',
				'Remarque' => '',
				'Tlphoneplerin' => '',
				'Tlphonefamille' => '',
				'Personnecontacter' => '',
				'Squence' => '',
				'Profession' => '',
				'Ethnie' => '',
				'Region' => '',
				'total_entree' => '0',
				'total_sortie' => '0',
				'solde' => '0',
				'groupe' => '',
				'agent' => ''
			),
			'hajj_oumrah' => array(
				'idhajjoumrah' => '',
				'Pelerinage' => '',
				'Prenom' => '',
				'Nom' => '',
				'Datedenaissance' => '',
				'Lieudenaissance' => '',
				'Adresse' => '',
				'Sexe' => '',
				'Numropasseport' => '',
				'Remarque' => '',
				'Tlphoneplerin' => '',
				'Tlphonefamille' => '',
				'Personnecontacter' => '',
				'Squence' => '',
				'Profession' => '',
				'Ethnie' => '',
				'Region' => '',
				'total_entree' => '0',
				'total_sortie' => '0',
				'solde' => '0',
				'groupe' => '',
				'agent' => ''
			),
			'souscriptions' => array(
				'idsouscription' => '',
				'date_enr' => '',
				'pelerin' => '',
				'oumrah' => '',
				'package' => '',
				'prix' => '0',
				'remise' => '0',
				'net_a_payer' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'entrees' => array(
				'identrees' => '',
				'date_entree' => '1',
				'client' => '',
				'oumrah' => '',
				'description' => '',
				'montant' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'sorties' => array(
				'idsorties' => '',
				'date_sortie' => '1',
				'client' => '',
				'oumrah' => '',
				'montant' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'agences' => array(
				'idagence' => '',
				'agence' => '',
				'adresse' => '',
				'responsable' => '',
				'telephone' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'gestion_transactions' => array(
				'idgtransaction' => '',
				'link_in' => '',
				'agent_init' => '',
				'agent' => '',
				'matricule' => '',
				'numero' => '',
				'date' => '1',
				'avec_entete' => '',
				'rs' => '',
				'type' => '',
				'nom_prenom' => '',
				'adclient' => '',
				'telclient' => '',
				'emclient' => '',
				'raison_sociale' => '',
				'termes' => '',
				'fpdf' => '',
				'fzip' => '',
				'devise' => '',
				'logo' => '',
				'description' => '',
				'adresse' => '',
				'telephone' => '',
				'whatsapp' => '',
				'email' => '',
				'site_web' => '',
				'bp' => '',
				'footer_3' => '',
				'notice' => '',
				'signataire' => '',
				'groupe' => ''
			),
			'billeteries' => array(
				'idbilleterie' => '',
				'link_out' => '',
				'facture' => '',
				'date' => '1',
				'service' => '',
				'passager' => '',
				'gds' => '',
				'compagnie' => '',
				'parcours' => '',
				'nature_transaction' => '',
				'billet' => '',
				'dossier' => '',
				'prix_achat' => '0',
				'prix_vente' => '0',
				'qts' => '1',
				'commission' => '0',
				'frais_service' => '0',
				'frais_assurance' => '0',
				'mtva' => '0',
				'tva' => '0',
				'tht' => '0',
				'net_compagnie' => '0',
				'net_a_payer' => '0',
				'account' => '0',
				'reste_a_payer' => '0',
				'agent' => '',
				'groupe' => '',
				'observations' => ''
			),
			'gestion_changes' => array(
				'idgchange' => '',
				'link_in' => '',
				'agent_init' => '',
				'agent' => '',
				'matricule' => '',
				'numero' => '',
				'date' => '1',
				'avec_entete' => '',
				'rs' => '',
				'type' => '',
				'nom_prenom' => '',
				'nationalite' => '',
				'profession' => '',
				'adclient' => '',
				'telclient' => '',
				'emclient' => '',
				'raison_sociale' => '',
				'termes' => '',
				'fpdf' => '',
				'fzip' => '',
				'devise' => '',
				'logo' => '',
				'description' => '',
				'adresse' => '',
				'telephone' => '',
				'whatsapp' => '',
				'email' => '',
				'site_web' => '',
				'bp' => '',
				'footer_3' => '',
				'notice' => '',
				'signataire' => '',
				'groupe' => ''
			),
			'changes' => array(
				'idchange' => '',
				'link_out' => '',
				'facture' => '',
				'date' => '1',
				'nature_transaction' => '',
				'billet' => '',
				'dossier' => '',
				'prix_achat' => '0',
				'mtva' => '0',
				'net_a_payer' => '0',
				'net_compagnie' => '0',
				'prix_vente' => '0',
				'qts' => '1',
				'commission' => '0',
				'frais_service' => '0',
				'frais_assurance' => '0',
				'tva' => '0',
				'tht' => '0',
				'account' => '0',
				'reste_a_payer' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'partages' => array(
				'idpartage' => '',
				'agent' => '',
				'date' => '1',
				'statut' => '',
				'client' => '',
				'image' => '',
				'word' => '',
				'document' => '',
				'compresse' => '',
				'commentaire' => '',
				'groupe' => ''
			),
			'type_compagnie' => array(
				'idtypecompagnie' => '',
				'type_compangie' => '',
				'observations' => ''
			),
			'compagnies' => array(
				'idcompagnie' => '',
				'nom_compagnie' => '',
				'adresse' => '',
				'contact' => '',
				'type' => '',
				'observations' => ''
			),
			'produits_services' => array(
				'idps' => '',
				'produit_service' => '',
				'observations' => ''
			),
			'banques' => array(
				'idbanque' => '',
				'banque' => '',
				'adresse' => '',
				'telephone' => '',
				'email' => '',
				'contact' => '',
				'observations' => ''
			),
			'pays' => array(
				'idpays' => '',
				'pays' => ''
			),
			'villes' => array(
				'idville' => '',
				'ville' => ''
			),
			'items' => array(
				'iditem' => '',
				'item' => '',
				'observation' => ''
			),
			'type_client' => array(
				'idtype_client' => '',
				'type_client' => '',
				'observation' => ''
			),
			'fonctions' => array(
				'idfonction' => '',
				'fonction' => '',
				'observations' => ''
			),
			'activites' => array(
				'idactivite' => '',
				'activite' => '',
				'observations' => ''
			),
			'postes' => array(
				'idposte' => '',
				'poste' => '',
				'observations' => ''
			),
			'annees' => array(
				'idannee' => '',
				'annee' => ''
			),
			'gds' => array(
				'idgds' => '',
				'gds' => '',
				'observations' => ''
			),
			'objets' => array(
				'idobjet' => '',
				'objet' => '',
				'obs' => ''
			),
			'type_rapport' => array(
				'idtrpt' => '',
				'type_rapport' => '',
				'obs' => ''
			),
			'fidelite' => array(
				'idfidelite' => '',
				'carte_fidelite' => '',
				'observations' => ''
			),
			'pointages' => array(
				'idpointage' => '',
				'date' => '1',
				'nom_prenom' => '',
				'agence' => '',
				'fonction' => '',
				'arrivee' => '',
				'depart' => '',
				'obs' => '',
				'groupe' => '',
				'agent' => ''
			),
			'note_de_service' => array(
				'idnote_service' => '',
				'date' => '1',
				'objet' => '',
				'texte' => '',
				'groupe' => '',
				'agent' => ''
			),
			'redactions' => array(
				'idredaction' => '',
				'date' => '1',
				'objet' => '',
				'agent' => '',
				'redaction' => '',
				'obs' => '',
				'groupe' => ''
			),
			'rapports_activite' => array(
				'idrapport' => '',
				'date' => '1',
				'nom_prenom' => '',
				'objet' => '',
				'type_rapport' => '',
				'rapport' => '',
				'obs' => '',
				'groupe' => '',
				'agent' => ''
			),
			'gestion_comptes' => array(
				'idgestioncompte' => '',
				'nom_compte' => '',
				'num_compte' => '',
				'banque' => '',
				'type_compte' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'gestion_comptes_1' => array(
				'idgestioncompte' => '',
				'nom_compte' => '',
				'num_compte' => '',
				'banque' => '',
				'type_compte' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'type_comptes' => array(
				'idtypecompte' => '',
				'type_compte' => '',
				'observations' => ''
			),
			'journal' => array(
				'idjournal' => '',
				'date' => '1',
				'libelle' => '',
				'compte_debit' => '',
				'compte_credit' => '',
				'tht' => '0',
				'tva' => '0',
				'tva2' => '0',
				'ttc' => '0',
				'remarques' => '',
				'groupe' => '',
				'agent' => ''
			),
			'liens' => array(
				'idlien' => '',
				'logo' => '',
				'description' => '',
				'lien' => '',
				'observations' => ''
			),
			'courrier_entrant' => array(
				'idcentrant' => '',
				'date' => '1',
				'expediteur' => '',
				'objet' => '',
				'destinataire' => '',
				'piece_jointe' => '',
				'statut' => '',
				'remarques' => '',
				'groupe' => '',
				'agent' => ''
			),
			'courrier_sortant' => array(
				'idcsortant' => '',
				'date' => '1',
				'expediteur' => '',
				'objet' => '',
				'destinataire' => '',
				'piece_jointe' => '',
				'statut' => '',
				'remarques' => '',
				'groupe' => '',
				'agent' => ''
			),
			'vitae' => array(
				'idvitae' => '',
				'date' => '1',
				'candidat' => '',
				'domaine' => '',
				'dossier' => '',
				'statut' => '',
				'photo' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'reunions' => array(
				'idreunion' => '',
				'link_in' => '',
				'avec_entete' => '',
				'ordre_jour' => '',
				'date' => '1',
				'temps' => '',
				'duree' => '',
				'lieu' => '',
				'objectif' => '',
				'fpdf' => '',
				'fzip' => '',
				'rs' => '',
				'devise' => '',
				'logo' => '',
				'description' => '',
				'adresse' => '',
				'telephone' => '',
				'whatsapp' => '',
				'email' => '',
				'site_web' => '',
				'bp' => '',
				'footer_3' => '',
				'notice' => '',
				'signataire' => '',
				'groupe' => '',
				'agent' => ''
			),
			'item_reunions' => array(
				'iditemreunion' => '',
				'link_out' => '',
				'activite' => '',
				'temps' => '',
				'responsable' => '',
				'objectif' => '',
				'observations' => ''
			),
			'statut_partage' => array(
				'idstatutpartage' => '',
				'statut' => '',
				'observations' => ''
			),
			'chequiers' => array(
				'idchequier' => '',
				'date' => '1',
				'lot_num' => '',
				'lot_qts' => '',
				'compte' => '',
				'banque' => '',
				'groupe' => '',
				'agent' => ''
			),
			'cheques' => array(
				'idcheque' => '',
				'num' => '',
				'chequier' => '',
				'groupe' => '',
				'agent' => ''
			),
			'gestion_banques' => array(
				'idgestion_banque' => '',
				'date' => '1',
				'mouvement' => '',
				'libelle' => '',
				'compte_emetteur' => '',
				'numero' => '',
				'banque' => '',
				'compte_beneficiaire' => '',
				'numero_cb' => '',
				'banque_cb' => '',
				'cheque_mv' => '',
				'cheque_ce' => '',
				'depense' => '0',
				'recette' => '0',
				'solde' => '0',
				'cheque' => '',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'suivi_banques' => array(
				'idsb' => '',
				'date' => '1',
				'mouvement' => '',
				'description' => '',
				'reference' => '',
				'debits' => '0',
				'credits' => '0',
				'balance' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'charges_fixe' => array(
				'idcf' => '',
				'date' => '1',
				'libelle' => '',
				'mouvement' => '',
				'piece' => '',
				'beneficiaire' => '',
				'montant' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'caisse' => array(
				'idcaisse' => '',
				'date' => '1',
				'mouvement' => '',
				'libelle' => '',
				'recette' => '0',
				'depense' => '0',
				'solde' => '0',
				'observations' => '',
				'groupe' => '',
				'agent' => ''
			),
			'type_visa' => array(
				'idtype_visa' => '',
				'type_visa' => ''
			),
			'libelle_charges_fixe' => array(
				'idlcf' => '',
				'libelle' => ''
			),
			'desc_suivi_banque' => array(
				'iddsb' => '',
				'description' => ''
			)
		);

		return isset($defaults[$table]) ? $defaults[$table] : array();
	}

	#########################################################

	function logInMember() {
		$redir = 'index.php';
		if($_POST['signIn'] != '') {
			if($_POST['username'] != '' && $_POST['password'] != '') {
				$username = makeSafe(strtolower($_POST['username']));
				$hash = sqlValue("select passMD5 from membership_users where lcase(memberID)='{$username}' and isApproved=1 and isBanned=0");
				$password = $_POST['password'];

				if(password_match($password, $hash)) {
					$_SESSION['memberID'] = $username;
					$_SESSION['memberGroupID'] = sqlValue("SELECT `groupID` FROM `membership_users` WHERE LCASE(`memberID`)='{$username}'");

					if($_POST['rememberMe'] == 1) {
						RememberMe::login($username);
					}else{
						RememberMe::delete();
					}

					// harden user's password hash
					password_harden($username, $password, $hash);

					// hook: login_ok
					if(function_exists('login_ok')) {
						$args=array();
						if(!$redir=login_ok(getMemberInfo(), $args)) {
							$redir='index.php';
						}
					}

					redirect($redir);
					exit;
				}
			}

			// hook: login_failed
			if(function_exists('login_failed')) {
				$args=array();
				login_failed(array(
					'username' => $_POST['username'],
					'password' => $_POST['password'],
					'IP' => $_SERVER['REMOTE_ADDR']
					), $args);
			}

			if(!headers_sent()) header('HTTP/1.0 403 Forbidden');
			redirect("index.php?loginFailed=1");
			exit;
		}

		/* do we have a JWT auth header? */
		jwt_check_login();

		if(!empty($_SESSION['memberID']) && !empty($_SESSION['memberGroupID'])) return;

		/* check if a rememberMe cookie exists and sign in user if so */
		if(RememberMe::check()) {
			$username = makeSafe(strtolower(RememberMe::user()));
			$_SESSION['memberID'] = $username;
			$_SESSION['memberGroupID'] = sqlValue("SELECT `groupID` FROM `membership_users` WHERE LCASE(`memberID`)='{$username}'");
		}
	}

	#########################################################

	function htmlUserBar() {
		global $adminConfig, $Translation;
		if(!defined('PREPEND_PATH')) define('PREPEND_PATH', '');

		ob_start();
		$home_page = (basename($_SERVER['PHP_SELF'])=='index.php' ? true : false);

		?>
		<nav class="navbar navbar-default navbar-fixed-top hidden-print" role="navigation">
			<div class="navbar-header">
				<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
					<span class="sr-only">Toggle navigation</span>
					<span class="icon-bar"></span>
					<span class="icon-bar"></span>
					<span class="icon-bar"></span>
				</button>
				<!-- application title is obtained from the name besides the yellow database icon in AppGini, use underscores for spaces -->
				<a class="navbar-brand" href="<?php echo PREPEND_PATH; ?>index.php"><i class="glyphicon glyphicon-home"></i> MAREGA VOYAGES</a>
			</div>
			<div class="collapse navbar-collapse">
				<ul class="nav navbar-nav">
					<?php if(!$home_page) { ?>
						<?php echo NavMenus(); ?>
					<?php } ?>
				</ul>

				<?php if(getLoggedAdmin()) { ?>
					<ul class="nav navbar-nav">
						<a href="<?php echo PREPEND_PATH; ?>admin/pageHome.php" class="btn btn-danger navbar-btn hidden-xs" title="<?php echo html_attr($Translation['admin area']); ?>"><i class="glyphicon glyphicon-cog"></i> <?php echo $Translation['admin area']; ?></a>
						<a href="<?php echo PREPEND_PATH; ?>admin/pageHome.php" class="btn btn-danger navbar-btn visible-xs btn-lg" title="<?php echo html_attr($Translation['admin area']); ?>"><i class="glyphicon glyphicon-cog"></i> <?php echo $Translation['admin area']; ?></a>
					</ul>
				<?php } ?>

				<?php if(!$_GET['signIn'] && !$_GET['loginFailed']) { ?>
					<?php if(getLoggedMemberID() == $adminConfig['anonymousMember']) { ?>
						<p class="navbar-text navbar-right">&nbsp;</p>
						<a href="<?php echo PREPEND_PATH; ?>index.php?signIn=1" class="btn btn-success navbar-btn navbar-right"><?php echo $Translation['sign in']; ?></a>
						<p class="navbar-text navbar-right">
							<?php echo $Translation['not signed in']; ?>
						</p>
					<?php }else{ ?>
						<ul class="nav navbar-nav navbar-right hidden-xs" style="min-width: 330px;">
							<a class="btn navbar-btn btn-default" href="<?php echo PREPEND_PATH; ?>index.php?signOut=1"><i class="glyphicon glyphicon-log-out"></i> <?php echo $Translation['sign out']; ?></a>
							<p class="navbar-text">
								<?php echo $Translation['signed as']; ?> <strong><a href="<?php echo PREPEND_PATH; ?>membership_profile.php" class="navbar-link"><?php echo getLoggedMemberID(); ?></a></strong>
							</p>
						</ul>
						<ul class="nav navbar-nav visible-xs">
							<a class="btn navbar-btn btn-default btn-lg visible-xs" href="<?php echo PREPEND_PATH; ?>index.php?signOut=1"><i class="glyphicon glyphicon-log-out"></i> <?php echo $Translation['sign out']; ?></a>
							<p class="navbar-text text-center">
								<?php echo $Translation['signed as']; ?> <strong><a href="<?php echo PREPEND_PATH; ?>membership_profile.php" class="navbar-link"><?php echo getLoggedMemberID(); ?></a></strong>
							</p>
						</ul>
						<script>
							/* periodically check if user is still signed in */
							setInterval(function() {
								$j.ajax({
									url: '<?php echo PREPEND_PATH; ?>ajax_check_login.php',
									success: function(username) {
										if(!username.length) window.location = '<?php echo PREPEND_PATH; ?>index.php?signIn=1';
									}
								});
							}, 60000);
						</script>
					<?php } ?>
				<?php } ?>
			</div>
		</nav>
		<?php

		$html = ob_get_contents();
		ob_end_clean();

		return $html;
	}

	#########################################################

	function showNotifications($msg = '', $class = '', $fadeout = true) {
		global $Translation;

		$notify_template_no_fadeout = '<div id="%%ID%%" class="alert alert-dismissable %%CLASS%%" style="display: none; padding-top: 6px; padding-bottom: 6px;">' .
					'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' .
					'%%MSG%%</div>' .
					'<script> jQuery(function() { /* */ jQuery("#%%ID%%").show("slow"); }); </script>'."\n";
		$notify_template = '<div id="%%ID%%" class="alert %%CLASS%%" style="display: none; padding-top: 6px; padding-bottom: 6px;">%%MSG%%</div>' .
					'<script>' .
						'jQuery(function() {' .
							'jQuery("#%%ID%%").show("slow", function() {' .
								'setTimeout(function() { /* */ jQuery("#%%ID%%").hide("slow"); }, 4000);' .
							'});' .
						'});' .
					'</script>'."\n";

		if(!$msg) { // if no msg, use url to detect message to display
			if($_REQUEST['record-added-ok'] != '') {
				$msg = $Translation['new record saved'];
				$class = 'alert-success';
			}elseif($_REQUEST['record-added-error'] != '') {
				$msg = $Translation['Couldn\'t save the new record'];
				$class = 'alert-danger';
				$fadeout = false;
			}elseif($_REQUEST['record-updated-ok'] != '') {
				$msg = $Translation['record updated'];
				$class = 'alert-success';
			}elseif($_REQUEST['record-updated-error'] != '') {
				$msg = $Translation['Couldn\'t save changes to the record'];
				$class = 'alert-danger';
				$fadeout = false;
			}elseif($_REQUEST['record-deleted-ok'] != '') {
				$msg = $Translation['The record has been deleted successfully'];
				$class = 'alert-success';
				$fadeout = false;
			}elseif($_REQUEST['record-deleted-error'] != '') {
				$msg = $Translation['Couldn\'t delete this record'];
				$class = 'alert-danger';
				$fadeout = false;
			}else{
				return '';
			}
		}
		$id = 'notification-' . rand();

		$out = ($fadeout ? $notify_template : $notify_template_no_fadeout);
		$out = str_replace('%%ID%%', $id, $out);
		$out = str_replace('%%MSG%%', $msg, $out);
		$out = str_replace('%%CLASS%%', $class, $out);

		return $out;
	}

	#########################################################

	function parseMySQLDate($date, $altDate) {
		// is $date valid?
		if(preg_match("/^\d{4}-\d{1,2}-\d{1,2}$/", trim($date))) {
			return trim($date);
		}

		if($date != '--' && preg_match("/^\d{4}-\d{1,2}-\d{1,2}$/", trim($altDate))) {
			return trim($altDate);
		}

		if($date != '--' && $altDate && intval($altDate)==$altDate) {
			return @date('Y-m-d', @time() + ($altDate >= 1 ? $altDate - 1 : $altDate) * 86400);
		}

		return '';
	}

	#########################################################

	function parseCode($code, $isInsert=true, $rawData=false) {
		if($isInsert) {
			$arrCodes=array(
				'<%%creatorusername%%>' => $_SESSION['memberID'],
				'<%%creatorgroupid%%>' => $_SESSION['memberGroupID'],
				'<%%creatorip%%>' => $_SERVER['REMOTE_ADDR'],
				'<%%creatorgroup%%>' => sqlValue("select name from membership_groups where groupID='{$_SESSION['memberGroupID']}'"),

				'<%%creationdate%%>' => ($rawData ? @date('Y-m-d') : @date('j/n/Y')),
				'<%%creationtime%%>' => ($rawData ? @date('H:i:s') : @date('h:i:s a')),
				'<%%creationdatetime%%>' => ($rawData ? @date('Y-m-d H:i:s') : @date('j/n/Y h:i:s a')),
				'<%%creationtimestamp%%>' => ($rawData ? @date('Y-m-d H:i:s') : @time())
			);
		}else{
			$arrCodes=array(
				'<%%editorusername%%>' => $_SESSION['memberID'],
				'<%%editorgroupid%%>' => $_SESSION['memberGroupID'],
				'<%%editorip%%>' => $_SERVER['REMOTE_ADDR'],
				'<%%editorgroup%%>' => sqlValue("select name from membership_groups where groupID='{$_SESSION['memberGroupID']}'"),

				'<%%editingdate%%>' => ($rawData ? @date('Y-m-d') : @date('j/n/Y')),
				'<%%editingtime%%>' => ($rawData ? @date('H:i:s') : @date('h:i:s a')),
				'<%%editingdatetime%%>' => ($rawData ? @date('Y-m-d H:i:s') : @date('j/n/Y h:i:s a')),
				'<%%editingtimestamp%%>' => ($rawData ? @date('Y-m-d H:i:s') : @time())
			);
		}

		$pc=str_ireplace(array_keys($arrCodes), array_values($arrCodes), $code);

		return $pc;
	}

	#########################################################

	function addFilter($index, $filterAnd, $filterField, $filterOperator, $filterValue) {
		// validate input
		if($index < 1 || $index > 80 || !is_int($index)) return false;
		if($filterAnd != 'or')   $filterAnd = 'and';
		$filterField = intval($filterField);

		/* backward compatibility */
		if(in_array($filterOperator, $GLOBALS['filter_operators'])) {
			$filterOperator = array_search($filterOperator, $GLOBALS['filter_operators']);
		}

		if(!in_array($filterOperator, array_keys($GLOBALS['filter_operators']))) {
			$filterOperator = 'like';
		}

		if(!$filterField) {
			$filterOperator = '';
			$filterValue = '';
		}

		$_REQUEST['FilterAnd'][$index] = $filterAnd;
		$_REQUEST['FilterField'][$index] = $filterField;
		$_REQUEST['FilterOperator'][$index] = $filterOperator;
		$_REQUEST['FilterValue'][$index] = $filterValue;

		return true;
	}

	#########################################################

	function clearFilters() {
		for($i=1; $i<=80; $i++) {
			addFilter($i, '', 0, '', '');
		}
	}

	#########################################################

	if(!function_exists('str_ireplace')) {
		function str_ireplace($search, $replace, $subject) {
			$ret=$subject;
			if(is_array($search)) {
				for($i=0; $i<count($search); $i++) {
					$ret=str_ireplace($search[$i], $replace[$i], $ret);
				}
			}else{
				$ret=preg_replace('/'.preg_quote($search, '/').'/i', $replace, $ret);
			}

			return $ret;
		} 
	} 

	#########################################################

	/**
	* Loads a given view from the templates folder, passing the given data to it
	* @param $view the name of a php file (without extension) to be loaded from the 'templates' folder
	* @param $the_data_to_pass_to_the_view (optional) associative array containing the data to pass to the view
	* @return the output of the parsed view as a string
	*/
	function loadView($view, $the_data_to_pass_to_the_view=false) {
		global $Translation;

		$view = dirname(__FILE__)."/templates/$view.php";
		if(!is_file($view)) return false;

		if(is_array($the_data_to_pass_to_the_view)) {
			foreach($the_data_to_pass_to_the_view as $k => $v)
				$$k = $v;
		}
		unset($the_data_to_pass_to_the_view, $k, $v);

		ob_start();
		@include($view);
		$out=ob_get_contents();
		ob_end_clean();

		return $out;
	}

	#########################################################

	/**
	* Loads a table template from the templates folder, passing the given data to it
	* @param $table_name the name of the table whose template is to be loaded from the 'templates' folder
	* @param $the_data_to_pass_to_the_table associative array containing the data to pass to the table template
	* @return the output of the parsed table template as a string
	*/
	function loadTable($table_name, $the_data_to_pass_to_the_table = array()) {
		$dont_load_header = $the_data_to_pass_to_the_table['dont_load_header'];
		$dont_load_footer = $the_data_to_pass_to_the_table['dont_load_footer'];

		$header = $table = $footer = '';

		if(!$dont_load_header) {
			// try to load tablename-header
			if(!($header = loadView("{$table_name}-header", $the_data_to_pass_to_the_table))) {
				$header = loadView('table-common-header', $the_data_to_pass_to_the_table);
			}
		}

		$table = loadView($table_name, $the_data_to_pass_to_the_table);

		if(!$dont_load_footer) {
			// try to load tablename-footer
			if(!($footer = loadView("{$table_name}-footer", $the_data_to_pass_to_the_table))) {
				$footer = loadView('table-common-footer', $the_data_to_pass_to_the_table);
			}
		}

		return "{$header}{$table}{$footer}";
	}

	#########################################################

	function filterDropdownBy($filterable, $filterers, $parentFilterers, $parentPKField, $parentCaption, $parentTable, &$filterableCombo) {
		$filterersArray = explode(',', $filterers);
		$parentFilterersArray = explode(',', $parentFilterers);
		$parentFiltererList = '`' . implode('`, `', $parentFilterersArray) . '`';
		$res=sql("SELECT `$parentPKField`, $parentCaption, $parentFiltererList FROM `$parentTable` ORDER BY 2", $eo);
		$filterableData = array();
		while($row=db_fetch_row($res)) {
			$filterableData[$row[0]] = $row[1];
			$filtererIndex = 0;
			foreach($filterersArray as $filterer) {
				$filterableDataByFilterer[$filterer][$row[$filtererIndex + 2]][$row[0]] = $row[1];
				$filtererIndex++;
			}
			$row[0] = addslashes($row[0]);
			$row[1] = addslashes($row[1]);
			$jsonFilterableData .= "\"{$row[0]}\":\"{$row[1]}\",";
		}
		$jsonFilterableData .= '}';
		$jsonFilterableData = '{'.str_replace(',}', '}', $jsonFilterableData);     
		$filterJS = "\nvar {$filterable}_data = $jsonFilterableData;";

		foreach($filterersArray as $filterer) {
			if(is_array($filterableDataByFilterer[$filterer])) foreach($filterableDataByFilterer[$filterer] as $filtererItem => $filterableItem) {
				$jsonFilterableDataByFilterer[$filterer] .= '"'.addslashes($filtererItem).'":{';
				foreach($filterableItem as $filterableItemID => $filterableItemData) {
					$jsonFilterableDataByFilterer[$filterer] .= '"'.addslashes($filterableItemID).'":"'.addslashes($filterableItemData).'",';
				}
				$jsonFilterableDataByFilterer[$filterer] .= '},';
			}
			$jsonFilterableDataByFilterer[$filterer] .= '}';
			$jsonFilterableDataByFilterer[$filterer] = '{'.str_replace(',}', '}', $jsonFilterableDataByFilterer[$filterer]);

			$filterJS.="\n\n// code for filtering {$filterable} by {$filterer}\n";
			$filterJS.="\nvar {$filterable}_data_by_{$filterer} = {$jsonFilterableDataByFilterer[$filterer]}; ";
			$filterJS.="\nvar selected_{$filterable} = \$j('#{$filterable}').val();";
			$filterJS.="\nvar {$filterable}_change_by_{$filterer} = function() {";
			$filterJS.="\n\t$('{$filterable}').options.length=0;";
			$filterJS.="\n\t$('{$filterable}').options[0] = new Option();";
			$filterJS.="\n\tif(\$j('#{$filterer}').val()) {";
			$filterJS.="\n\t\tfor({$filterable}_item in {$filterable}_data_by_{$filterer}[\$j('#{$filterer}').val()]) {";
			$filterJS.="\n\t\t\t$('{$filterable}').options[$('{$filterable}').options.length] = new Option(";
			$filterJS.="\n\t\t\t\t{$filterable}_data_by_{$filterer}[\$j('#{$filterer}').val()][{$filterable}_item],";
			$filterJS.="\n\t\t\t\t{$filterable}_item,";
			$filterJS.="\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false),";
			$filterJS.="\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false)";
			$filterJS.="\n\t\t\t);";
			$filterJS.="\n\t\t}";
			$filterJS.="\n\t}else{";
			$filterJS.="\n\t\tfor({$filterable}_item in {$filterable}_data) {";
			$filterJS.="\n\t\t\t$('{$filterable}').options[$('{$filterable}').options.length] = new Option(";
			$filterJS.="\n\t\t\t\t{$filterable}_data[{$filterable}_item],";
			$filterJS.="\n\t\t\t\t{$filterable}_item,";
			$filterJS.="\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false),";
			$filterJS.="\n\t\t\t\t({$filterable}_item == selected_{$filterable} ? true : false)";
			$filterJS.="\n\t\t\t);";
			$filterJS.="\n\t\t}";
			$filterJS.="\n\t\tif(selected_{$filterable} && selected_{$filterable} == \$j('#{$filterable}').val()) {";
			$filterJS.="\n\t\t\tfor({$filterer}_item in {$filterable}_data_by_{$filterer}) {";
			$filterJS.="\n\t\t\t\tfor({$filterable}_item in {$filterable}_data_by_{$filterer}[{$filterer}_item]) {";
			$filterJS.="\n\t\t\t\t\tif({$filterable}_item == selected_{$filterable}) {";
			$filterJS.="\n\t\t\t\t\t\t$('{$filterer}').value = {$filterer}_item;";
			$filterJS.="\n\t\t\t\t\t\tbreak;";
			$filterJS.="\n\t\t\t\t\t}";
			$filterJS.="\n\t\t\t\t}";
			$filterJS.="\n\t\t\t\tif({$filterable}_item == selected_{$filterable}) break;";
			$filterJS.="\n\t\t\t}";
			$filterJS.="\n\t\t}";
			$filterJS.="\n\t}";
			$filterJS.="\n\t$('{$filterable}').highlight();";
			$filterJS.="\n};";
			$filterJS.="\n$('{$filterer}').observe('change', function() { /* */ window.setTimeout({$filterable}_change_by_{$filterer}, 25); });";
			$filterJS.="\n";
		}

		$filterableCombo = new Combo;
		$filterableCombo->ListType = 0;
		$filterableCombo->ListItem = array_slice(array_values($filterableData), 0, 10);
		$filterableCombo->ListData = array_slice(array_keys($filterableData), 0, 10);
		$filterableCombo->SelectName = $filterable;
		$filterableCombo->AllowNull = true;

		return $filterJS;
	}

	#########################################################
	function br2nl($text) {
		return  preg_replace('/\<br(\s*)?\/?\>/i', "\n", $text);
	}

	#########################################################

	if(!function_exists('htmlspecialchars_decode')) {
		function htmlspecialchars_decode($string, $quote_style = ENT_COMPAT) {
			return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
		}
	}

	#########################################################

	function entitiesToUTF8($input) {
		return preg_replace_callback('/(&#[0-9]+;)/', '_toUTF8', $input);
	}

	function _toUTF8($m) {
		if(function_exists('mb_convert_encoding')) {
			return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES");
		}else{
			return $m[1];
		}
	}

	#########################################################

	function func_get_args_byref() {
		if(!function_exists('debug_backtrace')) return false;

		$trace = debug_backtrace();
		return $trace[1]['args'];
	}

	#########################################################

	function permissions_sql($table, $level = 'all') {
		if(!in_array($level, array('user', 'group'))) { $level = 'all'; }
		$perm = getTablePermissions($table);
		$from = '';
		$where = '';
		$pk = getPKFieldName($table);

		if($perm[2] == 1 || ($perm[2] > 1 && $level == 'user')) { // view owner only
			$from = 'membership_userrecords';
			$where = "(`$table`.`$pk`=membership_userrecords.pkValue and membership_userrecords.tableName='$table' and lcase(membership_userrecords.memberID)='".getLoggedMemberID()."')";
		}elseif($perm[2] == 2 || ($perm[2] > 2 && $level == 'group')) { // view group only
			$from = 'membership_userrecords';
			$where = "(`$table`.`$pk`=membership_userrecords.pkValue and membership_userrecords.tableName='$table' and membership_userrecords.groupID='".getLoggedGroupID()."')";
		}elseif($perm[2] == 3) { // view all
			// no further action
		}elseif($perm[2] == 0) { // view none
			return false;
		}

		return array('where' => $where, 'from' => $from, 0 => $where, 1 => $from);
	}

	#########################################################

	function error_message($msg, $back_url = '', $full_page = true) {
		$curr_dir = dirname(__FILE__);
		global $Translation;

		ob_start();

		if($full_page) include_once($curr_dir . '/header.php');

		echo '<div class="panel panel-danger">';
			echo '<div class="panel-heading"><h3 class="panel-title">' . $Translation['error:'] . '</h3></div>';
			echo '<div class="panel-body"><p class="text-danger">' . $msg . '</p>';
			if($back_url !== false) { // explicitly passing false suppresses the back link completely
				echo '<div class="text-center">';
				if($back_url) {
					echo '<a href="' . $back_url . '" class="btn btn-danger btn-lg vspacer-lg"><i class="glyphicon glyphicon-chevron-left"></i> ' . $Translation['< back'] . '</a>';
				}else{
					echo '<a href="#" class="btn btn-danger btn-lg vspacer-lg" onclick="history.go(-1); return false;"><i class="glyphicon glyphicon-chevron-left"></i> ' . $Translation['< back'] . '</a>';
				}
				echo '</div>';
			}
			echo '</div>';
		echo '</div>';

		if($full_page) include_once($curr_dir . '/footer.php');

		$out = ob_get_contents();
		ob_end_clean();

		return $out;
	}

	#########################################################

	function toMySQLDate($formattedDate, $sep = datalist_date_separator, $ord = datalist_date_format) {
		// extract date elements
		$de=explode($sep, $formattedDate);
		$mySQLDate=intval($de[strpos($ord, 'Y')]).'-'.intval($de[strpos($ord, 'm')]).'-'.intval($de[strpos($ord, 'd')]);
		return $mySQLDate;
	}

	#########################################################

	function reIndex(&$arr) {
		$i=1;
		foreach($arr as $n=>$v) {
			$arr2[$i]=$n;
			$i++;
		}
		return $arr2;
	}

	#########################################################

	function get_embed($provider, $url, $max_width = '', $max_height = '', $retrieve = 'html') {
		global $Translation;
		if(!$url) return '';

		$providers = array(
			'youtube' => array('oembed' => 'http://www.youtube.com/oembed?'),
			'googlemap' => array('oembed' => '', 'regex' => '/^http.*\.google\..*maps/i')
		);

		if(!isset($providers[$provider])) {
			return '<div class="text-danger">' . $Translation['invalid provider'] . '</div>';
		}

		if(isset($providers[$provider]['regex']) && !preg_match($providers[$provider]['regex'], $url)) {
			return '<div class="text-danger">' . $Translation['invalid url'] . '</div>';
		}

		if($providers[$provider]['oembed']) {
			$oembed = $providers[$provider]['oembed'] . 'url=' . urlencode($url) . "&maxwidth={$max_width}&maxheight={$max_height}&format=json";
			$data_json = request_cache($oembed);

			$data = json_decode($data_json, true);
			if($data === null) {
				/* an error was returned rather than a json string */
				if($retrieve == 'html') return "<div class=\"text-danger\">{$data_json}\n<!-- {$oembed} --></div>";
				return '';
			}

			return (isset($data[$retrieve]) ? $data[$retrieve] : $data['html']);
		}

		/* special cases (where there is no oEmbed provider) */
		if($provider == 'googlemap') return get_embed_googlemap($url, $max_width, $max_height, $retrieve);

		return '<div class="text-danger">Invalid provider!</div>';
	}

	#########################################################

	function get_embed_googlemap($url, $max_width = '', $max_height = '', $retrieve = 'html') {
		global $Translation;
		$url_parts = parse_url($url);
		$coords_regex = '/-?\d+(\.\d+)?[,+]-?\d+(\.\d+)?(,\d{1,2}z)?/'; /* https://stackoverflow.com/questions/2660201 */

		if(preg_match($coords_regex, $url_parts['path'] . '?' . $url_parts['query'], $m)) {
			list($lat, $long, $zoom) = explode(',', $m[0]);
			$zoom = intval($zoom);
			if(!$zoom) $zoom = 10; /* default zoom */
			if(!$max_height) $max_height = 360;
			if(!$max_width) $max_width = 480;

			$api_key = '';
			$embed_url = "https://www.google.com/maps/embed/v1/view?key={$api_key}&center={$lat},{$long}&zoom={$zoom}&maptype=roadmap";
			$thumbnail_url = "https://maps.googleapis.com/maps/api/staticmap?key={$api_key}&center={$lat},{$long}&zoom={$zoom}&maptype=roadmap&size={$max_width}x{$max_height}";

			if($retrieve == 'html') {
				return "<iframe width=\"{$max_width}\" height=\"{$max_height}\" frameborder=\"0\" style=\"border:0\" src=\"{$embed_url}\"></iframe>";
			}else{
				return $thumbnail_url;
			}
		}else{
			return '<div class="text-danger">' . $Translation['cant retrieve coordinates from url'] . '</div>';
		}
	}

	#########################################################

	function request_cache($request, $force_fetch = false) {
		$max_cache_lifetime = 7 * 86400; /* max cache lifetime in seconds before refreshing from source */

		/* membership_cache table exists? if not, create it */
		static $cache_table_exists = false;
		if(!$cache_table_exists && !$force_fetch) {
			$te = sqlValue("show tables like 'membership_cache'");
			if(!$te) {
				if(!sql("CREATE TABLE `membership_cache` (`request` VARCHAR(100) NOT NULL, `request_ts` INT, `response` TEXT NOT NULL, PRIMARY KEY (`request`))", $eo)) {
					/* table can't be created, so force fetching request */
					return request_cache($request, true);
				}
			}
			$cache_table_exists = true;
		}

		/* retrieve response from cache if exists */
		if(!$force_fetch) {
			$res = sql("select response, request_ts from membership_cache where request='" . md5($request) . "'", $eo);
			if(!$row = db_fetch_array($res)) return request_cache($request, true);

			$response = $row[0];
			$response_ts = $row[1];
			if($response_ts < time() - $max_cache_lifetime) return request_cache($request, true);
		}

		/* if no response in cache, issue a request */
		if(!$response || $force_fetch) {
			$response = @file_get_contents($request);
			if($response === false) {
				$error = error_get_last();
				$error_message = preg_replace('/.*: (.*)/', '$1', $error['message']);
				return $error_message;
			}elseif($cache_table_exists) {
				/* store response in cache */
				$ts = time();
				sql("replace into membership_cache set request='" . md5($request) . "', request_ts='{$ts}', response='" . makeSafe($response, false) . "'", $eo);
			}
		}

		return $response;
	}

	#########################################################

	function check_record_permission($table, $id, $perm = 'view') {
		if($perm != 'edit' && $perm != 'delete') $perm = 'view';

		$perms = getTablePermissions($table);
		if(!$perms[$perm]) return false;

		$safe_id = makeSafe($id);
		$safe_table = makeSafe($table);

		if($perms[$perm] == 1) { // own records only
			$username = getLoggedMemberID();
			$owner = sqlValue("select memberID from membership_userrecords where tableName='{$safe_table}' and pkValue='{$safe_id}'");
			if($owner == $username) return true;
		}elseif($perms[$perm] == 2) { // group records
			$group_id = getLoggedGroupID();
			$owner_group_id = sqlValue("select groupID from membership_userrecords where tableName='{$safe_table}' and pkValue='{$safe_id}'");
			if($owner_group_id == $group_id) return true;
		}elseif($perms[$perm] == 3) { // all records
			return true;
		}

		return false;
	}

	#########################################################

	function NavMenus($options = array()) {
		if(!defined('PREPEND_PATH')) define('PREPEND_PATH', '');
		global $Translation;
		$prepend_path = PREPEND_PATH;

		/* default options */
		if(empty($options)) {
			$options = array(
				'tabs' => 7
			);
		}

		$table_group_name = array_keys(get_table_groups()); /* 0 => group1, 1 => group2 .. */
		/* if only one group named 'None', set to translation of 'select a table' */
		if((count($table_group_name) == 1 && $table_group_name[0] == 'None') || count($table_group_name) < 1) $table_group_name[0] = $Translation['select a table'];
		$table_group_index = array_flip($table_group_name); /* group1 => 0, group2 => 1 .. */
		$menu = array_fill(0, count($table_group_name), '');

		$t = time();
		$arrTables = getTableList();
		if(is_array($arrTables)) {
			foreach($arrTables as $tn => $tc) {
				/* ---- list of tables where hide link in nav menu is set ---- */
				$tChkHL = array_search($tn, array('type_comptes','journal'));

				/* ---- list of tables where filter first is set ---- */
				$tChkFF = array_search($tn, array());
				if($tChkFF !== false && $tChkFF !== null) {
					$searchFirst = '&Filter_x=1';
				}else{
					$searchFirst = '';
				}

				/* when no groups defined, $table_group_index['None'] is NULL, so $menu_index is still set to 0 */
				$menu_index = intval($table_group_index[$tc[3]]);
				if(!$tChkHL && $tChkHL !== 0) $menu[$menu_index] .= "<li><a href=\"{$prepend_path}{$tn}_view.php?t={$t}{$searchFirst}\"><img src=\"{$prepend_path}" . ($tc[2] ? $tc[2] : 'blank.gif') . "\" height=\"32\"> {$tc[0]}</a></li>";
			}
		}

		// custom nav links, as defined in "hooks/links-navmenu.php" 
		global $navLinks;
		if(is_array($navLinks)) {
			$memberInfo = getMemberInfo();
			$links_added = array();
			foreach($navLinks as $link) {
				if(!isset($link['url']) || !isset($link['title'])) continue;
				if($memberInfo['admin'] || @in_array($memberInfo['group'], $link['groups']) || @in_array('*', $link['groups'])) {
					$menu_index = intval($link['table_group']);
					if(!$links_added[$menu_index]) $menu[$menu_index] .= '<li class="divider"></li>';

					/* add prepend_path to custom links if they aren't absolute links */
					if(!preg_match('/^(http|\/\/)/i', $link['url'])) $link['url'] = $prepend_path . $link['url'];
					if(!preg_match('/^(http|\/\/)/i', $link['icon']) && $link['icon']) $link['icon'] = $prepend_path . $link['icon'];

					$menu[$menu_index] .= "<li><a href=\"{$link['url']}\"><img src=\"" . ($link['icon'] ? $link['icon'] : "{$prepend_path}blank.gif") . "\" height=\"32\"> {$link['title']}</a></li>";
					$links_added[$menu_index]++;
				}
			}
		}

		$menu_wrapper = '';
		for($i = 0; $i < count($menu); $i++) {
			$menu_wrapper .= <<<EOT
				<li class="dropdown">
					<a href="#" class="dropdown-toggle" data-toggle="dropdown">{$table_group_name[$i]} <b class="caret"></b></a>
					<ul class="dropdown-menu" role="menu">{$menu[$i]}</ul>
				</li>
EOT;
		}

		return $menu_wrapper;
	}

	#########################################################

	function StyleSheet() {
		if(!defined('PREPEND_PATH')) define('PREPEND_PATH', '');
		$prepend_path = PREPEND_PATH;

		$css_links = <<<EOT

			<link rel="stylesheet" href="{$prepend_path}resources/initializr/css/cyborg.css">
			<link rel="stylesheet" href="{$prepend_path}resources/lightbox/css/lightbox.css" media="screen">
			<link rel="stylesheet" href="{$prepend_path}resources/select2/select2.css" media="screen">
			<link rel="stylesheet" href="{$prepend_path}resources/timepicker/bootstrap-timepicker.min.css" media="screen">
			<link rel="stylesheet" href="{$prepend_path}dynamic.css.php">
EOT;

		return $css_links;
	}

	#########################################################

	function getUploadDir($dir) {
		global $Translation;

		if($dir=="") {
			$dir=$Translation['ImageFolder'];
		}

		if(substr($dir, -1)!="/") {
			$dir.="/";
		}

		return $dir;
	}

	#########################################################

	function PrepareUploadedFile($FieldName, $MaxSize, $FileTypes = 'jpg|jpeg|gif|png', $NoRename = false, $dir = '') {
		global $Translation;
		$f = $_FILES[$FieldName];
		if($f['error'] == 4 || !$f['name']) return '';

		$dir = getUploadDir($dir);

		/* get php.ini upload_max_filesize in bytes */
		$php_upload_size_limit = trim(ini_get('upload_max_filesize'));
		$last = strtolower($php_upload_size_limit[strlen($php_upload_size_limit) - 1]);
		switch($last) {
			case 'g':
				$php_upload_size_limit *= 1024;
			case 'm':
				$php_upload_size_limit *= 1024;
			case 'k':
				$php_upload_size_limit *= 1024;
		}

		$MaxSize = min($MaxSize, $php_upload_size_limit);

		if($f['size'] > $MaxSize || $f['error']) {
			echo error_message(str_replace('<MaxSize>', intval($MaxSize / 1024), $Translation['file too large']));
			exit;
		}
		if(!preg_match('/\.(' . $FileTypes . ')$/i', $f['name'], $ft)) {
			echo error_message(str_replace('<FileTypes>', str_replace('|', ', ', $FileTypes), $Translation['invalid file type']));
			exit;
		}

		$name = str_replace(' ', '_', $f['name']);
		if(!$NoRename) $name = substr(md5(microtime() . rand(0, 100000)), -17) . $ft[0];

		if(!file_exists($dir)) @mkdir($dir, 0777);

		if(!@move_uploaded_file($f['tmp_name'], $dir . $name)) {
			echo error_message("Couldn't save the uploaded file. Try chmoding the upload folder '{$dir}' to 777.");
			exit;
		}

		@chmod($dir . $name, 0666);
		return $name;
	}

	#########################################################

	function get_home_links($homeLinks, $default_classes, $tgroup = '') {
		if(!is_array($homeLinks) || !count($homeLinks)) return '';

		$memberInfo = getMemberInfo();

		ob_start();
		foreach($homeLinks as $link) {
			if(!isset($link['url']) || !isset($link['title'])) continue;
			if($tgroup != $link['table_group'] && $tgroup != '*') continue;

			/* fall-back classes if none defined */
			if(!$link['grid_column_classes']) $link['grid_column_classes'] = $default_classes['grid_column'];
			if(!$link['panel_classes']) $link['panel_classes'] = $default_classes['panel'];
			if(!$link['link_classes']) $link['link_classes'] = $default_classes['link'];

			if($memberInfo['admin'] || @in_array($memberInfo['group'], $link['groups']) || @in_array('*', $link['groups'])) {
				?>
				<div class="col-xs-12 <?php echo $link['grid_column_classes']; ?>">
					<div class="panel <?php echo $link['panel_classes']; ?>">
						<div class="panel-body">
							<a class="btn btn-block btn-lg <?php echo $link['link_classes']; ?>" title="<?php echo preg_replace("/&amp;(#[0-9]+|[a-z]+);/i", "&$1;", html_attr(strip_tags($link['description']))); ?>" href="<?php echo $link['url']; ?>"><?php echo ($link['icon'] ? '<img src="' . $link['icon'] . '">' : ''); ?><strong><?php echo $link['title']; ?></strong></a>
							<div class="panel-body-description"><?php echo $link['description']; ?></div>
						</div>
					</div>
				</div>
				<?php
			}
		}

		$html = ob_get_contents();
		ob_end_clean();

		return $html;
	}

	#########################################################

	function quick_search_html($search_term, $label, $separate_dv = true) {
		global $Translation;

		$safe_search = html_attr($search_term);
		$safe_label = html_attr($label);
		$safe_clear_label = html_attr($Translation['Reset Filters']);

		if($separate_dv) {
			$reset_selection = "document.myform.SelectedID.value = '';";
		}else{
			$reset_selection = "document.myform.writeAttribute('novalidate', 'novalidate');";
		}
		$reset_selection .= ' document.myform.NoDV.value=1; return true;';

		$html = <<<EOT
		<div class="input-group" id="quick-search">
			<input type="text" id="SearchString" name="SearchString" value="{$safe_search}" class="form-control" placeholder="{$safe_label}">
			<span class="input-group-btn">
				<button name="Search_x" value="1" id="Search" type="submit" onClick="{$reset_selection}" class="btn btn-default" title="{$safe_label}"><i class="glyphicon glyphicon-search"></i></button>
				<button name="ClearQuickSearch" value="1" id="ClearQuickSearch" type="submit" onClick="\$j('#SearchString').val(''); {$reset_selection}" class="btn btn-default" title="{$safe_clear_label}"><i class="glyphicon glyphicon-remove-circle"></i></button>
			</span>
		</div>
EOT;
		return $html;
	}

	#########################################################

