diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 435f6a7e24e..6852f57e5a8 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -358,7 +358,13 @@ class Members extends DolibarrApi } } } else { - $member->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $member->array_options[$index] = $this->_checkValForAPI($field, $val, $member); + } + continue; + } + $member->$field = $this->_checkValForAPI($field, $value, $member); } } diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index 302270d5c5f..cbfb7a3148c 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -202,10 +202,15 @@ class MembersTypes extends DolibarrApi $membertype->context['caller'] = $request_data['caller']; continue; } - + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $membertype->array_options[$index] = $this->_checkValForAPI($field, $val, $membertype); + } + continue; + } // Process the status separately because it must be updated using // the validate(), resiliate() and exclude() methods of the class AdherentType. - $membertype->$field = $value; + $membertype->$field = $this->_checkValForAPI($field, $value, $membertype); } // If there is no error, update() returns the number of affected rows diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index 77c7a8b933a..6d27ba72dea 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -196,7 +196,13 @@ class Subscriptions extends DolibarrApi continue; } - $subscription->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $subscription->array_options[$index] = $this->_checkValForAPI($field, $val, $subscription); + } + continue; + } + $subscription->$field = $this->_checkValForAPI($field, $val, $subscription); } if ($subscription->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index 8a08da12678..322fbe2701a 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -251,7 +251,13 @@ class Boms extends DolibarrApi continue; } - $this->bom->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->bom->array_options[$index] = $this->_checkValForAPI($field, $val, $this->bom); + } + continue; + } + $this->bom->$field = $this->_checkValForAPI($field, $value, $this->bom); } $this->checkRefNumbering(); diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index 9f73b1b9e65..bec3a20e8f9 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -248,7 +248,13 @@ class Categories extends DolibarrApi continue; } - $this->category->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->category->array_options[$index] = $this->_checkValForAPI($field, $val, $this->category); + } + continue; + } + $this->category->$field = $this->_checkValForAPI($field, $value, $this->category); } if ($this->category->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index e8fb9d8b3f6..82f6d69d6a9 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -629,7 +629,7 @@ class ActionComm extends CommonObject foreach ($this->userassigned as $key => $val) { // Common value with new behavior is to have $val = array('id'=>iduser, 'transparency'=>0|1) and $this->userassigned is an array of iduser => $val. if (!is_array($val)) { // For backward compatibility when $val='id'. - $val = array('id'=>$val); + $val = array('id' => $val); } if ($val['id'] > 0) { @@ -1271,7 +1271,7 @@ class ActionComm extends CommonObject $already_inserted = array(); foreach (array_keys($this->socpeopleassigned) as $key => $val) { if (!is_array($val)) { // For backward compatibility when val=id - $val = array('id'=>$val); + $val = array('id' => $val); } if (!empty($already_inserted[$val['id']])) { continue; diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index d1c013bc59c..2d983c28867 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -279,6 +279,12 @@ class AgendaEvents extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->actioncomm->array_options[$index] = $this->_checkValForAPI($field, $val, $this->actioncomm); + } + continue; + } $this->actioncomm->$field = $this->_checkValForAPI($field, $value, $this->actioncomm); } diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 91d24c44009..0a55e1dd95d 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -708,7 +708,13 @@ class Proposals extends DolibarrApi continue; } - $this->propal->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->propal->array_options[$index] = $this->_checkValForAPI($field, $val, $this->propal); + } + continue; + } + $this->propal->$field = $this->_checkValForAPI($field, $value, $this->propal); } // update end of validity date diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 72e439598ca..da3ad17a6e0 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -662,7 +662,13 @@ class Orders extends DolibarrApi continue; } - $this->commande->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->commande->array_options[$index] = $this->_checkValForAPI($field, $val, $this->commande); + } + continue; + } + $this->commande->$field = $this->_checkValForAPI($field, $value, $this->commande); } // Update availability diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 4be3f7dee2d..ba9c8089c22 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -345,6 +345,12 @@ class BankAccounts extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $account->array_options[$index] = $this->_checkValForAPI($field, $val, $account); + } + continue; + } $account->$field = $this->_checkValForAPI($field, $value, $account); } diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 39e100c274b..e24b8ee0459 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -633,7 +633,13 @@ class Invoices extends DolibarrApi continue; } - $this->invoice->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->invoice->array_options[$index] = $this->_checkValForAPI($field, $val, $this->invoice); + } + continue; + } + $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice); } // update bank account diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index 51c3d63d412..d6b64186283 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -519,7 +519,13 @@ class Contracts extends DolibarrApi continue; } - $this->contract->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->contract->array_options[$index] = $this->_checkValForAPI($field, $val, $this->contract); + } + continue; + } + $this->contract->$field = $this->_checkValForAPI($field, $value, $this->contract); } if ($this->contract->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index cdf8a79f024..e41fa2d0ca5 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -694,7 +694,7 @@ class CMailFile $this->error = "Error in hook maildao sendMail ".$reshook; dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); - return $reshook; + return false; } if ($reshook == 1) { // Hook replace standard code return true; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 739012ffe37..661c690c353 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -9557,10 +9557,11 @@ function dol_osencode($str) * @param string $fieldid Field to get * @param int $entityfilter Filter by entity * @param string $filters Filters to add. WARNING: string must be escaped for SQL and not coming from user input. + * @param bool $useCache If true (default), cache will be queried and updated. * @return int Return integer <0 if KO, Id of code if OK * @see $langs->getLabelFromKey */ -function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = 'id', $entityfilter = 0, $filters = '') +function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = 'id', $entityfilter = 0, $filters = '', $useCache = true) { global $cache_codes; @@ -9570,8 +9571,8 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = } // Check in cache - if (isset($cache_codes[$tablename][$key][$fieldid])) { // Can be defined to 0 or '' - return $cache_codes[$tablename][$key][$fieldid]; // Found in cache + if ($useCache && isset($cache_codes[$tablename][$fieldkey][$fieldid][$entityfilter][$filters][$key])) { // Can be defined to 0 or '' + return $cache_codes[$tablename][$fieldkey][$fieldid][$entityfilter][$filters][$key]; // Found in cache } dol_syslog('dol_getIdFromCode (value for field '.$fieldid.' from key '.$key.' not found into cache)', LOG_DEBUG); @@ -9589,13 +9590,15 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); + $valuetoget = ''; if ($obj) { - $cache_codes[$tablename][$key][$fieldid] = $obj->valuetoget; - } else { - $cache_codes[$tablename][$key][$fieldid] = ''; + $valuetoget = $obj->valuetoget; } $db->free($resql); - return $cache_codes[$tablename][$key][$fieldid]; + if ($useCache) { + $cache_codes[$tablename][$fieldkey][$fieldid][$entityfilter][$filters][$key] = $valuetoget; + } + return $valuetoget; } else { return -1; } @@ -11588,11 +11591,11 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * 'classOverride' => '' // to replace class attribute of the button * ], * 'confirm' => [ - * 'url' => 'http://', // Overide Url to go when user click on action btn, if empty default url is $url.?confirm=yes, for no js compatibility use $url for fallback confirm. - * 'title' => '', // Overide title of modal, if empty default title use "ConfirmBtnCommonTitle" lang key - * 'action-btn-label' => '', // Overide label of action button, if empty default label use "Confirm" lang key - * 'cancel-btn-label' => '', // Overide label of cancel button, if empty default label use "CloseDialog" lang key - * 'content' => '', // Overide text of content, if empty default content use "ConfirmBtnCommonContent" lang key + * 'url' => 'http://', // Override Url to go when user click on action btn, if empty default url is $url.?confirm=yes, for no js compatibility use $url for fallback confirm. + * 'title' => '', // Override title of modal, if empty default title use "ConfirmBtnCommonTitle" lang key + * 'action-btn-label' => '', // Override label of action button, if empty default label use "Confirm" lang key + * 'cancel-btn-label' => '', // Override label of cancel button, if empty default label use "CloseDialog" lang key + * 'content' => '', // Override text of content, if empty default content use "ConfirmBtnCommonContent" lang key * 'modal' => true, // true|false to display dialog as a modal (with dark background) * 'isDropDrown' => false, // true|false to display dialog as a dropdown (with dark background) * ], diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 9583846ab8a..acd77ac6752 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1485,6 +1485,8 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : ''); $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false); + $multilangsactive = getDolGlobalInt('MAIN_MULTILANGS'); + if ($issupplierline) { include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; $prodser = new ProductFournisseur($db); @@ -1497,11 +1499,55 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, } } + //id + $idprod = (!empty($object->lines[$i]->fk_product) ? $object->lines[$i]->fk_product : false); if ($idprod) { $prodser->fetch($idprod); + //load multilangs + if ($multilangsactive) { + $prodser->getMultiLangs(); + $object->lines[$i]->multilangs = $prodser->multilangs; + } + } + //label + if (!empty($object->lines[$i]->label)) { + $label = $object->lines[$i]->label; + } else { + if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['label']) && $multilangsactive) { + $label = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['label']; + } else { + if (!empty($object->lines[$i]->product_label)) { + $label = $object->lines[$i]->product_label; + } else { + $label = ''; + } + } + } + //description + if (!empty($object->lines[$i]->desc)) { + $desc = $object->lines[$i]->desc; + } else { + if (!empty($object->lines[$i]->multilangs[$outputlangs->defaultlang]['description']) && $multilangsactive) { + $desc = $object->lines[$i]->multilangs[$outputlangs->defaultlang]['description']; + } else { + if (!empty($object->lines[$i]->description)) { + $desc = $object->lines[$i]->description; + } else { + $desc = ''; + } + } + } + //ref supplier + $ref_supplier = (!empty($object->lines[$i]->ref_supplier) ? $object->lines[$i]->ref_supplier : (!empty($object->lines[$i]->ref_fourn) ? $object->lines[$i]->ref_fourn : '')); // TODO Not yet saved for supplier invoices, only supplier orders + //note + $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : ''); + //dbatch + $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false); + + if ($idprod) { // If a predefined product and multilang and on other lang, we renamed label with label translated - if (getDolGlobalInt('MAIN_MULTILANGS') && ($outputlangs->defaultlang != $langs->defaultlang)) { - $translatealsoifmodified = (getDolGlobalString('MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED')); // By default if value was modified manually, we keep it (no translation because we don't have it) + if ($multilangsactive && ($outputlangs->defaultlang != $langs->defaultlang)) { + $translatealsoifmodified = getDolGlobalString('MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED'); // By default if value was modified manually, we keep it (no translation because we don't have it) // TODO Instead of making a compare to see if param was modified, check that content contains reference translation. If yes, add the added part to the new translation // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion). diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index d4cffb751eb..adf53f537d4 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -87,38 +87,17 @@ class InterfaceTicketEmail extends DolibarrTriggers $appli = $mysoc->name; // Send email to assigned user - $subject = '['.$appli.'] '.$langs->transnoentities('TicketAssignedToYou'); - $message = '

