PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.1
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.1
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | includes/class-metasync-error-logger.php +19 -38 2.7.0 → 2.7.1 View file →
@@ -188,49 +188,30 @@
188 188 * @param string $log_line Formatted log line
189 189 * @return bool True on success, false on failure
190 190 */
191 191 private static function write_to_log_file($log_line) {
192 - // Get log directory (same as Log_Manager uses)
193 - $log_directory = WP_CONTENT_DIR . '/metasync_data';
194 -
195 - // Create directory if it doesn't exist
196 - if (!is_dir($log_directory)) {
197 - if (!@mkdir($log_directory, 0755, true)) {
198 - error_log('Metasync_Error_Logger: Failed to create log directory: ' . $log_directory);
199 - return false;
200 - }
192 + // Directory creation, web-server protection, and writability
193 + // guarantees live in Metasync_Data_Store so every writer agrees on
194 + // the location; a false return means "no writable data directory".
195 + $log_directory = Metasync_Data_Store::base_dir();
196 + if (false === $log_directory) {
197 + return false;
201 198 }
202 199
203 - // Protect log directory from direct web access
204 - $htaccess_file = $log_directory . '/.htaccess';
205 - if (!file_exists($htaccess_file)) {
206 - @file_put_contents($htaccess_file, "Order deny,allow\nDeny from all\n");
200 + // Get log file path
201 + $log_file = Metasync_Data_Store::file_path(self::LOG_FILE_NAME);
202 + if (false === $log_file) {
203 + return false;
207 204 }
208 - $index_file = $log_directory . '/index.php';
209 - if (!file_exists($index_file)) {
210 - @file_put_contents($index_file, "<?php\n// Silence is golden\n");
211 - }
212 205
213 - // Verify directory is writable
214 - if (!is_writable($log_directory)) {
215 - @chmod($log_directory, 0755);
216 - if (!is_writable($log_directory)) {
217 - error_log('Metasync_Error_Logger: Directory not writable: ' . $log_directory);
218 - return false;
219 - }
220 - }
221 -
222 - // Get log file path
223 - $log_file = wp_normalize_path($log_directory . '/' . self::LOG_FILE_NAME);
224 -
225 206 // Serialize rotation and append across requests. Locking only the log
226 207 // file is insufficient because rename() changes the inode being locked.
227 - $rotation_lock = @fopen($log_file . '.lock', 'c');
208 + $rotation_lock = @fopen($log_file . '.lock', 'c'); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- streaming file I/O; WP_Filesystem cannot return a raw stream handle
228 209 if (false === $rotation_lock || !flock($rotation_lock, LOCK_EX)) {
229 210 if (false !== $rotation_lock) {
230 - fclose($rotation_lock);
211 + fclose($rotation_lock); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- operates on a native stream handle
231 212 }
232 - error_log('Metasync_Error_Logger: Failed to lock log file: ' . $log_file);
213 + error_log('Metasync_Error_Logger: Failed to lock log file: ' . $log_file); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- plugin logger sink / last-resort fallback
233 214 return false;
234 215 }
235 216
236 217 // Rotate while holding the stable sidecar lock so concurrent requests
@@ -238,26 +219,26 @@
238 219 $log_size = file_exists($log_file) ? filesize($log_file) : false;
239 220 if (false !== $log_size && $log_size >= self::MAX_LOG_SIZE) {
240 221 $backup = $log_file . '.old';
241 222 if (file_exists($backup)) {
242 - @unlink($backup);
223 + @wp_delete_file($backup);
243 224 }
244 - @rename($log_file, $backup);
225 + @rename($log_file, $backup); // phpcs:ignore WordPress.WP.AlternativeFunctions.rename_rename -- atomic same-filesystem replace; WP_Filesystem::move() needs credential bootstrapping on non-direct hosts
245 226 }
246 227
247 228 // Append to log file with file locking
248 229 $result = @file_put_contents($log_file, $log_line, FILE_APPEND | LOCK_EX);
249 230 flock($rotation_lock, LOCK_UN);
250 - fclose($rotation_lock);
231 + fclose($rotation_lock); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- operates on a native stream handle
251 232
252 233 if ($result === false) {
253 - error_log('Metasync_Error_Logger: Failed to write to log file: ' . $log_file);
234 + error_log('Metasync_Error_Logger: Failed to write to log file: ' . $log_file); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- plugin logger sink / last-resort fallback
254 235 return false;
255 236 }
256 237
257 238 // Set file permissions if file was just created
258 239 if (!file_exists($log_file) || filesize($log_file) === strlen($log_line)) {
259 - @chmod($log_file, 0644);
240 + @chmod($log_file, 0644); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chmod -- direct POSIX permission change; WP_Filesystem would prompt for FTP credentials on non-direct hosts
260 241 }
261 242
262 243 return true;
263 244 }
@@ -476,8 +457,8 @@
476 457
477 458 // Also check on shutdown (for immediate detection, throttled)
478 459 add_action('shutdown', function() {
479 460 // Only check in admin or if triggered manually
480 - if (is_admin() || isset($_GET['metasync_check_queue'])) {
461 + if (is_admin() || isset($_GET['metasync_check_queue'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only, throttled queue check
481 462 metasync_check_action_scheduler_queue_overflow();
482 463 }
483 464 }, 999);