post_status || '' !== (string) $post->post_password ) { return ''; } return md5( (string) $post->post_modified_gmt . '|' . AGENTIMUS_VERSION . '|' . (string) get_option( self::EPOCH_OPTION, '0' ) ); } /** * The cache directory (created on demand under uploads/), or '' when it can't be used. * * @return string */ private static function dir() { $up = wp_upload_dir(); if ( ! empty( $up['error'] ) || empty( $up['basedir'] ) ) { return ''; } $dir = $up['basedir'] . '/agentimus-md-cache'; if ( ! is_dir( $dir ) ) { wp_mkdir_p( $dir ); } return ( is_dir( $dir ) && wp_is_writable( $dir ) ) ? $dir : ''; } /** * The cache file path for a post, or '' when the directory isn't usable. * * @param int $post_id Post ID. * @return string */ private static function file( $post_id ) { $dir = self::dir(); return '' === $dir ? '' : $dir . '/' . (int) $post_id . '.md'; } /** * Write the body (fingerprint-prefixed) to the post's cache file. * * @param int $post_id Post ID. * @param string $fp Fingerprint. * @param string $body Rendered markdown. */ private static function write_file( $post_id, $fp, $body ) { $file = self::file( $post_id ); if ( '' === $file ) { return; } @file_put_contents( $file, $fp . "\n" . $body, LOCK_EX ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents, WordPress.PHP.NoSilencedErrors -- our own cache file; a write failure is non-fatal (next request regenerates). } /** * Drop a post's cache file (object-cache entries expire by fingerprint/TTL on their own). * * @param int $post_id Post ID. */ public static function forget( $post_id ) { $file = self::file( (int) $post_id ); if ( '' !== $file && file_exists( $file ) ) { @unlink( $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink, WordPress.PHP.NoSilencedErrors -- our own cache file. } } /** * Roll the epoch so every cached body's fingerprint stops matching — a one-write mass * invalidation. Hooked to `agentimus_cache_flushed`. A unique token (not a timestamp) * so an edit + flush within the same second still changes the fingerprint. */ public static function bump_epoch() { update_option( self::EPOCH_OPTION, uniqid( '', true ), false ); } /** * Remove the whole cache directory (uninstall). */ public static function purge_all() { $dir = self::dir(); if ( '' === $dir ) { return; } foreach ( (array) glob( $dir . '/*.md' ) as $f ) { @unlink( $f ); // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink, WordPress.PHP.NoSilencedErrors -- our own cache files. } @rmdir( $dir ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir, WordPress.WP.AlternativeFunctions.directory_rmdir, WordPress.PHP.NoSilencedErrors -- our own now-empty cache dir; WP_Filesystem would need credentials we may not have here. } }