Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0

This commit is contained in:
Laurent Destailleur (aka Eldy)
2025-01-20 15:02:37 +01:00
32 changed files with 568 additions and 29 deletions

View File

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

View File

@@ -0,0 +1,336 @@
<?php
/* Copyright (C) 2017 Regis Houssin <regis.houssin@inodbox.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Luracast\Restler\RestException;
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
/**
* API class for members types
*
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
class MembersTypes extends DolibarrApi
{
/**
* @var array $FIELDS Mandatory fields, checked when create and update object
*/
public static $FIELDS = array(
'label',
);
/**
* Constructor
*/
public function __construct()
{
global $db, $conf;
$this->db = $db;
}
/**
* Get properties of a member type object
*
* Return an array with member type information
*
* @param int $id ID of member type
* @return Object Object with cleaned properties
*
* @throws RestException
*/
public function get($id)
{
if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
throw new RestException(401);
}
$membertype = new AdherentType($this->db);
$result = $membertype->fetch($id);
if (!$result) {
throw new RestException(404, 'member type not found');
}
if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
return $this->_cleanObjectDatas($membertype);
}
/**
* List members types
*
* Get a list of members types
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @param int $limit Limit for list
* @param int $page Page number
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.libelle:like:'SO-%') and (t.subscription:=:'1')"
* @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names
* @return array Array of member type objects
*
* @throws RestException
*/
public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '')
{
global $db, $conf;
$obj_ret = array();
if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
throw new RestException(401);
}
$sql = "SELECT t.rowid";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent_type AS t LEFT JOIN ".MAIN_DB_PREFIX."adherent_type_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields
$sql .= ' WHERE t.entity IN ('.getEntity('member_type').')';
// Add sql filters
if ($sqlfilters) {
$errormessage = '';
$sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
if ($errormessage) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage);
}
}
$sql .= $this->db->order($sortfield, $sortorder);
if ($limit) {
if ($page < 0) {
$page = 0;
}
$offset = $limit * $page;
$sql .= $this->db->plimit($limit + 1, $offset);
}
$result = $this->db->query($sql);
if ($result) {
$i = 0;
$num = $this->db->num_rows($result);
$min = min($num, ($limit <= 0 ? $num : $limit));
while ($i < $min) {
$obj = $this->db->fetch_object($result);
$membertype = new AdherentType($this->db);
if ($membertype->fetch($obj->rowid)) {
$obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($membertype), $properties);
}
$i++;
}
} else {
throw new RestException(503, 'Error when retrieve member type list : '.$this->db->lasterror());
}
return $obj_ret;
}
/**
* Create member type object
*
* @param array $request_data Request data
* @return int ID of member type
*/
public function post($request_data = null)
{
if (!DolibarrApiAccess::$user->hasRight('adherent', 'configurer')) {
throw new RestException(401);
}
// Check mandatory fields
$result = $this->_validate($request_data);
$membertype = new AdherentType($this->db);
foreach ($request_data as $field => $value) {
if ($field === 'caller') {
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
$membertype->context['caller'] = $request_data['caller'];
continue;
}
$membertype->$field = $value;
}
if ($membertype->create(DolibarrApiAccess::$user) < 0) {
throw new RestException(500, 'Error creating member type', array_merge(array($membertype->error), $membertype->errors));
}
return $membertype->id;
}
/**
* Update member type
*
* @param int $id ID of member type to update
* @param array $request_data Datas
* @return int
*/
public function put($id, $request_data = null)
{
if (!DolibarrApiAccess::$user->hasRight('adherent', 'configurer')) {
throw new RestException(401);
}
$membertype = new AdherentType($this->db);
$result = $membertype->fetch($id);
if (!$result) {
throw new RestException(404, 'member type not found');
}
if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
foreach ($request_data as $field => $value) {
if ($field == 'id') {
continue;
}
if ($field === 'caller') {
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
$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 = $this->_checkValForAPI($field, $value, $membertype);
}
// If there is no error, update() returns the number of affected rows
// so if the update is a no op, the return value is zero.
if ($membertype->update(DolibarrApiAccess::$user) >= 0) {
return $this->get($id);
} else {
throw new RestException(500, 'Error when updating member type: '.$membertype->error);
}
}
/**
* Delete member type
*
* @param int $id member type ID
* @return array
*/
public function delete($id)
{
if (!DolibarrApiAccess::$user->hasRight('adherent', 'configurer')) {
throw new RestException(401);
}
$membertype = new AdherentType($this->db);
$result = $membertype->fetch($id);
if (!$result) {
throw new RestException(404, 'member type not found');
}
if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
$res = $membertype->delete(DolibarrApiAccess::$user);
if ($res < 0) {
throw new RestException(500, "Can't delete, error occurs");
} elseif ($res == 0) {
throw new RestException(409, "Can't delete, that product is probably used");
}
return array(
'success' => array(
'code' => 200,
'message' => 'Member type deleted'
)
);
}
/**
* Validate fields before creating an object
*
* @param array|null $data Data to validate
* @return array
*
* @throws RestException
*/
private function _validate($data)
{
$membertype = array();
foreach (MembersTypes::$FIELDS as $field) {
if (!isset($data[$field])) {
throw new RestException(400, "$field field missing");
}
$membertype[$field] = $data[$field];
}
return $membertype;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
* Clean sensible object datas
*
* @param Object $object Object to clean
* @return Object Object with cleaned properties
*/
protected function _cleanObjectDatas($object)
{
// phpcs:enable
$object = parent::_cleanObjectDatas($object);
unset($object->array_options);
unset($object->linkedObjectsIds);
unset($object->context);
unset($object->canvas);
unset($object->fk_project);
unset($object->contact);
unset($object->contact_id);
unset($object->thirdparty);
unset($object->user);
unset($object->origin);
unset($object->origin_id);
unset($object->ref_ext);
unset($object->country);
unset($object->country_id);
unset($object->country_code);
unset($object->barcode_type);
unset($object->barcode_type_code);
unset($object->barcode_type_label);
unset($object->barcode_type_coder);
unset($object->mode_reglement_id);
unset($object->cond_reglement_id);
unset($object->cond_reglement);
unset($object->fk_delivery_address);
unset($object->shipping_method_id);
unset($object->model_pdf);
unset($object->fk_account);
unset($object->note_public);
unset($object->note_private);
unset($object->fk_incoterms);
unset($object->label_incoterms);
unset($object->location_incoterms);
unset($object->name);
unset($object->lastname);
unset($object->firstname);
unset($object->civility_id);
unset($object->total_ht);
unset($object->total_tva);
unset($object->total_localtax1);
unset($object->total_localtax2);
unset($object->total_ttc);
return $object;
}
}

View File

@@ -234,6 +234,12 @@ class Subscriptions extends DolibarrApi
continue;
}
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, $value, $subscription);
}

