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") ->set("tags", $tags) ->set("expiration", $lifetime) ->set("cache", serialize($data)) ->where("key", "=", $id) ->execute(); } else { $status = db::build() ->insert("caches") ->columns("key", "tags", "expiration", "cache") ->values($id, $tags, $lifetime, serialize($data)) ->execute(); } } return true; } /** * Get cache items by tag * @param array cache tags * @return array cached data */ public function get_tag($tags) { $db = db::build() ->select() ->from("caches"); foreach ($tags as $tag) { $db->where("tags", "LIKE", "%<$tag>%"); } $db_result = $db->execute(); // 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() ->select() ->from("caches") ->where("key", "IN", $keys) ->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(array($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($keys, $is_tag=false) { $db = db::build() ->delete("caches"); if ($keys === true) { // Delete all caches } else if ($is_tag === true) { foreach ($keys as $tag) { $db->where("tags", "LIKE", "%<$tag>%"); } } else { $db->where("key", "IN", $keys); } $status = $db->execute(); 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 = db::build() ->delete("caches") ->where("expiration", "<>", 0) ->where("expiration", "<=", time()) ->execute(); return count($status) > 0; } /** * Empty the cache */ public function delete_all() { Database::instance()->query("TRUNCATE {caches}"); } }