2
0
forked from Wavyzz/dolibarr

Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0

This commit is contained in:
Laurent Destailleur (aka Eldy)
2025-01-20 12:28:49 +01:00
42 changed files with 426 additions and 97 deletions

View File

@@ -358,7 +358,13 @@ class Members extends DolibarrApi
} }
} }
} else { } 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);
} }
} }

View File

@@ -202,10 +202,15 @@ class MembersTypes extends DolibarrApi
$membertype->context['caller'] = $request_data['caller']; $membertype->context['caller'] = $request_data['caller'];
continue; 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 // Process the status separately because it must be updated using
// the validate(), resiliate() and exclude() methods of the class AdherentType. // 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 // If there is no error, update() returns the number of affected rows

View File

@@ -196,7 +196,13 @@ class Subscriptions extends DolibarrApi
continue; 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) { if ($subscription->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -251,7 +251,13 @@ class Boms extends DolibarrApi
continue; 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(); $this->checkRefNumbering();

View File

@@ -248,7 +248,13 @@ class Categories extends DolibarrApi
continue; 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) { if ($this->category->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -629,7 +629,7 @@ class ActionComm extends CommonObject
foreach ($this->userassigned as $key => $val) { 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. // 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'. if (!is_array($val)) { // For backward compatibility when $val='id'.
$val = array('id'=>$val); $val = array('id' => $val);
} }
if ($val['id'] > 0) { if ($val['id'] > 0) {
@@ -1271,7 +1271,7 @@ class ActionComm extends CommonObject
$already_inserted = array(); $already_inserted = array();
foreach (array_keys($this->socpeopleassigned) as $key => $val) { foreach (array_keys($this->socpeopleassigned) as $key => $val) {
if (!is_array($val)) { // For backward compatibility when val=id if (!is_array($val)) { // For backward compatibility when val=id
$val = array('id'=>$val); $val = array('id' => $val);
} }
if (!empty($already_inserted[$val['id']])) { if (!empty($already_inserted[$val['id']])) {
continue; continue;

View File

@@ -279,6 +279,12 @@ class AgendaEvents extends DolibarrApi
continue; 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); $this->actioncomm->$field = $this->_checkValForAPI($field, $value, $this->actioncomm);
} }

View File

@@ -708,7 +708,13 @@ class Proposals extends DolibarrApi
continue; 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 // update end of validity date

View File

@@ -662,7 +662,13 @@ class Orders extends DolibarrApi
continue; 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 // Update availability

View File

@@ -345,6 +345,12 @@ class BankAccounts extends DolibarrApi
continue; 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); $account->$field = $this->_checkValForAPI($field, $value, $account);
} }

View File

@@ -633,7 +633,13 @@ class Invoices extends DolibarrApi
continue; 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 // update bank account

View File

@@ -519,7 +519,13 @@ class Contracts extends DolibarrApi
continue; 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) { if ($this->contract->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -694,7 +694,7 @@ class CMailFile
$this->error = "Error in hook maildao sendMail ".$reshook; $this->error = "Error in hook maildao sendMail ".$reshook;
dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
return $reshook; return false;
} }
if ($reshook == 1) { // Hook replace standard code if ($reshook == 1) { // Hook replace standard code
return true; return true;

View File

@@ -9557,10 +9557,11 @@ function dol_osencode($str)
* @param string $fieldid Field to get * @param string $fieldid Field to get
* @param int $entityfilter Filter by entity * @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 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 * @return int Return integer <0 if KO, Id of code if OK
* @see $langs->getLabelFromKey * @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; global $cache_codes;
@@ -9570,8 +9571,8 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid =
} }
// Check in cache // Check in cache
if (isset($cache_codes[$tablename][$key][$fieldid])) { // Can be defined to 0 or '' if ($useCache && isset($cache_codes[$tablename][$fieldkey][$fieldid][$entityfilter][$filters][$key])) { // Can be defined to 0 or ''
return $cache_codes[$tablename][$key][$fieldid]; // Found in cache 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); 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); $resql = $db->query($sql);
if ($resql) { if ($resql) {
$obj = $db->fetch_object($resql); $obj = $db->fetch_object($resql);
$valuetoget = '';
if ($obj) { if ($obj) {
$cache_codes[$tablename][$key][$fieldid] = $obj->valuetoget; $valuetoget = $obj->valuetoget;
} else {
$cache_codes[$tablename][$key][$fieldid] = '';
} }
$db->free($resql); $db->free($resql);
return $cache_codes[$tablename][$key][$fieldid]; if ($useCache) {
$cache_codes[$tablename][$fieldkey][$fieldid][$entityfilter][$filters][$key] = $valuetoget;
}
return $valuetoget;
} else { } else {
return -1; return -1;
} }
@@ -11588,11 +11591,11 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st
* 'classOverride' => '' // to replace class attribute of the button * 'classOverride' => '' // to replace class attribute of the button
* ], * ],
* 'confirm' => [ * '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. * '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' => '', // Overide title of modal, if empty default title use "ConfirmBtnCommonTitle" lang key * 'title' => '', // Override 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 * 'action-btn-label' => '', // Override 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 * 'cancel-btn-label' => '', // Override 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 * '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) * '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) * 'isDropDrown' => false, // true|false to display dialog as a dropdown (with dark background)
* ], * ],

