From 733d2be39c1d45acfc7bbf3b7e3ffe81e05e7310 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 2 Feb 2015 11:13:11 +0100 Subject: [PATCH 01/46] readd index.html file --- htdocs/contrat/class/index.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 htdocs/contrat/class/index.html diff --git a/htdocs/contrat/class/index.html b/htdocs/contrat/class/index.html new file mode 100644 index 00000000000..e69de29bb2d From 2f59a63e5ad6f063e3a18c77e3c2c4b79f40bde9 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 2 Feb 2015 18:03:18 +0100 Subject: [PATCH 02/46] Fix bug on contract create form propal and fix extrafield must be control before create object --- htdocs/contrat/card.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index b2b99a9dde3..248a9a46115 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -73,7 +73,7 @@ $object = new Contrat($db); $extrafields = new ExtraFields($db); // Load object -if ($id > 0 || ! empty($ref)) { +if ($id > 0 || ! empty($ref) && $action!='add') { $ret = $object->fetch($id, $ref); if ($ret > 0) $ret = $object->fetch_thirdparty(); @@ -203,6 +203,13 @@ if ($action == 'add' && $user->rights->contrat->creer) $error++; } + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + if (! $error) { $object->socid = $socid; @@ -352,10 +359,6 @@ if ($action == 'add' && $user->rights->contrat->creer) } else { - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - $result = $object->create($user); if ($result > 0) { From 7f5e4aa135da4b33b1571eaa91b7cff98617d5a5 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 11 Feb 2015 11:44:49 +0100 Subject: [PATCH 03/46] FIX : bug #1840 Email template modules in HTML are not render correctly --- htdocs/core/class/doleditor.class.php | 10 ++++++---- htdocs/core/class/html.formmail.class.php | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 6dc726b084e..0433d7799c4 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -43,6 +43,7 @@ class DolEditor var $height; var $width; var $readonly; + var $allowed_content; /** @@ -62,8 +63,9 @@ class DolEditor * @param int $rows Size of rows for textarea tool * @param int $cols Size of cols for textarea tool (textarea number of cols or %) * @param int $readonly 0=Read/Edit, 1=Read only + * @param int $allowed_content 0=filter input text, 1=render as it is */ - function __construct($htmlname,$content,$width='',$height=200,$toolbarname='Basic',$toolbarlocation='In',$toolbarstartexpanded=false,$uselocalbrowser=true,$okforextendededitor=true,$rows=0,$cols=0,$readonly=0) + function __construct($htmlname,$content,$width='',$height=200,$toolbarname='Basic',$toolbarlocation='In',$toolbarstartexpanded=false,$uselocalbrowser=true,$okforextendededitor=true,$rows=0,$cols=0,$readonly=0,$allowed_content=0) { global $conf,$langs; @@ -132,6 +134,7 @@ class DolEditor $this->cols = (preg_match('/%/',$cols)?$cols:max(40,$cols)); // If $cols is a percent, we keep it, otherwise, we take max $this->height = $height; $this->width = $width; + $this->allowed_content = $allowed_content; } } @@ -163,16 +166,14 @@ class DolEditor $out.= ''; - if ($this->tool == 'ckeditor') { if (! defined('REQUIRE_CKEDITOR')) define('REQUIRE_CKEDITOR','1'); //$skin='kama'; $skin='moono'; // default with cdeditor 4 - + $htmlencode_force=preg_match('/_encoded$/',$this->toolbarname)?'true':'false'; - $out.= '' . "\n"; + foreach ($showextcals as $val) { - $htmlname = dol_string_nospecial($val['name']); - $htmlname = dol_string_nospecial($htmlname,'_',array("\.","#")); - $s.='' . "\n"; - $s.='
' . $val ['name'] . '  
'; + $htmlname = md5($val['name']); + + $s.='
' . $val ['name'] . '  
'; } } $s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; @@ -1174,7 +1179,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $numicals[dol_string_nospecial($event->icalname)]++; } $color=$event->icalcolor; - $cssclass=(! empty($event->icalname)?'family_'.dol_string_nospecial($event->icalname):'family_other unmovable'); + $cssclass=(! empty($event->icalname)?'family_ext'.md5($event->icalname):'family_other unmovable'); } else if ($event->type_code == 'BIRTHDAY') { From c9b3cab22b23b2765043d99afc7b766b69778427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Thu, 5 Mar 2015 10:22:22 +0100 Subject: [PATCH 19/46] Mytasks is not clickable --- htdocs/comm/action/index.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index a5b83217c80..5ba3a4d9b0b 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -348,7 +348,6 @@ if (! empty($conf->use_javascript_ajax)) $s=''; $s.='' . "\n"; From 0ef46b06f400487e7350e94fe8d6346ccbdf0df2 Mon Sep 17 00:00:00 2001 From: guillaume Date: Thu, 5 Mar 2015 10:52:37 +0100 Subject: [PATCH 20/46] Sqlite3-PDO restoration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FR: - Restauration de la version PDO dans sqlite.class.php et désactivation. - Ajout de la classe de base de données Sqlite3 dans sqlite3.class.php EN: - revert of the PDO version of sqlite.class.php and deactivation. - add database class Sqlite3 into sqlite3.class.php. --- htdocs/admin/system/database-tables.php | 3 +- htdocs/core/db/sqlite.class.php | 378 +---- htdocs/core/db/sqlite3.class.php | 1478 +++++++++++++++++ htdocs/install/etape2.php | 4 +- htdocs/install/fileconf.php | 7 +- .../functions/functions.sql | 0 htdocs/install/{sqlite => sqlite3}/index.html | 0 7 files changed, 1540 insertions(+), 330 deletions(-) create mode 100644 htdocs/core/db/sqlite3.class.php rename htdocs/install/{sqlite => sqlite3}/functions/functions.sql (100%) rename htdocs/install/{sqlite => sqlite3}/index.html (100%) diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index 3af715a09b8..5ac7292042e 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -66,7 +66,7 @@ else if ($conf->db->type == 'mssql') //$sqls[0] = ""; //$base=3; } -else if ($conf->db->type == 'sqlite') { +else if ($conf->db->type == 'sqlite3') { //$sql = "SELECT name, type FROM sqlite_master"; $base = 4; } @@ -176,6 +176,7 @@ else if ($base == 4) { + // Sqlite3 print ''; print ''; print ''; diff --git a/htdocs/core/db/sqlite.class.php b/htdocs/core/db/sqlite.class.php index 77e9dcdba54..786bf435fcf 100644 --- a/htdocs/core/db/sqlite.class.php +++ b/htdocs/core/db/sqlite.class.php @@ -34,16 +34,17 @@ class DoliDBSqlite extends DoliDB //! Database type public $type='sqlite'; //! Database label - const LABEL='Sqlite3'; + const LABEL='PDO Sqlite'; //! Version min database const VERSIONMIN='3.0.0'; //! Resultset of last query private $_results; - const WEEK_MONDAY_FIRST=1; - const WEEK_YEAR = 2; - const WEEK_FIRST_WEEKDAY=4; - + /** + * Indique que les fonctions personnalisées sont définies + * @var boolean + */ + private static $customFunctionsDefined = false; /** * Constructor. @@ -101,15 +102,7 @@ class DoliDBSqlite extends DoliDB $this->database_selected = 1; $this->database_name = $name; - $this->addCustomFunction('IF'); - $this->addCustomFunction('MONTH'); - $this->addCustomFunction('CURTIME'); - $this->addCustomFunction('CURDATE'); - $this->addCustomFunction('WEEK', 1); - $this->addCustomFunction('WEEK', 2); - $this->addCustomFunction('WEEKDAY'); - $this->addCustomFunction('date_format'); - //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } else { @@ -329,16 +322,14 @@ class DoliDBSqlite extends DoliDB if (empty($dir)) $dir=DOL_DATA_ROOT; // With sqlite, port must be in connect parameters //if (! $newport) $newport=3306; - $database_name = $dir.'/database_'.$name.'.sdb'; try { /*** connect to SQLite database ***/ - //$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb'); - $this->db = new SQLite3($database_name); - //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb'); + $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } - catch(Exception $e) + catch(PDOException $e) { - $this->error= self::LABEL.' '.$e->getMessage().' current dir='.$database_name; + $this->error='PDO SQLITE '.$e->getMessage().' current dir='.$dir.'/database_'.$name.'.sdb'; return ''; } @@ -354,7 +345,9 @@ class DoliDBSqlite extends DoliDB */ function getVersion() { - return $this->db->version()['versionString']; + $resql=$this->query('SELECT sqlite_version() as sqliteversion'); + $row=$this->fetch_row($resql); + return $row[0]; } /** @@ -383,7 +376,6 @@ class DoliDBSqlite extends DoliDB { if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened,LOG_ERR); $this->connected=0; - $this->db->close(); $this->db=null; // Clean this->db return true; } @@ -419,10 +411,13 @@ class DoliDBSqlite extends DoliDB $constraintname=trim($reg[2]); $tablename=trim($reg[1]); - $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); + $res = $this->db->query("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); + $descTable = $res->fetchColumn(); + $res->closeCursor(); // 1- Renommer la table avec un nom temporaire - $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); + $res = $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); + $res->closeCursor(); // 2- Recréer la table avec la contrainte ajoutée @@ -434,13 +429,17 @@ class DoliDBSqlite extends DoliDB $descTable .= ')'; // Création proprement dite de la table - $this->query($descTable); + $res = $this->query($descTable); + $res->closeCursor(); // 3- Transférer les données - $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); + $res = $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); + $res->closeCursor(); + // 4- Supprimer la table temporaire - $this->query('DROP TABLE tmp_' . $tablename); + $res = $this->query('DROP TABLE tmp_' . $tablename); + $res->closeCursor(); // dummy statement $query="SELECT 0"; @@ -456,13 +455,10 @@ class DoliDBSqlite extends DoliDB try { //$ret = $this->db->exec($query); $ret = $this->db->query($query); // $ret is a PDO object - if ($ret) { - $ret->queryString = $query; - } } - catch(Exception $e) + catch(PDOException $e) { - $this->error=$this->db->lastErrorMsg(); + $this->error=$e->getMessage(); } if (! preg_match("/^COMMIT/i",$query) && ! preg_match("/^ROLLBACK/i",$query)) @@ -501,11 +497,7 @@ class DoliDBSqlite extends DoliDB { // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion if (! is_object($resultset)) { $resultset=$this->_results; } - //return $resultset->fetch(PDO::FETCH_OBJ); - $ret = $resultset->fetchArray(SQLITE3_ASSOC); - if ($ret) { - return (object)$ret; - } + return $resultset->fetch(PDO::FETCH_OBJ); } @@ -519,11 +511,7 @@ class DoliDBSqlite extends DoliDB { // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } - //return $resultset->fetch(PDO::FETCH_ASSOC); - $ret = $resultset->fetchArray(SQLITE3_ASSOC); - if ($ret) { - return (array)$ret; - } + return $resultset->fetch(PDO::FETCH_ASSOC); } /** @@ -538,7 +526,7 @@ class DoliDBSqlite extends DoliDB if (! is_bool($resultset)) { if (! is_object($resultset)) { $resultset=$this->_results; } - return $resultset->fetchArray(SQLITE3_NUM); + return $resultset->fetch(PDO::FETCH_NUM); } else { @@ -559,9 +547,10 @@ class DoliDBSqlite extends DoliDB // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } if (preg_match("/^SELECT/i", $resultset->queryString)) { - return $this->db->querySingle("SELECT count(*) FROM (" . $resultset->queryString . ") q"); + $res = $this->db->query("SELECT count(*) FROM (" . $resultset->queryString . ") q"); + return $res->fetchColumn(); } - return 0; + return $resultset->rowCount(); } /** @@ -575,12 +564,9 @@ class DoliDBSqlite extends DoliDB { // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } - if (preg_match("/^SELECT/i", $resultset->queryString)) { - return $this->num_rows($resultset); - } // mysql necessite un link de base pour cette fonction contrairement // a pqsql qui prend un resultset - return $this->db->changes(); + return $resultset->rowCount(); } @@ -595,7 +581,7 @@ class DoliDBSqlite extends DoliDB // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } // Si resultset en est un, on libere la memoire - if ($resultset && is_object($resultset)) $resultset->finalize(); + if (is_object($resultset)) $resultset->closeCursor(); } /** @@ -606,7 +592,12 @@ class DoliDBSqlite extends DoliDB */ function escape($stringtoencode) { - return Sqlite3::escapeString($stringtoencode); + $ret = $this->db->quote($stringtoencode); + $l = strlen($ret); + if ($l >= 2) { + return substr($ret, 1, $l -2); + } + return ''; } /** @@ -654,8 +645,8 @@ class DoliDBSqlite extends DoliDB { return $errorcode_map[$this->db->errorCode()]; }*/ - $errno=$this->db->lastErrorCode(); - if ($errno=='HY000' || $errno == 0) + $errno=$this->db->errorCode(); + if ($errno=='HY000') { if (preg_match('/table.*already exists/i',$this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS'; elseif (preg_match('/index.*already exists/i',$this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS'; @@ -666,9 +657,6 @@ class DoliDBSqlite extends DoliDB if (preg_match('/column.* not unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; elseif (preg_match('/PRIMARY KEY must be unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; } - if ($errno > 1) { - // TODO Voir la liste des messages d'erreur - } return ($errno?'DB_ERROR_'.$errno:'0'); } @@ -699,7 +687,7 @@ class DoliDBSqlite extends DoliDB */ function last_insert_id($tab,$fieldid='rowid') { - return $this->db->lastInsertRowId(); + return $this->db->lastInsertId(); } /** @@ -1183,39 +1171,15 @@ class DoliDBSqlite extends DoliDB function getServerParametersValues($filter='') { $result=array(); - static $pragmas; - if (! isset($pragmas)) { - // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur - // indépendante de la base de données. - // cf. http://www.sqlite.org/pragma.html - $pragmas = array( - 'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size', - 'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list', - 'compile_options', 'data_version', /*'database_list',*/ - 'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count', - 'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check', - 'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode', - 'max_page_count', 'page_count', 'page_size', 'parser_trace', - 'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers', - 'reverse_unordered_selects', 'schema_version', 'user_version', - 'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit', - 'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads', - 'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace', - 'wal_autocheckpoint', - ); - } - // TODO prendre en compte le filtre - foreach($pragmas as $var) { - $sql = "PRAGMA $var"; - $resql=$this->query($sql); - if ($resql) - { - $obj = $this->fetch_row($resql); - //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG); - $result[$var] = $obj[0]; - } - } + $sql='SHOW VARIABLES'; + if ($filter) $sql.=" LIKE '".$this->escape($filter)."'"; + $resql=$this->query($sql); + if ($resql) + { + while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value; + } + return $result; } @@ -1228,7 +1192,7 @@ class DoliDBSqlite extends DoliDB function getServerStatusValues($filter='') { $result=array(); - /* + $sql='SHOW STATUS'; if ($filter) $sql.=" LIKE '".$this->escape($filter)."'"; $resql=$this->query($sql); @@ -1236,243 +1200,9 @@ class DoliDBSqlite extends DoliDB { while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value; } - */ return $result; } - /** - * Permet le chargement d'une fonction personnalisee dans le moteur de base de donnees. - * Note: le nom de la fonction personnalisee est prefixee par 'db_'. La fonction doit être - * statique et publique. Le nombre de parametres est determine automatiquement. - * @param string $name Le nom de la fonction a definir dans Sqlite - */ - private function addCustomFunction($name, $arg_count = -1) { - if ($this->db) { - $localname = __CLASS__ . '::' . 'db_' . $name; - $reflectClass = new ReflectionClass(__CLASS__); - $reflectFunction = $reflectClass->getMethod('db_' . $name); - if ($arg_count < 0) { - $arg_count = $reflectFunction->getNumberOfParameters(); - } - if (!$this->db->createFunction($name, $localname , $arg_count)) { - $this->error = "unable to create custom function '$name'"; - } - } - } - - /** - * Cette fonction est l'equivalent de la fonction MONTH de MySql. - * @param string $date - * @return integer - */ - public static function db_MONTH($date) { - return date('n', strtotime($date)); - } - - /** - * calcule du numéro de semaine - * - * @param string date - * @param int mode - */ - public static function db_WEEK($date, $mode = 0) { - $arr = date_parse($date); - $calc_year = 0; - return self::calc_week($arr['year'], $arr['month'], $arr['day'], self::week_mode($mode), $calc_year); - } - - public static function db_CURDATE() { - return date('Y-m-d'); - } - - public static function db_CURTIME() { - return date('H:i:s'); - } - - public static function db_WEEKDAY($date) { - $arr = date_parse($date); - return self::calc_weekday(self::calc_daynr($arr['year'], $arr['month'], $arr['day']), 0); - - } - - /** - * Cette fonction est l'equivelent de la fonction date_format de MySQL. - * @staticvar string $mysql_replacement Les symboles formatage a remplacer - * @param string $date la date dans un format ISO - * @param string $format la chaine de formatage - * @return string La date formatee. - */ - public static function db_date_format($date, $format) { - static $mysql_replacement; - if (! isset($mysql_replacement)) { - $mysql_replacement = array( - '%' => '%', - 'a' => 'D', - 'b' => 'M', - 'c' => 'n', - 'D' => 'jS', - 'd' => 'd', - 'e' => 'j', - 'f' => 'u', - 'H' => 'H', - 'h' => 'h', - 'I' => 'h', - 'i' => 'i', - 'k' => 'H', - 'l' => 'g', - 'M' => 'F', - 'm' => 'm', - 'p' => 'A', - 'r' => 'h:i:s A', - 'S' => 's', - 's' => 's', - 'T' => 'H:i:s', - 'W' => 'l', - 'w' => 'w', - 'Y' => 'Y', - 'y' => 'y', - ); - } - - $fmt = ''; - $lg = strlen($format); - $state = 0; - $timestamp = strtotime($date); - $yday = date('z', $timestamp); - $month = (integer)date("n", $timestamp); - $year = (integer)date("Y", $timestamp); - $day = (integer)date("d", $timestamp); - for($idx = 0; $idx < $lg; ++$idx) { - $char = $format[$idx]; - if ($state == 0) { - if ($char == '%') { - $state = 1; - } else { - $fmt .= $char; - } - } - elseif ($state == 1) { - if (array_key_exists($char, $mysql_replacement)) { - $fmt .= $mysql_replacement[$char]; - } else { - $calc_year = 0; - switch ($char) { - case 'j': // day of the year 001 - $char = sprintf("%03d", $yday+1); - break; - case 'U': // mode 0: semaine 0 = premiere semaine complète qui commence un dimanche - $char = sprintf("%02d", self::calc_week($year, $month, $day, 4, $calc_year)); - break; - case 'u': // mode 1: semaine 0 = première semaine de 4 jours. Début le dimanche - $char = sprintf("%02d", self::calc_week($year, $month, $day, 1, $calc_year)); - break; - case 'V': // mode 2: semaine 1 = premiere semaine complète qui commence un dimanche - $char = sprintf("%02d", self::calc_week($year, $month, $day, 6, $calc_year)); - break; - case 'v': // mode 3: semaine 1 = premiere semaine de 4 jours. Début le lundi - $char = sprintf("%02d", self::calc_week($year, $month, $day, 3, $calc_year)); - break; - case 'X': - self::calc_week($year, $month, $day, 6, $calc_year); - $char = sprintf("%04d", $calc_year); - break; - case 'x': - self::calc_week($year, $month, $day, 3, $calc_year); - $char = sprintf("%04d", $calc_year); - break; - } - $fmt .= $char; - } - $state = 0; - } - } - return date($fmt, strtotime($date)); - } - - /** - * Equivalent de la fonction MySQL IF - * @param boolean $test Le resultat du test - * @param mixed $true_part Partie a retourner si vrai - * @param mixed $false_part Partie a retourner si faux - * @return mixed Partie selectionnee en fonction du test - */ - public static function db_IF($test, $true_part, $false_part) { - return ( $test ) ? $true_part : $false_part; - } - - // Adapté de mytime.c des sources de mariadb - // fonction calc_daynr - private static function calc_daynr($year, $month, $day) { - $y = $year; - if ($y == 0 && $month == 0) return 0; - $num = (365* $y + 31 * ($month - 1) + $day); - if ($month <= 2) { - $y--; } - else { - $num -= floor(($month * 4 + 23) / 10); - } - $temp = floor(($y / 100 + 1) * 3 / 4); - return $num + floor($y / 4) - $temp; - } - - private static function calc_weekday($daynr, $sunday_first_day_of_week) { - $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7); - return $ret; - } - - private static function calc_days_in_year($year) - { - return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365); - } - - private static function week_mode($mode) { - $week_format= ($mode & 7); - if (!($week_format & self::WEEK_MONDAY_FIRST)) { - $week_format^= self::WEEK_FIRST_WEEKDAY; - } - return $week_format; - } - - - private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year) { - $daynr=self::calc_daynr($year,$month,$day); - $first_daynr=self::calc_daynr($year,1,1); - $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0; - $week_year= ($week_behaviour & self::WEEK_YEAR) ? 1 : 0; - $first_weekday= ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0; - - $weekday=self::calc_weekday($first_daynr, !$monday_first); - $calc_year=$year; - - if ($month == 1 && $day <= 7-$weekday) - { - if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4))) - return 0; - $week_year= 1; - $calc_year--; - $first_daynr-= ($days=self::calc_days_in_year($calc_year)); - $weekday= ($weekday + 53*7- $days) % 7; - } - - if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) { - $days= $daynr - ($first_daynr+ (7-$weekday)); - } - else { - $days= $daynr - ($first_daynr - $weekday); - } - - if ($week_year && $days >= 52*7) - { - $weekday= ($weekday + self::calc_days_in_year($calc_year)) % 7; - if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0)) - { - $calc_year++; - return 1; - } - } - return floor($days/7+1); - } - } diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php new file mode 100644 index 00000000000..f232acb199e --- /dev/null +++ b/htdocs/core/db/sqlite3.class.php @@ -0,0 +1,1478 @@ + + * Copyright (C) 2002-2005 Rodolphe Quiedeville + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2005-2009 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/db/sqlite.class.php + * \brief Class file to manage Dolibarr database access for a Sqlite database + */ + +require_once DOL_DOCUMENT_ROOT .'/core/db/DoliDB.class.php'; + +/** + * Class to manage Dolibarr database access for a Sqlite database + */ +class DoliDBSqlite3 extends DoliDB +{ + //! Database type + public $type='sqlite3'; + //! Database label + const LABEL='Sqlite3'; + //! Version min database + const VERSIONMIN='3.0.0'; + //! Resultset of last query + private $_results; + + const WEEK_MONDAY_FIRST=1; + const WEEK_YEAR = 2; + const WEEK_FIRST_WEEKDAY=4; + + + /** + * Constructor. + * This create an opened connexion to a database server and eventually to a database + * + * @param string $type Type of database (mysql, pgsql...) + * @param string $host Address of database server + * @param string $user Nom de l'utilisateur autorise + * @param string $pass Mot de passe + * @param string $name Nom de la database + * @param int $port Port of database server + */ + function __construct($type, $host, $user, $pass, $name='', $port=0) + { + global $conf,$langs; + + // Note that having "static" property for "$forcecharset" and "$forcecollate" will make error here in strict mode, so they are not static + if (! empty($conf->db->character_set)) $this->forcecharset=$conf->db->character_set; + if (! empty($conf->db->dolibarr_main_db_collation)) $this->forcecollate=$conf->db->dolibarr_main_db_collation; + + $this->database_user=$user; + $this->database_host=$host; + $this->database_port=$port; + + $this->transaction_opened=0; + + //print "Name DB: $host,$user,$pass,$name
"; + + /*if (! function_exists("sqlite_query")) + { + $this->connected = 0; + $this->ok = 0; + $this->error="Sqlite PHP functions for using Sqlite driver are not available in this version of PHP. Try to use another driver."; + dol_syslog(get_class($this)."::DoliDBSqlite3 : Sqlite PHP functions for using Sqlite driver are not available in this version of PHP. Try to use another driver.",LOG_ERR); + return $this->ok; + }*/ + + /*if (! $host) + { + $this->connected = 0; + $this->ok = 0; + $this->error=$langs->trans("ErrorWrongHostParameter"); + dol_syslog(get_class($this)."::DoliDBSqlite3 : Erreur Connect, wrong host parameters",LOG_ERR); + return $this->ok; + }*/ + + // Essai connexion serveur + // We do not try to connect to database, only to server. Connect to database is done later in constrcutor + $this->db = $this->connect($host, $user, $pass, $name, $port); + + if ($this->db) + { + $this->connected = 1; + $this->ok = 1; + $this->database_selected = 1; + $this->database_name = $name; + + $this->addCustomFunction('IF'); + $this->addCustomFunction('MONTH'); + $this->addCustomFunction('CURTIME'); + $this->addCustomFunction('CURDATE'); + $this->addCustomFunction('WEEK', 1); + $this->addCustomFunction('WEEK', 2); + $this->addCustomFunction('WEEKDAY'); + $this->addCustomFunction('date_format'); + //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + else + { + // host, login ou password incorrect + $this->connected = 0; + $this->ok = 0; + $this->database_selected = 0; + $this->database_name = ''; + //$this->error=sqlite_connect_error(); + dol_syslog(get_class($this)."::DoliDBSqlite3 : Error Connect ".$this->error,LOG_ERR); + } + + return $this->ok; + } + + + /** + * Convert a SQL request in Mysql syntax to native syntax + * + * @param string $line SQL request line to convert + * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) + * @return string SQL request line converted + */ + static function convertSQLFromMysql($line,$type='ddl') + { + // Removed empty line if this is a comment line for SVN tagging + if (preg_match('/^--\s\$Id/i',$line)) { + return ''; + } + // Return line if this is a comment + if (preg_match('/^#/i',$line) || preg_match('/^$/i',$line) || preg_match('/^--/i',$line)) + { + return $line; + } + if ($line != "") + { + if ($type == 'auto') + { + if (preg_match('/ALTER TABLE/i',$line)) $type='dml'; + else if (preg_match('/CREATE TABLE/i',$line)) $type='dml'; + else if (preg_match('/DROP TABLE/i',$line)) $type='dml'; + } + + if ($type == 'dml') + { + $line=preg_replace('/\s/',' ',$line); // Replace tabulation with space + + // we are inside create table statement so lets process datatypes + if (preg_match('/(ISAM|innodb)/i',$line)) { // end of create table sequence + $line=preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); + $line=preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); + $line=preg_replace('/,$/','',$line); + } + + // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..." + if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) { + $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line); + //$line = "-- ".$line." replaced by --\n".$newline; + $line=$newline; + } + + // tinyint type conversion + $line=str_replace('tinyint','smallint',$line); + + // nuke unsigned + $line=preg_replace('/(int\w+|smallint)\s+unsigned/i','\\1',$line); + + // blob -> text + $line=preg_replace('/\w*blob/i','text',$line); + + // tinytext/mediumtext -> text + $line=preg_replace('/tinytext/i','text',$line); + $line=preg_replace('/mediumtext/i','text',$line); + + // change not null datetime field to null valid ones + // (to support remapping of "zero time" to null + $line=preg_replace('/datetime not null/i','datetime',$line); + $line=preg_replace('/datetime/i','timestamp',$line); + + // double -> numeric + $line=preg_replace('/^double/i','numeric',$line); + $line=preg_replace('/(\s*)double/i','\\1numeric',$line); + // float -> numeric + $line=preg_replace('/^float/i','numeric',$line); + $line=preg_replace('/(\s*)float/i','\\1numeric',$line); + + // unique index(field1,field2) + if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i',$line)) + { + $line=preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i','UNIQUE\(\\1\)',$line); + } + + // We remove end of requests "AFTER fieldxxx" + $line=preg_replace('/AFTER [a-z0-9_]+/i','',$line); + + // We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX + $line=preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i','DROP INDEX',$line); + + // Translate order to rename fields + if (preg_match('/ALTER TABLE ([a-z0-9_]+) CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "ALTER TABLE ".$reg[1]." RENAME COLUMN ".$reg[2]." TO ".$reg[3]; + } + + // Translate order to modify field format + if (preg_match('/ALTER TABLE ([a-z0-9_]+) MODIFY(?: COLUMN)? ([a-z0-9_]+) (.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $newreg3=$reg[3]; + $newreg3=preg_replace('/ DEFAULT NULL/i','',$newreg3); + $newreg3=preg_replace('/ NOT NULL/i','',$newreg3); + $newreg3=preg_replace('/ NULL/i','',$newreg3); + $newreg3=preg_replace('/ DEFAULT 0/i','',$newreg3); + $newreg3=preg_replace('/ DEFAULT \'[0-9a-zA-Z_@]*\'/i','',$newreg3); + $line.= "ALTER TABLE ".$reg[1]." ALTER COLUMN ".$reg[2]." TYPE ".$newreg3; + // TODO Add alter to set default value or null/not null if there is this in $reg[3] + } + + // alter table add primary key (field1, field2 ...) -> We create a unique index instead as dynamic creation of primary key is not supported + // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity); + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "CREATE UNIQUE INDEX ".$reg[2]." ON ".$reg[1]."(".$reg[3]; + } + + // Translate order to drop foreign keys + // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx; + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*DROP\s+FOREIGN\s+KEY\s*(.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "ALTER TABLE ".$reg[1]." DROP CONSTRAINT ".$reg[2]; + } + + // alter table add [unique] [index] (field1, field2 ...) + // ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version) + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i',$line,$reg)) + { + $fieldlist=$reg[4]; + $idxname=$reg[3]; + $tablename=$reg[1]; + $line = "-- ".$line." replaced by --\n"; + $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")"; + } + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$line, $reg)) { + // Pour l'instant les contraintes ne sont pas créées + dol_syslog(get_class().'::query line emptied'); + $line = 'SELECT 0;'; + + } + + //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) { + //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line); + //} + } + + // Delete using criteria on other table must not declare twice the deleted table + // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable + if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg)) + { + if ($reg[1] == $reg[2]) // If same table, we remove second one + { + $line=preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i','DELETE FROM \\1 USING \\3', $line); + } + } + + // Remove () in the tables in FROM if one table + $line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line); + //print $line."\n"; + + // Remove () in the tables in FROM if two table + $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2',$line); + //print $line."\n"; + + // Remove () in the tables in FROM if two table + $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2, \\3',$line); + //print $line."\n"; + + //print "type=".$type." newline=".$line."
\n"; + } + + return $line; + } + + /** + * Select a database + * + * @param string $database Name of database + * @return boolean true if OK, false if KO + */ + function select_db($database) + { + dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG); + return sqlite_select_db($this->db,$database); + } + + + /** + * Connexion to server + * + * @param string $host database server host + * @param string $login login + * @param string $passwd password + * @param string $name name of database (not used for mysql, used for pgsql) + * @param string $port Port of database server + * @return resource Database access handler + * @see close + */ + function connect($host, $login, $passwd, $name, $port=0) + { + global $conf,$main_data_dir; + + dol_syslog(get_class($this)."::connect name=".$name,LOG_DEBUG); + + $dir=$main_data_dir; + if (empty($dir)) $dir=DOL_DATA_ROOT; + // With sqlite, port must be in connect parameters + //if (! $newport) $newport=3306; + $database_name = $dir.'/database_'.$name.'.sdb'; + try { + /*** connect to SQLite database ***/ + //$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb'); + $this->db = new SQLite3($database_name); + //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + catch(Exception $e) + { + $this->error= self::LABEL.' '.$e->getMessage().' current dir='.$database_name; + return ''; + } + + //print "Resultat fonction connect: ".$this->db; + return $this->db; + } + + + /** + * Return version of database server + * + * @return string Version string + */ + function getVersion() + { + return $this->db->version()['versionString']; + } + + /** + * Return version of database client driver + * + * @return string Version string + */ + function getDriverInfo() + { + // FIXME: Dummy method + // TODO: Implement + + return ''; + } + + + /** + * Close database connexion + * + * @return boolean True if disconnect successfull, false otherwise + * @see connect + */ + function close() + { + if ($this->db) + { + if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened,LOG_ERR); + $this->connected=0; + $this->db->close(); + $this->db=null; // Clean this->db + return true; + } + return false; + } + + /** + * Execute a SQL request and return the resultset + * + * @param string $query SQL query string + * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollbock to savepoint if error (this allow to have some request with errors inside global transactions). + * Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints. + * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) + * @return resource Resultset of answer + */ + function query($query,$usesavepoint=0,$type='auto') + { + $errmsg=''; + + $ret=''; + $query = trim($query); + $this->error = 0; + + // Convert MySQL syntax to SQLite syntax + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$query, $reg)) { + // Ajout d'une clef étrangère à la table + // procédure de remplacement de la table pour ajouter la contrainte + // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid) + // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)) + $foreignFields = $reg[5]; + $foreignTable = $reg[4]; + $localfields = $reg[3]; + $constraintname=trim($reg[2]); + $tablename=trim($reg[1]); + + $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); + + // 1- Renommer la table avec un nom temporaire + $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); + + // 2- Recréer la table avec la contrainte ajoutée + + // on bricole la requete pour ajouter la contrainte + $descTable = substr($descTable, 0, strlen($descTable) - 1); + $descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")"; + + // fermeture de l'instruction + $descTable .= ')'; + + // Création proprement dite de la table + $this->query($descTable); + + // 3- Transférer les données + $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); + + // 4- Supprimer la table temporaire + $this->query('DROP TABLE tmp_' . $tablename); + + // dummy statement + $query="SELECT 0"; + + } else { + $query=$this->convertSQLFromMysql($query,$type); + } + //print "After convertSQLFromMysql:\n".$query."
\n"; + + dol_syslog('sql='.$query, LOG_DEBUG); + + // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE) + try { + //$ret = $this->db->exec($query); + $ret = $this->db->query($query); // $ret is a PDO object + if ($ret) { + $ret->queryString = $query; + } + } + catch(Exception $e) + { + $this->error=$this->db->lastErrorMsg(); + } + + if (! preg_match("/^COMMIT/i",$query) && ! preg_match("/^ROLLBACK/i",$query)) + { + // Si requete utilisateur, on la sauvegarde ainsi que son resultset + if (! is_object($ret) || $this->error) + { + $this->lastqueryerror = $query; + $this->lasterror = $this->error(); + $this->lasterrno = $this->errno(); + + dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); + + $errormsg = get_class($this)."::query SQL Error message: ".$this->lasterror; + + if (preg_match('/[0-9]/',$this->lasterrno)) { + $errormsg .= ' ('.$this->lasterrno.')'; + } + + dol_syslog($errormsg, LOG_ERR); + } + $this->lastquery=$query; + $this->_results = $ret; + } + + return $ret; + } + + /** + * Renvoie la ligne courante (comme un objet) pour le curseur resultset + * + * @param Resultset $resultset Curseur de la requete voulue + * @return Object Object result line or false if KO or end of cursor + */ + function fetch_object($resultset) + { + // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + //return $resultset->fetch(PDO::FETCH_OBJ); + $ret = $resultset->fetchArray(SQLITE3_ASSOC); + if ($ret) { + return (object)$ret; + } + } + + + /** + * Return datas as an array + * + * @param Resultset $resultset Resultset of request + * @return array Array + */ + function fetch_array($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + //return $resultset->fetch(PDO::FETCH_ASSOC); + $ret = $resultset->fetchArray(SQLITE3_ASSOC); + if ($ret) { + return (array)$ret; + } + } + + /** + * Return datas as an array + * + * @param Resultset $resultset Resultset of request + * @return array Array + */ + function fetch_row($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_bool($resultset)) + { + if (! is_object($resultset)) { $resultset=$this->_results; } + return $resultset->fetchArray(SQLITE3_NUM); + } + else + { + // si le curseur est un booleen on retourne la valeur 0 + return 0; + } + } + + /** + * Return number of lines for result of a SELECT + * + * @param Resultset $resultset Resulset of requests + * @return int Nb of lines + * @see affected_rows + */ + function num_rows($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + if (preg_match("/^SELECT/i", $resultset->queryString)) { + return $this->db->querySingle("SELECT count(*) FROM (" . $resultset->queryString . ") q"); + } + return 0; + } + + /** + * Return number of lines for result of a SELECT + * + * @param Resultset $resultset Resulset of requests + * @return int Nb of lines + * @see affected_rows + */ + function affected_rows($resultset) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + if (preg_match("/^SELECT/i", $resultset->queryString)) { + return $this->num_rows($resultset); + } + // mysql necessite un link de base pour cette fonction contrairement + // a pqsql qui prend un resultset + return $this->db->changes(); + } + + + /** + * Free last resultset used. + * + * @param resultset $resultset Curseur de la requete voulue + * @return void + */ + function free($resultset=0) + { + // If resultset not provided, we take the last used by connexion + if (! is_object($resultset)) { $resultset=$this->_results; } + // Si resultset en est un, on libere la memoire + if ($resultset && is_object($resultset)) $resultset->finalize(); + } + + /** + * Escape a string to insert data + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + function escape($stringtoencode) + { + return Sqlite3::escapeString($stringtoencode); + } + + /** + * Renvoie le code erreur generique de l'operation precedente. + * + * @return string Error code (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...) + */ + function errno() + { + if (! $this->connected) { + // Si il y a eu echec de connexion, $this->db n'est pas valide. + return 'DB_ERROR_FAILED_TO_CONNECT'; + } + else { + // Constants to convert error code to a generic Dolibarr error code + /*$errorcode_map = array( + 1004 => 'DB_ERROR_CANNOT_CREATE', + 1005 => 'DB_ERROR_CANNOT_CREATE', + 1006 => 'DB_ERROR_CANNOT_CREATE', + 1007 => 'DB_ERROR_ALREADY_EXISTS', + 1008 => 'DB_ERROR_CANNOT_DROP', + 1025 => 'DB_ERROR_NO_FOREIGN_KEY_TO_DROP', + 1044 => 'DB_ERROR_ACCESSDENIED', + 1046 => 'DB_ERROR_NODBSELECTED', + 1048 => 'DB_ERROR_CONSTRAINT', + 'HY000' => 'DB_ERROR_TABLE_ALREADY_EXISTS', + 1051 => 'DB_ERROR_NOSUCHTABLE', + 1054 => 'DB_ERROR_NOSUCHFIELD', + 1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS', + 1061 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS', + 1062 => 'DB_ERROR_RECORD_ALREADY_EXISTS', + 1064 => 'DB_ERROR_SYNTAX', + 1068 => 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS', + 1075 => 'DB_ERROR_CANT_DROP_PRIMARY_KEY', + 1091 => 'DB_ERROR_NOSUCHFIELD', + 1100 => 'DB_ERROR_NOT_LOCKED', + 1136 => 'DB_ERROR_VALUE_COUNT_ON_ROW', + 1146 => 'DB_ERROR_NOSUCHTABLE', + 1216 => 'DB_ERROR_NO_PARENT', + 1217 => 'DB_ERROR_CHILD_EXISTS', + 1451 => 'DB_ERROR_CHILD_EXISTS' + ); + + if (isset($errorcode_map[$this->db->errorCode()])) + { + return $errorcode_map[$this->db->errorCode()]; + }*/ + $errno=$this->db->lastErrorCode(); + if ($errno=='HY000' || $errno == 0) + { + if (preg_match('/table.*already exists/i',$this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS'; + elseif (preg_match('/index.*already exists/i',$this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS'; + elseif (preg_match('/syntax error/i',$this->error)) return 'DB_ERROR_SYNTAX'; + } + if ($errno=='23000') + { + if (preg_match('/column.* not unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; + elseif (preg_match('/PRIMARY KEY must be unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; + } + if ($errno > 1) { + // TODO Voir la liste des messages d'erreur + } + + return ($errno?'DB_ERROR_'.$errno:'0'); + } + } + + /** + * Renvoie le texte de l'erreur mysql de l'operation precedente. + * + * @return string Error text + */ + function error() + { + if (! $this->connected) { + // Si il y a eu echec de connexion, $this->db n'est pas valide pour sqlite_error. + return 'Not connected. Check setup parameters in conf/conf.php file and your sqlite version'; + } + else { + return $this->error; + } + } + + /** + * Get last ID after an insert INSERT + * + * @param string $tab Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql + * @param string $fieldid Field name + * @return int Id of row + */ + function last_insert_id($tab,$fieldid='rowid') + { + return $this->db->lastInsertRowId(); + } + + /** + * Encrypt sensitive data in database + * Warning: This function includes the escape, so it must use direct value + * + * @param string $fieldorvalue Field name or value to encrypt + * @param int $withQuotes Return string with quotes + * @return return XXX(field) or XXX('value') or field or 'value' + */ + function encrypt($fieldorvalue, $withQuotes=0) + { + global $conf; + + // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption) + $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0); + + //Encryption key + $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:''); + + $return = ($withQuotes?"'":"").$this->escape($fieldorvalue).($withQuotes?"'":""); + + if ($cryptType && !empty($cryptKey)) + { + if ($cryptType == 2) + { + $return = 'AES_ENCRYPT('.$return.',\''.$cryptKey.'\')'; + } + else if ($cryptType == 1) + { + $return = 'DES_ENCRYPT('.$return.',\''.$cryptKey.'\')'; + } + } + + return $return; + } + + /** + * Decrypt sensitive data in database + * + * @param string $value Value to decrypt + * @return string Decrypted value if used + */ + function decrypt($value) + { + global $conf; + + // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption) + $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0); + + //Encryption key + $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:''); + + $return = $value; + + if ($cryptType && !empty($cryptKey)) + { + if ($cryptType == 2) + { + $return = 'AES_DECRYPT('.$value.',\''.$cryptKey.'\')'; + } + else if ($cryptType == 1) + { + $return = 'DES_DECRYPT('.$value.',\''.$cryptKey.'\')'; + } + } + + return $return; + } + + + /** + * Return connexion ID + * + * @return string Id connexion + */ + function DDLGetConnectId() + { + return '?'; + } + + + /** + * Create a new database + * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated + * We force to create database with charset this->forcecharset and collate this->forcecollate + * + * @param string $database Database name to create + * @param string $charset Charset used to store data + * @param string $collation Charset used to sort data + * @param string $owner Username of database owner + * @return resource resource defined if OK, null if KO + */ + function DDLCreateDb($database,$charset='',$collation='',$owner='') + { + if (empty($charset)) $charset=$this->forcecharset; + if (empty($collation)) $collation=$this->forcecollate; + + // ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci + $sql = 'CREATE DATABASE '.$database; + $sql.= ' DEFAULT CHARACTER SET '.$charset.' DEFAULT COLLATE '.$collation; + + dol_syslog($sql,LOG_DEBUG); + $ret=$this->query($sql); + if (! $ret) + { + // We try again for compatibility with Mysql < 4.1.1 + $sql = 'CREATE DATABASE '.$database; + $ret=$this->query($sql); + dol_syslog($sql,LOG_DEBUG); + } + return $ret; + } + + /** + * List tables into a database + * + * @param string $database Name of database + * @param string $table Name of table filter ('xxx%') + * @return array List of tables in an array + */ + function DDLListTables($database, $table='') + { + $listtables=array(); + + $like = ''; + if ($table) $like = "LIKE '".$table."'"; + $sql="SHOW TABLES FROM ".$database." ".$like.";"; + //print $sql; + $result = $this->query($sql); + while($row = $this->fetch_row($result)) + { + $listtables[] = $row[0]; + } + return $listtables; + } + + /** + * List information of columns into a table. + * + * @param string $table Name of table + * @return array Tableau des informations des champs de la table + * TODO modify for sqlite + */ + function DDLInfoTable($table) + { + $infotables=array(); + + $sql="SHOW FULL COLUMNS FROM ".$table.";"; + + dol_syslog($sql,LOG_DEBUG); + $result = $this->query($sql); + while($row = $this->fetch_row($result)) + { + $infotables[] = $row; + } + return $infotables; + } + + /** + * Create a table into database + * + * @param string $table Nom de la table + * @param array $fields Tableau associatif [nom champ][tableau des descriptions] + * @param string $primary_key Nom du champ qui sera la clef primaire + * @param string $type Type de la table + * @param array $unique_keys Tableau associatifs Nom de champs qui seront clef unique => valeur + * @param array $fulltext_keys Tableau des Nom de champs qui seront indexes en fulltext + * @param string $keys Tableau des champs cles noms => valeur + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys="",$fulltext_keys="",$keys="") + { + // cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra + // ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment'); + $sql = "create table ".$table."("; + $i=0; + foreach($fields as $field_name => $field_desc) + { + $sqlfields[$i] = $field_name." "; + $sqlfields[$i] .= $field_desc['type']; + if( preg_match("/^[^\s]/i",$field_desc['value'])) + $sqlfields[$i] .= "(".$field_desc['value'].")"; + else if( preg_match("/^[^\s]/i",$field_desc['attribute'])) + $sqlfields[$i] .= " ".$field_desc['attribute']; + else if( preg_match("/^[^\s]/i",$field_desc['default'])) + { + if(preg_match("/null/i",$field_desc['default'])) + $sqlfields[$i] .= " default ".$field_desc['default']; + else + $sqlfields[$i] .= " default '".$field_desc['default']."'"; + } + else if( preg_match("/^[^\s]/i",$field_desc['null'])) + $sqlfields[$i] .= " ".$field_desc['null']; + + else if( preg_match("/^[^\s]/i",$field_desc['extra'])) + $sqlfields[$i] .= " ".$field_desc['extra']; + $i++; + } + if($primary_key != "") + $pk = "primary key(".$primary_key.")"; + + if($unique_keys != "") + { + $i = 0; + foreach($unique_keys as $key => $value) + { + $sqluq[$i] = "UNIQUE KEY '".$key."' ('".$value."')"; + $i++; + } + } + if($keys != "") + { + $i = 0; + foreach($keys as $key => $value) + { + $sqlk[$i] = "KEY ".$key." (".$value.")"; + $i++; + } + } + $sql .= implode(',',$sqlfields); + if($primary_key != "") + $sql .= ",".$pk; + if($unique_keys != "") + $sql .= ",".implode(',',$sqluq); + if($keys != "") + $sql .= ",".implode(',',$sqlk); + $sql .=") type=".$type; + + dol_syslog($sql,LOG_DEBUG); + if(! $this -> query($sql)) + return -1; + else + return 1; + } + + /** + * Return a pointer of line with description of a table or field + * + * @param string $table Name of table + * @param string $field Optionnel : Name of field if we want description of field + * @return resource Resource + */ + function DDLDescTable($table,$field="") + { + $sql="DESC ".$table." ".$field; + + dol_syslog(get_class($this)."::DDLDescTable ".$sql,LOG_DEBUG); + $this->_results = $this->query($sql); + return $this->_results; + } + + /** + * Create a new field into table + * + * @param string $table Name of table + * @param string $field_name Name of field to add + * @param string $field_desc Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre] + * @param string $field_position Optionnel ex.: "after champtruc" + * @return int <0 if KO, >0 if OK + */ + function DDLAddField($table,$field_name,$field_desc,$field_position="") + { + // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra + // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment'); + $sql= "ALTER TABLE ".$table." ADD ".$field_name." "; + $sql.= $field_desc['type']; + if(preg_match("/^[^\s]/i",$field_desc['value'])) + if (! in_array($field_desc['type'],array('date','datetime'))) + { + $sql.= "(".$field_desc['value'].")"; + } + if(preg_match("/^[^\s]/i",$field_desc['attribute'])) + $sql.= " ".$field_desc['attribute']; + if(preg_match("/^[^\s]/i",$field_desc['null'])) + $sql.= " ".$field_desc['null']; + if(preg_match("/^[^\s]/i",$field_desc['default'])) + { + if(preg_match("/null/i",$field_desc['default'])) + $sql.= " default ".$field_desc['default']; + else + $sql.= " default '".$field_desc['default']."'"; + } + if(preg_match("/^[^\s]/i",$field_desc['extra'])) + $sql.= " ".$field_desc['extra']; + $sql.= " ".$field_position; + + dol_syslog(get_class($this)."::DDLAddField ".$sql,LOG_DEBUG); + if(! $this->query($sql)) + { + return -1; + } + else + { + return 1; + } + } + + /** + * Update format of a field into a table + * + * @param string $table Name of table + * @param string $field_name Name of field to modify + * @param string $field_desc Array with description of field format + * @return int <0 if KO, >0 if OK + */ + function DDLUpdateField($table,$field_name,$field_desc) + { + $sql = "ALTER TABLE ".$table; + $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type']; + if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') { + $sql.="(".$field_desc['value'].")"; + } + + dol_syslog(get_class($this)."::DDLUpdateField ".$sql,LOG_DEBUG); + if (! $this->query($sql)) + return -1; + else + return 1; + } + + /** + * Drop a field from table + * + * @param string $table Name of table + * @param string $field_name Name of field to drop + * @return int <0 if KO, >0 if OK + */ + function DDLDropField($table,$field_name) + { + $sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`"; + dol_syslog(get_class($this)."::DDLDropField ".$sql,LOG_DEBUG); + if (! $this->query($sql)) + { + $this->error=$this->lasterror(); + return -1; + } + else return 1; + } + + + /** + * Create a user and privileges to connect to database (even if database does not exists yet) + * + * @param string $dolibarr_main_db_host Ip serveur + * @param string $dolibarr_main_db_user Nom user a creer + * @param string $dolibarr_main_db_pass Mot de passe user a creer + * @param string $dolibarr_main_db_name Database name where user must be granted + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name) + { + $sql = "INSERT INTO user "; + $sql.= "(Host,User,password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)"; + $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_user)."',password('".addslashes($dolibarr_main_db_pass)."')"; + $sql.= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')"; + + dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log + $resql=$this->query($sql); + if (! $resql) + { + return -1; + } + + $sql = "INSERT INTO db "; + $sql.= "(Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)"; + $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_name)."','".addslashes($dolibarr_main_db_user)."'"; + $sql.= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')"; + + dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); + $resql=$this->query($sql); + if (! $resql) + { + return -1; + } + + $sql="FLUSH Privileges"; + + dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); + $resql=$this->query($sql); + if (! $resql) + { + return -1; + } + + return 1; + } + + /** + * Return charset used to store data in database + * + * @return string Charset + */ + function getDefaultCharacterSetDatabase() + { + return 'UTF-8'; + } + + /** + * Return list of available charset that can be used to store data in database + * + * @return array List of Charset + */ + function getListOfCharacterSet() + { + $liste = array(); + $i=0; + $liste[$i]['charset'] = 'UTF-8'; + $liste[$i]['description'] = 'UTF-8'; + return $liste; + } + + /** + * Return collation used in database + * + * @return string Collation value + */ + function getDefaultCollationDatabase() + { + return 'UTF-8'; + } + + /** + * Return list of available collation that can be used for database + * + * @return array List of Collation + */ + function getListOfCollation() + { + $liste = array(); + $i=0; + $liste[$i]['charset'] = 'UTF-8'; + $liste[$i]['description'] = 'UTF-8'; + return $liste; + } + + /** + * Return full path of dump program + * + * @return string Full path of dump program + */ + function getPathOfDump() + { + $fullpathofdump='/pathtomysqldump/mysqldump'; + + $resql=$this->query('SHOW VARIABLES LIKE \'basedir\''); + if ($resql) + { + $liste=$this->fetch_array($resql); + $basedir=$liste['Value']; + $fullpathofdump=$basedir.(preg_match('/\/$/',$basedir)?'':'/').'bin/mysqldump'; + } + return $fullpathofdump; + } + + /** + * Return full path of restore program + * + * @return string Full path of restore program + */ + function getPathOfRestore() + { + $fullpathofimport='/pathtomysql/mysql'; + + $resql=$this->query('SHOW VARIABLES LIKE \'basedir\''); + if ($resql) + { + $liste=$this->fetch_array($resql); + $basedir=$liste['Value']; + $fullpathofimport=$basedir.(preg_match('/\/$/',$basedir)?'':'/').'bin/mysql'; + } + return $fullpathofimport; + } + + /** + * Return value of server parameters + * + * @param string $filter Filter list on a particular value + * @return array Array of key-values (key=>value) + */ + function getServerParametersValues($filter='') + { + $result=array(); + static $pragmas; + if (! isset($pragmas)) { + // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur + // indépendante de la base de données. + // cf. http://www.sqlite.org/pragma.html + $pragmas = array( + 'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size', + 'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list', + 'compile_options', 'data_version', /*'database_list',*/ + 'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count', + 'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check', + 'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode', + 'max_page_count', 'page_count', 'page_size', 'parser_trace', + 'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers', + 'reverse_unordered_selects', 'schema_version', 'user_version', + 'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit', + 'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads', + 'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace', + 'wal_autocheckpoint', + ); + } + + // TODO prendre en compte le filtre + foreach($pragmas as $var) { + $sql = "PRAGMA $var"; + $resql=$this->query($sql); + if ($resql) + { + $obj = $this->fetch_row($resql); + //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG); + $result[$var] = $obj[0]; + } + } + return $result; + } + + /** + * Return value of server status + * + * @param string $filter Filter list on a particular value + * @return array Array of key-values (key=>value) + */ + function getServerStatusValues($filter='') + { + $result=array(); + /* + $sql='SHOW STATUS'; + if ($filter) $sql.=" LIKE '".$this->escape($filter)."'"; + $resql=$this->query($sql); + if ($resql) + { + while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value; + } + */ + + return $result; + } + + /** + * Permet le chargement d'une fonction personnalisee dans le moteur de base de donnees. + * Note: le nom de la fonction personnalisee est prefixee par 'db_'. La fonction doit être + * statique et publique. Le nombre de parametres est determine automatiquement. + * @param string $name Le nom de la fonction a definir dans Sqlite + */ + private function addCustomFunction($name, $arg_count = -1) { + if ($this->db) { + $localname = __CLASS__ . '::' . 'db_' . $name; + $reflectClass = new ReflectionClass(__CLASS__); + $reflectFunction = $reflectClass->getMethod('db_' . $name); + if ($arg_count < 0) { + $arg_count = $reflectFunction->getNumberOfParameters(); + } + if (!$this->db->createFunction($name, $localname , $arg_count)) { + $this->error = "unable to create custom function '$name'"; + } + } + } + + /** + * Cette fonction est l'equivalent de la fonction MONTH de MySql. + * @param string $date + * @return integer + */ + public static function db_MONTH($date) { + return date('n', strtotime($date)); + } + + /** + * calcule du numéro de semaine + * + * @param string date + * @param int mode + */ + public static function db_WEEK($date, $mode = 0) { + $arr = date_parse($date); + $calc_year = 0; + return self::calc_week($arr['year'], $arr['month'], $arr['day'], self::week_mode($mode), $calc_year); + } + + public static function db_CURDATE() { + return date('Y-m-d'); + } + + public static function db_CURTIME() { + return date('H:i:s'); + } + + public static function db_WEEKDAY($date) { + $arr = date_parse($date); + return self::calc_weekday(self::calc_daynr($arr['year'], $arr['month'], $arr['day']), 0); + + } + + /** + * Cette fonction est l'equivelent de la fonction date_format de MySQL. + * @staticvar string $mysql_replacement Les symboles formatage a remplacer + * @param string $date la date dans un format ISO + * @param string $format la chaine de formatage + * @return string La date formatee. + */ + public static function db_date_format($date, $format) { + static $mysql_replacement; + if (! isset($mysql_replacement)) { + $mysql_replacement = array( + '%' => '%', + 'a' => 'D', + 'b' => 'M', + 'c' => 'n', + 'D' => 'jS', + 'd' => 'd', + 'e' => 'j', + 'f' => 'u', + 'H' => 'H', + 'h' => 'h', + 'I' => 'h', + 'i' => 'i', + 'k' => 'H', + 'l' => 'g', + 'M' => 'F', + 'm' => 'm', + 'p' => 'A', + 'r' => 'h:i:s A', + 'S' => 's', + 's' => 's', + 'T' => 'H:i:s', + 'W' => 'l', + 'w' => 'w', + 'Y' => 'Y', + 'y' => 'y', + ); + } + + $fmt = ''; + $lg = strlen($format); + $state = 0; + $timestamp = strtotime($date); + $yday = date('z', $timestamp); + $month = (integer)date("n", $timestamp); + $year = (integer)date("Y", $timestamp); + $day = (integer)date("d", $timestamp); + for($idx = 0; $idx < $lg; ++$idx) { + $char = $format[$idx]; + if ($state == 0) { + if ($char == '%') { + $state = 1; + } else { + $fmt .= $char; + } + } + elseif ($state == 1) { + if (array_key_exists($char, $mysql_replacement)) { + $fmt .= $mysql_replacement[$char]; + } else { + $calc_year = 0; + switch ($char) { + case 'j': // day of the year 001 + $char = sprintf("%03d", $yday+1); + break; + case 'U': // mode 0: semaine 0 = premiere semaine complète qui commence un dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 4, $calc_year)); + break; + case 'u': // mode 1: semaine 0 = première semaine de 4 jours. Début le dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 1, $calc_year)); + break; + case 'V': // mode 2: semaine 1 = premiere semaine complète qui commence un dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 6, $calc_year)); + break; + case 'v': // mode 3: semaine 1 = premiere semaine de 4 jours. Début le lundi + $char = sprintf("%02d", self::calc_week($year, $month, $day, 3, $calc_year)); + break; + case 'X': + self::calc_week($year, $month, $day, 6, $calc_year); + $char = sprintf("%04d", $calc_year); + break; + case 'x': + self::calc_week($year, $month, $day, 3, $calc_year); + $char = sprintf("%04d", $calc_year); + break; + } + $fmt .= $char; + } + $state = 0; + } + } + return date($fmt, strtotime($date)); + } + + /** + * Equivalent de la fonction MySQL IF + * @param boolean $test Le resultat du test + * @param mixed $true_part Partie a retourner si vrai + * @param mixed $false_part Partie a retourner si faux + * @return mixed Partie selectionnee en fonction du test + */ + public static function db_IF($test, $true_part, $false_part) { + return ( $test ) ? $true_part : $false_part; + } + + // Adapté de mytime.c des sources de mariadb + // fonction calc_daynr + private static function calc_daynr($year, $month, $day) { + $y = $year; + if ($y == 0 && $month == 0) return 0; + $num = (365* $y + 31 * ($month - 1) + $day); + if ($month <= 2) { + $y--; } + else { + $num -= floor(($month * 4 + 23) / 10); + } + $temp = floor(($y / 100 + 1) * 3 / 4); + return $num + floor($y / 4) - $temp; + } + + private static function calc_weekday($daynr, $sunday_first_day_of_week) { + $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7); + return $ret; + } + + private static function calc_days_in_year($year) + { + return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365); + } + + private static function week_mode($mode) { + $week_format= ($mode & 7); + if (!($week_format & self::WEEK_MONDAY_FIRST)) { + $week_format^= self::WEEK_FIRST_WEEKDAY; + } + return $week_format; + } + + + private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year) { + $daynr=self::calc_daynr($year,$month,$day); + $first_daynr=self::calc_daynr($year,1,1); + $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0; + $week_year= ($week_behaviour & self::WEEK_YEAR) ? 1 : 0; + $first_weekday= ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0; + + $weekday=self::calc_weekday($first_daynr, !$monday_first); + $calc_year=$year; + + if ($month == 1 && $day <= 7-$weekday) + { + if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4))) + return 0; + $week_year= 1; + $calc_year--; + $first_daynr-= ($days=self::calc_days_in_year($calc_year)); + $weekday= ($weekday + 53*7- $days) % 7; + } + + if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) { + $days= $daynr - ($first_daynr+ (7-$weekday)); + } + else { + $days= $daynr - ($first_daynr - $weekday); + } + + if ($week_year && $days >= 52*7) + { + $weekday= ($weekday + self::calc_days_in_year($calc_year)) % 7; + if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0)) + { + $calc_year++; + return 1; + } + } + return floor($days/7+1); + } + +} + diff --git a/htdocs/install/etape2.php b/htdocs/install/etape2.php index d934f79f0af..612c3c64148 100644 --- a/htdocs/install/etape2.php +++ b/htdocs/install/etape2.php @@ -51,7 +51,7 @@ if ($dolibarr_main_db_type == "mysql") $choix=1; if ($dolibarr_main_db_type == "mysqli") $choix=1; if ($dolibarr_main_db_type == "pgsql") $choix=2; if ($dolibarr_main_db_type == "mssql") $choix=3; -if ($dolibarr_main_db_type == "sqlite") $choix=4; +if ($dolibarr_main_db_type == "sqlite3") $choix=4; //if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into etape2.php page'); @@ -413,7 +413,7 @@ if ($action == "set") if ($choix==1) $dir = "mysql/functions/"; elseif ($choix==2) $dir = "pgsql/functions/"; elseif ($choix==3) $dir = "mssql/functions/"; - elseif ($choix==4) { $dir = "sqlite/functions/"; } + elseif ($choix==4) { $dir = "sqlite3/functions/"; } // Creation donnees $file = "functions.sql"; diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index 49b80eb1b6b..ec3e208374b 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -306,7 +306,7 @@ if (! empty($force_install_message)) $class='DoliDB'.ucfirst($type); include_once $dir."/".$file; - //if ($type == 'sqlite') continue; // We hide sqlite because support can't be complete unti sqlit does not manage foreign key creation after table creation + if ($type == 'sqlite') continue; // We hide sqlite because support can't be complete unti sqlit does not manage foreign key creation after table creation // Version min of database $versionbasemin=explode('.',$class::VERSIONMIN); @@ -320,7 +320,7 @@ if (! empty($force_install_message)) if ($type=='mysqli') { $testfunction='mysqli_connect'; $testclass=''; } if ($type=='pgsql') { $testfunction='pg_connect'; $testclass=''; } if ($type=='mssql') { $testfunction='mssql_connect'; $testclass=''; } - if ($type=='sqlite') { $testfunction=''; $testclass='PDO'; } + if ($type=='sqlite3') { $testfunction=''; $testclass='SQLite3'; } $option.=''; @@ -479,7 +480,7 @@ if (! empty($force_install_message)) jQuery(document).ready(function() { jQuery("#db_type").change(function() { - if (jQuery("#db_type").val()=='sqlite') { jQuery(".hidesqlite").hide(); } + if (jQuery("#db_type").val()=='sqlite' || jQuery("#db_type").val()=='sqlite3') { jQuery(".hidesqlite").hide(); } else { jQuery(".hidesqlite").show(); } }); diff --git a/htdocs/install/sqlite/functions/functions.sql b/htdocs/install/sqlite3/functions/functions.sql similarity index 100% rename from htdocs/install/sqlite/functions/functions.sql rename to htdocs/install/sqlite3/functions/functions.sql diff --git a/htdocs/install/sqlite/index.html b/htdocs/install/sqlite3/index.html similarity index 100% rename from htdocs/install/sqlite/index.html rename to htdocs/install/sqlite3/index.html From dd2594692e9d6cab9ce6c3c329e606abf1ad43fb Mon Sep 17 00:00:00 2001 From: Guillaume de Lestanville Date: Thu, 5 Mar 2015 17:35:37 +0100 Subject: [PATCH 21/46] Updating compatibility with Sqlite3 - Replace USING syntax by IN SELECT syntax - Fix error on database creation - Removing test on username parameter when installing. --- htdocs/admin/system/database-tables.php | 2 +- htdocs/core/db/sqlite3.class.php | 974 +++++++++--------- htdocs/core/modules/DolibarrModules.class.php | 587 +++++------ htdocs/install/etape1.php | 7 +- index.php | 2 - 5 files changed, 794 insertions(+), 778 deletions(-) delete mode 100644 index.php diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index 5ac7292042e..e75cec3f513 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -180,7 +180,7 @@ else print '
'.$langs->trans("TableName").'
'; print ''; print ''; - print ''; + print ''; print "\n"; $sql = "SELECT name, type FROM sqlite_master where type='table' and name not like 'sqlite%' ORDER BY name"; diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index f232acb199e..c52578fa579 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -37,18 +37,18 @@ class DoliDBSqlite3 extends DoliDB const LABEL='Sqlite3'; //! Version min database const VERSIONMIN='3.0.0'; - //! Resultset of last query - private $_results; + //! Resultset of last query + private $_results; - const WEEK_MONDAY_FIRST=1; - const WEEK_YEAR = 2; - const WEEK_FIRST_WEEKDAY=4; + const WEEK_MONDAY_FIRST=1; + const WEEK_YEAR = 2; + const WEEK_FIRST_WEEKDAY=4; /** * Constructor. * This create an opened connexion to a database server and eventually to a database - * + * * @param string $type Type of database (mysql, pgsql...) * @param string $host Address of database server * @param string $user Nom de l'utilisateur autorise @@ -101,14 +101,14 @@ class DoliDBSqlite3 extends DoliDB $this->database_selected = 1; $this->database_name = $name; - $this->addCustomFunction('IF'); - $this->addCustomFunction('MONTH'); - $this->addCustomFunction('CURTIME'); - $this->addCustomFunction('CURDATE'); - $this->addCustomFunction('WEEK', 1); - $this->addCustomFunction('WEEK', 2); - $this->addCustomFunction('WEEKDAY'); - $this->addCustomFunction('date_format'); + $this->addCustomFunction('IF'); + $this->addCustomFunction('MONTH'); + $this->addCustomFunction('CURTIME'); + $this->addCustomFunction('CURDATE'); + $this->addCustomFunction('WEEK', 1); + $this->addCustomFunction('WEEK', 2); + $this->addCustomFunction('WEEKDAY'); + $this->addCustomFunction('date_format'); //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } else @@ -135,83 +135,83 @@ class DoliDBSqlite3 extends DoliDB */ static function convertSQLFromMysql($line,$type='ddl') { - // Removed empty line if this is a comment line for SVN tagging - if (preg_match('/^--\s\$Id/i',$line)) { - return ''; - } - // Return line if this is a comment - if (preg_match('/^#/i',$line) || preg_match('/^$/i',$line) || preg_match('/^--/i',$line)) - { - return $line; - } - if ($line != "") - { - if ($type == 'auto') - { + // Removed empty line if this is a comment line for SVN tagging + if (preg_match('/^--\s\$Id/i',$line)) { + return ''; + } + // Return line if this is a comment + if (preg_match('/^#/i',$line) || preg_match('/^$/i',$line) || preg_match('/^--/i',$line)) + { + return $line; + } + if ($line != "") + { + if ($type == 'auto') + { if (preg_match('/ALTER TABLE/i',$line)) $type='dml'; else if (preg_match('/CREATE TABLE/i',$line)) $type='dml'; else if (preg_match('/DROP TABLE/i',$line)) $type='dml'; - } + } - if ($type == 'dml') - { + if ($type == 'dml') + { $line=preg_replace('/\s/',' ',$line); // Replace tabulation with space - // we are inside create table statement so lets process datatypes - if (preg_match('/(ISAM|innodb)/i',$line)) { // end of create table sequence - $line=preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); - $line=preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); - $line=preg_replace('/,$/','',$line); - } + // we are inside create table statement so lets process datatypes + if (preg_match('/(ISAM|innodb)/i',$line)) { // end of create table sequence + $line=preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); + $line=preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line); + $line=preg_replace('/,$/','',$line); + } - // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..." - if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) { - $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line); + // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..." + if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) { + $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line); //$line = "-- ".$line." replaced by --\n".$newline; $line=$newline; - } + } - // tinyint type conversion - $line=str_replace('tinyint','smallint',$line); + // tinyint type conversion + $line=str_replace('tinyint','smallint',$line); - // nuke unsigned - $line=preg_replace('/(int\w+|smallint)\s+unsigned/i','\\1',$line); + // nuke unsigned + $line=preg_replace('/(int\w+|smallint)\s+unsigned/i','\\1',$line); - // blob -> text - $line=preg_replace('/\w*blob/i','text',$line); + // blob -> text + $line=preg_replace('/\w*blob/i','text',$line); - // tinytext/mediumtext -> text - $line=preg_replace('/tinytext/i','text',$line); - $line=preg_replace('/mediumtext/i','text',$line); + // tinytext/mediumtext -> text + $line=preg_replace('/tinytext/i','text',$line); + $line=preg_replace('/mediumtext/i','text',$line); - // change not null datetime field to null valid ones - // (to support remapping of "zero time" to null - $line=preg_replace('/datetime not null/i','datetime',$line); - $line=preg_replace('/datetime/i','timestamp',$line); + // change not null datetime field to null valid ones + // (to support remapping of "zero time" to null + $line=preg_replace('/datetime not null/i','datetime',$line); + $line=preg_replace('/datetime/i','timestamp',$line); - // double -> numeric - $line=preg_replace('/^double/i','numeric',$line); - $line=preg_replace('/(\s*)double/i','\\1numeric',$line); - // float -> numeric - $line=preg_replace('/^float/i','numeric',$line); - $line=preg_replace('/(\s*)float/i','\\1numeric',$line); + // double -> numeric + $line=preg_replace('/^double/i','numeric',$line); + $line=preg_replace('/(\s*)double/i','\\1numeric',$line); + // float -> numeric + $line=preg_replace('/^float/i','numeric',$line); + $line=preg_replace('/(\s*)float/i','\\1numeric',$line); - // unique index(field1,field2) - if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i',$line)) - { - $line=preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i','UNIQUE\(\\1\)',$line); - } + // unique index(field1,field2) + if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i',$line)) + { + $line=preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i','UNIQUE\(\\1\)',$line); + } - // We remove end of requests "AFTER fieldxxx" - $line=preg_replace('/AFTER [a-z0-9_]+/i','',$line); + // We remove end of requests "AFTER fieldxxx" + $line=preg_replace('/AFTER [a-z0-9_]+/i','',$line); - // We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX - $line=preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i','DROP INDEX',$line); + // We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX + $line=preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i','DROP INDEX',$line); // Translate order to rename fields if (preg_match('/ALTER TABLE ([a-z0-9_]+) CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i',$line,$reg)) { - $line = "-- ".$line." replaced by --\n"; + $line = "-- ".$line." replaced by --\n"; $line.= "ALTER TABLE ".$reg[1]." RENAME COLUMN ".$reg[2]." TO ".$reg[3]; } @@ -230,12 +230,12 @@ class DoliDBSqlite3 extends DoliDB } // alter table add primary key (field1, field2 ...) -> We create a unique index instead as dynamic creation of primary key is not supported - // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity); - if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg)) - { - $line = "-- ".$line." replaced by --\n"; - $line.= "CREATE UNIQUE INDEX ".$reg[2]." ON ".$reg[1]."(".$reg[3]; - } + // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity); + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg)) + { + $line = "-- ".$line." replaced by --\n"; + $line.= "CREATE UNIQUE INDEX ".$reg[2]." ON ".$reg[1]."(".$reg[3]; + } // Translate order to drop foreign keys // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx; @@ -245,62 +245,62 @@ class DoliDBSqlite3 extends DoliDB $line.= "ALTER TABLE ".$reg[1]." DROP CONSTRAINT ".$reg[2]; } - // alter table add [unique] [index] (field1, field2 ...) - // ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version) - if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i',$line,$reg)) - { - $fieldlist=$reg[4]; - $idxname=$reg[3]; - $tablename=$reg[1]; - $line = "-- ".$line." replaced by --\n"; - $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")"; - } - if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$line, $reg)) { - // Pour l'instant les contraintes ne sont pas créées - dol_syslog(get_class().'::query line emptied'); - $line = 'SELECT 0;'; + // alter table add [unique] [index] (field1, field2 ...) + // ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version) + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i',$line,$reg)) + { + $fieldlist=$reg[4]; + $idxname=$reg[3]; + $tablename=$reg[1]; + $line = "-- ".$line." replaced by --\n"; + $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")"; + } + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$line, $reg)) { + // Pour l'instant les contraintes ne sont pas créées + dol_syslog(get_class().'::query line emptied'); + $line = 'SELECT 0;'; - } + } - //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) { - //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line); - //} + //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) { + //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line); + //} } - // Delete using criteria on other table must not declare twice the deleted table - // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable - if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg)) - { + // Delete using criteria on other table must not declare twice the deleted table + // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable + if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg)) + { if ($reg[1] == $reg[2]) // If same table, we remove second one - { - $line=preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i','DELETE FROM \\1 USING \\3', $line); - } - } + { + $line=preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i','DELETE FROM \\1 USING \\3', $line); + } + } - // Remove () in the tables in FROM if one table - $line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line); - //print $line."\n"; + // Remove () in the tables in FROM if one table + $line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line); + //print $line."\n"; - // Remove () in the tables in FROM if two table - $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2',$line); - //print $line."\n"; + // Remove () in the tables in FROM if two table + $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2',$line); + //print $line."\n"; - // Remove () in the tables in FROM if two table - $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2, \\3',$line); - //print $line."\n"; + // Remove () in the tables in FROM if two table + $line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2, \\3',$line); + //print $line."\n"; - //print "type=".$type." newline=".$line."
\n"; - } + //print "type=".$type." newline=".$line."
\n"; + } - return $line; + return $line; } - /** + /** * Select a database - * + * * @param string $database Name of database * @return boolean true if OK, false if KO - */ + */ function select_db($database) { dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG); @@ -310,7 +310,7 @@ class DoliDBSqlite3 extends DoliDB /** * Connexion to server - * + * * @param string $host database server host * @param string $login login * @param string $passwd password @@ -329,7 +329,7 @@ class DoliDBSqlite3 extends DoliDB if (empty($dir)) $dir=DOL_DATA_ROOT; // With sqlite, port must be in connect parameters //if (! $newport) $newport=3306; - $database_name = $dir.'/database_'.$name.'.sdb'; + $database_name = $dir.'/database_'.$name.'.sdb'; try { /*** connect to SQLite database ***/ //$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb'); @@ -349,12 +349,12 @@ class DoliDBSqlite3 extends DoliDB /** * Return version of database server - * + * * @return string Version string */ function getVersion() { - return $this->db->version()['versionString']; + return $this->db->version()['versionString']; } /** @@ -364,10 +364,10 @@ class DoliDBSqlite3 extends DoliDB */ function getDriverInfo() { - // FIXME: Dummy method - // TODO: Implement + // FIXME: Dummy method + // TODO: Implement - return ''; + return ''; } @@ -381,9 +381,9 @@ class DoliDBSqlite3 extends DoliDB { if ($this->db) { - if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened,LOG_ERR); + if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened,LOG_ERR); $this->connected=0; - $this->db->close(); + $this->db->close(); $this->db=null; // Clean this->db return true; } @@ -391,7 +391,7 @@ class DoliDBSqlite3 extends DoliDB } /** - * Execute a SQL request and return the resultset + * Execute a SQL request and return the resultset * * @param string $query SQL query string * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollbock to savepoint if error (this allow to have some request with errors inside global transactions). @@ -407,58 +407,58 @@ class DoliDBSqlite3 extends DoliDB $query = trim($query); $this->error = 0; - // Convert MySQL syntax to SQLite syntax - if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$query, $reg)) { - // Ajout d'une clef étrangère à la table - // procédure de remplacement de la table pour ajouter la contrainte - // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid) - // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)) - $foreignFields = $reg[5]; - $foreignTable = $reg[4]; - $localfields = $reg[3]; - $constraintname=trim($reg[2]); - $tablename=trim($reg[1]); + // Convert MySQL syntax to SQLite syntax + if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$query, $reg)) { + // Ajout d'une clef étrangère à la table + // procédure de remplacement de la table pour ajouter la contrainte + // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid) + // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)) + $foreignFields = $reg[5]; + $foreignTable = $reg[4]; + $localfields = $reg[3]; + $constraintname=trim($reg[2]); + $tablename=trim($reg[1]); - $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); + $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); - // 1- Renommer la table avec un nom temporaire - $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); + // 1- Renommer la table avec un nom temporaire + $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); - // 2- Recréer la table avec la contrainte ajoutée + // 2- Recréer la table avec la contrainte ajoutée - // on bricole la requete pour ajouter la contrainte - $descTable = substr($descTable, 0, strlen($descTable) - 1); - $descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")"; + // on bricole la requete pour ajouter la contrainte + $descTable = substr($descTable, 0, strlen($descTable) - 1); + $descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")"; - // fermeture de l'instruction - $descTable .= ')'; + // fermeture de l'instruction + $descTable .= ')'; - // Création proprement dite de la table - $this->query($descTable); + // Création proprement dite de la table + $this->query($descTable); - // 3- Transférer les données - $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); + // 3- Transférer les données + $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); - // 4- Supprimer la table temporaire - $this->query('DROP TABLE tmp_' . $tablename); + // 4- Supprimer la table temporaire + $this->query('DROP TABLE tmp_' . $tablename); - // dummy statement - $query="SELECT 0"; + // dummy statement + $query="SELECT 0"; - } else { - $query=$this->convertSQLFromMysql($query,$type); - } - //print "After convertSQLFromMysql:\n".$query."
\n"; + } else { + $query=$this->convertSQLFromMysql($query,$type); + } + //print "After convertSQLFromMysql:\n".$query."
\n"; - dol_syslog('sql='.$query, LOG_DEBUG); + dol_syslog('sql='.$query, LOG_DEBUG); - // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE) + // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE) try { //$ret = $this->db->exec($query); - $ret = $this->db->query($query); // $ret is a PDO object - if ($ret) { - $ret->queryString = $query; - } + $ret = $this->db->query($query); // $ret is a Sqlite3Result + if ($ret) { + $ret->queryString = $query; + } } catch(Exception $e) { @@ -474,15 +474,15 @@ class DoliDBSqlite3 extends DoliDB $this->lasterror = $this->error(); $this->lasterrno = $this->errno(); - dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); + dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); - $errormsg = get_class($this)."::query SQL Error message: ".$this->lasterror; + $errormsg = get_class($this)."::query SQL Error message: ".$this->lasterror; - if (preg_match('/[0-9]/',$this->lasterrno)) { + if (preg_match('/[0-9]/',$this->lasterrno)) { $errormsg .= ' ('.$this->lasterrno.')'; } - dol_syslog($errormsg, LOG_ERR); + dol_syslog($errormsg, LOG_ERR); } $this->lastquery=$query; $this->_results = $ret; @@ -502,10 +502,10 @@ class DoliDBSqlite3 extends DoliDB // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion if (! is_object($resultset)) { $resultset=$this->_results; } //return $resultset->fetch(PDO::FETCH_OBJ); - $ret = $resultset->fetchArray(SQLITE3_ASSOC); - if ($ret) { - return (object)$ret; - } + $ret = $resultset->fetchArray(SQLITE3_ASSOC); + if ($ret) { + return (object)$ret; + } } @@ -520,10 +520,10 @@ class DoliDBSqlite3 extends DoliDB // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } //return $resultset->fetch(PDO::FETCH_ASSOC); - $ret = $resultset->fetchArray(SQLITE3_ASSOC); - if ($ret) { - return (array)$ret; - } + $ret = $resultset->fetchArray(SQLITE3_ASSOC); + if ($ret) { + return (array)$ret; + } } /** @@ -558,10 +558,10 @@ class DoliDBSqlite3 extends DoliDB { // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } - if (preg_match("/^SELECT/i", $resultset->queryString)) { - return $this->db->querySingle("SELECT count(*) FROM (" . $resultset->queryString . ") q"); - } - return 0; + if (preg_match("/^SELECT/i", $resultset->queryString)) { + return $this->db->querySingle("SELECT count(*) FROM (" . $resultset->queryString . ") q"); + } + return 0; } /** @@ -575,21 +575,21 @@ class DoliDBSqlite3 extends DoliDB { // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } - if (preg_match("/^SELECT/i", $resultset->queryString)) { - return $this->num_rows($resultset); - } + if (preg_match("/^SELECT/i", $resultset->queryString)) { + return $this->num_rows($resultset); + } // mysql necessite un link de base pour cette fonction contrairement // a pqsql qui prend un resultset return $this->db->changes(); } - /** + /** * Free last resultset used. - * + * * @param resultset $resultset Curseur de la requete voulue * @return void - */ + */ function free($resultset=0) { // If resultset not provided, we take the last used by connexion @@ -598,15 +598,15 @@ class DoliDBSqlite3 extends DoliDB if ($resultset && is_object($resultset)) $resultset->finalize(); } - /** + /** * Escape a string to insert data - * + * * @param string $stringtoencode String to escape * @return string String escaped - */ + */ function escape($stringtoencode) { - return Sqlite3::escapeString($stringtoencode); + return Sqlite3::escapeString($stringtoencode); } /** @@ -656,19 +656,19 @@ class DoliDBSqlite3 extends DoliDB }*/ $errno=$this->db->lastErrorCode(); if ($errno=='HY000' || $errno == 0) - { + { if (preg_match('/table.*already exists/i',$this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS'; elseif (preg_match('/index.*already exists/i',$this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS'; elseif (preg_match('/syntax error/i',$this->error)) return 'DB_ERROR_SYNTAX'; - } - if ($errno=='23000') - { + } + if ($errno=='23000') + { if (preg_match('/column.* not unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; elseif (preg_match('/PRIMARY KEY must be unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS'; - } - if ($errno > 1) { - // TODO Voir la liste des messages d'erreur - } + } + if ($errno > 1) { + // TODO Voir la liste des messages d'erreur + } return ($errno?'DB_ERROR_'.$errno:'0'); } @@ -691,8 +691,8 @@ class DoliDBSqlite3 extends DoliDB } /** - * Get last ID after an insert INSERT - * + * Get last ID after an insert INSERT + * * @param string $tab Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql * @param string $fieldid Field name * @return int Id of row @@ -772,13 +772,13 @@ class DoliDBSqlite3 extends DoliDB /** - * Return connexion ID - * + * Return connexion ID + * * @return string Id connexion */ function DDLGetConnectId() { - return '?'; + return '?'; } @@ -786,7 +786,7 @@ class DoliDBSqlite3 extends DoliDB * Create a new database * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated * We force to create database with charset this->forcecharset and collate this->forcecollate - * + * * @param string $database Database name to create * @param string $charset Charset used to store data * @param string $collation Charset used to sort data @@ -815,8 +815,8 @@ class DoliDBSqlite3 extends DoliDB } /** - * List tables into a database - * + * List tables into a database + * * @param string $database Name of database * @param string $table Name of table filter ('xxx%') * @return array List of tables in an array @@ -839,7 +839,7 @@ class DoliDBSqlite3 extends DoliDB /** * List information of columns into a table. - * + * * @param string $table Name of table * @return array Tableau des informations des champs de la table * TODO modify for sqlite @@ -861,7 +861,7 @@ class DoliDBSqlite3 extends DoliDB /** * Create a table into database - * + * * @param string $table Nom de la table * @param array $fields Tableau associatif [nom champ][tableau des descriptions] * @param string $primary_key Nom du champ qui sera la clef primaire @@ -938,7 +938,7 @@ class DoliDBSqlite3 extends DoliDB /** * Return a pointer of line with description of a table or field - * + * * @param string $table Name of table * @param string $field Optionnel : Name of field if we want description of field * @return resource Resource @@ -954,7 +954,7 @@ class DoliDBSqlite3 extends DoliDB /** * Create a new field into table - * + * * @param string $table Name of table * @param string $field_name Name of field to add * @param string $field_desc Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre] @@ -1000,7 +1000,7 @@ class DoliDBSqlite3 extends DoliDB /** * Update format of a field into a table - * + * * @param string $table Name of table * @param string $field_name Name of field to modify * @param string $field_desc Array with description of field format @@ -1011,7 +1011,7 @@ class DoliDBSqlite3 extends DoliDB $sql = "ALTER TABLE ".$table; $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type']; if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') { - $sql.="(".$field_desc['value'].")"; + $sql.="(".$field_desc['value'].")"; } dol_syslog(get_class($this)."::DDLUpdateField ".$sql,LOG_DEBUG); @@ -1023,7 +1023,7 @@ class DoliDBSqlite3 extends DoliDB /** * Drop a field from table - * + * * @param string $table Name of table * @param string $field_name Name of field to drop * @return int <0 if KO, >0 if OK @@ -1043,7 +1043,7 @@ class DoliDBSqlite3 extends DoliDB /** * Create a user and privileges to connect to database (even if database does not exists yet) - * + * * @param string $dolibarr_main_db_host Ip serveur * @param string $dolibarr_main_db_user Nom user a creer * @param string $dolibarr_main_db_pass Mot de passe user a creer @@ -1088,21 +1088,21 @@ class DoliDBSqlite3 extends DoliDB return 1; } - /** + /** * Return charset used to store data in database - * + * * @return string Charset - */ + */ function getDefaultCharacterSetDatabase() { return 'UTF-8'; } - /** + /** * Return list of available charset that can be used to store data in database - * + * * @return array List of Charset - */ + */ function getListOfCharacterSet() { $liste = array(); @@ -1112,21 +1112,21 @@ class DoliDBSqlite3 extends DoliDB return $liste; } - /** + /** * Return collation used in database - * + * * @return string Collation value - */ + */ function getDefaultCollationDatabase() { return 'UTF-8'; } - /** + /** * Return list of available collation that can be used for database - * + * * @return array List of Collation - */ + */ function getListOfCollation() { $liste = array(); @@ -1136,12 +1136,12 @@ class DoliDBSqlite3 extends DoliDB return $liste; } - /** + /** * Return full path of dump program - * + * * @return string Full path of dump program - */ - function getPathOfDump() + */ + function getPathOfDump() { $fullpathofdump='/pathtomysqldump/mysqldump'; @@ -1155,11 +1155,11 @@ class DoliDBSqlite3 extends DoliDB return $fullpathofdump; } - /** + /** * Return full path of restore program - * + * * @return string Full path of restore program - */ + */ function getPathOfRestore() { $fullpathofimport='/pathtomysql/mysql'; @@ -1174,61 +1174,65 @@ class DoliDBSqlite3 extends DoliDB return $fullpathofimport; } - /** - * Return value of server parameters - * + /** + * Return value of server parameters + * * @param string $filter Filter list on a particular value * @return array Array of key-values (key=>value) - */ + */ function getServerParametersValues($filter='') { $result=array(); - static $pragmas; - if (! isset($pragmas)) { - // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur - // indépendante de la base de données. - // cf. http://www.sqlite.org/pragma.html - $pragmas = array( - 'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size', - 'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list', + static $pragmas; + if (! isset($pragmas)) { + // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur + // indépendante de la base de données. + // cf. http://www.sqlite.org/pragma.html + $pragmas = array( + 'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size', + 'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list', 'compile_options', 'data_version', /*'database_list',*/ - 'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count', - 'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check', - 'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode', - 'max_page_count', 'page_count', 'page_size', 'parser_trace', - 'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers', - 'reverse_unordered_selects', 'schema_version', 'user_version', - 'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit', - 'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads', - 'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace', - 'wal_autocheckpoint', - ); - } + 'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count', + 'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check', + 'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode', + 'max_page_count', 'page_count', 'page_size', 'parser_trace', + 'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers', + 'reverse_unordered_selects', 'schema_version', 'user_version', + 'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit', + 'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads', + 'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace', + 'wal_autocheckpoint', + ); + } - // TODO prendre en compte le filtre - foreach($pragmas as $var) { - $sql = "PRAGMA $var"; - $resql=$this->query($sql); - if ($resql) - { - $obj = $this->fetch_row($resql); - //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG); - $result[$var] = $obj[0]; - } - } + // TODO prendre en compte le filtre + foreach($pragmas as $var) { + $sql = "PRAGMA $var"; + $resql=$this->query($sql); + if ($resql) + { + $obj = $this->fetch_row($resql); + //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG); + $result[$var] = $obj[0]; + } + else { + // TODO Récupérer le message + $result[$var] = 'FAIL'; + } + } return $result; } - /** - * Return value of server status - * + /** + * Return value of server status + * * @param string $filter Filter list on a particular value * @return array Array of key-values (key=>value) - */ + */ function getServerStatusValues($filter='') { $result=array(); - /* + /* $sql='SHOW STATUS'; if ($filter) $sql.=" LIKE '".$this->escape($filter)."'"; $resql=$this->query($sql); @@ -1236,243 +1240,243 @@ class DoliDBSqlite3 extends DoliDB { while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value; } - */ + */ return $result; } - /** - * Permet le chargement d'une fonction personnalisee dans le moteur de base de donnees. - * Note: le nom de la fonction personnalisee est prefixee par 'db_'. La fonction doit être - * statique et publique. Le nombre de parametres est determine automatiquement. - * @param string $name Le nom de la fonction a definir dans Sqlite - */ - private function addCustomFunction($name, $arg_count = -1) { - if ($this->db) { - $localname = __CLASS__ . '::' . 'db_' . $name; - $reflectClass = new ReflectionClass(__CLASS__); - $reflectFunction = $reflectClass->getMethod('db_' . $name); - if ($arg_count < 0) { - $arg_count = $reflectFunction->getNumberOfParameters(); - } - if (!$this->db->createFunction($name, $localname , $arg_count)) { - $this->error = "unable to create custom function '$name'"; - } - } - } + /** + * Permet le chargement d'une fonction personnalisee dans le moteur de base de donnees. + * Note: le nom de la fonction personnalisee est prefixee par 'db_'. La fonction doit être + * statique et publique. Le nombre de parametres est determine automatiquement. + * @param string $name Le nom de la fonction a definir dans Sqlite + */ + private function addCustomFunction($name, $arg_count = -1) { + if ($this->db) { + $localname = __CLASS__ . '::' . 'db_' . $name; + $reflectClass = new ReflectionClass(__CLASS__); + $reflectFunction = $reflectClass->getMethod('db_' . $name); + if ($arg_count < 0) { + $arg_count = $reflectFunction->getNumberOfParameters(); + } + if (!$this->db->createFunction($name, $localname , $arg_count)) { + $this->error = "unable to create custom function '$name'"; + } + } + } - /** - * Cette fonction est l'equivalent de la fonction MONTH de MySql. - * @param string $date - * @return integer - */ - public static function db_MONTH($date) { - return date('n', strtotime($date)); - } + /** + * Cette fonction est l'equivalent de la fonction MONTH de MySql. + * @param string $date + * @return integer + */ + public static function db_MONTH($date) { + return date('n', strtotime($date)); + } - /** - * calcule du numéro de semaine - * - * @param string date - * @param int mode - */ - public static function db_WEEK($date, $mode = 0) { - $arr = date_parse($date); - $calc_year = 0; - return self::calc_week($arr['year'], $arr['month'], $arr['day'], self::week_mode($mode), $calc_year); - } + /** + * calcule du numéro de semaine + * + * @param string date + * @param int mode + */ + public static function db_WEEK($date, $mode = 0) { + $arr = date_parse($date); + $calc_year = 0; + return self::calc_week($arr['year'], $arr['month'], $arr['day'], self::week_mode($mode), $calc_year); + } - public static function db_CURDATE() { - return date('Y-m-d'); - } + public static function db_CURDATE() { + return date('Y-m-d'); + } - public static function db_CURTIME() { - return date('H:i:s'); - } + public static function db_CURTIME() { + return date('H:i:s'); + } - public static function db_WEEKDAY($date) { - $arr = date_parse($date); - return self::calc_weekday(self::calc_daynr($arr['year'], $arr['month'], $arr['day']), 0); + public static function db_WEEKDAY($date) { + $arr = date_parse($date); + return self::calc_weekday(self::calc_daynr($arr['year'], $arr['month'], $arr['day']), 0); - } + } - /** - * Cette fonction est l'equivelent de la fonction date_format de MySQL. + /** + * Cette fonction est l'equivelent de la fonction date_format de MySQL. * @staticvar string $mysql_replacement Les symboles formatage a remplacer - * @param string $date la date dans un format ISO - * @param string $format la chaine de formatage - * @return string La date formatee. - */ - public static function db_date_format($date, $format) { - static $mysql_replacement; - if (! isset($mysql_replacement)) { - $mysql_replacement = array( - '%' => '%', - 'a' => 'D', - 'b' => 'M', - 'c' => 'n', - 'D' => 'jS', - 'd' => 'd', - 'e' => 'j', - 'f' => 'u', - 'H' => 'H', - 'h' => 'h', - 'I' => 'h', - 'i' => 'i', - 'k' => 'H', - 'l' => 'g', - 'M' => 'F', - 'm' => 'm', - 'p' => 'A', - 'r' => 'h:i:s A', - 'S' => 's', - 's' => 's', - 'T' => 'H:i:s', - 'W' => 'l', - 'w' => 'w', - 'Y' => 'Y', - 'y' => 'y', - ); - } + * @param string $date la date dans un format ISO + * @param string $format la chaine de formatage + * @return string La date formatee. + */ + public static function db_date_format($date, $format) { + static $mysql_replacement; + if (! isset($mysql_replacement)) { + $mysql_replacement = array( + '%' => '%', + 'a' => 'D', + 'b' => 'M', + 'c' => 'n', + 'D' => 'jS', + 'd' => 'd', + 'e' => 'j', + 'f' => 'u', + 'H' => 'H', + 'h' => 'h', + 'I' => 'h', + 'i' => 'i', + 'k' => 'H', + 'l' => 'g', + 'M' => 'F', + 'm' => 'm', + 'p' => 'A', + 'r' => 'h:i:s A', + 'S' => 's', + 's' => 's', + 'T' => 'H:i:s', + 'W' => 'l', + 'w' => 'w', + 'Y' => 'Y', + 'y' => 'y', + ); + } - $fmt = ''; - $lg = strlen($format); - $state = 0; - $timestamp = strtotime($date); - $yday = date('z', $timestamp); - $month = (integer)date("n", $timestamp); - $year = (integer)date("Y", $timestamp); - $day = (integer)date("d", $timestamp); - for($idx = 0; $idx < $lg; ++$idx) { - $char = $format[$idx]; - if ($state == 0) { - if ($char == '%') { - $state = 1; - } else { - $fmt .= $char; - } - } - elseif ($state == 1) { - if (array_key_exists($char, $mysql_replacement)) { - $fmt .= $mysql_replacement[$char]; - } else { - $calc_year = 0; - switch ($char) { + $fmt = ''; + $lg = strlen($format); + $state = 0; + $timestamp = strtotime($date); + $yday = date('z', $timestamp); + $month = (integer)date("n", $timestamp); + $year = (integer)date("Y", $timestamp); + $day = (integer)date("d", $timestamp); + for($idx = 0; $idx < $lg; ++$idx) { + $char = $format[$idx]; + if ($state == 0) { + if ($char == '%') { + $state = 1; + } else { + $fmt .= $char; + } + } + elseif ($state == 1) { + if (array_key_exists($char, $mysql_replacement)) { + $fmt .= $mysql_replacement[$char]; + } else { + $calc_year = 0; + switch ($char) { case 'j': // day of the year 001 - $char = sprintf("%03d", $yday+1); - break; - case 'U': // mode 0: semaine 0 = premiere semaine complète qui commence un dimanche - $char = sprintf("%02d", self::calc_week($year, $month, $day, 4, $calc_year)); - break; - case 'u': // mode 1: semaine 0 = première semaine de 4 jours. Début le dimanche - $char = sprintf("%02d", self::calc_week($year, $month, $day, 1, $calc_year)); - break; - case 'V': // mode 2: semaine 1 = premiere semaine complète qui commence un dimanche - $char = sprintf("%02d", self::calc_week($year, $month, $day, 6, $calc_year)); - break; - case 'v': // mode 3: semaine 1 = premiere semaine de 4 jours. Début le lundi - $char = sprintf("%02d", self::calc_week($year, $month, $day, 3, $calc_year)); - break; - case 'X': - self::calc_week($year, $month, $day, 6, $calc_year); - $char = sprintf("%04d", $calc_year); - break; - case 'x': - self::calc_week($year, $month, $day, 3, $calc_year); - $char = sprintf("%04d", $calc_year); - break; - } - $fmt .= $char; - } - $state = 0; - } - } - return date($fmt, strtotime($date)); - } + $char = sprintf("%03d", $yday+1); + break; + case 'U': // mode 0: semaine 0 = premiere semaine complète qui commence un dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 4, $calc_year)); + break; + case 'u': // mode 1: semaine 0 = première semaine de 4 jours. Début le dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 1, $calc_year)); + break; + case 'V': // mode 2: semaine 1 = premiere semaine complète qui commence un dimanche + $char = sprintf("%02d", self::calc_week($year, $month, $day, 6, $calc_year)); + break; + case 'v': // mode 3: semaine 1 = premiere semaine de 4 jours. Début le lundi + $char = sprintf("%02d", self::calc_week($year, $month, $day, 3, $calc_year)); + break; + case 'X': + self::calc_week($year, $month, $day, 6, $calc_year); + $char = sprintf("%04d", $calc_year); + break; + case 'x': + self::calc_week($year, $month, $day, 3, $calc_year); + $char = sprintf("%04d", $calc_year); + break; + } + $fmt .= $char; + } + $state = 0; + } + } + return date($fmt, strtotime($date)); + } - /** - * Equivalent de la fonction MySQL IF - * @param boolean $test Le resultat du test - * @param mixed $true_part Partie a retourner si vrai - * @param mixed $false_part Partie a retourner si faux - * @return mixed Partie selectionnee en fonction du test - */ - public static function db_IF($test, $true_part, $false_part) { - return ( $test ) ? $true_part : $false_part; - } + /** + * Equivalent de la fonction MySQL IF + * @param boolean $test Le resultat du test + * @param mixed $true_part Partie a retourner si vrai + * @param mixed $false_part Partie a retourner si faux + * @return mixed Partie selectionnee en fonction du test + */ + public static function db_IF($test, $true_part, $false_part) { + return ( $test ) ? $true_part : $false_part; + } - // Adapté de mytime.c des sources de mariadb - // fonction calc_daynr - private static function calc_daynr($year, $month, $day) { - $y = $year; - if ($y == 0 && $month == 0) return 0; - $num = (365* $y + 31 * ($month - 1) + $day); - if ($month <= 2) { - $y--; } - else { - $num -= floor(($month * 4 + 23) / 10); - } - $temp = floor(($y / 100 + 1) * 3 / 4); - return $num + floor($y / 4) - $temp; - } + // Adapté de mytime.c des sources de mariadb + // fonction calc_daynr + private static function calc_daynr($year, $month, $day) { + $y = $year; + if ($y == 0 && $month == 0) return 0; + $num = (365* $y + 31 * ($month - 1) + $day); + if ($month <= 2) { + $y--; } + else { + $num -= floor(($month * 4 + 23) / 10); + } + $temp = floor(($y / 100 + 1) * 3 / 4); + return $num + floor($y / 4) - $temp; + } - private static function calc_weekday($daynr, $sunday_first_day_of_week) { - $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7); - return $ret; - } + private static function calc_weekday($daynr, $sunday_first_day_of_week) { + $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7); + return $ret; + } - private static function calc_days_in_year($year) - { - return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365); - } + private static function calc_days_in_year($year) + { + return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365); + } - private static function week_mode($mode) { - $week_format= ($mode & 7); - if (!($week_format & self::WEEK_MONDAY_FIRST)) { - $week_format^= self::WEEK_FIRST_WEEKDAY; - } - return $week_format; - } + private static function week_mode($mode) { + $week_format= ($mode & 7); + if (!($week_format & self::WEEK_MONDAY_FIRST)) { + $week_format^= self::WEEK_FIRST_WEEKDAY; + } + return $week_format; + } - private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year) { - $daynr=self::calc_daynr($year,$month,$day); - $first_daynr=self::calc_daynr($year,1,1); - $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0; - $week_year= ($week_behaviour & self::WEEK_YEAR) ? 1 : 0; - $first_weekday= ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0; + private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year) { + $daynr=self::calc_daynr($year,$month,$day); + $first_daynr=self::calc_daynr($year,1,1); + $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0; + $week_year= ($week_behaviour & self::WEEK_YEAR) ? 1 : 0; + $first_weekday= ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0; - $weekday=self::calc_weekday($first_daynr, !$monday_first); - $calc_year=$year; + $weekday=self::calc_weekday($first_daynr, !$monday_first); + $calc_year=$year; - if ($month == 1 && $day <= 7-$weekday) - { - if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4))) - return 0; - $week_year= 1; - $calc_year--; - $first_daynr-= ($days=self::calc_days_in_year($calc_year)); - $weekday= ($weekday + 53*7- $days) % 7; - } + if ($month == 1 && $day <= 7-$weekday) + { + if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4))) + return 0; + $week_year= 1; + $calc_year--; + $first_daynr-= ($days=self::calc_days_in_year($calc_year)); + $weekday= ($weekday + 53*7- $days) % 7; + } - if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) { - $days= $daynr - ($first_daynr+ (7-$weekday)); - } - else { - $days= $daynr - ($first_daynr - $weekday); - } + if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) { + $days= $daynr - ($first_daynr+ (7-$weekday)); + } + else { + $days= $daynr - ($first_daynr - $weekday); + } - if ($week_year && $days >= 52*7) - { - $weekday= ($weekday + self::calc_days_in_year($calc_year)) % 7; - if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0)) - { - $calc_year++; - return 1; - } - } - return floor($days/7+1); - } + if ($week_year && $days >= 52*7) + { + $weekday= ($weekday + self::calc_days_in_year($calc_year)) % 7; + if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0)) + { + $calc_year++; + return 1; + } + } + return floor($days/7+1); + } } diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 0b0ceb5460c..017d1eb8662 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -39,166 +39,166 @@ abstract class DolibarrModules */ public $db; - /** - * @var string Relative path to module style sheet - * @deprecated - */ - public $style_sheet = ''; + /** + * @var string Relative path to module style sheet + * @deprecated + */ + public $style_sheet = ''; - /** - * @var array Paths to create when module is activated - */ - public $dirs = array(); + /** + * @var array Paths to create when module is activated + */ + public $dirs = array(); - /** - * @var array Module boxes - */ - public $boxes = array(); + /** + * @var array Module boxes + */ + public $boxes = array(); - /** - * @var array Module constants - */ - public $const = array(); + /** + * @var array Module constants + */ + public $const = array(); - /** - * @var array Module access rights - */ - public $rights; + /** + * @var array Module access rights + */ + public $rights; - /** - * @var string Module access rights family - */ - public $rights_class; + /** + * @var string Module access rights family + */ + public $rights_class; - /** - * @var array Module menu entries - */ - public $menu = array(); + /** + * @var array Module menu entries + */ + public $menu = array(); - /** - * @var array Module parts - * array( - * // Set this to 1 if module has its own trigger directory (/mymodule/core/triggers) - * 'triggers' => 0, - * // Set this to 1 if module has its own login method directory (/mymodule/core/login) + /** + * @var array Module parts + * array( + * // Set this to 1 if module has its own trigger directory (/mymodule/core/triggers) + * 'triggers' => 0, + * // Set this to 1 if module has its own login method directory (/mymodule/core/login) * 'login' => 0, - * // Set this to 1 if module has its own substitution function file (/mymodule/core/substitutions) + * // Set this to 1 if module has its own substitution function file (/mymodule/core/substitutions) * 'substitutions' => 0, - * // Set this to 1 if module has its own menus handler directory (/mymodule/core/menus) + * // Set this to 1 if module has its own menus handler directory (/mymodule/core/menus) * 'menus' => 0, - * // Set this to 1 if module has its own theme directory (/mymodule/theme) + * // Set this to 1 if module has its own theme directory (/mymodule/theme) * 'theme' => 0, - * // Set this to 1 if module overwrite template dir (/mymodule/core/tpl) - * 'tpl' => 0, - * // Set this to 1 if module has its own barcode directory (/mymodule/core/modules/barcode) + * // Set this to 1 if module overwrite template dir (/mymodule/core/tpl) + * 'tpl' => 0, + * // Set this to 1 if module has its own barcode directory (/mymodule/core/modules/barcode) * 'barcode' => 0, - * // Set this to 1 if module has its own models directory (/mymodule/core/modules/xxx) + * // Set this to 1 if module has its own models directory (/mymodule/core/modules/xxx) * 'models' => 0, - * // Set this to relative path of css file if module has its own css file + * // Set this to relative path of css file if module has its own css file * 'css' => '/mymodule/css/mymodule.css.php', - * // Set this to relative path of js file if module must load a js on all pages + * // Set this to relative path of js file if module must load a js on all pages * 'js' => '/mymodule/js/mymodule.js', - * // Set here all hooks context managed by module + * // Set here all hooks context managed by module * 'hooks' => array('hookcontext1','hookcontext2'), - * // Set here all workflow context managed by module + * // Set here all workflow context managed by module * 'workflow' => array( - * 'WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2' = >array( - * 'enabled' => '! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', - * 'picto'=>'yourpicto@mymodule' - * ) - * ) - * ) - */ - public $module_parts = array(); + * 'WORKFLOW_MODULE1_YOURACTIONTYPE_MODULE2' = >array( + * 'enabled' => '! empty($conf->module1->enabled) && ! empty($conf->module2->enabled)', + * 'picto'=>'yourpicto@mymodule' + * ) + * ) + * ) + */ + public $module_parts = array(); - /** - * @var string Module documents ? - * @deprecated Seems unused anywhere - */ - public $docs; + /** + * @var string Module documents ? + * @deprecated Seems unused anywhere + */ + public $docs; - /** - * @var string ? - * @deprecated Seems unused anywhere - */ - public $dbversion = "-"; + /** + * @var string ? + * @deprecated Seems unused anywhere + */ + public $dbversion = "-"; - /** - * @var string Error message - */ - public $error; + /** + * @var string Error message + */ + public $error; - /** - * @var int Module unique ID - */ - public $numero; + /** + * @var int Module unique ID + */ + public $numero; - /** - * @var string Module name - */ - public $name; + /** + * @var string Module name + */ + public $name; - /** - * @var string Module version - */ - public $version; + /** + * @var string Module version + */ + public $version; - /** - * @var string Module description - */ - public $description; + /** + * @var string Module description + */ + public $description; - /** - * @var string[] Module language files - */ - public $langfiles; + /** + * @var string[] Module language files + */ + public $langfiles; - /** - * @var string Module export code - */ - public $export_code; + /** + * @var string Module export code + */ + public $export_code; - /** - * @var string Module export label - */ - public $export_label; + /** + * @var string Module export label + */ + public $export_label; - /** - * @var string Module import code - */ - public $import_code; + /** + * @var string Module import code + */ + public $import_code; - /** - * @var string Module import label - */ - public $import_label; + /** + * @var string Module import label + */ + public $import_label; - /** - * @var string Module constant name - */ - public $const_name; + /** + * @var string Module constant name + */ + public $const_name; - /** - * @var bool Module can't be disabled - */ - public $always_enabled; + /** + * @var bool Module can't be disabled + */ + public $always_enabled; - /** - * @var bool Module is enabled globally (Multicompany support) - */ - public $core_enabled; + /** + * @var bool Module is enabled globally (Multicompany support) + */ + public $core_enabled; - /** - * Enables a module. - * Inserts all informations into database - * + /** + * Enables a module. + * Inserts all informations into database + * * @param array $array_sql SQL requests to be executed when enabling module - * @param string $options String with options when disabling module: - * 'noboxes' = Do not insert boxes - * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation - * - * @return int 1 if OK, 0 if KO - */ + * @param string $options String with options when disabling module: + * 'noboxes' = Do not insert boxes + * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation + * + * @return int 1 if OK, 0 if KO + */ function _init($array_sql, $options='') { global $conf; @@ -232,12 +232,12 @@ abstract class DolibarrModules // Execute addons requests $num=count($array_sql); - for ($i = 0; $i < $num; $i++) + for ($i = 0; $i < $num; $i++) { if (! $err) { $val=$array_sql[$i]; - $sql=$val; + $sql=$val; $ignoreerror=0; if (is_array($val)) { @@ -367,12 +367,12 @@ abstract class DolibarrModules // If module name translation using it's unique id does not exists, we take use its name to find translation if (is_array($this->langfiles)) { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } } - return $langs->trans($this->name); + return $langs->trans($this->name); } } @@ -389,20 +389,20 @@ abstract class DolibarrModules if ($langs->trans("Module".$this->numero."Desc") != ("Module".$this->numero."Desc")) { - // If module description translation exists + // If module description translation exists return $langs->trans("Module".$this->numero."Desc"); } else - { + { // If module description translation using it's unique id does not exists, we take use its name to find translation if (is_array($this->langfiles)) { - foreach($this->langfiles as $val) - { - if ($val) $langs->load($val); - } + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } } - return $langs->trans($this->description); + return $langs->trans($this->description); } } @@ -429,7 +429,7 @@ abstract class DolibarrModules else $ret=$langs->trans("VersionUnknown"); if (preg_match('/_deprecated/',$this->version)) $ret.=' ('.$langs->trans("Deprecated").')'; - return $ret; + return $ret; } @@ -582,9 +582,9 @@ abstract class DolibarrModules global $conf; $error=0; - $dirfound=0; + $dirfound=0; - if (empty($reldir)) return 1; + if (empty($reldir)) return 1; include_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; @@ -599,10 +599,10 @@ abstract class DolibarrModules $handle=@opendir($dir); // Dir may not exists if (is_resource($handle)) { - $dirfound++; + $dirfound++; - // Run llx_mytable.sql files - while (($file = readdir($handle))!==false) + // Run llx_mytable.sql files + while (($file = readdir($handle))!==false) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -613,8 +613,8 @@ abstract class DolibarrModules rewinddir($handle); - // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) - while (($file = readdir($handle))!==false) + // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql) + while (($file = readdir($handle))!==false) { if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -626,7 +626,7 @@ abstract class DolibarrModules rewinddir($handle); // Run data_xxx.sql files (Must be done after llx_mytable.key.sql) - while (($file = readdir($handle))!==false) + while (($file = readdir($handle))!==false) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data') { @@ -638,7 +638,7 @@ abstract class DolibarrModules rewinddir($handle); // Run update_xxx.sql files - while (($file = readdir($handle))!==false) + while (($file = readdir($handle))!==false) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update') { @@ -671,9 +671,9 @@ abstract class DolibarrModules */ function insert_boxes($option='') { - require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php'; - global $conf; + global $conf; $err=0; @@ -681,8 +681,8 @@ abstract class DolibarrModules { $pos_name = InfoBox::getListOfPagesForBoxes(); - foreach ($this->boxes as $key => $value) - { + foreach ($this->boxes as $key => $value) + { $file = isset($this->boxes[$key]['file'])?$this->boxes[$key]['file']:''; $note = isset($this->boxes[$key]['note'])?$this->boxes[$key]['note']:''; $enabledbydefaulton = isset($this->boxes[$key]['enabledbydefaulton'])?$this->boxes[$key]['enabledbydefaulton']:'Home'; @@ -724,15 +724,15 @@ abstract class DolibarrModules foreach ($pos_name as $key2 => $val2) { - //print 'key2='.$key2.'-val2='.$val2."
\n"; + //print 'key2='.$key2.'-val2='.$val2."
\n"; if ($enabledbydefaulton && $val2 != $enabledbydefaulton) continue; // Not enabled by default onto this page. - $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)"; - $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes (box_id,position,box_order,fk_user,entity)"; + $sql.= " VALUES (".$lastid.", ".$key2.", '0', 0, ".$conf->entity.")"; - dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) $err++; + dol_syslog(get_class($this)."::insert_boxes onto page ".$key2."=".$val2."", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $err++; } } @@ -741,7 +741,7 @@ abstract class DolibarrModules $this->db->commit(); } else - { + { $this->error=$this->db->lasterror(); $this->db->rollback(); } @@ -781,11 +781,22 @@ abstract class DolibarrModules if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility - $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; - $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; - $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; - $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; - $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + if ($this->db->type == 'sqlite3') { + // sqlite doesn't support "USING" syntax. + // TODO: remove this dependency. + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes "; + $sql .= "WHERE ".MAIN_DB_PREFIX."boxes.box_id IN ("; + $sql .= "SELECT ".MAIN_DB_PREFIX."boxes_def.rowid "; + $sql .= "FROM ".MAIN_DB_PREFIX."boxes_def "; + $sql .= "WHERE ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."') "; + $sql .= "AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + } else { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; + $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; + $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; + $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; + $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; + } dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); $resql=$this->db->query($sql); @@ -1027,54 +1038,54 @@ abstract class DolibarrModules if (empty($r_type)) $r_type='w'; - // Search if perm already present - $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def"; - $sql.= " WHERE id = ".$r_id." AND entity = ".$entity; - $resqlselect=$this->db->query($sql); + // Search if perm already present + $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."rights_def"; + $sql.= " WHERE id = ".$r_id." AND entity = ".$entity; + $resqlselect=$this->db->query($sql); - $obj = $this->db->fetch_object($resqlselect); + $obj = $this->db->fetch_object($resqlselect); if ($obj->nb == 0) { - if (dol_strlen($r_perms) ) - { - if (dol_strlen($r_subperms) ) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; - $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)"; - $sql.= " VALUES "; - $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')"; - } - else - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; - $sql.= " (id, entity, libelle, module, type, bydefault, perms)"; - $sql.= " VALUES "; - $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')"; - } - } - else - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def "; - $sql .= " (id, entity, libelle, module, type, bydefault)"; - $sql .= " VALUES "; - $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")"; - } + if (dol_strlen($r_perms) ) + { + if (dol_strlen($r_subperms) ) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; + $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)"; + $sql.= " VALUES "; + $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')"; + } + else + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def"; + $sql.= " (id, entity, libelle, module, type, bydefault, perms)"; + $sql.= " VALUES "; + $sql.= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')"; + } + } + else + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def "; + $sql .= " (id, entity, libelle, module, type, bydefault)"; + $sql .= " VALUES "; + $sql .= "(".$r_id.",".$entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")"; + } - $resqlinsert=$this->db->query($sql,1); + $resqlinsert=$this->db->query($sql,1); - if (! $resqlinsert) - { - if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS") - { - $this->error=$this->db->lasterror(); - $err++; - break; - } - else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO); + if (! $resqlinsert) + { + if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS") + { + $this->error=$this->db->lasterror(); + $err++; + break; + } + else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO); - } + } - $this->db->free($resqlinsert); + $this->db->free($resqlinsert); } $this->db->free($resqlselect); @@ -1082,9 +1093,9 @@ abstract class DolibarrModules // If we want to init permissions on admin users if ($reinitadminperms) { - if (! class_exists('User')) { - require DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; - } + if (! class_exists('User')) { + require DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; + } $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."user WHERE admin = 1"; dol_syslog(get_class($this)."::insert_permissions Search all admin users", LOG_DEBUG); $resqlseladmin=$this->db->query($sql,1); @@ -1099,7 +1110,7 @@ abstract class DolibarrModules $tmpuser=new User($this->db); $tmpuser->fetch($obj2->rowid); if (!empty($tmpuser->id)) { - $tmpuser->addrights($r_id); + $tmpuser->addrights($r_id); } $i++; } @@ -1158,7 +1169,7 @@ abstract class DolibarrModules */ function insert_menus() { - global $user; + global $user; require_once DOL_DOCUMENT_ROOT . '/core/class/menubase.class.php'; @@ -1415,68 +1426,68 @@ abstract class DolibarrModules */ function insert_module_parts() { - global $conf; + global $conf; - $error=0; - $entity=$conf->entity; + $error=0; + $entity=$conf->entity; - if (is_array($this->module_parts) && ! empty($this->module_parts)) - { - foreach($this->module_parts as $key => $value) - { + if (is_array($this->module_parts) && ! empty($this->module_parts)) + { + foreach($this->module_parts as $key => $value) + { if (is_array($value) && count($value) == 0) continue; // Discard empty arrays - $newvalue = $value; + $newvalue = $value; - // Serialize array parameters - if (is_array($value)) - { - // Can defined other parameters - if (is_array($value['data']) && ! empty($value['data'])) - { - $newvalue = json_encode($value['data']); - if (isset($value['entity'])) $entity = $value['entity']; - } - else - { - $newvalue = json_encode($value); - } - } + // Serialize array parameters + if (is_array($value)) + { + // Can defined other parameters + if (is_array($value['data']) && ! empty($value['data'])) + { + $newvalue = json_encode($value['data']); + if (isset($value['entity'])) $entity = $value['entity']; + } + else + { + $newvalue = json_encode($value); + } + } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; - $sql.= "name"; - $sql.= ", type"; - $sql.= ", value"; - $sql.= ", note"; - $sql.= ", visible"; - $sql.= ", entity"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1); - $sql.= ", 'chaine'"; - $sql.= ", ".$this->db->encrypt($newvalue, 1); - $sql.= ", null"; - $sql.= ", '0'"; - $sql.= ", ".$entity; - $sql.= ")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; + $sql.= "name"; + $sql.= ", type"; + $sql.= ", value"; + $sql.= ", note"; + $sql.= ", visible"; + $sql.= ", entity"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= $this->db->encrypt($this->const_name."_".strtoupper($key), 1); + $sql.= ", 'chaine'"; + $sql.= ", ".$this->db->encrypt($newvalue, 1); + $sql.= ", null"; + $sql.= ", '0'"; + $sql.= ", ".$entity; + $sql.= ")"; - dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG); - $resql=$this->db->query($sql,1); - if (! $resql) - { - if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $error++; - $this->error=$this->db->lasterror(); - } - else - { - dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING); - } - } - } - } - return $error; + dol_syslog(get_class($this)."::insert_const_".$key."", LOG_DEBUG); + $resql=$this->db->query($sql,1); + if (! $resql) + { + if ($this->db->lasterrno() != 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $error++; + $this->error=$this->db->lasterror(); + } + else + { + dol_syslog(get_class($this)."::insert_const_".$key." Record already exists.", LOG_WARNING); + } + } + } + } + return $error; } /** @@ -1486,31 +1497,31 @@ abstract class DolibarrModules */ function delete_module_parts() { - global $conf; + global $conf; - $err=0; - $entity=$conf->entity; + $err=0; + $entity=$conf->entity; - if (is_array($this->module_parts) && ! empty($this->module_parts)) - { - foreach($this->module_parts as $key => $value) - { - // If entity is defined - if (is_array($value) && isset($value['entity'])) $entity = $value['entity']; + if (is_array($this->module_parts) && ! empty($this->module_parts)) + { + foreach($this->module_parts as $key => $value) + { + // If entity is defined + if (is_array($value) && isset($value['entity'])) $entity = $value['entity']; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; - $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->const_name."_".strtoupper($key)."'"; - $sql.= " AND entity = ".$entity; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->const_name."_".strtoupper($key)."'"; + $sql.= " AND entity = ".$entity; - dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $this->error=$this->db->lasterror(); - $err++; - } - } - } - return $err; + dol_syslog(get_class($this)."::delete_const_".$key."", LOG_DEBUG); + if (! $this->db->query($sql)) + { + $this->error=$this->db->lasterror(); + $err++; + } + } + } + return $err; } } diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php index 50d5ee27b55..7b39fa06cf7 100644 --- a/htdocs/install/etape1.php +++ b/htdocs/install/etape1.php @@ -86,12 +86,15 @@ if (! is_writable($conffile)) // Check parameters +$is_sqlite = false; if (empty($db_type)) { print '
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseType")).'
'; $error++; +} else { + $is_sqlite = ($db_type === 'sqlite' || $db_type === 'sqlite3' ); } -if (empty($db_host)) +if (empty($db_host) && ! $is_sqlite) { print '
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Server")).'
'; $error++; @@ -101,7 +104,7 @@ if (empty($db_name)) print '
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseName")).'
'; $error++; } -if (empty($db_user)) +if (empty($db_user) && ! $is_sqlite) { print '
'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Login")).'
'; $error++; diff --git a/index.php b/index.php deleted file mode 100644 index e4341bb53ec..00000000000 --- a/index.php +++ /dev/null @@ -1,2 +0,0 @@ - Date: Fri, 6 Mar 2015 06:12:47 +0100 Subject: [PATCH 22/46] NEW: (Dev) DolGraph allow extended class to override $_stringtoshow --- htdocs/core/class/dolgraph.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index c400dc151d3..5451d7457ce 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -65,7 +65,7 @@ class DolGraph var $bgcolorgrid=array(255,255,255); // array(R,G,B) var $datacolor; // array(array(R,G,B),...) - private $_stringtoshow; // To store string to output graph into HTML page + protected $_stringtoshow; // To store string to output graph into HTML page /** From 9a7346f8895e54ef6e4727c87837b4726522b2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garc=C3=ADa?= Date: Fri, 6 Mar 2015 12:09:23 +0100 Subject: [PATCH 23/46] Update ChangeLog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index e861f04ae86..0664bda856d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ English Dolibarr ChangeLog - Fix: [ bug #1827 ] Tax reports gives incorrect amounts when using external modules that create lines with special codes - Fix: [ bug #1822 ] SQL error in clientfourn.php report with PostgreSQL - Fix: [ bug #1832 ] SQL error when adding a product with no price defined to an object +- Fix: [ bug #1833 ] user permissions in contact/note.php not working - Fix: [ bug #1826 ] Supplier payment types are not translated into fourn/facture/paiement.php - Fix: [ bug #1830 ] Salaries payment only allows checking accounts - Fix: [ bug #1825 ] External agenda: hide/show checkbox doesn't work From df305bd31661351190d95fff91323b4bf840fb5b Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:01:30 +0100 Subject: [PATCH 24/46] Deactivate conflict with Mod Deplacement - Need to access on old data --- htdocs/core/modules/modExpenseReport.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modExpenseReport.class.php b/htdocs/core/modules/modExpenseReport.class.php index 5d826ae9a54..cf106fa4588 100755 --- a/htdocs/core/modules/modExpenseReport.class.php +++ b/htdocs/core/modules/modExpenseReport.class.php @@ -84,7 +84,7 @@ class modExpenseReport extends DolibarrModules // Dependencies $this->depends = array(); // List of modules id that must be enabled if this module is enabled - $this->conflictwith = array("modDeplacement"); + // $this->conflictwith = array("modDeplacement"); // Deactivate for access on old information $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->phpmin = array(4,3); // Minimum version of PHP required by module $this->need_dolibarr_version = array(3,7); // Minimum version of Dolibarr required by module From 402e0c8ad5d90a33cc107b68cc597d9836f862d0 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:06:45 +0100 Subject: [PATCH 25/46] Add condition to access on dictionary c_type_fees when the module is enabled --- htdocs/admin/dict.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 05402898ee6..8de52ef73c5 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -8,7 +8,7 @@ * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2013 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2014 Alexandre Spangaro + * Copyright (C) 2011-2015 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -316,7 +316,7 @@ $tabcond[13]= (! empty($conf->commande->enabled) || ! empty($conf->propal->enabl $tabcond[14]= (! empty($conf->product->enabled) && ! empty($conf->ecotax->enabled)); $tabcond[15]= true; $tabcond[16]= (! empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)); -$tabcond[17]= ! empty($conf->deplacement->enabled); +$tabcond[17]= (! empty($conf->deplacement->enabled) || ! empty($conf->expensereport->enabled)); $tabcond[18]= ! empty($conf->expedition->enabled); $tabcond[19]= ! empty($conf->societe->enabled); $tabcond[20]= ! empty($conf->fournisseur->enabled); From f780e908f419cf49421177870283050765368eba Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:14:51 +0100 Subject: [PATCH 26/46] Add index.html --- htdocs/expensereport/ajax/index.html | 0 htdocs/expensereport/class/index.html | 0 htdocs/expensereport/index.html | 0 htdocs/expensereport/stats/index.html | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 htdocs/expensereport/ajax/index.html create mode 100644 htdocs/expensereport/class/index.html create mode 100644 htdocs/expensereport/index.html create mode 100644 htdocs/expensereport/stats/index.html diff --git a/htdocs/expensereport/ajax/index.html b/htdocs/expensereport/ajax/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/expensereport/class/index.html b/htdocs/expensereport/class/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/expensereport/index.html b/htdocs/expensereport/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/expensereport/stats/index.html b/htdocs/expensereport/stats/index.html new file mode 100644 index 00000000000..e69de29bb2d From 1baf71874ccf9a9e366a39db617f284f6e70e4cf Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:31:23 +0100 Subject: [PATCH 27/46] Sql & $_SERVER["PHP_SELF"] --- htdocs/expensereport/card.php | 10 +++++----- .../class/expensereport.class.php | 20 +++++++++---------- htdocs/expensereport/list.php | 10 +++++----- htdocs/expensereport/synchro_compta.php | 18 ++++++++--------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 86c113c24da..345d983b2f6 100755 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -733,12 +733,12 @@ if ($action == "confirm_paid" && GETPOST('confirm')=="yes" && $id > 0 && $user-> $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, $cat1, $user); if ($insertid > 0): - $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " SET integration_compta = 1, fk_bank_account = $idAccount"; $sql.= " WHERE rowid = $idTrip"; $resql=$db->query($sql); if($result): - Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); exit; else: dol_print_error($db); @@ -1529,9 +1529,9 @@ else $sql.= ' fde.fk_c_tva as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det fde'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON fde.fk_c_type_fees=ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet pjt ON fde.fk_projet=pjt.rowid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; $sql.= ' WHERE fde.fk_expensereport = '.$id; $resql = $db->query($sql); diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index b31329fae95..c34edc5ff79 100755 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -270,7 +270,7 @@ class ExpenseReport extends CommonObject $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_c_expensereport_statuts as status, d.fk_c_paiement,"; $sql.= " d.fk_user_valid, d.fk_user_approve, d.fk_user_paid,"; $sql.= " dp.libelle as libelle_paiement, dp.code as code_paiement"; // INNER JOIN paiement - $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." d LEFT JOIN ".MAIN_DB_PREFIX."c_paiement dp ON d.fk_c_paiement = dp.id"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id"; if ($ref) $sql.= " WHERE d.ref = '".$this->db->escape($ref)."'"; else $sql.= " WHERE d.rowid = ".$id; $sql.= $restrict; @@ -707,8 +707,8 @@ class ExpenseReport extends CommonObject $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; $sql.= ' p.ref as ref_projet, p.title as title_projet'; $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON de.fk_c_type_fees = ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet p ON de.fk_projet = p.rowid'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as p ON de.fk_projet = p.rowid'; $sql.= ' WHERE de.'.$this->fk_element.' = '.$this->id; dol_syslog('ExpenseReport::fetch_lines sql='.$sql, LOG_DEBUG); @@ -1186,7 +1186,7 @@ class ExpenseReport extends CommonObject // Select du taux de tva par rapport au code $sql = "SELECT t.taux as taux_tva"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_tva t"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t"; $sql.= " WHERE t.rowid = ".$c_tva; $result = $this->db->query($sql); $objp_tva = $this->db->fetch_object($result); @@ -1222,7 +1222,7 @@ class ExpenseReport extends CommonObject // Select des infos sur le type fees $sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees c"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c"; $sql.= " WHERE c.id = ".$type_fees_id; $result = $this->db->query($sql); $objp_fees = $this->db->fetch_object($result); @@ -1231,7 +1231,7 @@ class ExpenseReport extends CommonObject // Select des informations du projet $sql = "SELECT p.ref as ref_projet, p.title as title_projet"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet p"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " WHERE p.rowid = ".$projet_id; $result = $this->db->query($sql); $objp_projet = $this->db->fetch_object($result); @@ -1460,9 +1460,9 @@ class ExpenseReportLine $sql.= ' fde.fk_c_tva as tva_taux, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det fde'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON fde.fk_c_type_fees=ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet pjt ON fde.fk_projet=pjt.rowid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; $sql.= ' WHERE fde.rowid = '.$rowid; $result = $this->db->query($sql); @@ -1708,4 +1708,4 @@ function select_type_fees_id($selected='',$htmlname='type',$showempty=0) } } print ''; -} +} \ No newline at end of file diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index d6700ac26a2..76a72836e17 100755 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -88,16 +88,16 @@ $pagenext = $page + 1; $sql = "SELECT d.rowid, d.ref, d.total_ht, d.total_tva, d.total_ttc, d.fk_c_expensereport_statuts as status,"; $sql.= " d.date_debut, d.date_fin,"; $sql.= " u.rowid as id_user, u.firstname, u.lastname"; -$sql.= " FROM ".MAIN_DB_PREFIX."expensereport d\n"; -$sql.= " INNER JOIN ".MAIN_DB_PREFIX."user u ON d.fk_user_author = u.rowid\n"; +$sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; +$sql.= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON d.fk_user_author = u.rowid"; // WHERE if(!empty($search_ref)){ - $sql.= " WHERE d.ref LIKE '%".$db->escape($search_ref)."%'\n"; + $sql.= " WHERE d.ref LIKE '%".$db->escape($search_ref)."%'"; }else{ - $sql.= " WHERE 1 = 1\n"; + $sql.= " WHERE 1 = 1"; } // DATE START if ($month_start > 0) { @@ -156,7 +156,7 @@ if ($month_start > 0) { } } } -if (!empty($search_user) && $search_user > 0) $sql.= " AND d.fk_user_author = ".$search_user."\n"; +if (!empty($search_user) && $search_user > 0) $sql.= " AND d.fk_user_author = '".$search_user."'"; if($search_state != '') $sql.= " AND d.fk_c_expensereport_statuts = '$search_state'\n"; // RESTRICT RIGHTS diff --git a/htdocs/expensereport/synchro_compta.php b/htdocs/expensereport/synchro_compta.php index b8f7760e409..a436f92e682 100755 --- a/htdocs/expensereport/synchro_compta.php +++ b/htdocs/expensereport/synchro_compta.php @@ -49,12 +49,12 @@ if ($_GET["action"] == 'confirm_ndf_to_account' && $_GET["confirm"] == "yes"): $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, $cat1, $user); if ($insertid > 0): - $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " SET integration_compta = 1, fk_bank_account = $idAccount"; $sql.= " WHERE rowid = $idTrip"; $resql=$db->query($sql); if($result): - Header("Location: synchro_compta.php?account=".$idAccount); + Header("Location: ".$_SERVER["PHP_SELF"]."?account=".$idAccount); exit; else: dol_print_error($db); @@ -75,12 +75,12 @@ if ($_GET["action"] == 'confirm_account_to_ndf' && $_GET["confirm"] == "yes"): $sql.= " WHERE label LIKE '%".$expensereport->ref."%'"; $resql=$db->query($sql); if ($resql > 0): - $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " SET integration_compta = 0, fk_bank_account = 0"; $sql.= " WHERE rowid = $idTrip"; $resql=$db->query($sql); if($result): - Header("Location: synchro_compta.php?account=".$idAccount); + Header("Location: ".$_SERVER["PHP_SELF"]."?account=".$idAccount); exit; else: dol_print_error($db); @@ -110,13 +110,13 @@ dol_fiche_head(''); if ($_GET["action"] == 'ndfTOaccount'): $idTrip = $_GET['idTrip']; - $ret=$html->form_confirm("synchro_compta.php?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("ndfToAccount"),$langs->trans("ConfirmNdfToAccount"),"confirm_ndf_to_account","","",1); + $ret=$html->form_confirm($_SERVER["PHP_SELF"]."?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("ndfToAccount"),$langs->trans("ConfirmNdfToAccount"),"confirm_ndf_to_account","","",1); if ($ret == 'html') print '
'; endif; if ($_GET["action"] == 'accountTOndf'): $idTrip = $_GET['idTrip']; - $ret=$html->form_confirm("synchro_compta.php?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("AccountToNdf"),$langs->trans("ConfirmAccountToNdf"),"confirm_account_to_ndf","","",1); + $ret=$html->form_confirm($_SERVER["PHP_SELF"]."?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("AccountToNdf"),$langs->trans("ConfirmAccountToNdf"),"confirm_account_to_ndf","","",1); if ($ret == 'html') print '
'; endif; @@ -138,8 +138,8 @@ else: $sql = "SELECT d.fk_bank_account, d.ref, d.rowid, d.date_valid, d.fk_user_author, d.total_ttc, d.integration_compta, d.fk_c_expensereport_statuts"; $sql.= " ,CONCAT(u.firstname,' ',u.lastname) as declarant_NDF"; - $sql.= " FROM ".MAIN_DB_PREFIX."expensereport d"; - $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user u ON d.fk_user_author = u.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; + $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON d.fk_user_author = u.rowid"; $sql.= " WHERE d.fk_c_expensereport_statuts = 6"; $sql.= " ORDER BY d.date_valid DESC"; @@ -200,7 +200,7 @@ else: print "
'.$langs->trans("TableName").'Rows'.$langs->trans("NbOfRecord").'
"; else: - print '
'.$langs->trans("AucuneTripToSynch").'
'; + print '
'.$langs->trans("NoTripToSync").'
'; endif; $db->free($resql); From 2c738df1970fd460bbd65e955573801dc2e186a0 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:34:58 +0100 Subject: [PATCH 28/46] Add GPLV3 & Copyright --- .../class/expensereport.class.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index c34edc5ff79..e1ddbc6198b 100755 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1,5 +1,22 @@ + * Copyright (C) 2015 Laurent Destailleur + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; /** * Class to manage Trips and Expenses From 55db57d10c8fd8c0eeb5acc3186892bc3af25ef0 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:41:30 +0100 Subject: [PATCH 29/46] Path --- htdocs/expensereport/class/expensereportstats.class.php | 4 ++-- htdocs/expensereport/export_csv.php | 4 ++-- htdocs/expensereport/index.php | 4 ++-- htdocs/expensereport/list.php | 4 ++-- htdocs/expensereport/synchro_compta.php | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/expensereport/class/expensereportstats.class.php b/htdocs/expensereport/class/expensereportstats.class.php index 9536d59937d..5d71be15738 100644 --- a/htdocs/expensereport/class/expensereportstats.class.php +++ b/htdocs/expensereport/class/expensereportstats.class.php @@ -19,11 +19,11 @@ /** * \file htdocs/expensereport/class/expensereportstats.class.php - * \ingroup factures + * \ingroup ExpenseReport * \brief Fichier de la classe de gestion des stats des expensereport et notes de frais */ include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; -dol_include_once('/expensereport/class/expensereport.class.php'); +include_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; /** * Classe permettant la gestion des stats des expensereports et notes de frais diff --git a/htdocs/expensereport/export_csv.php b/htdocs/expensereport/export_csv.php index 05036deaf7c..8228eb68532 100755 --- a/htdocs/expensereport/export_csv.php +++ b/htdocs/expensereport/export_csv.php @@ -21,8 +21,8 @@ */ require '../main.inc.php'; -require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php"); -dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; $langs->load("users"); $langs->load("trips"); diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index 89469609e2a..b90e6416192 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -25,8 +25,8 @@ */ require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; -dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT . '/compta/tva/class/tva.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; $langs->load("companies"); $langs->load("users"); diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 76a72836e17..44f1426fd36 100755 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -25,8 +25,8 @@ */ require "../main.inc.php"; -dol_include_once("/expensereport/class/expensereport.class.php"); -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; $langs->load("companies"); $langs->load("users"); diff --git a/htdocs/expensereport/synchro_compta.php b/htdocs/expensereport/synchro_compta.php index a436f92e682..ec2703d059a 100755 --- a/htdocs/expensereport/synchro_compta.php +++ b/htdocs/expensereport/synchro_compta.php @@ -16,8 +16,8 @@ */ require '../main.inc.php'; -require_once(DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'); -dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; $langs->load("companies"); $langs->load("users"); From 26b1f6902548a7b86c66283bb863695718ba3d7c Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sat, 7 Mar 2015 15:47:08 +0100 Subject: [PATCH 30/46] Add traduction on type label --- .../class/expensereport.class.php | 33 +++++++++++++++++++ htdocs/expensereport/index.php | 3 +- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index e1ddbc6198b..c14c7ff2be7 100755 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1420,6 +1420,39 @@ class ExpenseReport extends CommonObject return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); } + + /** + * List of types + * + * @param int $active Active or not + * @return array + */ + function listOfTypes($active=1) + { + global $langs; + $ret=array(); + $sql = "SELECT id, code, label"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees"; + $sql.= " WHERE active = ".$active; + dol_syslog(get_class($this)."::listOfTypes", LOG_DEBUG); + $result = $this->db->query($sql); + if ( $result ) + { + $num = $this->db->num_rows($result); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + $ret[$obj->code]=(($langs->trans($obj->code)!=$obj->code)?$langs->trans($obj->code):$obj->label); + $i++; + } + } + else + { + dol_print_error($this->db); + } + return $ret; + } } diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index b90e6416192..ec9ccba2c0b 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -111,8 +111,7 @@ print ''; print ''.$langs->trans("Statistics").''; print "\n"; -//$listoftype=$tripandexpense_static->listOfTypes(); -$listoftype=$label; +$listoftype=$tripandexpense_static->listOfTypes(); foreach ($listoftype as $code => $label) { $dataseries[]=array('label'=>$label,'data'=>(isset($somme[$code])?(int) $somme[$code]:0)); From f3258d59c6f97e192256815dd5cb002c3f78749b Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 8 Mar 2015 07:21:07 +0100 Subject: [PATCH 31/46] Uniformize status & add price() --- htdocs/compta/hrm.php | 8 +-- htdocs/expensereport/card.php | 44 +++++++-------- .../class/expensereport.class.php | 54 +++++++++---------- .../class/expensereportstats.class.php | 2 +- htdocs/expensereport/index.php | 6 +-- htdocs/expensereport/list.php | 4 +- htdocs/expensereport/synchro_compta.php | 4 +- .../install/mysql/migration/3.7.0-3.8.0.sql | 2 +- .../mysql/tables/llx_expensereport.sql | 2 +- 9 files changed, 63 insertions(+), 63 deletions(-) diff --git a/htdocs/compta/hrm.php b/htdocs/compta/hrm.php index 866399ef1cc..59389f41d51 100644 --- a/htdocs/compta/hrm.php +++ b/htdocs/compta/hrm.php @@ -196,7 +196,7 @@ if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire) if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire) { - $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, x.rowid, x.date_debut as date, x.tms as dm, x.total_ttc"; + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, x.rowid, x.date_debut as date, x.tms as dm, x.total_ttc, x.fk_statut as status"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as x, ".MAIN_DB_PREFIX."user as u"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE u.rowid = x.fk_user_author"; @@ -218,7 +218,7 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; print ''; @@ -239,9 +239,9 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire print ''; print ''; print ''; - print ''; + print ''; print ''; - //print ''; + print ''; print ''; $var=!$var; $i++; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 345d983b2f6..02d899def0a 100755 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -109,7 +109,7 @@ if ($action == 'add' && $user->rights->expensereport->creer) $object->date_debut = $date_start; $object->date_fin = $date_end; - $object->fk_c_expensereport_statuts = 1; + $object->fk_statut = 1; $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); $object->fk_user_validator = GETPOST('fk_user_validator','int'); $object->note_public = GETPOST('note_public'); @@ -151,7 +151,7 @@ if ($action == 'update' && $user->rights->expensereport->creer) $object->date_debut = $date_start; $object->date_fin = $date_end; - if($object->fk_c_expensereport_statuts < 3) + if($object->fk_statut < 3) { $object->fk_user_validator = GETPOST('fk_user_validator','int'); } @@ -1197,7 +1197,7 @@ else $head = expensereport_prepare_head($object); - if ($action == 'edit' && ($object->fk_c_expensereport_statuts < 3 || $object->fk_c_expensereport_statuts==99)) + if ($action == 'edit' && ($object->fk_statut < 3 || $object->fk_statut==99)) { print "\n"; print ''; @@ -1205,7 +1205,7 @@ else dol_fiche_head($head, 'card', $langs->trans("TripCard"), 0, 'trip'); - if($object->fk_c_expensereport_statuts==99) + if($object->fk_statut==99) { print ''; } @@ -1246,7 +1246,7 @@ else print ''; } - if($object->fk_c_expensereport_statuts<3) + if($object->fk_statut<3) { print ''; print ''; // Approbator @@ -1275,7 +1275,7 @@ else $userfee->fetch($object->fk_user_author); print $userfee->getNomUrl(1); print ''; - if ($object->fk_c_expensereport_statuts==6) + if ($object->fk_statut==6) { print ''; print ''; @@ -1437,7 +1437,7 @@ else print ''; print ''; print ''; - if($object->fk_c_expensereport_statuts==6) + if($object->fk_statut==6) { print ''; print ''; @@ -1452,7 +1452,7 @@ else print ''; } - if($object->fk_c_expensereport_statuts<3) // informed + if($object->fk_statut<3) // informed { print ''; print ''; @@ -1465,7 +1465,7 @@ else } print ''; } - elseif($object->fk_c_expensereport_statuts==4) + elseif($object->fk_statut==4) { print ''; print ''; @@ -1504,7 +1504,7 @@ else print ''; } - if($object->fk_c_expensereport_statuts==99 || !empty($object->detail_refuse)) + if($object->fk_statut==99 || !empty($object->detail_refuse)) { print ''; print ''; @@ -1566,7 +1566,7 @@ else print ''; } // Ajout des boutons de modification/suppression - if ($object->fk_c_expensereport_statuts < 2 || $object->fk_c_expensereport_statuts==99) + if ($object->fk_statut < 2 || $object->fk_statut==99) { print ''; } @@ -1609,7 +1609,7 @@ else } // Ajout des boutons de modification/suppression - if($object->fk_c_expensereport_statuts<2 OR $object->fk_c_expensereport_statuts==99) + if($object->fk_statut<2 OR $object->fk_statut==99) { print ''; print ''; print ''; - print ''; - print ''; + print ''; + print ''; print ''; print ''; - // Sélection date + // Select date print ''; - // Sélection projet + // Select project print ''; - // Sélection type + // Select type print ''; @@ -1732,7 +1732,7 @@ else print ''; print ''; - // Sélection TVA + // Select VAT print ''; - // Quantité + // Quantity print ''; diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 5d82aa1be4e..864c169c11c 100755 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -335,7 +335,7 @@ class ExpenseReport extends CommonObject if ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator); $this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname); - $this->fk_statut = $obj->status; + $this->fk_statut = $obj->status; $this->status = $obj->status; $this->fk_c_paiement = $obj->fk_c_paiement; diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index f48a0111a46..6d82b86e4af 100755 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -21,12 +21,13 @@ /** * \file htdocs/expensereport/index.php - * \brief Page liste des expensereports + * \brief list of expense reports */ require "../main.inc.php"; require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; $langs->load("companies"); $langs->load("users"); @@ -39,7 +40,7 @@ $result = restrictedArea($user, 'expensereport','',''); $search_ref = GETPOST('search_ref'); $search_user = GETPOST('search_user','int'); -$search_state = GETPOST('search_state','int'); +$search_status = GETPOST('search_status','int'); $month_start = GETPOST("month_start","int"); $year_start = GETPOST("year_start","int"); $month_end = GETPOST("month_end","int"); @@ -49,7 +50,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both { $search_ref=""; $search_user=""; - $search_state=""; + $search_status=""; $month_start=""; $year_start=""; $month_end=""; @@ -69,13 +70,12 @@ llxHeader('', $langs->trans("ListOfTrips")); $max_year = 5; $min_year = 5; -$sortorder = $_GET["sortorder"]; -$sortfield = $_GET["sortfield"]; -$page = $_GET["page"]; +$sortorder = GETPOST("sortorder"); +$sortfield = GETPOST("sortfield"); +$page = GETPOST("page"); if (!$sortorder) $sortorder="DESC"; if (!$sortfield) $sortfield="d.date_debut"; - if ($page == -1) { $page = 0 ; } @@ -91,73 +91,47 @@ $sql.= " u.rowid as id_user, u.firstname, u.lastname"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON d.fk_user_author = u.rowid"; - - -// WHERE +// Where if(!empty($search_ref)){ $sql.= " WHERE d.ref LIKE '%".$db->escape($search_ref)."%'"; }else{ $sql.= " WHERE 1 = 1"; } -// DATE START -if ($month_start > 0) { - if ($year_start > 0) { - if($month_end > 0) { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; - } - } else { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; - } - } - } else { - $sql.= " AND date_format(d.date_debut, '%m') >= '$month_start'"; - } -} else { - if ($year_start > 0) { - if($month_end > 0) { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; - } - } else { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - } - } - } else { - if($month_end > 0) { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; - } else { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; - } - } else { - if($year_end > 0) { - $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; - $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; - } - } - } +// Date Start +if ($month_start > 0) +{ + if ($year_start > 0 && empty($day)) + $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_get_first_day($year_start,$month_start,false))."' AND '".$db->idate(dol_get_last_day($year_start,$month_start,false))."'"; + else if ($year_start > 0 && ! empty($day)) + $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_start, $day, $year_start))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_start, $day, $year_start))."'"; + else + $sql.= " AND date_format(d.date_debut, '%m') = '".$month_start."'"; } -if (!empty($search_user) && $search_user > 0) $sql.= " AND d.fk_user_author = '".$search_user."'"; -if($search_state != '') $sql.= " AND d.fk_statut = '$search_state'\n"; +else if ($year_start > 0) +{ + $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_get_first_day($year_start,1,false))."' AND '".$db->idate(dol_get_last_day($year_start,12,false))."'"; +} +// Date Start +if ($month_end > 0) +{ + if ($year_end > 0 && empty($day)) + $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_get_first_day($year_end,$month_end,false))."' AND '".$db->idate(dol_get_last_day($year_end,$month_end,false))."'"; + else if ($year_end > 0 && ! empty($day)) + $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_end, $day, $year_end))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_end, $day, $year_end))."'"; + else + $sql.= " AND date_format(d.date_fin, '%m') = '".$month_end."'"; +} +else if ($year_end > 0) +{ + $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_get_first_day($year_end,1,false))."' AND '".$db->idate(dol_get_last_day($year_end,12,false))."'"; +} +// User +if ($search_name) +{ + $sql .= natural_search('u.lastname', $search_name); +} +// Status +if($search_status != '') $sql.= " AND d.fk_statut = '".$search_status."'"; // RESTRICT RIGHTS if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) @@ -219,17 +193,13 @@ if ($resql) print ''; } - print ''; - print ''; - - print '"; + print ''; // Status print ''; print ''; print ''; print ''; - /*print ''; - print ''; - print ''; - */ print ''; print ''; print ''; @@ -281,11 +247,7 @@ if ($resql) print ''; print ''; - /* - print ''; - print ''; - print ''; - */ + print ''; print ''; print ''; From e6984bae9d260e33b856d05106420623340d11a8 Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Sun, 8 Mar 2015 12:37:07 +0100 Subject: [PATCH 33/46] FIX: jdate returning -62169955200 on x64 machine on x64 machine jdate return -62169955200 instead of 0 when the input is 00-00-00 00:00:00 or equivalent same issue for mktime https://bugs.php.net/bug.php?id=53662 --- htdocs/core/db/DoliDB.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 67e3022d6e3..c689e49b85e 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -274,6 +274,8 @@ abstract class DoliDB implements Database */ function jdate($string, $gm=false) { + if($string==0 || $string=="0000-00-00 00:00:00") + return NULL; $string=preg_replace('/([^0-9])/i','',$string); $tmp=$string.'000000'; $date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),$gm); From 9d320e4268132df3a3accadf196524699f649b3a Mon Sep 17 00:00:00 2001 From: "Estephe L." Date: Sun, 8 Mar 2015 23:29:09 +0100 Subject: [PATCH 34/46] Fix Anchor link for quick access when editing. This is a quick fix to make anchor link works well when editing a proposal, order or invoice ... --- htdocs/core/tpl/objectline_view.tpl.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 948a61bae2c..c31d8da9277 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -27,7 +27,7 @@ global->MAIN_VIEW_LINE_NUMBER)) { ?> - '; + } print_liste_field_titre($langs->trans("DefaultRIB"), '', '', '', '', 'align="center"'); print ''; print ''; @@ -356,6 +362,12 @@ if ($socid && $action != 'edit' && $action != "create") print ''; // BIC print ''; + + if (! empty($conf->prelevement->enabled)) + { + print ''; + } + // Default print '\n"; // Date end validity From 05a2a6af00f1c2a2934574d8d961fe3e27b41a7e Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Tue, 10 Mar 2015 15:53:02 +0100 Subject: [PATCH 39/46] FIX : [bug #1900] Unable to remove a salary with enough permissions --- htdocs/compta/salaries/fiche.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/salaries/fiche.php b/htdocs/compta/salaries/fiche.php index 34a2b9b4435..dac250eabc7 100644 --- a/htdocs/compta/salaries/fiche.php +++ b/htdocs/compta/salaries/fiche.php @@ -365,7 +365,7 @@ if ($id) print "
\n"; if ($salpayment->rappro == 0) { - if (! empty($user->rights->tax->charges->supprimer)) + if (! empty($user->rights->salaries->delete)) { print ''.$langs->trans("Delete").''; } From 0df2b4cc26cc8c76d7f5338e3a611a11a9cec037 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Mar 2015 16:14:46 +0100 Subject: [PATCH 40/46] Fix check parameters --- htdocs/societe/class/societe.class.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index a18aedfcc1b..dc6503646b4 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1158,12 +1158,21 @@ class Societe extends CommonObject * @param boolean $case Case sensitive (true/false) * @param boolean $similar Add test if string inside name into database, or name into database inside string. Do not use this: Not compatible with other database. * @param string $clause Clause for filters - * @return array Array of thirdparties object + * @return array|int <0 if KO, array of thirdparties object if OK */ function searchByName($name, $type='0', $filters = array(), $exact = false, $case = false, $similar = false, $clause = 'AND') { $thirdparties = array(); + dol_syslog("searchByName name=".$name." type=".$type." exact=".$exact); + + // Check parameter + if (empty($name)) + { + $this->errors[]='ErrorBadValueForParameter'; + return -1; + } + // Generation requete recherche $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe"; $sql.= " WHERE entity IN (".getEntity('category',1).")"; @@ -1242,7 +1251,7 @@ class Societe extends CommonObject } else { - $this->error=$this->db->error().' sql='.$sql; + $this->error=$this->db->lasterror(); return -1; } } From 154865f545466e212e8f85f4aa34ab3ae66cb2e3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Mar 2015 16:37:39 +0100 Subject: [PATCH 41/46] Fix return error when it is not --- htdocs/societe/class/societe.class.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index dc6503646b4..181c9f3ec8d 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -953,7 +953,7 @@ class Societe extends CommonObject * @param string $idprof2 Prof id 2 of third party (Warning, this can return several records) * @param string $idprof3 Prof id 3 of third party (Warning, this can return several records) * @param string $idprof4 Prof id 4 of third party (Warning, this can return several records) - * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof. + * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found. */ function fetch($rowid, $ref='', $ref_ext='', $ref_int='', $idprof1='',$idprof2='',$idprof3='',$idprof4='') { @@ -1008,7 +1008,7 @@ class Societe extends CommonObject { $this->error='Fetch several records found for ref='.$ref; dol_syslog($this->error, LOG_ERR); - $result = -1; + $result = -2; } if ($num) { @@ -1128,17 +1128,15 @@ class Societe extends CommonObject $this->fetch_optionals($this->id,$extralabels); } else - { - $this->error='Fetch no third party found for id='.$rowid; - dol_syslog($this->error, LOG_ERR); - $result = -2; + { + $result = 0; } $this->db->free($resql); } else - { - $this->error=$this->db->error(); + { + $this->error=$this->db->lasterror(); $result = -3; } From 364b1854424aacc1fcb54f12503b9220f2e9b5a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Mar 2015 18:33:14 +0100 Subject: [PATCH 42/46] Fix sql syntax --- htdocs/core/class/extrafields.class.php | 88 ++++++++++++++----------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index f1ad5d6687f..5a79c5ccf97 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -48,10 +48,12 @@ class ExtraFields var $attribute_required; // Array to store parameters of attribute (used in select type) var $attribute_param; - // Int to store position of attribute + // Array to store position of attribute var $attribute_pos; - // Int to store if attribute is editable regardless of the document status + // Array to store if attribute is editable regardless of the document status var $attribute_alwayseditable; + // Array to store permission to check + var $attribute_perms; var $error; var $errno; @@ -90,6 +92,7 @@ class ExtraFields $this->attribute_elementtype = array(); $this->attribute_unique = array(); $this->attribute_required = array(); + $this->attribute_perms = array(); } /** @@ -106,9 +109,10 @@ class ExtraFields * @param string $default_value Defaulted value * @param array $param Params for field * @param int $alwayseditable Is attribute always editable regardless of the document status + * @param string $perms Permission to check * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0) + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='') { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -124,7 +128,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable); + $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable, $perms); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -225,9 +229,10 @@ class ExtraFields * @param int $required Is field required or not * @param array||string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status + * @param string $perms Permission to check * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0) + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='') { global $conf; @@ -251,7 +256,7 @@ class ExtraFields $params=''; } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable)"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable, perms)"; $sql.= " VALUES('".$attrname."',"; $sql.= " '".$this->db->escape($label)."',"; $sql.= " '".$type."',"; @@ -262,7 +267,8 @@ class ExtraFields $sql.= " '".$unique."',"; $sql.= " '".$required."',"; $sql.= " '".$params."',"; - $sql.= " '".$alwayseditable."'"; + $sql.= " '".$alwayseditable."',"; + $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null"); $sql.=')'; dol_syslog(get_class($this)."::create_label", LOG_DEBUG); @@ -363,9 +369,10 @@ class ExtraFields * @param int $pos Position of attribute * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status + * @param string $perms Permission to check * @return int >0 if OK, <=0 if KO */ - function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0) + function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='') { if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -402,7 +409,7 @@ class ExtraFields { if ($label) { - $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable); + $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms); } if ($result > 0) { @@ -451,12 +458,13 @@ class ExtraFields * @param int $pos Position of attribute * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status + * @param string $perms Permission to check * @return int <=0 if KO, >0 if OK */ - private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0) + private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='') { global $conf; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms); if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -485,6 +493,7 @@ class ExtraFields $sql.= " elementtype,"; $sql.= " fieldunique,"; $sql.= " fieldrequired,"; + $sql.= " perms,"; $sql.= " pos,"; $sql.= " alwayseditable,"; $sql.= " param"; @@ -497,6 +506,7 @@ class ExtraFields $sql.= " '".$elementtype."',"; $sql.= " '".$unique."',"; $sql.= " '".$required."',"; + $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").","; $sql.= " '".$pos."',"; $sql.= " '".$alwayseditable."',"; $sql.= " '".$param."'"; @@ -542,7 +552,7 @@ class ExtraFields // For avoid conflicts with external modules if (!$forceload && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label; - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms"; $sql.= " FROM ".MAIN_DB_PREFIX."extrafields"; $sql.= " WHERE entity IN (0,".$conf->entity.")"; if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'"; @@ -571,6 +581,7 @@ class ExtraFields $this->attribute_param[$tab->name]=unserialize($tab->param); $this->attribute_pos[$tab->name]=$tab->pos; $this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable; + $this->attribute_perms[$tab->name]=$tab->perms; } } } @@ -603,6 +614,8 @@ class ExtraFields $unique=$this->attribute_unique[$key]; $required=$this->attribute_required[$key]; $param=$this->attribute_param[$key]; + $perms=$this->attribute_perms[$key]; + if ($type == 'date') { $showsize=10; @@ -883,7 +896,7 @@ class ExtraFields elseif ($type == 'chkbxlst') { $value_arr = explode(',', $value); - + if (is_array($param['options'])) { $param_list = array_keys($param['options']); $InfoFieldList = explode(":", $param_list[0]); @@ -893,7 +906,7 @@ class ExtraFields // 3 : key field parent (for dependent lists) // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid'); - + if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) { list ( $parentName, $parentField ) = explode('|', $InfoFieldList[3]); $keyList .= ', ' . $parentField; @@ -905,13 +918,13 @@ class ExtraFields $keyList = $InfoFieldList[2] . ' as rowid'; } } - + $fields_label = explode('|', $InfoFieldList[1]); if (is_array($fields_label)) { $keyList .= ', '; $keyList .= implode(', ', $fields_label); } - + $sqlwhere = ''; $sql = 'SELECT ' . $keyList; $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0]; @@ -927,7 +940,7 @@ class ExtraFields $sqlwhere .= ' WHERE 1'; } if (in_array($InfoFieldList[0], array ( - 'tablewithentity' + 'tablewithentity' ))) $sqlwhere .= ' AND entity = ' . $conf->entity; // Some tables may have field, some other not. For the moment we disable it. // $sql.=preg_replace('/^ AND /','',$sqlwhere); @@ -941,7 +954,7 @@ class ExtraFields while ( $i < $num ) { $labeltoshow = ''; $obj = $this->db->fetch_object($resql); - + // Several field into label (eq table:code|libelle:rowid) $fields_label = explode('|', $InfoFieldList[1]); if (is_array($fields_label)) { @@ -953,7 +966,7 @@ class ExtraFields $labeltoshow = $obj->$InfoFieldList[1]; } $labeltoshow = dol_trunc($labeltoshow, 45); - + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { foreach ( $fields_label as $field_toshow ) { $translabel = $langs->trans($obj->$field_toshow); @@ -965,9 +978,9 @@ class ExtraFields } $out .= 'rowid . '"'; - + $out .= 'checked="checked"'; - + $out .= '/>' . $labeltoshow . '
'; } else { if (! $notrans) { @@ -980,31 +993,31 @@ class ExtraFields } if (empty($labeltoshow)) $labeltoshow = '(not defined)'; - + if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { $out .= 'rowid . '"'; - + $out .= 'checked="checked"'; $out .= ''; - + $out .= '/>' . $labeltoshow . '
'; } - + if (! empty($InfoFieldList[3])) { $parent = $parentName . ':' . $obj->{$parentField}; } - + $out .= 'rowid . '"'; - + $out .= ((is_array($value_arr) && in_array($obj->rowid, $value_arr)) ? ' checked="checked" ' : ''); ; $out .= ''; - + $out .= '/>' . $labeltoshow . '
'; } - + $i ++; } $this->db->free($resql); @@ -1040,6 +1053,7 @@ class ExtraFields $unique=$this->attribute_unique[$key]; $required=$this->attribute_required[$key]; $params=$this->attribute_param[$key]; + $perms=$this->attribute_perms[$key]; if ($type == 'date') { $showsize=10; @@ -1172,24 +1186,24 @@ class ExtraFields elseif ($type == 'chkbxlst') { $value_arr = explode(',', $value); - + $param_list = array_keys($params['options']); $InfoFieldList = explode(":", $param_list[0]); - + $selectkey = "rowid"; $keyList = 'rowid'; - + if (count($InfoFieldList) >= 3) { $selectkey = $InfoFieldList[2]; $keyList = $InfoFieldList[2] . ' as rowid'; } - + $fields_label = explode('|', $InfoFieldList[1]); if (is_array($fields_label)) { $keyList .= ', '; $keyList .= implode(', ', $fields_label); } - + $sql = 'SELECT ' . $keyList; $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0]; if (strpos($InfoFieldList[4], 'extra') !== false) { @@ -1197,14 +1211,14 @@ class ExtraFields } // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'"; // $sql.= ' AND entity = '.$conf->entity; - + dol_syslog(get_class($this) . ':showOutputField:$type=chkbxlst',LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $value = ''; // value was used, so now we reste it to use it to build final output - + while ( $obj = $this->db->fetch_object($resql) ) { - + // Several field into label (eq table:code|libelle:rowid) $fields_label = explode('|', $InfoFieldList[1]); if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { From 548e720ca2c76b45417f27ca990ebe46d5615499 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Mar 2015 19:31:04 +0100 Subject: [PATCH 43/46] Uniformize code --- htdocs/comm/propal.php | 17 ++++++++--------- htdocs/core/tpl/extrafields_view.tpl.php | 2 +- htdocs/fourn/commande/card.php | 22 +++++++++++----------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 98f662e3d5d..4a45f724f01 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -2003,8 +2003,7 @@ if ($action == 'create') // Amount HT print '
'; - print ''; - print ''; + print ''; // Margin Infos if (! empty($conf->margin->enabled)) { @@ -2016,27 +2015,27 @@ if ($action == 'create') // Amount VAT print ''; - print ''; - print ''; + print ''; + print ''; // Amount Local Taxes if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) // Localtax1 { print ''; - print ''; + print ''; print ''; } if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) // Localtax2 { print ''; - print ''; - print ''; + print ''; + print ''; } // Amount TTC print ''; - print ''; - print ''; + print ''; + print ''; // Statut print ''; diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 7f0115b83bc..b6b26cc380d 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -65,7 +65,7 @@ if (empty($reshook) && ! empty($extrafields->attribute_label)) print ''; print '
'.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).''.$langs->trans("FeesAmount").''.$langs->trans("TotalTTC").''.$langs->trans("DateModificationShort").' 
'.$expensereportstatic->getNomUrl(1).''.$userstatic->getNomUrl(1).''.$obj->total_ttc.''.price($obj->total_ttc).''.dol_print_date($db->jdate($obj->dm),'day').''.$expensereportstatic->LibStatut($obj->fk_statut,3).''.$expensereportstatic->LibStatut($obj->status,3).'
'.$langs->trans("VALIDATOR").'
'.$langs->trans("AUTHORPAIEMENT").''.$langs->trans("DATE_SAVE").''.dol_print_date($object->date_create,'dayhour').'
'.$langs->trans("AUTHORPAIEMENT").'
'.$langs->trans("VALIDATOR").'
'.$langs->trans("CANCEL_USER").'
'.$langs->trans("REFUSEUR").''.$langs->trans('AmountTTC').''; print 'rowid.'#'.$objp->rowid.'">'; @@ -1689,7 +1689,7 @@ else //print ''; // Add a line - if (($object->fk_c_expensereport_statuts==0 || $object->fk_c_expensereport_statuts==99) && $action != 'editline') + if (($object->fk_statut==0 || $object->fk_statut==99) && $action != 'editline') { print_fiche_titre($langs->trans("AddLine"),'',''); @@ -1799,7 +1799,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" */ - if ($user->rights->expensereport->creer && $object->fk_c_expensereport_statuts==0) + if ($user->rights->expensereport->creer && $object->fk_statut==0) { if ($object->fk_user_author == $user->id) { @@ -1825,7 +1825,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" */ - if($user->rights->expensereport->creer && $object->fk_c_expensereport_statuts==99) + if($user->rights->expensereport->creer && $object->fk_statut==99) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { @@ -1845,7 +1845,7 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==5) + if ($user->rights->expensereport->to_paid && $object->fk_statut==5) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { @@ -1859,7 +1859,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_validator == user courant * Afficher : "Valider" / "Refuser" / "Supprimer" */ - if ($object->fk_c_expensereport_statuts == 2) + if ($object->fk_statut == 2) { if ($object->fk_user_author == $user->id) { @@ -1868,7 +1868,7 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->approve && $object->fk_c_expensereport_statuts == 2) + if ($user->rights->expensereport->approve && $object->fk_statut == 2) { //if($object->fk_user_validator==$user->id) //{ @@ -1895,7 +1895,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit de "to_paid" * Afficher : "Annuler" / "Payer" / "Supprimer" */ - if ($user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts == 5) + if ($user->rights->expensereport->to_paid && $object->fk_statut == 5) { // Payer print ''.$langs->trans('TO_PAID').''; @@ -1918,7 +1918,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit "to_paid" * Afficher : "Annuler" */ - if ($user->rights->expensereport->approve && $user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==6) + if ($user->rights->expensereport->approve && $user->rights->expensereport->to_paid && $object->fk_statut==6) { // Annuler print ''.$langs->trans('Cancel').''; @@ -1933,7 +1933,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit "supprimer" * Afficher : "Supprimer" */ - if ($user->rights->expensereport->supprimer && $object->fk_c_expensereport_statuts==4) + if ($user->rights->expensereport->supprimer && $object->fk_statut==4) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) @@ -1959,7 +1959,7 @@ print '
'; /* * Documents generes */ -if($user->rights->expensereport->export && $object->fk_c_expensereport_statuts>0 && $action != 'edit') +if($user->rights->expensereport->export && $object->fk_statut>0 && $action != 'edit') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref); diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index c14c7ff2be7..5d82aa1be4e 100755 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -43,7 +43,7 @@ class ExpenseReport extends CommonObject var $fk_user_validator; var $status; - var $fk_c_expensereport_statuts; // -- 1=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied + var $fk_statut; // -- 1=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied var $fk_c_paiement; var $user_author_infos; @@ -150,7 +150,7 @@ class ExpenseReport extends CommonObject $sql.= ",date_create"; $sql.= ",fk_user_author"; $sql.= ",fk_user_validator"; - $sql.= ",fk_c_expensereport_statuts"; + $sql.= ",fk_statut"; $sql.= ",fk_c_paiement"; $sql.= ",note_public"; $sql.= ",note_private"; @@ -164,7 +164,7 @@ class ExpenseReport extends CommonObject $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", ".($user->id > 0 ? $user->id:"null"); $sql.= ", ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); - $sql.= ", ".($this->fk_c_expensereport_statuts > 1 ? $this->fk_c_expensereport_statuts:0); + $sql.= ", ".($this->fk_statut > 1 ? $this->fk_statut:0); $sql.= ", ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null"); $sql.= ", ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); $sql.= ", ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); @@ -248,7 +248,7 @@ class ExpenseReport extends CommonObject $sql.= " , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); $sql.= " , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid:"null"); $sql.= " , fk_user_paid = ".($this->fk_user_paid > 0 ? $this->fk_user_paid:"null"); - $sql.= " , fk_c_expensereport_statuts = ".($this->fk_c_expensereport_statuts >= 0 ? $this->fk_c_expensereport_statuts:'0'); + $sql.= " , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut:'0'); $sql.= " , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null"); $sql.= " , note_public = ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"''"); $sql.= " , note_private = ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"''"); @@ -284,7 +284,7 @@ class ExpenseReport extends CommonObject $sql.= " d.date_refuse, d.date_cancel,"; // ACTIONS $sql.= " d.total_ht, d.total_ttc, d.total_tva,"; // TOTAUX (int) $sql.= " d.date_debut, d.date_fin, d.date_create, d.date_valid, d.date_approve, d.date_paiement,"; // DATES (datetime) - $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_c_expensereport_statuts as status, d.fk_c_paiement,"; + $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_statut as status, d.fk_c_paiement,"; $sql.= " d.fk_user_valid, d.fk_user_approve, d.fk_user_paid,"; $sql.= " dp.libelle as libelle_paiement, dp.code as code_paiement"; // INNER JOIN paiement $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id"; @@ -335,18 +335,18 @@ class ExpenseReport extends CommonObject if ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator); $this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname); - $this->fk_c_expensereport_statuts = $obj->status; + $this->fk_statut = $obj->status; $this->status = $obj->status; $this->fk_c_paiement = $obj->fk_c_paiement; - if ($this->fk_c_expensereport_statuts==5 || $this->fk_c_expensereport_statuts==6) + if ($this->fk_statut==5 || $this->fk_statut==6) { $user_valid = new User($this->db); if ($this->fk_user_valid > 0) $user_valid->fetch($this->fk_user_valid); $this->user_valid_infos = dolGetFirstLastname($user_valid->firstname, $user_valid->lastname); } - if ($this->fk_c_expensereport_statuts==6) + if ($this->fk_statut==6) { $user_paid = new User($this->db); if ($this->fk_user_paid > 0) $user_paid->fetch($this->fk_user_paid); @@ -514,7 +514,7 @@ class ExpenseReport extends CommonObject $this->date_approve = $now; $this->status = 5; - $this->fk_c_expensereport_statuts = 5; + $this->fk_statut = 5; $this->fk_user_author = $user->id; $this->fk_user_valid = $user->id; @@ -584,7 +584,7 @@ class ExpenseReport extends CommonObject $objp = $db->fetch_object($result); - $sql2 = "SELECT d.rowid, d.fk_user_author, d.ref, d.fk_c_expensereport_statuts"; + $sql2 = "SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut"; $sql2.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; $sql2.= " WHERE d.rowid = '".$objp->fk_expensereport."'"; @@ -593,7 +593,7 @@ class ExpenseReport extends CommonObject $objp->fk_user_author = $obj->fk_user_author; $objp->ref = $obj->ref; - $objp->fk_c_expensereport_status = $obj->fk_c_expensereport_statuts; + $objp->fk_c_expensereport_status = $obj->fk_statut; $objp->rowid = $obj->rowid; $total_HT = $total_HT + $objp->total_ht; @@ -848,10 +848,10 @@ class ExpenseReport extends CommonObject $this->ref = strtoupper($user->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d'); } - if ($this->fk_c_expensereport_statuts != 2) + if ($this->fk_statut != 2) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_c_expensereport_statuts = 2, fk_user_valid = ".$user->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$user->id.","; $sql.= " ref_number_int = ".$ref_number_int; $sql.= ' WHERE rowid = '.$this->id; @@ -894,10 +894,10 @@ class ExpenseReport extends CommonObject $this->date_debut = $this->db->jdate($objp->date_debut); - if ($this->fk_c_expensereport_statuts != 2) + if ($this->fk_statut != 2) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 2"; + $sql.= " SET fk_statut = 2"; $sql.= ' WHERE rowid = '.$this->id; dol_syslog(get_class($this)."::set_save_from_refuse sql=".$sql, LOG_DEBUG); @@ -930,10 +930,10 @@ class ExpenseReport extends CommonObject // date approval $this->date_approve = $this->db->idate($now); - if ($this->fk_c_expensereport_statuts != 5) + if ($this->fk_statut != 5) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_c_expensereport_statuts = 5, fk_user_approve = ".$user->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 5, fk_user_approve = ".$user->id.","; $sql.= " date_approve='".$this->date_approve."'"; $sql.= ' WHERE rowid = '.$this->id; if ($this->db->query($sql)) @@ -963,17 +963,17 @@ class ExpenseReport extends CommonObject $now = dol_now(); // date de refus - if ($this->fk_c_expensereport_statuts != 99) + if ($this->fk_statut != 99) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_c_expensereport_statuts = 99, fk_user_refuse = ".$user->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 99, fk_user_refuse = ".$user->id.","; $sql.= " date_refuse='".$this->db->idate($now)."',"; $sql.= " detail_refuse='".$this->db->escape($details)."'"; $sql.= " fk_user_approve=NULL,"; $sql.= ' WHERE rowid = '.$this->id; if ($this->db->query($sql)) { - $this->fk_c_expensereport_statuts = 99; + $this->fk_statut = 99; $this->fk_user_refuse = $user->id; $this->detail_refuse = $details; $this->date_refuse = $now; @@ -1002,10 +1002,10 @@ class ExpenseReport extends CommonObject $now= dol_now(); $this->date_paiement = $this->db->idate($now); - if ($this->fk_c_expensereport_statuts != 6) + if ($this->fk_statut != 6) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 6, fk_user_paid = ".$user->id.","; + $sql.= " SET fk_statut = 6, fk_user_paid = ".$user->id.","; $sql.= " date_paiement='".$this->db->idate($this->date_paiement)."'"; $sql.= ' WHERE rowid = '.$this->id; @@ -1037,7 +1037,7 @@ class ExpenseReport extends CommonObject if ($this->fk_c_deplacement_statuts != 5) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 5"; + $sql.= " SET fk_statut = 5"; $sql.= ' WHERE rowid = '.$this->id; dol_syslog(get_class($this)."::set_unpaid sql=".$sql, LOG_DEBUG); @@ -1065,10 +1065,10 @@ class ExpenseReport extends CommonObject function set_cancel($user,$detail) { $this->date_cancel = $this->db->idate(gmmktime()); - if ($this->fk_c_expensereport_statuts != 4) + if ($this->fk_statut != 4) { $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_c_expensereport_statuts = 4, fk_user_cancel = ".$user->id; + $sql.= " SET fk_statut = 4, fk_user_cancel = ".$user->id; $sql.= ", date_cancel='".$this->date_cancel."'"; $sql.= " ,detail_cancel='".$this->db->escape($detail)."'"; $sql.= ' WHERE rowid = '.$this->id; @@ -1197,7 +1197,7 @@ class ExpenseReport extends CommonObject function updateline($rowid, $type_fees_id, $projet_id, $c_tva, $comments, $qty, $value_unit, $date, $expensereport_id) { - if ($this->fk_c_expensereport_statuts==0 || $this->fk_c_expensereport_statuts==99) + if ($this->fk_statut==0 || $this->fk_statut==99) { $this->db->begin(); @@ -1693,7 +1693,7 @@ class ExpenseReportLine * @param int $useempty 1=Add empty line * @return string HTML select with sattus */ -function select_expensereport_statut($selected='',$htmlname='fk_c_expensereport_statuts',$useempty=1) +function select_expensereport_statut($selected='',$htmlname='fk_statut',$useempty=1) { global $db; diff --git a/htdocs/expensereport/class/expensereportstats.class.php b/htdocs/expensereport/class/expensereportstats.class.php index 5d71be15738..140e492972e 100644 --- a/htdocs/expensereport/class/expensereportstats.class.php +++ b/htdocs/expensereport/class/expensereportstats.class.php @@ -59,7 +59,7 @@ class ExpenseReportStats extends Stats $this->from = MAIN_DB_PREFIX.$object->table_element; $this->field='total_ht'; - $this->where = " fk_c_expensereport_statuts > 0 and date_valid > '2000-01-01'"; + $this->where = " fk_statut > 0 and date_valid > '2000-01-01'"; //$this->where.= " AND entity = ".$conf->entity; if ($this->socid) { diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index ec9ccba2c0b..62f5cbe89fc 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -142,7 +142,7 @@ $max=10; $langs->load("boxes"); -$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.date_debut as dated, d.date_fin as datef, d.date_create as dm, d.total_ht, d.total_ttc, d.fk_c_expensereport_statuts as fk_status"; +$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.date_debut as dated, d.date_fin as datef, d.date_create as dm, d.total_ht, d.total_ttc, d.fk_statut as fk_status"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d, ".MAIN_DB_PREFIX."user as u"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE u.rowid = d.fk_user_author"; @@ -186,8 +186,8 @@ if ($result) print '
'.$expensereportstatic->getNomUrl(1).''.$userstatic->getNomUrl(1).''.$obj->total_ht.''.$obj->total_ttc.''.price($obj->total_ht).''.price($obj->total_ttc).''.dol_print_date($db->jdate($obj->dm),'day').''; //print $obj->libelle; diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 44f1426fd36..f48a0111a46 100755 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -85,7 +85,7 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -$sql = "SELECT d.rowid, d.ref, d.total_ht, d.total_tva, d.total_ttc, d.fk_c_expensereport_statuts as status,"; +$sql = "SELECT d.rowid, d.ref, d.total_ht, d.total_tva, d.total_ttc, d.fk_statut as status,"; $sql.= " d.date_debut, d.date_fin,"; $sql.= " u.rowid as id_user, u.firstname, u.lastname"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; @@ -157,7 +157,7 @@ if ($month_start > 0) { } } if (!empty($search_user) && $search_user > 0) $sql.= " AND d.fk_user_author = '".$search_user."'"; -if($search_state != '') $sql.= " AND d.fk_c_expensereport_statuts = '$search_state'\n"; +if($search_state != '') $sql.= " AND d.fk_statut = '$search_state'\n"; // RESTRICT RIGHTS if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) diff --git a/htdocs/expensereport/synchro_compta.php b/htdocs/expensereport/synchro_compta.php index ec2703d059a..58fcbaee301 100755 --- a/htdocs/expensereport/synchro_compta.php +++ b/htdocs/expensereport/synchro_compta.php @@ -136,11 +136,11 @@ else: print ' '; print ""; - $sql = "SELECT d.fk_bank_account, d.ref, d.rowid, d.date_valid, d.fk_user_author, d.total_ttc, d.integration_compta, d.fk_c_expensereport_statuts"; + $sql = "SELECT d.fk_bank_account, d.ref, d.rowid, d.date_valid, d.fk_user_author, d.total_ttc, d.integration_compta, d.fk_statut"; $sql.= " ,CONCAT(u.firstname,' ',u.lastname) as declarant_NDF"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON d.fk_user_author = u.rowid"; - $sql.= " WHERE d.fk_c_expensereport_statuts = 6"; + $sql.= " WHERE d.fk_statut = 6"; $sql.= " ORDER BY d.date_valid DESC"; $resql=$db->query($sql); diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 2a36ef78737..aa0b0571bbb 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -157,7 +157,7 @@ CREATE TABLE llx_expensereport ( fk_user_refuse integer DEFAULT NULL, fk_user_cancel integer DEFAULT NULL, fk_user_paid integer DEFAULT NULL, - fk_c_expensereport_statuts integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + fk_statut integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé fk_c_paiement integer DEFAULT NULL, note_public text, note_private text, diff --git a/htdocs/install/mysql/tables/llx_expensereport.sql b/htdocs/install/mysql/tables/llx_expensereport.sql index e60be7251a5..657d8f9e278 100755 --- a/htdocs/install/mysql/tables/llx_expensereport.sql +++ b/htdocs/install/mysql/tables/llx_expensereport.sql @@ -44,7 +44,7 @@ CREATE TABLE llx_expensereport ( fk_user_refuse integer DEFAULT NULL, fk_user_cancel integer DEFAULT NULL, fk_user_paid integer DEFAULT NULL, - fk_c_expensereport_statuts integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + fk_statut integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé fk_c_paiement integer DEFAULT NULL, note_public text, note_private text, From 69dc3cdd6153cd6ccccdc5419c28af79096a9cd5 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 8 Mar 2015 08:21:49 +0100 Subject: [PATCH 32/46] Correct fk_statut & work en list --- htdocs/core/class/commonobject.class.php | 2 +- .../doc/pdf_standard.modules.php | 8 +- .../core/modules/modExpenseReport.class.php | 2 +- htdocs/expensereport/card.php | 10 +- .../class/expensereport.class.php | 2 +- htdocs/expensereport/list.php | 128 ++++++------------ 6 files changed, 57 insertions(+), 95 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 02ccd13b97c..114648fdf14 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2140,7 +2140,7 @@ abstract class CommonObject $fieldstatus="fk_statut"; if ($elementTable == 'user') $fieldstatus="statut"; - if ($elementTable == 'expensereport') $fieldstatus="fk_c_expensereport_statuts"; + if ($elementTable == 'expensereport') $fieldstatus="fk_statut"; if ($elementTable == 'commande_fournisseur_dispatch') $fieldstatus="status"; $sql = "UPDATE ".MAIN_DB_PREFIX.$elementTable; diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index bdb19778c87..d2cdb71e429 100755 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -508,7 +508,7 @@ class pdf_standard extends ModeleExpenseReport */ // Filligrane brouillon - if ($object->fk_c_expensereport_statuts==1 && ! empty($conf->global->EXPENSEREPORT_FREE_TEXT)) + if ($object->fk_statut==1 && ! empty($conf->global->EXPENSEREPORT_FREE_TEXT)) { pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->EXPENSEREPORT_FREE_TEXT); } @@ -640,7 +640,7 @@ class pdf_standard extends ModeleExpenseReport $pdf->MultiCell(96,4,$outputlangs->transnoentities("DateCreation")." : ".dol_print_date($object->date_create,"day",false,$outpulangs),0,'L'); } - if ($object->fk_c_expensereport_statuts==99) + if ($object->fk_statut==99) { if ($object->fk_user_refuse > 0) { @@ -656,7 +656,7 @@ class pdf_standard extends ModeleExpenseReport $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_REFUS")." : ".dol_print_date($object->date_refuse,"day",false,$outpulangs),0,'L'); } } - else if($object->fk_c_expensereport_statuts==4) + else if($object->fk_statut==4) { if ($object->fk_user_cancel > 0) { @@ -686,7 +686,7 @@ class pdf_standard extends ModeleExpenseReport } } - if($object->fk_c_expensereport_statuts==6) + if($object->fk_statut==6) { if ($object->fk_user_paid > 0) { diff --git a/htdocs/core/modules/modExpenseReport.class.php b/htdocs/core/modules/modExpenseReport.class.php index cf106fa4588..53289c512ff 100755 --- a/htdocs/core/modules/modExpenseReport.class.php +++ b/htdocs/core/modules/modExpenseReport.class.php @@ -270,7 +270,7 @@ class modExpenseReport extends DolibarrModules 'titre'=>'ListToApprove', 'mainmenu'=>'hrm', 'leftmenu'=>'expensereport_detaillist_approve', - 'url'=>'/expensereport/list.php?search_state=2', + 'url'=>'/expensereport/list.php?search_status=2', 'langs'=>'trips', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>100, 'enabled'=>'$conf->expensereport->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 02d899def0a..c71705628b6 100755 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1712,17 +1712,17 @@ else print '
'; $form->select_date($date?$date:-1,'date'); print ''; $formproject->select_projects(-1, GETPOST('fk_projet'), 'fk_projet', 0, 0, 1, 1); print ''; select_type_fees_id(GETPOST('fk_c_type_fees'),'fk_c_type_fees',1); print ''; $defaultvat=-1; if (! empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none'; @@ -1747,7 +1747,7 @@ else print ''; print ''; print ''; print '   '; - print " '; - select_expensereport_statut($search_state,'search_state'); + select_expensereport_statut($search_status,'search_status'); print ''; @@ -257,10 +227,6 @@ if ($resql) print ''.($objp->date_debut > 0 ? dol_print_date($objp->date_debut, 'day') : '').''.($objp->date_fin > 0 ? dol_print_date($objp->date_fin, 'day') : '').''.img_object($langs->trans("ShowUser"),"user").' '.dolGetFirstLastname($objp->firstname, $objp->lastname).''.price($objp->total_tva, '', $langs, 0, 'MT', 0, $conf->currency).''.price($objp->total_ht, '', $langs, 0, 'MT', 0, $conf->currency).''.price($objp->total_ttc, '', $langs, 0, 'MT', 0, $conf->currency).''.price($objp->total_ht).''.price($objp->total_tva).''.price($objp->total_ttc).'
'.$langs->trans("Total").''.price($total_total_tva, '', $langs, 0, 'MT', 0, $conf->currency).''.price($total_total_ht, '', $langs, 0, 'MT', 0, $conf->currency).''.price($total_total_ttc, '', $langs, 0, 'MT', 0, $conf->currency).''.$total_total_ht.''.$total_total_tva.''.$total_total_ttc.'
+
info_bits & 2) == 2) { ?> info_bits & 2) == 2) { ?> - id.'#'.$line->id; ?>"> + id.'#line_'.$line->id; ?>"> From f8dfa618595106bdc7b3a0bb0b185ee99735896b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Mon, 9 Mar 2015 16:20:51 +0100 Subject: [PATCH 35/46] FIXED #1901: Inverted supplier order/invoice buttons in project referring objects --- htdocs/projet/element.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index f0e5efa7254..5a499007fae 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -360,11 +360,11 @@ foreach ($listofreferent as $key => $value) { if ($key == 'order_supplier' && ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande->creer) { - print ''.$langs->trans("AddSupplierInvoice").''; + print ''.$langs->trans("AddSupplierOrder").''; } if ($key == 'invoice_supplier' && ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->creer) { - print ''.$langs->trans("AddSupplierOrder").''; + print ''.$langs->trans("AddSupplierInvoice").''; } } } From a065b8a9b4f732015b9a188b93361e160e08dc36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Votruba?= Date: Tue, 10 Mar 2015 09:57:40 +0100 Subject: [PATCH 36/46] travis: PHP 7.0 nightly added --- .travis.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 031226251c1..e3348e97b67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,10 +18,15 @@ services: language: php php: # - "5.2" is not supported because pyrus to install PHP_Codesniffer is not available - - "5.3" - - "5.4" - - "5.5" - - "5.6" + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + +matrix: + allow_failures: + - php: 7.0 env: - DB=mysql From d847f9581e2c1057bd09275b221797b3d4cb8f44 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Mar 2015 11:31:23 +0100 Subject: [PATCH 37/46] Fix generation of RUM number. Show it on card to help debug. --- .../class/bonprelevement.class.php | 25 +++++++++++++++---- .../class/companybankaccount.class.php | 8 +++++- htdocs/societe/rib.php | 16 ++++++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 2c07baba5a0..eb0344d7010 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1300,7 +1300,7 @@ class BonPrelevement extends CommonObject while ($i < $num) { $obj = $this->db->fetch_object($resql); - $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $ListOfFactures, $obj->idfac, $obj->iban, $obj->bic, $obj->datec, $obj->drum); + $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $ListOfFactures, $obj->idfac, $obj->iban, $obj->bic, $this->db->jdate($obj->datec), $obj->drum); $this->total = $this->total + $obj->somme; $i++; } @@ -1502,6 +1502,20 @@ class BonPrelevement extends CommonObject } + /** + * Build RUM number for a customer bank account + * + * @param string $row_code_client Customer code (soc.code_client) + * @param int $row_datec Creation date of bank account (rib.datec) + * @param string $row_drum Id of customer bank account (rib.rowid) + * @return string RUM number + */ + static function buildRumNumber($row_code_client, $row_datec, $row_drum) + { + $pre = ($row_datec > 1359673200) ? 'Rum' : '++R'; + return $pre.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); + } + /** * Write recipient of request (customer) * @@ -1520,7 +1534,7 @@ class BonPrelevement extends CommonObject * @param string $row_iban rib.iban_prefix AS iban, * @param string $row_bic rib.bic AS bic, * @param string $row_datec rib.datec, - * @param string $row_drum rib.rowid AS drum + * @param string $row_drum rib.rowid used to generate rum * @return string Return string with SEPA part DrctDbtTxInf */ function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_facnumber, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum) @@ -1530,10 +1544,11 @@ class BonPrelevement extends CommonObject // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) - $Date_Rum = strtotime($row_datec); + $Rum = $this->buildRumNumber($row_code_client, $row_datec, $row_drum); + + // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - $pre = ($date_Rum > 1359673200) ? 'Rum' : '++R'; - $Rum = $pre.$row_code_client.$row_drum.'-0'.date('U', $Date_Rum); + $XML_DEBITOR =''; $XML_DEBITOR .=' '.$CrLf; $XML_DEBITOR .=' '.$CrLf; diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 37e646d6b88..255ab6a05a6 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -49,6 +49,10 @@ class CompanyBankAccount extends Account var $owner_address; var $default_rib; + var $datec; + var $datem; + + /** * Constructor * @@ -174,7 +178,7 @@ class CompanyBankAccount extends Account { if (empty($id) && empty($socid)) return -1; - $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio, owner_address, default_rib, label"; + $sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio, owner_address, default_rib, label, datec, tms as datem"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_rib"; if ($id) $sql.= " WHERE rowid = ".$id; if ($socid) $sql.= " WHERE fk_soc = ".$socid." AND default_rib = 1"; @@ -200,6 +204,8 @@ class CompanyBankAccount extends Account $this->owner_address = $obj->owner_address; $this->label = $obj->label; $this->default_rib = $obj->default_rib; + $this->datec = $this->db->jdate($obj->datec); + $this->datem = $this->db->jdate($obj->datem); } $this->db->free($resql); diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index ab14d757f6f..5af9d2a7df2 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -29,6 +29,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; $langs->load("companies"); $langs->load("commercial"); @@ -191,6 +192,7 @@ if ($action == 'confirm_delete' && $_GET['confirm'] == 'yes') */ $form = new Form($db); +$prelevement = new BonPrelevement($db); llxHeader(); @@ -320,11 +322,11 @@ if ($socid && $action != 'edit' && $action != "create") print "
"; - + /* * List of bank accounts */ - + print_titre($langs->trans("AllRIB")); $rib_list = $soc->get_all_rib(); @@ -339,6 +341,10 @@ if ($socid && $action != 'edit' && $action != "create") print_liste_field_titre($langs->trans("RIB")); print_liste_field_titre($langs->trans("IBAN")); print_liste_field_titre($langs->trans("BIC")); + if (! empty($conf->prelevement->enabled)) + { + print '
RUM
'.$rib->iban.''.$rib->bic.''.$prelevement->buildRumNumber($soc->code_client, $rib->datec, $rib->id).''; if (!$rib->default_rib) { From 978dc8170dfff1a03138e7dd476a4a2c06c7a490 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Tue, 10 Mar 2015 14:56:58 +0100 Subject: [PATCH 38/46] Fix : display proposal date on proposal list --- htdocs/comm/propal/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index ba0a49f2772..21d774e36bb 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -388,7 +388,7 @@ if ($result) // Date proposal print ''; - print dol_print_date($db->jdate($obj->dp), 'day'); + print dol_print_date($db->jdate($objp->dp), 'day'); print "
' . $langs->trans('AmountHT') . '' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . $langs->trans('AmountVAT') . '' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . $langs->trans('AmountTTC') . '' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '
' . $langs->trans('Status') . '' . $object->getLibStatut(4) . '
' . img_edit().'
'; - print ''; + print ''; // Convert date into timestamp format if (in_array($extrafields->attribute_type[$key], array('date','datetime'))) { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 6101aa7e17d..41d06bebf43 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1947,28 +1947,28 @@ elseif (! empty($object->id)) // Ligne de 3 colonnes print ''.$langs->trans("AmountHT").''; - print ''.price($object->total_ht).''; - print ''.$langs->trans("Currency".$conf->currency).''; + print ''.price($object->total_ht,'',$langs,1,-1,-1,$conf->currency).''; + print ''; - print ''.$langs->trans("AmountVAT").''.price($object->total_tva).''; - print ''.$langs->trans("Currency".$conf->currency).''; + print ''.$langs->trans("AmountVAT").''.price($object->total_tva,'',$langs,1,-1,-1,$conf->currency).''; + print ''; // Amount Local Taxes if ($mysoc->localtax1_assuj=="1" || $object->total_localtax1 != 0) //Localtax1 { print ''.$langs->transcountry("AmountLT1",$mysoc->country_code).''; - print ''.price($object->total_localtax1).''; - print ''.$langs->trans("Currency".$conf->currency).''; + print ''.price($object->total_localtax1,'',$langs,1,-1,-1,$conf->currency).''; + print ''; } if ($mysoc->localtax2_assuj=="1" || $object->total_localtax2 != 0) //Localtax2 { print ''.$langs->transcountry("AmountLT2",$mysoc->country_code).''; - print ''.price($object->total_localtax2).''; - print ''.$langs->trans("Currency".$conf->currency).''; + print ''.price($object->total_localtax2,'',$langs,1,-1,-1,$conf->currency).''; + print ''; } - print ''.$langs->trans("AmountTTC").''.price($object->total_ttc).''; - print ''.$langs->trans("Currency".$conf->currency).''; + print ''.$langs->trans("AmountTTC").''.price($object->total_ttc,'',$langs,1,-1,-1,$conf->currency).''; + print ''; print "
"; @@ -2610,7 +2610,7 @@ elseif (! empty($object->id)) print ''.$langs->trans("ReOpen").''; } } - + // Create bill if (! empty($conf->fournisseur->enabled) && $object->statut >= 2) // 2 means accepted { From c27125745282002d91b08f82b25229d37d5db17b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 10 Mar 2015 22:27:16 +0100 Subject: [PATCH 44/46] Prepare extrafield for option by default into lists --- htdocs/core/class/extrafields.class.php | 46 +++++++++++++------ .../install/mysql/migration/3.7.0-3.8.0.sql | 1 + .../install/mysql/tables/llx_extrafields.sql | 3 +- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 5a79c5ccf97..24d8c40f5b3 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -54,6 +54,8 @@ class ExtraFields var $attribute_alwayseditable; // Array to store permission to check var $attribute_perms; + // Array to store permission to check + var $attribute_list; var $error; var $errno; @@ -93,6 +95,7 @@ class ExtraFields $this->attribute_unique = array(); $this->attribute_required = array(); $this->attribute_perms = array(); + $this->attribute_list = array(); } /** @@ -110,9 +113,10 @@ class ExtraFields * @param array $param Params for field * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='') + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='', $list=0) { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -122,13 +126,13 @@ class ExtraFields // Create field into database except for separator type which is not stored in database if ($type != 'separate') { - $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param); + $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value, $param, $perms, $list); } $err1=$this->errno; if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable, $perms); + $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable, $perms, $list); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -156,10 +160,11 @@ class ExtraFields * @param int $required Is field required or not * @param string $default_value Default value for field * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option')) - * + * @param string $perms Permission + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='') + private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='', $perms='', $list=0) { if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -230,9 +235,10 @@ class ExtraFields * @param array||string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='') + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=0) { global $conf; @@ -240,6 +246,7 @@ class ExtraFields // Clean parameters if (empty($pos)) $pos=0; + if (empty($list)) $list=0; if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname) && ! is_numeric($attrname)) { @@ -256,7 +263,7 @@ class ExtraFields $params=''; } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable, perms)"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable, perms, list)"; $sql.= " VALUES('".$attrname."',"; $sql.= " '".$this->db->escape($label)."',"; $sql.= " '".$type."',"; @@ -268,7 +275,8 @@ class ExtraFields $sql.= " '".$required."',"; $sql.= " '".$params."',"; $sql.= " '".$alwayseditable."',"; - $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null"); + $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").","; + $sql.= " ".$list; $sql.=')'; dol_syslog(get_class($this)."::create_label", LOG_DEBUG); @@ -370,9 +378,10 @@ class ExtraFields * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int >0 if OK, <=0 if KO */ - function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='') + function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='',$list='') { if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -409,7 +418,7 @@ class ExtraFields { if ($label) { - $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms); + $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list); } if ($result > 0) { @@ -459,14 +468,17 @@ class ExtraFields * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check + * @param int $list Into list view by default * @return int <=0 if KO, >0 if OK */ - private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='') + private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0) { global $conf; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list); + // Clean parameters if ($elementtype == 'thirdparty') $elementtype='societe'; + if (empty($list)) $list=0; if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { @@ -496,7 +508,8 @@ class ExtraFields $sql.= " perms,"; $sql.= " pos,"; $sql.= " alwayseditable,"; - $sql.= " param"; + $sql.= " param,"; + $sql.= " list"; $sql.= ") VALUES ("; $sql.= "'".$attrname."',"; $sql.= " ".$conf->entity.","; @@ -510,6 +523,7 @@ class ExtraFields $sql.= " '".$pos."',"; $sql.= " '".$alwayseditable."',"; $sql.= " '".$param."'"; + $sql.= " ".$list; $sql.= ")"; dol_syslog(get_class($this)."::update_label", LOG_DEBUG); $resql2=$this->db->query($sql); @@ -552,7 +566,7 @@ class ExtraFields // For avoid conflicts with external modules if (!$forceload && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label; - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,list"; $sql.= " FROM ".MAIN_DB_PREFIX."extrafields"; $sql.= " WHERE entity IN (0,".$conf->entity.")"; if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'"; @@ -582,6 +596,7 @@ class ExtraFields $this->attribute_pos[$tab->name]=$tab->pos; $this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable; $this->attribute_perms[$tab->name]=$tab->perms; + $this->attribute_perms[$tab->name]=$tab->list; } } } @@ -615,6 +630,7 @@ class ExtraFields $required=$this->attribute_required[$key]; $param=$this->attribute_param[$key]; $perms=$this->attribute_perms[$key]; + $list=$this->attribute_list[$key]; if ($type == 'date') { @@ -1054,6 +1070,8 @@ class ExtraFields $required=$this->attribute_required[$key]; $params=$this->attribute_param[$key]; $perms=$this->attribute_perms[$key]; + $list=$this->attribute_list[$key]; + if ($type == 'date') { $showsize=10; diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 03736b088fc..6d767e20d45 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -20,6 +20,7 @@ ALTER TABLE llx_extrafields ADD COLUMN perms varchar(255) after fieldrequired; +ALTER TABLE llx_extrafields ADD COLUMN list integer DEFAULT 0 after perms; ALTER TABLE llx_payment_salary ADD COLUMN salary real after datev; diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index 11271125508..21610d07c0e 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -32,5 +32,6 @@ create table llx_extrafields perms varchar(255), pos integer DEFAULT 0, alwayseditable integer DEFAULT 0, - param text + param text, + list integer DEFAULT 0 )ENGINE=innodb; From ec322e2e2974d52f767d4132bb1878e6685ded55 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 11 Mar 2015 03:03:17 +0100 Subject: [PATCH 45/46] Revert was not complete --- htdocs/admin/system/database-tables.php | 5 +- htdocs/core/db/sqlite.class.php | 84 +++---------------------- htdocs/core/db/sqlite3.class.php | 3 +- htdocs/install/etape2.php | 3 +- htdocs/install/fileconf.php | 3 +- 5 files changed, 17 insertions(+), 81 deletions(-) diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index e75cec3f513..39b3dd4cad5 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -66,7 +66,8 @@ else if ($conf->db->type == 'mssql') //$sqls[0] = ""; //$base=3; } -else if ($conf->db->type == 'sqlite3') { +else if ($conf->db->type == 'sqlite' || $conf->db->type == 'sqlite3') +{ //$sql = "SELECT name, type FROM sqlite_master"; $base = 4; } @@ -176,7 +177,7 @@ else if ($base == 4) { - // Sqlite3 + // Sqlite by PDO or by Sqlite3 print ''; print ''; print ''; diff --git a/htdocs/core/db/sqlite.class.php b/htdocs/core/db/sqlite.class.php index 786bf435fcf..88efde86394 100644 --- a/htdocs/core/db/sqlite.class.php +++ b/htdocs/core/db/sqlite.class.php @@ -40,12 +40,6 @@ class DoliDBSqlite extends DoliDB //! Resultset of last query private $_results; - /** - * Indique que les fonctions personnalisées sont définies - * @var boolean - */ - private static $customFunctionsDefined = false; - /** * Constructor. * This create an opened connexion to a database server and eventually to a database @@ -56,6 +50,7 @@ class DoliDBSqlite extends DoliDB * @param string $pass Mot de passe * @param string $name Nom de la database * @param int $port Port of database server + * @return int 1 if OK, 0 if not */ function __construct($type, $host, $user, $pass, $name='', $port=0) { @@ -159,7 +154,7 @@ class DoliDBSqlite extends DoliDB // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..." if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) { - $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line); + $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 SERIAL PRIMARY KEY',$line); //$line = "-- ".$line." replaced by --\n".$newline; $line=$newline; } @@ -248,18 +243,11 @@ class DoliDBSqlite extends DoliDB $line = "-- ".$line." replaced by --\n"; $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")"; } - if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$line, $reg)) { - // Pour l'instant les contraintes ne sont pas créées - dol_syslog(get_class().'::query line emptied'); - $line = 'SELECT 0;'; - - } - - //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) { - //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line); - //} } + // To have postgresql case sensitive + $line=str_replace(' LIKE \'',' ILIKE \'',$line); + // Delete using criteria on other table must not declare twice the deleted table // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg)) @@ -400,53 +388,7 @@ class DoliDBSqlite extends DoliDB $this->error = 0; // Convert MySQL syntax to SQLite syntax - if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$query, $reg)) { - // Ajout d'une clef étrangère à la table - // procédure de remplacement de la table pour ajouter la contrainte - // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid) - // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)) - $foreignFields = $reg[5]; - $foreignTable = $reg[4]; - $localfields = $reg[3]; - $constraintname=trim($reg[2]); - $tablename=trim($reg[1]); - - $res = $this->db->query("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'"); - $descTable = $res->fetchColumn(); - $res->closeCursor(); - - // 1- Renommer la table avec un nom temporaire - $res = $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename); - $res->closeCursor(); - - // 2- Recréer la table avec la contrainte ajoutée - - // on bricole la requete pour ajouter la contrainte - $descTable = substr($descTable, 0, strlen($descTable) - 1); - $descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")"; - - // fermeture de l'instruction - $descTable .= ')'; - - // Création proprement dite de la table - $res = $this->query($descTable); - $res->closeCursor(); - - // 3- Transférer les données - $res = $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename); - $res->closeCursor(); - - - // 4- Supprimer la table temporaire - $res = $this->query('DROP TABLE tmp_' . $tablename); - $res->closeCursor(); - - // dummy statement - $query="SELECT 0"; - - } else { - $query=$this->convertSQLFromMysql($query,$type); - } + $query=$this->convertSQLFromMysql($query,$type); //print "After convertSQLFromMysql:\n".$query."
\n"; dol_syslog('sql='.$query, LOG_DEBUG); @@ -546,11 +488,7 @@ class DoliDBSqlite extends DoliDB { // If resultset not provided, we take the last used by connexion if (! is_object($resultset)) { $resultset=$this->_results; } - if (preg_match("/^SELECT/i", $resultset->queryString)) { - $res = $this->db->query("SELECT count(*) FROM (" . $resultset->queryString . ") q"); - return $res->fetchColumn(); - } - return $resultset->rowCount(); + return $resultset->rowCount(); } /** @@ -592,12 +530,7 @@ class DoliDBSqlite extends DoliDB */ function escape($stringtoencode) { - $ret = $this->db->quote($stringtoencode); - $l = strlen($ret); - if ($l >= 2) { - return substr($ret, 1, $l -2); - } - return ''; + return $this->db->quote($stringtoencode); } /** @@ -1203,6 +1136,5 @@ class DoliDBSqlite extends DoliDB return $result; } - } diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index c52578fa579..ce3762202e4 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -354,7 +354,8 @@ class DoliDBSqlite3 extends DoliDB */ function getVersion() { - return $this->db->version()['versionString']; + $tmp=$this->db->version(); + return $tmp['versionString']; } /** diff --git a/htdocs/install/etape2.php b/htdocs/install/etape2.php index 612c3c64148..8c0e3f8ab5c 100644 --- a/htdocs/install/etape2.php +++ b/htdocs/install/etape2.php @@ -51,7 +51,8 @@ if ($dolibarr_main_db_type == "mysql") $choix=1; if ($dolibarr_main_db_type == "mysqli") $choix=1; if ($dolibarr_main_db_type == "pgsql") $choix=2; if ($dolibarr_main_db_type == "mssql") $choix=3; -if ($dolibarr_main_db_type == "sqlite3") $choix=4; +if ($dolibarr_main_db_type == "sqlite") $choix=4; +if ($dolibarr_main_db_type == "sqlite3") $choix=5; //if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into etape2.php page'); diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index ec3e208374b..5dce328d04c 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -306,7 +306,7 @@ if (! empty($force_install_message)) $class='DoliDB'.ucfirst($type); include_once $dir."/".$file; - if ($type == 'sqlite') continue; // We hide sqlite because support can't be complete unti sqlit does not manage foreign key creation after table creation + if ($type == 'sqlite') continue; // We hide sqlite because support can't be complete until sqlite does not manage foreign key creation after table creation // Version min of database $versionbasemin=explode('.',$class::VERSIONMIN); @@ -320,6 +320,7 @@ if (! empty($force_install_message)) if ($type=='mysqli') { $testfunction='mysqli_connect'; $testclass=''; } if ($type=='pgsql') { $testfunction='pg_connect'; $testclass=''; } if ($type=='mssql') { $testfunction='mssql_connect'; $testclass=''; } + if ($type=='sqlite') { $testfunction=''; $testclass='PDO'; } if ($type=='sqlite3') { $testfunction=''; $testclass='SQLite3'; } $option.='
'.$langs->trans("TableName").'