diff --git a/composer.json b/composer.json index 648b356a..45294794 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,8 @@ "bower-asset/jquery" : "^1.12", "bower-asset/jquery-timeago" : "^1.5", - "bower-asset/js-cookie" : "^2.1" + "bower-asset/js-cookie" : "^2.1", + "psr/simple-cache": "3.0.x-dev" }, "require-dev" : { diff --git a/composer.lock b/composer.lock index 1d80c7bd..73078ee6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1a9bc743870e5e5749b80ee7cdb07086", + "content-hash": "c5b40df44e9d52a91768469533768052", "packages": [ { "name": "bower-asset/jquery", @@ -282,6 +282,58 @@ }, "type": "library" }, + { + "name": "psr/simple-cache", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "2d280c2aaa23a120f35d55cfde8581954a8e77fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/2d280c2aaa23a120f35d55cfde8581954a8e77fa", + "reference": "2d280c2aaa23a120f35d55cfde8581954a8e77fa", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, + "time": "2022-04-08T16:41:45+00:00" + }, { "name": "shish/eventtracer-php", "version": "v2.0.1", @@ -5254,6 +5306,7 @@ "minimum-stability": "dev", "stability-flags": { "shish/gqla": 20, + "psr/simple-cache": 20, "scrutinizer/ocular": 20 }, "prefer-stable": false, diff --git a/core/cacheengine.php b/core/cacheengine.php index 44307588..0bdbf6cc 100644 --- a/core/cacheengine.php +++ b/core/cacheengine.php @@ -135,32 +135,19 @@ class RedisCache implements CacheEngine } } -class Cache +class CacheWithStats implements \Psr\SimpleCache\CacheInterface { public $engine; public int $hits=0; public int $misses=0; public int $time=0; - public function __construct(?string $dsn) + public function __construct(CacheEngine $c) { - $matches = []; - $c = null; - if ($dsn && preg_match("#(.*)://(.*)#", $dsn, $matches) && !isset($_GET['DISABLE_CACHE'])) { - if ($matches[1] == "memcached" || $matches[1] == "memcache") { - $c = new MemcachedCache($matches[2]); - } elseif ($matches[1] == "apc") { - $c = new APCCache($matches[2]); - } elseif ($matches[1] == "redis") { - $c = new RedisCache($matches[2]); - } - } else { - $c = new NoCache(); - } $this->engine = $c; } - public function get(string $key) + public function get(string $key, mixed $default=null): mixed { global $_tracer; $_tracer->begin("Cache Query", ["key"=>$key]); @@ -170,26 +157,60 @@ class Cache $this->hits++; } else { $res = "miss"; + $val = $default; $this->misses++; } $_tracer->end(null, ["result"=>$res]); return $val; } - public function set(string $key, $val, int $time=0) + public function set(string $key, mixed $value, \DateInterval|int|null $ttl = null): bool { global $_tracer; - $_tracer->begin("Cache Set", ["key"=>$key, "time"=>$time]); - $this->engine->set($key, $val, $time); + $_tracer->begin("Cache Set", ["key"=>$key, "ttl"=>$ttl]); + $this->engine->set($key, $value, $ttl ?? 0); $_tracer->end(); + return true; } - public function delete(string $key) + public function delete(string $key): bool { global $_tracer; $_tracer->begin("Cache Delete", ["key"=>$key]); $this->engine->delete($key); $_tracer->end(); + return true; + } + + public function clear(): bool + { + throw new Exception("Not implemented"); + } + + public function getMultiple(iterable $keys, mixed $default = null): iterable + { + $results = []; + foreach($keys as $key) { + $results[$key] = $this->get($key, $default); + } + return $results; + } + + public function setMultiple(iterable $values, \DateInterval|int|null $ttl = null): bool { + foreach($values as $key => $value) { + $this->set($key, $value, $ttl); + } + return true; + } + + public function deleteMultiple(iterable $keys): bool { + foreach($keys as $key) { + $this->delete($key); + } + } + public function has(string $key): bool { + $sentinel = 4345345735673; + return $this->get($key, $sentinel) != $sentinel; } public function get_hits(): int @@ -201,3 +222,20 @@ class Cache return $this->misses; } } + +function loadCache(?string $dsn): CacheWithStats { + $matches = []; + $c = null; + if ($dsn && preg_match("#(.*)://(.*)#", $dsn, $matches) && !isset($_GET['DISABLE_CACHE'])) { + if ($matches[1] == "memcached" || $matches[1] == "memcache") { + $c = new MemcachedCache($matches[2]); + } elseif ($matches[1] == "apc") { + $c = new APCCache($matches[2]); + } elseif ($matches[1] == "redis") { + $c = new RedisCache($matches[2]); + } + } else { + $c = new NoCache(); + } + return new CacheWithStats($c); +} diff --git a/core/config.php b/core/config.php index ecaa274f..5c658629 100644 --- a/core/config.php +++ b/core/config.php @@ -284,7 +284,7 @@ class DatabaseConfig extends BaseConfig } $cached = $cache->get($cache_name); - if ($cached) { + if (!is_null($cached)) { $this->values = $cached; } else { $this->values = []; diff --git a/core/imageboard/image.php b/core/imageboard/image.php index adcfb7cf..c5ec8296 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -185,7 +185,7 @@ class Image { global $cache, $database; $total = $cache->get("image-count"); - if (!$total) { + if (is_null($total)) { $total = (int)$database->get_one("SELECT COUNT(*) FROM images"); $cache->set("image-count", $total, 600); } @@ -227,7 +227,7 @@ class Image // implode(tags) can be too long for memcache... $cache_key = "image-count:" . md5(Tag::implode($tags)); $total = $cache->get($cache_key); - if (!$total) { + if (is_null($total)) { if (Extension::is_enabled(RatingsInfo::KEY)) { $tags[] = "rating:*"; } diff --git a/core/imageboard/tag.php b/core/imageboard/tag.php index d49bbce3..0b509f98 100644 --- a/core/imageboard/tag.php +++ b/core/imageboard/tag.php @@ -49,7 +49,7 @@ class TagUsage { } $res = $cache->get($cache_key); - if (!$res) { + if (is_null($res)) { $res = $database->get_pairs( " SELECT tag, count diff --git a/core/user.php b/core/user.php index 30e97e1f..11546a8e 100644 --- a/core/user.php +++ b/core/user.php @@ -74,7 +74,7 @@ class User { global $cache, $config, $database; $row = $cache->get("user-session:$name-$session"); - if (!$row) { + if (is_null($row)) { if ($database->get_driver_id() === DatabaseDriverID::MYSQL) { $query = "SELECT * FROM users WHERE name = :name AND md5(concat(pass, :ip)) = :sess"; } else { @@ -91,7 +91,7 @@ class User global $cache, $database; if ($id === 1) { $cached = $cache->get('user-id:'.$id); - if ($cached) { + if (!is_null($cached)) { return new User($cached); } } diff --git a/ext/autocomplete/main.php b/ext/autocomplete/main.php index 3a2c0880..e97ed987 100644 --- a/ext/autocomplete/main.php +++ b/ext/autocomplete/main.php @@ -62,7 +62,7 @@ class AutoComplete extends Extension } $res = $cache->get($cache_key); - if (!$res) { + if (is_null($res)) { $res = $database->get_pairs( " SELECT tag, count diff --git a/ext/blocks/main.php b/ext/blocks/main.php index 299a360c..ccf71069 100644 --- a/ext/blocks/main.php +++ b/ext/blocks/main.php @@ -49,7 +49,7 @@ class Blocks extends Extension global $cache, $database, $page, $user; $blocks = $cache->get("blocks"); - if ($blocks === false) { + if (is_null($blocks)) { $blocks = $database->get_all("SELECT * FROM blocks"); $cache->set("blocks", $blocks, 600); } diff --git a/ext/comment/main.php b/ext/comment/main.php index 449ebe27..299b8779 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -274,7 +274,7 @@ class CommentList extends Extension $where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : ""; $total_pages = $cache->get("comment_pages"); - if (empty($total_pages)) { + if (is_null($total_pages)) { $total_pages = (int)ceil($database->get_one(" SELECT COUNT(c1) FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1 @@ -346,7 +346,7 @@ class CommentList extends Extension $cc = $config->get_int("comment_count"); if ($cc > 0) { $recent = $cache->get("recent_comments"); - if (empty($recent)) { + if (is_null($recent)) { $recent = $this->get_recent_comments($cc); $cache->set("recent_comments", $recent, 60); } diff --git a/ext/featured/main.php b/ext/featured/main.php index 7351edbb..0f87114f 100644 --- a/ext/featured/main.php +++ b/ext/featured/main.php @@ -53,7 +53,7 @@ class Featured extends Extension $fid = $config->get_int("featured_id"); if ($fid > 0) { $image = $cache->get("featured_image_object:$fid"); - if ($image === false) { + if (is_null($image)) { $image = Image::by_id($fid); if ($image) { // make sure the object is fully populated before saving $image->get_tag_array(); diff --git a/ext/index/main.php b/ext/index/main.php index 97286e57..3bb56976 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -85,7 +85,7 @@ class Index extends Extension if ($count_search_terms === 0 && ($page_number < 10)) { // extra caching for the first few post/list pages $images = $cache->get("post-list:$page_number"); - if (!$images) { + if (is_null($images)) { $images = Image::find_images(($page_number-1)*$page_size, $page_size, $search_terms); $cache->set("post-list:$page_number", $images, 60); } diff --git a/ext/ipban/main.php b/ext/ipban/main.php index 24795c81..3113dd79 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -107,7 +107,7 @@ class IPBan extends Extension // Get lists of banned IPs and banned networks $ips = $cache->get("ip_bans"); $networks = $cache->get("network_bans"); - if ($ips === false || $networks === false) { + if (is_null($ips) || is_null($networks)) { $rows = $database->get_pairs(" SELECT ip, id FROM bans diff --git a/ext/pm/main.php b/ext/pm/main.php index 2e07a1b0..1e13d062 100644 --- a/ext/pm/main.php +++ b/ext/pm/main.php @@ -241,7 +241,7 @@ class PrivMsg extends Extension global $cache, $database; $count = $cache->get("pm-count:{$user->id}"); - if (is_null($count) || $count === false) { + if (is_null($count)) { $count = $database->get_one(" SELECT count(*) FROM private_message diff --git a/ext/report_image/main.php b/ext/report_image/main.php index a65d54d1..8a30f8a2 100644 --- a/ext/report_image/main.php +++ b/ext/report_image/main.php @@ -243,7 +243,7 @@ class ReportImage extends Extension global $cache, $database; $count = $cache->get("image-report-count"); - if (is_null($count) || $count === false) { + if (is_null($count)) { $count = $database->get_one("SELECT count(*) FROM image_reports"); $cache->set("image-report-count", $count, 600); } diff --git a/ext/rss_images/main.php b/ext/rss_images/main.php index 228aa343..5cccc51c 100644 --- a/ext/rss_images/main.php +++ b/ext/rss_images/main.php @@ -97,7 +97,7 @@ class RSSImages extends Extension global $cache; $cached = $cache->get("rss-item-image:{$image->id}"); - if ($cached) { + if (!is_null($cached)) { return $cached; } diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php index c90fe8cb..345cf9c4 100644 --- a/ext/tag_list/main.php +++ b/ext/tag_list/main.php @@ -157,7 +157,7 @@ class TagList extends Extension $results = $cache->get("tag_list_omitted_tags:".$tags_config); - if ($results==null) { + if (is_null($results)) { $tags = explode(" ", $tags_config); if (empty($tags)) { @@ -494,7 +494,7 @@ class TagList extends Extension global $cache, $database, $config; $tags = $cache->get("popular_tags"); - if (empty($tags)) { + if (is_null($tags)) { $omitted_tags = self::get_omitted_tags(); if (empty($omitted_tags)) { @@ -556,7 +556,7 @@ class TagList extends Extension $str_search = Tag::implode($search); $related_tags = $cache->get("related_tags:$str_search"); - if (empty($related_tags)) { + if (is_null($related_tags)) { // $search_tags = array(); $starting_tags = []; diff --git a/index.php b/index.php index de93a3c2..c80883b6 100644 --- a/index.php +++ b/index.php @@ -46,7 +46,7 @@ _set_up_shimmie_environment(); $_tracer = new \EventTracer(); $_tracer->begin("Bootstrap"); _load_core_files(); -$cache = new Cache(CACHE_DSN); +$cache = loadCache(CACHE_DSN); $database = new Database(DATABASE_DSN); $config = new DatabaseConfig($database); ExtensionInfo::load_all_extension_info(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3dfddfac..a1accb69 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -25,7 +25,7 @@ $tracer_enabled = true; $_tracer = new \EventTracer(); $_tracer->begin("bootstrap"); _load_core_files(); -$cache = new Cache(CACHE_DSN); +$cache = loadCache(CACHE_DSN); $dsn = getenv("TEST_DSN"); $database = new Database($dsn ? $dsn : "sqlite::memory:"); create_dirs(); diff --git a/themes/rule34v2/themelet.class.php b/themes/rule34v2/themelet.class.php index 1d0f2ab5..4ba5e1aa 100644 --- a/themes/rule34v2/themelet.class.php +++ b/themes/rule34v2/themelet.class.php @@ -11,7 +11,7 @@ class Themelet extends BaseThemelet global $cache, $config; $cached = $cache->get("thumb-block:{$image->id}"); - if ($cached) { + if(!is_null($cached)) { return $cached; }