From 081be37787e745c96f5806237a511766522d0bc7 Mon Sep 17 00:00:00 2001 From: moreauf Date: Mon, 14 Nov 2016 19:25:50 +0100 Subject: [PATCH 001/137] NEW: Add project and Hook to Loan BUG: Correct discard_closed parametters management in project --- htdocs/core/class/html.formprojet.class.php | 2 +- .../install/mysql/migration/4.0.0-5.0.0.sql | 2 +- htdocs/install/mysql/tables/llx_loan.sql | 3 +- htdocs/loan/card.php | 320 ++++++++++-------- htdocs/loan/class/loan.class.php | 9 +- htdocs/projet/ajax/projects.php | 3 +- 6 files changed, 198 insertions(+), 141 deletions(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 1112d34d13f..ddc26d0bb91 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -79,7 +79,7 @@ class FormProjets $project->fetch($selected); $selected_input_value=$project->ref; } - $urloption='socid='.$socid.'&htmlname='.$htmlname; + $urloption='socid='.$socid.'&htmlname='.$htmlname.'&discardclosed='.$discard_closed; $out.=ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array( // 'update' => array( // 'projectid' => 'id' diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql index fb862457b45..76aa7d85928 100644 --- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql +++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql @@ -221,4 +221,4 @@ drop table tmp_links_double; ALTER TABLE llx_links ADD UNIQUE INDEX uk_links (objectid,label); - +ALTER TABLE llx_loan ADD COLUMN fk_project integer DEFAULT NULL; diff --git a/htdocs/install/mysql/tables/llx_loan.sql b/htdocs/install/mysql/tables/llx_loan.sql index 6fd3c0d2099..64d1de5dc29 100644 --- a/htdocs/install/mysql/tables/llx_loan.sql +++ b/htdocs/install/mysql/tables/llx_loan.sql @@ -47,5 +47,6 @@ create table llx_loan fk_user_author integer DEFAULT NULL, fk_user_modif integer DEFAULT NULL, - active tinyint DEFAULT 1 NOT NULL + active tinyint DEFAULT 1 NOT NULL, + fk_project integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 0894447d485..b24f9c75253 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -28,6 +28,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/html.formventilation.class.php'; +if (! empty($conf->projet->enabled)) +{ + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} $langs->load("compta"); $langs->load("bills"); @@ -45,134 +50,143 @@ $result = restrictedArea($user, 'loan', $id, '',''); $object = new Loan($db); +$hookmanager->initHooks(array('loancard','globalcard')); + /* * Actions */ -// Classify paid -if ($action == 'confirm_paid' && $confirm == 'yes') -{ - $object->fetch($id); - $result = $object->set_paid($user); - if ($result > 0) - { - setEventMessages($langs->trans('LoanPaid'), null, 'mesgs'); - } - else - { - setEventMessages($loan->error, null, 'errors'); - } -} +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -// Delete loan -if ($action == 'confirm_delete' && $confirm == 'yes') +if (empty($reshook)) { - $object->fetch($id); - $result=$object->delete($user); - if ($result > 0) + // Classify paid + if ($action == 'confirm_paid' && $confirm == 'yes') { - setEventMessages($langs->trans('LoanDeleted'), null, 'mesgs'); - header("Location: index.php"); - exit; + $object->fetch($id); + $result = $object->set_paid($user); + if ($result > 0) + { + setEventMessages($langs->trans('LoanPaid'), null, 'mesgs'); + } + else + { + setEventMessages($loan->error, null, 'errors'); + } } - else - { - setEventMessages($loan->error, null, 'errors'); - } -} -// Add loan -if ($action == 'add' && $user->rights->loan->write) -{ - if (! $cancel) + // Delete loan + if ($action == 'confirm_delete' && $confirm == 'yes') { - $datestart=@dol_mktime(12,0,0, $_POST["startmonth"], $_POST["startday"], $_POST["startyear"]); - $dateend=@dol_mktime(12,0,0, $_POST["endmonth"], $_POST["endday"], $_POST["endyear"]); - - if (! $datestart) + $object->fetch($id); + $result=$object->delete($user); + if ($result > 0) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateStart")), null, 'errors'); - $action = 'create'; - } - elseif (! $dateend) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateEnd")), null, 'errors'); - $action = 'create'; - } - elseif (! $_POST["capital"]) - { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("LoanCapital")), null, 'errors'); - $action = 'create'; + setEventMessages($langs->trans('LoanDeleted'), null, 'mesgs'); + header("Location: index.php"); + exit; } else { - $object->label = $_POST["label"]; - $object->fk_bank = $_POST["accountid"]; - $object->capital = $_POST["capital"]; - $object->datestart = $datestart; - $object->dateend = $dateend; - $object->nbterm = $_POST["nbterm"]; - $object->rate = $_POST["rate"]; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + setEventMessages($loan->error, null, 'errors'); + } + } - $accountancy_account_capital = GETPOST('accountancy_account_capital'); - $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); - $accountancy_account_interest = GETPOST('accountancy_account_interest'); + // Add loan + if ($action == 'add' && $user->rights->loan->write) + { + if (! $cancel) + { + $datestart=@dol_mktime(12,0,0, $_POST["startmonth"], $_POST["startday"], $_POST["startyear"]); + $dateend=@dol_mktime(12,0,0, $_POST["endmonth"], $_POST["endday"], $_POST["endyear"]); - if ($accountancy_account_capital <= 0) { $object->account_capital = ''; } else { $object->account_capital = $accountancy_account_capital; } - if ($accountancy_account_insurance <= 0) { $object->account_insurance = ''; } else { $object->account_insurance = $accountancy_account_insurance; } - if ($accountancy_account_interest <= 0) { $object->account_interest = ''; } else { $object->account_interest = $accountancy_account_interest; } - - $id=$object->create($user); - if ($id <= 0) + if (! $datestart) { - setEventMessages($object->error, $object->errors, 'errors'); + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateStart")), null, 'errors'); + $action = 'create'; + } + elseif (! $dateend) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DateEnd")), null, 'errors'); + $action = 'create'; + } + elseif (! $_POST["capital"]) + { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("LoanCapital")), null, 'errors'); + $action = 'create'; + } + else + { + $object->label = $_POST["label"]; + $object->fk_bank = $_POST["accountid"]; + $object->capital = $_POST["capital"]; + $object->datestart = $datestart; + $object->dateend = $dateend; + $object->nbterm = $_POST["nbterm"]; + $object->rate = $_POST["rate"]; + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); + $object->fk_project = GETPOST('fk_project'); + + $accountancy_account_capital = GETPOST('accountancy_account_capital'); + $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); + $accountancy_account_interest = GETPOST('accountancy_account_interest'); + + if ($accountancy_account_capital <= 0) { $object->account_capital = ''; } else { $object->account_capital = $accountancy_account_capital; } + if ($accountancy_account_insurance <= 0) { $object->account_insurance = ''; } else { $object->account_insurance = $accountancy_account_insurance; } + if ($accountancy_account_interest <= 0) { $object->account_interest = ''; } else { $object->account_interest = $accountancy_account_interest; } + + $id=$object->create($user); + if ($id <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } } } - } - else - { - header("Location: index.php"); - exit(); - } -} - -// Update record -else if ($action == 'update' && $user->rights->loan->write) -{ - if (! $cancel) - { - $result = $object->fetch($id); - - if ($object->fetch($id)) + else { - $object->label = GETPOST("label"); - $object->datestart = dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int')); - $object->dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); - $object->nbterm = GETPOST("nbterm"); - $object->rate = GETPOST("rate"); + header("Location: index.php"); + exit(); } + } - $result = $object->update($user); + // Update record + else if ($action == 'update' && $user->rights->loan->write) + { + if (! $cancel) + { + $result = $object->fetch($id); - if ($result > 0) - { - header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); - exit; - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - } - } - else - { - header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); - exit; - } + if ($object->fetch($id)) + { + $object->label = GETPOST("label"); + $object->datestart = dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int')); + $object->dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); + $object->nbterm = GETPOST("nbterm"); + $object->rate = GETPOST("rate"); + $object->fk_project = GETPOST("fk_project"); + } + + $result = $object->update($user); + + if ($result > 0) + { + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + else + { + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit; + } + } } - /* * View */ @@ -240,6 +254,20 @@ if ($action == 'create') // Rate print ''.$langs->trans("Rate").' %'; + // Project + if (! empty($conf->projet->enabled)) + { + $formproject=new FormProjets($db); + + // Projet associe + $langs->load("projects"); + + print ''.$langs->trans("Project").''; + + $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1); + + print ''; + } // Note Private print ''; print ''.$langs->trans('NotePrivate').''; @@ -283,8 +311,8 @@ if ($action == 'create') print ''; print $formaccountancy->select_account($object->accountancy_account_interest, 'accountancy_account_interest', 1, '', 0, 1); print ''; - } - else // For external software + } + else // For external software { // Accountancy_account_capital print ''.$langs->trans("LoanAccountancyCapitalCode").''; @@ -300,11 +328,11 @@ if ($action == 'create') print ''.$langs->trans("LoanAccountancyInterestCode").''; print ''; print ''; - + print ''; } print ''; - + dol_fiche_end(); print '
     '; @@ -438,6 +466,23 @@ if ($id > 0) } print ''; + // projet + if (! empty($conf->projet->enabled)){ + print ''; + print $langs->trans("Project"); + print ''; + if ($action == 'edit') { + $formproject=new FormProjets($db); + $numproject=$formproject->select_projects(-1,$object->fk_project,'fk_project',16,0,1,1); + + } else { + $project=new Project($db); + $project->fetch($object->fk_project); + print $project->getNomUrl(1,'',1);; + } + print ''; + } + // Status print ''.$langs->trans("Status").''.$object->getLibStatut(4, $totalpaye).''; @@ -445,7 +490,7 @@ if ($id > 0) dol_fiche_end(); - + if ($action == 'edit') { print '
'; @@ -455,7 +500,7 @@ if ($id > 0) print '
'; print '

'; } - + print ''; print ''; } @@ -473,11 +473,11 @@ if ($id > 0) print ''; diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index 8ed6e682ce6..ac0062d3ed9 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -50,7 +50,7 @@ class Loan extends CommonObject var $fk_bank; var $fk_user_creat; var $fk_user_modif; - var $fk_project; + var $fk_projet; /** @@ -73,7 +73,7 @@ class Loan extends CommonObject function fetch($id) { $sql = "SELECT l.rowid, l.label, l.capital, l.datestart, l.dateend, l.nbterm, l.rate, l.note_private, l.note_public,"; - $sql.= " l.paid, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest,l.fk_project"; + $sql.= " l.paid, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest,l.fk_projet"; $sql.= " FROM ".MAIN_DB_PREFIX."loan as l"; $sql.= " WHERE l.rowid = ".$id; @@ -100,7 +100,7 @@ class Loan extends CommonObject $this->account_capital = $obj->accountancy_account_capital; $this->account_insurance = $obj->accountancy_account_insurance; $this->account_interest = $obj->accountancy_account_interest; - $this->fk_project = $obj->fk_project; + $this->fk_projet = $obj->fk_projet; $this->db->free($resql); return 1; @@ -128,7 +128,7 @@ class Loan extends CommonObject function create($user) { global $conf; - + $error=0; $now=dol_now(); @@ -143,7 +143,7 @@ class Loan extends CommonObject if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank); if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat); if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif); - if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); + if (isset($this->fk_projet)) $this->fk_projet=trim($this->fk_projet); // Check parameters if (! $newcapital > 0 || empty($this->datestart) || empty($this->dateend)) @@ -161,7 +161,7 @@ class Loan extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."loan (label, fk_bank, capital, datestart, dateend, nbterm, rate, note_private, note_public"; $sql.= " ,accountancy_account_capital, accountancy_account_insurance, accountancy_account_interest, entity"; - $sql.= " ,datec,fk_project,fk_user_author)"; + $sql.= " ,datec,fk_projet,fk_user_author)"; $sql.= " VALUES ('".$this->db->escape($this->label)."',"; $sql.= " '".$this->db->escape($this->fk_bank)."',"; $sql.= " '".price2num($newcapital)."',"; @@ -176,7 +176,7 @@ class Loan extends CommonObject $sql.= " '".$this->db->escape($this->account_interest)."',"; $sql.= " ".$conf->entity.","; $sql.= " '".$this->db->idate($now)."',"; - $sql.= " '".$this->fk_project."',"; + $sql.= " ".(empty($this->fk_projet)?'NULL':$this->fk_projet).","; $sql.= " ".$user->id; $sql.= ")"; @@ -284,7 +284,7 @@ class Loan extends CommonObject $sql.= " SET label='".$this->db->escape($this->label)."',"; $sql.= " datestart='".$this->db->idate($this->datestart)."',"; $sql.= " dateend='".$this->db->idate($this->dateend)."',"; - $sql.= " fk_project='".$this->db->escape($this->fk_project)."',"; + $sql.= " fk_projet=".(empty($this->fk_projet)?'NULL':$this->fk_projet).","; $sql.= " fk_user_modif = ".$user->id; $sql.= " WHERE rowid=".$this->id; @@ -348,7 +348,7 @@ class Loan extends CommonObject global $langs; $langs->load('customers'); $langs->load('bills'); - + if ($mode == 0) { if ($statut == 0) return $langs->trans("Unpaid"); diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 958f0b242a2..9abcc1d0771 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -47,6 +47,7 @@ if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compt if (! empty($conf->expensereport->enabled)) require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; if (! empty($conf->don->enabled)) require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; +if (! empty($conf->loan->enabled)) require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; $langs->load("projects"); $langs->load("companies"); @@ -58,6 +59,7 @@ if (! empty($conf->ficheinter->enabled)) $langs->load("interventions"); if (! empty($conf->deplacement->enabled)) $langs->load("trips"); if (! empty($conf->expensereport->enabled)) $langs->load("trips"); if (! empty($conf->don->enabled)) $langs->load("donations"); +if (! empty($conf->loan->enabled)) $langs->load("loan"); $id=GETPOST('id','int'); $ref=GETPOST('ref','alpha'); @@ -370,6 +372,19 @@ $listofreferent=array( 'buttonnew'=>'AddDonation', 'testnew'=>$user->rights->don->creer, 'test'=>$conf->don->enabled && $user->rights->don->lire), +'loan'=>array( + 'name'=>"Loan", + 'title'=>"ListLoanAssociatedProject", + 'class'=>'Loan', + 'margin'=>'add', + 'table'=>'Loan', + 'datefieldname'=>'datestart', + 'disableamount'=>0, + 'urlnew'=>DOL_URL_ROOT.'/loan/card.php?action=create&projectid='.$id.'&socid='.$socid, + 'lang'=>'loan', + 'buttonnew'=>'AddLoan', + 'testnew'=>$user->rights->loan->creer, + 'test'=>$conf->loan->enabled && $user->rights->loan->lire), 'agenda'=>array( 'name'=>"Agenda", 'title'=>"ListActionsAssociatedProject", @@ -397,9 +412,9 @@ $parameters=array('listofreferent'=>$listofreferent); $resHook = $hookmanager->executeHooks('completeListOfReferent',$parameters,$object,$action); if(!empty($hookmanager->resArray)) { - + $listofreferent = array_merge($listofreferent, $hookmanager->resArray); - + } if ($action=="addelement") @@ -490,7 +505,7 @@ foreach ($listofreferent as $key => $value) $element = new $classname($db); $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee); - + if (count($elementarray)>0 && is_array($elementarray)) { $total_ht = 0; @@ -506,7 +521,7 @@ foreach ($listofreferent as $key => $value) $element->fetch($idofelement); if ($idofelementuser) $elementuser->fetch($idofelementuser); - // Special cases + // Special cases if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) $element->fetch_thirdparty(); if ($tablename == 'don') $total_ht_by_line=$element->amount; elseif ($tablename == 'projet_task') @@ -529,7 +544,7 @@ foreach ($listofreferent as $key => $value) { if (! empty($element->close_code) && $element->close_code == 'replaced') $qualifiedfortotal=false; // Replacement invoice, do not include into total } - + if ($qualifiedfortotal) $total_ht = $total_ht + $total_ht_by_line; if ($tablename == 'don') $total_ttc_by_line=$element->amount; @@ -795,7 +810,7 @@ foreach ($listofreferent as $key => $value) print ' - '.dol_trunc($element->label, 48); } else print $element->getNomUrl(1); - + $element_doc = $element->element; $filename=dol_sanitizeFileName($element->ref); $filedir=$conf->{$element_doc}->dir_output . '/' . dol_sanitizeFileName($element->ref); @@ -811,7 +826,7 @@ foreach ($listofreferent as $key => $value) } print '
'.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'
'; - + // Show supplier ref if (! empty($element->ref_supplier)) print ' - '.$element->ref_supplier; // Show customer ref @@ -826,7 +841,7 @@ foreach ($listofreferent as $key => $value) elseif (! empty($element->status) || ! empty($element->statut) || ! empty($element->fk_status)) { if ($tablename=='don') $date = $element->datedon; - if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') + if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') { $date=($element->date_commande?$element->date_commande:$element->date_valid); } From ff734bb5d9379f5ca42b105783df5e0589a11a09 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Wed, 16 Nov 2016 09:40:29 +0100 Subject: [PATCH 003/137] Fix travis --- htdocs/core/lib/functions.lib.php | 144 +++++++++++++++--------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 677b619bd02..e535dd9f928 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -191,7 +191,7 @@ function getBrowserInfo($user_agent) elseif (preg_match('/opera(\/|\s)([\d\.]*)/i', $user_agent, $reg)) { $name='opera'; $version=$reg[2]; } elseif (preg_match('/(MSIE\s([0-9]+\.[0-9]))|.*(Trident\/[0-9]+.[0-9];\srv:([0-9]+\.[0-9]+))/i', $user_agent, $reg)) { $name='ie'; $version=end($reg); } // MS products at end elseif (preg_match('/l(i|y)n(x|ks)(\(|\/|\s)*([\d\.]+)/i', $user_agent, $reg)) { $name='lynxlinks'; $version=$reg[4]; } - + if ($tablet) { $layout = 'tablet'; } elseif ($phone) { @@ -256,14 +256,14 @@ function GETPOST($paramname,$check='',$method=0,$filter=NULL,$options=NULL) { $tmp=dol_getdate(dol_now(), true); $out = $tmp['mon']; - } + } elseif ($reg[1] == 'YEAR') { $tmp=dol_getdate(dol_now(), true); $out = $tmp['year']; } } - + switch ($check) { case 'int': @@ -387,15 +387,15 @@ function dol_buildpath($path, $type=0) if ($type == 1) $res = DOL_URL_ROOT.'/'.$path; // Standard value if ($type == 2) $res = DOL_MAIN_URL_ROOT.'/'.$path; // Standard value if ($type == 3) $res = DOL_URL_ROOT.'/'.$path; - + foreach ($conf->file->dol_document_root as $key => $dirroot) // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...) { - if ($key == 'main') + if ($key == 'main') { if ($type == 3) { global $dolibarr_main_url_root; - + // Define $urlwithroot $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file @@ -422,12 +422,12 @@ function dol_buildpath($path, $type=0) if ($type == 3) { global $dolibarr_main_url_root; - + // Define $urlwithroot $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - + $res=(preg_match('/^http/i',$conf->file->dol_url_root[$key])?'':$urlwithroot).$conf->file->dol_url_root[$key].'/'.$path; // Test on start with http is for old conf syntax } break; @@ -693,13 +693,13 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename=' throw new Exception('Incorrect log level'); } if ($level > $conf->global->SYSLOG_LEVEL) return; - + // If adding log inside HTML page is required if (! empty($_REQUEST['logtohtml']) && (! empty($conf->global->MAIN_ENABLE_LOG_TO_HTML) || ! empty($conf->global->MAIN_LOGTOHTML))) // MAIN_LOGTOHTML kept for backward compatibility { $conf->logbuffer[] = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; } - + //TODO: Remove this. MAIN_ENABLE_LOG_INLINE_HTML should be deprecated and use a log handler dedicated to HTML output // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments if (! empty($conf->global->MAIN_ENABLE_LOG_INLINE_HTML) && ! empty($_GET["log"])) @@ -708,7 +708,7 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename=' print $message."\n"; print "Log end -->\n"; } - + $data = array( 'message' => $message, 'script' => (isset($_SERVER['PHP_SELF'])? basename($_SERVER['PHP_SELF'],'.php') : false), @@ -716,7 +716,7 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename=' 'user' => ((is_object($user) && $user->id) ? $user->login : false), 'ip' => false ); - + if (! empty($_SERVER["REMOTE_ADDR"])) $data['ip'] = $_SERVER['REMOTE_ADDR']; // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) else if (! empty($_SERVER['SERVER_ADDR'])) $data['ip'] = $_SERVER['SERVER_ADDR']; @@ -903,7 +903,7 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi { $out = $hookmanager->resPrint; } - + return $out; } @@ -944,8 +944,8 @@ function dol_get_fiche_end($notab=0) * @param int $nodbprefix Do not include DB prefix to forge table name * @param string $morehtmlleft More html code to show before ref * @param string $morehtmlstatus More html code to show under navigation arrows - * @param string $morehtmlright More html code to show before navigation arrows * @param int $onlybanner Put this to 1, if the card will contains only a banner + * @param string $morehtmlright More html code to show before navigation arrows * @return void */ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='') @@ -962,7 +962,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if ($object->element == 'member') $modulepart='memberphoto'; if ($object->element == 'user') $modulepart='userphoto'; if ($object->element == 'product') $modulepart='product'; - + if ($object->element == 'product') { $width=80; $cssclass='photoref'; @@ -970,7 +970,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $maxvisiblephotos=(isset($conf->global->PRODUCT_MAX_VISIBLE_PHOTO)?$conf->global->PRODUCT_MAX_VISIBLE_PHOTO:5); if ($conf->browser->phone) $maxvisiblephotos=1; if ($showimage) $morehtmlleft.='
'.$object->show_photos($conf->product->multidir_output[$object->entity],'small',$maxvisiblephotos,0,0,0,$width,0).'
'; - else + else { if (!empty($conf->global->PRODUCT_NODISPLAYIFNOPHOTO)) { $nophoto=''; @@ -980,14 +980,14 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $nophoto='/public/theme/common/nophoto.png'; $morehtmlleft.='
No photo
'; } - + } } - else + else { - if ($showimage) + if ($showimage) { - if ($modulepart != 'unknown') + if ($modulepart != 'unknown') { $phototoshow = $form->showphoto($modulepart,$object,0,0,0,'photoref','small',1,0,$maxvisiblephotos); if ($phototoshow) @@ -1000,7 +1000,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r elseif ($conf->browser->layout != 'phone') // Show no photo link { $morehtmlleft.='
'; - if ($object->element == 'action') + if ($object->element == 'action') { $cssclass='photorefcenter'; $nophoto=img_picto('', 'title_agenda', '', false, 1); @@ -1019,7 +1019,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if ($showbarcode) $morehtmlleft.='
'.$form->showbarcode($object).'
'; if ($object->element == 'societe' && ! empty($conf->use_javascript_ajax) && $user->rights->societe->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) { $morehtmlstatus.=ajax_object_onoff($object, 'status', 'status', 'InActivity', 'ActivityCeased'); - } + } elseif ($object->element == 'product') { //$morehtmlstatus.=$langs->trans("Status").' ('.$langs->trans("Sell").') '; @@ -1039,21 +1039,21 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r elseif ($object->element == 'facture' || $object->element == 'invoice' || $object->element == 'invoice_supplier') { $tmptxt=$object->getLibStatut(6, $object->totalpaye); - if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || $conf->browser->layout=='phone') $tmptxt=$object->getLibStatut(5, $object->totalpaye); + if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || $conf->browser->layout=='phone') $tmptxt=$object->getLibStatut(5, $object->totalpaye); $morehtmlstatus.=$tmptxt; } - elseif ($object->element == 'facturerec') + elseif ($object->element == 'facturerec') { $morehtmlstatus.=''; } else { // Generic case $tmptxt=$object->getLibStatut(6); - if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || $conf->browser->layout=='phone') $tmptxt=$object->getLibStatut(5); + if (empty($tmptxt) || $tmptxt == $object->getLibStatut(3) || $conf->browser->layout=='phone') $tmptxt=$object->getLibStatut(5); $morehtmlstatus.=$tmptxt; } if (! empty($object->name_alias)) $morehtmlref.='
'.$object->name_alias.'
'; // For thirdparty if (! empty($object->label)) $morehtmlref.='
'.$object->label.'
'; // For product - if ($object->element != 'product') + if ($object->element != 'product') { $morehtmlref.='
'; $morehtmlref.=$object->getBannerAddress('refaddress',$object); @@ -1065,7 +1065,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $morehtmlref.=$langs->trans("TechnicalID").': '.$object->id; $morehtmlref.='
'; } - + print '
'; print $form->showrefnav($object, $paramid, $morehtml, $shownav, $fieldid, $fieldref, $morehtmlref, $moreparam, $nodbprefix, $morehtmlleft, $morehtmlstatus, $morehtmlright); print '
'; @@ -1240,9 +1240,9 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e $reduceformat=(! empty($conf->dol_optimize_smallscreen) && in_array($format,array('day','dayhour')))?1:0; $formatwithoutreduce = preg_replace('/reduceformat/','',$format); if ($formatwithoutreduce != $format) { $format = $formatwithoutreduce; $reduceformat=1; } // so format 'dayreduceformat' is processed like day - + // Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default. - // TODO Add format daysmallyear and dayhoursmallyear + // TODO Add format daysmallyear and dayhoursmallyear if ($format == 'day') $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short); else if ($format == 'hour') $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short); else if ($format == 'hourduration') $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration); @@ -1744,7 +1744,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone=($separ!=''?'(':'').substr($newphone,0,3).($separ!=''?')':'').$separ.substr($newphone,3,3).($separ!=''?'-':'').substr($newphone,6,4); } } - + if (! empty($addlink)) // Link on phone number (+ link to add action if conf->global->AGENDA_ADDACTIONFORPHONE set) { if (! empty($conf->browser->phone) || (! empty($conf->clicktodial->enabled) && ! empty($conf->global->CLICKTODIAL_USE_TEL_LINK_ON_PHONE_NUMBERS))) // If phone or option for, we use link of phone @@ -1874,7 +1874,7 @@ function dol_user_country() * @param int $mode thirdparty|contact|member|other * @param int $id Id of object * @param int $noprint No output. Result is the function return - * @param string $charfornl Char to use instead of nl2br. '' means we use a standad nl2br. + * @param string $charfornl Char to use instead of nl2br. '' means we use a standad nl2br. * @return string|void Nothing if noprint is 0, formatted address if noprint is 1 * @see dol_format_address */ @@ -1895,7 +1895,7 @@ function dol_print_address($address, $htmlid, $mode, $id, $noprint=0, $charfornl { if (empty($charfornl)) $out.=nl2br($address); else $out.=preg_replace('/[\r\n]+/', $charfornl, $address); - + $showgmap=$showomap=0; // TODO Add a hook here @@ -2023,7 +2023,7 @@ function dol_print_graph($htmlid,$width,$height,$data,$showlegend=0,$type='pie', print '
'.$langs->trans("NotEnoughDataYet").'
'; return; } - + if (empty($conf->use_javascript_ajax)) return; $jsgraphlib='flot'; $datacolor=array(); @@ -2192,7 +2192,7 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo global $conf; if ($size==0 || ! empty($conf->global->MAIN_DISABLE_TRUNC)) return $string; - + if (empty($stringencoding)) $stringencoding='UTF-8'; // reduce for small screen if ($conf->dol_optimize_smallscreen==1 && $display==1) $size = round($size/3); @@ -3144,7 +3144,7 @@ function load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', * @param string $options More parameters for links ('' by default, does not include sortfield neither sortorder) * @param string $sortfield Field to sort on ('' by default) * @param string $sortorder Order to sort ('' by default) - * @param string $center Strin gin the middle ('' by default). We often find here string $massaction comming from $form->selectMassAction() + * @param string $center Strin gin the middle ('' by default). We often find here string $massaction comming from $form->selectMassAction() * @param int $num Number of records found by select with limit+1 * @param int $totalnboflines Total number of records/lines for all pages (if known). Use a negative value to not show number. * @param string $picto Icon to use before title (should be a 32x32 transparent png file) @@ -3158,11 +3158,11 @@ function load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines=0, $picto='title_generic.png', $pictoisfullpath=0, $morehtml='', $morecss='', $limit=-1, $hideselectlimit=0) { global $conf,$langs; - + $savlimit = $limit; $savtotalnboflines = $totalnboflines; $totalnboflines=abs($totalnboflines); - + if ($picto == 'setup') $picto='title_setup.png'; if (($conf->browser->name == 'ie') && $picto=='title_generic.png') $picto='title.gif'; if ($limit < 0) $limit = $conf->liste_limit; @@ -3175,7 +3175,7 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so $nextpage = 0; } //print 'totalnboflines='.$totalnboflines.'-savlimit='.$savlimit.'-limit='.$limit.'-num='.$num.'-nextpage='.$nextpage; - + print "\n"; print "\n"; print '
'; @@ -537,33 +582,38 @@ if ($id > 0) */ if ($action != 'edit') { - print '
'; + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if (empty($reshook)) + { + print '
'; - // Edit - if ($user->rights->loan->write) - { - print ''.$langs->trans("Modify").''; + // Edit + if ($user->rights->loan->write) + { + print ''.$langs->trans("Modify").''; + } + + // Emit payment + if ($object->paid == 0 && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write) + { + print ''.$langs->trans("DoPayment").''; + } + + // Classify 'paid' + if ($object->paid == 0 && round($staytopay) <=0 && $user->rights->loan->write) + { + print ''.$langs->trans("ClassifyPaid").''; + } + + // Delete + if ($user->rights->loan->delete) + { + print ''.$langs->trans("Delete").''; + } + + print "
"; } - - // Emit payment - if ($object->paid == 0 && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write) - { - print ''.$langs->trans("DoPayment").''; - } - - // Classify 'paid' - if ($object->paid == 0 && round($staytopay) <=0 && $user->rights->loan->write) - { - print ''.$langs->trans("ClassifyPaid").''; - } - - // Delete - if ($user->rights->loan->delete) - { - print ''.$langs->trans("Delete").''; - } - - print "
"; } } else diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index 5c57764bf97..8ed6e682ce6 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -50,6 +50,7 @@ class Loan extends CommonObject var $fk_bank; var $fk_user_creat; var $fk_user_modif; + var $fk_project; /** @@ -72,7 +73,7 @@ class Loan extends CommonObject function fetch($id) { $sql = "SELECT l.rowid, l.label, l.capital, l.datestart, l.dateend, l.nbterm, l.rate, l.note_private, l.note_public,"; - $sql.= " l.paid, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest"; + $sql.= " l.paid, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest,l.fk_project"; $sql.= " FROM ".MAIN_DB_PREFIX."loan as l"; $sql.= " WHERE l.rowid = ".$id; @@ -99,6 +100,7 @@ class Loan extends CommonObject $this->account_capital = $obj->accountancy_account_capital; $this->account_insurance = $obj->accountancy_account_insurance; $this->account_interest = $obj->accountancy_account_interest; + $this->fk_project = $obj->fk_project; $this->db->free($resql); return 1; @@ -141,6 +143,7 @@ class Loan extends CommonObject if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank); if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat); if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif); + if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); // Check parameters if (! $newcapital > 0 || empty($this->datestart) || empty($this->dateend)) @@ -158,7 +161,7 @@ class Loan extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."loan (label, fk_bank, capital, datestart, dateend, nbterm, rate, note_private, note_public"; $sql.= " ,accountancy_account_capital, accountancy_account_insurance, accountancy_account_interest, entity"; - $sql.= " ,datec, fk_user_author)"; + $sql.= " ,datec,fk_project,fk_user_author)"; $sql.= " VALUES ('".$this->db->escape($this->label)."',"; $sql.= " '".$this->db->escape($this->fk_bank)."',"; $sql.= " '".price2num($newcapital)."',"; @@ -173,6 +176,7 @@ class Loan extends CommonObject $sql.= " '".$this->db->escape($this->account_interest)."',"; $sql.= " ".$conf->entity.","; $sql.= " '".$this->db->idate($now)."',"; + $sql.= " '".$this->fk_project."',"; $sql.= " ".$user->id; $sql.= ")"; @@ -280,6 +284,7 @@ class Loan extends CommonObject $sql.= " SET label='".$this->db->escape($this->label)."',"; $sql.= " datestart='".$this->db->idate($this->datestart)."',"; $sql.= " dateend='".$this->db->idate($this->dateend)."',"; + $sql.= " fk_project='".$this->db->escape($this->fk_project)."',"; $sql.= " fk_user_modif = ".$user->id; $sql.= " WHERE rowid=".$this->id; diff --git a/htdocs/projet/ajax/projects.php b/htdocs/projet/ajax/projects.php index 55a4597dc08..3140352bf60 100644 --- a/htdocs/projet/ajax/projects.php +++ b/htdocs/projet/ajax/projects.php @@ -37,6 +37,7 @@ $htmlname=GETPOST('htmlname','alpha'); $socid=GETPOST('socid','int'); $action=GETPOST('action', 'alpha'); $id=GETPOST('id', 'int'); +$discard_closed =GETPOST('discardclosed','int'); /* @@ -63,7 +64,7 @@ if (! GETPOST($htmlname) && ! GETPOST($idprod)) return; $searchkey=(GETPOST($idprod)?GETPOST($idprod):(GETPOST($htmlname)?GETPOST($htmlname):'')); $form = new FormProjets($db); -$arrayresult=$form->select_projects_list($socid, '', $htmlname, 0, 0, 1, 0, 0, 0, 1, $searchkey); +$arrayresult=$form->select_projects_list($socid, '', $htmlname, 0, 0, 1, $discard_closed, 0, 0, 1, $searchkey); $db->close(); From a251f0df51eec143a42e23de6133a4c66e60b0d3 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Wed, 16 Nov 2016 09:38:13 +0100 Subject: [PATCH 002/137] Various fix on Loan and project link --- .../install/mysql/migration/4.0.0-5.0.0.sql | 2 +- htdocs/install/mysql/tables/llx_loan.sql | 2 +- htdocs/loan/card.php | 10 +++--- htdocs/loan/class/loan.class.php | 18 +++++------ htdocs/projet/element.php | 31 ++++++++++++++----- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql index 42f7e8fd76c..5f5581a6d48 100644 --- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql +++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql @@ -223,4 +223,4 @@ ALTER TABLE llx_links ADD UNIQUE INDEX uk_links (objectid,label); ALTER TABLE llx_c_actioncomm MODIFY COLUMN type varchar(50) DEFAULT 'system' NOT NULL; -ALTER TABLE llx_loan ADD COLUMN fk_project integer DEFAULT NULL; +ALTER TABLE llx_loan ADD COLUMN fk_projet integer DEFAULT NULL; diff --git a/htdocs/install/mysql/tables/llx_loan.sql b/htdocs/install/mysql/tables/llx_loan.sql index 64d1de5dc29..c6d8147fe47 100644 --- a/htdocs/install/mysql/tables/llx_loan.sql +++ b/htdocs/install/mysql/tables/llx_loan.sql @@ -48,5 +48,5 @@ create table llx_loan fk_user_author integer DEFAULT NULL, fk_user_modif integer DEFAULT NULL, active tinyint DEFAULT 1 NOT NULL, - fk_project integer DEFAULT NULL + fk_projet integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index b24f9c75253..8d8c938f641 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -127,7 +127,7 @@ if (empty($reshook)) $object->rate = $_POST["rate"]; $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); - $object->fk_project = GETPOST('fk_project'); + $object->fk_projet = GETPOST('fk_projet'); $accountancy_account_capital = GETPOST('accountancy_account_capital'); $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); @@ -165,7 +165,7 @@ if (empty($reshook)) $object->dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); $object->nbterm = GETPOST("nbterm"); $object->rate = GETPOST("rate"); - $object->fk_project = GETPOST("fk_project"); + $object->fk_projet = GETPOST("fk_projet"); } $result = $object->update($user); @@ -264,7 +264,7 @@ if ($action == 'create') print '
'.$langs->trans("Project").''; - $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1); + $numproject=$formproject->select_projects(-1,GETPOST("fk_projet"),'fk_projet',16,0,1,1); print '
'; if ($action == 'edit') { $formproject=new FormProjets($db); - $numproject=$formproject->select_projects(-1,$object->fk_project,'fk_project',16,0,1,1); + $numproject=$formproject->select_projects(-1,$object->fk_projet,'fk_projet',16,0,1,1); } else { $project=new Project($db); - $project->fetch($object->fk_project); + $project->fetch($object->fk_projet); print $project->getNomUrl(1,'',1);; } print '
'; @@ -3276,7 +3276,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee //$pagesizechoices.=',0:'.$langs->trans("All"); // Not yet supported //$pagesizechoices.=',2:2'; if (! empty($conf->global->MAIN_PAGESIZE_CHOICES)) $pagesizechoices=$conf->global->MAIN_PAGESIZE_CHOICES; - + print ''; } @@ -473,11 +473,11 @@ if ($id > 0) print ''; diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index ac0062d3ed9..bf6d67930ae 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -50,7 +50,7 @@ class Loan extends CommonObject var $fk_bank; var $fk_user_creat; var $fk_user_modif; - var $fk_projet; + var $fk_project; /** @@ -73,7 +73,7 @@ class Loan extends CommonObject function fetch($id) { $sql = "SELECT l.rowid, l.label, l.capital, l.datestart, l.dateend, l.nbterm, l.rate, l.note_private, l.note_public,"; - $sql.= " l.paid, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest,l.fk_projet"; + $sql.= " l.paid, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest,l.fk_project"; $sql.= " FROM ".MAIN_DB_PREFIX."loan as l"; $sql.= " WHERE l.rowid = ".$id; @@ -100,7 +100,7 @@ class Loan extends CommonObject $this->account_capital = $obj->accountancy_account_capital; $this->account_insurance = $obj->accountancy_account_insurance; $this->account_interest = $obj->accountancy_account_interest; - $this->fk_projet = $obj->fk_projet; + $this->fk_project = $obj->fk_project; $this->db->free($resql); return 1; @@ -143,7 +143,7 @@ class Loan extends CommonObject if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank); if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat); if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif); - if (isset($this->fk_projet)) $this->fk_projet=trim($this->fk_projet); + if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); // Check parameters if (! $newcapital > 0 || empty($this->datestart) || empty($this->dateend)) @@ -161,7 +161,7 @@ class Loan extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."loan (label, fk_bank, capital, datestart, dateend, nbterm, rate, note_private, note_public"; $sql.= " ,accountancy_account_capital, accountancy_account_insurance, accountancy_account_interest, entity"; - $sql.= " ,datec,fk_projet,fk_user_author)"; + $sql.= " ,datec,fk_project,fk_user_author)"; $sql.= " VALUES ('".$this->db->escape($this->label)."',"; $sql.= " '".$this->db->escape($this->fk_bank)."',"; $sql.= " '".price2num($newcapital)."',"; @@ -176,7 +176,7 @@ class Loan extends CommonObject $sql.= " '".$this->db->escape($this->account_interest)."',"; $sql.= " ".$conf->entity.","; $sql.= " '".$this->db->idate($now)."',"; - $sql.= " ".(empty($this->fk_projet)?'NULL':$this->fk_projet).","; + $sql.= " ".(empty($this->fk_project)?'NULL':$this->fk_project).","; $sql.= " ".$user->id; $sql.= ")"; @@ -284,7 +284,7 @@ class Loan extends CommonObject $sql.= " SET label='".$this->db->escape($this->label)."',"; $sql.= " datestart='".$this->db->idate($this->datestart)."',"; $sql.= " dateend='".$this->db->idate($this->dateend)."',"; - $sql.= " fk_projet=".(empty($this->fk_projet)?'NULL':$this->fk_projet).","; + $sql.= " fk_project=".(empty($this->fk_project)?'NULL':$this->fk_project).","; $sql.= " fk_user_modif = ".$user->id; $sql.= " WHERE rowid=".$this->id; From 056b76a831930b5a1931f993879adbbdd96acf92 Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 10:34:22 +0000 Subject: [PATCH 005/137] Better Separator for Products/Services in Top Menu Easier to read when both modules are enabled --- htdocs/core/menus/standard/eldy.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7b5e5d98d9d..67bc5674443 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -112,7 +112,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $chaine.=$langs->trans("Products"); } if (! empty($conf->product->enabled) && ! empty($conf->service->enabled)) { - $chaine.="/"; + $chaine.=" | "; } if (! empty($conf->service->enabled)) { $chaine.=$langs->trans("Services"); From 86d195fa811daeb2c8082689598ed91e2e27dcaf Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 10:37:15 +0000 Subject: [PATCH 006/137] Add Unique Top Menu Translation Add unique top menu translation for products/services so it can be better translated separately from other words/links using the same text. --- htdocs/core/menus/standard/eldy.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 67bc5674443..441bbd2da31 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -109,13 +109,13 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $chaine=""; if (! empty($conf->product->enabled)) { - $chaine.=$langs->trans("Products"); + $chaine.=$langs->trans("TMenuProducts"); } if (! empty($conf->product->enabled) && ! empty($conf->service->enabled)) { $chaine.=" | "; } if (! empty($conf->service->enabled)) { - $chaine.=$langs->trans("Services"); + $chaine.=$langs->trans("TMenuServices"); } if (empty($noout)) print_start_menu_entry($idsel,$classname,$showmode); From f96fd895e3c8bb1a4f8b768f871ee46c6fcebecd Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 10:40:45 +0000 Subject: [PATCH 007/137] Add Products/Services Menu Translation String Add the translation string into language file --- htdocs/langs/en_US/products.lang | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 27b64a4399d..7ce98277a73 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -5,6 +5,8 @@ ProductLabelTranslated=Translated product label ProductDescriptionTranslated=Translated product description ProductNoteTranslated=Translated product note ProductServiceCard=Products/Services card +TMenuProducts=PRODUCTS +TMenuServices=SERVICES Products=Products Services=Services Product=Product From 636fbb476c4eee92424bb3f9e55057bef30b13a0 Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 10:49:12 +0000 Subject: [PATCH 008/137] Add Unique Top Menu Translation Add unique top menu translation for Tools so it can be better translated separately from other words/links using the same text. --- htdocs/core/menus/standard/eldy.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 441bbd2da31..fe3b36860a9 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -259,7 +259,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $idsel='tools'; if (empty($noout)) print_start_menu_entry($idsel,$classname,$showmode); - if (empty($noout)) print_text_menu_entry($langs->trans("Tools"), $showmode, DOL_URL_ROOT.'/core/tools.php?mainmenu=tools&leftmenu=', $id, $idsel, $classname, $atarget); + if (empty($noout)) print_text_menu_entry($langs->trans("TMenuTools"), $showmode, DOL_URL_ROOT.'/core/tools.php?mainmenu=tools&leftmenu=', $id, $idsel, $classname, $atarget); if (empty($noout)) print_end_menu_entry($showmode); $menu->add('/core/tools.php?mainmenu=tools&leftmenu=', $langs->trans("Tools"), 0, $showmode, $atarget, "tools", ''); } From 5c46095fa37b6ee559ebc6123f2e83449273a62f Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 10:52:30 +0000 Subject: [PATCH 009/137] Add Translation String for Tools Add translation string so it can be used independently for the top menu --- htdocs/langs/en_US/other.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 1ea1f9da1db..69e0a808e62 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -2,6 +2,7 @@ SecurityCode=Security code NumberingShort=N° Tools=Tools +TMenuTools=TOOLS ToolsDesc=All miscellaneous tools not included in other menu entries are collected here.

