dolibarr 19.0.3
ProductAttributeValue.class.php
1<?php
2/* Copyright (C) 2016 Marcos GarcĂ­a <marcosgdf@gmail.com>
3 * Copyright (C) 2022 Open-Dsi <support@open-dsi.fr>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
25{
29 public $module = 'variants';
30
34 public $element = 'productattributevalue';
35
39 public $table_element = 'product_attribute_value';
40
45 public $ismultientitymanaged = 1;
46
50 public $isextrafieldmanaged = 0;
51
80 public $fields=array(
81 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"),
82 'fk_product_attribute' => array('type'=>'integer:ProductAttribute:variants/class/ProductAttribute.class.php', 'label'=>'ProductAttribute', 'enabled'=>1, 'visible'=>0, 'position'=>10, 'notnull'=>1, 'index'=>1,),
83 'ref' => array('type'=>'varchar(255)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'css'=>''),
84 'value' => array('type'=>'varchar(255)', 'label'=>'Value', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'help'=>"", 'showoncombobox'=>'1',),
85 'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,),
86 );
87 public $id;
88 public $fk_product_attribute;
89 public $ref;
90 public $value;
91 public $position;
92
98 public function __construct(DoliDB $db)
99 {
100 global $conf, $langs;
101
102 $this->db = $db;
103 $this->entity = $conf->entity;
104
105 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
106 $this->fields['rowid']['visible'] = 0;
107 }
108 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
109 $this->fields['entity']['enabled'] = 0;
110 }
111
112 // Unset fields that are disabled
113 foreach ($this->fields as $key => $val) {
114 if (isset($val['enabled']) && empty($val['enabled'])) {
115 unset($this->fields[$key]);
116 }
117 }
118
119 // Translate some data of arrayofkeyval
120 if (is_object($langs)) {
121 foreach ($this->fields as $key => $val) {
122 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
123 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
124 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
125 }
126 }
127 }
128 }
129 }
130
138 public function create(User $user, $notrigger = 0)
139 {
140 global $langs;
141 $error = 0;
142
143 // Clean parameters
144 $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
145 $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
146 $this->value = trim($this->value);
147
148 // Check parameters
149 if (empty($this->fk_product_attribute)) {
150 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
151 $error++;
152 }
153 if (empty($this->ref)) {
154 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
155 $error++;
156 }
157 if (empty($this->value)) {
158 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
159 $error++;
160 }
161 if ($error) {
162 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
163 return -1;
164 }
165
166 $this->db->begin();
167
168 $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (";
169 $sql .= " fk_product_attribute, ref, value, entity, position";
170 $sql .= ")";
171 $sql .= " VALUES (";
172 $sql .= " " . ((int) $this->fk_product_attribute);
173 $sql .= ", '" . $this->db->escape($this->ref) . "'";
174 $sql .= ", '" . $this->db->escape($this->value) . "'";
175 $sql .= ", " . ((int) $this->entity);
176 $sql .= ", " . ((int) $this->position);
177 $sql .= ")";
178
179 dol_syslog(__METHOD__, LOG_DEBUG);
180 $resql = $this->db->query($sql);
181 if (!$resql) {
182 $this->errors[] = "Error " . $this->db->lasterror();
183 $error++;
184 }
185
186 if (!$error) {
187 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
188 }
189
190 if (!$error && !$notrigger) {
191 // Call trigger
192 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user);
193 if ($result < 0) {
194 $error++;
195 }
196 // End call triggers
197 }
198
199 if ($error) {
200 $this->db->rollback();
201 return -1 * $error;
202 } else {
203 $this->db->commit();
204 return $this->id;
205 }
206 }
207
214 public function fetch($id)
215 {
216 global $langs;
217 $error = 0;
218
219 // Clean parameters
220 $id = $id > 0 ? $id : 0;
221
222 // Check parameters
223 if (empty($id)) {
224 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
225 $error++;
226 }
227 if ($error) {
228 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
229 return -1;
230 }
231
232 $sql = "SELECT rowid, fk_product_attribute, ref, value";
233 $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
234 $sql .= " WHERE rowid = " . ((int) $id);
235 $sql .= " AND entity IN (" . getEntity('product') . ")";
236
237 dol_syslog(__METHOD__, LOG_DEBUG);
238 $resql = $this->db->query($sql);
239 if (!$resql) {
240 $this->errors[] = "Error " . $this->db->lasterror();
241 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
242 return -1;
243 }
244
245 $numrows = $this->db->num_rows($resql);
246 if ($numrows) {
247 $obj = $this->db->fetch_object($resql);
248
249 $this->id = $obj->rowid;
250 $this->fk_product_attribute = $obj->fk_product_attribute;
251 $this->ref = $obj->ref;
252 $this->value = $obj->value;
253 }
254 $this->db->free($resql);
255
256 return $numrows;
257 }
258
267 public function fetchAllByProductAttribute($prodattr_id, $only_used = false, $returnonlydata = 0)
268 {
269 $return = array();
270
271 $sql = "SELECT ";
272
273 if ($only_used) {
274 $sql .= "DISTINCT ";
275 }
276
277 $sql .= "v.fk_product_attribute, v.rowid, v.ref, v.value FROM " . MAIN_DB_PREFIX . "product_attribute_value v ";
278
279 if ($only_used) {
280 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination2val c2v ON c2v.fk_prod_attr_val = v.rowid ";
281 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination c ON c.rowid = c2v.fk_prod_combination ";
282 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product p ON p.rowid = c.fk_product_child ";
283 }
284
285 $sql .= "WHERE v.fk_product_attribute = " . ((int) $prodattr_id);
286
287 if ($only_used) {
288 $sql .= " AND c2v.rowid IS NOT NULL AND p.tosell = 1";
289 }
290
291 $sql .= " ORDER BY v.position ASC";
292
293 $query = $this->db->query($sql);
294
295 while ($result = $this->db->fetch_object($query)) {
296 if (empty($returnonlydata)) {
297 $tmp = new ProductAttributeValue($this->db);
298 } else {
299 $tmp = new stdClass();
300 }
301
302 $tmp->fk_product_attribute = $result->fk_product_attribute;
303 $tmp->id = $result->rowid;
304 $tmp->ref = $result->ref;
305 $tmp->value = $result->value;
306
307 $return[] = $tmp;
308 }
309
310 return $return;
311 }
312
320 public function update(User $user, $notrigger = 0)
321 {
322 global $langs;
323 $error = 0;
324
325 // Clean parameters
326 $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
327 $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
328 $this->value = trim($this->value);
329
330 // Check parameters
331 if (empty($this->fk_product_attribute)) {
332 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
333 $error++;
334 }
335 if (empty($this->ref)) {
336 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
337 $error++;
338 }
339 if (empty($this->value)) {
340 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
341 $error++;
342 }
343 if ($error) {
344 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
345 return -1;
346 }
347
348 $this->db->begin();
349
350 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET";
351
352 $sql .= " fk_product_attribute = " . ((int) $this->fk_product_attribute);
353 $sql .= ", ref = '" . $this->db->escape($this->ref) . "'";
354 $sql .= ", value = '" . $this->db->escape($this->value) . "'";
355 $sql .= ", position = " . ((int) $this->position);
356
357 $sql .= " WHERE rowid = " . ((int) $this->id);
358
359 dol_syslog(__METHOD__, LOG_DEBUG);
360 $resql = $this->db->query($sql);
361 if (!$resql) {
362 $this->errors[] = "Error " . $this->db->lasterror();
363 $error++;
364 }
365
366 if (!$error && !$notrigger) {
367 // Call trigger
368 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user);
369 if ($result < 0) {
370 $error++;
371 }
372 // End call triggers
373 }
374
375 if (!$error) {
376 $this->db->commit();
377 return 1;
378 } else {
379 $this->db->rollback();
380 return -1 * $error;
381 }
382 }
383
391 public function delete(User $user, $notrigger = 0)
392 {
393 global $langs;
394 $error = 0;
395
396 // Clean parameters
397 $this->id = $this->id > 0 ? $this->id : 0;
398
399 // Check parameters
400 if (empty($this->id)) {
401 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
402 $error++;
403 }
404 if ($error) {
405 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
406 return -1;
407 }
408
409 $result = $this->isUsed();
410 if ($result < 0) {
411 return -1;
412 } elseif ($result > 0) {
413 $this->errors[] = $langs->trans('ErrorAttributeValueIsUsedIntoProduct');
414 return -1;
415 }
416
417 $this->db->begin();
418
419 if (!$error && !$notrigger) {
420 // Call trigger
421 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user);
422 if ($result < 0) {
423 $error++;
424 }
425 // End call triggers
426 }
427
428 if (!$error) {
429 $sql = "DELETE FROM " . MAIN_DB_PREFIX . $this->table_element . " WHERE rowid = " . ((int) $this->id);
430
431 dol_syslog(__METHOD__, LOG_DEBUG);
432 $resql = $this->db->query($sql);
433 if (!$resql) {
434 $this->errors[] = "Error " . $this->db->lasterror();
435 $error++;
436 }
437 }
438
439 if (!$error) {
440 $this->db->commit();
441 return 1;
442 } else {
443 $this->db->rollback();
444 return -1 * $error;
445 }
446 }
447
453 public function isUsed()
454 {
455 global $langs;
456 $error = 0;
457
458 // Clean parameters
459 $this->id = $this->id > 0 ? $this->id : 0;
460
461 // Check parameters
462 if (empty($this->id)) {
463 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
464 $error++;
465 }
466 if ($error) {
467 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
468 return -1;
469 }
470
471 $sql = "SELECT COUNT(*) AS nb FROM " . MAIN_DB_PREFIX . "product_attribute_combination2val WHERE fk_prod_attr_val = " . ((int) $this->id);
472
473 dol_syslog(__METHOD__, LOG_DEBUG);
474 $resql = $this->db->query($sql);
475 if (!$resql) {
476 $this->errors[] = "Error " . $this->db->lasterror();
477 return -1;
478 }
479
480 $used = 0;
481 if ($obj = $this->db->fetch_object($resql)) {
482 $used = $obj->nb;
483 }
484
485 return $used ? 1 : 0;
486 }
487}
$object ref
Definition info.php:79
errorsToString()
Method to output saved errors.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class ProductAttributeValue Used to represent a product attribute value.
create(User $user, $notrigger=0)
Creates a value for a product attribute.
fetch($id)
Gets a product attribute value.
update(User $user, $notrigger=0)
Updates a product attribute value.
isUsed()
Test if used by a product.
__construct(DoliDB $db)
Constructor.
fetchAllByProductAttribute($prodattr_id, $only_used=false, $returnonlydata=0)
Returns all product attribute values of a product attribute.
Class to manage Dolibarr users.
dol_string_nospecial($str, $newstr='_', $badcharstoreplace='', $badcharstoremove='', $keepspaces=0)
Clean a string from all punctuation characters to use it as a ref or login.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
rtl background position