'.$langs->transnoentities('TicketAssignedEmailBody', $object->track_id, dolGetFirstLastname($user->firstname, $user->lastname))."

"; - $message .= ''; - $message .= '

'.$langs->trans('Message').' :
'.$object->message.'

'; - $message .= '

'.$langs->trans('SeeThisTicketIntomanagementInterface').'

'; - $sendto = $userstat->email; - $from = dolGetFirstLastname($user->firstname, $user->lastname).'<'.$user->email.'>'; - - $message = dol_nl2br($message); + $subject_assignee = 'TicketAssignedToYou'; + $body_assignee = 'TicketAssignedEmailBody'; + $see_ticket_assignee = 'SeeThisTicketIntomanagementInterface'; if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1); - if ($mailfile->error) { - setEventMessages($mailfile->error, $mailfile->errors, 'errors'); - } else { - $result = $mailfile->sendfile(); + if (!empty($sendto)) { + $this->composeAndSendAssigneeMessage($sendto, $subject_assignee, $body_assignee, $see_ticket_assignee, $object, $langs); } if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; @@ -177,10 +156,15 @@ class InterfaceTicketEmail extends DolibarrTriggers $subject_admin = 'TicketNewEmailSubjectAdmin'; $body_admin = 'TicketNewEmailBodyAdmin'; + $subject_customer = 'TicketNewEmailSubjectCustomer'; $body_customer = 'TicketNewEmailBodyCustomer'; $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer'; + $subject_assignee = 'TicketAssignedToYou'; + $body_assignee = 'TicketAssignedEmailBody'; + $see_ticket_assignee = 'SeeThisTicketIntomanagementInterface'; + // Send email to notification email if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) { $sendto = !getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; @@ -189,6 +173,34 @@ class InterfaceTicketEmail extends DolibarrTriggers } } + // Send email to assignee if an assignee was set at creation + if ($object->fk_user_assign > 0 && $object->fk_user_assign != $user->id && empty($object->context['disableticketemail'])) { + $userstat = new User($this->db); + $res = $userstat->fetch($object->fk_user_assign); + if ($res > 0) { + // Send email to notification email + if (!getDolGlobalString('TICKET_DISABLE_ALL_MAILS')) { + // Send email to assigned user + $sendto = $userstat->email; + if (!getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + + if (!empty($sendto)) { + $this->composeAndSendAssigneeMessage($sendto, $subject_assignee, $body_assignee, $see_ticket_assignee, $object, $langs); + } + + if (!getDolUserString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } + } else { + $this->error = $userstat->error; + $this->errors = $userstat->errors; + } + } + // Send email to customer if (!getDolGlobalString('TICKET_DISABLE_CUSTOMER_MAILS') && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { $sendto = ''; @@ -460,4 +472,72 @@ class InterfaceTicketEmail extends DolibarrTriggers $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; } } + + /** + * Composes and sends a message concerning a ticket, to be sent to user assigned to the ticket + * + * @param string $sendto Addresses to send the mail, format "first@address.net, second@address.net, " etc. + * @param string $base_subject email subject. Non-translated string. + * @param string $body email body (first line). Non-translated string. + * @param string $see_ticket string indicating the ticket public address + * @param Ticket $object the ticket thet the email refers to + * @param Translate $langs the translation object + * @return void + */ + private function composeAndSendAssigneeMessage($sendto, $base_subject, $body, $see_ticket, Ticket $object, Translate $langs) + { + global $conf, $user, $mysoc; + + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + // Send email to assigned user + $appli = $mysoc->name; + + $subject = '['.$appli.'] '.$langs->transnoentities($base_subject); + $message = '

