From a5814ce77907f7a2c7b874b493324596a64796b0 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 9 Feb 2018 11:00:43 +0100 Subject: [PATCH 01/45] Fix: nocheck for "fournisseur", already check with "societe" --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index e84eef83924..f8753193888 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -382,7 +382,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet','project'); // Test for project object $checktask = array('projet_task'); - $nocheck = array('barcode','stock'); // No test + $nocheck = array('barcode','stock','fournisseur'); // No test $checkdefault = 'all other not already defined'; // Test on entity and link to third party. Not allowed if link is empty (Ex: invoice, orders...). // If dbtablename not defined, we use same name for table than module name From 67ce71bc487feba279c83c57cfb287a6bea08f52 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Fri, 9 Feb 2018 18:23:11 +0100 Subject: [PATCH 02/45] Fix: Contracts not show price --- htdocs/contrat/tpl/linkedobjectblock.tpl.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index eae46dad772..68d7a8462f2 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -1,5 +1,6 @@ + * Copyright (C) 2018 Juanjo Menent * * 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 @@ -50,7 +51,15 @@ foreach($linkedObjectBlock as $key => $objectlink) getNomUrl(1); ?> date_contrat,'day'); ?> -   + rights->contrat->lire) { + $totalcontrat = 0; + foreach ($objectlink->lines as $linecontrat) { + $totalcontrat = $totalcontrat + $linecontrat->total_ht; + $total = $total + $linecontrat->total_ht; + } + echo price($totalcontrat); + } ?> getLibStatut(7); ?> ">transnoentitiesnoconv("RemoveLink")); ?> From d731857fd0dfaa0ac22ee8db3d8aa1ce29f5d4f5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 03:13:12 +0100 Subject: [PATCH 03/45] Update linkedobjectblock.tpl.php --- htdocs/contrat/tpl/linkedobjectblock.tpl.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index 68d7a8462f2..a44f20679b8 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -52,7 +52,11 @@ foreach($linkedObjectBlock as $key => $objectlink) date_contrat,'day'); ?> rights->contrat->lire) { + // Price of contract is not shown by default because a contract is a list of service with + // start and end date that change with time andd that may be different that the period of reference for price. + // So price of a contract does often means nothing. Prices is on the different invoices done on same contract. + if ($user->rights->contrat->lire && empty($conf->global->CONTRACT_SHOW_TOTAL_OF_PRODUCT_AS_PRICE)) + { $totalcontrat = 0; foreach ($objectlink->lines as $linecontrat) { $totalcontrat = $totalcontrat + $linecontrat->total_ht; @@ -65,4 +69,4 @@ foreach($linkedObjectBlock as $key => $objectlink) - \ No newline at end of file + From 448fcae02fc36f196883460814f0df8416d2b0c8 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 12 Feb 2018 09:03:53 +0100 Subject: [PATCH 04/45] Fix: move "fournisseur" in $checksoc --- htdocs/core/lib/security.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 50ce574e271..14ff7bfdf53 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -378,11 +378,11 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh if ($feature == 'task') $feature='projet_task'; $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) - $checksoc = array('societe'); // Test for societe object + $checksoc = array('societe','fournisseur'); // Test for societe object $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet','project'); // Test for project object $checktask = array('projet_task'); - $nocheck = array('barcode','stock','fournisseur'); // No test + $nocheck = array('barcode','stock'); // No test $checkdefault = 'all other not already defined'; // Test on entity and link to third party. Not allowed if link is empty (Ex: invoice, orders...). // If dbtablename not defined, we use same name for table than module name From 24cc687724758e474d2e772a41532e252ec884e3 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 12 Feb 2018 09:28:41 +0100 Subject: [PATCH 05/45] Fix: you can't check "fournisseur" with checkUserAccessToObject without object ID --- htdocs/core/lib/security.lib.php | 2 +- htdocs/product/fournisseurs.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 14ff7bfdf53..c204809e9a1 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -378,7 +378,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh if ($feature == 'task') $feature='projet_task'; $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) - $checksoc = array('societe','fournisseur'); // Test for societe object + $checksoc = array('societe'); // Test for societe object $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet','project'); // Test for project object $checktask = array('projet_task'); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 2c49319fc19..9c91b5e11d7 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -51,6 +51,8 @@ $cost_price=GETPOST('cost_price', 'alpha'); $backtopage=GETPOST('backtopage','alpha'); $error=0; +if (!$user->rights->fournisseur->lire) accessforbidden(); + // If socid provided by ajax company selector if (! empty($_REQUEST['search_fourn_id'])) { @@ -63,7 +65,7 @@ if (! empty($_REQUEST['search_fourn_id'])) $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); if ($user->societe_id) $socid=$user->societe_id; -$result=restrictedArea($user,'produit|service&fournisseur',$fieldvalue,'product&product','','',$fieldtype); +$result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); From ef051716410fcb7eef18447f6facc1086924beec Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Mon, 12 Feb 2018 13:48:43 +0100 Subject: [PATCH 06/45] Fix : contract service list context was mixing up with service list from product/service module --- htdocs/contrat/services.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index f21c476fe35..09df597d017 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -75,7 +75,7 @@ $opclotureyear=GETPOST('opclotureyear'); $filter_opcloture=GETPOST('filter_opcloture'); // Initialize context for list -$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'servicelist'.$mode; +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'contractservicelist'.$mode; // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array($contextpage)); From d762226a70ed31da529fa45900327a78710b1566 Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Mon, 12 Feb 2018 14:39:18 +0100 Subject: [PATCH 07/45] FIX : Call to trigger on chargesociale create --- .../compta/sociales/class/chargesociales.class.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index cf359d691ec..b6386ae3b98 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -155,6 +155,7 @@ class ChargeSociales extends CommonObject function create($user) { global $conf; + $error=0; $now=dol_now(); @@ -190,8 +191,17 @@ class ChargeSociales extends CommonObject $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX."chargesociales"); //dol_syslog("ChargesSociales::create this->id=".$this->id); - $this->db->commit(); - return $this->id; + $result=$this->call_trigger('PAYMENTSOCIALECONTRIBUTION_CREATE',$user); + if ($result < 0) $error++; + + if(empty($error)) { + $this->db->commit(); + return $this->id; + } + else { + $this->db->rollback(); + return -1*$error; + } } else { From 6f7d6f977bd49a122095e6e4da7af556392457b0 Mon Sep 17 00:00:00 2001 From: De Coninck Laurent Date: Mon, 12 Feb 2018 15:47:04 +0100 Subject: [PATCH 08/45] fix error in latest release --- htdocs/compta/tva/class/tva.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php index 187d21cb0a6..dbc18a83605 100644 --- a/htdocs/compta/tva/class/tva.class.php +++ b/htdocs/compta/tva/class/tva.class.php @@ -655,7 +655,7 @@ class Tva extends CommonObject * @param string $morecss More CSS * @return string Chaine with URL */ - function getNomUrl($withpicto=0, $option='', $notooltip=0, morecss='') + function getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='') { global $langs, $conf; @@ -669,6 +669,9 @@ class Tva extends CommonObject $linkclose=''; if (empty($notooltip)) { + + + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label=$langs->trans("ShowMyObject"); From b2835fc80380793127f2de74e7a44d9a3640226a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 15:54:24 +0100 Subject: [PATCH 09/45] Fix check of vat only for european countries --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/lib/company.lib.php | 2 +- htdocs/langs/en_US/companies.lang | 10 +++++----- htdocs/societe/card.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3dd6d7b03a6..ecabc30b681 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3434,7 +3434,7 @@ abstract class CommonObject /** * Return if a country is inside the EEC (European Economic Community) - * @deprecated + * @deprecated Use function isInEEC function instead * * @return boolean true = country inside EEC, false = country outside EEC */ diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 4f1726a45c6..b44be44e222 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -573,7 +573,7 @@ function getFormeJuridiqueLabel($code) } /** - * Return if a country is inside the EEC (European Economic Community) + * Return if a country of an object is inside the EEC (European Economic Community) * TODO Add a field into country dictionary. * * @param Object $object Object diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 353b8ca0c47..8b9e205e4a7 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -74,8 +74,8 @@ Town=City Web=Web Poste= Position DefaultLang=Language by default -VATIsUsed=VAT is used -VATIsNotUsed=VAT is not used +VATIsUsed=Sale tax is used +VATIsNotUsed=Sale tax is not used CopyAddressFromSoc=Fill address with third party address ThirdpartyNotCustomerNotSupplierSoNoRef=Thirdparty neither customer nor supplier, no available refering objects PaymentBankAccount=Payment bank account @@ -238,7 +238,7 @@ ProfId3TN=Prof Id 3 (Douane code) ProfId4TN=Prof Id 4 (BAN) ProfId5TN=- ProfId6TN=- -ProfId1US=Prof Id +ProfId1US=Prof Id (FEIN) ProfId2US=- ProfId3US=- ProfId4US=- @@ -254,8 +254,8 @@ ProfId1DZ=RC ProfId2DZ=Art. ProfId3DZ=NIF ProfId4DZ=NIS -VATIntra=VAT number -VATIntraShort=VAT number +VATIntra=Sales tax ID +VATIntraShort=Tax ID VATIntraSyntaxIsValid=Syntax is valid ProspectCustomer=Prospect / Customer Prospect=Prospect diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 0d8f256e15e..67abb030b09 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1222,7 +1222,7 @@ else print ''; $s = ''; - if (empty($conf->global->MAIN_DISABLEVATCHECK)) + if (empty($conf->global->MAIN_DISABLEVATCHECK) && isInEEC($object)) { $s.=' '; @@ -1833,7 +1833,7 @@ else print ''; $s =''; - if (empty($conf->global->MAIN_DISABLEVATCHECK)) + if (empty($conf->global->MAIN_DISABLEVATCHECK) && isInEEC($object)) { $s.='   '; From 1c9f543fd54ffb1cb6fdae5cf4c90b336b95cce9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 15:55:37 +0100 Subject: [PATCH 10/45] Translation --- htdocs/langs/en_US/companies.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 8b9e205e4a7..defecf8ed67 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -74,8 +74,8 @@ Town=City Web=Web Poste= Position DefaultLang=Language by default -VATIsUsed=Sale tax is used -VATIsNotUsed=Sale tax is not used +VATIsUsed=Sales tax is used +VATIsNotUsed=Sales tax is not used CopyAddressFromSoc=Fill address with third party address ThirdpartyNotCustomerNotSupplierSoNoRef=Thirdparty neither customer nor supplier, no available refering objects PaymentBankAccount=Payment bank account From a4f48fcfb6a10281cf041df7364cfee88361bce2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 16:09:22 +0100 Subject: [PATCH 11/45] Fix feature must be hidden (not stable) --- htdocs/core/lib/company.lib.php | 2 +- htdocs/core/modules/modWebsite.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index b44be44e222..3f7c45dda52 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -206,7 +206,7 @@ function societe_prepare_head(Societe $object) $h++; } - if (! empty($conf->website->enabled) && (!empty($user->rights->societe->lire) )) + if (! empty($conf->website->enabled) && (! empty($conf->global->WEBSITE_USE_WEBSITE_ACCOUNTS)) && (!empty($user->rights->societe->lire))) { $head[$h][0] = DOL_URL_ROOT.'/societe/website.php?id='.$object->id; $head[$h][1] = $langs->trans("WebSiteAccounts"); diff --git a/htdocs/core/modules/modWebsite.class.php b/htdocs/core/modules/modWebsite.class.php index 47d44d66164..d62576c5063 100644 --- a/htdocs/core/modules/modWebsite.class.php +++ b/htdocs/core/modules/modWebsite.class.php @@ -80,7 +80,7 @@ class modWebsite extends DolibarrModules // New pages on tabs // ----------------- - //$this->tabs[] = array('data'=>'thirdparty:+website:WebSites:website:($conf->societe->enabled && $user->rights->societe->lire):/societe/website.php?mainmenu=home&id=__ID__'); // To add a new tab identified by code tabname1 + //$this->tabs[] = array(); // To add a new tab identified by code tabname1 // Boxes //------ From 1052213c978274c3bacb2188aba0c6b4b91f96c3 Mon Sep 17 00:00:00 2001 From: De Coninck Laurent Date: Mon, 12 Feb 2018 18:12:43 +0100 Subject: [PATCH 12/45] Fix 8183 - adherent welcome e-mail Fix the adherent welcome e-mail. [see: #8183] --- htdocs/adherents/type.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index a0f36c409de..01c8841708f 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -96,7 +96,7 @@ if ($action == 'add' && $user->rights->adherent->configurer) $object->label = trim($label); $object->subscription = (int) trim($subscription); $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); + $object->mail_valid = $db->escape(trim($mail_valid)); $object->vote = (boolean) trim($vote); // Fill array 'array_options' with data from add form @@ -134,7 +134,7 @@ if ($action == 'update' && $user->rights->adherent->configurer) $object->label = trim($label); $object->subscription = (int) trim($subscription); $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); + $object->mail_valid = $db->escape(trim($mail_valid)); $object->vote = (boolean) trim($vote); // Fill array 'array_options' with data from add form From 00a8be22a288435b16aa86e704fe7c12cce8b895 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 22:11:43 +0100 Subject: [PATCH 13/45] Fix field too small --- htdocs/product/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 257d3344ba5..fb9b9672015 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -716,7 +716,7 @@ else // Ref if (! empty($arrayfields['p.ref']['checked'])) { - print ''; + print ''; print $product_static->getNomUrl(1); print "\n"; if (! $i) $totalarray['nbfield']++; @@ -724,7 +724,7 @@ else // Ref supplier if (! empty($arrayfields['pfp.ref_fourn']['checked'])) { - print ''; + print ''; print $product_static->getNomUrl(1); print "\n"; if (! $i) $totalarray['nbfield']++; From 88bdebb80fd2d531e9b0db45ba073d587425bc55 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 23:08:01 +0100 Subject: [PATCH 14/45] Fix label truncated --- htdocs/contrat/card.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index db3301174c3..08c43551509 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1549,7 +1549,7 @@ else if ($action != 'editline' || GETPOST('rowid') != $objp->rowid) { - print ''; + print ''; // Label if ($objp->fk_product > 0) { @@ -1559,12 +1559,10 @@ else $productstatic->ref=$objp->pref; $productstatic->entity=$objp->pentity; $productstatic->label=$objp->plabel; - $text = $productstatic->getNomUrl(1,'',20); + $text = $productstatic->getNomUrl(1,'',32); if ($objp->plabel) { $text .= ' - '; - //$productstatic->ref=$objp->label; - //$text .= $productstatic->getNomUrl(0,'',16); $text .= $objp->plabel; } $description = $objp->description; @@ -1701,8 +1699,8 @@ else $productstatic->type=$objp->ptype; $productstatic->ref=$objp->pref; $productstatic->entity=$objp->pentity; - print $productstatic->getNomUrl(1,'',20); - print $objp->label?' - '.dol_trunc($objp->label,16):''; + print $productstatic->getNomUrl(1,'',32); + print $objp->label?' - '.dol_trunc($objp->label,32):''; print '
'; } else @@ -1810,7 +1808,7 @@ else 'text' => $langs->trans("ConfirmMoveToAnotherContractQuestion"), array('type' => 'select', 'name' => 'newcid', 'values' => $arraycontractid)); - $form->form_confirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'),$langs->trans("MoveToAnotherContract"),$langs->trans("ConfirmMoveToAnotherContract"),"confirm_move",$formquestion); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'),$langs->trans("MoveToAnotherContract"),$langs->trans("ConfirmMoveToAnotherContract"),"confirm_move",$formquestion); print '
'; } @@ -1822,7 +1820,7 @@ else $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); $comment = GETPOST('comment','alpha'); - $form->form_confirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment),$langs->trans("ActivateService"),$langs->trans("ConfirmActivateService",dol_print_date($dateactstart,"%A %d %B %Y")),"confirm_active", '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment),$langs->trans("ActivateService"),$langs->trans("ConfirmActivateService",dol_print_date($dateactstart,"%A %d %B %Y")),"confirm_active", '', 0, 1); print '
'; } @@ -1841,7 +1839,7 @@ else } else { - $form->form_confirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne','int')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment), $langs->trans("CloseService"), $langs->trans("ConfirmCloseService",dol_print_date($dateactend,"%A %d %B %Y")), "confirm_closeline", '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne','int')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment), $langs->trans("CloseService"), $langs->trans("ConfirmCloseService",dol_print_date($dateactend,"%A %d %B %Y")), "confirm_closeline", '', 0, 1); } print '
'; } From 144c13998a87fba22acf7bbf20f8b89adc2ad2e0 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 13 Feb 2018 09:51:33 +0100 Subject: [PATCH 15/45] NEW_einstein_pdf_modules --- .../modules/commande/doc/pdf_einstein.modules.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index d8bfff2e528..9fecdc277b5 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -1311,7 +1311,17 @@ class pdf_einstein extends ModelePDFCommandes if ($showaddress) { // Sender properties - $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); + $carac_emetteur=''; + // Add internal contact of proposal if defined + $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $object->fetch_user($arrayidcontact[0]); + $labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name")); + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; + } + + $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); // Show sender $posy=42+$top_shift; From 39a2d0326356f0111e2fda76458af6695f07e75a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 13:36:44 +0100 Subject: [PATCH 16/45] Update changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 3a5fa7d4f37..f9516e49a7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 7.0.0 compared to 6.0.5 ***** For users: +NEW: Add a preview icon after files that can be previewed (pdf + images) NEW: When payment is registered, PDF of invoices are also regenerated so payments appears with no need to click on regenerate. NEW: #5711 Add shipment line deleting and editing for draft shipments. From af9e5885d0423b5b19acc4d01b8e5db01d58288b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 13:36:44 +0100 Subject: [PATCH 17/45] Update changelog --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3a5fa7d4f37..d0893cbc3a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,11 @@ English Dolibarr ChangeLog ***** ChangeLog for 7.0.0 compared to 6.0.5 ***** For users: +NEW: Add a preview icon after files that can be previewed (pdf + images) NEW: When payment is registered, PDF of invoices are also regenerated so payments appears with no need to click on regenerate. NEW: #5711 Add shipment line deleting and editing for draft shipments. +NEW: Accept substitution key __(ABC)__ replaced with value of translation of key ABC NEW: Accept substitution key __[ABC]__ replaced with value of const ABC NEW: Accountancy Add variant on sell account for intracommunity sales & export sales NEW: Add a button "Activate all services" on contracts From 1a4aa894893b252a2aa69f37f262423ab04120ee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 13:55:36 +0100 Subject: [PATCH 18/45] NEW Can share any file from the "Document" tab. --- htdocs/core/actions_linkedfiles.inc.php | 85 +++++++++++----- htdocs/core/class/html.formfile.class.php | 59 ++++++++++-- htdocs/core/lib/files.lib.php | 7 +- htdocs/document.php | 31 +++--- htdocs/ecm/file_card.php | 4 - htdocs/viewimage.php | 112 +++++++++++++++++++--- 6 files changed, 227 insertions(+), 71 deletions(-) diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php index 0e0c444af33..7f938ba9b6c 100644 --- a/htdocs/core/actions_linkedfiles.inc.php +++ b/htdocs/core/actions_linkedfiles.inc.php @@ -182,37 +182,70 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave','alpha')) $filenamefrom=dol_sanitizeFileName(GETPOST('renamefilefrom','alpha'), '_', 0); // Do not remove accents $filenameto=dol_sanitizeFileName(GETPOST('renamefileto','alpha'), '_', 0); // Do not remove accents - // Security: - // Disallow file with some extensions. We rename them. - // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. - if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$filenameto) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + if ($filenamefrom != $filenameto) { - $filenameto.= '.noexe'; - } + // Security: + // Disallow file with some extensions. We rename them. + // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. + if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$filenameto) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + { + $filenameto.= '.noexe'; + } - if ($filenamefrom && $filenameto) - { - $srcpath = $upload_dir.'/'.$filenamefrom; - $destpath = $upload_dir.'/'.$filenameto; + if ($filenamefrom && $filenameto) + { + $srcpath = $upload_dir.'/'.$filenamefrom; + $destpath = $upload_dir.'/'.$filenameto; - $result = dol_move($srcpath, $destpath); - if ($result) - { - if ($object->id) - { - $object->addThumbs($destpath); - } + $result = dol_move($srcpath, $destpath); + if ($result) + { + if ($object->id) + { + $object->addThumbs($destpath); + } - // TODO Add revert function of addThumbs to remove for old name - //$object->delThumbs($srcpath); + // TODO Add revert function of addThumbs to remove for old name + //$object->delThumbs($srcpath); - setEventMessages($langs->trans("FileRenamed"), null); - } - 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'); - } + setEventMessages($langs->trans("FileRenamed"), null); + } + 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'); + } + } } } + + // Update properties in ECM table + if (GETPOST('ecmfileid', 'int') > 0) + { + $shareenabled = GETPOST('shareenabled', 'alpha'); + + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(GETPOST('ecmfileid', 'int')); + if ($result > 0) + { + if ($shareenabled) + { + if (empty($ecmfile->share)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $ecmfile->share = getRandomPassword(true); + } + } + else + { + $ecmfile->share = ''; + } + $result = $ecmfile->update($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + } } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 4bff96700d5..ac5bfdcabb7 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -938,7 +938,7 @@ class FormFile * @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 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 $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this 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. @@ -951,6 +951,7 @@ class FormFile global $user, $conf, $langs, $hookmanager; global $bc,$bcdd; global $sortfield, $sortorder, $maxheightmini; + global $dolibarr_main_url_root; // Define relative path used to store the file if (empty($relativepath)) @@ -1038,6 +1039,7 @@ class FormFile print ''; if (empty($useinecm)) print ''; print ''; + print ''; if (! $disablemove) print ''; print "\n"; } @@ -1047,7 +1049,8 @@ class FormFile print_liste_field_titre('Documents2',$url,"name","",$param,'align="left"',$sortfield,$sortorder); print_liste_field_titre('Size',$url,"size","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre('Date',$url,"date","",$param,'align="center"',$sortfield,$sortorder); - if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); + if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); // Preview + print_liste_field_titre(''); print_liste_field_titre(''); if (! $disablemove) print_liste_field_titre(''); print "\n"; @@ -1063,7 +1066,6 @@ class FormFile //var_dump($sortfield); $filearray=dol_sort_array($filearray, $sortfield, $sortorder); } - //var_dump($filearray); } $nboffiles=count($filearray); @@ -1146,6 +1148,48 @@ class FormFile else print ' '; print ''; } + + // Hash of file (only if we are in a mode where a scan of dir were done and we have id of file in ECM table) + print ''; + if ($relativedir && $filearray[$key]['rowid'] > 0) + { + if ($editline) + { + print $langs->trans("FileSharedViaALink").' '; + print ' '; + } + else + { + if ($file['share']) + { + // 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 + + //print ''.$langs->trans("Hash").' : '.$file['share'].''; + $forcedownload=0; + $paramlink=''; + if (! empty($file['share'])) $paramlink.=($paramlink?'&':'').'hashp='.$file['share']; // Hash for public share + if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1'; + + $fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:''); + //if (! empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path + //elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label; // Hash of file content + + print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' '; + print ''; + //print ' '.$langs->trans("Download").''; // No target here + } + else + { + //print ''.$langs->trans("FileNotShared").''; + } + } + } + print ''; + + // Actions buttons if (! $editline) { // Delete or view link @@ -1215,6 +1259,7 @@ class FormFile else { print ''; + print ''; print ''; print ''; print ''; @@ -1227,9 +1272,9 @@ class FormFile } if ($nboffiles == 0) { - $colspan=(empty($useinecm)?'5':'5'); - if (empty($disablemove)) $colspan++; - print ''; + $colspan=(empty($useinecm)?'6':'6'); + if (empty($disablemove)) $colspan++; // 6 columns or 7 + print ''; if (empty($textifempty)) print $langs->trans("NoFileFound"); else print $textifempty; print ''; @@ -1249,6 +1294,8 @@ class FormFile print ''; } + print ajax_autoselect('downloadlink'); + return $nboffiles; } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 206d1bb8099..b53e588c275 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -225,7 +225,8 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc { global $conf, $db; - $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"; + $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,"; + $sql.=" acl, position, share"; if ($mode) $sql.=", description"; $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; $sql.=" WHERE filepath = '".$db->escape($path)."'"; @@ -258,7 +259,8 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc "keywords" => $obj->keywords, "cover" => $obj->cover, "position" => (int) $obj->position, - "acl" => $obj->acl + "acl" => $obj->acl, + "share" => $obj->share ); } $i++; @@ -318,6 +320,7 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir) $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl']; $filearray[$key]['rowid']=$filearrayindatabase[$key2]['rowid']; $filearray[$key]['label']=$filearrayindatabase[$key2]['label']; + $filearray[$key]['share']=$filearrayindatabase[$key2]['share']; $found=1; break; } diff --git a/htdocs/document.php b/htdocs/document.php index 1c722e4cb55..50f4a61186d 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -25,9 +25,9 @@ * \file htdocs/document.php * \brief Wrapper to download data files * \remarks Call of this wrapper is made with URL: - * document.php?modulepart=repfichierconcerne&file=relativepathoffile - * document.php?modulepart=logs&file=dolibarr.log - * document.php?modulepart=logs&hashp=sharekey + * DOL_URL_ROOT.'/document.php?modulepart=repfichierconcerne&file=relativepathoffile' + * DOL_URL_ROOT.'/document.php?modulepart=logs&file=dolibarr.log' + * DOL_URL_ROOT.'/document.php?hashp=sharekey' */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -36,9 +36,9 @@ //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); //if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); //if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); // Disable "main.inc.php" hooks // For bittorent link, we don't need to load/check we are into a login session if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'bittorrent' && ! defined("NOLOGIN")) @@ -58,9 +58,6 @@ if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias') && ! defined define("NOLOGIN",1); define("NOCSRFCHECK",1); // We accept to go on this page from external web site. } -if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); -if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); -if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); /** * Header empty @@ -75,7 +72,6 @@ function llxHeader() { } */ function llxFooter() { } - require 'main.inc.php'; // Load $user and permissions require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -103,21 +99,17 @@ if (in_array($modulepart, array('facture_paiement','unpaid'))) /* - * Action + * Actions */ // None + /* * View */ -// Define mime type -$type = 'application/octet-stream'; -if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); -else $type=dol_mimetype($original_file); - // Define attachment (attachment=true to force choice popup 'open'/'save as') $attachment = true; if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false; @@ -160,6 +152,10 @@ if (! empty($hashp)) } } +// Define mime type +$type = 'application/octet-stream'; +if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); +else $type=dol_mimetype($original_file); // Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); @@ -252,9 +248,6 @@ header('Content-Length: ' . dol_filesize($fullpath_original_file)); header('Cache-Control: Public, must-revalidate'); header('Pragma: public'); -//ob_clean(); -//flush(); - readfile($fullpath_original_file_osencoded); if (is_object($db)) $db->close(); diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php index 8c62cbe18f2..e0926e0f777 100644 --- a/htdocs/ecm/file_card.php +++ b/htdocs/ecm/file_card.php @@ -341,13 +341,9 @@ if (! empty($object->share)) { if ($action != 'edit') { - $modulepart='ecm'; $forcedownload=0; $paramlink=''; - //if (! empty($modulepart)) $paramlink.=($paramlink?'&':'').'modulepart='.$modulepart; // For sharing with hash (so public files), modulepart is not required. - //if (! empty($object->entity)) $paramlink.='&entity='.$object->entity; // For sharing with hash (so public files), entity is not required. - //$paramlink.=($paramlink?'&':'').'file='.urlencode($filepath); // No need of name of file for public link, we will use the hash if (! empty($object->share)) $paramlink.=($paramlink?'&':'').'hashp='.$object->share; // Hash for public share if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1'; diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 3f7ddbcd1cb..3e2b59ae404 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -20,8 +20,10 @@ /** * \file htdocs/viewimage.php - * \brief Wrapper to show images into Dolibarr screens - * \remarks Call to wrapper is '' + * \brief Wrapper to show images into Dolibarr screens. + * \remarks Call to wrapper is : + * DOL_URL_ROOT.'/viewimage.php?modulepart=diroffile&file=relativepathofofile&cache=0 + * DOL_URL_ROOT.'/viewimage.php?hashp=sharekey */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -35,7 +37,16 @@ if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); // Disable "main.inc.php" hooks // Some value of modulepart can be used to get resources that are public so no login are required. -if ((isset($_GET["modulepart"]) && ($_GET["modulepart"] == 'mycompany' || $_GET["modulepart"] == 'companylogo')) && ! defined("NOLOGIN")) define("NOLOGIN",'1'); +if ((isset($_GET["modulepart"]) && ($_GET["modulepart"] == 'mycompany' || $_GET["modulepart"] == 'companylogo')) && ! defined("NOLOGIN")) +{ + define("NOLOGIN",'1'); +} +// For direct external download link, we don't need to load/check we are into a login session +if (isset($_GET["hashp"]) && ! defined("NOLOGIN")) +{ + define("NOLOGIN",1); +} +// Some value of modulepart can be used to get resources that are public so no login are required. if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias') && ! defined("NOLOGIN")) { define("NOLOGIN",'1'); @@ -57,18 +68,20 @@ function llxHeader() { } */ function llxFooter() { } -require 'main.inc.php'; +require 'main.inc.php'; // Load $user and permissions require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $action=GETPOST('action','alpha'); -$original_file=GETPOST("file",'alpha'); +$original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). +$hashp=GETPOST('hashp','aZ09'); $modulepart=GETPOST('modulepart','alpha'); -$urlsource=GETPOST("urlsource",'alpha'); +$urlsource=GETPOST('urlsource','alpha'); $entity=GETPOST('entity','int')?GETPOST('entity','int'):$conf->entity; // Security check -if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); +if (empty($modulepart) && empty($hashp)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); +if (empty($original_file) && empty($hashp)) accessforbidden('Bad link. Missing identification to find file (original_file or hashp)',0,0,1); if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility @@ -97,9 +110,45 @@ if (GETPOST("cache",'alpha')) //print $dolibarr_nocache; exit; } +// If we have a hash public (hashp), we guess the original_file. +if (! empty($hashp)) +{ + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', '', '', $hashp); + if ($result > 0) + { + $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepath is relative to document directory + $moduleparttocheck = $tmp[0]; + if ($modulepart) // Not required for link using public hashp + { + if ($moduleparttocheck == $modulepart) + { + // We remove first level of directory + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + //var_dump($original_file); exit; + } + else + { + accessforbidden('Bad link. File is from another module part.',0,0,1); + } + } + else + { + $modulepart = $moduleparttocheck; + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + } + } + else + { + $langs->load("errors"); + accessforbidden($langs->trans("ErrorFileNotFoundWithSharedLink"),0,0,1); + } +} + // Define mime type $type = 'application/octet-stream'; -if (! empty($_GET["type"])) $type=$_GET["type"]; +if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); else $type=dol_mimetype($original_file); // Security: Delete string ../ into $original_file @@ -110,16 +159,49 @@ $refname=basename(dirname($original_file)."/"); // Security check if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); -$check_access = dol_check_secure_access_document($modulepart,$original_file,$entity,$refname); + +$check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, $refname); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; -$fullpath_original_file = $check_access['original_file']; +$fullpath_original_file = $check_access['original_file']; // $fullpath_original_file is now a full path name + +if (! empty($hashp)) +{ + $accessallowed = 1; // When using hashp, link is public so we force $accessallowed + $sqlprotectagainstexternals = ''; +} +else +{ + // Basic protection (against external users only) + if ($user->societe_id > 0) + { + if ($sqlprotectagainstexternals) + { + $resql = $db->query($sqlprotectagainstexternals); + if ($resql) + { + $num=$db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($user->societe_id != $obj->fk_soc) + { + $accessallowed=0; + break; + } + $i++; + } + } + } + } +} // Security: // Limit access if permissions are wrong if (! $accessallowed) { - accessforbidden(); + accessforbidden(); } // Security: @@ -128,7 +210,7 @@ if (preg_match('/\.\./',$fullpath_original_file) || preg_match('/[<>|]/',$fullpa { dol_syslog("Refused to deliver file ".$fullpath_original_file); print "ErrorFileNameInvalid: ".$original_file; - exit; + exit; } @@ -174,8 +256,10 @@ else // Open and return file { clearstatcache(); + $filename = basename($fullpath_original_file); + // Output files on browser - dol_syslog("viewimage.php return file $fullpath_original_file content-type=$type"); + dol_syslog("viewimage.php return file $fullpath_original_file filename=$filename content-type=$type"); // This test is to avoid error images when image is not available (for example thumbs). if (! dol_is_file($fullpath_original_file) && empty($_GET["noalt"])) @@ -186,7 +270,7 @@ else // Open and return file exit;*/ } - // Les drois sont ok et fichier trouve + // Permissions are ok and file found, so we return it if ($type) { top_httphead($type); From 7743f88e98efa921e7ccca9ebb947e1c8509c413 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 14:03:11 +0100 Subject: [PATCH 19/45] Fix bad escaping --- htdocs/core/tpl/ajaxrow.tpl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index a75ed1846ff..e4a63b23b3d 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -71,7 +71,8 @@ $(document).ready(function(){ function() { console.log("tableDND end of ajax call"); if (reloadpage == 1) { - location.href = ''; + //console.log(''); + location.href = ''; } else { $("# .drag").each( function( intIndex ) { From 7ed128ff2b642af0aa8ba5e99d4fd0352f50e27b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 14:03:11 +0100 Subject: [PATCH 20/45] Fix bad escaping --- htdocs/core/tpl/ajaxrow.tpl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index a75ed1846ff..e4a63b23b3d 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -71,7 +71,8 @@ $(document).ready(function(){ function() { console.log("tableDND end of ajax call"); if (reloadpage == 1) { - location.href = ''; + //console.log(''); + location.href = ''; } else { $("# .drag").each( function( intIndex ) { From 8a32ae69353d087c2b964c665efeb47dee644d1e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 15:46:39 +0100 Subject: [PATCH 21/45] Move ajax_autoselect into functions.lib.php --- htdocs/core/lib/ajax.lib.php | 18 ------------------ htdocs/core/lib/functions.lib.php | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 2ddc7125d4a..845a758703e 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -358,24 +358,6 @@ function ajax_dialog($title,$message,$w=350,$h=150) } -/** - * Make content of an input box selected when we click into input field. - * - * @param string $htmlname Id of html object - * @param string $addlink Add a 'link to' after - */ -function ajax_autoselect($htmlname, $addlink='') -{ - global $langs; - $out = ''; - if ($addlink) $out.=' '.$langs->trans("Link").''; - return $out; -} - /** * Convert a html select field into an ajax combobox. * Use ajax_combobox() only for small combo list! If not, use instead ajax_autocompleter(). diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a736f3c139a..534555cd8e5 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6861,6 +6861,25 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='' } +/** + * Make content of an input box selected when we click into input field. + * + * @param string $htmlname Id of html object + * @param string $addlink Add a 'link to' after + */ +function ajax_autoselect($htmlname, $addlink='') +{ + global $langs; + $out = ''; + if ($addlink) $out.=' '.$langs->trans("Link").''; + return $out; +} + + /** * Return mime type of a file * From 35aece060cdf34320183525130ce6f7588efe661 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 15:47:17 +0100 Subject: [PATCH 22/45] Search field in correct column --- htdocs/core/class/html.formfile.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index ac5bfdcabb7..3d560c9644e 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1289,13 +1289,13 @@ class FormFile } } + print ajax_autoselect('downloadlink'); + if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline) { print ''; } - print ajax_autoselect('downloadlink'); - return $nboffiles; } } @@ -1344,8 +1344,8 @@ class FormFile if (! empty($addfilterfields)) { print ''; - print ''; print ''; + print ''; print ''; print ''; // Action column From e510e1b679aa97b04f9e10c873b654bcaad33884 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 15:48:29 +0100 Subject: [PATCH 23/45] Fix search field at wrong column --- htdocs/core/class/html.formfile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 4bff96700d5..ba1520e9a81 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1297,8 +1297,8 @@ class FormFile if (! empty($addfilterfields)) { print ''; - print ''; print ''; + print ''; print ''; print ''; // Action column From 92e67ebb8fe34bf73fd632eacf9d7a66d3925f13 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 16:33:45 +0100 Subject: [PATCH 24/45] Fix svg image preview ko --- htdocs/core/lib/functions.lib.php | 3 ++- htdocs/core/lib/images.lib.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 534555cd8e5..457f8068c0e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6844,7 +6844,7 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='' if (empty($conf->use_javascript_ajax)) return ''; - $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css'); + $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css', 'svg+xml'); //$mime_preview[]='vnd.oasis.opendocument.presentation'; //$mime_preview[]='archive'; $num_mime = array_search(dol_mimetype($relativepath, '', 1), $mime_preview); @@ -6950,6 +6950,7 @@ function dol_mimetype($file, $default='application/octet-stream', $mode=0) if (preg_match('/\.gif$/i',$tmpfile)) { $mime='image/gif'; $imgmime='image.png'; $famime='file-image-o'; } if (preg_match('/\.bmp$/i',$tmpfile)) { $mime='image/bmp'; $imgmime='image.png'; $famime='file-image-o'; } if (preg_match('/\.(tif|tiff)$/i',$tmpfile)) { $mime='image/tiff'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.svg$/i',$tmpfile)) { $mime='image/svg+xml';$imgmime='image.png'; $famime='file-image-o'; } // Calendar if (preg_match('/\.vcs$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } if (preg_match('/\.ics$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index e6f69da1d93..f0a666b03e9 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -37,7 +37,7 @@ $quality = 80; */ function image_format_supported($file) { - $regeximgext='\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.xpm|\.xbm'; // See also into product.class.php + $regeximgext='\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.xpm|\.xbm|\.svg'; // See also into product.class.php // Case filename is not a format image if (! preg_match('/('.$regeximgext.')$/i',$file,$reg)) return -1; From 4f369bd746075fa2f60c55167f8218a2a2d5f8cf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 16:34:43 +0100 Subject: [PATCH 25/45] NEW Can force usage of shared link for photo of products --- htdocs/product/class/product.class.php | 40 +++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e6439031146..73d867e7141 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4095,9 +4095,11 @@ class Product extends CommonObject * @param int $maxHeight Max height of original image when size='small' (so we can use original even if small requested). If 0, always use 'small' thumb image. * @param int $maxWidth Max width of original image when size='small' * @param int $nolink Do not add a href link to view enlarged imaged into a new tab + * @param int $notitle Do not add title tag on image + * @param int $usesharelink Use the public shared link of image (if not available, the 'nophoto' image will be shown instead) * @return string Html code to show photo. Number of photos shown is saved in this->nbphoto */ - function show_photos($sdir,$size=0,$nbmax=0,$nbbyrow=5,$showfilename=0,$showaction=0,$maxHeight=120,$maxWidth=160,$nolink=0) + function show_photos($sdir,$size=0,$nbmax=0,$nbbyrow=5,$showfilename=0,$showaction=0,$maxHeight=120,$maxWidth=160,$nolink=0,$notitle=0,$usesharelink=0) { global $conf,$user,$langs; @@ -4196,15 +4198,39 @@ class Product extends CommonObject // Si fichier vignette disponible et image source trop grande, on utilise la vignette, sinon on utilise photo origine $alt=$langs->transnoentitiesnoconv('File').': '.$relativefile; $alt.=' - '.$langs->transnoentitiesnoconv('Size').': '.$imgarray['width'].'x'.$imgarray['height']; + if ($notitle) $alt=''; - if (empty($maxHeight) || $photo_vignette && $imgarray['height'] > $maxHeight) + if ($usesharelink) { - $return.= ''; - $return.= ''; + if ($val['share']) + { + if (empty($maxHeight) || $photo_vignette && $imgarray['height'] > $maxHeight) + { + $return.= ''; + $return.= ''; + } + else { + $return.= ''; + $return.= ''; + } + } + else + { + $return.= ''; + $return.= ''; + } } - else { - $return.= ''; - $return.= ''; + else + { + if (empty($maxHeight) || $photo_vignette && $imgarray['height'] > $maxHeight) + { + $return.= ''; + $return.= ''; + } + else { + $return.= ''; + $return.= ''; + } } if (empty($nolink)) $return.= ''; From 434980bb2212208e401d7d757f3a9ca72af577e7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 16:33:45 +0100 Subject: [PATCH 26/45] Fix svg image preview ko --- htdocs/core/lib/functions.lib.php | 3 ++- htdocs/core/lib/images.lib.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6a67dec48f6..3fc40ab8af6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6832,7 +6832,7 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='' if (empty($conf->use_javascript_ajax)) return ''; - $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css'); + $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css', 'svg+xml'); //$mime_preview[]='vnd.oasis.opendocument.presentation'; //$mime_preview[]='archive'; $num_mime = array_search(dol_mimetype($relativepath, '', 1), $mime_preview); @@ -6919,6 +6919,7 @@ function dol_mimetype($file, $default='application/octet-stream', $mode=0) if (preg_match('/\.gif$/i',$tmpfile)) { $mime='image/gif'; $imgmime='image.png'; $famime='file-image-o'; } if (preg_match('/\.bmp$/i',$tmpfile)) { $mime='image/bmp'; $imgmime='image.png'; $famime='file-image-o'; } if (preg_match('/\.(tif|tiff)$/i',$tmpfile)) { $mime='image/tiff'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.svg$/i',$tmpfile)) { $mime='image/svg+xml';$imgmime='image.png'; $famime='file-image-o'; } // Calendar if (preg_match('/\.vcs$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } if (preg_match('/\.ics$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index e6f69da1d93..f0a666b03e9 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -37,7 +37,7 @@ $quality = 80; */ function image_format_supported($file) { - $regeximgext='\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.xpm|\.xbm'; // See also into product.class.php + $regeximgext='\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.xpm|\.xbm|\.svg'; // See also into product.class.php // Case filename is not a format image if (! preg_match('/('.$regeximgext.')$/i',$file,$reg)) return -1; From b128c95a74ffa4e6e3aaea01933ac8eab15255b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 19:08:46 +0100 Subject: [PATCH 27/45] NEW Add showempty parameter in country selection --- htdocs/core/class/html.form.class.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cbd2eb5c3b3..4e8f67d6552 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -646,9 +646,10 @@ class Form * @param integer $maxlength Max length for labels (0=no limit) * @param string $morecss More css class * @param string $usecodeaskey 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key + * @param int $showempty Show empty choice * @return string HTML string with select */ - function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300',$usecodeaskey='') + function select_country($selected='', $htmlname='country_id', $htmloption='', $maxlength=0, $morecss='minwidth300', $usecodeaskey='', $showempty=1) { global $conf,$langs; @@ -693,20 +694,22 @@ class Form foreach ($countryArray as $row) { + if (empty($showempty) && empty($row['rowid'])) continue; + if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++; if (empty($row['favorite']) && $atleastonefavorite) { $atleastonefavorite=0; - $out.= ''; + $out.= ''; } if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) ) { $foundselected=true; - $out.= '