All the tools can be reached in the left menu. Birthday=Birthday BirthdayDate=Birthday date From 9f2879515947574e8bb33517c41711a54c5793bc Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 11:29:35 +0000 Subject: [PATCH 010/137] Add Unique Top Menu Translation Add unique top menu translation for products/services so it can be better translated separately from other words/links using the same text. ** Requires re-enabling module --- htdocs/core/modules/modAgenda.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index 47e6fb43d5c..80cc63ac610 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -189,7 +189,7 @@ class modAgenda extends DolibarrModules // $r++; $this->menu[$r]=array('fk_menu'=>0, 'type'=>'top', - 'titre'=>'Agenda', + 'titre'=>'TMenuAgenda', 'mainmenu'=>'agenda', 'url'=>'/comm/action/index.php', 'langs'=>'agenda', From 6ebafe1a871405420882a8459b705d9cc41c25a7 Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 11:32:28 +0000 Subject: [PATCH 011/137] Add Translation String for Agenda Add translation string so it can be used independently for the top menu --- htdocs/langs/en_US/agenda.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index b626d991615..48b1862d706 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -2,6 +2,7 @@ IdAgenda=ID event Actions=Events Agenda=Agenda +TMenuAgenda=AGENDA Agendas=Agendas LocalAgenda=Internal calendar ActionsOwnedBy=Event owned by From d5fe7b8b9c3d25ffab2c2815d17f4cb6df78fa16 Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 12:21:47 +0000 Subject: [PATCH 012/137] Add Search Tip for User Add a simple tip on the search strings which could be used by the end user when they are searching from the main search box. Tested strings are '*' and *|* This would be very useful to the end user and new users --- htdocs/langs/en_US/main.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index a3851b89339..4da744b2a75 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -775,7 +775,7 @@ SetRef=Set ref Select2ResultFoundUseArrows=Some results found. Use arrows to select. Select2NotFound=No result found Select2Enter=Enter -Select2MoreCharacter=or more character +Select2MoreCharacter=or more characters

