where("key", "=", $id) ->where("expiration", ">=", "time()") ->count_records("caches"); return $count > 0; } /** * Sets a cache item to the given data, tags, and lifetime. * * @param array assoc array of key => value pairs * @param array cache tags * @param integer lifetime * @return bool */ public function set($items, $tags=null, $lifetime=null) { if (!empty($tags)) { // Escape the tags, adding brackets so the tag can be explicitly matched $tags = "<" . implode(">,<", $tags) . ">"; } else { $tags = null; } // Cache Database driver expects unix timestamp if ($lifetime !== 0) { $lifetime += time(); } foreach ($items as $id => $data) { if ($this->exists($id)) { $status = db::build()->update( "caches", array("tags" => $tags, "expiration" => $lifetime, "cache" => serialize($data)), array("key", "=", $id)); } else { $status = db::build()->insert( "caches", array("key" => $id, "tags" => $tags, "expiration" => $lifetime, "cache" => serialize($data))); } } return true; } /** * Get cache items by tag * @param array cache tags * @return array cached data */ public function get_tag($tags) { $db = db::build()->from("caches"); foreach ($tags as $tag) { $db->where("tags", "like", "<$tag>"); } $db_result = $db->execute()->as_array(); // An array will always be returned $result = array(); // Disable notices for unserializing $ER = error_reporting(~E_NOTICE); if ($db_result->count() > 0) { foreach ($db_result as $row) { // Add each cache to the array $result[$row->key] = unserialize($row->cache); } } error_reporting($ER); return $result; } /** * Fetches a cache item. This will delete the item if it is expired or if * the hash does not match the stored hash. * * @param string cache id * @return mixed|NULL */ public function get($keys, $single=false) { $data = null; $result = db::build() ->from("caches") ->where("key", "IN", $keys) ->select() ->execute(); if (count($result) > 0) { $cache = $result->current(); // Make sure the expiration is valid and that the hash matches if ($cache->expiration != 0 && $cache->expiration <= time()) { // Cache is not valid, delete it now $this->delete($cache->id); } else { // Disable notices for unserializing $ER = error_reporting(~E_NOTICE); // Return the valid cache data $data = unserialize($cache->cache); // Turn notices back on error_reporting($ER); } } return $data; } /** * Deletes a cache item by id or tag * * @param string cache id or tag, or true for "all items" * @param bool delete a tag * @return bool */ public function delete($id, $tag = false) { $this->db->from("caches"); if ($id === true) { $this->db->where(1); // Delete all caches } else if ($tag === true) { $this->db->like("tags", "<$id>"); } else { $this->db->where("key", $id); } $status = $this->db->delete(); return count($status) > 0; } /** * Delete cache items by tag */ public function delete_tag($tags) { return $this->delete($tags, true); } /** * Deletes all cache files that are older than the current time. */ public function delete_expired() { // Delete all expired caches $status = $this->db->from("caches") ->where(array("expiration !=" => 0, "expiration <=" => time())) ->delete(); return count($status) > 0; } /** * Empty the cache */ public function delete_all() { db::build()->query("TRUNCATE {caches}"); } }