Skip to content

Commit c0de94b

Browse files
committed
Add skipUpdateIfUnchanged flag in ObjectModel to prevent update performance issues
1 parent 7a647f2 commit c0de94b

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

classes/ObjectModel.php

+39-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* @copyright Since 2007 PrestaShop SA and Contributors
2424
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
2525
*/
26+
use PrestaShop\PrestaShop\Adapter\ObjectModelComparator;
2627
use PrestaShop\PrestaShop\Adapter\ServiceLocator;
2728
use PrestaShop\PrestaShop\Core\Image\ImageFormatConfiguration;
2829
use PrestaShopBundle\Translation\TranslatorComponent;
@@ -153,6 +154,13 @@ abstract class ObjectModelCore implements PrestaShop\PrestaShop\Core\Foundation\
153154
*/
154155
protected static $cache_objects = true;
155156

157+
/**
158+
* Skip the update process when no change detected to improve performances
159+
*
160+
* @var bool
161+
*/
162+
public $skipUpdateIfUnchanged = false;
163+
156164
/**
157165
* @return null
158166
*/
@@ -686,12 +694,36 @@ public function duplicateObject()
686694
*
687695
* @throws PrestaShopDatabaseException
688696
* @throws PrestaShopException
697+
* @throws PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException
689698
*/
690699
public function update($null_values = false)
700+
{
701+
$currentClassName = $this->getObjectName();
702+
$oldObject = new $currentClassName($this->id, $this->id_lang, $this->id_shop);
703+
$comparator = new ObjectModelComparator($oldObject, $this);
704+
705+
if ($this->skipUpdateIfUnchanged && !$comparator->hasChanges()) {
706+
return true;
707+
}
708+
709+
return $this->processUpdateAction((bool) $null_values, $comparator);
710+
}
711+
712+
/**
713+
* Updates the current object in the database.
714+
*
715+
* @param bool $null_values
716+
* @param ObjectModelComparator|null $comparator
717+
* @return bool
718+
*
719+
* @throws PrestaShopDatabaseException
720+
* @throws PrestaShopException
721+
*/
722+
protected function processUpdateAction(bool $null_values = false, ObjectModelComparator $comparator = null): bool
691723
{
692724
// @hook actionObject<ObjectClassName>UpdateBefore
693-
Hook::exec('actionObjectUpdateBefore', ['object' => $this]);
694-
Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateBefore', ['object' => $this]);
725+
Hook::exec('actionObjectUpdateBefore', ['object' => $this, 'objectComparator' => $comparator]);
726+
Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateBefore', ['object' => $this, 'objectComparator' => $comparator]);
695727

696728
$this->clearCache();
697729

@@ -779,8 +811,8 @@ public function update($null_values = false)
779811
foreach ($id_shop_list as $id_shop) {
780812
$field['id_shop'] = (int) $id_shop;
781813
$where = pSQL($this->def['primary']) . ' = ' . (int) $this->id
782-
. ' AND id_lang = ' . (int) $field['id_lang']
783-
. ' AND id_shop = ' . (int) $id_shop;
814+
. ' AND id_lang = ' . (int) $field['id_lang']
815+
. ' AND id_shop = ' . (int) $id_shop;
784816

785817
if (Db::getInstance()->getValue('SELECT COUNT(*) FROM ' . pSQL(_DB_PREFIX_ . $this->def['table']) . '_lang WHERE ' . $where)) {
786818
$result &= Db::getInstance()->update($this->def['table'] . '_lang', $field, $where);
@@ -791,7 +823,7 @@ public function update($null_values = false)
791823
} else {
792824
// If this table is not linked to multishop system ...
793825
$where = pSQL($this->def['primary']) . ' = ' . (int) $this->id
794-
. ' AND id_lang = ' . (int) $field['id_lang'];
826+
. ' AND id_lang = ' . (int) $field['id_lang'];
795827
if (Db::getInstance()->getValue('SELECT COUNT(*) FROM ' . pSQL(_DB_PREFIX_ . $this->def['table']) . '_lang WHERE ' . $where)) {
796828
$result &= Db::getInstance()->update($this->def['table'] . '_lang', $field, $where);
797829
} else {
@@ -803,8 +835,8 @@ public function update($null_values = false)
803835
}
804836

805837
// @hook actionObject<ObjectClassName>UpdateAfter
806-
Hook::exec('actionObjectUpdateAfter', ['object' => $this]);
807-
Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateAfter', ['object' => $this]);
838+
Hook::exec('actionObjectUpdateAfter', ['object' => $this, 'objectComparator' => $comparator]);
839+
Hook::exec('actionObject' . $this->getFullyQualifiedName() . 'UpdateAfter', ['object' => $this, 'objectComparator' => $comparator]);
808840

809841
return $result;
810842
}

0 commit comments

Comments
 (0)