Passed
Push — master ( b0f5d7...c171ec )
by Sergey
02:30
created

File::__destruct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
1
<?php
2
3
namespace PhpConsole\Storage;
4
5
/**
6
 * File storage for postponed response data. Use it if session handler in your project is overridden.
7
 *
8
 * @package PhpConsole
9
 * @version 3.1
10
 * @link http://consle.com
11
 * @author Sergey Barbushin http://linkedin.com/in/barbushin
12
 * @copyright © Sergey Barbushin, 2011-2013. All rights reserved.
13
 * @license http://www.opensource.org/licenses/BSD-3-Clause "The BSD 3-Clause License"
14
 */
15
class File extends AllKeysList {
16
17
	protected $filePath;
18
	protected $fileHandler;
19
20
	/**
21
	 * @param string $filePath Writable path for postponed data storage (should not be under DOCUMENT_ROOT)
22
	 * @param bool $validatePathNotUnderDocRoot Throw \Exception if $filePath is not under DOCUMENT_ROOT
23
	 * @throws \Exception
24
	 */
25 5
	public function __construct($filePath, $validatePathNotUnderDocRoot = true) {
26 5
		if(!file_exists($filePath)) {
27 5
			if(file_put_contents($filePath, '') === false) {
28
				throw new \Exception('Unable to write file ' . $filePath);
29
			}
30
		}
31 5
		$this->filePath = realpath($filePath);
32
33 5
		if($validatePathNotUnderDocRoot && $this->isPathUnderDocRoot()) {
34 1
			throw new \Exception('Path ' . $this->filePath . ' is under DOCUMENT_ROOT. It\'s insecure!');
35
		}
36 5
	}
37
38 2
	protected function isPathUnderDocRoot() {
0 ignored issues
show
Coding Style introduced by
isPathUnderDocRoot uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
39 2
		return !empty($_SERVER['DOCUMENT_ROOT']) && strpos($this->filePath, $_SERVER['DOCUMENT_ROOT']) === 0;
40
	}
41
42 3
	protected function initFileHandler() {
43 3
		$this->fileHandler = fopen($this->filePath, 'a+b');
44 3
		if(!$this->fileHandler) {
45
			throw new \Exception('Unable to read/write file ' . $this->filePath);
46
		}
47 3
		while(!flock($this->fileHandler, LOCK_EX | LOCK_NB)) {
48
			usleep(10000);
49
		}
50 3
		fseek($this->fileHandler, 0);
51 3
	}
52
53
	/**
54
	 * @throws \Exception
55
	 * @return array
56
	 */
57 3
	protected function getKeysData() {
58 3
		return json_decode(fgets($this->fileHandler), true) ? : array();
59
	}
60
61
	/**
62
	 * @param array $keysData
63
	 */
64 3
	protected function saveKeysData(array $keysData) {
65 3
		ftruncate($this->fileHandler, 0);
66 3
		fwrite($this->fileHandler, json_encode($keysData, defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : null));
67 3
	}
68
69 4
	protected function closeFileHandler() {
70 4
		if($this->fileHandler) {
71 3
			flock($this->fileHandler, LOCK_UN);
72 3
			fclose($this->fileHandler);
73 3
			$this->fileHandler = null;
74
		}
75 4
	}
76
77 3
	public function pop($key) {
78 3
		$this->initFileHandler();
79 3
		$result = parent::pop($key);
80 3
		$this->closeFileHandler();
81 3
		return $result;
82
	}
83
84 3
	public function push($key, $data) {
85 3
		$this->initFileHandler();
86 3
		parent::push($key, $data);
87 3
		$this->closeFileHandler();
88 3
	}
89
90 1
	public function __destruct() {
91 1
		$this->closeFileHandler();
92 1
	}
93
}
94