dolibarr 20.0.5
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 v.fk_product_attribute, v.rowid, v.ref, v.value FROM " . MAIN_DB_PREFIX . "product_attribute_value v ";
291
292 $sql .= "WHERE v.fk_product_attribute = " . ((int) $prodattr_id);
293
294 if ($only_used) {
295 $sql .= " AND EXISTS (SELECT c2v.fk_prod_attr_val ";
296 $sql .= "FROM " . MAIN_DB_PREFIX . "product_attribute_combination2val c2v ";
297 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product_attribute_combination c ON c.rowid = c2v.fk_prod_combination ";
298 $sql .= "LEFT JOIN " . MAIN_DB_PREFIX . "product p ON p.rowid = c.fk_product_child";
299 $sql .= " WHERE c2v.rowid IS NOT NULL AND p.tosell = 1 AND c2v.fk_prod_attr_val = v.rowid)";
300 }
301
302 $sql .= " ORDER BY v.position ASC";
303
304 $query = $this->db->query($sql);
305
306 if ($query) {
307 while ($result = $this->db->fetch_object($query)) {
308 if (empty($returnonlydata)) {
309 $tmp = new ProductAttributeValue($this->db);
310 } else {
311 $tmp = new stdClass();
312 }
313
314 $tmp->fk_product_attribute = $result->fk_product_attribute;
315 $tmp->id = $result->rowid;
316 $tmp->ref = $result->ref;
317 $tmp->value = $result->value;
318
319 $return[] = $tmp;
320 }
321 }
322
323 return $return;
324 }
325
333 public function update(User $user, $notrigger = 0)
334 {
335 global $langs;
336 $error = 0;
337
338 // Clean parameters
339 $this->fk_product_attribute = $this->fk_product_attribute > 0 ? $this->fk_product_attribute : 0;
340 $this->ref = strtoupper(dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)))); // Ref must be uppercase
341 $this->value = trim($this->value);
342
343 // Check parameters
344 if (empty($this->fk_product_attribute)) {
345 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductAttribute"));
346 $error++;
347 }
348 if (empty($this->ref)) {
349 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
350 $error++;
351 }
352 if (empty($this->value)) {
353 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Value"));
354 $error++;
355 }
356 if ($error) {
357 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
358 return -1;
359 }
360
361 $this->db->begin();
362
363 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET";
364
365 $sql .= " fk_product_attribute = " . ((int) $this->fk_product_attribute);
366 $sql .= ", ref = '" . $this->db->escape($this->ref) . "'";
367 $sql .= ", value = '" . $this->db->escape($this->value) . "'";
368 $sql .= ", position = " . ((int) $this->position);
369
370 $sql .= " WHERE rowid = " . ((int) $this->id);
371
372 dol_syslog(__METHOD__, LOG_DEBUG);
373 $resql = $this->db->query($sql);
374 if (!$resql) {
375 $this->errors[] = "Error " . $this->db->lasterror();
376 $error++;
377 }
378
379 if (!$error && !$notrigger) {
380 // Call trigger
381 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user);
382 if ($result < 0) {
383 $error++;
384 }
385 // End call triggers
386 }
387
388 if (!$error) {
389 $this->db->commit();
390 return 1;
391 } else {
392 $this->db->rollback();
393 return -1 * $error;
394 }
395 }
396
404 public function delete(User $user, $notrigger = 0)
405 {
406 global $langs;
407 $error = 0;
408
409 // Clean parameters
410 $this->id = $this->id > 0 ? $this->id : 0;
411
412 // Check parameters
413 if (empty($this->id)) {
414 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
415 $error++;
416 }
417 if ($error) {
418 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
419 return -1;
420 }
421
422 $result = $this->isUsed();
423 if ($result < 0) {
424 return -1;
425 } elseif ($result > 0) {
426 $this->errors[] = $langs->trans('ErrorAttributeValueIsUsedIntoProduct');
427 return -1;
428 }
429
430 $this->db->begin();
431
432 if (!$error && !$notrigger) {
433 // Call trigger
434 $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user);
435 if ($result < 0) {
436 $error++;
437 }
438 // End call triggers
439 }
440
441 if (!$error) {
442 $sql = "DELETE FROM " . MAIN_DB_PREFIX . $this->table_element . " WHERE rowid = " . ((int) $this->id);
443
444 dol_syslog(__METHOD__, LOG_DEBUG);
445 $resql = $this->db->query($sql);
446 if (!$resql) {
447 $this->errors[] = "Error " . $this->db->lasterror();
448 $error++;
449 }
450 }
451
452 if (!$error) {
453 $this->db->commit();
454 return 1;
455 } else {
456 $this->db->rollback();
457 return -1 * $error;
458 }
459 }
460
466 public function isUsed()
467 {
468 global $langs;
469 $error = 0;
470
471 // Clean parameters
472 $this->id = $this->id > 0 ? $this->id : 0;
473
474 // Check parameters
475 if (empty($this->id)) {
476 $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TechnicalID"));
477 $error++;
478 }
479 if ($error) {
480 dol_syslog(__METHOD__ . ' ' . $this->errorsToString(), LOG_ERR);
481 return -1;
482 }
483
484 $sql = "SELECT COUNT(*) AS nb FROM " . MAIN_DB_PREFIX . "product_attribute_combination2val WHERE fk_prod_attr_val = " . ((int) $this->id);
485
486 dol_syslog(__METHOD__, LOG_DEBUG);
487 $resql = $this->db->query($sql);
488 if (!$resql) {
489 $this->errors[] = "Error " . $this->db->lasterror();
490 return -1;
491 }
492
493 $used = 0;
494 if ($obj = $this->db->fetch_object($resql)) {
495 $used = $obj->nb;
496 }
497
498 return $used ? 1 : 0;
499 }
500}
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.