View File

@@ -249,11 +249,10 @@ class Boms extends DolibarrApi
if ($field == 'array_options' && is_array($value)) {
foreach ($value as $index => $val) {
$this->bom->array_options[$index] = $this->_checkValForAPI('extrafields', $val, $this->bom);
$this->bom->array_options[$index] = $this->_checkValForAPI($field, $val, $this->bom);
}
continue;
}
$this->bom->$field = $this->_checkValForAPI($field, $value, $this->bom);
}

View File

@@ -252,6 +252,13 @@ class Categories extends DolibarrApi
continue;
}
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);
}

View File

@@ -287,6 +287,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);
}

View File

@@ -348,6 +348,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);
}

View File

@@ -3336,9 +3336,9 @@ if ($action == 'create') {
$expesrc->fetch_optionals();
$object->array_options = $expesrc->array_options;
} else {
$cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0));
$mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
$fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
$cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : (!empty($cond_reglement_id) ? $cond_reglement_id : 0)));
$mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : (!empty($mode_reglement_id) ? $mode_reglement_id : 0)));
$fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : (!empty($fk_account) ? $fk_account : 0)));
if (isModEnabled('multicurrency')) {
if (!empty($objectsrc->multicurrency_code)) {

View File

@@ -10512,10 +10512,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<-1,max>|string ID of code if OK, 0 if key empty, -1 if KO
* @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 $conf;
@@ -10525,7 +10526,7 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid =
}
// Check in cache
if (isset($conf->cache['codeid'][$tablename][$key][$fieldid])) { // Can be defined to 0 or ''
if ($useCache && isset($conf->cache['codeid'][$tablename][$key][$fieldid])) { // Can be defined to 0 or ''
return $conf->cache['codeid'][$tablename][$key][$fieldid]; // Found in cache
}
@@ -10548,14 +10549,16 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid =
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
$valuetoget = '';
if ($obj) {
$conf->cache['codeid'][$tablename][$key][$fieldid] = $obj->valuetoget;
$valuetoget = $obj->valuetoget;
$conf->cache['codeid'][$tablename][$key][$fieldid] = $valuetoget;
} else {
$conf->cache['codeid'][$tablename][$key][$fieldid] = '';
}
$db->free($resql);
return $conf->cache['codeid'][$tablename][$key][$fieldid];
return $valuetoget;
} else {
return -1;
}

View File

@@ -1506,6 +1506,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);
@@ -1518,11 +1520,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).