View File

@@ -1485,6 +1485,8 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
$note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : ''); $note = (!empty($object->lines[$i]->note) ? $object->lines[$i]->note : '');
$dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false); $dbatch = (!empty($object->lines[$i]->detail_batch) ? $object->lines[$i]->detail_batch : false);
$multilangsactive = getDolGlobalInt('MAIN_MULTILANGS');
if ($issupplierline) { if ($issupplierline) {
include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
$prodser = new ProductFournisseur($db); $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) { if ($idprod) {
$prodser->fetch($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 a predefined product and multilang and on other lang, we renamed label with label translated
if (getDolGlobalInt('MAIN_MULTILANGS') && ($outputlangs->defaultlang != $langs->defaultlang)) { 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) $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 // 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). // ($textwasnotmodified is replaced with $textwasmodifiedorcompleted and we add completion).

View File

@@ -87,38 +87,17 @@ class InterfaceTicketEmail extends DolibarrTriggers
$appli = $mysoc->name; $appli = $mysoc->name;
// Send email to assigned user // Send email to assigned user
$subject = '['.$appli.'] '.$langs->transnoentities('TicketAssignedToYou');
$message = '<p>'.$langs->transnoentities('TicketAssignedEmailBody', $object->track_id, dolGetFirstLastname($user->firstname, $user->lastname))."</p>";
$message .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
$message .= '<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
$message .= '<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
$message .= '<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
// Extrafields
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message .= '<li>'.$langs->trans($key).' : '.$value.'</li>';
}
}
$message .= '</ul>';
$message .= '<p>'.$langs->trans('Message').' : <br>'.$object->message.'</p>';
$message .= '<p><a href="'.dol_buildpath('/ticket/card.php', 2).'?track_id='.$object->track_id.'">'.$langs->trans('SeeThisTicketIntomanagementInterface').'</a></p>';
$sendto = $userstat->email; $sendto = $userstat->email;
$from = dolGetFirstLastname($user->firstname, $user->lastname).'<'.$user->email.'>'; $subject_assignee = 'TicketAssignedToYou';
$body_assignee = 'TicketAssignedEmailBody';
$message = dol_nl2br($message); $see_ticket_assignee = 'SeeThisTicketIntomanagementInterface';
if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) {
$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->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'; if (!empty($sendto)) {
$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1); $this->composeAndSendAssigneeMessage($sendto, $subject_assignee, $body_assignee, $see_ticket_assignee, $object, $langs);
if ($mailfile->error) {
setEventMessages($mailfile->error, $mailfile->errors, 'errors');
} else {
$result = $mailfile->sendfile();
} }
if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) { if (getDolGlobalString('TICKET_DISABLE_MAIL_AUTOCOPY_TO')) {
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_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'; $subject_admin = 'TicketNewEmailSubjectAdmin';
$body_admin = 'TicketNewEmailBodyAdmin'; $body_admin = 'TicketNewEmailBodyAdmin';
$subject_customer = 'TicketNewEmailSubjectCustomer'; $subject_customer = 'TicketNewEmailSubjectCustomer';
$body_customer = 'TicketNewEmailBodyCustomer'; $body_customer = 'TicketNewEmailBodyCustomer';
$see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer'; $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer';
$subject_assignee = 'TicketAssignedToYou';
$body_assignee = 'TicketAssignedEmailBody';
$see_ticket_assignee = 'SeeThisTicketIntomanagementInterface';
// Send email to notification email // Send email to notification email
if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) { if (getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') && empty($object->context['disableticketemail'])) {
$sendto = !getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO') ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; $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 // Send email to customer
if (!getDolGlobalString('TICKET_DISABLE_CUSTOMER_MAILS') && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { if (!getDolGlobalString('TICKET_DISABLE_CUSTOMER_MAILS') && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) {
$sendto = ''; $sendto = '';
@@ -460,4 +472,72 @@ class InterfaceTicketEmail extends DolibarrTriggers
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; $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 = '<p>'.$langs->transnoentities($body, $object->track_id, dolGetFirstLastname($user->firstname, $user->lastname))."</p>";
$message .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
$message .= '<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
$message .= '<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
$message .= '<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
// Extrafields
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message .= '<li>'.$langs->trans($key).' : '.$value.'</li>';
}
}
$message .= '</ul>';
$message .= '<p>'.$langs->trans('Message').' : <br>'.$object->message.'</p>';
$message .= '<p><a href="'.dol_buildpath('/ticket/card.php', 2).'?track_id='.$object->track_id.'">'.$langs->trans($see_ticket).'</a></p>';
$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;
}
}
} }

