public static doGetInheritedValues ( |
||
$object | ||
return | boolean |
/** * enables inheritance for field collections, if xxxInheritance field is available and set to string 'true' * * @param string $key * @return mixed|\Pimcore\Model\Object\Fieldcollection */ public function preGetValue($key) { if ($this->getClass()->getAllowInherit() && \Pimcore\Model\Object\AbstractObject::doGetInheritedValues() && $this->getClass()->getFieldDefinition($key) instanceof \Pimcore\Model\Object\ClassDefinition\Data\Fieldcollections) { $checkInheritanceKey = $key . "Inheritance"; if ($this->{'get' . $checkInheritanceKey}() == "true") { $parentValue = $this->getValueFromParent($key); $data = $this->{$key}; if (!$data) { $data = $this->getClass()->getFieldDefinition($key)->preGetData($this); } if (!$data) { return $parentValue; } else { if (!empty($parentValue)) { $value = new \Pimcore\Model\Object\Fieldcollection($parentValue->getItems()); if (!empty($data)) { foreach ($data as $entry) { $value->add($entry); } } } else { $value = new \Pimcore\Model\Object\Fieldcollection($data->getItems()); } return $value; } } } return parent::preGetValue($key); }
/** * @return \Pimcore\Model\Object\Objectbrick\Data\CoreShopDimensionSize */ public function getCoreShopDimensionSize() { if (!$this->CoreShopDimensionSize && \Pimcore\Model\Object\AbstractObject::doGetInheritedValues($this->getObject())) { $brick = $this->getObject()->getValueFromParent("dimensions"); if (!empty($brick)) { return $this->getObject()->getValueFromParent("dimensions")->getCoreShopDimensionSize(); } } return $this->CoreShopDimensionSize; }
/** * */ public function save() { $this->delete(false); $object = $this->model->getObject(); $validLanguages = Tool::getValidLanguages(); $context = $this->model->getContext(); if ($context && $context["containerType"] == "fieldcollection") { $containerKey = $context["containerKey"]; $container = Object\Fieldcollection\Definition::getByKey($containerKey); } else { $container = $this->model->getClass(); } $fieldDefinitions = $container->getFielddefinition("localizedfields")->getFielddefinitions(); foreach ($validLanguages as $language) { $inheritedValues = Object\AbstractObject::doGetInheritedValues(); Object\AbstractObject::setGetInheritedValues(false); $insertData = ["ooo_id" => $this->model->getObject()->getId(), "language" => $language]; if ($container instanceof Object\Fieldcollection\Definition) { $insertData["fieldname"] = $context["fieldname"]; $insertData["index"] = $context["index"]; } foreach ($fieldDefinitions as $fd) { if (method_exists($fd, "save")) { // for fieldtypes which have their own save algorithm eg. objects, multihref, ... $context = $this->model->getContext() ? $this->model->getContext() : []; if ($context["containerType"] == "fieldcollection") { $context["subContainerType"] = "localizedfield"; } $childParams = ["context" => $context, "language" => $language]; $fd->save($this->model, $childParams); } else { if (is_array($fd->getColumnType())) { $insertDataArray = $fd->getDataForResource($this->model->getLocalizedValue($fd->getName(), $language, true), $object); $insertData = array_merge($insertData, $insertDataArray); } else { $insertData[$fd->getName()] = $fd->getDataForResource($this->model->getLocalizedValue($fd->getName(), $language, true), $object); } } } $storeTable = $this->getTableName(); $queryTable = $this->getQueryTableName() . "_" . $language; $this->db->insertOrUpdate($storeTable, $insertData); if ($container instanceof Object\ClassDefinition) { // query table $data = []; $data["ooo_id"] = $this->model->getObject()->getId(); $data["language"] = $language; $this->inheritanceHelper = new Object\Concrete\Dao\InheritanceHelper($object->getClassId(), "ooo_id", $storeTable, $queryTable); $this->inheritanceHelper->resetFieldsToCheck(); $sql = "SELECT * FROM " . $queryTable . " WHERE ooo_id = " . $object->getId() . " AND language = '" . $language . "'"; $oldData = []; try { $oldData = $this->db->fetchRow($sql); } catch (\Exception $e) { // if the table doesn't exist -> create it! if (strpos($e->getMessage(), "exist")) { // the following is to ensure consistent data and atomic transactions, while having the flexibility // to add new languages on the fly without saving all classes having localized fields // first we need to roll back all modifications, because otherwise they would be implicitly committed // by the following DDL $this->db->rollBack(); // this creates the missing table $this->createUpdateTable(); // at this point we throw an exception so that the transaction gets repeated in Object::save() throw new \Exception("missing table created, start next run ... ;-)"); } } // get fields which shouldn't be updated $untouchable = []; // @TODO: currently we do not support lazyloading in localized fields $inheritanceEnabled = $object->getClass()->getAllowInherit(); $parentData = null; if ($inheritanceEnabled) { // get the next suitable parent for inheritance $parentForInheritance = $object->getNextParentForInheritance(); if ($parentForInheritance) { // we don't use the getter (built in functionality to get inherited values) because we need to avoid race conditions // we cannot Object\AbstractObject::setGetInheritedValues(true); and then $this->model->getLocalizedValue($key, $language) // so we select the data from the parent object using FOR UPDATE, which causes a lock on this row // so the data of the parent cannot be changed while this transaction is on progress $parentData = $this->db->fetchRow("SELECT * FROM " . $queryTable . " WHERE ooo_id = ? AND language = ? FOR UPDATE", [$parentForInheritance->getId(), $language]); } } foreach ($fieldDefinitions as $fd) { if ($fd->getQueryColumnType()) { $key = $fd->getName(); // exclude untouchables if value is not an array - this means data has not been loaded if (!(in_array($key, $untouchable) and !is_array($this->model->{$key}))) { $localizedValue = $this->model->getLocalizedValue($key, $language); $insertData = $fd->getDataForQueryResource($localizedValue, $object); $isEmpty = $fd->isEmpty($localizedValue); if (is_array($insertData)) { $columnNames = array_keys($insertData); $data = array_merge($data, $insertData); } else { $columnNames = [$key]; $data[$key] = $insertData; } // if the current value is empty and we have data from the parent, we just use it if ($isEmpty && $parentData) { foreach ($columnNames as $columnName) { if (array_key_exists($columnName, $parentData)) { $data[$columnName] = $parentData[$columnName]; if (is_array($insertData)) { $insertData[$columnName] = $parentData[$columnName]; } else { $insertData = $parentData[$columnName]; } } } } if ($inheritanceEnabled && $fd->getFieldType() != "calculatedValue") { //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; break; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$key] != $insertData) { // data changed, do check and update $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } } else { Logger::debug("Excluding untouchable query value for object [ " . $this->model->getId() . " ] key [ {$key} ] because it has not been loaded"); } } } $queryTable = $this->getQueryTableName() . "_" . $language; $this->db->insertOrUpdate($queryTable, $data); if ($inheritanceEnabled) { $this->inheritanceHelper->doUpdate($object->getId(), true); } $this->inheritanceHelper->resetFieldsToCheck(); } Object\AbstractObject::setGetInheritedValues($inheritedValues); } // foreach language }
/** * @param Object\Concrete $object * @throws \Exception */ public function save(Object\Concrete $object) { // HACK: set the pimcore admin mode to false to get the inherited values from parent if this source one is empty $inheritedValues = Object\AbstractObject::doGetInheritedValues(); $storetable = $this->model->getDefinition()->getTableName($object->getClass(), false); $querytable = $this->model->getDefinition()->getTableName($object->getClass(), true); $this->inheritanceHelper = new Object\Concrete\Dao\InheritanceHelper($object->getClassId(), "o_id", $storetable, $querytable); Object\AbstractObject::setGetInheritedValues(false); $fieldDefinitions = $this->model->getDefinition()->getFieldDefinitions(); $data = []; $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); // remove all relations try { $this->db->delete("object_relations_" . $object->getClassId(), "src_id = " . $object->getId() . " AND ownertype = 'objectbrick' AND ownername = '" . $this->model->getFieldname() . "' AND (position = '" . $this->model->getType() . "' OR position IS NULL OR position = '')"); } catch (\Exception $e) { Logger::warning("Error during removing old relations: " . $e); } foreach ($fieldDefinitions as $key => $fd) { $getter = "get" . ucfirst($fd->getName()); if (method_exists($fd, "save")) { // for fieldtypes which have their own save algorithm eg. objects, multihref, ... $fd->save($this->model); } elseif ($fd->getColumnType()) { if (is_array($fd->getColumnType())) { $insertDataArray = $fd->getDataForResource($this->model->{$getter}(), $object, ['context' => $this->model]); $data = array_merge($data, $insertDataArray); } else { $insertData = $fd->getDataForResource($this->model->{$getter}(), $object, ['context' => $this->model]); $data[$key] = $insertData; } } } $this->db->insertOrUpdate($storetable, $data); // get data for query table // $tableName = $this->model->getDefinition()->getTableName($object->getClass(), true); // this is special because we have to call each getter to get the inherited values from a possible parent object $data = []; $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); $this->inheritanceHelper->resetFieldsToCheck(); $oldData = $this->db->fetchRow("SELECT * FROM " . $querytable . " WHERE o_id = ?", $object->getId()); $inheritanceEnabled = $object->getClass()->getAllowInherit(); $parentData = null; if ($inheritanceEnabled) { // get the next suitable parent for inheritance $parentForInheritance = $object->getNextParentForInheritance(); if ($parentForInheritance) { // we don't use the getter (built in functionality to get inherited values) because we need to avoid race conditions // we cannot Object\AbstractObject::setGetInheritedValues(true); and then $this->model->$method(); // so we select the data from the parent object using FOR UPDATE, which causes a lock on this row // so the data of the parent cannot be changed while this transaction is on progress $parentData = $this->db->fetchRow("SELECT * FROM " . $querytable . " WHERE o_id = ? FOR UPDATE", $parentForInheritance->getId()); } } foreach ($fieldDefinitions as $key => $fd) { if ($fd->getQueryColumnType()) { //exclude untouchables if value is not an array - this means data has not been loaded $method = "get" . $key; $fieldValue = $this->model->{$method}(); $insertData = $fd->getDataForQueryResource($fieldValue, $object); $isEmpty = $fd->isEmpty($fieldValue); if (is_array($insertData)) { $columnNames = array_keys($insertData); $data = array_merge($data, $insertData); } else { $columnNames = [$key]; $data[$key] = $insertData; } // if the current value is empty and we have data from the parent, we just use it if ($isEmpty && $parentData) { foreach ($columnNames as $columnName) { if (array_key_exists($columnName, $parentData)) { $data[$columnName] = $parentData[$columnName]; if (is_array($insertData)) { $insertData[$columnName] = $parentData[$columnName]; } else { $insertData = $parentData[$columnName]; } } } } if ($inheritanceEnabled) { //get changed fields for inheritance if ($fd instanceof Object\ClassDefinition\Data\CalculatedValue) { // nothing to do, see https://github.com/pimcore/pimcore/issues/727 continue; } elseif ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; break; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$key] != $insertData) { // data changed, do check and update $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } } } $this->db->insertOrUpdate($querytable, $data); if ($inheritanceEnabled) { $this->inheritanceHelper->doUpdate($object->getId(), true); } $this->inheritanceHelper->resetFieldsToCheck(); // HACK: see a few lines above! Object\AbstractObject::setGetInheritedValues($inheritedValues); }
/** * @param $element * @return $this */ public function setDataFromElement($element) { $this->data = null; $this->id = new Data\Id($element); $this->fullPath = $element->getFullPath(); $this->creationDate = $element->getCreationDate(); $this->modificationDate = $element->getModificationDate(); $this->userModification = $element->getUserModification(); $this->userOwner = $element->getUserOwner(); $this->type = $element->getType(); if ($element instanceof Object\Concrete) { $this->subtype = $element->getClassName(); } else { $this->subtype = $this->type; } $this->properties = ""; $properties = $element->getProperties(); if (is_array($properties)) { foreach ($properties as $nextProperty) { $pData = (string) $nextProperty->getData(); if ($nextProperty->getName() == "bool") { $pData = $pData ? "true" : "false"; } $this->properties .= $nextProperty->getName() . ":" . $pData . " "; } } $this->data = ""; if ($element instanceof Document) { if ($element instanceof Document\Folder) { $this->data = $element->getKey(); $this->published = true; } else { if ($element instanceof Document\Link) { $this->published = $element->isPublished(); $this->data = $element->getTitle() . " " . $element->getHref(); } else { if ($element instanceof Document\PageSnippet) { $this->published = $element->isPublished(); $elements = $element->getElements(); if (is_array($elements) && !empty($elements)) { foreach ($elements as $tag) { if ($tag instanceof Document\Tag\TagInterface) { ob_start(); $this->data .= strip_tags($tag->frontend()) . " "; $this->data .= ob_get_clean(); } } } if ($element instanceof Document\Page) { $this->published = $element->isPublished(); $this->data .= " " . $element->getTitle() . " " . $element->getDescription() . " " . $element->getKeywords() . " " . $element->getPrettyUrl(); } } } } } else { if ($element instanceof Asset) { $this->data = $element->getFilename(); foreach ($element->getMetadata() as $md) { $this->data .= " " . $md["name"] . ":" . $md["data"]; } if ($element instanceof Asset\Document && \Pimcore\Document::isAvailable()) { if (\Pimcore\Document::isFileTypeSupported($element->getFilename())) { $contentText = $element->getText(); $contentText = str_replace(["\r\n", "\r", "\n", "\t", "\f"], " ", $contentText); $contentText = preg_replace("/[ ]+/", " ", $contentText); $this->data .= " " . $contentText; } } $this->published = true; } else { if ($element instanceof Object\AbstractObject) { if ($element instanceof Object\Concrete) { $getInheritedValues = Object\AbstractObject::doGetInheritedValues(); Object\AbstractObject::setGetInheritedValues(true); $this->published = $element->isPublished(); foreach ($element->getClass()->getFieldDefinitions() as $key => $value) { $this->data .= $value->getDataForSearchIndex($element) . " "; } Object\AbstractObject::setGetInheritedValues($getInheritedValues); } else { if ($element instanceof Object\Folder) { $this->data = $element->getKey(); $this->published = true; } } } else { \Logger::crit("Search\\Backend\\Data received an unknown element!"); } } } if ($element instanceof Element\ElementInterface) { $this->data = "ID: " . $element->getId() . " \nPath: " . $this->getFullPath() . " \n" . $this->cleanupData($this->data); } return $this; }
/** * @param $name * @param null $language * @return */ public function getLocalizedValue($name, $language = null, $ignoreFallbackLanguage = false) { $data = null; $language = $this->getLanguage($language); $fieldDefinition = $this->getObject()->getClass()->getFieldDefinition("localizedfields")->getFieldDefinition($name); if ($fieldDefinition instanceof Model\Object\ClassDefinition\Data\CalculatedValue) { $valueData = new Model\Object\Data\CalculatedValue($fieldDefinition->getName()); $valueData->setContextualData("localizedfield", "localizedfields", null, $language); $data = Service::getCalculatedFieldValue($this->getObject(), $valueData); return $data; } if ($this->languageExists($language)) { if (array_key_exists($name, $this->items[$language])) { $data = $this->items[$language][$name]; } } // check for inherited value $doGetInheritedValues = AbstractObject::doGetInheritedValues(); if ($fieldDefinition->isEmpty($data) && $doGetInheritedValues) { $object = $this->getObject(); $class = $object->getClass(); $allowInherit = $class->getAllowInherit(); if ($allowInherit) { if ($object->getParent() instanceof AbstractObject) { $parent = $object->getParent(); while ($parent && $parent->getType() == "folder") { $parent = $parent->getParent(); } if ($parent && ($parent->getType() == "object" || $parent->getType() == "variant")) { if ($parent->getClassId() == $object->getClassId()) { $method = "getLocalizedfields"; if (method_exists($parent, $method)) { $localizedFields = $parent->getLocalizedFields(); if ($localizedFields instanceof Localizedfield) { if ($localizedFields->object->getId() != $this->object->getId()) { $data = $localizedFields->getLocalizedValue($name, $language, true); } } } } } } } } // check for fallback value if ($fieldDefinition->isEmpty($data) && !$ignoreFallbackLanguage && self::doGetFallbackValues()) { foreach (Tool::getFallbackLanguagesFor($language) as $l) { if ($this->languageExists($l)) { if (array_key_exists($name, $this->items[$l])) { $data = $this->getLocalizedValue($name, $l); } } } } if ($fieldDefinition && method_exists($fieldDefinition, "preGetData")) { $data = $fieldDefinition->preGetData($this, array("data" => $data, "language" => $language, "name" => $name)); } return $data; }
/** * Save changes to database, it's an good idea to use save() instead * * @return void */ public function update() { parent::update(); // get fields which shouldn't be updated $fd = $this->model->getClass()->getFieldDefinitions(); $untouchable = array(); foreach ($fd as $key => $value) { if (method_exists($value, "getLazyLoading") && $value->getLazyLoading()) { if (!in_array($key, $this->model->getLazyLoadedFields())) { //this is a relation subject to lazy loading - it has not been loaded $untouchable[] = $key; } } } // empty relation table except the untouchable fields (eg. lazy loading fields) if (count($untouchable) > 0) { $untouchables = "'" . implode("','", $untouchable) . "'"; $this->db->delete("object_relations_" . $this->model->getClassId(), $this->db->quoteInto("src_id = ? AND fieldname not in (" . $untouchables . ") AND ownertype = 'object'", $this->model->getId())); } else { $this->db->delete("object_relations_" . $this->model->getClassId(), $this->db->quoteInto("src_id = ? AND ownertype = 'object'", $this->model->getId())); } $inheritedValues = Object\AbstractObject::doGetInheritedValues(); Object\AbstractObject::setGetInheritedValues(false); $data = array(); $data["oo_id"] = $this->model->getId(); foreach ($fd as $key => $value) { $getter = "get" . ucfirst($key); if (method_exists($value, "save")) { // for fieldtypes which have their own save algorithm eg. fieldcollections, objects, multihref, ... $value->save($this->model); } else { if ($value->getColumnType()) { // pimcore saves the values with getDataForResource if (is_array($value->getColumnType())) { $insertDataArray = $value->getDataForResource($this->model->{$getter}(), $this->model); if (is_array($insertDataArray)) { $data = array_merge($data, $insertDataArray); } } else { $insertData = $value->getDataForResource($this->model->{$getter}(), $this->model); $data[$key] = $insertData; } } } } $this->db->insertOrUpdate("object_store_" . $this->model->getClassId(), $data); // get data for query table // this is special because we have to call each getter to get the inherited values from a possible parent object Object\AbstractObject::setGetInheritedValues(true); $object = get_object_vars($this->model); $data = array(); $this->inheritanceHelper->resetFieldsToCheck(); $oldData = $this->db->fetchRow("SELECT * FROM object_query_" . $this->model->getClassId() . " WHERE oo_id = ?", $this->model->getId()); foreach ($object as $key => $value) { $fd = $this->model->getClass()->getFieldDefinition($key); if ($fd) { if ($fd->getQueryColumnType()) { //exclude untouchables if value is not an array - this means data has not been loaded if (!(in_array($key, $untouchable) and !is_array($this->model->{$key}))) { $method = "get" . $key; $insertData = $fd->getDataForQueryResource($this->model->{$method}(), $this->model); if (is_array($insertData)) { $data = array_merge($data, $insertData); } else { $data[$key] = $insertData; } //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } else { \Logger::debug("Excluding untouchable query value for object [ " . $this->model->getId() . " ] key [ {$key} ] because it has not been loaded"); } } } } $data["oo_id"] = $this->model->getId(); $this->db->insertOrUpdate("object_query_" . $this->model->getClassId(), $data); Object\AbstractObject::setGetInheritedValues($inheritedValues); }
/** * @param Concrete $object * @return void */ public function save($object) { // set the current object again, this is necessary because the related object in $this->object can change (eg. clone & copy & paste, etc.) $this->setObject($object); $getters = $this->getBrickGetters(); foreach ($getters as $getter) { $brick = $this->{$getter}(); if ($brick instanceof Objectbrick\Data\AbstractData) { if ($brick->getDoDelete()) { $brick->delete($object); $setter = "s" . substr($getter, 1); $this->{$setter}(null); //check if parent object has brick, and if so, create an empty brick to enable inheritance $parentBrick = null; $inheritanceModeBackup = AbstractObject::getGetInheritedValues(); AbstractObject::setGetInheritedValues(true); if (AbstractObject::doGetInheritedValues($object)) { $container = $object->getValueFromParent($this->fieldname); if (!empty($container)) { $parentBrick = $container->{$getter}(); } } AbstractObject::setGetInheritedValues($inheritanceModeBackup); if (!empty($parentBrick)) { $brickType = "\\Pimcore\\Model\\Object\\Objectbrick\\Data\\" . ucfirst($parentBrick->getType()); $brick = new $brickType($object); $brick->setFieldname($this->getFieldname()); $brick->save($object); $this->{$setter}($brick); } } else { $brick->setFieldname($this->getFieldname()); $brick->save($object); } } else { if ($brick == null) { $parentBrick = null; $inheritanceModeBackup = AbstractObject::getGetInheritedValues(); AbstractObject::setGetInheritedValues(true); if (AbstractObject::doGetInheritedValues($object)) { $container = $object->getValueFromParent($this->fieldname); if (!empty($container)) { $parentBrick = $container->{$getter}(); } } AbstractObject::setGetInheritedValues($inheritanceModeBackup); if (!empty($parentBrick)) { $brickType = "\\Pimcore\\Model\\Object\\Objectbrick\\Data\\" . ucfirst($parentBrick->getType()); $brick = new $brickType($object); $brick->setFieldname($this->getFieldname()); $brick->save($object); } } } } }
/** * @throws \Exception */ protected function update() { $fieldDefintions = $this->getClass()->getFieldDefinitions(); foreach ($fieldDefintions as $fd) { $getter = "get" . ucfirst($fd->getName()); $setter = "set" . ucfirst($fd->getName()); if (method_exists($this, $getter)) { //To make sure, inherited values are not set again $inheritedValues = AbstractObject::doGetInheritedValues(); AbstractObject::setGetInheritedValues(false); $value = $this->{$getter}(); if (is_array($value) and ($fd instanceof ClassDefinition\Data\Multihref or $fd instanceof ClassDefinition\Data\Objects)) { //don't save relations twice $this->{$setter}(array_unique($value)); } AbstractObject::setGetInheritedValues($inheritedValues); $value = $this->{$getter}(); $omitMandatoryCheck = $this->getOmitMandatoryCheck(); //check throws Exception try { $fd->checkValidity($value, $omitMandatoryCheck); } catch (\Exception $e) { if ($this->getClass()->getAllowInherit()) { //try again with parent data when inheritance in activated try { $getInheritedValues = AbstractObject::doGetInheritedValues(); AbstractObject::setGetInheritedValues(true); $value = $this->{$getter}(); $fd->checkValidity($value, $omitMandatoryCheck); AbstractObject::setGetInheritedValues($getInheritedValues); } catch (\Exception $e) { throw new \Exception($e->getMessage() . " fieldname=" . $fd->getName()); } } else { throw new \Exception($e->getMessage() . " fieldname=" . $fd->getName()); } } } } parent::update(); $this->getDao()->update(); // scheduled tasks are saved in $this->saveVersion(); $this->saveVersion(false, false); $this->saveChildData(); }
/** * @throws \Exception */ protected function update() { $fieldDefintions = $this->getClass()->getFieldDefinitions(); foreach ($fieldDefintions as $fd) { $getter = "get" . ucfirst($fd->getName()); $setter = "set" . ucfirst($fd->getName()); if (method_exists($this, $getter)) { //To make sure, inherited values are not set again $inheritedValues = AbstractObject::doGetInheritedValues(); AbstractObject::setGetInheritedValues(false); $value = $this->{$getter}(); if (is_array($value) and ($fd instanceof ClassDefinition\Data\Multihref or $fd instanceof ClassDefinition\Data\Objects)) { //don't save relations twice $this->{$setter}(array_unique($value)); } AbstractObject::setGetInheritedValues($inheritedValues); $value = $this->{$getter}(); $omitMandatoryCheck = $this->getOmitMandatoryCheck(); /*$timeSinceCreation = (time()-$this->getCreationDate()); if($timeSinceCreation <= 5){ // legacy hack: in previous version there was no check for mandatory fields, // and everybody uses the save method for new object creation - so now let's evict the mandatory check // if the object was created within the last 5 seconds $omitMandatoryCheck=true; \Logger::debug("executing mandatory fields check for object [ ".$this->getId()." ]"); } */ //check throws Exception try { $fd->checkValidity($value, $omitMandatoryCheck); } catch (\Exception $e) { if ($this->getClass()->getAllowInherit()) { //try again with parent data when inheritance in activated try { $getInheritedValues = AbstractObject::doGetInheritedValues(); AbstractObject::setGetInheritedValues(true); $value = $this->{$getter}(); $fd->checkValidity($value, $omitMandatoryCheck); AbstractObject::setGetInheritedValues($getInheritedValues); } catch (\Exception $e) { throw new \Exception($e->getMessage() . " fieldname=" . $fd->getName()); } } else { throw new \Exception($e->getMessage() . " fieldname=" . $fd->getName()); } } } } parent::update(); $this->getResource()->update(); // scheduled tasks are saved in $this->saveVersion(); $this->saveVersion(false, false); $this->saveChilds(); }
/** * Save changes to database, it's an good idea to use save() instead * * @return void */ public function update() { parent::update(); // get fields which shouldn't be updated $fieldDefinitions = $this->model->getClass()->getFieldDefinitions(); $untouchable = []; foreach ($fieldDefinitions as $key => $fd) { if (method_exists($fd, "getLazyLoading") && $fd->getLazyLoading()) { if (!in_array($key, $this->model->getLazyLoadedFields())) { //this is a relation subject to lazy loading - it has not been loaded $untouchable[] = $key; } } } // empty relation table except the untouchable fields (eg. lazy loading fields) if (count($untouchable) > 0) { $untouchables = "'" . implode("','", $untouchable) . "'"; $this->db->delete("object_relations_" . $this->model->getClassId(), $this->db->quoteInto("src_id = ? AND fieldname not in (" . $untouchables . ") AND ownertype = 'object'", $this->model->getId())); } else { $this->db->delete("object_relations_" . $this->model->getClassId(), $this->db->quoteInto("src_id = ? AND ownertype = 'object'", $this->model->getId())); } $inheritedValues = Object\AbstractObject::doGetInheritedValues(); Object\AbstractObject::setGetInheritedValues(false); $data = []; $data["oo_id"] = $this->model->getId(); foreach ($fieldDefinitions as $key => $fd) { $getter = "get" . ucfirst($key); if (method_exists($fd, "save")) { // for fieldtypes which have their own save algorithm eg. fieldcollections, objects, multihref, ... $fd->save($this->model); } elseif ($fd->getColumnType()) { // pimcore saves the values with getDataForResource if (is_array($fd->getColumnType())) { $insertDataArray = $fd->getDataForResource($this->model->{$getter}(), $this->model); if (is_array($insertDataArray)) { $data = array_merge($data, $insertDataArray); } } else { $insertData = $fd->getDataForResource($this->model->{$getter}(), $this->model); $data[$key] = $insertData; } } } $this->db->insertOrUpdate("object_store_" . $this->model->getClassId(), $data); // get data for query table $data = []; $this->inheritanceHelper->resetFieldsToCheck(); $oldData = $this->db->fetchRow("SELECT * FROM object_query_" . $this->model->getClassId() . " WHERE oo_id = ?", $this->model->getId()); $inheritanceEnabled = $this->model->getClass()->getAllowInherit(); $parentData = null; if ($inheritanceEnabled) { // get the next suitable parent for inheritance $parentForInheritance = $this->model->getNextParentForInheritance(); if ($parentForInheritance) { // we don't use the getter (built in functionality to get inherited values) because we need to avoid race conditions // we cannot Object\AbstractObject::setGetInheritedValues(true); and then $this->model->$method(); // so we select the data from the parent object using FOR UPDATE, which causes a lock on this row // so the data of the parent cannot be changed while this transaction is on progress $parentData = $this->db->fetchRow("SELECT * FROM object_query_" . $this->model->getClassId() . " WHERE oo_id = ? FOR UPDATE", $parentForInheritance->getId()); } } foreach ($fieldDefinitions as $key => $fd) { if ($fd->getQueryColumnType()) { //exclude untouchables if value is not an array - this means data has not been loaded if (!(in_array($key, $untouchable) and !is_array($this->model->{$key}))) { $method = "get" . $key; $fieldValue = $this->model->{$method}(); $insertData = $fd->getDataForQueryResource($fieldValue, $this->model); $isEmpty = $fd->isEmpty($fieldValue); if (is_array($insertData)) { $columnNames = array_keys($insertData); $data = array_merge($data, $insertData); } else { $columnNames = [$key]; $data[$key] = $insertData; } // if the current value is empty and we have data from the parent, we just use it if ($isEmpty && $parentData) { foreach ($columnNames as $columnName) { if (array_key_exists($columnName, $parentData)) { $data[$columnName] = $parentData[$columnName]; if (is_array($insertData)) { $insertData[$columnName] = $parentData[$columnName]; } else { $insertData = $parentData[$columnName]; } } } } if ($inheritanceEnabled && $fd->getFieldType() != "calculatedValue") { //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; break; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($isEmpty && $oldData[$insertDataKey] == $parentData[$insertDataKey]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($isEmpty && $oldData[$key] == $parentData[$key]) { // do nothing, ... value is still empty and parent data is equal to current data in query table } elseif ($oldData[$key] != $insertData) { // data changed, do check and update $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } } else { Logger::debug("Excluding untouchable query value for object [ " . $this->model->getId() . " ] key [ {$key} ] because it has not been loaded"); } } } $data["oo_id"] = $this->model->getId(); $this->db->insertOrUpdate("object_query_" . $this->model->getClassId(), $data); Object\AbstractObject::setGetInheritedValues($inheritedValues); }
/** * @param $keyId * @param $groupId * @param string $language * @param bool|false $ignoreFallbackLanguage * @return null */ public function getLocalizedKeyValue($groupId, $keyId, $language = "default", $ignoreFallbackLanguage = false, $ignoreDefaultLanguage = false) { $oid = $this->object->getId(); \Logger::debug($oid); $keyConfig = Model\Object\Classificationstore\DefinitionCache::get($keyId); $fieldDefinition = Model\Object\Classificationstore\Service::getFieldDefinitionFromKeyConfig($keyConfig); $language = $this->getLanguage($language); $data = null; if (array_key_exists($groupId, $this->items) && array_key_exists($keyId, $this->items[$groupId]) && array_key_exists($language, $this->items[$groupId][$keyId])) { $data = $this->items[$groupId][$keyId][$language]; } // check for fallback value if ($fieldDefinition->isEmpty($data) && !$ignoreFallbackLanguage && self::doGetFallbackValues()) { $data = $this->getFallbackValue($groupId, $keyId, $language, $fieldDefinition); } if ($fieldDefinition->isEmpty($data) && !$ignoreDefaultLanguage && $language != "default") { $data = $this->items[$groupId][$keyId]["default"]; } // check for inherited value $doGetInheritedValues = AbstractObject::doGetInheritedValues(); if ($fieldDefinition->isEmpty($data) && $doGetInheritedValues) { $object = $this->getObject(); $class = $object->getClass(); $allowInherit = $class->getAllowInherit(); if ($allowInherit) { if ($object->getParent() instanceof AbstractObject) { $parent = $object->getParent(); while ($parent && $parent->getType() == "folder") { $parent = $parent->getParent(); } if ($parent && ($parent->getType() == "object" || $parent->getType() == "variant")) { if ($parent->getClassId() == $object->getClassId()) { $method = "getLocalizedfields"; if (method_exists($parent, $method)) { $getter = "get" . ucfirst($this->fieldname); $classificationStore = $parent->{$getter}(); if ($classificationStore instanceof Classificationstore) { if ($classificationStore->object->getId() != $this->object->getId()) { $data = $classificationStore->getLocalizedKeyValue($groupId, $keyId, $language, false); \Logger::debug($data); } } } } } } } } if ($fieldDefinition && method_exists($fieldDefinition, "preGetData")) { $data = $fieldDefinition->preGetData($this, array("data" => $data, "language" => $language, "name" => $groupId . "-" . $keyId)); } return $data; }
/** * prepare data for index creation and store is in store table * * @param OnlineShop_Framework_ProductInterfaces_IIndexable $object */ public function prepareDataForIndex(OnlineShop_Framework_ProductInterfaces_IIndexable $object) { $subObjectIds = $this->tenantConfig->createSubIdsForObject($object); foreach ($subObjectIds as $subObjectId => $object) { /** * @var OnlineShop_Framework_ProductInterfaces_IIndexable $object */ if ($object->getOSDoIndexProduct() && $this->tenantConfig->inIndex($object)) { $a = Pimcore::inAdmin(); $b = \Pimcore\Model\Object\AbstractObject::doGetInheritedValues(); Pimcore::unsetAdminMode(); \Pimcore\Model\Object\AbstractObject::setGetInheritedValues(true); $hidePublishedMemory = \Pimcore\Model\Object\AbstractObject::doHideUnpublished(); \Pimcore\Model\Object\AbstractObject::setHideUnpublished(false); $categories = $object->getCategories(); $categoryIds = array(); $parentCategoryIds = array(); if ($categories) { foreach ($categories as $c) { $parent = $c; if ($parent != null) { if ($parent->getOSProductsInParentCategoryVisible()) { while ($parent && $parent instanceof OnlineShop_Framework_AbstractCategory) { $parentCategoryIds[$parent->getId()] = $parent->getId(); $parent = $parent->getParent(); } } else { $parentCategoryIds[$parent->getId()] = $parent->getId(); } $categoryIds[$c->getId()] = $c->getId(); } } } ksort($categoryIds); $virtualProductId = $subObjectId; $virtualProductActive = $object->isActive(); if ($object->getOSIndexType() == "variant") { $virtualProductId = $this->tenantConfig->createVirtualParentIdForSubId($object, $subObjectId); } $virtualProduct = \Pimcore\Model\Object\AbstractObject::getById($virtualProductId); if ($virtualProduct && method_exists($virtualProduct, "isActive")) { $virtualProductActive = $virtualProduct->isActive(); } $data = array("o_id" => $subObjectId, "o_classId" => $object->getClassId(), "o_virtualProductId" => $virtualProductId, "o_virtualProductActive" => $virtualProductActive, "o_parentId" => $object->getOSParentId(), "o_type" => $object->getOSIndexType(), "categoryIds" => ',' . implode(",", $categoryIds) . ",", "parentCategoryIds" => ',' . implode(",", $parentCategoryIds) . ",", "priceSystemName" => $object->getPriceSystemName(), "active" => $object->isActive(), "inProductList" => $object->isActive(true)); $relationData = array(); $columnConfig = $this->columnConfig->column; if (!empty($columnConfig->name)) { $columnConfig = array($columnConfig); } else { if (empty($columnConfig)) { $columnConfig = array(); } } foreach ($columnConfig as $column) { try { //$data[$column->name] = null; $value = null; if (!empty($column->getter)) { $getter = $column->getter; $value = $getter::get($object, $column->config, $subObjectId, $this->tenantConfig); } else { if (!empty($column->fieldname)) { $getter = "get" . ucfirst($column->fieldname); } else { $getter = "get" . ucfirst($column->name); } if (method_exists($object, $getter)) { $value = $object->{$getter}($column->locale); } } if (!empty($column->interpreter)) { $interpreter = $column->interpreter; $value = $interpreter::interpret($value, $column->config); $interpreterObject = new $interpreter(); if ($interpreterObject instanceof OnlineShop_Framework_IndexService_RelationInterpreter) { foreach ($value as $v) { $relData = array(); $relData['src'] = $subObjectId; $relData['src_virtualProductId'] = $virtualProductId; $relData['dest'] = $v['dest']; $relData['fieldname'] = $column->name; $relData['type'] = $v['type']; $relationData[] = $relData; } } else { $data[$column->name] = $value; } } else { $data[$column->name] = $value; } if (is_array($data[$column->name])) { $data[$column->name] = OnlineShop_Framework_IndexService_Tenant_IWorker::MULTISELECT_DELIMITER . implode($data[$column->name], OnlineShop_Framework_IndexService_Tenant_IWorker::MULTISELECT_DELIMITER) . OnlineShop_Framework_IndexService_Tenant_IWorker::MULTISELECT_DELIMITER; } } catch (Exception $e) { Logger::err("Exception in IndexService: " . $e->getMessage(), $e); } } if ($a) { Pimcore::setAdminMode(); } \Pimcore\Model\Object\AbstractObject::setGetInheritedValues($b); \Pimcore\Model\Object\AbstractObject::setHideUnpublished($hidePublishedMemory); $subTenantData = $this->tenantConfig->prepareSubTenantEntries($object, $subObjectId); $jsonData = json_encode(array("data" => $data, "relations" => $relationData ? $relationData : [], "subtenants" => $subTenantData ? $subTenantData : [])); $crc = crc32($jsonData); $insertData = array("id" => $subObjectId, "tenant" => $this->name, "data" => $jsonData, "crc_current" => $crc, "preparation_worker_timestamp" => 0, "preparation_worker_id" => $this->db->quote(null), "in_preparation_queue" => 0); $currentEntry = $this->db->fetchRow("SELECT crc_current, in_preparation_queue FROM " . $this->getStoreTableName() . " WHERE id = ? AND tenant = ?", array($subObjectId, $this->name)); if (!$currentEntry) { $this->db->insert($this->getStoreTableName(), $insertData); } else { if ($currentEntry['crc_current'] != $crc) { $this->db->update($this->getStoreTableName(), $insertData, "id = " . $this->db->quote((string) $subObjectId) . " AND tenant = " . $this->db->quote($this->name)); } else { if ($currentEntry['in_preparation_queue']) { $this->db->query("UPDATE " . $this->getStoreTableName() . " SET in_preparation_queue = 0, preparation_worker_timestamp = 0, preparation_worker_id = null WHERE id = ? AND tenant = ?", array($subObjectId, $this->name)); } } } } else { Logger::info("Don't adding product " . $subObjectId . " to index " . $this->name . "."); $this->doDeleteFromIndex($subObjectId); } } //cleans up all old zombie data $this->doCleanupOldZombieData($object, $subObjectIds); }
/** * */ public function save() { $this->delete(false); $object = $this->model->getObject(); $validLanguages = Tool::getValidLanguages(); $fieldDefinitions = $this->model->getClass()->getFielddefinition("localizedfields")->getFielddefinitions(); foreach ($validLanguages as $language) { $inheritedValues = Object\AbstractObject::doGetInheritedValues(); Object\AbstractObject::setGetInheritedValues(false); $insertData = array("ooo_id" => $this->model->getObject()->getId(), "language" => $language); foreach ($fieldDefinitions as $fd) { if (method_exists($fd, "save")) { // for fieldtypes which have their own save algorithm eg. objects, multihref, ... $fd->save($this->model, array("language" => $language)); } else { if (is_array($fd->getColumnType())) { $insertDataArray = $fd->getDataForResource($this->model->getLocalizedValue($fd->getName(), $language, true), $object); $insertData = array_merge($insertData, $insertDataArray); } else { $insertData[$fd->getName()] = $fd->getDataForResource($this->model->getLocalizedValue($fd->getName(), $language, true), $object); } } } $storeTable = $this->getTableName(); $queryTable = $this->getQueryTableName() . "_" . $language; $this->db->insertOrUpdate($this->getTableName(), $insertData); Object\AbstractObject::setGetInheritedValues(true); $data = array(); $data["ooo_id"] = $this->model->getObject()->getId(); $data["language"] = $language; $this->inheritanceHelper = new Object\Concrete\Resource\InheritanceHelper($object->getClassId(), "ooo_id", $storeTable, $queryTable); $this->inheritanceHelper->resetFieldsToCheck(); $sql = "SELECT * FROM " . $queryTable . " WHERE ooo_id = " . $object->getId() . " AND language = '" . $language . "'"; try { $oldData = $this->db->fetchRow($sql); } catch (\Exception $e) { // if the table doesn't exist -> create it! if (strpos($e->getMessage(), "exist")) { $this->model->commit(); $this->createUpdateTable(); $this->model->beginTransaction(); $oldData = $this->db->fetchRow($sql); } } // get fields which shouldn't be updated $untouchable = array(); // @TODO: currently we do not support lazyloading in localized fields foreach ($fieldDefinitions as $fd) { $key = $fd->getName(); if ($fd) { if ($fd->getQueryColumnType()) { // exclude untouchables if value is not an array - this means data has not been loaded if (!(in_array($key, $untouchable) and !is_array($this->model->{$key}))) { $localizedValue = $this->model->getLocalizedValue($key, $language); $insertData = $fd->getDataForQueryResource($localizedValue, $object); if (is_array($insertData)) { $data = array_merge($data, $insertData); } else { $data[$key] = $insertData; } //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } else { \Logger::debug("Excluding untouchable query value for object [ " . $this->model->getId() . " ] key [ {$key} ] because it has not been loaded"); } } } } $queryTable = $this->getQueryTableName() . "_" . $language; $this->db->insertOrUpdate($queryTable, $data); $this->inheritanceHelper->doUpdate($object->getId(), true); $this->inheritanceHelper->resetFieldsToCheck(); Object\AbstractObject::setGetInheritedValues($inheritedValues); } // foreach language }
/** * @param Object\Concrete $object * @return void */ public function save(Object\Concrete $object) { // HACK: set the pimcore admin mode to false to get the inherited values from parent if this source one is empty $inheritedValues = Object\AbstractObject::doGetInheritedValues(); $storetable = $this->model->getDefinition()->getTableName($object->getClass(), false); $querytable = $this->model->getDefinition()->getTableName($object->getClass(), true); $this->inheritanceHelper = new Object\Concrete\Resource\InheritanceHelper($object->getClassId(), "o_id", $storetable, $querytable); Object\AbstractObject::setGetInheritedValues(false); $fd = $this->model->getDefinition()->getFieldDefinitions(); $data = array(); $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); // remove all relations try { $this->db->delete("object_relations_" . $object->getClassId(), "src_id = " . $object->getId() . " AND ownertype = 'objectbrick' AND ownername = '" . $this->model->getFieldname() . "' AND (position = '" . $this->model->getType() . "' OR position IS NULL OR position = '')"); } catch (\Exception $e) { \Logger::warning("Error during removing old relations: " . $e); } foreach ($fd as $key => $value) { $getter = "get" . ucfirst($value->getName()); if (method_exists($value, "save")) { // for fieldtypes which have their own save algorithm eg. objects, multihref, ... $value->save($this->model); } else { if ($value->getColumnType()) { if (is_array($value->getColumnType())) { $insertDataArray = $value->getDataForResource($this->model->{$getter}(), $object); $data = array_merge($data, $insertDataArray); } else { $insertData = $value->getDataForResource($this->model->{$getter}(), $object); $data[$key] = $insertData; } } } } $this->db->insertOrUpdate($storetable, $data); // get data for query table // $tableName = $this->model->getDefinition()->getTableName($object->getClass(), true); // this is special because we have to call each getter to get the inherited values from a possible parent object Object\AbstractObject::setGetInheritedValues(true); $objectVars = get_object_vars($this->model); $data = array(); $data["o_id"] = $object->getId(); $data["fieldname"] = $this->model->getFieldname(); $this->inheritanceHelper->resetFieldsToCheck(); $oldData = $this->db->fetchRow("SELECT * FROM " . $querytable . " WHERE o_id = ?", $object->getId()); foreach ($objectVars as $key => $value) { $fd = $this->model->getDefinition()->getFieldDefinition($key); if ($fd) { if ($fd->getQueryColumnType()) { //exclude untouchables if value is not an array - this means data has not been loaded $method = "get" . $key; $insertData = $fd->getDataForQueryResource($this->model->{$method}(), $object); if (is_array($insertData)) { $data = array_merge($data, $insertData); } else { $data[$key] = $insertData; } //get changed fields for inheritance if ($fd->isRelationType()) { if (is_array($insertData)) { $doInsert = false; foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $doInsert = true; } } if ($doInsert) { $this->inheritanceHelper->addRelationToCheck($key, $fd, array_keys($insertData)); } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addRelationToCheck($key, $fd); } } } else { if (is_array($insertData)) { foreach ($insertData as $insertDataKey => $insertDataValue) { if ($oldData[$insertDataKey] != $insertDataValue) { $this->inheritanceHelper->addFieldToCheck($insertDataKey, $fd); } } } else { if ($oldData[$key] != $insertData) { $this->inheritanceHelper->addFieldToCheck($key, $fd); } } } } } } $this->db->insertOrUpdate($querytable, $data); $this->inheritanceHelper->doUpdate($object->getId(), true); $this->inheritanceHelper->resetFieldsToCheck(); // HACK: see a few lines above! Object\AbstractObject::setGetInheritedValues($inheritedValues); }
public function updateIndex(OnlineShop_Framework_ProductInterfaces_IIndexable $object) { if (!$this->tenantConfig->isActive($object)) { Logger::info("Tenant {$this->name} is not active."); return; } $subObjectIds = $this->tenantConfig->createSubIdsForObject($object); foreach ($subObjectIds as $subObjectId => $object) { if ($object->getOSDoIndexProduct() && $this->tenantConfig->inIndex($object)) { $a = Pimcore::inAdmin(); $b = \Pimcore\Model\Object\AbstractObject::doGetInheritedValues(); Pimcore::unsetAdminMode(); \Pimcore\Model\Object\AbstractObject::setGetInheritedValues(true); $hidePublishedMemory = \Pimcore\Model\Object\AbstractObject::doHideUnpublished(); \Pimcore\Model\Object\AbstractObject::setHideUnpublished(false); $categories = $object->getCategories(); $themes = $object->getTheme(); $categoryIds = array(); $parentCategoryIds = array(); if ($categories) { foreach ($categories as $c) { $parent = $c; if ($parent != null) { if ($parent->getOSProductsInParentCategoryVisible()) { while ($parent && $parent instanceof OnlineShop_Framework_AbstractCategory) { $parentCategoryIds[$parent->getId()] = $parent->getId(); $parent = $parent->getParent(); } } else { $parentCategoryIds[$parent->getId()] = $parent->getId(); } $categoryIds[$c->getId()] = $c->getId(); } } } $themeIds = array(); if ($themes) { foreach ($themes as $theme) { $parent = $theme; if ($parent != null) { $themeIds[$theme->getId()] = $theme->getId(); } } } ksort($categoryIds); $virtualProductId = $subObjectId; $virtualProductActive = $object->isActive(); if ($object->getOSIndexType() == "variant") { $virtualProductId = $this->tenantConfig->createVirtualParentIdForSubId($object, $subObjectId); } $virtualProduct = \Pimcore\Model\Object\AbstractObject::getById($virtualProductId); if ($virtualProduct && method_exists($virtualProduct, "isActive")) { $virtualProductActive = $virtualProduct->isActive(); } $data = array("o_id" => $subObjectId, "o_classId" => $object->getClassId(), "o_virtualProductId" => $virtualProductId, "o_virtualProductActive" => $virtualProductActive, "o_parentId" => $object->getOSParentId(), "o_type" => $object->getOSIndexType(), "categoryIds" => ',' . implode(",", $categoryIds) . ",", "parentCategoryIds" => ',' . implode(",", $parentCategoryIds) . ",", "priceSystemName" => $object->getPriceSystemName(), "active" => $object->isActive(), "inProductList" => $object->isActive(true), "theme" => ',' . implode(",", $themeIds) . ","); $relationData = array(); $columnConfig = $this->columnConfig->column; if (!empty($columnConfig->name)) { $columnConfig = array($columnConfig); } else { if (empty($columnConfig)) { $columnConfig = array(); } } foreach ($columnConfig as $column) { try { $value = null; if (!empty($column->getter)) { $getter = $column->getter; $value = $getter::get($object, $column->config, $subObjectId, $this->tenantConfig); } else { if (!empty($column->fieldname)) { $getter = "get" . ucfirst($column->fieldname); } else { $getter = "get" . ucfirst($column->name); } if (method_exists($object, $getter)) { $value = $object->{$getter}($column->locale); } } if (!empty($column->interpreter)) { $interpreter = $column->interpreter; $value = $interpreter::interpret($value, $column->config); $interpreterObject = new $interpreter(); if ($interpreterObject instanceof OnlineShop_Framework_IndexService_RelationInterpreter) { foreach ($value as $v) { $relData = array(); $relData['src'] = $subObjectId; $relData['src_virtualProductId'] = $virtualProductId; $relData['dest'] = $v['dest']; $relData['fieldname'] = $column->name; $relData['type'] = $v['type']; $relationData[] = $relData; } } else { $data[$column->name] = $value; } } else { $data[$column->name] = $value; } if (is_array($data[$column->name])) { $data[$column->name] = OnlineShop_Framework_IndexService_Tenant_IWorker::MULTISELECT_DELIMITER . implode($data[$column->name], OnlineShop_Framework_IndexService_Tenant_IWorker::MULTISELECT_DELIMITER) . OnlineShop_Framework_IndexService_Tenant_IWorker::MULTISELECT_DELIMITER; } } catch (Exception $e) { Logger::err("Exception in IndexService: " . $e->getMessage(), $e); } } if ($a) { Pimcore::setAdminMode(); } \Pimcore\Model\Object\AbstractObject::setGetInheritedValues($b); \Pimcore\Model\Object\AbstractObject::setHideUnpublished($hidePublishedMemory); try { $this->doInsertData($data); } catch (Exception $e) { Logger::warn("Error during updating index table: " . $e); } try { $this->db->delete($this->tenantConfig->getRelationTablename(), "src = " . $this->db->quote($subObjectId)); foreach ($relationData as $rd) { $this->db->insert($this->tenantConfig->getRelationTablename(), $rd); } } catch (Exception $e) { Logger::warn("Error during updating index relation table: " . $e->getMessage(), $e); } } else { Logger::info("Don't adding product " . $subObjectId . " to index."); try { $this->db->delete($this->tenantConfig->getTablename(), "o_id = " . $this->db->quote($subObjectId)); } catch (Exception $e) { Logger::warn("Error during updating index table: " . $e->getMessage(), $e); } try { $this->db->delete($this->tenantConfig->getRelationTablename(), "src = " . $this->db->quote($subObjectId)); } catch (Exception $e) { Logger::warn("Error during updating index relation table: " . $e->getMessage(), $e); } try { if ($this->tenantConfig->getTenantRelationTablename()) { $this->db->delete($this->tenantConfig->getTenantRelationTablename(), "o_id = " . $this->db->quote($subObjectId)); } } catch (Exception $e) { Logger::warn("Error during updating index tenant relation table: " . $e->getMessage(), $e); } } $this->tenantConfig->updateSubTenantEntries($object, $subObjectId); } //cleans up all old zombie data $this->doCleanupOldZombieData($object, $subObjectIds); }