/** * Get attribute value * * @return null|EntityCollection */ public function getValue() { if ($this->isNull($this->value)) { $this->value = Many2ManyStorage::getInstance()->load($this); // Add new items to value and unset these new items foreach ($this->addedItems as $item) { $this->value->add($item); } $this->addedItems = []; } return $this->value; }
/** * Save entity attributes to database */ public function save() { $objectHash = spl_object_hash($this); if (array_key_exists($objectHash, self::$saved)) { return true; } self::$saved[$objectHash] = true; $data = []; $validation = []; $one2many = AttributeType::ONE2MANY; $many2many = AttributeType::MANY2MANY; /* @var $attr AbstractAttribute */ foreach ($this->getAttributes() as $key => $attr) { if ($attr->isRequired() && !$attr->hasValue()) { $ex = new ValidationException(ValidationException::VALIDATION_FAILED); $ex->addError($key, ValidationException::REQUIRED); $validation[$key] = $ex; continue; } if (!count($validation) && !$this->isInstanceOf($attr, $one2many) && !$this->isInstanceOf($attr, $many2many)) { if ($attr->getStoreToDb()) { $data[$key] = $attr->getDbValue(); } } } // Throw EntityException with invalid attributes if (count($validation)) { $attributes = []; foreach ($validation as $attr => $error) { foreach ($error as $key => $value) { $attributes[$key] = $value; } } $ex = new EntityException(EntityException::VALIDATION_FAILED, [count($validation)]); $ex->setInvalidAttributes($attributes); throw $ex; } /** * Insert or update */ $mongo = $this->entity()->getDatabase(); if (!$this->exists()) { $data['_id'] = $mongo->isId($data['id']) ? $mongo->id($data['id']) : $mongo->id(); $data['id'] = (string) $data['_id']; $mongo->insertOne(static::$entityCollection, $data); $this->id = $data['id']; } else { $where = ['_id' => $mongo->id($this->id)]; $mongo->update(static::$entityCollection, $where, ['$set' => $data], ['upsert' => true]); } /** * Now save One2Many values */ foreach ($this->getAttributes() as $attr) { /* @var $attr One2ManyAttribute */ if ($this->isInstanceOf($attr, AttributeType::ONE2MANY) && $attr->isLoaded()) { foreach ($attr->getValue() as $item) { $item->getAttribute($attr->getRelatedAttribute())->setValue($this); $item->save(); } /** * The value of one2many attribute must be set to null to trigger data reload on next access. * This is necessary when we have circular references, and parent record does not get it's many2one ID saved * until all child referenced objects are saved. Only then can we get proper links between referenced classes. */ $attr->setValue(null, true); } } /** * Now save Many2Many values */ foreach ($this->getAttributes() as $attr) { /* @var $attr Many2ManyAttribute */ if ($this->isInstanceOf($attr, AttributeType::MANY2MANY)) { Many2ManyStorage::getInstance()->save($attr); } } // Now that this entity is saved, remove it from save log unset(self::$saved[$objectHash]); return true; }
/** * Get attribute value * * @param array $params * * @return null|EntityCollection */ public function getValue($params = []) { if ($this->isNull($this->value)) { $this->value = Many2ManyStorage::getInstance()->load($this); } // Add new items to value and unset these new items foreach ($this->addedItems as $item) { if ($this->value instanceof EntityCollection) { $this->value->add($item); } else { $this->value[] = $item; } } $this->addedItems = []; return $this->processGetValue($this->value, $params); }
/** * Save entity attributes to database */ public function save() { if (!$this->getDirty() && !$this->isNull($this->getId()->getValue())) { return true; } $data = []; foreach ($this->getAttributes() as $key => $attr) { if (!$this->isInstanceOf($attr, AttributeType::ONE2MANY) && !$this->isInstanceOf($attr, AttributeType::MANY2MANY)) { $data[$key] = $attr->getDbValue(); } } /** * Insert or update */ if ($this->getId()->getValue() === null) { $data['_id'] = new \MongoId(); $data['id'] = (string) $data['_id']; $this->entity()->getDatabase()->insert(static::$entityCollection, $data); $this->getId()->setValue($data['id']); } else { $where = ['_id' => new \MongoId($this->getId()->getValue())]; $this->entity()->getDatabase()->update(static::$entityCollection, $where, ['$set' => $data], ['upsert' => true]); } $this->setDirty(false); /** * Now save One2Many values */ foreach ($this->getAttributes() as $attr) { /* @var $attr One2ManyAttribute */ if ($this->isInstanceOf($attr, AttributeType::ONE2MANY)) { foreach ($attr->getValue() as $item) { $item->getAttribute($attr->getRelatedAttribute())->setValue($this); $item->save(); } /** * The value of one2many attribute must be set to null to trigger data reload on next access. * This is necessary when we have circular references, and parent record does not get it's many2one ID saved * until all child referenced objects are saved. Only then can we get proper links between referenced classes. */ $attr->setValue(null); } } /** * Now save Many2Many values */ foreach ($this->getAttributes() as $attr) { /* @var $attr Many2ManyAttribute */ if ($this->isInstanceOf($attr, AttributeType::MANY2MANY)) { Many2ManyStorage::getInstance()->save($attr); } } return true; }