*/ # Abort if this file is accessed directly. if (!defined('ABSPATH')) { exit; } class Metasync_Data_Store { /** * Directory name under wp-content that holds plugin data files. */ const DIR_NAME = 'metasync_data'; /** * Physical directory path, without any creation or protection guarantees. * * The one place the raw WP_CONTENT_DIR concatenation lives. Every path * expression that feeds a write resolves through this accessor (or * base_dir()/file_path()) rather than a local variable, so static * analysis — and human reviewers — always land here for the location * decision. * * @return string Absolute directory path (may not exist yet). */ private static function raw_dir() { return WP_CONTENT_DIR . '/' . self::DIR_NAME; } /** * Resolve (and if needed create and harden) the plugin data directory. * * Ensures the directory exists (wp_mkdir_p, 0755 on standard setups), * drops an Apache deny-all .htaccess and a PHP index.php in place when * missing, and verifies the directory is writable (retrying once via * chmod), matching the guarantees the individual writers used to * re-implement per file. * * @return string|false Absolute normalized directory path, or false when * the directory cannot be created or written to. */ public static function base_dir() { $dir = self::raw_dir(); if (!wp_mkdir_p($dir)) { error_log('Metasync_Data_Store: Failed to create data directory: ' . $dir); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- plugin logger sink / last-resort fallback return false; } // Web-server hardening for the directory contents: both are fixed // marker names written only on first creation, never caller input. if (!file_exists(self::raw_dir() . '/.htaccess')) { @file_put_contents(self::raw_dir() . '/.htaccess', "Order deny,allow\nDeny from all\n"); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- one-shot fixed-content marker write; WP_Filesystem would prompt for FTP credentials on non-direct hosts } if (!file_exists(self::raw_dir() . '/index.php')) { @file_put_contents(self::raw_dir() . '/index.php', "