View File

@@ -197,6 +197,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
// Note: $object->context['disableticketemail'] is set to 1 by public interface at creation because email sending is already managed by page
// $object->context['createdfrompublicinterface'] may also be defined when creation done from public interface

View File

@@ -256,6 +256,13 @@ class Donations extends DolibarrApi
continue;
}
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);
}

View File

@@ -483,6 +483,7 @@ class Shipments extends DolibarrApi
$this->shipment->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
continue;
}
if ($field == 'array_options' && is_array($value)) {
foreach ($value as $index => $val) {
$this->shipment->array_options[$index] = $this->_checkValForAPI($field, $val, $this->shipment);

View File

@@ -460,6 +460,13 @@ class ExpenseReports extends DolibarrApi
continue;
}
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);
}

View File

@@ -694,6 +694,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);
}

View File

@@ -289,6 +289,7 @@ class SupplierInvoices extends DolibarrApi
}
continue;
}
$this->invoice->$field = $this->_checkValForAPI($field, $value, $this->invoice);
}

View File

@@ -312,6 +312,7 @@ class SupplierOrders extends DolibarrApi
}
continue;
}
$this->order->$field = $this->_checkValForAPI($field, $value, $this->order);
}

View File

@@ -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 = '/&lt;([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/&gt;)|(?:&gt;(.*)&lt;\/\1&gt;))/';
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(\s.*)?&gt;).)*)&lt;\/\1&gt;))/';
/**

View File

@@ -311,6 +311,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);
}

View File

@@ -359,6 +359,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++;
}
}

View File

@@ -288,6 +288,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);
}

View File

@@ -235,6 +235,13 @@ class Mos extends DolibarrApi
continue;
}
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);
}

View File

@@ -249,6 +249,12 @@ class Partnerships extends DolibarrApi
$this->partnership->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
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);
}

View File

@@ -400,6 +400,7 @@ class Products extends DolibarrApi
}
continue;
}
$this->product->$field = $this->_checkValForAPI($field, $value, $this->product);
}

View File

@@ -217,6 +217,13 @@ class Warehouses extends DolibarrApi
continue;
}
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);
}

View File

@@ -496,6 +496,13 @@ class Receptions extends DolibarrApi
continue;
}
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, $value, $this->reception);
}

View File

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

View File

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

View File

@@ -402,6 +402,16 @@ class Tickets extends DolibarrApi
continue;
}
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);
}

View File

@@ -407,6 +407,12 @@ class Users extends DolibarrApi
$this->useraccount->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
continue;
}
if ($field == 'array_options' && is_array($value)) {
foreach ($value as $index => $val) {
$this->useraccount->array_options[$index] = $this->_checkValForAPI($field, $val, $this->useraccount);
}
continue;
}
if (DolibarrApiAccess::$user->admin) { // If user for API is admin
if ($field == 'admin' && $value != $this->useraccount->admin && empty($value)) {

View File

@@ -795,8 +795,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);
@@ -998,13 +998,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;

View File

@@ -218,33 +218,45 @@ class ODFTest extends CommonClassTest
'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'),
],
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
24 => [
26 => [
'to_convert' => 'One&amp;two',
'encode' => true,
'charset' => null,
'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;",
'encode' => false,
'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>',
],
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;",
'encode' => true,
'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>',
],
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;",
'encode' => false,
'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'),
],
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;",
'encode' => true,
'charset' => null,
@@ -263,20 +275,20 @@ class ODFTest extends CommonClassTest
// 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 <a href="/test.php">trucmachin > truc < troc > trac</a>bla bla',
'encode' => true,
'charset' => null,
'expected' => "123 trucmachin &gt; truc &lt; troc &gt; tracbla bla",
],
30 => [
32 => [
'to_convert' => '123 <h3>Title</h3> bla',
'encode' => true,
'charset' => null,
'expected' => "123 Title bla",
],
// 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>",
'encode' => false,
'charset' => 'UTF-8',
@@ -295,7 +307,7 @@ class ODFTest extends CommonClassTest
} else {
$res = $odf->convertVarToOdf($case['to_convert'], $case['encode']);
}
$this->assertEquals($res, $case['expected']);
$this->assertEquals($case['expected'], $res);
}
print __METHOD__." result=".$result."\n";