From 3396dfc7f60f31dc3660d7238638be043509354f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Dec 2016 21:58:52 +0100 Subject: [PATCH 01/75] NEW Index upload files into database. --- dev/skeletons/build_class_from_table.php | 4 +- dev/skeletons/skeleton_class.class.php | 8 +- htdocs/core/lib/files.lib.php | 55 +- htdocs/ecm/class/ecmdirectory.class.php | 3 +- htdocs/ecm/class/ecmfiles.class.php | 764 ++++++++++++++++++ .../install/mysql/migration/5.0.0-6.0.0.sql | 29 + htdocs/install/mysql/tables/llx_ecm_files.sql | 3 +- 7 files changed, 854 insertions(+), 12 deletions(-) create mode 100644 htdocs/ecm/class/ecmfiles.class.php create mode 100644 htdocs/install/mysql/migration/5.0.0-6.0.0.sql diff --git a/dev/skeletons/build_class_from_table.php b/dev/skeletons/build_class_from_table.php index 62ad1188759..d9e30b23501 100755 --- a/dev/skeletons/build_class_from_table.php +++ b/dev/skeletons/build_class_from_table.php @@ -303,7 +303,7 @@ foreach($property as $key => $prop) $varprop.="\$this->db->escape(\$this->".$prop['field'].")"; $varprop.=".\"'\")"; } - elseif ($prop['field']=='fk_user_mod' || $prop['field']=='fk_user_author') + elseif ($prop['field']=='fk_user_mod' || $prop['field']=='fk_user_m' || $prop['field']=='fk_user_author') { $varprop.="'.\$user->id"; } @@ -367,7 +367,7 @@ foreach($property as $key => $prop) $varprop.=')."\'" : \'null\')'; } - elseif ($prop['field']=='fk_user_mod') { + elseif ($prop['field']=='fk_user_mod' || $prop['field']=='fk_user_m') { $varprop.="'.\$user->id"; } else diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php index 4f725fa2dbe..1c9b8cb52bf 100644 --- a/dev/skeletons/skeleton_class.class.php +++ b/dev/skeletons/skeleton_class.class.php @@ -188,11 +188,13 @@ class Skeleton_Class extends CommonObject // Retrieve all extrafields for invoice // fetch optionals attributes and labels + /* require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields=new ExtraFields($this->db); $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); $this->fetch_optionals($this->id,$extralabels); - + */ + // $this->fetch_lines(); $this->db->free($resql); @@ -254,7 +256,7 @@ class Skeleton_Class extends CommonObject $sql .= ' ' . $this->db->plimit($limit + 1, $offset); } - $this->lines = array(); + //$this->lines = array(); $resql = $this->db->query($sql); if ($resql) { @@ -267,7 +269,7 @@ class Skeleton_Class extends CommonObject $line->prop1 = $obj->field1; $line->prop2 = $obj->field2; - $this->lines[$line->id] = $line; + //$this->lines[$line->id] = $line; //... } $this->db->free($resql); diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index f67f1a0daf4..68e3866f92e 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -743,7 +743,30 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n { if ($nophperrors) $ok=@unlink($filename); else $ok=unlink($filename); - if ($ok) dol_syslog("Removed file ".$filename, LOG_DEBUG); + if ($ok) + { + dol_syslog("Removed file ".$filename, LOG_DEBUG); + + // Delete entry into ecm database + $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); + if (! preg_match('/\/temp\//', $rel_filetodelete)) // If not a tmp file + { + $rel_filetodelete = preg_replace('/^\//', '', $rel_filetodelete); + + dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); + include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', $rel_filetodelete); + if ($result >= 0) + { + $result = $ecmfile->delete($user); + } + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + } else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); // TODO Failure to remove can be because file was already removed or because of permission // If error because of not exists, we must can return true but we should return false if this is a permission problem @@ -1000,7 +1023,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') * @param int $donotupdatesession 1=Do no edit _SESSION variable * @param string $varfiles _FILES var name * @param string $savingdocmask Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__' - * @param string $link Link to add + * @param string $link Link to add (to add a link instead of a file) * @param string $trackid Track id (used to prefix name of session vars to avoid conflict) * @return void */ @@ -1043,7 +1066,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $destpath = $info['dirname'].'/'.$info['filename'].'.'.strtolower($info['extension']); $info = pathinfo($destfile); $destfile = $info['filename'].'.'.strtolower($info['extension']); - + $resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destpath, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles); if (is_numeric($resupload) && $resupload > 0) { @@ -1057,6 +1080,30 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $formmail->trackid = $trackid; $formmail->add_attached_files($destpath, $destfile, $TFile['type'][$i]); } + else // Update table of files + { + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); + if (! preg_match('/\/temp\//', $rel_dir)) // If not a tmp file + { + $rel_dir = preg_replace('/\/$/', '', $rel_dir); + $rel_dir = preg_replace('/^\//', '', $rel_dir); + + include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $ecmfile->label = md5_file($destpath); + $ecmfile->filename = $destfile; + $ecmfile->filepath = $rel_dir; + $ecmfile->fullpath_orig = $TFile['name'][$i]; + $ecmfile->gen_or_uploaded = 'uploaded'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $result = $ecmfile->create($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + } if (image_format_supported($destpath) == 1) { // Create thumbs @@ -1145,7 +1192,7 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= { $pathtodelete=$listofpaths[$keytodelete]; $filetodelete=$listofnames[$keytodelete]; - if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete,1); + if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete,1); // The delete of ecm database is inside the function dol_delete_file else $result=0; if ($result >= 0) { diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index c16cfe62e7c..1644b58075e 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -23,8 +23,7 @@ */ /** - * \class EcmDirectory - * \brief Class to manage ECM directories + * Class to manage ECM directories */ class EcmDirectory // extends CommonObject { diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php new file mode 100644 index 00000000000..0133bff2580 --- /dev/null +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -0,0 +1,764 @@ + + * Copyright (C) 2014-2016 Juanjo Menent + * Copyright (C) 2015 Florian Henry + * Copyright (C) 2015 Raphaƫl Doursenaud + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 ecm/ecmfiles.class.php + * \ingroup ecm + * \brief Class to manage ECM Files (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class to manage ECM files + */ +class EcmFiles //extends CommonObject +{ + /** + * @var string Id to identify managed objects + */ + public $element = 'ecmfiles'; + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'ecm_files'; + + /** + */ + public $label; + public $entity; + public $filename; + public $filepath; + public $fullpath_orig; + public $description; + public $keywords; + public $cover; + public $position; + public $gen_or_uploaded; + public $extraparams; + public $date_c = ''; + public $date_m = ''; + public $fk_user_c; + public $fk_user_m; + public $acl; + + /** + */ + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + + // Clean parameters + + if (isset($this->label)) { + $this->label = trim($this->label); + } + if (isset($this->entity)) { + $this->entity = trim($this->entity); + } + if (isset($this->filename)) { + $this->filename = trim($this->filename); + } + if (isset($this->filepath)) { + $this->filepath = trim($this->filepath); + } + if (isset($this->fullpath_orig)) { + $this->fullpath_orig = trim($this->fullpath_orig); + } + if (isset($this->description)) { + $this->description = trim($this->description); + } + if (isset($this->keywords)) { + $this->keywords = trim($this->keywords); + } + if (isset($this->cover)) { + $this->cover = trim($this->cover); + } + if (isset($this->gen_or_uploaded)) { + $this->gen_or_uploaded = trim($this->gen_or_uploaded); + } + if (isset($this->extraparams)) { + $this->extraparams = trim($this->extraparams); + } + if (isset($this->fk_user_c)) { + $this->fk_user_c = trim($this->fk_user_c); + } + if (isset($this->fk_user_m)) { + $this->fk_user_m = trim($this->fk_user_m); + } + if (isset($this->acl)) { + $this->acl = trim($this->acl); + } + if (empty($this->date_c)) $this->date_c = dol_now(); + + + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; + $sql.= 'label,'; + $sql.= 'entity,'; + $sql.= 'filename,'; + $sql.= 'filepath,'; + $sql.= 'fullpath_orig,'; + $sql.= 'description,'; + $sql.= 'keywords,'; + $sql.= 'cover,'; + $sql.= 'position,'; + $sql.= 'gen_or_uploaded,'; + $sql.= 'extraparams,'; + $sql.= 'date_c,'; + $sql.= 'date_m,'; + $sql.= 'fk_user_c,'; + $sql.= 'fk_user_m,'; + $sql.= 'acl'; + $sql .= ') VALUES ('; + $sql .= ' '.(! isset($this->label)?'NULL':"'".$this->db->escape($this->label)."'").','; + $sql .= ' '.(! isset($this->entity)?$conf->entity:$this->entity).','; + $sql .= ' '.(! isset($this->filename)?'NULL':"'".$this->db->escape($this->filename)."'").','; + $sql .= ' '.(! isset($this->filepath)?'NULL':"'".$this->db->escape($this->filepath)."'").','; + $sql .= ' '.(! isset($this->fullpath_orig)?'NULL':"'".$this->db->escape($this->fullpath_orig)."'").','; + $sql .= ' '.(! isset($this->description)?'NULL':"'".$this->db->escape($this->description)."'").','; + $sql .= ' '.(! isset($this->keywords)?'NULL':"'".$this->db->escape($this->keywords)."'").','; + $sql .= ' '.(! isset($this->cover)?'NULL':"'".$this->db->escape($this->cover)."'").','; + $sql .= ' '.(! isset($this->position)?'0':$this->db->escape($this->position)).','; + $sql .= ' '.(! isset($this->gen_or_uploaded)?'NULL':"'".$this->db->escape($this->gen_or_uploaded)."'").','; + $sql .= ' '.(! isset($this->extraparams)?'NULL':"'".$this->db->escape($this->extraparams)."'").','; + $sql .= ' '."'".$this->db->idate($this->date_c)."'".','; + $sql .= ' '.(! isset($this->date_m) || dol_strlen($this->date_m)==0?'NULL':"'".$this->db->idate($this->date_m)."'").','; + $sql .= ' '.(! isset($this->fk_user_c)?$user->id:$this->fk_user_c).','; + $sql .= ' '.(! isset($this->fk_user_m)?'NULL':$this->fk_user_m).','; + $sql .= ' '.(! isset($this->acl)?'NULL':"'".$this->db->escape($this->acl)."'"); + $sql .= ')'; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + if (!$error) { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); + + if (!$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action to call a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_CREATE',$user); + //if ($result < 0) $error++; + //// End call triggers + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return $this->id; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref = md5 = label + * @param string $fullpath Full path of file (relative path to document directory) + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null, $fullpath = '') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + $sql .= " t.label,"; + $sql .= " t.entity,"; + $sql .= " t.filename,"; + $sql .= " t.filepath,"; + $sql .= " t.fullpath_orig,"; + $sql .= " t.description,"; + $sql .= " t.keywords,"; + $sql .= " t.cover,"; + $sql .= " t.position,"; + $sql .= " t.gen_or_uploaded,"; + $sql .= " t.extraparams,"; + $sql .= " t.date_c,"; + $sql .= " t.date_m,"; + $sql .= " t.fk_user_c,"; + $sql .= " t.fk_user_m,"; + $sql .= " t.acl"; + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t'; + $sql.= ' WHERE 1 = 1'; + if (! empty($conf->multicompany->enabled)) { + $sql .= " AND entity IN (" . getEntity("ecmfiles", 1) . ")"; + } + if ($fullpath) { + $sql .= " AND t.filepath = '" . $this->db->escape(dirname($fullpath)) . "' AND t.filename = '".$this->db->escape(basename($fullpath))."'"; + } + elseif (null !== $ref) { + $sql .= " AND t.label = '".$this->db->escape($ref)."'"; + } else { + $sql .= ' AND t.rowid = ' . $id; + } + + $resql = $this->db->query($sql); + if ($resql) { + $numrows = $this->db->num_rows($resql); + if ($numrows) { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + + $this->label = $obj->label; + $this->entity = $obj->entity; + $this->filename = $obj->filename; + $this->filepath = $obj->filepath; + $this->fullpath_orig = $obj->fullpath_orig; + $this->description = $obj->description; + $this->keywords = $obj->keywords; + $this->cover = $obj->cover; + $this->position = $obj->position; + $this->gen_or_uploaded = $obj->gen_or_uploaded; + $this->extraparams = $obj->extraparams; + $this->date_c = $this->db->jdate($obj->date_c); + $this->date_m = $this->db->jdate($obj->date_m); + $this->fk_user_c = $obj->fk_user_c; + $this->fk_user_m = $obj->fk_user_m; + $this->acl = $obj->acl; + } + + // Retrieve all extrafields for invoice + // fetch optionals attributes and labels + /* + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); + */ + // $this->fetch_lines(); + + $this->db->free($resql); + + if ($numrows) { + return 1; + } else { + return 0; + } + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Load object in memory from the database + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit offset limit + * @param int $offset offset limit + * @param array $filter filter array + * @param string $filtermode filter mode (AND or OR) + * + * @return int <0 if KO, >0 if OK + */ + public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = 'SELECT'; + $sql .= ' t.rowid,'; + $sql .= " t.label,"; + $sql .= " t.entity,"; + $sql .= " t.filename,"; + $sql .= " t.filepath,"; + $sql .= " t.fullpath_orig,"; + $sql .= " t.description,"; + $sql .= " t.keywords,"; + $sql .= " t.cover,"; + $sql .= " t.position,"; + $sql .= " t.gen_or_uploaded,"; + $sql .= " t.extraparams,"; + $sql .= " t.date_c,"; + $sql .= " t.date_m,"; + $sql .= " t.fk_user_c,"; + $sql .= " t.fk_user_m,"; + $sql .= " t.acl"; + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; + + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\''; + } + } + $sql.= ' WHERE 1 = 1'; + if (! empty($conf->multicompany->enabled)) { + $sql .= " AND entity IN (" . getEntity("ecmfiles", 1) . ")"; + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere); + } + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield,$sortorder); + } + if (!empty($limit)) { + $sql .= ' ' . $this->db->plimit($limit + 1, $offset); + } + + $this->lines = array(); + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + + while ($obj = $this->db->fetch_object($resql)) { + $line = new EcmfilesLine(); + + $line->id = $obj->rowid; + + $line->label = $obj->label; + $line->entity = $obj->entity; + $line->filename = $obj->filename; + $line->filepath = $obj->filepath; + $line->fullpath_orig = $obj->fullpath_orig; + $line->description = $obj->description; + $line->keywords = $obj->keywords; + $line->cover = $obj->cover; + $line->position = $obj->position; + $line->gen_or_uploaded = $obj->gen_or_uploaded; + $line->extraparams = $obj->extraparams; + $line->date_c = $this->db->jdate($obj->date_c); + $line->date_m = $this->db->jdate($obj->date_m); + $line->fk_user_c = $obj->fk_user_c; + $line->fk_user_m = $obj->fk_user_m; + $line->acl = $obj->acl; + } + $this->db->free($resql); + + return $num; + } else { + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + + return - 1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + // Clean parameters + + if (isset($this->label)) { + $this->label = trim($this->label); + } + if (isset($this->entity)) { + $this->entity = trim($this->entity); + } + if (isset($this->filename)) { + $this->filename = trim($this->filename); + } + if (isset($this->filepath)) { + $this->filepath = trim($this->filepath); + } + if (isset($this->fullpath_orig)) { + $this->fullpath_orig = trim($this->fullpath_orig); + } + if (isset($this->description)) { + $this->description = trim($this->description); + } + if (isset($this->keywords)) { + $this->keywords = trim($this->keywords); + } + if (isset($this->cover)) { + $this->cover = trim($this->cover); + } + if (isset($this->gen_or_uploaded)) { + $this->gen_or_uploaded = trim($this->gen_or_uploaded); + } + if (isset($this->extraparams)) { + $this->extraparams = trim($this->extraparams); + } + if (isset($this->fk_user_c)) { + $this->fk_user_c = trim($this->fk_user_c); + } + if (isset($this->fk_user_m)) { + $this->fk_user_m = trim($this->fk_user_m); + } + if (isset($this->acl)) { + $this->acl = trim($this->acl); + } + + + + // Check parameters + // Put here code to add a control on parameters values + + // Update request + $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; + $sql .= ' label = '.(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").','; + $sql .= ' entity = '.(isset($this->entity)?$this->entity:$conf->entity).','; + $sql .= ' filename = '.(isset($this->filename)?"'".$this->db->escape($this->filename)."'":"null").','; + $sql .= ' filepath = '.(isset($this->filepath)?"'".$this->db->escape($this->filepath)."'":"null").','; + $sql .= ' fullpath_orig = '.(isset($this->fullpath_orig)?"'".$this->db->escape($this->fullpath_orig)."'":"null").','; + $sql .= ' description = '.(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").','; + $sql .= ' keywords = '.(isset($this->keywords)?"'".$this->db->escape($this->keywords)."'":"null").','; + $sql .= ' cover = '.(isset($this->cover)?"'".$this->db->escape($this->cover)."'":"null").','; + $sql .= ' position = '.(isset($this->position)?$this->db->escape($this->position):"0").','; + $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded)?"'".$this->db->escape($this->gen_or_uploaded)."'":"null").','; + $sql .= ' extraparams = '.(isset($this->extraparams)?"'".$this->db->escape($this->extraparams)."'":"null").','; + $sql .= ' date_c = '.(! isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').','; + $sql .= ' date_m = '.(! isset($this->date_m) || dol_strlen($this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; + $sql .= ' fk_user_c = '.(isset($this->fk_user_c)?$this->fk_user_c:"null").','; + $sql .= ' fk_user_m = '.(isset($this->fk_user_m)?$this->fk_user_m:"null").','; + $sql .= ' acl = '.(isset($this->acl)?"'".$this->db->escape($this->acl)."'":"null"); + $sql .= ' WHERE rowid=' . $this->id; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + if (!$error && !$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_MODIFY',$user); + //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + //// End call triggers + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + + $this->db->begin(); + + if (!$error) { + if (!$notrigger) { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //$result=$this->call_trigger('MYOBJECT_DELETE',$user); + //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + //// End call triggers + } + } + + // If you need to delete child tables to, you can insert them here + + if (!$error) { + $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element; + $sql .= ' WHERE rowid=' . $this->id; + + $resql = $this->db->query($sql); + if (!$resql) { + $error ++; + $this->errors[] = 'Error ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return - 1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Load an object from its id and create a new one in database + * + * @param int $fromid Id of object to clone + * + * @return int New id of clone + */ + public function createFromClone($fromid) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + global $user; + $error = 0; + $object = new Ecmfiles($this->db); + + $this->db->begin(); + + // Load source object + $object->fetch($fromid); + // Reset object + $object->id = 0; + + // Clear fields + // ... + + // Create clone + $result = $object->create($user); + + // Other options + if ($result < 0) { + $error ++; + $this->errors = $object->errors; + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + } + + // End + if (!$error) { + $this->db->commit(); + + return $object->id; + } else { + $this->db->rollback(); + + return - 1; + } + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to + * @param int $notooltip 1=Disable tooltip + * @param int $maxlen Max length of visible user name + * @param string $morecss Add more css on link + * @return string String with URL + */ + function getNomUrl($withpicto=0, $option='', $notooltip=0, $maxlen=24, $morecss='') + { + global $db, $conf, $langs; + global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; + + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + + $result = ''; + $companylink = ''; + + $label = '' . $langs->trans("MyModule") . ''; + $label.= '
'; + $label.= '' . $langs->trans('Ref') . ': ' . $this->ref; + + $url = DOL_URL_ROOT.'/ecm/'.$this->table_name.'_card.php?id='.$this->id; + + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowProject"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + else $linkclose = ($morecss?' class="'.$morecss.'"':''); + + $linkstart = ''; + $linkend=''; + + if ($withpicto) + { + $result.=($linkstart.img_object(($notooltip?'':$label), 'label', ($notooltip?'':'class="classfortooltip"')).$linkend); + if ($withpicto != 2) $result.=' '; + } + $result.= $linkstart . $this->ref . $linkend; + return $result; + } + + /** + * Retourne le libelle du status d'un user (actif, inactif) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto + * @return string Label of status + */ + static function LibStatut($status,$mode=0) + { + global $langs; + + if ($mode == 0) + { + $prefix=''; + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 1) + { + if ($status == 1) return $langs->trans('Enabled'); + if ($status == 0) return $langs->trans('Disabled'); + } + if ($mode == 2) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); + } + if ($mode == 3) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5'); + } + if ($mode == 4) + { + if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled'); + if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled'); + } + if ($mode == 5) + { + if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); + } + if ($mode == 6) + { + if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4'); + if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5'); + } + } + + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + global $conf,$user; + + $this->id = 0; + + $this->label = '0a1b2c3e4f59999999'; + $this->entity = '1'; + $this->filename = 'myspecimenfilefile.pdf'; + $this->filepath = '/aaa/bbb'; + $this->fullpath_orig = 'c:/file on my disk.pdf'; + $this->description = 'This is a long description of file'; + $this->keywords = 'key1,key2'; + $this->cover = '1'; + $this->position = '5'; + $this->gen_or_uploaded = 'uploaded'; + $this->extraparams = ''; + $this->date_c = (dol_now() - 3600 * 24 * 10); + $this->date_m = ''; + $this->fk_user_c = $user->id; + $this->fk_user_m = ''; + $this->acl = ''; + } + +} + diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql new file mode 100644 index 00000000000..9c6aefdec6d --- /dev/null +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -0,0 +1,29 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 5.0.0 or higher. +-- +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To drop an index: -- VMYSQL4.0 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.0 DROP INDEX nomindex +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_c_shipment_mode CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): -- VPGSQL8.2 NOT POSSIBLE. MUST DELETE/CREATE TABLE +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. +-- -- VPGSQL8.2 DELETE FROM llx_usergroup_user WHERE fk_user NOT IN (SELECT rowid from llx_user); +-- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); + + +ALTER TABLE llx_ecm_files CHANGE COLUMN fullpath filepath varchar(750); +ALTER TABLE llx_ecm_files ADD COLUMN position integer; diff --git a/htdocs/install/mysql/tables/llx_ecm_files.sql b/htdocs/install/mysql/tables/llx_ecm_files.sql index 8310c160384..7a30066c2b2 100644 --- a/htdocs/install/mysql/tables/llx_ecm_files.sql +++ b/htdocs/install/mysql/tables/llx_ecm_files.sql @@ -21,12 +21,13 @@ CREATE TABLE llx_ecm_files rowid integer AUTO_INCREMENT PRIMARY KEY, label varchar(64) NOT NULL, entity integer DEFAULT 1 NOT NULL, -- multi company id + filepath varchar(750) NOT NULL, -- relative to dolibarr document dir. example module/def filename varchar(255) NOT NULL, -- file name only without any directory - fullpath varchar(750) NOT NULL, -- relative to dolibarr document dir. example abc/def/myfile fullpath_orig varchar(750), -- full path of original filename, when file is uploaded from a local computer description text, keywords text, -- list of keywords, separated with comma cover text, -- is this file a file to use for a cover + position integer, -- position of file among others gen_or_uploaded varchar(12), -- 'generated' or 'uploaded' extraparams varchar(255), -- for stocking other parameters with json format date_c datetime, From bfb628dab603020eeddd975062497998a462a7c3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Dec 2016 15:37:39 +0100 Subject: [PATCH 02/75] Code comment --- htdocs/user/class/user.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index d917b53078a..976379ff5e5 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2601,8 +2601,9 @@ class User extends CommonObject /** * Return list of all child users id in herarchy (all sublevels). + * Note: Calling this function also reste full list of users into $this->users. * - * @return array Array of user id lower than user. This overwrite this->users. + * @return array Array of user id lower than user (all levels under user). * @see get_children */ function getAllChildIds() From 51eb3726dcf2745b2c9c5e7c81cacbdbc7a20212 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Dec 2016 15:41:31 +0100 Subject: [PATCH 03/75] Code comment --- htdocs/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/document.php b/htdocs/document.php index 52b1584e7af..02eb7193675 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -109,7 +109,7 @@ if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); $check_access = dol_check_secure_access_document($modulepart,$original_file,$entity,$refname); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; -$original_file = $check_access['original_file']; +$original_file = $check_access['original_file']; // original_file is now a full path name // Basic protection (against external users only) if ($user->societe_id > 0) From e1a5a90f0a72bcdd5562d76978460043d16a6b00 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Dec 2016 00:15:21 +0100 Subject: [PATCH 04/75] NEW Uploaded files are indexed into database --- htdocs/core/class/html.formfile.class.php | 79 +++++++++++---- htdocs/core/lib/files.lib.php | 98 +++++++++++++++++-- .../tpl/document_actions_post_headers.tpl.php | 5 +- htdocs/ecm/class/ecmfiles.class.php | 17 +++- .../install/mysql/migration/5.0.0-6.0.0.sql | 1 + .../mysql/tables/llx_ecm_files.key.sql | 4 +- htdocs/install/mysql/tables/llx_ecm_files.sql | 6 +- 7 files changed, 173 insertions(+), 37 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 60ed409fc7f..b33ea772aa8 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -863,7 +863,7 @@ class FormFile * @param string $modulepart Value for modulepart used by download or viewimage wrapper * @param string $param Parameters on sort links (param must start with &, example &aaa=bbb&ccc=ddd) * @param int $forcedownload Force to open dialog box "Save As" when clicking on file - * @param string $relativepath Relative path of docs (autodefined if not provided) + * @param string $relativepath Relative path of docs (autodefined if not provided), relative to module. * @param int $permonobject Permission on object (so permission to delete or crop document) * @param int $useinecm Change output for use in ecm module * @param string $textifempty Text to show if filearray is empty ('NoFileFound' if not defined) @@ -871,23 +871,40 @@ class FormFile * @param string $title Title before list * @param string $url Full url to use for click links ('' = autodetect) * @param int $showrelpart 0=Show only filename (default), 1=Show first level 1 dir - * @param int $permtoeditline Permission to edit document line (-1 is deprecated) + * @param int $permtoeditline Permission to edit document line (You msut provide a value, -1 is deprecated and must not be used any more) * @return int <0 if KO, nb of files shown if OK + * @return string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. */ - function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1) + function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='') { global $user, $conf, $langs, $hookmanager; global $bc; global $sortfield, $sortorder, $maxheightmini; + // Define relative path used to store the file + if (empty($relativepath)) + { + $relativepath=(! empty($object->ref)?dol_sanitizeFileName($object->ref):'').'/'; + if ($object->element == 'invoice_supplier') $relativepath=get_exdir($object->id,2,0,0,$object,'invoice_supplier').$relativepath; // TODO Call using a defined value for $relativepath + if ($object->element == 'project_task') $relativepath='Call_not_supported_._Call_function_using_a_defined_relative_path_.'; + } + // For backward compatiblity, we detect file is stored into an old path + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $file['level1name'] == 'photos') + { + $relativepath=preg_replace('/^.*\/produit\//','',$file['path']).'/'; + } + // Defined relative dir to DOL_DATA_ROOT + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); + $rel_dir = preg_replace('/^[\\/]/','',$rel_dir); + $hookmanager->initHooks(array('formfile')); - $parameters=array( 'filearray' => $filearray, 'modulepart'=> $modulepart, 'param' => $param, 'forcedownload' => $forcedownload, - 'relativepath' => $relativepath, + 'relativepath' => $relativepath, // relative filename to module dir + 'reldir' => $rel_dir, // relative dirname to DOL_DATA_ROOT 'permtodelete' => $permonobject, 'useinecm' => $useinecm, 'textifempty' => $textifempty, @@ -942,10 +959,42 @@ class FormFile print_liste_field_titre(''); print "\n"; + // Get list of files stored into database for same directory + $filearrayindatabase = dol_dir_list_in_database($rel_dir, '', null, 'name', SORT_ASC); + + //var_dump($filearray); + //var_dump($filearrayindatabase); + + // Complete filearray with properties found into $filearrayindatabase + foreach($filearray as $key => $val) + { + $found=0; + // Search if it exists into $filearrayindatabase + foreach($filearrayindatabase as $key2 => $val2) + { + if ($filearrayindatabase[$key2]['name'] == $filearray[$key]['name']) + { + $filearray[$key]['position']=$filearrayindatabase[$key2]['position']; + $filearray[$key]['cover']=$filearrayindatabase[$key2]['cover']; + $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl']; + $found=1; + break; + } + } + if (! $found) + { + $filearray[$key]['position']=999999; // File not indexed are at end. So if we add a file, it will not replace existing in position + $filearray[$key]['cover']=0; + $filearray[$key]['acl']=''; + } + } + + $filearray=dol_sort_array($filearray, 'position'); + //var_dump($filearray); + $nboffiles=count($filearray); - if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; - + $var=true; foreach($filearray as $key => $file) // filearray must be only files here { @@ -953,23 +1002,13 @@ class FormFile && $file['name'] != '..' && ! preg_match('/\.meta$/i',$file['name'])) { - // Define relative path used to store the file - if (empty($relativepath)) - { - $relativepath=(! empty($object->ref)?dol_sanitizeFileName($object->ref):'').'/'; - if ($object->element == 'invoice_supplier') $relativepath=get_exdir($object->id,2,0,0,$object,'invoice_supplier').$relativepath; // TODO Call using a defined value for $relativepath - if ($object->element == 'project_task') $relativepath='Call_not_supported_._Call_function_using_a_defined_relative_path_.'; - } - // For backward compatiblity, we detect file is stored into an old path - if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $file['level1name'] == 'photos') - { - $relativepath=preg_replace('/^.*\/produit\//','',$file['path']).'/'; - } $var=!$var; $editline=0; - print ''."\n"; + print ''."\n"; + // Do we have entry into database ? + print ''."\n"; print ''; print ''; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index cc22f44ec48..059448b35dc 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -41,7 +41,7 @@ function dol_basename($pathfile) * Scan a directory and return a list of files/directories. * Content for string is UTF8 and dir separator is "/". * - * @param string $path Starting path from which to search + * @param string $path Starting path from which to search. This is a full path. * @param string $types Can be "directories", "files", or "all" * @param int $recursive Determines whether subdirectories are searched * @param string $filter Regex filter to restrict list. This regex value must be escaped for '/', since this char is used for preg_match function @@ -50,7 +50,8 @@ function dol_basename($pathfile) * @param string $sortorder Sort order (SORT_ASC, SORT_DESC) * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only * @param int $nohook Disable all hooks - * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file') + * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file',...) + * @see dol_dir_list_indatabase */ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter="", $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=false) { @@ -205,6 +206,82 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil } +/** + * Scan a directory and return a list of files/directories. + * Content for string is UTF8 and dir separator is "/". + * + * @param string $path Starting path from which to search + * @param string $filter Regex filter to restrict list. This regex value must be escaped for '/', since this char is used for preg_match function + * @param array|null $excludefilter Array of Regex for exclude filter (example: array('(\.meta|_preview\.png)$','^\.')) + * @param string $sortcriteria Sort criteria ("","fullname","name","date","size") + * @param string $sortorder Sort order (SORT_ASC, SORT_DESC) + * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like description + * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','type'=>'dir|file',...) + * @see dol_dir_list + */ +function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0) +{ + global $conf, $db; + + $sql=" SELECT label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; + if ($mode) $sql.=", description"; + $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; + $sql.=" WHERE filepath = '".$db->escape($path)."'"; + $sql.=" AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) + { + $file_list=array(); + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); + $level1name=(isset($reg[1])?$reg[1]:''); + $file_list[] = array( + "name" => $obj->filename, + "path" => DOL_DATA_ROOT.'/'.$obj->filepath, + "level1name" => $level1name, + "fullname" => DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename, + "fullpath_orig" => $obj->fullpath_orig, + "date_c" => $db->jdate($obj->date_c), + "date_m" => $db->jdate($obj->date_m), + "type" => 'file', + "keywords" => $obj->keywords, + "cover" => $obj->cover, + "position" => (int) $obj->position, + "acl" => $obj->acl + ); + } + $i++; + } + + // Obtain a list of columns + if (! empty($sortcriteria)) + { + $myarray=array(); + foreach ($file_list as $key => $row) + { + $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:''); + } + // Sort the data + if ($sortorder) array_multisort($myarray, $sortorder, $file_list); + } + + return $file_list; + } + else + { + dol_print_error($db); + return array(); + } +} + + /** * Fast compare of 2 files identified by their properties ->name, ->date and ->size * @@ -751,7 +828,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); if (! preg_match('/\/temp\//', $rel_filetodelete)) // If not a tmp file { - $rel_filetodelete = preg_replace('/^\//', '', $rel_filetodelete); + $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; @@ -1083,10 +1160,10 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio else // Update table of files { $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); - if (! preg_match('/\/temp\//', $rel_dir)) // If not a tmp file + if (! preg_match('/[\\/]temp[\\/]/', $rel_dir)) // If not a tmp file { - $rel_dir = preg_replace('/\/$/', '', $rel_dir); - $rel_dir = preg_replace('/^\//', '', $rel_dir); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $ecmfile=new EcmFiles($db); @@ -1384,11 +1461,11 @@ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta * Security check when accessing to a document (used by document.php, viewimage.php and webservices) * * @param string $modulepart Module of document ('module', 'module_user_temp', 'module_user' or 'module_temp') - * @param string $original_file Relative path with filename + * @param string $original_file Relative path with filename, relative to modulepart. * @param string $entity Restrict onto entity * @param User $fuser User object (forced) * @param string $refname Ref of object to check permission for external users (autodetect if not provided) - * @return mixed Array with access information : accessallowed & sqlprotectagainstexternals & original_file (as full path name) + * @return mixed Array with access information : 'accessallowed' & 'sqlprotectagainstexternals' & 'original_file' (as a full path name) */ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fuser='',$refname='') { @@ -1682,7 +1759,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $accessallowed=1; } $original_file=$conf->projet->dir_output.'/'.$original_file; - $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project', 1).")"; } else if ($modulepart == 'project_task') { @@ -1691,7 +1768,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $accessallowed=1; } $original_file=$conf->projet->dir_output.'/'.$original_file; - $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project', 1).")"; } // Wrapping for interventions else if ($modulepart == 'fichinter') @@ -1806,6 +1883,7 @@ function dol_check_secure_access_document($modulepart,$original_file,$entity,$fu $accessallowed=1; } $original_file=$conf->contrat->dir_output.'/'.$original_file; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."contrat WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('contract', 1).")"; } // Wrapping pour les dons diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index 83d38793072..546cec91142 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -79,7 +79,7 @@ $formfile->list_of_documents( $modulepart, $param, 0, - $relativepathwithnofile, // relative path with no file. For example "moduledir/0/1" + $relativepathwithnofile, // relative path with no file. For example "0/1" $permission, 0, '', @@ -87,7 +87,8 @@ $formfile->list_of_documents( '', '', 0, - $permtoedit + $permtoedit, + $upload_dir ); print "
"; diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 0133bff2580..0e1885fa62f 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -136,6 +136,21 @@ class EcmFiles //extends CommonObject } if (empty($this->date_c)) $this->date_c = dol_now(); + $maxposition=0; + if (empty($this->position)) // Get max used + { + $sql = "SELECT MAX(position) as maxposition FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql.= " WHERE filepath ='".$this->filepath."'"; + + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $maxposition = (int) $obj->maxposition; + } + else dol_print_error($this->db); + } + $maxposition=$maxposition+1; // Check parameters // Put here code to add control on parameters values @@ -167,7 +182,7 @@ class EcmFiles //extends CommonObject $sql .= ' '.(! isset($this->description)?'NULL':"'".$this->db->escape($this->description)."'").','; $sql .= ' '.(! isset($this->keywords)?'NULL':"'".$this->db->escape($this->keywords)."'").','; $sql .= ' '.(! isset($this->cover)?'NULL':"'".$this->db->escape($this->cover)."'").','; - $sql .= ' '.(! isset($this->position)?'0':$this->db->escape($this->position)).','; + $sql .= ' '.$maxposition.','; $sql .= ' '.(! isset($this->gen_or_uploaded)?'NULL':"'".$this->db->escape($this->gen_or_uploaded)."'").','; $sql .= ' '.(! isset($this->extraparams)?'NULL':"'".$this->db->escape($this->extraparams)."'").','; $sql .= ' '."'".$this->db->idate($this->date_c)."'".','; diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 9c6aefdec6d..73d209b0cdc 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -27,3 +27,4 @@ ALTER TABLE llx_ecm_files CHANGE COLUMN fullpath filepath varchar(750); ALTER TABLE llx_ecm_files ADD COLUMN position integer; +ALTER TABLE llx_ecm_files CHANGE COLUMN keyword keyword varchar(750); diff --git a/htdocs/install/mysql/tables/llx_ecm_files.key.sql b/htdocs/install/mysql/tables/llx_ecm_files.key.sql index 9b1f4fcf164..2b8b1348ba3 100644 --- a/htdocs/install/mysql/tables/llx_ecm_files.key.sql +++ b/htdocs/install/mysql/tables/llx_ecm_files.key.sql @@ -17,5 +17,7 @@ -- ============================================================================ -ALTER TABLE llx_ecm_files ADD UNIQUE INDEX uk_ecm_files (label, entity); +ALTER TABLE llx_ecm_files ADD UNIQUE INDEX uk_ecm_files (label, entity); -- label is a md5 --ALTER TABLE llx_ecm_files ADD UNIQUE INDEX uk_ecm_files_fullpath(fullpath); Disabled, mysql limits size of index + + diff --git a/htdocs/install/mysql/tables/llx_ecm_files.sql b/htdocs/install/mysql/tables/llx_ecm_files.sql index 7a30066c2b2..45157cdf959 100644 --- a/htdocs/install/mysql/tables/llx_ecm_files.sql +++ b/htdocs/install/mysql/tables/llx_ecm_files.sql @@ -19,13 +19,13 @@ CREATE TABLE llx_ecm_files ( rowid integer AUTO_INCREMENT PRIMARY KEY, - label varchar(64) NOT NULL, + label varchar(64) NOT NULL, -- label contains a md5 entity integer DEFAULT 1 NOT NULL, -- multi company id - filepath varchar(750) NOT NULL, -- relative to dolibarr document dir. example module/def + filepath varchar(750) NOT NULL, -- relative to dolibarr document dir. Example module/def filename varchar(255) NOT NULL, -- file name only without any directory fullpath_orig varchar(750), -- full path of original filename, when file is uploaded from a local computer description text, - keywords text, -- list of keywords, separated with comma + keywords varchar(750), -- list of keywords, separated with comma. Must be limited to most important keywords. cover text, -- is this file a file to use for a cover position integer, -- position of file among others gen_or_uploaded varchar(12), -- 'generated' or 'uploaded' From 902169cb665a2a925a92294407908a034a27eb84 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Dec 2016 00:40:12 +0100 Subject: [PATCH 05/75] Can sort on position on list of documents --- htdocs/core/class/html.formfile.class.php | 98 +++++++++++-------- .../tpl/document_actions_post_headers.tpl.php | 4 +- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index b33ea772aa8..46eeb7eaf51 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -856,26 +856,28 @@ class FormFile /** - * Show list of documents in a directory + * Show list of documents in $filearray (may be they are all in same directory but may not) * - * @param array $filearray Array of files loaded by dol_dir_list('files') function before calling this - * @param Object $object Object on which document is linked to - * @param string $modulepart Value for modulepart used by download or viewimage wrapper + * @param array $filearray Array of files loaded by dol_dir_list('files') function before calling this. + * @param Object $object Object on which document is linked to. + * @param string $modulepart Value for modulepart used by download or viewimage wrapper. * @param string $param Parameters on sort links (param must start with &, example &aaa=bbb&ccc=ddd) - * @param int $forcedownload Force to open dialog box "Save As" when clicking on file - * @param string $relativepath Relative path of docs (autodefined if not provided), relative to module. + * @param int $forcedownload Force to open dialog box "Save As" when clicking on file. + * @param string $relativepath Relative path of docs (autodefined if not provided), relative to module dir, not to MAIN_DATA_ROOT. * @param int $permonobject Permission on object (so permission to delete or crop document) * @param int $useinecm Change output for use in ecm module * @param string $textifempty Text to show if filearray is empty ('NoFileFound' if not defined) - * @param int $maxlength Maximum length of file name shown + * @param int $maxlength Maximum length of file name shown. * @param string $title Title before list * @param string $url Full url to use for click links ('' = autodetect) * @param int $showrelpart 0=Show only filename (default), 1=Show first level 1 dir - * @param int $permtoeditline Permission to edit document line (You msut provide a value, -1 is deprecated and must not be used any more) + * @param int $permtoeditline Permission to edit document line (You must provide a value, -1 is deprecated and must not be used any more) + * @param string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this if you want to complete file data with database indexes. + * @param string $sortfield Sort field ('name', 'size', 'position', ...) + * @param string $sortorder Sort order ('ASC' or 'DESC') * @return int <0 if KO, nb of files shown if OK - * @return string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. */ - function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='') + function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='',$sortfield='',$sortorder='ASC') { global $user, $conf, $langs, $hookmanager; global $bc; @@ -894,9 +896,13 @@ class FormFile $relativepath=preg_replace('/^.*\/produit\//','',$file['path']).'/'; } // Defined relative dir to DOL_DATA_ROOT - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); - $rel_dir = preg_replace('/^[\\/]/','',$rel_dir); - + $relativedir = ''; + if ($upload_dir) + { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); + $relativedir = preg_replace('/^[\\/]/','',$relativedir); + } + $hookmanager->initHooks(array('formfile')); $parameters=array( 'filearray' => $filearray, @@ -904,7 +910,7 @@ class FormFile 'param' => $param, 'forcedownload' => $forcedownload, 'relativepath' => $relativepath, // relative filename to module dir - 'reldir' => $rel_dir, // relative dirname to DOL_DATA_ROOT + 'relativedir' => $relativedir, // relative dirname to DOL_DATA_ROOT 'permtodelete' => $permonobject, 'useinecm' => $useinecm, 'textifempty' => $textifempty, @@ -960,37 +966,43 @@ class FormFile print "\n"; // Get list of files stored into database for same directory - $filearrayindatabase = dol_dir_list_in_database($rel_dir, '', null, 'name', SORT_ASC); - - //var_dump($filearray); - //var_dump($filearrayindatabase); - - // Complete filearray with properties found into $filearrayindatabase - foreach($filearray as $key => $val) + if ($relativedir) { - $found=0; - // Search if it exists into $filearrayindatabase - foreach($filearrayindatabase as $key2 => $val2) - { - if ($filearrayindatabase[$key2]['name'] == $filearray[$key]['name']) - { - $filearray[$key]['position']=$filearrayindatabase[$key2]['position']; - $filearray[$key]['cover']=$filearrayindatabase[$key2]['cover']; - $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl']; - $found=1; - break; - } - } - if (! $found) - { - $filearray[$key]['position']=999999; // File not indexed are at end. So if we add a file, it will not replace existing in position - $filearray[$key]['cover']=0; - $filearray[$key]['acl']=''; - } + $filearrayindatabase = dol_dir_list_in_database($relativedir, '', null, 'name', SORT_ASC); + + //var_dump($filearray); + //var_dump($filearrayindatabase); + + // Complete filearray with properties found into $filearrayindatabase + foreach($filearray as $key => $val) + { + $found=0; + // Search if it exists into $filearrayindatabase + foreach($filearrayindatabase as $key2 => $val2) + { + if ($filearrayindatabase[$key2]['name'] == $filearray[$key]['name']) + { + $filearray[$key]['position']=$filearrayindatabase[$key2]['position']; + $filearray[$key]['cover']=$filearrayindatabase[$key2]['cover']; + $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl']; + $found=1; + break; + } + } + if (! $found) + { + $filearray[$key]['position']=999999; // File not indexed are at end. So if we add a file, it will not replace existing in position + $filearray[$key]['cover']=0; + $filearray[$key]['acl']=''; + } + } + + if ($sortfield && $sortorder) + { + $filearray=dol_sort_array($filearray, $sortfield, $sortorder); + } + //var_dump($filearray); } - - $filearray=dol_sort_array($filearray, 'position'); - //var_dump($filearray); $nboffiles=count($filearray); if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index 546cec91142..a28f46f58f2 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -88,7 +88,9 @@ $formfile->list_of_documents( '', 0, $permtoedit, - $upload_dir + $upload_dir, + $sortfield, + $sortorder ); print "
"; From a736f3782c410f30b79e2c7be4804fcf5043b361 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Dec 2016 13:21:09 +0100 Subject: [PATCH 06/75] FIX security bugs --- htdocs/accountancy/bookkeeping/balancebymonth.php | 4 +++- htdocs/accountancy/customer/index.php | 4 ++-- htdocs/accountancy/report/result.php | 4 +++- htdocs/accountancy/supplier/index.php | 4 ++-- htdocs/asterisk/wrapper.php | 8 ++++---- htdocs/categories/traduction.php | 2 +- htdocs/install/step4.php | 2 +- htdocs/loan/calc.php | 12 ++++++------ htdocs/loan/payment/card.php | 4 ++-- .../canvas/product/actions_card_product.class.php | 5 ++--- .../canvas/service/actions_card_service.class.php | 4 ++-- htdocs/product/traduction.php | 2 +- 12 files changed, 29 insertions(+), 26 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balancebymonth.php b/htdocs/accountancy/bookkeeping/balancebymonth.php index 9202371e5a5..83908f72172 100644 --- a/htdocs/accountancy/bookkeeping/balancebymonth.php +++ b/htdocs/accountancy/bookkeeping/balancebymonth.php @@ -38,7 +38,7 @@ $langs->load("other"); $langs->load("accountancy"); // Filter -$year = $_GET["year"]; +$year = GETPOST("year",'int'); if ($year == 0) { $year_current = strftime("%Y", time()); $year_start = $year_current; @@ -47,9 +47,11 @@ if ($year == 0) { $year_start = $year; } + /* * View */ + llxHeader('', $langs->trans("Bookkeeping")); $textprevyear = '' . img_previous() . ''; diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index fea8281935f..ef5c512179a 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -47,7 +47,7 @@ if (! $user->rights->accounting->bind->write) accessforbidden(); // Filter -$year = $_GET["year"]; +$year = GETPOST("year",'int'); if ($year == 0) { $year_current = strftime("%Y", time()); $year_start = $year_current; @@ -57,7 +57,7 @@ if ($year == 0) { } // Validate History -$action = GETPOST('action'); +$action = GETPOST('action','alpha'); diff --git a/htdocs/accountancy/report/result.php b/htdocs/accountancy/report/result.php index e31e1c92f17..317b7193ff3 100644 --- a/htdocs/accountancy/report/result.php +++ b/htdocs/accountancy/report/result.php @@ -43,7 +43,7 @@ $rowid = GETPOST('rowid', 'int'); $cancel = GETPOST('cancel'); // Filter -$year = $_GET["year"]; +$year = GETPOST('year','int'); if ($year == 0) { $year_current = strftime("%Y", time()); $year_start = $year_current; @@ -64,9 +64,11 @@ if (! $user->rights->accounting->comptarapport->lire) $AccCat = new AccountancyCategory($db); + /* * View */ + llxheader('', $langs->trans('ReportInOut')); $formaccounting = new FormAccounting($db); diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 82c7cebe087..ef7d470bb07 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -45,7 +45,7 @@ if (! $user->rights->accounting->bind->write) accessforbidden(); // Filter -$year = $_GET["year"]; +$year = GETPOST("year",'int'); if ($year == 0) { $year_current = strftime("%Y", time()); $year_start = $year_current; @@ -55,7 +55,7 @@ if ($year == 0) { } // Validate History -$action = GETPOST('action'); +$action = GETPOST('action', 'alpha'); /* diff --git a/htdocs/asterisk/wrapper.php b/htdocs/asterisk/wrapper.php index e5c9a6b2093..381750546ce 100644 --- a/htdocs/asterisk/wrapper.php +++ b/htdocs/asterisk/wrapper.php @@ -85,10 +85,10 @@ if (! isset($conf->global->ASTERISK_PRIORITY)) $conf->global->ASTERISK_PRIORITY if (! isset($conf->global->ASTERISK_MAX_RETRY)) $conf->global->ASTERISK_MAX_RETRY="2"; -$login = $_GET['login']; -$password = $_GET['password']; -$caller = $_GET['caller']; -$called = $_GET['called']; +$login = GETPOST('login'); +$password = GETPOST('password'); +$caller = GETPOST('caller'); +$called = GETPOST('called'); // IP address of Asterisk server $strHost = $conf->global->ASTERISK_HOST; diff --git a/htdocs/categories/traduction.php b/htdocs/categories/traduction.php index 00741f81390..1967727b32f 100644 --- a/htdocs/categories/traduction.php +++ b/htdocs/categories/traduction.php @@ -277,7 +277,7 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service print '
'; print ''; print ''; - print ''; + print ''; print ''; print ''; + print ''; print ''; print '
'.$langs->trans('Translation').''; diff --git a/htdocs/install/step4.php b/htdocs/install/step4.php index ce16596bdbf..740a45a9063 100644 --- a/htdocs/install/step4.php +++ b/htdocs/install/step4.php @@ -79,7 +79,7 @@ $db=getDoliDBInstance($conf->db->type,$conf->db->host,$conf->db->user,$conf->db- if ($db->ok) { print '
'.$langs->trans("DolibarrAdminLogin").' :'; - print '
'.$langs->trans("Password").' :'; print '
'.$langs->trans("PasswordAgain").' :'; diff --git a/htdocs/loan/calc.php b/htdocs/loan/calc.php index b6e649962fa..76b4c989aa7 100644 --- a/htdocs/loan/calc.php +++ b/htdocs/loan/calc.php @@ -49,12 +49,12 @@ $error = false; * Set the USER INPUT values * --------------------------------------------------- */ if (isset($_REQUEST['form_complete'])) { - $sale_price = $_REQUEST['sale_price']; - $annual_interest_percent = $_REQUEST['annual_interest_percent']; - $year_term = $_REQUEST['year_term']; - $down_percent = $_REQUEST['down_percent']; - $show_progress = (isset($_REQUEST['show_progress'])) ? $_REQUEST['show_progress'] : false; - $form_complete = $_REQUEST['form_complete']; + $sale_price = GETPOST('sale_price'); + $annual_interest_percent = GETPOST('annual_interest_percent'); + $year_term = GETPOST('year_term'); + $down_percent = GETPOST('down_percent'); + $show_progress = (isset($_REQUEST['show_progress'])) ? GETPOST('show_progress') : false; + $form_complete = GETPOST('form_complete'); } // This function does the actual mortgage calculations diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php index 41f332e5dd0..c76b0565a3f 100644 --- a/htdocs/loan/payment/card.php +++ b/htdocs/loan/payment/card.php @@ -32,7 +32,7 @@ $langs->load('companies'); $langs->load('loan'); // Security check -$id=GETPOST("id"); +$id=GETPOST("id",'int'); $action=GETPOST("action"); $confirm=GETPOST('confirm'); if ($user->societe_id) $socid=$user->societe_id; @@ -120,7 +120,7 @@ $form = new Form($db); $h=0; -$head[$h][0] = DOL_URL_ROOT.'/loan/payment/card.php?id='.$_GET["id"]; +$head[$h][0] = DOL_URL_ROOT.'/loan/payment/card.php?id='.$id; $head[$h][1] = $langs->trans("Card"); $hselected = $h; $h++; diff --git a/htdocs/product/canvas/product/actions_card_product.class.php b/htdocs/product/canvas/product/actions_card_product.class.php index e32d31122dc..06803e8239d 100644 --- a/htdocs/product/canvas/product/actions_card_product.class.php +++ b/htdocs/product/canvas/product/actions_card_product.class.php @@ -325,16 +325,15 @@ class ActionsCardProduct $this->list_datas = array(); - //$_GET["sall"] = 'LL'; // Clean parameters - $sall=trim(isset($_GET["sall"])?$_GET["sall"]:$_POST["sall"]); + $sall=trim(GETPOST("sall")); foreach($this->field_list as $field) { if ($field['enabled']) { $fieldname = "s".$field['alias']; - $$fieldname = trim(isset($_GET[$fieldname])?$_GET[$fieldname]:$_POST[$fieldname]); + $$fieldname = trim(GETPOST($fieldname)); } } diff --git a/htdocs/product/canvas/service/actions_card_service.class.php b/htdocs/product/canvas/service/actions_card_service.class.php index 7bc04ecb42a..af6fbccc320 100644 --- a/htdocs/product/canvas/service/actions_card_service.class.php +++ b/htdocs/product/canvas/service/actions_card_service.class.php @@ -308,9 +308,9 @@ class ActionsCardService $sql.= ' FROM '.MAIN_DB_PREFIX.'product as p'; // We'll need this table joined to the select in order to filter by categ if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp"; - if ($_GET["fourn_id"] > 0) + if (GETPOST("fourn_id",'int') > 0) { - $fourn_id = $_GET["fourn_id"]; + $fourn_id = GETPOST("fourn_id",'int'); $sql.= ", ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; } $sql.= " WHERE p.entity IN (".getEntity('product', 1).")"; diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 1f6ae678a81..f616004db42 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -305,7 +305,7 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service print ''; print ''; print ''; - print ''; + print ''; print ''; print '
'.$langs->trans('Language').''; From 94eeaf9ed05cb70bb79897363283626bc5549569 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 19 Dec 2016 18:47:21 +0100 Subject: [PATCH 07/75] Fix typo error --- htdocs/langs/en_US/errors.lang | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 5727c0edb11..8635b3e2d88 100755 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -176,10 +176,10 @@ ErrorWarehouseRequiredIntoShipmentLine=Warehouse is required on the line to ship ErrorFileMustHaveFormat=File must have format %s ErrorSupplierCountryIsNotDefined=Country for this supplier is not defined. Correct this first. ErrorsThirdpartyMerge=Failed to merge the two records. Request canceled. -ErrorStockIsNotEnoughToAddProductOnOrder=Stock is not enougth for product %s to add it into a new order. -ErrorStockIsNotEnoughToAddProductOnInvoice=Stock is not enougth for product %s to add it into a new invoice. -ErrorStockIsNotEnoughToAddProductOnShipment=Stock is not enougth for product %s to add it into a new shipment. -ErrorStockIsNotEnoughToAddProductOnProposal=Stock is not enougth for product %s to add it into a new proposal. +ErrorStockIsNotEnoughToAddProductOnOrder=Stock is not enough for product %s to add it into a new order. +ErrorStockIsNotEnoughToAddProductOnInvoice=Stock is not enough for product %s to add it into a new invoice. +ErrorStockIsNotEnoughToAddProductOnShipment=Stock is not enough for product %s to add it into a new shipment. +ErrorStockIsNotEnoughToAddProductOnProposal=Stock is not enough for product %s to add it into a new proposal. ErrorPhpMailDelivery=Check that you don't use a too high number of recipients and that your email content is not similar to a Spam. Ask also your administrator to check firewall and server logs files for a more complete information. # Warnings From f7e5898b4ad79393ffe300b91b42fb580050ee3f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 20 Dec 2016 10:58:31 +0100 Subject: [PATCH 08/75] Fix show a more accurate translation --- htdocs/langs/en_US/mails.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index f682df02406..67a8a24c04d 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -42,7 +42,7 @@ MailingStatusSentPartialy=Sent partialy MailingStatusSentCompletely=Sent completely MailingStatusError=Error MailingStatusNotSent=Not sent -MailSuccessfulySent=Email successfully sent (from %s to %s) +MailSuccessfulySent=Email successfully accepted for delivery (from %s to %s) MailingSuccessfullyValidated=EMailing successfully validated MailUnsubcribe=Unsubscribe Unsuscribe=Unsubscribe From 08449a2d4f3efdd04f1b98785a70eaf25ad918b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 20 Dec 2016 12:05:00 +0100 Subject: [PATCH 09/75] Prepare action tracking on products --- htdocs/install/mysql/data/llx_c_action_trigger.sql | 3 +++ htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index b35d08036b3..c01e8d5ae20 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -76,6 +76,9 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_UNBILLED','Intervention set unbilled','Executed when a intervention is set to unbilled (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',19); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_REOPEN','Intervention opened','Executed when a intervention is re-opened','ficheinter',19); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',19); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_CREATE','Product or service created','Executed when a product or sevice is created','product',30); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_MODIFY','Product or service modified','Executed when a product or sevice is modified','product',30); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_DELETE','Product or service deleted','Executed when a product or sevice is deleted','product',30); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_CREATE','Project creation','Executed when a project is created','project',140); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_MODIFY','Project modified','Executed when a project is modified','project',141); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_DELETE','Project deleted','Executed when a project is deleted','project',142); diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 73d209b0cdc..56fdb70b809 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -28,3 +28,9 @@ ALTER TABLE llx_ecm_files CHANGE COLUMN fullpath filepath varchar(750); ALTER TABLE llx_ecm_files ADD COLUMN position integer; ALTER TABLE llx_ecm_files CHANGE COLUMN keyword keyword varchar(750); + + +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_CREATE','Product or service created','Executed when a product or sevice is created','product',30); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_MODIFY','Product or service modified','Executed when a product or sevice is modified','product',30); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_DELETE','Product or service deleted','Executed when a product or sevice is deleted','product',30); + From ed0ffd6f5a16e34141751f11b5cb5f65e17b40a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 20 Dec 2016 19:42:25 +0100 Subject: [PATCH 10/75] NEW Uploaded files are indexed into database --- htdocs/core/actions_linkedfiles.inc.php | 6 +- htdocs/core/class/html.formfile.class.php | 62 +++++++-- htdocs/core/lib/files.lib.php | 118 ++++++++++++++---- htdocs/core/photos_resize.php | 97 ++++++++++++-- htdocs/core/tpl/ajaxrow.tpl.php | 9 +- .../tpl/document_actions_post_headers.tpl.php | 6 +- htdocs/ecm/class/ecmfiles.class.php | 7 +- htdocs/product/document.php | 2 +- 8 files changed, 254 insertions(+), 53 deletions(-) diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php index 672da011a79..d97ecbe716a 100644 --- a/htdocs/core/actions_linkedfiles.inc.php +++ b/htdocs/core/actions_linkedfiles.inc.php @@ -165,7 +165,11 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave')) setEventMessages($langs->trans("FileRenamed"), null); } - else setEventMessages($langs->trans("ErrorFailToRenameFile", $filenamefrom, $filenameto), null, 'errors'); + else + { + $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now. + setEventMessages($langs->trans("ErrorFailToRenameFile", $filenamefrom, $filenameto), null, 'errors'); + } } } } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index b5c370bee07..a82024d86cf 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -875,12 +875,13 @@ class FormFile * @param string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this if you want to complete file data with database indexes. * @param string $sortfield Sort field ('name', 'size', 'position', ...) * @param string $sortorder Sort order ('ASC' or 'DESC') + * @param int $disablemove 1=Disable move button, 0=Position move is possible. * @return int <0 if KO, nb of files shown if OK */ - function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='',$sortfield='',$sortorder='ASC') + function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='',$sortfield='',$sortorder='ASC', $disablemove=1) { global $user, $conf, $langs, $hookmanager; - global $bc; + global $bc,$bcdd; global $sortfield, $sortorder, $maxheightmini; // Define relative path used to store the file @@ -955,17 +956,18 @@ class FormFile print ''; print ''; } - print ''."\n"; + print '
'."\n"; - print ''; + print ''; print_liste_field_titre($langs->trans("Documents2"),$url,"name","",$param,'align="left"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Size"),$url,"size","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Date"),$url,"date","",$param,'align="center"',$sortfield,$sortorder); if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); print_liste_field_titre(''); + if (! $disablemove) print_liste_field_titre(''); print "\n"; - // Get list of files stored into database for same directory + // Get list of files stored into database for same relative directory if ($relativedir) { $filearrayindatabase = dol_dir_list_in_database($relativedir, '', null, 'name', SORT_ASC); @@ -985,15 +987,21 @@ class FormFile $filearray[$key]['position']=$filearrayindatabase[$key2]['position']; $filearray[$key]['cover']=$filearrayindatabase[$key2]['cover']; $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl']; + $filearray[$key]['rowid']=$filearrayindatabase[$key2]['rowid']; $found=1; break; } } if (! $found) { - $filearray[$key]['position']=999999; // File not indexed are at end. So if we add a file, it will not replace existing in position + $filearray[$key]['position']=999999; // File not indexed are at end. So if we add a file, it will not replace an existing position $filearray[$key]['cover']=0; $filearray[$key]['acl']=''; + $filearray[$key]['rowid']=0; + // TODO Add entry into database + + //... + } } @@ -1007,7 +1015,7 @@ class FormFile $nboffiles=count($filearray); if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; - $var=true; + $var=true; $i=0; $nboflines = 0; $lastrowid=0; foreach($filearray as $key => $file) // filearray must be only files here { if ($file['name'] != '.' @@ -1016,12 +1024,14 @@ class FormFile { $var=!$var; - $editline=0; + if ($filearray[$key]['rowid'] > 0) $lastrowid = $filearray[$key]['rowid']; + $editline=0; + $nboflines++; print ''."\n"; // Do we have entry into database ? print ''."\n"; - print ''; + print ''; print '"; + + if (empty($disablemove)) + { + if ($nboffiles > 1 && empty($conf->browser->phone)) { + print ''; + } + else { + print ''; + } + } } else { @@ -1132,18 +1160,32 @@ class FormFile print ''; print ''; print ''; + if (empty($disablemove)) print ''; } print "\n"; + + $i++; } } if ($nboffiles == 0) { - print ''; } print "
'; //print "XX".$file['name']; //$file['name'] must be utf8 @@ -1125,6 +1135,24 @@ class FormFile print ''.img_delete().''; } print "'; + if ($i > 0) { + print 'id.'">'.img_up('default',0,'imgupforline').''; + } + if ($i < $nboffiles-1) { + print 'id.'">'.img_down('default',0,'imgdownforline').''; + } + print 'browser->phone) && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"').'>'; + print '
'; + $colspan=(empty($useinecm)?'5':'5'); + if (empty($disablemove)) $colspan++; + print '
'; if (empty($textifempty)) print $langs->trans("NoFileFound"); else print $textifempty; print '
"; + + + if (! $editline && $nboflines > 1) { + if (! empty($conf->use_javascript_ajax) && $permtoeditline) { + $table_element_line = 'ecm_files'; + include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; + } + } + if (GETPOST('action') == 'editfile' && $permtoeditline) { print ''; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 059448b35dc..a4273644fdf 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -223,7 +223,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc { global $conf, $db; - $sql=" SELECT label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; + $sql=" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; if ($mode) $sql.=", description"; $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; $sql.=" WHERE filepath = '".$db->escape($path)."'"; @@ -243,6 +243,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( + "rowid" => $obj->rowid, "name" => $obj->filename, "path" => DOL_DATA_ROOT.'/'.$obj->filepath, "level1name" => $level1name, @@ -574,11 +575,19 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists) */ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1) { - global $conf; + global $user, $db, $conf; $result=false; dol_syslog("files.lib.php::dol_move srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwritifexists=".$overwriteifexists); + $srcexists=dol_is_file($srcfile); $destexists=dol_is_file($destfile); + + if (! $srcexists) + { + dol_syslog("files.lib.php::dol_move srcfile does not exists. we ignore the move request."); + return false; + } + if ($overwriteifexists || ! $destexists) { $newpathofsrcfile=dol_osencode($srcfile); @@ -589,13 +598,69 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1) { if ($destexists) { - dol_syslog("files.lib.php::dol_move failed. We try to delete first and move after.", LOG_WARNING); + dol_syslog("files.lib.php::dol_move Failed. We try to delete target first and move after.", LOG_WARNING); // We force delete and try again. Rename function sometimes fails to replace dest file with some windows NTFS partitions. dol_delete_file($destfile); $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @ } - else dol_syslog("files.lib.php::dol_move failed", LOG_WARNING); + else dol_syslog("files.lib.php::dol_move Failed.", LOG_WARNING); } + + // Move ok + if ($result) + { + // Rename entry into ecm database + $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile); + $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile); + if (! preg_match('/(\/temp\/|\/thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file + { + $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore); + $rel_filetorenameafter = preg_replace('/^[\\/]/', '', $rel_filetorenameafter); + //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter); + + dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG); + include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', $rel_filetorenamebefore); + if ($result > 0) // If found + { + $filename = basename($rel_filetorenameafter); + $rel_dir = dirname($rel_filetorenameafter); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $result = $ecmfile->update($user); + } + elseif ($result == 0) // If not found + { + $filename = basename($rel_filetorenameafter); + $rel_dir = dirname($rel_filetorenameafter); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($destfile)); // $destfile is a full path to file + $ecmfile->fullpath_orig = $srcfile; + $ecmfile->gen_or_uploaded = 'unknown'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $result = $ecmfile->create($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + $result = $ecmfile->create($user); + } + elseif ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + } + if (empty($newmask)) $newmask=empty($conf->global->MAIN_UMASK)?'0755':$conf->global->MAIN_UMASK; $newmaskdec=octdec($newmask); // Currently method is restricted to files (dol_delete_files previously used is for files, and mask usage if for files too) @@ -826,7 +891,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n // Delete entry into ecm database $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); - if (! preg_match('/\/temp\//', $rel_filetodelete)) // If not a tmp file + if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file { $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); @@ -846,7 +911,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n } else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); // TODO Failure to remove can be because file was already removed or because of permission - // If error because of not exists, we must can return true but we should return false if this is a permission problem + // If error because of not exists, we must should return true and we should return false if this is a permission problem } } else dol_syslog("No files to delete found", LOG_WARNING); @@ -1095,7 +1160,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') * All information used are in db, conf, langs, user and _FILES. * Note: This function can be used only into a HTML page context. * - * @param string $upload_dir Directory where to store uploaded file (note: also find in first part of dest_file) + * @param string $upload_dir Directory where to store uploaded file (note: used to forge $destpath = $upload_dir + filename) * @param int $allowoverwrite 1=Allow overwrite existing file * @param int $donotupdatesession 1=Do no edit _SESSION variable * @param string $varfiles _FILES var name @@ -1150,6 +1215,21 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini; include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; + + // Generate thumbs. + if (image_format_supported($destpath) == 1) + { + // Create thumbs + // We can't use $object->addThumbs here because there is no $object known + + // Used on logon for example + $imgThumbSmall = vignette($destpath, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); + // Create mini thumbs for image (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($destpath, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); + } + + // Update session if (empty($donotupdatesession)) { include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; @@ -1157,19 +1237,22 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $formmail->trackid = $trackid; $formmail->add_attached_files($destpath, $destfile, $TFile['type'][$i]); } - else // Update table of files + + // Update table of files + if ($donotupdatesession) { - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile); if (! preg_match('/[\\/]temp[\\/]/', $rel_dir)) // If not a tmp file { + $filename = basename($destfile); $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $ecmfile=new EcmFiles($db); - $ecmfile->label = md5_file($destpath); - $ecmfile->filename = $destfile; $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($destpath)); $ecmfile->fullpath_orig = $TFile['name'][$i]; $ecmfile->gen_or_uploaded = 'uploaded'; $ecmfile->description = ''; // indexed content @@ -1181,18 +1264,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio } } } - if (image_format_supported($destpath) == 1) - { - // Create thumbs - // We can't use $object->addThumbs here because there is no $object known - - // Used on logon for example - $imgThumbSmall = vignette($destpath, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); - // Create mini thumbs for image (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($destpath, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); - } - + setEventMessages($langs->trans("FileTransferComplete"), null, 'mesgs'); } else diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index ae73347edfa..5642300bd6c 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -134,11 +134,50 @@ if ($action == 'confirm_resize' && (isset($_POST["file"]) != "") && (isset($_POS { $fullpath=$dir."/".$original_file; $result=dol_imageResizeOrCrop($fullpath,0,$_POST['sizex'],$_POST['sizey']); - + if ($result == $fullpath) { $object->addThumbs($fullpath); + // Update/create database for file $fullpath + $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $fullpath); + $rel_filename = preg_replace('/^[\\/]/','',$rel_filename); + + include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', $rel_filename); + if ($result > 0) // If found + { + $filename = basename($rel_filename); + $rel_dir = dirname($rel_filename); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->label = md5_file(dol_osencode($fullpath)); + $result = $ecmfile->update($user); + } + elseif ($result == 0) // If not found + { + $filename = basename($rel_filename); + $rel_dir = dirname($rel_filename); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($fullpath)); // $fullpath is a full path to file + $ecmfile->fullpath_orig = $fullpath; + $ecmfile->gen_or_uploaded = 'unknown'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $result = $ecmfile->create($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + $result = $ecmfile->create($user); + } + if ($backtourl) { header("Location: ".$backtourl); @@ -168,6 +207,45 @@ if ($action == 'confirm_crop') { $object->addThumbs($fullpath); + // Update/create database for file $fullpath + $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $fullpath); + $rel_filename = preg_replace('/^[\\/]/','',$rel_filename); + + include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', $rel_filename); + if ($result > 0) // If found + { + $filename = basename($rel_filename); + $rel_dir = dirname($rel_filename); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->label = md5_file(dol_osencode($fullpath)); + $result = $ecmfile->update($user); + } + elseif ($result == 0) // If not found + { + $filename = basename($rel_filename); + $rel_dir = dirname($rel_filename); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($fullpath)); // $fullpath is a full path to file + $ecmfile->fullpath_orig = $fullpath; + $ecmfile->gen_or_uploaded = 'unknown'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $result = $ecmfile->create($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + $result = $ecmfile->create($user); + } + if ($backtourl) { header("Location: ".$backtourl); @@ -197,7 +275,7 @@ llxHeader($head, $langs->trans("Image"), '', '', 0, 0, array('/includes/jquery/p print load_fiche_titre($langs->trans("ImageEditor")); -$infoarray=dol_getImageSize($dir."/".urldecode($_GET["file"])); +$infoarray=dol_getImageSize($dir."/".GETPOST("file")); $height=$infoarray['height']; $width=$infoarray['width']; print $langs->trans("CurrentInformationOnImage").': '; @@ -218,7 +296,8 @@ print ''.$langs->trans("Resize").''; print $langs->trans("ResizeDesc").'
'; print $langs->trans("NewLength").': px   '.$langs->trans("or").'   '; print $langs->trans("NewHeight").': px  
'; -print ''; + +print ''; print ''; print ''; print ''; @@ -240,7 +319,7 @@ print '
'."\n"; if (! empty($conf->use_javascript_ajax)) { - $infoarray=dol_getImageSize($dir."/".urldecode($_GET["file"])); + $infoarray=dol_getImageSize($dir."/".GETPOST("file")); $height=$infoarray['height']; $width=$infoarray['width']; $widthforcrop=$width; $refsizeforcrop='orig'; $ratioforcrop=1; @@ -260,7 +339,7 @@ if (! empty($conf->use_javascript_ajax)) print ''; print ''; print '
'; - print '
+ print '
'.$langs->trans("NewSizeAfterCropping").': @@ -271,13 +350,13 @@ if (! empty($conf->use_javascript_ajax))
- + - + - - + +
  diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index 123fcef662c..c970631f907 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -17,16 +17,16 @@ * * Javascript code to activate drag and drop on lines * You can use this if you want to be abale to drag and drop rows of a table. - * You must add id="tablelines" on table level tag and have count($object->lines) or count($taskarray) > 0 + * You must add id="tablelines" on table level tag and have ($nboflines or count($object->lines) or count($taskarray) > 0) */ ?> - + id; $fk_element=$object->fk_element; -$table_element_line=$object->table_element_line; -$nboflines=(isset($object->lines)?count($object->lines):(isset($tasksarray)?count($tasksarray):0)); +$table_element_line=(empty($table_element_line)?$object->table_element_line:$table_element_line); +$nboflines=(isset($object->lines)?count($object->lines):(isset($tasksarray)?count($tasksarray):(empty($nboflines)?0:$nboflines))); $forcereloadpage=empty($conf->global->MAIN_FORCE_RELOAD_PAGE)?0:1; $tagidfortablednd=(empty($tagidfortablednd)?'tablelines':$tagidfortablednd); @@ -43,6 +43,7 @@ $(document).ready(function(){ $("#").tableDnD({ onDrop: function(table, row) { var reloadpage = ""; + console.log($("#").tableDnDSerialize()); var roworder = cleanSerialize($("#").tableDnDSerialize()); var table_element_line = ""; var fk_element = ""; diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index a28f46f58f2..c4e2dbc89f9 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -72,6 +72,9 @@ $formfile->form_attach_new_file( $savingdocmask ); +$disablemove=1; +if ($modulepart == 'produit') $disablemove=0; + // List of document $formfile->list_of_documents( $filearray, @@ -90,7 +93,8 @@ $formfile->list_of_documents( $permtoedit, $upload_dir, $sortfield, - $sortorder + $sortorder, + $disablemove ); print "
"; diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 0e1885fa62f..ffe354fd5bf 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -55,7 +55,7 @@ class EcmFiles //extends CommonObject public $keywords; public $cover; public $position; - public $gen_or_uploaded; + public $gen_or_uploaded; // can be 'generated', 'uploaded', 'unknown' public $extraparams; public $date_c = ''; public $date_m = ''; @@ -474,7 +474,6 @@ class EcmFiles //extends CommonObject $this->acl = trim($this->acl); } - // Check parameters // Put here code to add a control on parameters values @@ -493,9 +492,9 @@ class EcmFiles //extends CommonObject $sql .= ' gen_or_uploaded = '.(isset($this->gen_or_uploaded)?"'".$this->db->escape($this->gen_or_uploaded)."'":"null").','; $sql .= ' extraparams = '.(isset($this->extraparams)?"'".$this->db->escape($this->extraparams)."'":"null").','; $sql .= ' date_c = '.(! isset($this->date_c) || dol_strlen($this->date_c) != 0 ? "'".$this->db->idate($this->date_c)."'" : 'null').','; - $sql .= ' date_m = '.(! isset($this->date_m) || dol_strlen($this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; + //$sql .= ' date_m = '.(! isset($this->date_m) || dol_strlen($this->date_m) != 0 ? "'".$this->db->idate($this->date_m)."'" : 'null').','; // Field automatically updated $sql .= ' fk_user_c = '.(isset($this->fk_user_c)?$this->fk_user_c:"null").','; - $sql .= ' fk_user_m = '.(isset($this->fk_user_m)?$this->fk_user_m:"null").','; + $sql .= ' fk_user_m = '.($this->fk_user_m > 0?$this->fk_user_m:$user->id).','; $sql .= ' acl = '.(isset($this->acl)?"'".$this->db->escape($this->acl)."'":"null"); $sql .= ' WHERE rowid=' . $this->id; diff --git a/htdocs/product/document.php b/htdocs/product/document.php index 2e241d9c156..07381787cb6 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -192,7 +192,7 @@ if ($object->id) $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - + // Construit liste des fichiers $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); From 26098082d009f39a91959df869fbe87584ba3b4f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 20 Dec 2016 22:14:27 +0100 Subject: [PATCH 11/75] NEW Uploaded files are indexed into database --- htdocs/core/class/html.formfile.class.php | 40 ++++++++++++++++++++--- htdocs/core/lib/files.lib.php | 1 - htdocs/core/tpl/ajaxrow.tpl.php | 5 ++- htdocs/ecm/class/ecmfiles.class.php | 3 +- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index a82024d86cf..1e07f5c2b0a 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -997,11 +997,41 @@ class FormFile $filearray[$key]['position']=999999; // File not indexed are at end. So if we add a file, it will not replace an existing position $filearray[$key]['cover']=0; $filearray[$key]['acl']=''; - $filearray[$key]['rowid']=0; - // TODO Add entry into database - - //... - + + $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filearray[$key]['fullname']); + if (! preg_match('/(\/temp\/|\/thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file + { + dol_syslog("list_of_documents We found a file not indexed into database. We add it"); + include DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($this->db); + + // Add entry into database + $filename = basename($rel_filename); + $rel_dir = dirname($rel_filename); + $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); + $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); + + $ecmfile->filepath = $rel_dir; + $ecmfile->filename = $filename; + $ecmfile->label = md5_file(dol_osencode($filearray[$key]['fullname'])); // $destfile is a full path to file + $ecmfile->fullpath_orig = $filearray[$key]['fullname']; + $ecmfile->gen_or_uploaded = 'unknown'; + $ecmfile->description = ''; // indexed content + $ecmfile->keyword = ''; // keyword content + $result = $ecmfile->create($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + else + { + $filearray[$key]['rowid']=$result; + } + } + else + { + $filearray[$key]['rowid']=0; // Should not happened + } } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index a4273644fdf..8b338f8aea1 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -652,7 +652,6 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1) { setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); } - $result = $ecmfile->create($user); } elseif ($result < 0) { diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index c970631f907..d0a7b45efea 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -29,6 +29,7 @@ $table_element_line=(empty($table_element_line)?$object->table_element_line:$tab $nboflines=(isset($object->lines)?count($object->lines):(isset($tasksarray)?count($tasksarray):(empty($nboflines)?0:$nboflines))); $forcereloadpage=empty($conf->global->MAIN_FORCE_RELOAD_PAGE)?0:1; $tagidfortablednd=(empty($tagidfortablednd)?'tablelines':$tagidfortablednd); +$filepath=(empty($filepath)?'':$filepath); if (GETPOST('action') != 'editline' && $nboflines > 1) { ?>