SEARCH PARAMETERS:
[without spaces]

| OR
* SEARCH ALL
Select2MoreCharacters=or more characters Select2LoadingMoreResults=Loading more results... Select2SearchInProgress=Search in progress... From 5a8b844c49468c7cb2ece00ac0fcc654e6992c4a Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 22:41:08 +0000 Subject: [PATCH 013/137] Update other.lang --- htdocs/langs/en_US/other.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 69e0a808e62..253560454ec 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -2,7 +2,7 @@ SecurityCode=Security code NumberingShort=N° Tools=Tools -TMenuTools=TOOLS +TMenuTools=Tools ToolsDesc=All miscellaneous tools not included in other menu entries are collected here.

All the tools can be reached in the left menu. Birthday=Birthday BirthdayDate=Birthday date From 9bb60e8d2c2cb3c31356138973fa6a3ebf8afdee Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 22:41:35 +0000 Subject: [PATCH 014/137] Update agenda.lang --- htdocs/langs/en_US/agenda.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 48b1862d706..f378ec7afbc 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -2,7 +2,7 @@ IdAgenda=ID event Actions=Events Agenda=Agenda -TMenuAgenda=AGENDA +TMenuAgenda=Agenda Agendas=Agendas LocalAgenda=Internal calendar ActionsOwnedBy=Event owned by From 66693c52682e7ec8e93deaa48a0a7b17fca4c334 Mon Sep 17 00:00:00 2001 From: IJ Date: Sat, 19 Nov 2016 22:42:03 +0000 Subject: [PATCH 015/137] Update products.lang --- htdocs/langs/en_US/products.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 7ce98277a73..a228a9ef4df 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -5,8 +5,8 @@ ProductLabelTranslated=Translated product label ProductDescriptionTranslated=Translated product description ProductNoteTranslated=Translated product note ProductServiceCard=Products/Services card -TMenuProducts=PRODUCTS -TMenuServices=SERVICES +TMenuProducts=Products +TMenuServices=Services Products=Products Services=Services Product=Product From b631db1d6062032470403447daed0afb65d301f0 Mon Sep 17 00:00:00 2001 From: IJ Date: Tue, 22 Nov 2016 02:29:25 +0000 Subject: [PATCH 016/137] New: Add Hidden Options Quick Reference Link Add the dolibarr wiki link for quick reference from the page Setup>Other Setup --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index ca53bc971a9..c4dee6a5da1 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -982,7 +982,7 @@ TriggerAlwaysActive=Triggers in this file are always active, whatever are the ac TriggerActiveAsModuleActive=Triggers in this file are active as module %s is enabled. GeneratedPasswordDesc=Define here which rule you want to use to generate new password if you ask to have auto generated password DictionaryDesc=Insert all reference data. You can add your values to the default. -ConstDesc=This page allows you to edit all other parameters not available in previous pages. These are mostly reserved parameters for developers or advanced troubleshooting. +ConstDesc=This page allows you to edit all other parameters not available in previous pages. These are mostly reserved parameters for developers or advanced troubleshooting. For a list of options check here. MiscellaneousDesc=All other security related parameters are defined here. LimitsSetup=Limits/Precision setup LimitsDesc=You can define limits, precisions and optimisations used by Dolibarr here From c1652169f2f0554e6d4a9234af9f15e193a357ae Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Wed, 30 Nov 2016 16:09:59 +0100 Subject: [PATCH 017/137] NEW : Add in export thirdparty for user limit on view thirpdarty to sales team also to subsidiaries --- htdocs/core/modules/modSociete.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 1943e3f7b20..6e55077b19d 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -281,7 +281,7 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id'; $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe', 1).')'; - if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; + if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' OR sc.fk_user IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'user where fk_user= '.$user->id.'))'; // Export list of contacts and attributes $r++; @@ -311,7 +311,7 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid'; $this->export_sql_end[$r] .=' WHERE c.entity IN ('.getEntity("societe", 1).')'; - if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; + if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' OR sc.fk_user IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'user where fk_user= '.$user->id.'))'; // Imports From 7ab7149e64910ea7644c615b2d82e3420d8b5112 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Mon, 5 Dec 2016 11:03:12 +0100 Subject: [PATCH 018/137] just little indenting --- htdocs/core/lib/pdf.lib.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 9d6201998db..23c2f5e9bf4 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1234,11 +1234,14 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl { if ($issupplierline) { - //$ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); // Show local ref and supplier ref - if (! empty($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES)) $ref_prodserv =$ref_supplier; - else $ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); // Show local ref and supplier ref + //$ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); // Show local ref and supplier ref + if (! empty($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES)) + $ref_prodserv =$ref_supplier; + else + $ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); // Show local ref and supplier ref } - else $ref_prodserv = $prodser->ref; // Show local ref only + else + $ref_prodserv = $prodser->ref; // Show local ref only if (! empty($libelleproduitservice)) $ref_prodserv .= " - "; } From d86503cb66ab7920ee54d732ae36e3bd970a56d5 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Mon, 5 Dec 2016 11:09:47 +0100 Subject: [PATCH 019/137] additionnal feature on supplier ref display we have like this 3 mode of display supplier ref --- htdocs/core/lib/pdf.lib.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 23c2f5e9bf4..ac08f4c25a4 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1234,11 +1234,12 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl { if ($issupplierline) { - //$ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); // Show local ref and supplier ref - if (! empty($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES)) - $ref_prodserv =$ref_supplier; + if ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 1) + $ref_prodserv = $ref_supplier; + elseif ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 2) + $ref_prodserv = $ref_supplier. ' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')'; else - $ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); // Show local ref and supplier ref + $ref_prodserv = $prodser->ref.' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')'; } else $ref_prodserv = $prodser->ref; // Show local ref only From 3396dfc7f60f31dc3660d7238638be043509354f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Dec 2016 21:58:52 +0100 Subject: [PATCH 020/137] 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 1e39805945334723dcf00a910b47e77ca20df42d Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 9 Dec 2016 16:14:43 +0100 Subject: [PATCH 021/137] integrate Eldy remarks --- htdocs/core/modules/modSociete.class.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 6e55077b19d..2de744801f0 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -281,7 +281,11 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id'; $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe', 1).')'; - if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' OR sc.fk_user IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'user where fk_user= '.$user->id.'))'; + if(!$user->rights->societe->client->voir) { + $subordinatesids = $user->getAllChildIds(); + var_dump($subordinatesids); + $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '.count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).'))' : ''; + } // Export list of contacts and attributes $r++; @@ -311,7 +315,10 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid'; $this->export_sql_end[$r] .=' WHERE c.entity IN ('.getEntity("societe", 1).')'; - if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' OR sc.fk_user IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'user where fk_user= '.$user->id.'))'; + if(!$user->rights->societe->client->voir) { + $subordinatesids = $user->getAllChildIds(); + $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '.count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).'))' : ''; + } // Imports From a797c45e3bf954e9f5ce528c089e1e1504be2b0c Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 9 Dec 2016 16:28:06 +0100 Subject: [PATCH 022/137] sdf --- htdocs/core/modules/modSociete.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 2de744801f0..f0ea5370c6c 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -283,7 +283,6 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe', 1).')'; if(!$user->rights->societe->client->voir) { $subordinatesids = $user->getAllChildIds(); - var_dump($subordinatesids); $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '.count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).'))' : ''; } From cbfb7df05ea22762ad1c4c9407f579c5a807a671 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 10 Dec 2016 12:23:02 +0100 Subject: [PATCH 023/137] Add send contract by mail --- htdocs/contrat/card.php | 189 ++++++++++++++++++++++++++++++++++------ 1 file changed, 164 insertions(+), 25 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 7ef9924ac00..51a61d911b3 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -919,7 +919,19 @@ if (empty($reshook)) else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); } } - + + /* + * Send mail + */ + + // Actions to send emails + $actiontypecode='AC_CONT'; + $trigger_name='CONTRACT_SENTBYMAIL'; + $paramname='id'; + $mode='emailfromcontract'; + $trackid='cont'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->contrat->creer) { if ($action == 'addcontact') @@ -2026,37 +2038,164 @@ else print ""; } + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } - print '
'; + if ($action != 'presend') + { + print '
'; - /* - * Documents generes - */ - $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->contrat->dir_output . "/" . dol_sanitizeFileName($object->ref); - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->contrat->creer; - $delallowed = $user->rights->contrat->supprimer; + /* + * Documents generes + */ + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->contrat->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->contrat->creer; + $delallowed = $user->rights->contrat->supprimer; - $var = true; + $var = true; - print $formfile->showdocuments('contract', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - - - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object, null, array('contrat')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + print $formfile->showdocuments('contract', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - print '
'; + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, array('contrat')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + + print '
'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'contract', $socid); + + + print '
'; + } + + /* + * Action presend + */ + if ($action == 'presend') + { + $object->fetch_projet(); + + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); + $file = $fileparams['fullname']; + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + + if (!empty($newlang)) + { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($newlang); + $outputlangs->load('commercial'); + } + + // Build document if it not exists + if (! $file || ! is_readable($file)) { + $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) { + dol_print_error($db, $object->error, $object->errors); + exit(); + } + $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); + $file = $fileparams['fullname']; + } + + print '
'; + print '
'; + print load_fiche_titre($langs->trans('SendOrderByMail')); + + dol_fiche_head(''); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); + $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + + if($formmail->fromtype === 'user'){ + $formmail->fromid = $user->id; + + } + $formmail->trackid='ord'.$object->id; + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set + { + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id); + } + $formmail->withfrom = 1; + $liste = array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) + $liste [$key] = $value; + $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; + $formmail->withtocc = $liste; + $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; + if (empty($object->ref_client)) { + $formmail->withtopic = $outputlangs->trans('SendOrderRef', '__ORDERREF__'); + } else if (! empty($object->ref_client)) { + $formmail->withtopic = $outputlangs->trans('SendOrderRef', '__ORDERREF__ (__REFCLIENT__)'); + } + $formmail->withfile = 2; + $formmail->withbody = 1; + $formmail->withdeliveryreceipt = 1; + $formmail->withcancel = 1; + // Tableau des substitutions + $formmail->setSubstitFromObject($object); + $formmail->substit ['__ORDERREF__'] = $object->ref; + + $custcontact = ''; + $contactarr = array(); + $contactarr = $object->liste_contact(- 1, 'external'); + + if (is_array($contactarr) && count($contactarr) > 0) + { + foreach ($contactarr as $contact) + { + if ($contact['libelle'] == $langs->trans('TypeContact_commande_external_CUSTOMER')) { // TODO Use code and not label + $contactstatic = new Contact($db); + $contactstatic->fetch($contact ['id']); + $custcontact = $contactstatic->getFullName($langs, 1); + } + } + + if (! empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__'] = $custcontact; + } + } + + // Tableau des parametres complementaires + $formmail->param['action'] = 'send'; + $formmail->param['models'] = 'order_send'; + $formmail->param['models_id']=GETPOST('modelmailselected','int'); + $formmail->param['orderid'] = $object->id; + $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; + + // Init list of files + if (GETPOST("mode") == 'init') { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); + } + + // Show form + print $formmail->get_form(); + + dol_fiche_end(); + } - // List of actions on element - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'contract', $socid); - - - print '
'; } } From ba8deb29c9b97bd79e7ab56c90305075ed51e9e4 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sat, 10 Dec 2016 12:28:52 +0100 Subject: [PATCH 024/137] Update card.php --- htdocs/contrat/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 51a61d911b3..e59f8c95ed2 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -2086,7 +2086,7 @@ else $ref = dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); + $fileparams = dol_most_recent_file($conf->contrat->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); $file = $fileparams['fullname']; // Define output language From bfb628dab603020eeddd975062497998a462a7c3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Dec 2016 15:37:39 +0100 Subject: [PATCH 025/137] 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 026/137] 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 027/137] 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 '\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 a99ac7fb6b0098b1ff2193d28e0aca3ba40b6cc9 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 13 Dec 2016 16:52:49 +0100 Subject: [PATCH 029/137] taking account @eldy remarks --- htdocs/core/modules/modSociete.class.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 7984ed7f6a1..af4da616ce9 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -282,8 +282,12 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id'; $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe', 1).')'; if(!$user->rights->societe->client->voir) { - $subordinatesids = $user->getAllChildIds(); - $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '.count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).'))' : ''; + $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '; + if ($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS) { + $subordinatesids = $user->getAllChildIds(); + $this->export_sql_end[$r] .=count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).')' : ''; + } + $this->export_sql_end[$r] .=')'; } // Export list of contacts and attributes @@ -315,8 +319,12 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid'; $this->export_sql_end[$r] .=' WHERE c.entity IN ('.getEntity("societe", 1).')'; if(!$user->rights->societe->client->voir) { - $subordinatesids = $user->getAllChildIds(); - $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '.count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).'))' : ''; + $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '; + if ($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS) { + $subordinatesids = $user->getAllChildIds(); + $this->export_sql_end[$r] .=count($subronidatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',',$subronidatesids).')' : ''; + } + $this->export_sql_end[$r] .=')'; } From a736f3782c410f30b79e2c7be4804fcf5043b361 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 18 Dec 2016 13:21:09 +0100 Subject: [PATCH 030/137] 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 '
'.$langs->trans("Project").''; - $numproject=$formproject->select_projects(-1,GETPOST("fk_projet"),'fk_projet',16,0,1,1); + $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1); print '
'; if ($action == 'edit') { $formproject=new FormProjets($db); - $numproject=$formproject->select_projects(-1,$object->fk_projet,'fk_projet',16,0,1,1); + $numproject=$formproject->select_projects(-1,$object->fk_project,'fk_project',16,0,1,1); } else { $project=new Project($db); - $project->fetch($object->fk_projet); + $project->fetch($object->fk_project); print $project->getNomUrl(1,'',1);; } 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 028/137] 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 "
'; 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 ''; } // Action column From dba777c57b1444737a95396aab33ee3e4b35f34f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 8 Jan 2017 12:10:07 +0100 Subject: [PATCH 113/137] Fix missing field alias --- htdocs/societe/soc.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 06413548d9a..020d0aad63f 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -290,9 +290,8 @@ if (empty($reshook)) else { $object->name = GETPOST('name', 'alpha'); - $object->name_alias = GETPOST('name_alias'); } - + $object->name_alias = GETPOST('name_alias'); $object->address = GETPOST('address'); $object->zip = GETPOST('zipcode', 'alpha'); $object->town = GETPOST('town', 'alpha'); @@ -920,7 +919,6 @@ else $("#radiocompany").click(function() { $(".individualline").hide(); $("#typent_id").val(0); - $("#name_alias").show(); $("#effectif_id").val(0); $("#TypeName").html(document.formsoc.ThirdPartyName.value); document.formsoc.private.value=0; @@ -928,7 +926,6 @@ else $("#radioprivate").click(function() { $(".individualline").show(); $("#typent_id").val(id_te_private); - $("#name_alias").hide(); $("#effectif_id").val(id_ef15); $("#TypeName").html(document.formsoc.LastName.value); document.formsoc.private.value=1; @@ -970,7 +967,7 @@ else print ''; print ''; print ''; - print ''; + print ''; print ''; if ($modCodeClient->code_auto || $modCodeFournisseur->code_auto) print ''; @@ -982,11 +979,11 @@ else print 'global->SOCIETE_USEPREFIX)?' colspan="3"':'').'>'; print ''; From a583fd7a3b43a2d95717dded0b1ee79135a09e7a Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 8 Jan 2017 20:52:42 +0100 Subject: [PATCH 114/137] Fix : Bank - Presentation, no titlefield in a list --- htdocs/compta/bank/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 5e3f81bb205..82283547d99 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -449,7 +449,7 @@ foreach ($accounts as $key=>$type) // Ref if (! empty($arrayfields['b.ref']['checked'])) { - print ''; + print ''; if (! $i) $totalarray['nbfield']++; } From 62a668d8997a7eb26375f618f425da73f91c6415 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 9 Jan 2017 10:02:17 +0100 Subject: [PATCH 115/137] Fix https link --- htdocs/main.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index b6a5d904c34..92df8f48f05 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1025,7 +1025,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print ''."\n"; if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print ''."\n"; - if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print ''."\n"; + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print ''."\n"; // Displays title $appli=constant('DOL_APPLICATION_TITLE'); From 03aa8343fd1486733b657865b176a506bcd293e7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 9 Jan 2017 10:21:35 +0100 Subject: [PATCH 116/137] Fix css --- htdocs/cashdesk/tpl/facturation1.tpl.php | 18 +++++++++--------- htdocs/theme/eldy/style.css.php | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/cashdesk/tpl/facturation1.tpl.php b/htdocs/cashdesk/tpl/facturation1.tpl.php index d20eb4c3299..208727a7644 100644 --- a/htdocs/cashdesk/tpl/facturation1.tpl.php +++ b/htdocs/cashdesk/tpl/facturation1.tpl.php @@ -106,23 +106,23 @@ $langs->load("cashdesk"); - - + - - +
'.$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 031/137] 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 032/137] 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 033/137] 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 034/137] 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 035/137] 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) { ?> -trans("Close"); ?> - +trans("Close"); ?> From 41832a0c2657087d8eeea72fff1cc886e7e19585 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 8 Jan 2017 11:20:29 +0100 Subject: [PATCH 110/137] Fix neutral color on login (no theme yet selected) --- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index d72d303aa32..6da8a7cf935 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -262,7 +262,7 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla input:focus, textarea:focus, button:focus, select:focus { /* box-shadow: 0 0 4px #8091BF; */ - border-bottom: 1px solid #8091BF !important; + border-bottom: 1px solid #aaa !important; } textarea.cke_source:focus { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 409a902648e..a66727cb3db 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -262,7 +262,7 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla input:focus, textarea:focus, button:focus, select:focus { /* box-shadow: 0 0 4px #8091BF; */ - border-bottom: 1px solid #8091BF !important; + border-bottom: 1px solid #aaa !important; } textarea.cke_source:focus { From 913df73ed918589d6e28fb05f9dc9abb5b677af9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 8 Jan 2017 11:31:39 +0100 Subject: [PATCH 111/137] Fix css --- htdocs/theme/eldy/style.css.php | 4 ++-- htdocs/theme/md/style.css.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 6da8a7cf935..02460670217 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -261,8 +261,8 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla } input:focus, textarea:focus, button:focus, select:focus { - /* box-shadow: 0 0 4px #8091BF; */ - border-bottom: 1px solid #aaa !important; + box-shadow: 0 0 4px #8091BF; + /* TODO Remove shadow on focus. Use instead border-bottom: 1px solid #aaa !important; To disable with select2 too. */ } textarea.cke_source:focus { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index a66727cb3db..7a0d16e4743 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -261,8 +261,8 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla } input:focus, textarea:focus, button:focus, select:focus { - /* box-shadow: 0 0 4px #8091BF; */ - border-bottom: 1px solid #aaa !important; + box-shadow: 0 0 4px #8091BF; + /* TODO Remove shadow on focus. Use instead border-bottom: 1px solid #aaa !important; To disable with select2 too. */ } textarea.cke_source:focus { From 1856b5cfb8790b47472295da1ddacbc62cbacb52 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 8 Jan 2017 11:50:43 +0100 Subject: [PATCH 112/137] Fix filter on status for third parties --- htdocs/societe/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 9506c5ad6bd..8982d2db32d 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -226,7 +226,7 @@ if (empty($reshook)) $search_idprof6=''; $search_type=''; $search_type_thirdparty=''; - $search_status=''; + $search_status=-1; $search_stcomm=''; $search_level_from=''; $search_level_to=''; @@ -413,7 +413,7 @@ if ($search_idprof6) $sql.= natural_search("s.idprof6",$search_idprof6); if ($search_type > 0 && in_array($search_type,array('1,3','2,3'))) $sql .= " AND s.client IN (".$db->escape($search_type).")"; if ($search_type > 0 && in_array($search_type,array('4'))) $sql .= " AND s.fournisseur = 1"; if ($search_type == '0') $sql .= " AND s.client = 0 AND s.fournisseur = 0"; -if ($search_status!='') $sql .= " AND s.status = ".$db->escape($search_status); +if ($search_status!='' && $search_status >= 0) $sql .= " AND s.status = ".$db->escape($search_status); if (!empty($conf->barcode->enabled) && $search_barcode) $sql.= " AND s.barcode LIKE '%".$db->escape($search_barcode)."%'"; if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')'; if ($search_levels) $sql .= " AND s.fk_prospectlevel IN (".$search_levels.')'; @@ -878,7 +878,7 @@ if (! empty($arrayfields['s.tms']['checked'])) if (! empty($arrayfields['s.status']['checked'])) { print '
'; - print $form->selectarray('search_status', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')),$search_status); + print $form->selectarray('search_status', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')), $search_status, 1); print '
'; if ($object->particulier || $private) { - print ''.$langs->trans('LastName','name').''; + print ''.$langs->trans('ThirdPartyName').' / '.$langs->trans('LastName','name').''; } else { - print ''.fieldLabel('ThirdPartyName','name').''; + print ''.fieldLabel('ThirdPartyName','name').''; } print ''.$acc->getNomUrl(1).''.$acc->getNomUrl(1).'trans("VATRate"); ?>
+ - + + @@ -155,17 +155,17 @@ $langs->load("cashdesk");
trans("Amount"); ?> - +
- + - - +
trans("TotalTicket"); ?>trans("Received"); ?>trans("Change"); ?>
+
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 02460670217..1b5c36bb000 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -4463,7 +4463,7 @@ border-top-right-radius: 6px; color: #fff; text-decoration: none; padding-top: 18px; - : 54px; + padding-left: 54px; font-size: 14px; height: 38px; } From fd008f88b100bcfc6918d3ec2e23969e783503b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 9 Jan 2017 10:21:59 +0100 Subject: [PATCH 117/137] Add github tools --- dev/tools/github_authors_peryear.sh | 8 ++++++++ dev/tools/github_commits_perversion.sh | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100755 dev/tools/github_authors_peryear.sh create mode 100755 dev/tools/github_commits_perversion.sh diff --git a/dev/tools/github_authors_peryear.sh b/dev/tools/github_authors_peryear.sh new file mode 100755 index 00000000000..99b28d4d417 --- /dev/null +++ b/dev/tools/github_authors_peryear.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +FROM=2016-01-01 +TO=2016-12-31 + +echo "git log --since $FROM --before $TO | grep ^Author | sort -u -f -i -b | wc -l" +git log --since $FROM --before $TO | grep ^Author | sort -u -f -i -b | wc -l + diff --git a/dev/tools/github_commits_perversion.sh b/dev/tools/github_commits_perversion.sh new file mode 100755 index 00000000000..40ddafee617 --- /dev/null +++ b/dev/tools/github_commits_perversion.sh @@ -0,0 +1,15 @@ +#/bin/bash +Releases=("3.8" "3.9" "4.0" "5.0", "develop") +Dates=("2010-01-01", "2011-01-01", "2012-01-01", "2013-01-01", "2014-01-01", "2015-01-01", "2016-07-01") +let "counter = 1" + +for i in "${Releases[@]}" +do + git shortlog -s -n --after=${Dates[counter-1]} --before=${Dates[counter]} + echo -n "Total $i: " + git log --pretty=oneline --after=${Dates[counter-1]} --before=${Dates[counter]} | wc -l + echo "=======================" + echo + let "counter +=1" +done + From 8ab0ad3b72732ce53e55756a8b5d2998f9e00e0c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 9 Jan 2017 10:36:24 +0100 Subject: [PATCH 118/137] Fix css --- htdocs/cashdesk/css/style.css | 5 ++++- htdocs/cashdesk/tpl/validation2.tpl.php | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/cashdesk/css/style.css b/htdocs/cashdesk/css/style.css index e606c8d2807..2931ad7638e 100644 --- a/htdocs/cashdesk/css/style.css +++ b/htdocs/cashdesk/css/style.css @@ -115,7 +115,7 @@ li.menu_choix0 { float: right; } -/* ------------------- R�capitulatif des articles ------------------- */ +/* ------------------- Remind of products ------------------- */ .liste_articles { min-width: 215px; float: right; @@ -212,6 +212,9 @@ p.titre { max-width: 900px; } +.blocksellfinished { + min-width: 215px; +} .titre1 { font-weight: bold; color: #ff9900; diff --git a/htdocs/cashdesk/tpl/validation2.tpl.php b/htdocs/cashdesk/tpl/validation2.tpl.php index b74f5afdd52..844522f55e0 100644 --- a/htdocs/cashdesk/tpl/validation2.tpl.php +++ b/htdocs/cashdesk/tpl/validation2.tpl.php @@ -22,9 +22,10 @@ $langs->load("bills"); ?> -

trans("SellFinished"); ?>


+
+

trans("SellFinished"); ?>