dolibarr 20.0.0
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 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
27{
31 public $module = 'variants';
32
36 public $element = 'productattributevalue';
37
41 public $table_element = 'product_attribute_value';
42
71 public $fields = array(
72 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
73 'fk_product_attribute' => array('type' => 'integer:ProductAttribute:variants/class/ProductAttribute.class.php', 'label' => 'ProductAttribute', 'enabled' => 1, 'visible' => 0, 'position' => 10, 'notnull' => 1, 'index' => 1,),
74 'ref' => array('type' => 'varchar(255)', 'label' => 'Ref', 'visible' => 1, 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'index' => 1, 'searchall' => 1, 'comment' => "Reference of object", 'css' => ''),
75 'value' => array('type' => 'varchar(255)', 'label' => 'Value', 'enabled' => 1, 'position' => 30, 'notnull' => 1, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'help' => "", 'showoncombobox' => 1,),
76 'position' => array('type' => 'integer', 'label' => 'Rank', 'enabled' => 1, 'visible' => 0, 'default' => '0', 'position' => 200, 'notnull' => 1,),
77 );
78
83 public $id;
84
89 public $fk_product_attribute;
90
95 public $ref;
96
101 public $value;
102
107 public $position;
108
114 public function __construct(DoliDB $db)
115 {
116 global $conf, $langs;
117
118 $this->db = $db;
119
120 $this->ismultientitymanaged = 1;
121 $this->isextrafieldmanaged = 0;
122 $this->entity = $conf->entity;
123
124 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
125 $this->fields['rowid']['visible'] = 0;
126 }
127 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
128 $this->fields['entity']['enabled'] = 0;
129 }
130
131 // Unset fields that are disabled
132 foreach ($this->fields as $key => $val) {
133 if (isset($val['enabled']) && empty($val['enabled'])) {
134 unset($this->fields[$key]);
135 }
136 }
137
138 // Translate some data of arrayofkeyval
139 if (is_object($langs)) {
140 foreach ($this->fields as $key => $val) {
141 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
142 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
143 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
144 }
145 }
146 }
147 }
148 }
149
157 public function create(User $user, $notrigger = 0)
158 {
159 global $langs;
160 $error = 0;
161
162 // Clean parameters
163 $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
164 $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
165 $this->value = trim($this->value);
166
167 // Check parameters
168 if (empty($this->fk_product_attribute)) {
169 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
170 $error++;
171 }
172 if (empty($this->ref)) {
173 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
174 $error++;
175 }
176 if (empty($this->value)) {
177 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
178 $error++;
179 }
180 if ($error) {
181 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
182 return -1;
183 }
184
185 $this->db->begin();
186
187 $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (";
188 $sql .= " fk_product_attribute, ref, value, entity, position";
189 $sql .= ")";
190 $sql .= " VALUES (";
191 $sql .= " " . ((int) $this->fk_product_attribute);
192 $sql .= ", '" . $this->db->escape($this->ref) . "'";
193 $sql .= ", '" . $this->db->escape($this->value) . "'";
194 $sql .= ", " . ((int) $this->entity);
195 $sql .= ", " . ((int) $this->position);
196 $sql .= ")";
197
198 dol_syslog(__METHOD__, LOG_DEBUG);
199 $resql = $this->db->query($sql);
200 if (!$resql) {
201 $this->errors[] = "Error " . $this->db->lasterror();
202 $error++;
203 }
204
205 if (!$error) {
206 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
207 }
208
209 if (!$error && !$notrigger) {
210 // Call trigger
211 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user);
212 if ($result < 0) {
213 $error++;
214 }
215 // End call triggers
216 }
217
218 if ($error) {
219 $this->db->rollback();
220 return -1 * $error;
221 } else {
222 $this->db->commit();
223 return $this->id;
224 }
225 }
226
233 public function fetch($id)
234 {
235 global $langs;
236 $error = 0;
237
238 // Clean parameters
239 $id = $id > 0 ? $id : 0;
240
241 // Check parameters
242 if (empty($id)) {
243 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
244 $error++;
245 }
246 if ($error) {
247 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
248 return -1;
249 }
250
251 $sql = "SELECT rowid, fk_product_attribute, ref, value";
252 $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
253 $sql .= " WHERE rowid = " . ((int) $id);
254 $sql .= " AND entity IN (" . getEntity('product') . ")";
255
256 dol_syslog(__METHOD__, LOG_DEBUG);
257 $resql = $this->db->query($sql);
258 if (!$resql) {
259 $this->errors[] = "Error " . $this->db->lasterror();
260 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
261 return -1;
262 }
263
264 $numrows = $this->db->num_rows($resql);
265 if ($numrows) {
266 $obj = $this->db->fetch_object($resql);
267
268 $this->id = $obj->rowid;
269 $this->fk_product_attribute = $obj->fk_product_attribute;
270 $this->ref = $obj->ref;
271 $this->value = $obj->value;
272 }
273 $this->db->free($resql);
274
275 return $numrows;
276 }
277
286 public function fetchAllByProductAttribute($prodattr_id, $only_used = false, $returnonlydata = 0)
287 {
288 $return = array();
289
290 $sql = "SELECT ";
291
292 if ($only_used) {
293 $sql .= "DISTINCT ";
294 }
295
296 $sql .= "v.fk_product_attribute, v.rowid, v.ref, v.value FROM " . MAIN_DB_PREFIX . "product_attribute_value v ";
297
298 if ($only_used) {
299 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination2val c2v ON c2v.fk_prod_attr_val = v.rowid ";
300 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination c ON c.rowid = c2v.fk_prod_combination ";
301 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product p ON p.rowid = c.fk_product_child ";
302 }
303
304 $sql .= "WHERE v.fk_product_attribute = " . ((int) $prodattr_id);
305
306 if ($only_used) {
307 $sql .= " AND c2v.rowid IS NOT NULL AND p.tosell = 1";
308 }
309
310 $sql .= " ORDER BY v.position ASC";
311
312 $query = $this->db->query($sql);
313
314 while ($result = $this->db->fetch_object($query)) {
315 if (empty($returnonlydata)) {
316 $tmp = new ProductAttributeValue($this->db);
317 } else {
318 $tmp = new stdClass();
319 }
320
321 $tmp->fk_product_attribute = $result->fk_product_attribute;
322 $tmp->id = $result->rowid;
323 $tmp->ref = $result->ref;
324 $tmp->value = $result->value;
325
326 $return[] = $tmp;
327 }
328
329 return $return;
330 }
331
339 public function update(User $user, $notrigger = 0)
340 {
341 global $langs;
342 $error = 0;
343
344 // Clean parameters
345 $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
346 $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
347 $this->value = trim($this->value);
348
349 // Check parameters
350 if (empty($this->fk_product_attribute)) {
351 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
352 $error++;
353 }
354 if (empty($this->ref)) {
355 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
356 $error++;
357 }
358 if (empty($this->value)) {
359 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
360 $error++;
361 }
362 if ($error) {
363 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
364 return -1;
365 }
366
367 $this->db->begin();
368
369 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET";
370
371 $sql .= " fk_product_attribute = " . ((int) $this->fk_product_attribute);
372 $sql .= ", ref = '" . $this->db->escape($this->ref) . "'";
373 $sql .= ", value = '" . $this->db->escape($this->value) . "'";
374 $sql .= ", position = " . ((int) $this->position);
375
376 $sql .= " WHERE rowid = " . ((int) $this->id);
377
378 dol_syslog(__METHOD__, LOG_DEBUG);
379 $resql = $this->db->query($sql);
380 if (!$resql) {
381 $this->errors[] = "Error " . $this->db->lasterror();
382 $error++;
383 }
384
385 if (!$error && !$notrigger) {
386 // Call trigger
387 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user);
388 if ($result < 0) {
389 $error++;
390 }
391 // End call triggers
392 }
393
394 if (!$error) {
395 $this->db->commit();
396 return 1;
397 } else {
398 $this->db->rollback();
399 return -1 * $error;
400 }
401 }
402
410 public function delete(User $user, $notrigger = 0)
411 {
412 global $langs;
413 $error = 0;
414
415 // Clean parameters
416 $this->id = $this->id > 0 ? $this->id : 0;
417
418 // Check parameters
419 if (empty($this->id)) {
420 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
421 $error++;
422 }
423 if ($error) {
424 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
425 return -1;
426 }
427
428 $result = $this->isUsed();
429 if ($result < 0) {
430 return -1;
431 } elseif ($result > 0) {
432 $this->errors[] = $langs->trans('ErrorAttributeValueIsUsedIntoProduct');
433 return -1;
434 }
435
436 $this->db->begin();
437
438 if (!$error && !$notrigger) {
439 // Call trigger
440 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user);
441 if ($result < 0) {
442 $error++;
443 }
444 // End call triggers
445 }
446
447 if (!$error) {
448 $sql = "DELETE FROM " . MAIN_DB_PREFIX . $this->table_element . " WHERE rowid = " . ((int) $this->id);
449
450 dol_syslog(__METHOD__, LOG_DEBUG);
451 $resql = $this->db->query($sql);
452 if (!$resql) {
453 $this->errors[] = "Error " . $this->db->lasterror();
454 $error++;
455 }
456 }
457
458 if (!$error) {
459 $this->db->commit();
460 return 1;
461 } else {
462 $this->db->rollback();
463 return -1 * $error;
464 }
465 }
466
472 public function isUsed()
473 {
474 global $langs;
475 $error = 0;
476
477 // Clean parameters
478 $this->id = $this->id > 0 ? $this->id : 0;
479
480 // Check parameters
481 if (empty($this->id)) {
482 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
483 $error++;
484 }
485 if ($error) {
486 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
487 return -1;
488 }
489
490 $sql = "SELECT COUNT(*) AS nb FROM " . MAIN_DB_PREFIX . "product_attribute_combination2val WHERE fk_prod_attr_val = " . ((int) $this->id);
491
492 dol_syslog(__METHOD__, LOG_DEBUG);
493 $resql = $this->db->query($sql);
494 if (!$resql) {
495 $this->errors[] = "Error " . $this->db->lasterror();
496 return -1;
497 }
498
499 $used = 0;
500 if ($obj = $this->db->fetch_object($resql)) {
501 $used = $obj->nb;
502 }
503
504 return $used ? 1 : 0;
505 }
506}
print $object position
Definition edit.php:195
$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.