# 404-solution/4.2.0/includes/php/FileSync.php

404 Solution, version 4.2.0. 76 lines.

- Page: https://pluginprobe.com/plugins/404-solution/4.2.0/code/includes/php/FileSync.php
- Raw: https://pluginprobe.com/plugins/404-solution/4.2.0/raw/includes/php/FileSync.php
- Modified: 2026-05-24T08:07:28+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/404-solution/4.2.0/code/includes/php/FileSync.php#L10-L20`.

```php
<?php


if (!defined('ABSPATH')) {
    exit;
}

class ABJ_404_Solution_FileSync {
	
	/** @var self|null */
	private static $instance = null;

	/** @return self */
	public static function getInstance(): self {
		if (self::$instance == null) {
			self::$instance = new ABJ_404_Solution_FileSync();
		}
		
		return self::$instance;
	}
	
	/**
	 * @param string $key
	 * @return string
	 */
	function getSyncFilePath(string $key): string {
		$filePath = abj404_getUploadsDir() . 'SYNC_FILE_' . $key . '.txt';
		return $filePath;
	}
    
	/**
	 * @param string $key
	 * @return string
	 */
	function getOwnerFromFile(string $key): string {
		$filePath = $this->getSyncFilePath($key);
		$fileUtils = abj_service('functions');

		// Fixed: TOCTOU race condition - catch exception instead of check-then-read
		try {
			$contents = $fileUtils->readFileContents($filePath, false);
			return $contents;
		} catch (Exception $e) { // allow-silent-catch: TOCTOU-safe file read; missing or unreadable file returns empty, caller treats as "no lock owner"
			return "";
		}
	}
	
	/**
	 * @param string $key
	 * @param string $uniqueID
	 * @return void
	 */
	function writeOwnerToFile(string $key, string $uniqueID): void {
		$filePath = $this->getSyncFilePath($key);

		// Fixed: Check return value to handle write failures (disk full, permissions, etc.)
		$result = @file_put_contents($filePath, $uniqueID, LOCK_EX);

		if ($result === false) {
			throw new Exception("Failed to write lock file: " . $filePath);
		}
	}
	
	/**
	 * @param string $uniqueID
	 * @param string $key
	 * @return void
	 */
	function releaseLock(string $uniqueID, string $key): void {
		$filePath = $this->getSyncFilePath($key);
		$fileUtils = abj_service('functions');
		$fileUtils->safeUnlink($filePath);
	}
	
}

```