'.$langs->transnoentities($body, $object->track_id, dolGetFirstLastname($user->firstname, $user->lastname))."

"; + $message .= ''; + $message .= '

'.$langs->trans('Message').' :
'.$object->message.'

'; + $message .= '

'.$langs->trans($see_ticket).'

'; + + $from = dolGetFirstLastname($user->firstname, $user->lastname).'<'.$user->email.'>'; + + $message = dol_nl2br($message); + + $old_MAIN_MAIL_AUTOCOPY_TO = null; + if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { + $old_MAIN_MAIL_AUTOCOPY_TO = getDolGlobalString('MAIN_MAIL_AUTOCOPY_TO'); + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1); + if ($mailfile->error) { + setEventMessages($mailfile->error, $mailfile->errors, 'errors'); + } else { + $result = $mailfile->sendfile(); + if ($result) { + // update last_msg_sent date + $object->fetch($object->id); + $object->date_last_msg_sent = dol_now(); + $object->update($user); + } + } + if (!getDolUserString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } } diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index e734be8efff..68aa22fea5f 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -240,7 +240,13 @@ class Donations extends DolibarrApi continue; } - $this->don->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->don->array_options[$index] = $this->_checkValForAPI($field, $val, $this->don); + } + continue; + } + $this->don->$field = $this->_checkValForAPI($field, $value, $this->don); } if ($this->don->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 5076132bf4e..b5995eed7ac 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -457,7 +457,13 @@ class Shipments extends DolibarrApi continue; } - $this->shipment->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->shipment->array_options[$index] = $this->_checkValForAPI($field, $val, $this->shipment); + } + continue; + } + $this->shipment->$field = $this->_checkValForAPI($field, $val, $this->shipment);; } if ($this->shipment->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 7372f9f98f8..95603c3562e 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -430,7 +430,13 @@ class ExpenseReports extends DolibarrApi continue; } - $this->expensereport->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->expensereport->array_options[$index] = $this->_checkValForAPI($field, $val, $this->expensereport); + } + continue; + } + $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport); } if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index e3dbf15a42d..5bc8aa5606e 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -630,6 +630,7 @@ class ExpenseReport extends CommonObject $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d"; if ($ref) { $sql .= " WHERE d.ref = '".$this->db->escape($ref)."'"; + $sql .= " AND d.entity IN (".getEntity('expensereport').")"; } else { $sql .= " WHERE d.rowid = ".((int) $id); } diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 1b3d1961467..8f929c17dd4 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -274,6 +274,13 @@ class SupplierInvoices extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->invoice->array_options[$index] = $this->_checkValForAPI($field, $val, $this->invoice); + } + continue; + } + $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice); } diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index 66fb7248bcd..45dde4033c6 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -294,6 +294,13 @@ class SupplierOrders extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->order->array_options[$index] = $this->_checkValForAPI($field, $val, $this->order); + } + continue; + } + $this->order->$field = $this->_checkValForAPI($field, $value, $this->order); } diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 4b70d54e93e..ffae2c50f43 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -53,8 +53,8 @@ class Odf public $userdefined=array(); const PIXEL_TO_CM = 0.026458333; - const FIND_TAGS_REGEX = '/<([A-Za-z0-9]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/s'; - const FIND_ENCODED_TAGS_REGEX = '/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/'; + const FIND_TAGS_REGEX = '/<([A-Za-z0-9]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(((?!<\1(\s.*)?>).)*)<\/\1>))/s'; + const FIND_ENCODED_TAGS_REGEX = '/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(((?!<\1(\s.*)?>).)*)<\/\1>))/'; /** diff --git a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php index 32791ffcc7a..b3b23855ed7 100644 --- a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php +++ b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php @@ -305,6 +305,13 @@ class KnowledgeManagement extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->knowledgerecord->array_options[$index] = $this->_checkValForAPI($field, $val, $this->knowledgerecord); + } + continue; + } + $this->knowledgerecord->$field = $this->_checkValForAPI($field, $value, $this->knowledgerecord); } diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 1f167bab403..1a0123eea87 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -84,7 +84,7 @@ if (empty($reshook)) { if ($result > 0) { setEventMessages($langs->trans('LoanPaid'), null, 'mesgs'); } else { - setEventMessages($loan->error, null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } @@ -97,7 +97,7 @@ if (empty($reshook)) { header("Location: list.php"); exit; } else { - setEventMessages($loan->error, null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); } } diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index 76a3f37b2f6..31d84f822dd 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -308,6 +308,7 @@ class Loan extends CommonObject $accountline->fetch($line_url['fk_bank']); $result = $accountline->delete_urls($user); if ($result < 0) { + $this->errors = array_merge($this->errors, [$accountline->error], $accountline->errors); $error++; } } diff --git a/htdocs/loan/class/paymentloan.class.php b/htdocs/loan/class/paymentloan.class.php index 4ba09c30bd4..0f81d1a1173 100644 --- a/htdocs/loan/class/paymentloan.class.php +++ b/htdocs/loan/class/paymentloan.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2015-2023 Frederic France + * Copyright (C) 2015-2023 Frederic France * Copyright (C) 2020 Maxime DEMAREST * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index 62ad513d307..f7d261ed739 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -268,6 +268,13 @@ class MyModuleApi extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->myobject->array_options[$index] = $this->_checkValForAPI($field, $val, $this->myobject); + } + continue; + } + $this->myobject->$field = $this->_checkValForAPI($field, $value, $this->myobject); } diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index 4f4e5f46a31..4818b3734f6 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -249,7 +249,14 @@ class Mos extends DolibarrApi continue; } - $this->mo->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->mo->array_options[$index] = $this->_checkValForAPI($field, $val, $this->mo); + } + continue; + } + + $this->mo->$field = $this->_checkValForAPI($field, $value, $this->mo); } $this->checkRefNumbering(); diff --git a/htdocs/partnership/class/api_partnerships.class.php b/htdocs/partnership/class/api_partnerships.class.php index e3ca8f23e2e..847d9f1a77f 100644 --- a/htdocs/partnership/class/api_partnerships.class.php +++ b/htdocs/partnership/class/api_partnerships.class.php @@ -264,6 +264,12 @@ class Partnerships extends DolibarrApi $this->partnership->context['caller'] = $request_data['caller']; continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->partnership->array_options[$index] = $this->_checkValForAPI($field, $val, $this->partnership); + } + continue; + } $this->partnership->$field = $this->_checkValForAPI($field, $value, $this->partnership); } diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 4023309ef35..4950bbc2608 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -371,7 +371,14 @@ class Products extends DolibarrApi continue; } - $this->product->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->product->array_options[$index] = $this->_checkValForAPI($field, $val, $this->product); + } + continue; + } + + $this->product->$field = $this->_checkValForAPI($field, $value, $this->product); } $updatetype = false; diff --git a/htdocs/product/stock/class/api_warehouses.class.php b/htdocs/product/stock/class/api_warehouses.class.php index 6fa256454b9..4354c5c959d 100644 --- a/htdocs/product/stock/class/api_warehouses.class.php +++ b/htdocs/product/stock/class/api_warehouses.class.php @@ -217,7 +217,13 @@ class Warehouses extends DolibarrApi continue; } - $this->warehouse->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->warehouse->array_options[$index] = $this->_checkValForAPI($field, $val, $this->warehouse); + } + continue; + } + $this->warehouse->$field = $this->_checkValForAPI($field, $value, $this->warehouse); } if ($this->warehouse->update($id, DolibarrApiAccess::$user)) { diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 638c500a2ea..b4da73f080e 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -476,7 +476,13 @@ class Projects extends DolibarrApi continue; } - $this->project->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->project->array_options[$index] = $this->_checkValForAPI($field, $val, $this->project); + } + continue; + } + $this->project->$field = $this->_checkValForAPI($field, $value, $this->project); } if ($this->project->update(DolibarrApiAccess::$user) >= 0) { diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index bd53ae007eb..353615ba887 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -472,7 +472,13 @@ class Tasks extends DolibarrApi continue; } - $this->task->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->task->array_options[$index] = $this->_checkValForAPI($field, $val, $this->task); + } + continue; + } + $this->task->$field = $this->_checkValForAPI($field, $val, $this->task); } if ($this->task->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/reception/class/api_receptions.class.php b/htdocs/reception/class/api_receptions.class.php index 95a0318202a..5eeece76d81 100644 --- a/htdocs/reception/class/api_receptions.class.php +++ b/htdocs/reception/class/api_receptions.class.php @@ -458,7 +458,13 @@ class Receptions extends DolibarrApi continue; } - $this->reception->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->reception->array_options[$index] = $this->_checkValForAPI($field, $val, $this->reception); + } + continue; + } + $this->reception->$field = $this->_checkValForAPI($field, $val, $this->reception); } if ($this->reception->update(DolibarrApiAccess::$user) > 0) { diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 7e8e8e858d9..82791b1a6aa 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -350,7 +350,7 @@ class Contacts extends DolibarrApi } if ($field == 'array_options' && is_array($value)) { foreach ($value as $index => $val) { - $this->contact->array_options[$index] = $val; + $this->contact->array_options[$index] = $this->_checkValForAPI($field, $val, $this->contact); } continue; } diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 712dc7685c5..afb3406b575 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -318,6 +318,12 @@ class Thirdparties extends DolibarrApi continue; } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->company->array_options[$index] = $this->_checkValForAPI($field, $val, $this->company); + } + continue; + } $this->company->$field = $this->_checkValForAPI($field, $value, $this->company); } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index bf1f86cc7b5..f0bd4ebe814 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -557,7 +557,7 @@ if ($search_sale == -2) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; //elseif ($search_sale || (empty($user->rights->societe->client->voir) && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->societe->client->readallthirdparties_advance)) && !$socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } elseif (!empty($search_sale) && $search_sale != '-1' || (!$user->hasRight('societe', 'client', 'voir') && !$socid)) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux AS sc ON s.rowid = sc.fk_soc"; } // Add table from hooks $parameters = array(); @@ -568,9 +568,6 @@ $sql .= " WHERE s.entity IN (".getEntity('societe').")"; if (!$user->hasRight('societe', 'client', 'voir') && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } -if ($search_sale && $search_sale != '-1' && $search_sale != '-2') { - $sql .= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale -} if (!$user->hasRight('fournisseur', 'lire')) { $sql .= " AND (s.fournisseur <> 1 OR s.client <> 0)"; // client=0, fournisseur=0 must be visible } diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index 508a9cbf768..5ac175f6622 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -394,7 +394,16 @@ class Tickets extends DolibarrApi continue; } - $this->ticket->$field = $value; + if ($field == 'id') { + continue; + } + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->ticket->array_options[$index] = $this->_checkValForAPI($field, $val, $this->ticket); + } + continue; + } + $this->ticket->$field = $this->_checkValForAPI($field, $value, $this->ticket); } if ($this->ticket->update(DolibarrApiAccess::$user)) { diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index e1424796c63..339ea853ce9 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -417,7 +417,13 @@ class Users extends DolibarrApi throw new RestException(500, 'Error when updating status of user: '.$this->useraccount->error); } } else { - $this->useraccount->$field = $value; + if ($field == 'array_options' && is_array($value)) { + foreach ($value as $index => $val) { + $this->useraccount->array_options[$index] = $this->_checkValForAPI($field, $val, $this->useraccount); + } + continue; + } + $this->useraccount->$field = $this->_checkValForAPI($field, $value, $this->useraccount); } } diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index cc2c56c8f1b..0fe34d1fec6 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -702,16 +702,16 @@ class ProductCombination * [...] * ) * - * @param User $user Object user - * @param Product $product Parent product - * @param array $combinations Attribute and value combinations. - * @param array $variations Price and weight variations - * @param bool|array $price_var_percent Is the price variation a relative variation? - * @param bool|float $forced_pricevar If the price variation is forced - * @param bool|float $forced_weightvar If the weight variation is forced - * @param bool|string $forced_refvar If the reference is forced - * @param string $ref_ext External reference - * @return int Return integer <0 KO, >0 OK + * @param User $user Object user + * @param Product $product Parent product + * @param array $combinations Attribute and value combinations. + * @param array $variations Price and weight variations + * @param bool|array $price_var_percent Is the price variation a relative variation? + * @param bool|float|array $forced_pricevar If the price variation is forced + * @param bool|float $forced_weightvar If the weight variation is forced + * @param bool|string $forced_refvar If the reference is forced + * @param string $ref_ext External reference + * @return int Return integer <0 KO, >0 OK */ public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false, $forced_refvar = false, $ref_ext = '') { @@ -752,8 +752,8 @@ class ProductCombination $price_impact = $forced_pricevar; } - if (!array($price_var_percent)) { - $price_var_percent[1] = (float) $price_var_percent; + if (!is_array($price_var_percent)) { + $price_var_percent = array(1 => (bool) $price_var_percent); } $newcomb = new ProductCombination($this->db); @@ -955,13 +955,26 @@ class ProductCombination $variations[$tmp_pc2v->fk_prod_attr] = $tmp_pc2v->fk_prod_attr_val; } + $variation_price_percentage = $combination->variation_price_percentage; + $variation_price = $combination->variation_price; + + if (getDolGlobalInt('PRODUIT_MULTIPRICES') && getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT') > 1) { + $variation_price_percentage = [ ]; + $variation_price = [ ]; + + foreach ($combination->combination_price_levels as $productCombinationLevel) { + $variation_price_percentage[$productCombinationLevel->fk_price_level] = $productCombinationLevel->variation_price_percentage; + $variation_price[$productCombinationLevel->fk_price_level] = $productCombinationLevel->variation_price; + } + } + if ($this->createProductCombination( $user, $destProduct, $variations, array(), - $combination->variation_price_percentage, - $combination->variation_price, + $variation_price_percentage, + $variation_price, $combination->variation_weight ) < 0) { return -1; diff --git a/test/phpunit/ODFTest.php b/test/phpunit/ODFTest.php index dbfe8d11456..bac87d4f651 100644 --- a/test/phpunit/ODFTest.php +++ b/test/phpunit/ODFTest.php @@ -296,33 +296,45 @@ class ODFTest extends PHPUnit\Framework\TestCase 'charset' => null, 'expected' => mb_convert_encoding('text with intricatedtags', 'UTF-8', 'ISO-8859-1'), ], + 24 => [ + 'to_convert' => "text with two (strong) tags", + 'encode' => true, + 'charset' => null, + 'expected' => utf8_encode('text with two (strong) tags'), + ], + 25 => [ + 'to_convert' => "text with two (strong) tags and intricated underline ", + 'encode' => true, + 'charset' => null, + 'expected' => utf8_encode('text with two (strong) tags and intricated underline '), + ], // One can also pass html-encoded string to the method - 24 => [ + 26 => [ 'to_convert' => 'One&two', 'encode' => true, 'charset' => null, 'expected' => 'One&two', ], - 25 => [ + 27 => [ 'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>", 'encode' => false, 'charset' => 'UTF-8', 'expected' => 'text with strong, emphasis and underlined words with it@lic sp&ciàlchärs éè l\'', ], - 26 => [ + 28 => [ 'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>", 'encode' => true, 'charset' => 'UTF-8', 'expected' => 'text with strong, emphasis and underlined words with it@lic sp&ciàlchärs éè l'', ], - 27 => [ + 29 => [ 'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>", 'encode' => false, 'charset' => null, 'expected' => mb_convert_encoding('text with strong, emphasis and underlined words with it@lic sp&ciàlchärs éè l\'', 'UTF-8', 'ISO-8859-1'), ], - 28 => [ + 30 => [ 'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>", 'encode' => true, 'charset' => null, @@ -341,20 +353,20 @@ class ODFTest extends PHPUnit\Framework\TestCase // Following tests reflect the current behavior. They may evolve if the method behavior changes. // The method removes hyperlinks and tags that are not dealt with. - 29 => [ + 31 => [ 'to_convert' => '123 trucmachin > truc < troc > tracbla bla', 'encode' => true, 'charset' => null, 'expected' => "123 trucmachin > truc < troc > tracbla bla", ], - 30 => [ + 32 => [ 'to_convert' => '123

Title

bla', 'encode' => true, 'charset' => null, 'expected' => "123 Title bla", ], // HTML should not take \n into account, but only
. - 31 => [ + 33 => [ 'to_convert' => "text with strong text , a line\nbreak and underlined words with it@lic sp&ciàlchärs éè l'", 'encode' => false, 'charset' => 'UTF-8', @@ -373,7 +385,7 @@ class ODFTest extends PHPUnit\Framework\TestCase } else { $res = $odf->convertVarToOdf($case['to_convert'], $case['encode']); } - $this->assertEquals($res, $case['expected']); + $this->assertEquals($case['expected'], $res); } print __METHOD__." result=".$result."\n";