public static setGetInheritedValues ( $getInheritedValues ) : void | ||
$getInheritedValues | ||
return | void |
/** * 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); }
/** * @throws \Zend_Exception */ public function init() { parent::init(); // set language if (\Zend_Registry::isRegistered("Zend_Locale")) { $locale = (string) \Zend_Registry::get("Zend_Locale"); $this->setLanguage($locale); } else { if ($this->getParam("language")) { $this->setLanguage($this->getParam("language")); } else { $config = Config::getSystemConfig(); $this->setLanguage($config->general->language); // try to set browser-language (validation if installed is in $this->setLanguage() ) $this->setLanguage(new \Zend_Locale()); } } if (self::$adminInitialized) { // this will be executed on every call to this init() method try { $this->setUser(\Zend_Registry::get("pimcore_admin_user")); } catch (\Exception $e) { \Logger::emerg("adminInitialized was set to true although there was no user set in the registry -> to be save the process was killed"); exit; } } else { // the following code is only called once, even when there are some subcalls (eg. with $this->action, ... ) \Pimcore::getEventManager()->trigger("admin.controller.preInit", $this); $this->disableBrowserCache(); // general definitions Model\Document::setHideUnpublished(false); Model\Object\AbstractObject::setHideUnpublished(false); Model\Object\AbstractObject::setGetInheritedValues(false); Model\Object\Localizedfield::setGetFallbackValues(false); \Pimcore::setAdminMode(); // init translations self::initTranslations($this); // init zend action helpers, we need to leave the prefixed class name here as the plugin loader isn't able to handle namespaces \Zend_Controller_Action_HelperBroker::addPrefix('Pimcore_Controller_Action_Helper'); // this is to make it possible to use the session id as a part of the route (ZF default route) used for external editors, etc. if ($this->getParam("pimcore_admin_sid")) { $_REQUEST["pimcore_admin_sid"] = $this->getParam("pimcore_admin_sid"); } // authenticate user, first try to authenticate with session information $user = Authentication::authenticateSession(); if ($user instanceof Model\User) { $this->setUser($user); if ($this->getUser()->getLanguage()) { $this->setLanguage($this->getUser()->getLanguage()); } } else { // try to authenticate with http basic auth, but this is only allowed for WebDAV if ($this->getParam("module") == "admin" && $this->getParam("controller") == "asset" && $this->getParam("action") == "webdav") { $user = Authentication::authenticateHttpBasic(); if ($user instanceof Model\User) { $this->setUser($user); \Zend_Registry::set("pimcore_admin_user", $this->getUser()); self::$adminInitialized = true; return; } } } // redirect to the login-page if the user isn't authenticated if (!$this->getUser() instanceof Model\User && !($this->getParam("module") == "admin" && $this->getParam("controller") == "login")) { // put a detailed message into the debug.log \Logger::error("Prevented access to " . $_SERVER["REQUEST_URI"] . " because there is no user in the session!", ["server" => $_SERVER, "get" => $_GET, "post" => $_POST, "session" => $_SESSION, "cookie" => $_COOKIE]); // send a auth header for the client (is covered by the ajax object in javascript) $this->getResponse()->setHeader("X-Pimcore-Auth", "required"); // redirect to login page $this->redirect("/admin/login"); // exit the execution -> just to be sure exit; } // we're now authenticated so we can remove the default error handler so that we get just the normal PHP errors if ($this->getParam("controller") != "login") { $front = \Zend_Controller_Front::getInstance(); $front->unregisterPlugin("Pimcore\\Controller\\Plugin\\ErrorHandler"); $front->throwExceptions(true); @ini_set("display_errors", "On"); @ini_set("display_startup_errors", "On"); } \Zend_Registry::set("pimcore_admin_user", $this->getUser()); self::$adminInitialized = true; // usage statistics $this->logUsageStatistics(); \Pimcore::getEventManager()->trigger("admin.controller.postInit", $this); } }
/** * @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(); }
/** * @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); } } } } }
protected function getCsvData($list, $fields, $addTitles = true) { $requestedLanguage = $this->extractLanguage(); $mappedFieldnames = []; $objects = []; Logger::debug("objects in list:" . count($list->getObjects())); //add inherited values to objects Object\AbstractObject::setGetInheritedValues(true); foreach ($list->getObjects() as $object) { if ($fields) { $objectData = []; foreach ($fields as $field) { $fieldData = $this->getCsvFieldData($field, $object, $requestedLanguage); if (!$mappedFieldnames[$field]) { $mappedFieldnames[$field] = $this->mapFieldname($field); } $objectData[$mappedFieldnames[$field]] = $fieldData; } $objects[] = $objectData; } else { /** * @extjs - TODO remove this, when old ext support is removed */ if ($object instanceof Object\Concrete) { $o = $this->csvObjectData($object); $objects[] = $o; } } } //create csv $csv = ""; if (!empty($objects)) { if ($addTitles) { $columns = array_keys($objects[0]); foreach ($columns as $key => $value) { $columns[$key] = '"' . $value . '"'; } $csv = implode(";", $columns) . "\r\n"; } foreach ($objects as $o) { foreach ($o as $key => $value) { //clean value of evil stuff such as " and linebreaks if (is_string($value)) { $value = strip_tags($value); $value = str_replace('"', '', $value); $value = str_replace("\r", "", $value); $value = str_replace("\n", "", $value); $o[$key] = '"' . $value . '"'; } } $csv .= implode(";", $o) . "\r\n"; } } return $csv; }
/** * Gets all Differences in the variants * * @param CoreShopProduct $product * @return array */ public static function getDimensions(CoreShopProduct $product) { $variants = $product->getChilds(array(AbstractObject::OBJECT_TYPE_VARIANT)); $fieldDefinition = $product->getClass()->getFieldDefinition("dimensions"); $variantsAndMaster = array_merge(array($product), $variants); $currentInheritedValue = AbstractObject::getGetInheritedValues(); AbstractObject::setGetInheritedValues(false); $overwrittenKeyValues = array(); $overwrittenKeys = array(); if (count($variants) > 0) { foreach ($variants as $variant) { $fieldData = $variant->getDimensions(); $value = $fieldDefinition->getDataForEditmode($fieldData, $variant); //Search for not inherited fields foreach ($value as $singleBrickData) { if (!$singleBrickData) { continue; } if (!array_key_exists($singleBrickData['type'], $overwrittenKeys)) { $overwrittenKeys[$singleBrickData['type']] = array(); } foreach ($singleBrickData['metaData'] as $key => $meta) { if (!$meta['inherited']) { if (!in_array($key, $overwrittenKeys[$singleBrickData['type']])) { $overwrittenKeys[$singleBrickData['type']][] = $key; } } } } } //We now have the keys and reloop the variants to get all the values foreach ($variantsAndMaster as $variant) { $fieldData = $variant->getDimensions(); $value = $fieldDefinition->getDataForEditmode($fieldData, $variant); foreach ($value as $singleBrickData) { if (!$singleBrickData) { continue; } if (array_key_exists($singleBrickData['type'], $overwrittenKeys)) { if (!is_array($overwrittenKeyValues[$singleBrickData['type']])) { $overwrittenKeyValues[$singleBrickData['type']] = array(); } foreach ($overwrittenKeys[$singleBrickData['type']] as $key) { $found = false; foreach ($overwrittenKeyValues[$singleBrickData['type']][$key] as $existingValue) { if ($existingValue['value'] == $singleBrickData['data'][$key]) { $found = true; break; } } if (!$found) { $overwrittenKeyValues[$singleBrickData['type']][$key][] = array("value" => $singleBrickData['data'][$key], "object" => $variant->getId()); } } } } } } AbstractObject::setGetInheritedValues($currentInheritedValue); return $overwrittenKeyValues; }
/** * @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(); }
/** * @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); }
/** * 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); }
/** * 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); }
/** * */ 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); }
/** * @throws \Zend_Controller_Router_Exception */ public function init() { // this is only executed once per request (first request) if (self::$isInitial) { \Pimcore::getEventManager()->trigger("frontend.controller.preInit", $this); } parent::init(); // log exceptions if handled by error_handler $this->checkForErrors(); // general definitions if (self::$isInitial) { \Pimcore::unsetAdminMode(); Document::setHideUnpublished(true); Object\AbstractObject::setHideUnpublished(true); Object\AbstractObject::setGetInheritedValues(true); Object\Localizedfield::setGetFallbackValues(true); } // assign variables $this->view->controller = $this; // init website config $config = Config::getWebsiteConfig(); $this->config = $config; $this->view->config = $config; $document = $this->getParam("document"); if (!$document instanceof Document) { \Zend_Registry::set("pimcore_editmode", false); $this->editmode = false; $this->view->editmode = false; self::$isInitial = false; // check for a locale first, and set it if available if ($this->getParam("pimcore_parentDocument")) { // this is a special exception for renderlets in editmode (ajax request), because they depend on the locale of the parent document // otherwise there'll be notices like: Notice: 'No translation for the language 'XX' available.' if ($parentDocument = Document::getById($this->getParam("pimcore_parentDocument"))) { if ($parentDocument->getProperty("language")) { $this->setLocaleFromDocument($parentDocument->getProperty("language")); } } } // no document available, continue, ... return; } else { $this->setDocument($document); // register global locale if the document has the system property "language" if ($this->getDocument()->getProperty("language")) { $this->setLocaleFromDocument($this->getDocument()->getProperty("language")); } if (self::$isInitial) { // append meta-data to the headMeta() view helper, if it is a document-request if (!Model\Staticroute::getCurrentRoute() && $this->getDocument() instanceof Document\Page) { if (is_array($this->getDocument()->getMetaData())) { foreach ($this->getDocument()->getMetaData() as $meta) { // only name if (!empty($meta["idName"]) && !empty($meta["idValue"]) && !empty($meta["contentValue"])) { $method = "append" . ucfirst($meta["idName"]); $this->view->headMeta()->{$method}($meta["idValue"], $meta["contentValue"]); } } } } } } // this is only executed once per request (first request) if (self::$isInitial) { // contains the logged in user if necessary $user = null; // default is to set the editmode to false, is enabled later if necessary \Zend_Registry::set("pimcore_editmode", false); if (Tool::isFrontentRequestByAdmin()) { $this->disableBrowserCache(); // start admin session & get logged in user $user = Authentication::authenticateSession(); } if (\Pimcore::inDebugMode()) { $this->disableBrowserCache(); } if (!$this->document->isPublished()) { if (Tool::isFrontentRequestByAdmin()) { if (!$user) { throw new \Zend_Controller_Router_Exception("access denied for " . $this->document->getFullPath()); } } else { throw new \Zend_Controller_Router_Exception("access denied for " . $this->document->getFullPath()); } } // logged in users only if ($user) { // set the user to registry so that it is available via \Pimcore\Tool\Admin::getCurrentUser(); \Zend_Registry::set("pimcore_admin_user", $user); // document editmode if ($this->getParam("pimcore_editmode")) { \Zend_Registry::set("pimcore_editmode", true); // check if there is the document in the session $docKey = "document_" . $this->getDocument()->getId(); $docSession = Session::getReadOnly("pimcore_documents"); if ($docSession->{$docKey}) { // if there is a document in the session use it $this->setDocument($docSession->{$docKey}); } else { // set the latest available version for editmode if there is no doc in the session $latestVersion = $this->getDocument()->getLatestVersion(); if ($latestVersion) { $latestDoc = $latestVersion->loadData(); if ($latestDoc instanceof Document\PageSnippet) { $this->setDocument($latestDoc); } } } // register editmode plugin $front = \Zend_Controller_Front::getInstance(); $front->registerPlugin(new \Pimcore\Controller\Plugin\Frontend\Editmode($this), 1000); } // document preview if ($this->getParam("pimcore_preview")) { // get document from session $docKey = "document_" . $this->getParam("document")->getId(); $docSession = Session::getReadOnly("pimcore_documents"); if ($docSession->{$docKey}) { $this->setDocument($docSession->{$docKey}); } } // object preview if ($this->getParam("pimcore_object_preview")) { $key = "object_" . $this->getParam("pimcore_object_preview"); $session = Session::getReadOnly("pimcore_objects"); if ($session->{$key}) { $object = $session->{$key}; // add the object to the registry so every call to Object::getById() will return this object instead of the real one \Zend_Registry::set("object_" . $object->getId(), $object); } } // for version preview if ($this->getParam("pimcore_version")) { // only get version data at the first call || because of embedded Snippets ... if (!\Zend_Registry::isRegistered("pimcore_version_active")) { $version = Model\Version::getById($this->getParam("pimcore_version")); $this->setDocument($version->getData()); \Zend_Registry::set("pimcore_version_active", true); } } } // for public versions if ($this->getParam("v")) { try { $version = Model\Version::getById($this->getParam("v")); if ($version->getPublic()) { $this->setDocument($version->getData()); } } catch (\Exception $e) { } } // check for persona if ($this->getDocument() instanceof Document\Page) { $this->getDocument()->setUsePersona(null); // reset because of preview and editmode (saved in session) if ($this->getParam("_ptp") && self::$isInitial) { $this->getDocument()->setUsePersona($this->getParam("_ptp")); } } // check if document is a wrapped hardlink, if this is the case send a rel=canonical header to the source document if ($this->getDocument() instanceof Document\Hardlink\Wrapper\WrapperInterface) { // get the cononical (source) document $hardlinkCanonicalSourceDocument = Document::getById($this->getDocument()->getId()); $request = $this->getRequest(); if (\Pimcore\Tool\Frontend::isDocumentInCurrentSite($hardlinkCanonicalSourceDocument)) { $this->getResponse()->setHeader("Link", '<' . $request->getScheme() . "://" . $request->getHttpHost() . $hardlinkCanonicalSourceDocument->getFullPath() . '>; rel="canonical"'); } } \Pimcore::getEventManager()->trigger("frontend.controller.postInit", $this); } // set some parameters $this->editmode = \Zend_Registry::get("pimcore_editmode"); $this->view->editmode = \Zend_Registry::get("pimcore_editmode"); self::$isInitial = false; }
/** * gets recursively attribute data from parent and fills objectData and metaData * * @param $item * @param $key * @param $fielddefinition * @return mixed */ private function getDataForField($item, $key, $fielddefinition, $level, $baseObject, $getter, $objectFromVersion) { $result = new \stdClass(); $parent = Object\Service::hasInheritableParentObject($baseObject); $valueGetter = "get" . ucfirst($key); // relations but not for objectsMetadata, because they have additional data which cannot be loaded directly from the DB if (!$objectFromVersion && method_exists($fielddefinition, "getLazyLoading") && $fielddefinition->getLazyLoading() && !$fielddefinition instanceof Object\ClassDefinition\Data\ObjectsMetadata && !$fielddefinition instanceof Object\ClassDefinition\Data\MultihrefMetadata) { //lazy loading data is fetched from DB differently, so that not every relation object is instantiated if ($fielddefinition->isRemoteOwner()) { $refKey = $fielddefinition->getOwnerFieldName(); $refId = $fielddefinition->getOwnerClassId(); } else { $refKey = $key; } $relations = $item->getRelationData($refKey, !$fielddefinition->isRemoteOwner(), $refId); if (empty($relations) && !empty($parent)) { $parentItem = $parent->{"get" . ucfirst($this->getName())}(); if (!empty($parentItem)) { $parentItem = $parentItem->{$getter}(); if ($parentItem) { return $this->getDataForField($parentItem, $key, $fielddefinition, $level + 1, $parent, $getter, $objectFromVersion); } } } $data = array(); if ($fielddefinition instanceof Object\ClassDefinition\Data\Href) { $data = $relations[0]; } else { foreach ($relations as $rel) { if ($fielddefinition instanceof Object\ClassDefinition\Data\Objects) { $data[] = array($rel["id"], $rel["path"], $rel["subtype"]); } else { $data[] = array($rel["id"], $rel["path"], $rel["type"], $rel["subtype"]); } } } $result->objectData = $data; $result->metaData['objectid'] = $baseObject->getId(); $result->metaData['inherited'] = $level != 0; } else { $editmodeValue = null; if (!empty($item)) { $fieldValue = $item->{$valueGetter}(); $editmodeValue = $fielddefinition->getDataForEditmode($fieldValue, $baseObject); } if ($fielddefinition->isEmpty($fieldValue) && !empty($parent)) { $backup = Object\AbstractObject::getGetInheritedValues(); Object\AbstractObject::setGetInheritedValues(true); $parentItem = $parent->{"get" . ucfirst($this->getName())}()->{$getter}(); Object\AbstractObject::setGetInheritedValues($backup); if (!empty($parentItem)) { return $this->getDataForField($parentItem, $key, $fielddefinition, $level + 1, $parent, $getter, $objectFromVersion); } } $result->objectData = $editmodeValue; $result->metaData['objectid'] = $baseObject->getId(); $result->metaData['inherited'] = $level != 0; } return $result; }
/** * @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; }
$request->setActionName("default"); $front->setRequest($request); $front->setResponse(new \Zend_Controller_Response_Cli()); // generic pimcore setup \Pimcore::setSystemRequirements(); \Pimcore::initAutoloader(); \Pimcore::initConfiguration(); \Pimcore::setupFramework(); \Pimcore::initLogger(); \Pimcore::initModules(); \Pimcore::initPlugins(); //Activate Inheritance for cli-scripts \Pimcore::unsetAdminMode(); Document::setHideUnpublished(true); Object\AbstractObject::setHideUnpublished(true); Object\AbstractObject::setGetInheritedValues(true); Object\Localizedfield::setGetFallbackValues(true); // CLI has no memory/time limits @ini_set('memory_limit', -1); @ini_set('max_execution_time', -1); @ini_set('max_input_time', -1); // Error reporting is enabled in CLI @ini_set("display_errors", "On"); @ini_set("display_startup_errors", "On"); error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT); // Pimcore\Console handles maintenance mode through the AbstractCommand if (!$pimcoreConsole) { // skip if maintenance mode is on and the flag is not set // we cannot use \Zend_Console_Getopt here because it doesn't allow to be called twice (unrecognized parameter, ...) if (\Pimcore\Tool\Admin::isInMaintenanceMode() && !in_array("--ignore-maintenance-mode", $_SERVER['argv'])) { die("in maintenance mode -> skip\nset the flag --ignore-maintenance-mode to force execution \n");
/** * */ 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 }
/** * Save Product * * @throws \Exception */ public function save() { $currentGetInheritedValues = \Pimcore\Model\Object\AbstractObject::getGetInheritedValues(); \Pimcore\Model\Object\AbstractObject::setGetInheritedValues(true); //Calculate Retail Price with Tax $retailPriceWithTax = $this->getRetailPrice() * (1 + $this->getTax()); $this->setPrice($retailPriceWithTax); \Pimcore\Model\Object\AbstractObject::setGetInheritedValues($currentGetInheritedValues); parent::save(); }