/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update($id, $name, $value, $value_type, $owner_guid, $access_id) { $id = (int) $id; if (!($md = $this->get($id))) { return false; } if (!$md->canEdit()) { return false; } $value_type = detect_extender_valuetype($value, $this->db->sanitizeString(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = $this->session->getLoggedInUserGuid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { $value = (int) $value; } // If ok then add it $query = "UPDATE {$this->table}\n\t\t\tSET name = :name,\n\t\t\t value = :value,\n\t\t\t\tvalue_type = :value_type,\n\t\t\t\taccess_id = :access_id,\n\t\t\t owner_guid = :owner_guid\n\t\t\tWHERE id = :id"; $result = $this->db->updateData($query, false, [':name' => $name, ':value' => $value, ':value_type' => $value_type, ':access_id' => $access_id, ':owner_guid' => $owner_guid, ':id' => $id]); if ($result !== false) { $this->cache->clear($md->entity_guid); // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. $obj = $this->get($id); $this->events->trigger('update', 'metadata', $obj); } return $result; }
/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update($id, $name, $value, $value_type, $owner_guid, $access_id) { $id = (int) $id; if (!($md = $this->get($id))) { return false; } if (!$md->canEdit()) { return false; } // If memcached then we invalidate the cache for this entry static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new \ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { // @todo fix memcache (name_id is not a property of \ElggMetadata) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } $value_type = detect_extender_valuetype($value, $this->db->sanitizeString(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = $this->session->getLoggedInUserGuid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { $value = (int) $value; } $value_id = $this->metastringsTable->getId($value); if (!$value_id) { return false; } $name_id = $this->metastringsTable->getId($name); if (!$name_id) { return false; } // If ok then add it $query = "UPDATE {$this->table}" . " set name_id='{$name_id}', value_id='{$value_id}', value_type='{$value_type}', access_id={$access_id}," . " owner_guid={$owner_guid} where id={$id}"; $result = $this->db->updateData($query); if ($result !== false) { $this->cache->clear($md->entity_guid); // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. $obj = $this->get($id); $this->events->trigger('update', 'metadata', $obj); } return $result; }
/** * Invalidate this class's entry in the cache. * * @param int $guid The entity guid * @return void */ public function remove($guid) { $guid = (int) $guid; if (!isset($this->entities[$guid])) { return; } unset($this->entities[$guid]); $username = array_search($guid, $this->username_cache); if ($username !== false) { unset($this->username_cache[$username]); } // Purge separate metadata cache. Original idea was to do in entity destructor, but that would // have caused a bunch of unnecessary purges at every shutdown. Doing it this way we have no way // to know that the expunged entity will be GCed (might be another reference living), but that's // OK; the metadata will reload if necessary. $this->metadata_cache->clear($guid); }
public function testClearActsOnAllAccessStates() { $session = ElggSession::getMock(); $cache = new MetadataCache($session); $session->setIgnoreAccess(false); $cache->inject(1, ['foo' => 'bar']); $session->setIgnoreAccess(true); $cache->clear(1); $session->setIgnoreAccess(false); $this->assertFalse($cache->isLoaded(1)); $session->setIgnoreAccess(true); $cache->inject(1, ['foo' => 'bar']); $session->setIgnoreAccess(false); $cache->clear(1); $session->setIgnoreAccess(true); $this->assertFalse($cache->isLoaded(1)); }