View File

@@ -240,7 +240,13 @@ class Donations extends DolibarrApi
continue; 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) { if ($this->don->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -457,7 +457,13 @@ class Shipments extends DolibarrApi
continue; 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) { if ($this->shipment->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -430,7 +430,13 @@ class ExpenseReports extends DolibarrApi
continue; 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) { if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -630,6 +630,7 @@ class ExpenseReport extends CommonObject
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d";
if ($ref) { if ($ref) {
$sql .= " WHERE d.ref = '".$this->db->escape($ref)."'"; $sql .= " WHERE d.ref = '".$this->db->escape($ref)."'";
$sql .= " AND d.entity IN (".getEntity('expensereport').")";
} else { } else {
$sql .= " WHERE d.rowid = ".((int) $id); $sql .= " WHERE d.rowid = ".((int) $id);
} }

View File

@@ -274,6 +274,13 @@ class SupplierInvoices extends DolibarrApi
continue; 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); $this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice);
} }

View File

@@ -294,6 +294,13 @@ class SupplierOrders extends DolibarrApi
continue; 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); $this->order->$field = $this->_checkValForAPI($field, $value, $this->order);
} }

View File

@@ -53,8 +53,8 @@ class Odf
public $userdefined=array(); public $userdefined=array();
const PIXEL_TO_CM = 0.026458333; 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_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 = '/&lt;([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/&gt;)|(?:&gt;(.*)&lt;\/\1&gt;))/'; const FIND_ENCODED_TAGS_REGEX = '/&lt;([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/&gt;)|(?:&gt;(((?!&lt;\1(\s.*)?&gt;).)*)&lt;\/\1&gt;))/';
/** /**

View File

@@ -305,6 +305,13 @@ class KnowledgeManagement extends DolibarrApi
continue; 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); $this->knowledgerecord->$field = $this->_checkValForAPI($field, $value, $this->knowledgerecord);
} }

View File

@@ -84,7 +84,7 @@ if (empty($reshook)) {
if ($result > 0) { if ($result > 0) {
setEventMessages($langs->trans('LoanPaid'), null, 'mesgs'); setEventMessages($langs->trans('LoanPaid'), null, 'mesgs');
} else { } else {
setEventMessages($loan->error, null, 'errors'); setEventMessages($object->error, $object->errors, 'errors');
} }
} }
@@ -97,7 +97,7 @@ if (empty($reshook)) {
header("Location: list.php"); header("Location: list.php");
exit; exit;
} else { } else {
setEventMessages($loan->error, null, 'errors'); setEventMessages($object->error, $object->errors, 'errors');
} }
} }

View File

@@ -308,6 +308,7 @@ class Loan extends CommonObject
$accountline->fetch($line_url['fk_bank']); $accountline->fetch($line_url['fk_bank']);
$result = $accountline->delete_urls($user); $result = $accountline->delete_urls($user);
if ($result < 0) { if ($result < 0) {
$this->errors = array_merge($this->errors, [$accountline->error], $accountline->errors);
$error++; $error++;
} }
} }

View File

@@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2014-2025 Alexandre Spangaro <alexandre@inovea-conseil.com> /* Copyright (C) 2014-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2015-2023 Frederic France <frederic.france@netlogic.fr> * Copyright (C) 2015-2023 Frederic France <frederic.france@free.fr>
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr> * Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify

View File

@@ -268,6 +268,13 @@ class MyModuleApi extends DolibarrApi
continue; 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); $this->myobject->$field = $this->_checkValForAPI($field, $value, $this->myobject);
} }

View File

@@ -249,7 +249,14 @@ class Mos extends DolibarrApi
continue; 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(); $this->checkRefNumbering();

View File

@@ -264,6 +264,12 @@ class Partnerships extends DolibarrApi
$this->partnership->context['caller'] = $request_data['caller']; $this->partnership->context['caller'] = $request_data['caller'];
continue; 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); $this->partnership->$field = $this->_checkValForAPI($field, $value, $this->partnership);
} }

View File

@@ -371,7 +371,14 @@ class Products extends DolibarrApi
continue; 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; $updatetype = false;

View File

@@ -217,7 +217,13 @@ class Warehouses extends DolibarrApi
continue; 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)) { if ($this->warehouse->update($id, DolibarrApiAccess::$user)) {

View File

@@ -476,7 +476,13 @@ class Projects extends DolibarrApi
continue; 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) { if ($this->project->update(DolibarrApiAccess::$user) >= 0) {

View File

@@ -472,7 +472,13 @@ class Tasks extends DolibarrApi
continue; 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) { if ($this->task->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -458,7 +458,13 @@ class Receptions extends DolibarrApi
continue; 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) { if ($this->reception->update(DolibarrApiAccess::$user) > 0) {

View File

@@ -350,7 +350,7 @@ class Contacts extends DolibarrApi
} }
if ($field == 'array_options' && is_array($value)) { if ($field == 'array_options' && is_array($value)) {
foreach ($value as $index => $val) { foreach ($value as $index => $val) {
$this->contact->array_options[$index] = $val; $this->contact->array_options[$index] = $this->_checkValForAPI($field, $val, $this->contact);
} }
continue; continue;
} }

View File

@@ -318,6 +318,12 @@ class Thirdparties extends DolibarrApi
continue; 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); $this->company->$field = $this->_checkValForAPI($field, $value, $this->company);
} }

View File

@@ -557,7 +557,7 @@ if ($search_sale == -2) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; $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 ($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)) { } 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 // Add table from hooks
$parameters = array(); $parameters = array();
@@ -568,9 +568,6 @@ $sql .= " WHERE s.entity IN (".getEntity('societe').")";
if (!$user->hasRight('societe', 'client', 'voir') && !$socid) { if (!$user->hasRight('societe', 'client', 'voir') && !$socid) {
$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); $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')) { if (!$user->hasRight('fournisseur', 'lire')) {
$sql .= " AND (s.fournisseur <> 1 OR s.client <> 0)"; // client=0, fournisseur=0 must be visible $sql .= " AND (s.fournisseur <> 1 OR s.client <> 0)"; // client=0, fournisseur=0 must be visible
} }

View File

@@ -394,7 +394,16 @@ class Tickets extends DolibarrApi
continue; 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)) { if ($this->ticket->update(DolibarrApiAccess::$user)) {

View File

@@ -417,7 +417,13 @@ class Users extends DolibarrApi
throw new RestException(500, 'Error when updating status of user: '.$this->useraccount->error); throw new RestException(500, 'Error when updating status of user: '.$this->useraccount->error);
} }
} else { } 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);
} }
} }

View File

@@ -702,16 +702,16 @@ class ProductCombination
* [...] * [...]
* ) * )
* *
* @param User $user Object user * @param User $user Object user
* @param Product $product Parent product * @param Product $product Parent product
* @param array $combinations Attribute and value combinations. * @param array $combinations Attribute and value combinations.
* @param array $variations Price and weight variations * @param array $variations Price and weight variations
* @param bool|array $price_var_percent Is the price variation a relative variation? * @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|array $forced_pricevar If the price variation is forced
* @param bool|float $forced_weightvar If the weight 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 bool|string $forced_refvar If the reference is forced
* @param string $ref_ext External reference * @param string $ref_ext External reference
* @return int Return integer <0 KO, >0 OK * @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 = '') 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; $price_impact = $forced_pricevar;
} }
if (!array($price_var_percent)) { if (!is_array($price_var_percent)) {
$price_var_percent[1] = (float) $price_var_percent; $price_var_percent = array(1 => (bool) $price_var_percent);
} }
$newcomb = new ProductCombination($this->db); $newcomb = new ProductCombination($this->db);
@@ -955,13 +955,26 @@ class ProductCombination
$variations[$tmp_pc2v->fk_prod_attr] = $tmp_pc2v->fk_prod_attr_val; $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( if ($this->createProductCombination(
$user, $user,
$destProduct, $destProduct,
$variations, $variations,
array(), array(),
$combination->variation_price_percentage, $variation_price_percentage,
$combination->variation_price, $variation_price,
$combination->variation_weight $combination->variation_weight
) < 0) { ) < 0) {
return -1; return -1;

View File

@@ -296,33 +296,45 @@ class ODFTest extends PHPUnit\Framework\TestCase
'charset' => null, 'charset' => null,
'expected' => mb_convert_encoding('text with <text:span text:style-name="boldText">intricated<text:span text:style-name="underlineText">tags</text:span></text:span>', 'UTF-8', 'ISO-8859-1'), 'expected' => mb_convert_encoding('text with <text:span text:style-name="boldText">intricated<text:span text:style-name="underlineText">tags</text:span></text:span>', 'UTF-8', 'ISO-8859-1'),
], ],
24 => [
'to_convert' => "text with <strong>two</strong> (strong) <strong>tags</strong>",
'encode' => true,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">two</text:span> (strong) <text:span text:style-name="boldText">tags</text:span>'),
],
25 => [
'to_convert' => "text with <strong class=\"whatever\">two</strong> (strong) <strong class=\"the weather\">tags and <u>intricated</u> underline </strong>",
'encode' => true,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">two</text:span> (strong) <text:span text:style-name="boldText">tags and <text:span text:style-name="underlineText">intricated</text:span> underline </text:span>'),
],
// One can also pass html-encoded string to the method // One can also pass html-encoded string to the method
24 => [ 26 => [
'to_convert' => 'One&amp;two', 'to_convert' => 'One&amp;two',
'encode' => true, 'encode' => true,
'charset' => null, 'charset' => null,
'expected' => 'One&amp;two', 'expected' => 'One&amp;two',
], ],
25 => [ 27 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;", 'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => false, 'encode' => false,
'charset' => 'UTF-8', 'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>', 'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>',
], ],
26 => [ 28 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;", 'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => true, 'encode' => true,
'charset' => 'UTF-8', 'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&amp;ciàlchärs éè l&apos;</text:span>', 'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&amp;ciàlchärs éè l&apos;</text:span>',
], ],
27 => [ 29 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;", 'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => false, 'encode' => false,
'charset' => null, 'charset' => null,
'expected' => mb_convert_encoding('text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>', 'UTF-8', 'ISO-8859-1'), 'expected' => mb_convert_encoding('text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>', 'UTF-8', 'ISO-8859-1'),
], ],
28 => [ 30 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;", 'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => true, 'encode' => true,
'charset' => null, '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. // 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. // The method removes hyperlinks and tags that are not dealt with.
29 => [ 31 => [
'to_convert' => '123 <a href="/test.php">trucmachin > truc < troc > trac</a>bla bla', 'to_convert' => '123 <a href="/test.php">trucmachin > truc < troc > trac</a>bla bla',
'encode' => true, 'encode' => true,
'charset' => null, 'charset' => null,
'expected' => "123 trucmachin &gt; truc &lt; troc &gt; tracbla bla", 'expected' => "123 trucmachin &gt; truc &lt; troc &gt; tracbla bla",
], ],
30 => [ 32 => [
'to_convert' => '123 <h3>Title</h3> bla', 'to_convert' => '123 <h3>Title</h3> bla',
'encode' => true, 'encode' => true,
'charset' => null, 'charset' => null,
'expected' => "123 Title bla", 'expected' => "123 Title bla",
], ],
// HTML should not take \n into account, but only <br />. // HTML should not take \n into account, but only <br />.
31 => [ 33 => [
'to_convert' => "text with <strong>strong text </strong>, a line\nbreak and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>", 'to_convert' => "text with <strong>strong text </strong>, a line\nbreak and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>",
'encode' => false, 'encode' => false,
'charset' => 'UTF-8', 'charset' => 'UTF-8',
@@ -373,7 +385,7 @@ class ODFTest extends PHPUnit\Framework\TestCase
} else { } else {
$res = $odf->convertVarToOdf($case['to_convert'], $case['encode']); $res = $odf->convertVarToOdf($case['to_convert'], $case['encode']);
} }
$this->assertEquals($res, $case['expected']); $this->assertEquals($case['expected'], $res);
} }
print __METHOD__." result=".$result."\n"; print __METHOD__." result=".$result."\n";