diff --git a/ChangeLog b/ChangeLog index e55cfad84d1..b67cbabafb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,103 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 15.0.2 compared to 15.0.1 ***** + +FIX: #19777 #20281 +FIX: #20140 #20301 +FIX: #20279 Accountancy - PostGreSQL - Error on mass update lines already binded +FIX: #20476 migration postgresql 14.0.x to 15.0.x packaging type +FIX: #20733 Inventory: Do not use batch qty even if present if batch module is disabled. +FIX: action comm list: holiday last day not included + handle duration with halfdays +FIX: Add missing entity on salary's payment +FIX: Add 'recruitment' into check array +FIX: add tools to fix bad bank amount in accounting with multicurrency +FIX: assign member cateogry to a member +FIX: backport +FIX: bad bank amount in accounting with multicurrency +FIX: Bad condition on remx +FIX: Bad filter on date on salary list +FIX: bad link to add a customer price (token duplicated) +FIX: bad status of member on widget by type and status +FIX: better error management at product selling price update +FIX: Can't edit bank record +FIX: check mandatory thirdparty fields for mass action +FIX: check thirdparty object loaded and properties exist +FIX: comment +FIX: compatibility for ticket number sharing +FIX: compatibility with multicompany sharings +FIX: contact card: single extrafield update failed +FIX: country not visible into list of states +FIX: Delete an extrafield where type is double +FIX: deprecated module are not more viewed as external modules +FIX: Disable customer type by default if type prospect/customer is disabled +FIX: each time we create a supplier order, we need to give it a ref_supplier +FIX: Error management +FIX: fatal error for $db usage in tpl +FIX: filter into the list of product lots +FIX: Filter on Object Referent page give CRSF page +FIX: Fix default options ($hidedetails, $hidedesc, $hideref) with globales when generate PDF in mass actions +FIX: Fix search by filters +FIX: Fix the adding of lines in the create invoice functions +FIX: forgotten form confirm before various payment delete +FIX: holiday/leave requests: write status change emails in HTML +FIX: include discount price for PMP after a reception (Issue #20029) +FIX: incrementation +FIX: in salary stats and payment list, we must check right perms as well as salary list +FIX: intervention entity missing +FIX: label tax cat trad +FIX: Mass action ship orders +FIX: missing advanced perms +FIX: missing call to executeHooks() +FIX: Missing entity on adding new VAT +FIX: missing hook for row ordering +FIX: missing hook parameter ($possiblelinks) +FIX: missing parenthesis +FIX: missing picto in combo of mass actions of thirdparties. +FIX: missing signature library when ODT model is used +FIX: Missing unset fields after updateline expensereport +FIX: ModuileBuilder - Fix getLinesArray() error reporting +FIX: Move delete task time trigger position +FIX: Navigation between invoices +FIX: No empty line inserted into accounting_bookkeeping +FIX: Numbering of sepa files +FIX: object cloning: set unique extrafield values to null to prevent duplicates +FIX: on update with action reminder in future there is user key error +FIX: originproductline array td identification data-id +FIX: out of memory when more than 100 000 invoices. +FIX: permit access to medias when logged in a different entity +FIX: phpcs +FIX: project creation prevented if PROJECTLEADER contact role renamed, de-activated or deleted +FIX: project timesheet by week: cleanup unused code +FIX: project timesheet: public holidays offset by 1 day +FIX: project timesheets: assume Saturday and Sunday as default weekend days when working days conf is empty or badly formed +FIX: propal list: bad error management when setting "not signed" mass action +FIX: propal list mass action translations and error management (v14 edition) +FIX: propal list: missing not signed massaction translation keys for transifex +FIX: PR returns +FIX: ref_client doesn't exists on supplier invoice, then ref_fourn needs to have a default value when we want to bill several supplier orders +FIX: replenish and manage product stock by warhouse +FIX: sending email on payment of registration of event +FIX: SEPA ICS is not mandatory for bank transfer +FIX: Set datec when add time spent on a project task +FIX: status filter on supplierOrder stats doesn't work +FIX: stickler-ci +FIX: still prevent project creation if PROJECTLEADER role unavailable, but with a specific error message +FIX: Supplier order stats +FIX: Tabulation must be allowed for HTML content +FIX: tool to fix bank account not in main currency for vendor invoice +FIX: translations +FIX: Travis + Update dev +FIX: truncate Customer Reference too long on PDF header (PR #20718) +FIX: uniformize code +FIX: Update of sale price (log not correctly updated) +FIX: user actions rights when mulit-company transverse mode is enabled +FIX: user employee tab: offset in open days messes up holiday length calculation +FIX: We need to have a different default_ref_supplier for each new fourn invoice +FIX: "WHERE" clause missing on resource export +FIX: #yogosha9754 + + ***** ChangeLog for 15.0.1 compared to 15.0.0 ***** FIX: #19777 #20281 FIX: bad position of extrafields for interventions diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index d43d35f84c7..0fd0b719cd7 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -431,12 +431,12 @@ if ($action == 'create') { // Account movement print ''; print ''.$langs->trans("NumMvts").''; - print ''.$object->piece_num.''; + print ''.($mode == '_tmp' ? ''.$langs->trans("Draft").'' : $object->piece_num).''; print ''; // Date print ''; - print '
'; + print ''; if ($action != 'editdate') { diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 507292d777a..94c0b717aef 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -1851,57 +1851,82 @@ class BookKeeping extends CommonObject if ($next_piecenum < 0) { $error++; } - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.' (doc_date, doc_type,'; - $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; - $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; - $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num, date_creation)'; - $sql .= ' SELECT doc_date, doc_type,'; - $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; - $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; - $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'"; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + if (!$error) { + // Delete if there is an empty line + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity)." AND numero_compte IS NULL AND debit = 0 AND credit = 0"; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + } } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + if (!$error) { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.' (doc_date, doc_type,'; + $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; + $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; + $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num, date_creation)'; + $sql .= ' SELECT doc_date, doc_type,'; + $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; + $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; + $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'"; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + } + } + + if (!$error) { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + } } } elseif ($direction == 1) { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + if (!$error) { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + } } - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'_tmp (doc_date, doc_type,'; - $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; - $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; - $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num)'; - $sql .= ' SELECT doc_date, doc_type,'; - $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; - $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; - $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + if (!$error) { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'_tmp (doc_date, doc_type,'; + $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; + $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; + $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num)'; + $sql .= ' SELECT doc_date, doc_type,'; + $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; + $sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; + $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num'; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + } } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); - dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + if (!$error) { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + } } } if (!$error) { diff --git a/htdocs/compta/bank/line.php b/htdocs/compta/bank/line.php index bc70d27ba70..3cde5212e2d 100644 --- a/htdocs/compta/bank/line.php +++ b/htdocs/compta/bank/line.php @@ -52,11 +52,12 @@ if (!empty($conf->salaries->enabled)) { $id = GETPOST('rowid', 'int'); -$accountid = (GETPOST('id', 'int') ? GETPOST('id', 'int') : GETPOST('account', 'int')); +$rowid = GETPOST("rowid", 'int'); +$accountoldid = GETPOST('account', 'int'); // GETPOST('account') is old account id +$accountid = GETPOST('accountid', 'int'); // GETPOST('accountid') is new account id $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -$rowid = GETPOST("rowid", 'int'); $orig_account = GETPOST("orig_account"); $backtopage = GETPOST('backtopage', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); @@ -69,7 +70,7 @@ if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'banque', $accountid, 'bank_account'); +$result = restrictedArea($user, 'banque', $accountoldid, 'bank_account'); if (empty($user->rights->banque->lire) && empty($user->rights->banque->consolidate)) { accessforbidden(); } @@ -124,18 +125,26 @@ if ($user->rights->banque->modifier && $action == "update") { $error = 0; $acline = new AccountLine($db); - $acline->fetch($rowid); + $result = $acline->fetch($rowid); + if ($result <= 0) { + dol_syslog('Failed to read bank line with id '.$rowid, LOG_WARNING); // This happens due to old bug that has set fk_account to null. + $acline->id = $rowid; + } $acsource = new Account($db); - $acsource->fetch($id); + $acsource->fetch($accountoldid); $actarget = new Account($db); if (GETPOST('accountid', 'int') > 0 && !$acline->rappro && !$acline->getVentilExportCompta()) { // We ask to change bank account $actarget->fetch(GETPOST('accountid', 'int')); } else { - $actarget->fetch($id); + $actarget->fetch($accountoldid); } + if (!($actarget->id > 0)) { + setEventMessages($langs->trans("ErrorFailedToLoadBankAccount"), null, 'errors'); + $error++; + } if ($actarget->courant == Account::TYPE_CASH && GETPOST('value', 'alpha') != 'LIQ') { setEventMessages($langs->trans("ErrorCashAccountAcceptsOnlyCashMoney"), null, 'errors'); $error++; @@ -229,7 +238,7 @@ if ($user->rights->banque->consolidate && ($action == 'num_releve' || $action == $db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."bank"; - $sql .= " SET num_releve=".($num_rel ? "'".$db->escape($num_rel)."'" : "null"); + $sql .= " SET num_releve = ".($num_rel ? "'".$db->escape($num_rel)."'" : "null"); if (empty($num_rel)) { $sql .= ", rappro = 0"; } else { @@ -307,7 +316,6 @@ if ($result) { print ''; print ''; print ''; - print ''; print dol_get_fiche_head($head, 'bankline', $langs->trans('LineRecord'), 0, 'accountline', 0); @@ -326,11 +334,12 @@ if ($result) { // Bank account print ''; print ''; print ''; diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php index 6ee1a057664..cb0e38b7a34 100644 --- a/htdocs/compta/facture/stats/index.php +++ b/htdocs/compta/facture/stats/index.php @@ -102,7 +102,7 @@ if ($mode == 'customer') { $stats->where .= ' AND f.fk_statut IN ('.$db->sanitize($object_status).')'; } if (is_array($custcats) && !empty($custcats)) { - $stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cat OmdN (f.fk_soc = cat.fk_soc)'; + $stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cat ON (f.fk_soc = cat.fk_soc)'; $stats->where .= ' AND cat.fk_categorie IN ('.$db->sanitize(implode(',', $custcats)).')'; } } diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 8b16cd4699c..8158b935ad5 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -48,7 +48,7 @@ if (!defined('NOREQUIRETRAN')) { require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php'; - +$hookmanager->initHooks(array('rowinterface')); // Security check // This is done later into view. @@ -116,7 +116,15 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } } - + $parameters = array('roworder'=> &$roworder, 'table_element_line' => &$table_element_line, 'fk_element' => &$fk_element, 'element_id' => &$element_id, 'perm' => &$perm); + $row = new GenericObject($db); + $row->table_element_line = $table_element_line; + $row->fk_element = $fk_element; + $row->id = $element_id; + $reshook = $hookmanager->executeHooks('checkRowPerms', $parameters, $row, $action); + if ($reshook > 0) { + $perm = $hookmanager->resArray['perm']; + } if (! $perm) { // We should not be here. If we are not allowed to reorder rows, feature should not be visible on script. // If we are here, it is a hack attempt, so we report a warning. @@ -133,10 +141,7 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) } } - $row = new GenericObject($db); - $row->table_element_line = $table_element_line; - $row->fk_element = $fk_element; - $row->id = $element_id; + $row->line_ajaxorder($newrowordertab); // This update field rank or position in table row->table_element_line diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index c01ff5af541..a9f79095242 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -892,7 +892,7 @@ class FormFile } $out .= '>'; $out .= img_mime($file["name"], $langs->trans("File").': '.$file["name"]); - $out .= dol_trunc($file["name"], 150); + $out .= dol_trunc($file["name"], 40); $out .= ''."\n"; $out .= $this->showPreview($file, $modulepart, $relativepath, 0, $param); $out .= ''; diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 4bf8a0e7219..e98a25ddbee 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -271,7 +271,7 @@ function societe_prepare_head(Societe $object) $h++; } - if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'thirdparty') { + if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR', 'thirdparty') == 'thirdparty') { if (!empty($user->rights->partnership->read)) { $langs->load("partnership"); $nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 22ff541f7d5..43a549655b9 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8200,7 +8200,7 @@ function verifCond($strToEvaluate) * @param string $s String to evaluate * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). * @param int $hideerrors 1=Hide errors - * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():"\';,/' + * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s^$_+-.*\/>&|=!?():"\',/';, 2=Accept also ';[]' * @return mixed Nothing or return result of eval */ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1') @@ -8218,7 +8218,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' // Test dangerous char (used for RCE), we allow only PHP variable testing. if ($onlysimplestring == '1') { //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('$_+-*/>&|=!?():"', '/').']/i', $s)) { + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-.*/>&|=!?():"\',/', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { @@ -8228,7 +8228,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' } } elseif ($onlysimplestring == '2') { //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-*/>&|=!?():"\';,/', '/').']/i', $s)) { + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-.*/>&|=!?():"\',/;[]', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { @@ -8245,7 +8245,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' return ''; } } - if (strpos($s, '.') !== false) { + if (preg_match('/[^0-9]+\.[^0-9]+/', $s)) { // We refuse . if not between 2 numbers if ($returnvalue) { return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; } else { diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index fb11846a4fb..2a436677cad 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -49,7 +49,7 @@ function dolSaveMasterFile($filemaster) @chmod($filemaster, octdec($conf->global->MAIN_UMASK)); } - return $result; + return $result; } /** @@ -291,11 +291,12 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, * @param string $fileindex Full path of file index.php * @param string $filetpl File tpl the index.php page redirect to (used only if $fileindex is provided) * @param string $filewrapper Full path of file wrapper.php + * @param Website $object Object website * @return boolean True if OK */ -function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper) +function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object = null) { - global $conf; + global $conf, $db; $result1 = false; $result2 = false; @@ -320,6 +321,44 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper) if (!empty($conf->global->MAIN_UMASK)) { @chmod($fileindex, octdec($conf->global->MAIN_UMASK)); } + + if (is_object($object) && $object->fk_default_home > 0) { + $objectpage = new WebsitePage($db); + $objectpage->fetch($object->fk_default_home); + + // Create a version for sublanguages + if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) { + if (empty($conf->global->WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR) && is_object($object) && !empty($object->otherlang)) { + $dirname = dirname($fileindex); + foreach (explode(',', $object->otherlang) as $sublang) { + // Avoid to erase main alias file if $sublang is empty string + if (empty(trim($sublang))) continue; + $fileindexsub = $dirname.'/'.$sublang.'/index.php'; + + // Same indexcontent than previously but with ../ instead of ./ for master and tpl file include/require_once. + $relpath = '..'; + $indexcontent = ''."\n"; + $result = file_put_contents($fileindexsub, $indexcontent); + if ($result === false) { + dol_syslog("Failed to write file ".$fileindexsub, LOG_WARNING); + } + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($fileindexsub, octdec($conf->global->MAIN_UMASK)); + } + } + } + } + } } else { $result1 = true; } @@ -491,7 +530,7 @@ function dolSaveReadme($file, $content) @chmod($file, octdec($conf->global->MAIN_UMASK)); } - return $result; + return $result; } @@ -545,9 +584,9 @@ function showWebsiteTemplates(Website $website) while (($subdir = readdir($handle)) !== false) { if (is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) <> '.' && substr($subdir, 0, 3) <> 'CVS' && preg_match('/\.zip$/i', $subdir)) { - $subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir); + $subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir); - // Disable not stable themes (dir ends with _exp or _dev) + // Disable not stable themes (dir ends with _exp or _dev) if ($conf->global->MAIN_FEATURES_LEVEL < 2 && preg_match('/_dev$/i', $subdir)) { continue; } @@ -555,38 +594,38 @@ function showWebsiteTemplates(Website $website) continue; } - print '
'; + print '
'; - $file = $dirtheme."/".$subdirwithoutzip.".jpg"; - $url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzip.".jpg"; + $file = $dirtheme."/".$subdirwithoutzip.".jpg"; + $url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzip.".jpg"; if (!file_exists($file)) { $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png'; } - $originalfile = basename($file); - $entity = $conf->entity; - $modulepart = 'doctemplateswebsite'; - $cache = ''; - $title = $file; + $originalfile = basename($file); + $entity = $conf->entity; + $modulepart = 'doctemplateswebsite'; + $cache = ''; + $title = $file; - $ret = ''; - $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 1, '&entity='.$entity); + $ret = ''; + $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 1, '&entity='.$entity); if (!empty($urladvanced)) { $ret .= ''; } else { $ret .= ''; } - print $ret; - print ''.$title.''; - print ''; + print $ret; + print ''.$title.''; + print ''; - print '
'; - print $subdir.' ('.dol_print_size(dol_filesize($dirtheme."/".$subdir), 1, 1).')'; - print '
ref.'&templateuserfile='.$subdir.'" class="button">'.$langs->trans("Load").''; - print '
'; + print '
'; + print $subdir.' ('.dol_print_size(dol_filesize($dirtheme."/".$subdir), 1, 1).')'; + print '
ref.'&templateuserfile='.$subdir.'" class="button">'.$langs->trans("Load").''; + print '
'; - $i++; + $i++; } } } diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 636bf4c4f7f..66e2f3c8312 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php'; /** diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index 61428170f50..0be260194c2 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -43,7 +43,6 @@ $forcereloadpage = empty($conf->global->MAIN_FORCE_RELOAD_PAGE) ? 0 : 1; $tagidfortablednd = (empty($tagidfortablednd) ? 'tablelines' : $tagidfortablednd); $filepath = (empty($filepath) ? '' : $filepath); - if (GETPOST('action', 'aZ09') != 'editline' && $nboflines > 1 && $conf->browser->layout != 'phone') { ?>
'; print $langs->trans('Docdate'); print '
'.$langs->trans("Account").''; - if (!$objp->rappro && !$bankline->getVentilExportCompta()) { - print img_picto('', 'bank_account', 'class="paddingright"'); - print $form->select_comptes($acct->id, 'accountid', 0, '', 0, '', 0, '', 1); - } else { + // $objp->fk_account may be not > 0 if data was lost by an old bug. In such a case, we let a chance to user to fix it. + if (($objp->rappro || $bankline->getVentilExportCompta()) && $objp->fk_account > 0) { print $acct->getNomUrl(1, 'transactions', 'reflabel'); + } else { + print img_picto('', 'bank_account', 'class="paddingright"'); + print $form->select_comptes($acct->id, 'accountid', 0, '', ($acct->id > 0 ? $acct->id : 1), '', 0, '', 1); } print '