From 34727286f1c6e154681acc9ca90dec8113b2882a Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Sun, 25 Jun 2017 22:03:06 +0200 Subject: [PATCH 01/62] Let's time to refactoring the tpl folder Propose to refactoring all the file present in /tpl folder for hamonisation with the rest of dolibarr file. Good resolution for this summer --- htdocs/core/tpl/bloc_showhide.tpl.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/core/tpl/bloc_showhide.tpl.php b/htdocs/core/tpl/bloc_showhide.tpl.php index 2c5d71c79d5..60ea83043a8 100644 --- a/htdocs/core/tpl/bloc_showhide.tpl.php +++ b/htdocs/core/tpl/bloc_showhide.tpl.php @@ -49,15 +49,15 @@ $(document).ready(function() { }); -
-
-
+'.img_picto('', '1uparrow.png').''."\n"; +print '
'.img_picto('', '1downarrow.png').'
'."\n"; +print '
'.$title.'
'."\n"; +print '
'."\n"; -
- - - -
-
- - \ No newline at end of file +include DOL_DOCUMENT_ROOT.'/core/tpl/'.$blocname.'.tpl.php'; +print '

'; +?> + From fe749cbd95cdc155ee87e35928fc77b054be9497 Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Sun, 25 Jun 2017 22:27:38 +0200 Subject: [PATCH 02/62] Update bloc_showhide.tpl.php --- htdocs/core/tpl/bloc_showhide.tpl.php | 52 ++++++++++++++------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/htdocs/core/tpl/bloc_showhide.tpl.php b/htdocs/core/tpl/bloc_showhide.tpl.php index 60ea83043a8..a98e8314097 100644 --- a/htdocs/core/tpl/bloc_showhide.tpl.php +++ b/htdocs/core/tpl/bloc_showhide.tpl.php @@ -21,35 +21,37 @@ if (isset($parameters['showblocbydefault'])) $hide=(empty($parameters['showblocb if (isset($object->extraparams[$blocname]['showhide'])) $hide = (empty($object->extraparams[$blocname]['showhide']) ? true : false); ?> - - +print '$("#show-'.$blocname.'").click(function(){'."\n"; +print ' setShowHide(1);'."\n"; +print ' $("#'.$blocname.'").show("blind", {direction: "vertical"}, 300).addClass("nohideobject");'."\n"; +print ' $(this).hide();'."\n"; +print ' $("#hide-'.$blocname.'").show();'."\n"; +print '});'."\n"; + +print 'function setShowHide(status) {'."\n"; +print ' var id = '.$object->id."\n"; +print ' var element = '.$object->element."\n"; +print ' var htmlelement = '.$blocname."\n"; +print ' var type = "showhide";'."\n"; +print ' $.get("'.dol_buildpath('/core/ajax/extraparams.php', 1); +print '?id="+id+"&element="+element+"&htmlelement="+htmlelement+"&type="+type+"&value="+status);'."\n"; +print '}'."\n"; + +print '});'."\n"; +print ''."\n"; -'.img_picto('', '1uparrow.png').''."\n"; print '
Date: Sun, 2 Jul 2017 22:20:07 +0200 Subject: [PATCH 03/62] new addMoreBoxStatsCustomer hook --- htdocs/comm/card.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index a51ef902eb6..0a290af1507 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -604,11 +604,17 @@ if ($id > 0) if ($link) $boxstat.=''; } + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreBoxStatsCustomer', $parameters, $object, $action); + if(empty($reshook)){ + $boxstat.= $hookmanager->resPrint; + } + $boxstat.=''; $boxstat.=''; $boxstat.='
'; - print $boxstat; + print $boxstat; $now=dol_now(); From 30153f8c2ef592a1b90641936fba08129c9ef155 Mon Sep 17 00:00:00 2001 From: Darkjeff Date: Mon, 3 Jul 2017 07:21:15 +0200 Subject: [PATCH 04/62] add in bookkeeping date lim reglement Date lim reglement for export Sage and Iris correct avoir when write in bookkeeping --- htdocs/accountancy/class/bookkeeping.class.php | 7 +++++++ htdocs/accountancy/journal/purchasesjournal.php | 12 ++++++++---- htdocs/accountancy/journal/sellsjournal.php | 12 ++++++++---- .../mysql/tables/llx_accounting_bookkeeping.sql | 1 + .../mysql/tables/llx_accounting_bookkeeping_tmp.sql | 1 + 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 51ef317e917..947a05a5e9e 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -71,6 +71,7 @@ class BookKeeping extends CommonObject /** */ public $doc_date; + public $date_lim_reglement; public $doc_type; public $doc_ref; public $fk_doc; @@ -255,6 +256,7 @@ class BookKeeping extends CommonObject $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " ("; $sql .= "doc_date"; + $sql .= ", date_lim_reglement"; $sql .= ", doc_type"; $sql .= ", doc_ref"; $sql .= ", fk_doc"; @@ -277,6 +279,7 @@ class BookKeeping extends CommonObject $sql .= ', entity'; $sql .= ") VALUES ("; $sql .= "'" . $this->db->idate($this->doc_date) . "'"; + $sql .= ",'" . $this->db->idate($this->date_lim_reglement) . "'"; $sql .= ",'" . $this->db->escape($this->doc_type) . "'"; $sql .= ",'" . $this->db->escape($this->doc_ref) . "'"; $sql .= "," . $this->fk_doc; @@ -441,6 +444,7 @@ class BookKeeping extends CommonObject // Insert request $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . $mode.'('; $sql .= 'doc_date,'; + $sql .= 'date_lim_reglement,'; $sql .= 'doc_type,'; $sql .= 'doc_ref,'; $sql .= 'fk_doc,'; @@ -463,6 +467,7 @@ class BookKeeping extends CommonObject $sql .= 'entity'; $sql .= ') VALUES ('; $sql .= ' ' . (! isset($this->doc_date) || dol_strlen($this->doc_date) == 0 ? 'NULL' : "'" . $this->db->idate($this->doc_date) . "'") . ','; + $sql .= ' ' . (! isset($this->date_lim_reglement) || dol_strlen($this->date_lim_reglement) == 0 ? 'NULL' : "'" . $this->db->idate($this->date_lim_reglement) . "'") . ','; $sql .= ' ' . (! isset($this->doc_type) ? 'NULL' : "'" . $this->db->escape($this->doc_type) . "'") . ','; $sql .= ' ' . (! isset($this->doc_ref) ? 'NULL' : "'" . $this->db->escape($this->doc_ref) . "'") . ','; $sql .= ' ' . (empty($this->fk_doc) ? '0' : $this->fk_doc) . ','; @@ -537,6 +542,7 @@ class BookKeeping extends CommonObject $sql = 'SELECT'; $sql .= ' t.rowid,'; $sql .= " t.doc_date,"; + $sql .= " t.date_lim_reglement,"; $sql .= " t.doc_type,"; $sql .= " t.doc_ref,"; $sql .= " t.fk_doc,"; @@ -574,6 +580,7 @@ class BookKeeping extends CommonObject $this->id = $obj->rowid; $this->doc_date = $this->db->jdate($obj->doc_date); + $this->date_lim_reglement = $this->db->jdate($obj->date_lim_reglement); $this->doc_type = $obj->doc_type; $this->doc_ref = $obj->doc_ref; $this->fk_doc = $obj->fk_doc; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 963ae4f19af..7bd8edc0fc0 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -88,7 +88,7 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end $idpays = $mysoc->country_id; -$sql = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.libelle,f.ref_supplier,"; +$sql = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.libelle,f.ref_supplier, f.date_lim_reglement as dlf, "; $sql .= " fd.rowid as fdid, fd.description, fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type, fd.vat_src_code,"; $sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; $sql .= " p.accountancy_code_buy , aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte"; @@ -154,6 +154,7 @@ if ($result) { } $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df); + $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr); $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier . ' (' . $obj->ref . ')'; $tabfac[$obj->rowid]["refsologest"] = $obj->ref; $tabfac[$obj->rowid]["refsuppliersologest"] = $obj->ref_supplier; @@ -218,6 +219,7 @@ if ($action == 'writebookkeeping') { if ($mt) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'supplier_invoice'; @@ -230,7 +232,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER; $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D'; - $bookkeeping->debit = ($mt <= 0) ? $mt : 0; + $bookkeeping->debit = ($mt <= 0) ? -$mt : 0; $bookkeeping->credit = ($mt > 0) ? $mt : 0; $bookkeeping->code_journal = $journal; $bookkeeping->journal_label = $journal_label; @@ -267,6 +269,7 @@ if ($action == 'writebookkeeping') { if ($accountingaccount->fetch(null, $k, true)) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'supplier_invoice'; @@ -280,7 +283,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'C' : 'D'; $bookkeeping->debit = ($mt > 0) ? $mt : 0; - $bookkeeping->credit = ($mt <= 0) ? $mt : 0; + $bookkeeping->credit = ($mt <= 0) ? -$mt : 0; $bookkeeping->code_journal = $journal; $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; @@ -314,6 +317,7 @@ if ($action == 'writebookkeeping') { // get compte id and label $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'supplier_invoice'; @@ -327,7 +331,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'C' : 'D'; $bookkeeping->debit = ($mt > 0) ? $mt : 0; - $bookkeeping->credit = ($mt <= 0) ? $mt : 0; + $bookkeeping->credit = ($mt <= 0) ? -$mt : 0; $bookkeeping->code_journal = $journal; $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index edaf3a87f27..3f51c1985e5 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -92,7 +92,7 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end $idpays = $mysoc->country_id; -$sql = "SELECT f.rowid, f.facnumber, f.type, f.datef as df, f.ref_client,"; +$sql = "SELECT f.rowid, f.facnumber, f.type, f.datef as df, f.ref_client, f.date_lim_reglement as dlr,"; $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code,"; $sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; $sql .= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte"; @@ -175,6 +175,7 @@ if ($result) { // Invoice lines $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df); + $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr); $tabfac[$obj->rowid]["ref"] = $obj->facnumber; $tabfac[$obj->rowid]["type"] = $obj->type; $tabfac[$obj->rowid]["description"] = $obj->label_compte; @@ -233,6 +234,7 @@ if ($action == 'writebookkeeping') { if ($mt) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'customer_invoice'; @@ -246,7 +248,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C'; $bookkeeping->debit = ($mt >= 0) ? $mt : 0; - $bookkeeping->credit = ($mt < 0) ? $mt : 0; + $bookkeeping->credit = ($mt < 0) ? -$mt : 0; $bookkeeping->code_journal = $journal; $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; @@ -280,6 +282,7 @@ if ($action == 'writebookkeeping') { if ($accountingaccount->fetch(null, $k, true)) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'customer_invoice'; @@ -292,7 +295,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $accountingaccount->label; $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'D' : 'C'; - $bookkeeping->debit = ($mt < 0) ? $mt : 0; + $bookkeeping->debit = ($mt < 0) ? -$mt : 0; $bookkeeping->credit = ($mt >= 0) ? $mt : 0; $bookkeeping->code_journal = $journal; $bookkeeping->journal_label = $journal_label; @@ -326,6 +329,7 @@ if ($action == 'writebookkeeping') { if ($mt) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'customer_invoice'; @@ -338,7 +342,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]); $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'D' : 'C'; - $bookkeeping->debit = ($mt < 0) ? $mt : 0; + $bookkeeping->debit = ($mt < 0) ? -$mt : 0; $bookkeeping->credit = ($mt >= 0) ? $mt : 0; $bookkeeping->code_journal = $journal; $bookkeeping->journal_label = $journal_label; diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql index ad1160c356d..5c5ed42fac0 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql @@ -40,6 +40,7 @@ CREATE TABLE llx_accounting_bookkeeping multicurrency_code varchar(255), -- FEC:Idevise lettering_code varchar(255), -- FEC:EcritureLet date_lettering datetime, -- FEC:DateLet + date_lim_reglement datetime, -- | date limite de reglement fk_user_author integer NOT NULL, -- | user creating fk_user_modif integer, -- | user making last change date_creation datetime, -- FEC:EcritureDate | creation date diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql index 79954769cef..8744429a8fe 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping_tmp.sql @@ -40,6 +40,7 @@ CREATE TABLE llx_accounting_bookkeeping_tmp multicurrency_code varchar(255), -- FEC:Idevise lettering_code varchar(255), -- FEC:EcritureLet date_lettering datetime, -- FEC:DateLet + date_lim_reglement datetime, -- | date limite de reglement fk_user_author integer NOT NULL, -- | user creating fk_user_modif integer, -- | user making last change date_creation datetime, -- FEC:EcritureDate | creation date From 67f11103a37caf61e5d1b295d44855f4e7b27071 Mon Sep 17 00:00:00 2001 From: TuxGasy Date: Tue, 4 Jul 2017 21:56:47 +0200 Subject: [PATCH 05/62] fix indent --- htdocs/comm/card.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 0a290af1507..f46d8060f4c 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -604,17 +604,17 @@ if ($id > 0) if ($link) $boxstat.=''; } - $parameters = array(); - $reshook = $hookmanager->executeHooks('addMoreBoxStatsCustomer', $parameters, $object, $action); - if(empty($reshook)){ - $boxstat.= $hookmanager->resPrint; - } + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreBoxStatsCustomer', $parameters, $object, $action); + if(empty($reshook)){ + $boxstat.= $hookmanager->resPrint; + } $boxstat.=''; $boxstat.=''; $boxstat.=''; - print $boxstat; + print $boxstat; $now=dol_now(); From bec5bde363e5ed22c91ea1aa9a26f18b315da2c0 Mon Sep 17 00:00:00 2001 From: TuxGasy Date: Thu, 6 Jul 2017 12:18:54 +0200 Subject: [PATCH 06/62] Move addMoreBoxStatsCustomer after table tag --- htdocs/comm/card.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index f46d8060f4c..e93bddb2e0b 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -604,16 +604,16 @@ if ($id > 0) if ($link) $boxstat.=''; } + $boxstat.=''; + $boxstat.=''; + $boxstat.=''; + $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreBoxStatsCustomer', $parameters, $object, $action); if(empty($reshook)){ $boxstat.= $hookmanager->resPrint; } - $boxstat.=''; - $boxstat.=''; - $boxstat.=''; - print $boxstat; $now=dol_now(); From ccbeb162cfed29abc9198a4cbfe8358b14c9b6d5 Mon Sep 17 00:00:00 2001 From: gauthier Date: Mon, 17 Jul 2017 11:27:57 +0200 Subject: [PATCH 07/62] FIX : Buying prices must always be in positive valueo --- htdocs/compta/facture.php | 2 +- htdocs/install/mysql/migration/3.8.0-3.9.0.sql | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 34ed1383e14..a5e4334228d 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -771,7 +771,7 @@ if (empty($reshook)) $line->fk_parent_line = $fk_parent_line; $line->subprice =-$line->subprice; // invert price for object - $line->pa_ht = -$line->pa_ht; + $line->pa_ht = $line->pa_ht; $line->total_ht=-$line->total_ht; $line->total_tva=-$line->total_tva; $line->total_ttc=-$line->total_ttc; diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql index 86d2549a8bc..88ba07cc24b 100755 --- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql +++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql @@ -611,3 +611,7 @@ INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (14 -- VMYSQL4.1 ALTER TABLE llx_c_type_resource CHANGE COLUMN rowid rowid integer NOT NULL AUTO_INCREMENT; ALTER TABLE llx_import_model MODIFY COLUMN type varchar(50); + +-- Negative buying prices + +UPDATE llx_facturedet SET buy_price_ht = ABS(buy_price_ht) From 2e63393bf237d142066a9e92cae150a555a291e4 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 21 Jul 2017 19:35:08 +0200 Subject: [PATCH 08/62] Fix: wrong values if array used to force entity 0 --- htdocs/core/modules/DolibarrModules.class.php | 130 +++++++++--------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index d682aa2db97..f98357bb698 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -48,22 +48,22 @@ class DolibarrModules // Can not be abstract, because we need to insta * @var string Publisher name */ public $editor_name; - + /** * @var string URL of module at publisher site */ - public $editor_web; - + public $editor_web; + /** * @var string Family */ public $family; - + /** * @var int module_position */ public $module_position=500; - + /** * @var string Module name */ @@ -171,7 +171,7 @@ class DolibarrModules // Can not be abstract, because we need to insta * @var string Module description (long text) */ public $descriptionlong; - + /** * @var string[] Module language files */ @@ -211,7 +211,7 @@ class DolibarrModules // Can not be abstract, because we need to insta * @var bool Module is enabled globally (Multicompany support) */ public $core_enabled; - + /** * @var string Relative path to module style sheet * @deprecated @@ -219,8 +219,8 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $style_sheet = ''; - - + + /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -468,9 +468,9 @@ class DolibarrModules // Can not be abstract, because we need to insta { global $langs; $langs->load("admin"); - + if (empty($this->descriptionlong)) return ''; - + // If module description translation does not exist using its unique id, we can use its name to find translation if (is_array($this->langfiles)) { @@ -481,7 +481,7 @@ class DolibarrModules // Can not be abstract, because we need to insta } return $langs->trans($this->descriptionlong); } - + /** * Gives the publisher name * @@ -491,7 +491,7 @@ class DolibarrModules // Can not be abstract, because we need to insta { return $this->editor_name; } - + /** * Gives the publisher url * @@ -501,7 +501,7 @@ class DolibarrModules // Can not be abstract, because we need to insta { return $this->editor_url; } - + /** * Gives module version (translated if param $translated is on) * For 'experimental' modules, gives 'experimental' translation @@ -705,7 +705,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -723,7 +723,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -741,7 +741,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data') { @@ -759,7 +759,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update') { @@ -899,19 +899,19 @@ class DolibarrModules // Can not be abstract, because we need to insta //$titre = $this->boxes[$key][0]; $file = $this->boxes[$key]['file']; //$note = $this->boxes[$key][2]; - + // TODO If the box is also included by another module and the other module is still on, we should not remove it. // For the moment, we manage this with hard coded exception //print "Remove box ".$file.'
'; if ($file == 'box_graph_product_distribution.php') { - if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) + if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) { dol_syslog("We discard disabling of module ".$file." because another module still active require it."); continue; } } - + if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility if ($this->db->type == 'sqlite3') { @@ -986,7 +986,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:''; $priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:''; $test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:''; // Line must be visible - + // Search if boxes def already present $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob"; $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'"; @@ -1124,55 +1124,55 @@ class DolibarrModules // Can not be abstract, because we need to insta * * @return int Error count (0 if ok) */ - function insert_tabs() - { - global $conf; + function insert_tabs() + { + global $conf; - $err=0; + $err=0; - if (! empty($this->tabs)) - { - $i=0; - foreach ($this->tabs as $key => $value) - { - if (is_array($value) && count($value) == 0) continue; // Discard empty arrays + if (! empty($this->tabs)) + { + $i=0; + foreach ($this->tabs as $key => $value) + { + if (is_array($value) && count($value) == 0) continue; // Discard empty arrays - $entity=$conf->entity; - $newvalue = $value; + $entity=$conf->entity; + $newvalue = $value; - if (is_array($value)) - { - $newvalue = $value['data']; - if (isset($value['entity'])) $entity = $value['entity']; - } + if (is_array($value)) + { + $newvalue = $value['data']; + if (isset($value['entity'])) $entity = $value['entity']; + } - if ($newvalue) - { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; - $sql.= "name"; - $sql.= ", type"; - $sql.= ", value"; - $sql.= ", note"; - $sql.= ", visible"; - $sql.= ", entity"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1); - $sql.= ", 'chaine'"; - $sql.= ", ".$this->db->encrypt($value,1); - $sql.= ", null"; - $sql.= ", '0'"; - $sql.= ", ".$conf->entity; - $sql.= ")"; + if ($newvalue) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."const ("; + $sql.= "name"; + $sql.= ", type"; + $sql.= ", value"; + $sql.= ", note"; + $sql.= ", visible"; + $sql.= ", entity"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1); + $sql.= ", 'chaine'"; + $sql.= ", ".$this->db->encrypt($newvalue,1); + $sql.= ", null"; + $sql.= ", '0'"; + $sql.= ", ".$entity; + $sql.= ")"; - dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG); - $this->db->query($sql); - } - $i++; - } - } - return $err; - } + dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG); + $this->db->query($sql); + } + $i++; + } + } + return $err; + } /** * Adds constants From 1f5a71f2c92a538ef0086ba0181a9a7514f3901d Mon Sep 17 00:00:00 2001 From: hguibourgdev Date: Sat, 22 Jul 2017 12:18:54 +0200 Subject: [PATCH 09/62] New : Prepare toolkit for alert warning --- htdocs/langs/en_US/stocks.lang | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 746268f7e98..231f5bb3a2e 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -67,6 +67,7 @@ NoPredefinedProductToDispatch=No predefined products for this object. So no disp DispatchVerb=Dispatch StockLimitShort=Limit for alert StockLimit=Stock limit for alert +StockLimitDesc="" (empty) default value means no alert.
"0" can be used with 'Stock can be negative' configuration. PhysicalStock=Physical stock RealStock=Real Stock RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements. @@ -142,4 +143,4 @@ OptionMULTIPRICESIsOn=Option "several prices per segment" is on. It means a prod ProductStockWarehouseCreated=Stock limit for alert and desired optimal stock correctly created ProductStockWarehouseUpdated=Stock limit for alert and desired optimal stock correctly updated ProductStockWarehouseDeleted=Stock limit for alert and desired optimal stock correctly deleted -AddNewProductStockWarehouse=Set new limit for alert and desired optimal stock \ No newline at end of file +AddNewProductStockWarehouse=Set new limit for alert and desired optimal stock From 44023606c65d74217fd02867e62aa5e0692f3346 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Jul 2017 12:47:35 +0200 Subject: [PATCH 10/62] Fix pb in dolGetFirstLineOfText. Add PHPunit --- htdocs/core/lib/files.lib.php | 1 + htdocs/core/lib/functions.lib.php | 51 +++++++++++++++++++---- test/phpunit/FunctionsLibTest.php | 67 ++++++++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 29706e15341..5d3c209bdc7 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -323,6 +323,7 @@ function dol_dir_is_emtpy($folder) * * @param string $file Filename * @return int <0 if KO, Number of lines in files if OK + * @see dol_nboflines */ function dol_count_nb_of_line($file) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a12e4c18ba4..a099b33eee7 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4488,22 +4488,57 @@ function dol_string_nohtmltag($StringHtml,$removelinefeed=1,$pagecodeto='UTF-8') * Return first line of text. Cut will depends if content is HTML or not. * * @param string $text Input text + * @param int $nboflines Nb of lines to get (default is 1 = first line only) * @return string Output text * @see dol_nboflines_bis, dol_string_nohtmltag, dol_escape_htmltag */ -function dolGetFirstLineOfText($text) +function dolGetFirstLineOfText($text, $nboflines=1) { - if (dol_textishtml($text)) + if ($nboflines == 1) { - $firstline=preg_replace('/]*>.*$/s','',$text); // The s pattern modifier means the . can match newline characters - $firstline=preg_replace('/]*>.*$/s','',$firstline); // The s pattern modifier means the . can match newline characters + if (dol_textishtml($text)) + { + $firstline=preg_replace('/]*>.*$/s','',$text); // The s pattern modifier means the . can match newline characters + $firstline=preg_replace('/]*>.*$/s','',$firstline); // The s pattern modifier means the . can match newline characters + } + else + { + $firstline=preg_replace('/[\n\r].*/','',$text); + } + return $firstline.((strlen($firstline) != strlen($text))?'...':''); } else { - $firstline=preg_replace('/[\n\r].*/','',$text); + $ishtml=0; + if (dol_textishtml($text)) + { + $text=preg_replace('/\n/','',$text); + $ishtml=1; + $repTable = array("\t" => " ", "\n" => " ", "\r" => " ", "\0" => " ", "\x0B" => " "); + } + else + { + $repTable = array("\t" => " ", "\n" => "
", "\r" => " ", "\0" => " ", "\x0B" => " "); + } + + $text = strtr($text, $repTable); + if ($charset == 'UTF-8') { $pattern = '/(]*>)/Uu'; } // /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support + else $pattern = '/(]*>)/U'; // /U is to have UNGREEDY regex to limit to one html tag. + $a = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + + $firstline=''; + $i=0; + $nba = count($a); // 2x nb of lines in $a because $a contains also a line for each new line separator + while (($i < $nba) && ($i < ($nboflines * 2))) + { + if ($i % 2 == 0) $firstline .= $a[$i]; + elseif (($i < (($nboflines * 2) - 1)) && ($i < ($nba - 1))) $firstline .= ($ishtml?"
\n":"\n"); + $i++; + } + unset($a); + return $firstline.(($i < $nba)?'...':''); } - return $firstline.((strlen($firstline) != strlen($text))?'...':''); } @@ -4665,7 +4700,7 @@ function dol_nboflines($s,$maxchar=0) /** - * Return nb of lines of a formated text with \n and
(we can't have both \n and br) + * Return nb of lines of a formated text with \n and
(WARNING: string must not have mixed \n and br separators) * * @param string $text Text * @param int $maxlinesize Largeur de ligne en caracteres (ou 0 si pas de limite - defaut) @@ -4701,6 +4736,8 @@ function dol_nboflines_bis($text,$maxlinesize=0,$charset='UTF-8') } } } + + unset($a); return $nblines; } diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 3345d780b7e..814adfb390b 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -120,10 +120,75 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase + /** + * testDolGetFirstLineOfText + * + * @return void + */ + public function testDolGetFirstLineOfText() + { + // Nb of line is same than entry text + + $input="aaaa"; + $result=dolGetFirstLineOfText($input); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa", $result); + + $input="aaaa\nbbbbbbbbbbbb\n"; + $result=dolGetFirstLineOfText($input, 2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa\nbbbbbbbbbbbb", $result); + + $input="aaaa
bbbbbbbbbbbb
"; + $result=dolGetFirstLineOfText($input, 2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa
\nbbbbbbbbbbbb", $result); + + // Nb of line is lower + + $input="aaaa\nbbbbbbbbbbbb\ncccccc\n"; + $result=dolGetFirstLineOfText($input); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa...", $result); + + $input="aaaa
bbbbbbbbbbbb
cccccc
"; + $result=dolGetFirstLineOfText($input); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa...", $result); + + $input="aaaa\nbbbbbbbbbbbb\ncccccc\n"; + $result=dolGetFirstLineOfText($input, 2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa\nbbbbbbbbbbbb...", $result); + + $input="aaaa
bbbbbbbbbbbb
cccccc
"; + $result=dolGetFirstLineOfText($input, 2); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa
\nbbbbbbbbbbbb...", $result); + + // Nb of line is higher + + $input="aaaa
bbbbbbbbbbbb
cccccc"; + $result=dolGetFirstLineOfText($input, 100); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa
\nbbbbbbbbbbbb
\ncccccc", $result, 'dolGetFirstLineOfText with nb 100 a'); + + $input="aaaa
bbbbbbbbbbbb
cccccc
"; + $result=dolGetFirstLineOfText($input, 100); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa
\nbbbbbbbbbbbb
\ncccccc", $result, 'dolGetFirstLineOfText with nb 100 b'); + + $input="aaaa
bbbbbbbbbbbb
cccccc
\n"; + $result=dolGetFirstLineOfText($input, 100); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("aaaa
\nbbbbbbbbbbbb
\ncccccc", $result, 'dolGetFirstLineOfText with nb 100 c'); + } + + /** * testDolBuildPath * - * @return boolean + * @return void */ public function testDolBuildPath() { From 7904e994a7f2ed39f24d27ea01b6cae0759b68c2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Jul 2017 23:43:40 +0200 Subject: [PATCH 11/62] FIX When disconnected, the search box jump to login instead of error. --- htdocs/core/ajax/selectsearchbox.php | 9 +++++++++ htdocs/langs/en_US/other.lang | 1 + htdocs/main.inc.php | 12 +++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php index 2e837fcbaae..2d92bc8f938 100644 --- a/htdocs/core/ajax/selectsearchbox.php +++ b/htdocs/core/ajax/selectsearchbox.php @@ -31,8 +31,17 @@ if (! isset($usedbyinclude) || empty($usedbyinclude)) if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); + if (! defined('NOREDIRECTBYMAINTOLOGIN')) define('NOREDIRECTBYMAINTOLOGIN','1'); $res=@include '../../main.inc.php'; + if ($res == 'ERROR_NOT_LOGGED') + { + $langs->load("other"); + $arrayresult['jumptologin']=array('img'=>'object_generic', 'label'=>$langs->trans("JumpToLogin"), 'text'=>' '.$langs->trans("JumpToLogin"), 'url'=>DOL_URL_ROOT.'/index.php'); + print json_encode($arrayresult); + if (is_object($db)) $db->close(); + exit; + } } include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php'; diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index e519f7af405..bd52f5dcaa2 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -18,6 +18,7 @@ NextMonthOfInvoice=Following month (number 1-12) of invoice date TextNextMonthOfInvoice=Following month (text) of invoice date ZipFileGeneratedInto=Zip file generated into %s. DocFileGeneratedInto=Doc file generated into %s. +JumpToLogin=Disconnected. Go to login page... YearOfInvoice=Year of invoice date PreviousYearOfInvoice=Previous year of invoice date diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1edc67d582f..090a35d6c83 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -457,9 +457,7 @@ if (! defined('NOLOGIN')) $passwordtotest = GETPOST('password','none',2); $entitytotest = (GETPOST('entity','int') ? GETPOST('entity','int') : (!empty($conf->entity) ? $conf->entity : 1)); - // Validation of login/pass/entity - // If ok, the variable login will be returned - // If error, we will put error message in session under the name dol_loginmesg + // Define if we received data to test the login. $goontestloop=false; if (isset($_SERVER["REMOTE_USER"]) && in_array('http',$authmode)) $goontestloop=true; if ($dolibarr_main_authentication == 'forceuser' && ! empty($dolibarr_auto_user)) $goontestloop=true; @@ -473,6 +471,9 @@ if (! defined('NOLOGIN')) $langs->setDefaultLang($langcode); } + // Validation of login/pass/entity + // If ok, the variable login will be returned + // If error, we will put error message in session under the name dol_loginmesg if ($test && $goontestloop) { $login = checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmode); @@ -531,9 +532,10 @@ if (! defined('NOLOGIN')) // End test login / passwords if (! $login || (in_array('ldap',$authmode) && empty($passwordtotest))) // With LDAP we refused empty password because some LDAP are "opened" for anonymous access so connexion is a success. { - // We show login page + // No data to test login, so we show the login page dol_syslog("--- Access to ".$_SERVER["PHP_SELF"]." showing the login form and exit"); - dol_loginfunction($langs,$conf,(! empty($mysoc)?$mysoc:'')); + if (defined('NOREDIRECTBYMAINTOLOGIN')) return 'ERROR_NOT_LOGGED'; + else dol_loginfunction($langs,$conf,(! empty($mysoc)?$mysoc:'')); exit; } From 0963a649b7c359d825d27c0054f3099980275fa0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Jul 2017 23:49:28 +0200 Subject: [PATCH 12/62] Update doc --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index cdbd8ce4b95..2417a7db682 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ NEW: Add a payment module for Stripe. NEW: Add module "Product variant" (like red, blue for the product shoes) NEW: Accountancy - Activate multi-journal & Add journal_label to database (FEC) NEW: Add a tracking id into mass emailing. +NEW: Tax system more compatible with the new tax roollout in India (IGST / CGST / SGST). NEW: Add calculation function for Loan schedule NEW: Add "depends on" and "required by" into module informations NEW: Add hidden option THIRDPARTY_INCLUDE_PARENT_IN_LINKTO From 63b8835885e3abebd8af584961af9c5c82a47152 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sun, 23 Jul 2017 11:42:18 +0200 Subject: [PATCH 13/62] Fix: remove unused $_COOKIE['DOLENTITY'] --- htdocs/master.inc.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php index fc1c41895a4..a8d068cfd7d 100644 --- a/htdocs/master.inc.php +++ b/htdocs/master.inc.php @@ -160,10 +160,6 @@ else if (defined('DOLENTITY') && is_numeric(DOLENTITY)) // For public page wit { $conf->entity = DOLENTITY; } -else if (!empty($_COOKIE['DOLENTITY'])) // For other application with MultiCompany module (TODO: We should remove this. entity to use should never be stored into client side) -{ - $conf->entity = $_COOKIE['DOLENTITY']; -} // Sanitize entity if (! is_numeric($conf->entity)) $conf->entity=1; From c934f1bd13cce511ce8013ad8a717cb5140fad63 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sun, 23 Jul 2017 12:07:20 +0200 Subject: [PATCH 14/62] Fix: remove unused old code --- htdocs/user/logout.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/htdocs/user/logout.php b/htdocs/user/logout.php index 37ff691fdcc..4421c6d6298 100644 --- a/htdocs/user/logout.php +++ b/htdocs/user/logout.php @@ -50,13 +50,6 @@ if ($result < 0) { $error++; } // Define url to go after disconnect $urlfrom=empty($_SESSION["urlfrom"])?'':$_SESSION["urlfrom"]; -// Destroy some cookies -// TODO external module -if (! empty($conf->phenix->enabled) && ! empty($conf->phenix->cookie)) -{ - setcookie($conf->phenix->cookie, '', 1, "/"); -} - // Define url to go $url=DOL_URL_ROOT."/index.php"; // By default go to login page if ($urlfrom) $url=DOL_URL_ROOT.$urlfrom; From 336400d9ea709863dcabf7475906bee6c9b15acb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Jul 2017 16:20:53 +0200 Subject: [PATCH 15/62] Can clone a page onto another website --- htdocs/core/class/html.formwebsite.class.php | 1254 ++++++++++++++++++ htdocs/websites/class/websitepage.class.php | 4 +- htdocs/websites/index.php | 9 +- 3 files changed, 1263 insertions(+), 4 deletions(-) create mode 100644 htdocs/core/class/html.formwebsite.class.php diff --git a/htdocs/core/class/html.formwebsite.class.php b/htdocs/core/class/html.formwebsite.class.php new file mode 100644 index 00000000000..666311d1744 --- /dev/null +++ b/htdocs/core/class/html.formwebsite.class.php @@ -0,0 +1,1254 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/class/html.formwebsite.class.php + * \ingroup core + * \brief File of class to manage component html for module website + */ + + +/** + * Class to manage component html for module website + */ +class FormWebsite +{ + private $db; + public $error; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + + return 1; + } + + + /** + * Return HTML select list of export models + * + * @param string $selected Id modele pre-selectionne + * @param string $htmlname Name of HTML select + * @param int $useempty Show empty value or not + * @return string Html component + */ + function selectWebsite($selected='',$htmlname='exportmodelid',$useempty=0) + { + $out=''; + + $sql = "SELECT rowid, ref"; + $sql.= " FROM ".MAIN_DB_PREFIX."website"; + $sql.= " WHERE 1 = 1"; + $sql.= " ORDER BY rowid"; + $result = $this->db->query($sql); + if ($result) + { + $out.='"; + } + else { + dol_print_error($this->db); + } + + return $out; + } + + + /** + * Return list of export models + * + * @param string $selected Id modele pre-selectionne + * @param string $htmlname Nom de la zone select + * @param string $type Type des modeles recherches + * @param int $useempty Affiche valeur vide dans liste + * @return void + */ + function select_import_model($selected='',$htmlname='importmodelid',$type='',$useempty=0) + { + $sql = "SELECT rowid, label"; + $sql.= " FROM ".MAIN_DB_PREFIX."import_model"; + $sql.= " WHERE type = '".$type."'"; + $sql.= " ORDER BY rowid"; + $result = $this->db->query($sql); + if ($result) + { + print '"; + } + else { + dol_print_error($this->db); + } + } + + + /** + * Return list of ecotaxes with label + * + * @param string $selected Preselected ecotaxes + * @param string $htmlname Name of combo list + * @return integer + */ + function select_ecotaxes($selected='',$htmlname='ecotaxe_id') + { + global $langs; + + $sql = "SELECT e.rowid, e.code, e.libelle, e.price, e.organization,"; + $sql.= " c.label as country"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_ecotaxe as e,".MAIN_DB_PREFIX."c_country as c"; + $sql.= " WHERE e.active = 1 AND e.fk_pays = c.rowid"; + $sql.= " ORDER BY country, e.organization ASC, e.code ASC"; + + dol_syslog(get_class($this).'::select_ecotaxes', LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + print ''; + return 0; + } + else + { + dol_print_error($this->db); + return 1; + } + } + + + /** + * Return list of revenue stamp for country + * + * @param string $selected Value of preselected revenue stamp + * @param string $htmlname Name of combo list + * @param string $country_code Country Code + * @return string HTML select list + */ + function select_revenue_stamp($selected='',$htmlname='revenuestamp',$country_code='') + { + global $langs; + + $out=''; + + $sql = "SELECT r.taux"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_revenuestamp as r,".MAIN_DB_PREFIX."c_country as c"; + $sql.= " WHERE r.active = 1 AND r.fk_pays = c.rowid"; + $sql.= " AND c.code = '".$country_code."'"; + + dol_syslog(get_class($this).'::select_revenue_stamp', LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $out.=''; + return $out; + } + else + { + dol_print_error($this->db); + return ''; + } + } + + + /** + * Return a HTML select list to select a percent + * + * @param integer $selected pourcentage pre-selectionne + * @param string $htmlname nom de la liste deroulante + * @param int $disabled Disabled or not + * @param int $increment increment value + * @param int $start start value + * @param int $end end value + * @param int $showempty Add also an empty line + * @return string HTML select string + */ + function select_percent($selected=0,$htmlname='percent',$disabled=0,$increment=5,$start=0,$end=100,$showempty=0) + { + $return = ''; + + return $return; + } + + /** + * Return select list for categories (to use in form search selectors) + * + * @param int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. + * @param integer $selected Preselected value + * @param string $htmlname Name of combo list + * @param int $nocateg Show also an entry "Not categorized" + * @param int $showempty Add also an empty line + * @param string $morecss More CSS + * @return string Html combo list code + * @see select_all_categories + */ + function select_categories($type, $selected=0, $htmlname='search_categ', $nocateg=0, $showempty=1, $morecss='') + { + global $conf, $langs; + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + + // For backward compatibility + if (is_numeric($type)) + { + dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING); + } + + // Load list of "categories" + $static_categs = new Categorie($this->db); + $tab_categs = $static_categs->get_full_arbo($type); + + $moreforfilter = ''; + // Enhance with select2 + if ($conf->use_javascript_ajax) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $comboenhancement = ajax_combobox('select_categ_'.$htmlname); + $moreforfilter.=$comboenhancement; + } + + // Print a select with each of them + $moreforfilter.=''; + + return $moreforfilter; + } + + + /** + * Return select list for categories (to use in form search selectors) + * + * @param string $selected Preselected value + * @param string $htmlname Name of combo list (example: 'search_sale') + * @param User $user Object user + * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param int $showempty 1=show also an empty value + * @param string $morecss More CSS + * @return string Html combo list code + */ + function select_salesrepresentatives($selected,$htmlname,$user,$showstatus=0,$showempty=1,$morecss='') + { + global $conf,$langs; + $langs->load('users'); + + $out = ''; + // Enhance with select2 + if ($conf->use_javascript_ajax) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + + $comboenhancement = ajax_combobox($htmlname); + if ($comboenhancement) + { + $out.=$comboenhancement; + } + } + // Select each sales and print them in a select input + $out.=''; + + return $out; + } + + /** + * Return list of project and tasks + * + * @param int $selectedtask Pre-selected task + * @param int $projectid Project id + * @param string $htmlname Name of html select + * @param int $modeproject 1 to restrict on projects owned by user + * @param int $modetask 1 to restrict on tasks associated to user + * @param int $mode 0=Return list of tasks and their projects, 1=Return projects and tasks if exists + * @param int $useempty 0=Allow empty values + * @param int $disablechildoftaskid 1=Disable task that are child of the provided task id + * @return void + */ + function selectProjectTasks($selectedtask='', $projectid=0, $htmlname='task_parent', $modeproject=0, $modetask=0, $mode=0, $useempty=0, $disablechildoftaskid=0) + { + global $user, $langs; + + require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; + + //print $modeproject.'-'.$modetask; + $task=new Task($this->db); + $tasksarray=$task->getTasksArray($modetask?$user:0, $modeproject?$user:0, $projectid, 0, $mode); + if ($tasksarray) + { + print ''; + } + else + { + print '
'.$langs->trans("NoProject").'
'; + } + } + + /** + * Write lines of a project (all lines of a project if parent = 0) + * + * @param int $inc Cursor counter + * @param int $parent Id of parent task we want to see + * @param array $lines Array of task lines + * @param int $level Level + * @param int $selectedtask Id selected task + * @param int $selectedproject Id selected project + * @param int $disablechildoftaskid 1=Disable task that are child of the provided task id + * @return void + */ + private function _pLineSelect(&$inc, $parent, $lines, $level=0, $selectedtask=0, $selectedproject=0, $disablechildoftaskid=0) + { + global $langs, $user, $conf; + + $lastprojectid=0; + + $numlines=count($lines); + for ($i = 0 ; $i < $numlines ; $i++) + { + if ($lines[$i]->fk_parent == $parent) + { + $var = !$var; + + //var_dump($selectedproject."--".$selectedtask."--".$lines[$i]->fk_project."_".$lines[$i]->id); // $lines[$i]->id may be empty if project has no lines + + // Break on a new project + if ($parent == 0) // We are on a task at first level + { + if ($lines[$i]->fk_project != $lastprojectid) // Break found on project + { + if ($i > 0) print ''; + print '\n"; + + $lastprojectid=$lines[$i]->fk_project; + $inc++; + } + } + + $newdisablechildoftaskid=$disablechildoftaskid; + + // Print task + if (isset($lines[$i]->id)) // We use isset because $lines[$i]->id may be null if project has no task and are on root project (tasks may be caught by a left join). We enter here only if '0' or >0 + { + // Check if we must disable entry + $disabled=0; + if ($disablechildoftaskid && (($lines[$i]->id == $disablechildoftaskid || $lines[$i]->fk_parent == $disablechildoftaskid))) + { + $disabled++; + if ($lines[$i]->fk_parent == $disablechildoftaskid) $newdisablechildoftaskid=$lines[$i]->id; // If task is child of a disabled parent, we will propagate id to disable next child too + } + + print '\n"; + $inc++; + } + + $level++; + if ($lines[$i]->id) $this->_pLineSelect($inc, $lines[$i]->id, $lines, $level, $selectedtask, $selectedproject, $newdisablechildoftaskid); + $level--; + } + } + } + + + /** + * Output a HTML thumb of color or a text if not defined. + * + * @param string $color String with hex (FFFFFF) or comma RGB ('255,255,255') + * @param string $textifnotdefined Text to show if color not defined + * @return string HTML code for color thumb + * @see selectColor + */ + static function showColor($color, $textifnotdefined='') + { + $textcolor='FFF'; + if ($color) + { + $tmp=explode(',', $color); + if (count($tmp) > 1) // This is a comma RGB ('255','255','255') + { + $r = $tmp[0]; + $g = $tmp[1]; + $b = $tmp[2]; + } + else + { + $hexr=$color[0].$color[1]; + $hexg=$color[2].$color[3]; + $hexb=$color[4].$color[5]; + $r = hexdec($hexr); + $g = hexdec($hexg); + $b = hexdec($hexb); + } + $bright = (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm + if ($bright > 0.6) $textcolor='000'; + } + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $color = colorArrayToHex(colorStringToArray($color,array()),''); + + if ($color) print ''; + else print $textifnotdefined; + } + + /** + * Output a HTML code to select a color + * + * @param string $set_color Pre-selected color + * @param string $prefix Name of HTML field + * @param string $form_name Deprecated. Not used. + * @param int $showcolorbox 1=Show color code and color box, 0=Show only color code + * @param array $arrayofcolors Array of colors. Example: array('29527A','5229A3','A32929','7A367A','B1365F','0D7813') + * @return void + * @deprecated Use instead selectColor + * @see selectColor() + */ + function select_color($set_color='', $prefix='f_color', $form_name='', $showcolorbox=1, $arrayofcolors='') + { + print $this->selectColor($set_color, $prefix, $form_name, $showcolorbox, $arrayofcolors); + } + + /** + * Output a HTML code to select a color. Field will return an hexa color like '334455'. + * + * @param string $set_color Pre-selected color + * @param string $prefix Name of HTML field + * @param string $form_name Deprecated. Not used. + * @param int $showcolorbox 1=Show color code and color box, 0=Show only color code + * @param array $arrayofcolors Array of colors. Example: array('29527A','5229A3','A32929','7A367A','B1365F','0D7813') + * @param string $morecss Add css style into input field + * @return string + * @see showColor + */ + static function selectColor($set_color='', $prefix='f_color', $form_name='', $showcolorbox=1, $arrayofcolors='', $morecss='') + { + // Deprecation warning + if ($form_name) { + dol_syslog(__METHOD__ . ": form_name parameter is deprecated", LOG_WARNING); + } + + global $langs,$conf; + + $out=''; + + if (! is_array($arrayofcolors) || count($arrayofcolors) < 1) + { + $langs->load("other"); + if (empty($conf->dol_use_jmobile)) + { + $out.= ''; + $out.= ''; + $out.= ''; + } + $out.= ''; + } + else // In most cases, this is not used. We used instead function with no specific list of colors + { + if (empty($conf->dol_use_jmobile)) + { + $out.= ''; + $out.= ''; + $out.= ''; + } + $out.= ''; + } + + return $out; + } + + /** + * Creation d'un icone de couleur + * + * @param string $color Couleur de l'image + * @param string $module Nom du module + * @param string $name Nom de l'image + * @param int $x Largeur de l'image en pixels + * @param int $y Hauteur de l'image en pixels + * @return void + */ + function CreateColorIcon($color,$module,$name,$x='12',$y='12') + { + global $conf; + + $file = $conf->$module->dir_temp.'/'.$name.'.png'; + + // On cree le repertoire contenant les icones + if (! file_exists($conf->$module->dir_temp)) + { + dol_mkdir($conf->$module->dir_temp); + } + + // On cree l'image en vraies couleurs + $image = imagecreatetruecolor($x,$y); + + $color = substr($color,1,6); + + $rouge = hexdec(substr($color,0,2)); //conversion du canal rouge + $vert = hexdec(substr($color,2,2)); //conversion du canal vert + $bleu = hexdec(substr($color,4,2)); //conversion du canal bleu + + $couleur = imagecolorallocate($image,$rouge,$vert,$bleu); + //print $rouge.$vert.$bleu; + imagefill($image,0,0,$couleur); //on remplit l'image + // On cree la couleur et on l'attribue a une variable pour ne pas la perdre + ImagePng($image,$file); //renvoie une image sous format png + ImageDestroy($image); + } + + /** + * Return HTML combo list of week + * + * @param string $selected Preselected value + * @param string $htmlname Nom de la zone select + * @param int $useempty Affiche valeur vide dans liste + * @return string + */ + function select_dayofweek($selected='',$htmlname='weekid',$useempty=0) + { + global $langs; + + $week = array( 0=>$langs->trans("Day0"), + 1=>$langs->trans("Day1"), + 2=>$langs->trans("Day2"), + 3=>$langs->trans("Day3"), + 4=>$langs->trans("Day4"), + 5=>$langs->trans("Day5"), + 6=>$langs->trans("Day6")); + + $select_week = ''; + return $select_week; + } + + /** + * Return HTML combo list of month + * + * @param string $selected Preselected value + * @param string $htmlname Name of HTML select object + * @param int $useempty Show empty in list + * @param int $longlabel Show long label + * @return string + */ + function select_month($selected='',$htmlname='monthid',$useempty=0,$longlabel=0) + { + global $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + + if ($longlabel) $montharray = monthArray($langs, 0); // Get array + else $montharray = monthArray($langs, 1); + + $select_month = ''; + return $select_month; + } + + /** + * Return HTML combo list of years + * + * @param string $selected Preselected value (''=current year, -1=none, year otherwise) + * @param string $htmlname Name of HTML select object + * @param int $useempty Affiche valeur vide dans liste + * @param int $min_year Offset of minimum year into list (by default current year -10) + * @param int $max_year Offset of maximum year into list (by default current year + 5) + * @param int $offset Offset + * @param int $invert Invert + * @param string $option Option + * @return string + */ + function select_year($selected='',$htmlname='yearid',$useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='') + { + print $this->selectyear($selected,$htmlname,$useempty,$min_year,$max_year,$offset,$invert,$option); + } + + /** + * Return HTML combo list of years + * + * @param string $selected Preselected value (''=current year, -1=none, year otherwise) + * @param string $htmlname Name of HTML select object + * @param int $useempty Affiche valeur vide dans liste + * @param int $min_year Offset of minimum year into list (by default current year -10) + * @param int $max_year Offset of maximum year into list (by default current year + 5) + * @param int $offset Offset + * @param int $invert Invert + * @param string $option Option + * @return string + */ + function selectyear($selected='',$htmlname='yearid',$useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='') + { + $out=''; + + $currentyear = date("Y")+$offset; + $max_year = $currentyear+$max_year; + $min_year = $currentyear-$min_year; + if(empty($selected) && empty($useempty)) $selected = $currentyear; + + $out.= '\n"; + + return $out; + } + + /** + * Show form to select address + * + * @param int $page Page + * @param string $selected Id condition pre-selectionne + * @param int $socid Id of third party + * @param string $htmlname Nom du formulaire select + * @param string $origin Origine de l'appel pour pouvoir creer un retour + * @param int $originid Id de l'origine + * @return void + */ + function form_address($page, $selected, $socid, $htmlname='address_id', $origin='', $originid='') + { + global $langs,$conf; + global $form; + + if ($htmlname != "none") + { + print '
'; + print ''; + print ''; + $form->select_address($selected, $socid, $htmlname, 1); + print ''; + $langs->load("companies"); + print '   '.$langs->trans("AddAddress").''; + print '
'; + } + else + { + if ($selected) + { + require_once DOL_DOCUMENT_ROOT .'/societe/class/address.class.php'; + $address=new Address($this->db); + $result=$address->fetch_address($selected); + print ''.$address->label.''; + } + else + { + print " "; + } + } + } + + + + /** + * Get array with HTML tabs with boxes of a particular area including personalized choices of user. + * Class 'Form' must be known. + * + * @param User $user Object User + * @param String $areacode Code of area for pages ('0'=value for Home page) + * @return array array('selectboxlist'=>, 'boxactivated'=>, 'boxlista'=>, 'boxlistb'=>) + */ + static function getBoxesArea($user,$areacode) + { + global $conf,$langs,$db; + + include_once DOL_DOCUMENT_ROOT.'/core/class/infobox.class.php'; + + $confuserzone='MAIN_BOXES_'.$areacode; + + // $boxactivated will be array of boxes enabled into global setup + // $boxidactivatedforuser will be array of boxes choosed by user + + $selectboxlist=''; + $boxactivated=InfoBox::listBoxes($db, 'activated', $areacode, (empty($user->conf->$confuserzone)?null:$user), array(), 0); // Search boxes of common+user (or common only if user has no specific setup) + + $boxidactivatedforuser=array(); + foreach($boxactivated as $box) + { + if (empty($user->conf->$confuserzone) || $box->fk_user == $user->id) $boxidactivatedforuser[$box->id]=$box->id; // We keep only boxes to show for user + } + + // Define selectboxlist + $arrayboxtoactivatelabel=array(); + if (! empty($user->conf->$confuserzone)) + { + $boxorder=''; + $langs->load("boxes"); // Load label of boxes + foreach($boxactivated as $box) + { + if (! empty($boxidactivatedforuser[$box->id])) continue; // Already visible for user + $label=$langs->transnoentitiesnoconv($box->boxlabel); + if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')'; + //$label = ''.$label; KO with select2. No html rendering. + $arrayboxtoactivatelabel[$box->id]=$label; // We keep only boxes not shown for user, to show into combo list + } + foreach($boxidactivatedforuser as $boxid) + { + if (empty($boxorder)) $boxorder.='A:'; + $boxorder.=$boxid.','; + } + + //var_dump($boxidactivatedforuser); + + // Class Form must have been already loaded + $selectboxlist.='
'; + $selectboxlist.=''; + $selectboxlist.=''; + $selectboxlist.=''; + $selectboxlist.=''; + $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected', 0, 1); + if (empty($conf->use_javascript_ajax)) $selectboxlist.=' '; + $selectboxlist.='
'; + $selectboxlist.=ajax_combobox("boxcombo"); + } + + // Javascript code for dynamic actions + if (! empty($conf->use_javascript_ajax)) + { + $selectboxlist.=''."\n"; + } + + // Define boxlista and boxlistb + $nbboxactivated=count($boxidactivatedforuser); + + if ($nbboxactivated) + { + $langs->load("boxes"); + $langs->load("projects"); + + $emptybox=new ModeleBoxes($db); + + $boxlista.="\n\n"; + $boxlista.='
'."\n"; + + // Define $box_max_lines + $box_max_lines=5; + if (! empty($conf->global->MAIN_BOXES_MAXLINES)) $box_max_lines=$conf->global->MAIN_BOXES_MAXLINES; + + $ii=0; + foreach ($boxactivated as $key => $box) + { + if ((! empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) continue; + if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) $box->box_order='A'.sprintf("%02d",($ii+1)); // When box_order was not yet set to Axx or Bxx and is still 0 + if (preg_match('/^A/i',$box->box_order)) // column A + { + $ii++; + //print 'box_id '.$boxactivated[$ii]->box_id.' '; + //print 'box_order '.$boxactivated[$ii]->box_order.'
'; + // Show box + $box->loadBox($box_max_lines); + $boxlista.= $box->outputBox(); + } + } + + if (empty($conf->browser->phone)) + { + $emptybox->box_id='A'; + $emptybox->info_box_head=array(); + $emptybox->info_box_contents=array(); + $boxlista.= $emptybox->outputBox(array(),array()); + } + $boxlista.= "
\n"; + $boxlista.= "\n"; + + $boxlistb.= "\n\n"; + $boxlistb.= '\n"; + $boxlistb.= "\n"; + + } + + return array('selectboxlist'=>count($boxactivated)?$selectboxlist:'', 'boxactivated'=>$boxactivated, 'boxlista'=>$boxlista, 'boxlistb'=>$boxlistb); + } + + + /** + * Return a HTML select list of bank accounts + * + * @param string $htmlname Name of select zone + * @param string $dictionarytable Dictionary table + * @param string $keyfield Field for key + * @param string $labelfield Label field + * @param string $selected Selected value + * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @param string $moreattrib More attributes on HTML select tag + * @return void + */ + function select_dictionary($htmlname,$dictionarytable,$keyfield='code',$labelfield='label',$selected='',$useempty=0,$moreattrib='') + { + global $langs, $conf; + + $langs->load("admin"); + + $sql = "SELECT rowid, ".$keyfield.", ".$labelfield; + $sql.= " FROM ".MAIN_DB_PREFIX.$dictionarytable; + $sql.= " ORDER BY ".$labelfield; + + dol_syslog(get_class($this)."::select_dictionary", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + if ($num) + { + print '"; + } + else + { + print $langs->trans("DictionaryEmpty"); + } + } + else { + dol_print_error($this->db); + } + } + +} + diff --git a/htdocs/websites/class/websitepage.class.php b/htdocs/websites/class/websitepage.class.php index 73158fac7be..7d5e59830e1 100644 --- a/htdocs/websites/class/websitepage.class.php +++ b/htdocs/websites/class/websitepage.class.php @@ -500,9 +500,10 @@ class WebsitePage extends CommonObject * @param string $newref New ref/alias of page * @param string $newlang New language * @param int $istranslation 1=New page is a translation of the cloned page. + * @param int $newwebsite 0=Same web site, 1=New web site * @return int New id of clone */ - public function createFromClone($fromid, $newref, $newlang='', $istranslation=0) + public function createFromClone($fromid, $newref, $newlang='', $istranslation=0, $newwebsite=0) { global $user, $langs; @@ -525,6 +526,7 @@ class WebsitePage extends CommonObject if (! empty($newlang)) $object->lang=$newlang; if ($istranslation) $object->fk_page = $fromid; else $object->fk_page = 0; + if (! empty($newwebsite)) $object->fk_website=$newwebsite; // Create clone $result = $object->create($user); diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index d692295d2a5..14bb0b3a90f 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -66,12 +66,12 @@ function llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, } - require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formwebsite.class.php'; require_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php'; require_once DOL_DOCUMENT_ROOT.'/websites/class/websitepage.class.php'; @@ -549,7 +549,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf if (! $error) { $objectpage = new WebsitePage($db); - $result = $objectpage->createFromClone($pageid, GETPOST('pageurl','aZ09'), (GETPOST('newlang','aZ09')?GETPOST('newlang','aZ09'):''), $istranslation); + $result = $objectpage->createFromClone($pageid, GETPOST('pageurl','aZ09'), (GETPOST('newlang','aZ09')?GETPOST('newlang','aZ09'):''), $istranslation, GETPOST('newwebsite','int')); if ($result < 0) { $error++; @@ -745,6 +745,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf $form = new Form($db); $formadmin = new FormAdmin($db); +$formwebsite = new FormWebsite($db); $help_url=''; @@ -958,7 +959,9 @@ if (count($object->records) > 0) $formquestion = array( array('type' => 'text', 'name' => 'pageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME") ,'value'=> 'copy_of_'.$objectpage->pageurl), array('type' => 'checkbox', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0), - array('type' => 'other','name' => 'newlang','label' => $langs->trans("Language"), 'value' => $formadmin->select_language(GETPOST('newlang', 'az09')?GETPOST('newlang', 'az09'):$langs->defaultlang, 'newlang', 0, null, '', 0, 0, 'minwidth200'))); + array('type' => 'other','name' => 'newlang','label' => $langs->trans("Language"), 'value' => $formadmin->select_language(GETPOST('newlang', 'az09')?GETPOST('newlang', 'az09'):$langs->defaultlang, 'newlang', 0, null, '', 0, 0, 'minwidth200')), + array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("Website"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)) + ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?pageid=' . $pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 250); From 7eee529c9f166dad8a77cd08cf1c69c18012895f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Jul 2017 16:28:56 +0200 Subject: [PATCH 16/62] Can use - and _ into website alias --- htdocs/websites/index.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 14bb0b3a90f..c8ba93c86f1 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -174,10 +174,11 @@ if ($action == 'add') $error++; $action='create'; } - else if (! preg_match('/^[a-z0-9]+$/i', $objectpage->pageurl)) + else if (! preg_match('/^[a-z0-9\-\_]+$/i', $objectpage->pageurl)) { - $error++; setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities('WEBSITE_PAGENAME')), null, 'errors'); + $error++; + $action='create'; } if (empty($objectpage->title)) { From f3de6cfd3275b29cbee9323d6fb57c316415c53c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Jul 2017 17:44:26 +0200 Subject: [PATCH 17/62] Support for robots and .htaccess file --- htdocs/websites/index.php | 125 ++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 13 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index c8ba93c86f1..0f1e813e3ed 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -138,6 +138,8 @@ global $dolibarr_main_data_root; $pathofwebsite=$dolibarr_main_data_root.'/websites/'.$website; $filehtmlheader=$pathofwebsite.'/htmlheader.html'; $filecss=$pathofwebsite.'/styles.css.php'; +$filerobot=$pathofwebsite.'/robots.txt'; +$filehtaccess=$pathofwebsite.'/.htaccess'; $filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php'; $fileindex=$pathofwebsite.'/index.php'; @@ -311,7 +313,6 @@ if ($action == 'updatecss') $csscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; $csscontent.= "// END PHP ?>"."\n"; - dol_syslog("Save file css into ".$filecss); dol_mkdir($pathofwebsite); @@ -326,6 +327,70 @@ if ($action == 'updatecss') } + // Css file + $robotcontent =''; + + /*$robotcontent.= "\n";*/ + + $robotcontent.= GETPOST('WEBSITE_ROBOT'); + + /*$robotcontent.= "\n".'"."\n";*/ + + dol_syslog("Save file robot into ".$filerobot); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filerobot, $robotcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filerobot, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filerobot, null, 'errors'); + } + + + // Css file + $htaccesscontent =''; + + /*$robotcontent.= "\n";*/ + + $htaccesscontent.= GETPOST('WEBSITE_HTACCESS'); + + /*$robotcontent.= "\n".'"."\n";*/ + + dol_syslog("Save file htaccess into ".$filehtaccess); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filehtaccess, $htaccesscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filehtaccess, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filehtaccess, null, 'errors'); + } + + // Message if no error if (! $error) { setEventMessages($langs->trans("Saved"), null, 'mesgs'); @@ -1098,30 +1163,49 @@ if ($action == 'editcss') $csscontent = @file_get_contents($filecss); // Clean the php css file to remove php code and get only css part $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $csscontent); - $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); - if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n".'body.bodywebsite { margin: 0; }'; - $htmlheader = @file_get_contents($filehtmlheader); // Clean the php htmlheader file to remove php code and get only html part $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $htmlheader); - if (! trim($htmlheader)) $htmlheader=''."\n".''."\n".''; else $htmlheader=''."\n".$htmlheader."\n".''; + $robotcontent = @file_get_contents($filerobot); + // Clean the php htmlheader file to remove php code and get only html part + $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $robotcontent); + if (! trim($robotcontent)) + { + $robotcontent.="# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n"; + $robotcontent.="User-agent: *\n"; + $robotcontent.="Allow: /public/\n"; + $robotcontent.="Disallow: /administrator/\n"; + } + + $htaccesscontent = @file_get_contents($filehtaccess); + // Clean the php htmlheader file to remove php code and get only html part + $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $htaccesscontent); + if (! trim($htaccesscontent)) + { + $htaccesscontent.="# Order allow,deny\n"; + $htaccesscontent.="# Deny from all\n"; + } + //else $htaccesscontent=''."\n".$htaccesscontent."\n".'';*/ + dol_fiche_head(); print ''."\n"; print ''; + // Website print ''; + // CSS file print ''; + // Common HTML header print ''; + + // Robot file + print ''; + + // .htaccess + print ''; print '
'; print $langs->trans('WebSite'); print ''; print $website; print '
'; print $langs->trans('WEBSITE_CSS_INLINE'); print ''; @@ -1129,11 +1213,9 @@ if ($action == 'editcss') $doleditor=new DolEditor('WEBSITE_CSS_INLINE', $csscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'CSS', 'css'); - /*print '';*/ print '
'; print $langs->trans('WEBSITE_HTML_HEADER'); print ''; @@ -1141,9 +1223,26 @@ if ($action == 'editcss') $doleditor=new DolEditor('WEBSITE_HTML_HEADER', $htmlheader, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); print $doleditor->Create(1, '', true, 'HTML Header', 'html'); - /*print '';*/ + print '
'; + print $langs->trans('WEBSITE_ROBOT'); + print ''; + + $doleditor=new DolEditor('WEBSITE_ROBOT', $robotcontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + print $doleditor->Create(1, '', true, 'Robot file', 'txt'); + + print '
'; + print $langs->trans('WEBSITE_HTACCESS'); + print ''; + + $doleditor=new DolEditor('WEBSITE_HTACCESS', $htaccesscontent, '', '220', 'ace', 'In', true, false, 'ace', 0, '100%', ''); + print $doleditor->Create(1, '', true, $langs->trans("File").' .htaccess', 'txt'); + print '
'; @@ -1242,7 +1341,7 @@ if ($action == 'editsource') * Editing global variables not related to a specific theme */ - $csscontent = @file_get_contents($filecss); + //$csscontent = @file_get_contents($filecss); $contentforedit = ''; /*$contentforedit.='