1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14namespace phpbb\cache\driver;
15
16abstract class base implements \phpbb\cache\driver\driver_interface
17{
18	var $vars = array();
19	var $is_modified = false;
20
21	var $sql_rowset = array();
22	var $sql_row_pointer = array();
23	var $cache_dir = '';
24
25	/**
26	* {@inheritDoc}
27	*/
28	function purge()
29	{
30		// Purge all phpbb cache files
31		try
32		{
33			$iterator = new \DirectoryIterator($this->cache_dir);
34		}
35		catch (\Exception $e)
36		{
37			return;
38		}
39
40		foreach ($iterator as $fileInfo)
41		{
42			if ($fileInfo->isDot())
43			{
44				continue;
45			}
46			$filename = $fileInfo->getFilename();
47			if ($fileInfo->isDir())
48			{
49				$this->remove_dir($fileInfo->getPathname());
50			}
51			else if (strpos($filename, 'container_') === 0 ||
52				strpos($filename, 'autoload_') === 0 ||
53				strpos($filename, 'url_matcher') === 0 ||
54				strpos($filename, 'url_generator') === 0 ||
55				strpos($filename, 'sql_') === 0 ||
56				strpos($filename, 'data_') === 0)
57			{
58				$this->remove_file($fileInfo->getPathname());
59			}
60		}
61
62		unset($this->vars);
63		unset($this->sql_rowset);
64		unset($this->sql_row_pointer);
65
66		if (function_exists('opcache_reset'))
67		{
68			@opcache_reset();
69		}
70
71		$this->vars = array();
72		$this->sql_rowset = array();
73		$this->sql_row_pointer = array();
74
75		$this->is_modified = false;
76	}
77
78	/**
79	* {@inheritDoc}
80	*/
81	function unload()
82	{
83		$this->save();
84		unset($this->vars);
85		unset($this->sql_rowset);
86		unset($this->sql_row_pointer);
87
88		$this->vars = array();
89		$this->sql_rowset = array();
90		$this->sql_row_pointer = array();
91	}
92
93	/**
94	* {@inheritDoc}
95	*/
96	function sql_load($query)
97	{
98		// Remove extra spaces and tabs
99		$query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
100		$query_id = md5($query);
101
102		if (($result = $this->_read('sql_' . $query_id)) === false)
103		{
104			return false;
105		}
106
107		$this->sql_rowset[$query_id] = $result;
108		$this->sql_row_pointer[$query_id] = 0;
109
110		return $query_id;
111	}
112
113	/**
114	* {@inheritDoc}
115	*/
116	function sql_exists($query_id)
117	{
118		return isset($this->sql_rowset[$query_id]);
119	}
120
121	/**
122	* {@inheritDoc}
123	*/
124	function sql_fetchrow($query_id)
125	{
126		if ($this->sql_row_pointer[$query_id] < count($this->sql_rowset[$query_id]))
127		{
128			return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++];
129		}
130
131		return false;
132	}
133
134	/**
135	* {@inheritDoc}
136	*/
137	function sql_fetchfield($query_id, $field)
138	{
139		if ($this->sql_row_pointer[$query_id] < count($this->sql_rowset[$query_id]))
140		{
141			return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false;
142		}
143
144		return false;
145	}
146
147	/**
148	* {@inheritDoc}
149	*/
150	function sql_rowseek($rownum, $query_id)
151	{
152		if ($rownum >= count($this->sql_rowset[$query_id]))
153		{
154			return false;
155		}
156
157		$this->sql_row_pointer[$query_id] = $rownum;
158		return true;
159	}
160
161	/**
162	* {@inheritDoc}
163	*/
164	function sql_freeresult($query_id)
165	{
166		if (!isset($this->sql_rowset[$query_id]))
167		{
168			return false;
169		}
170
171		unset($this->sql_rowset[$query_id]);
172		unset($this->sql_row_pointer[$query_id]);
173
174		return true;
175	}
176
177	/**
178	* Removes/unlinks file
179	*
180	* @param string $filename Filename to remove
181	* @param bool $check Check file permissions
182	* @return bool True if the file was successfully removed, otherwise false
183	*/
184	function remove_file($filename, $check = false)
185	{
186		global $phpbb_filesystem;
187
188		if ($check && !$phpbb_filesystem->is_writable($this->cache_dir))
189		{
190			// E_USER_ERROR - not using language entry - intended.
191			trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
192		}
193
194		return @unlink($filename);
195	}
196
197	/**
198	* Remove directory
199	*
200	* @param string $dir Directory to remove
201	*
202	* @return null
203	*/
204	protected function remove_dir($dir)
205	{
206		try
207		{
208			$iterator = new \DirectoryIterator($dir);
209		}
210		catch (\Exception $e)
211		{
212			return;
213		}
214
215		foreach ($iterator as $fileInfo)
216		{
217			if ($fileInfo->isDot())
218			{
219				continue;
220			}
221
222			if ($fileInfo->isDir())
223			{
224				$this->remove_dir($fileInfo->getPathname());
225			}
226			else
227			{
228				$this->remove_file($fileInfo->getPathname());
229			}
230		}
231
232		@rmdir($dir);
233	}
234}
235