You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
5.8 KiB

7 years ago
  1. <?php
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP
  6. *
  7. * This content is released under the MIT License (MIT)
  8. *
  9. * Copyright (c) 2014 - 2017, British Columbia Institute of Technology
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy
  12. * of this software and associated documentation files (the "Software"), to deal
  13. * in the Software without restriction, including without limitation the rights
  14. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. * copies of the Software, and to permit persons to whom the Software is
  16. * furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included in
  19. * all copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. * THE SOFTWARE.
  28. *
  29. * @package CodeIgniter
  30. * @author EllisLab Dev Team
  31. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
  32. * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/)
  33. * @license http://opensource.org/licenses/MIT MIT License
  34. * @link https://codeigniter.com
  35. * @since Version 1.0.0
  36. * @filesource
  37. */
  38. defined('BASEPATH') OR exit('No direct script access allowed');
  39. /**
  40. * Database Cache Class
  41. *
  42. * @category Database
  43. * @author EllisLab Dev Team
  44. * @link https://codeigniter.com/user_guide/database/
  45. */
  46. class CI_DB_Cache {
  47. /**
  48. * CI Singleton
  49. *
  50. * @var object
  51. */
  52. public $CI;
  53. /**
  54. * Database object
  55. *
  56. * Allows passing of DB object so that multiple database connections
  57. * and returned DB objects can be supported.
  58. *
  59. * @var object
  60. */
  61. public $db;
  62. // --------------------------------------------------------------------
  63. /**
  64. * Constructor
  65. *
  66. * @param object &$db
  67. * @return void
  68. */
  69. public function __construct(&$db)
  70. {
  71. // Assign the main CI object to $this->CI and load the file helper since we use it a lot
  72. $this->CI =& get_instance();
  73. $this->db =& $db;
  74. $this->CI->load->helper('file');
  75. $this->check_path();
  76. }
  77. // --------------------------------------------------------------------
  78. /**
  79. * Set Cache Directory Path
  80. *
  81. * @param string $path Path to the cache directory
  82. * @return bool
  83. */
  84. public function check_path($path = '')
  85. {
  86. if ($path === '')
  87. {
  88. if ($this->db->cachedir === '')
  89. {
  90. return $this->db->cache_off();
  91. }
  92. $path = $this->db->cachedir;
  93. }
  94. // Add a trailing slash to the path if needed
  95. $path = realpath($path)
  96. ? rtrim(realpath($path), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR
  97. : rtrim($path, '/').'/';
  98. if ( ! is_dir($path))
  99. {
  100. log_message('debug', 'DB cache path error: '.$path);
  101. // If the path is wrong we'll turn off caching
  102. return $this->db->cache_off();
  103. }
  104. if ( ! is_really_writable($path))
  105. {
  106. log_message('debug', 'DB cache dir not writable: '.$path);
  107. // If the path is not really writable we'll turn off caching
  108. return $this->db->cache_off();
  109. }
  110. $this->db->cachedir = $path;
  111. return TRUE;
  112. }
  113. // --------------------------------------------------------------------
  114. /**
  115. * Retrieve a cached query
  116. *
  117. * The URI being requested will become the name of the cache sub-folder.
  118. * An MD5 hash of the SQL statement will become the cache file name.
  119. *
  120. * @param string $sql
  121. * @return string
  122. */
  123. public function read($sql)
  124. {
  125. $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
  126. $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
  127. $filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);
  128. if ( ! is_file($filepath) OR FALSE === ($cachedata = file_get_contents($filepath)))
  129. {
  130. return FALSE;
  131. }
  132. return unserialize($cachedata);
  133. }
  134. // --------------------------------------------------------------------
  135. /**
  136. * Write a query to a cache file
  137. *
  138. * @param string $sql
  139. * @param object $object
  140. * @return bool
  141. */
  142. public function write($sql, $object)
  143. {
  144. $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
  145. $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
  146. $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
  147. $filename = md5($sql);
  148. if ( ! is_dir($dir_path) && ! @mkdir($dir_path, 0750))
  149. {
  150. return FALSE;
  151. }
  152. if (write_file($dir_path.$filename, serialize($object)) === FALSE)
  153. {
  154. return FALSE;
  155. }
  156. chmod($dir_path.$filename, 0640);
  157. return TRUE;
  158. }
  159. // --------------------------------------------------------------------
  160. /**
  161. * Delete cache files within a particular directory
  162. *
  163. * @param string $segment_one
  164. * @param string $segment_two
  165. * @return void
  166. */
  167. public function delete($segment_one = '', $segment_two = '')
  168. {
  169. if ($segment_one === '')
  170. {
  171. $segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
  172. }
  173. if ($segment_two === '')
  174. {
  175. $segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
  176. }
  177. $dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
  178. delete_files($dir_path, TRUE);
  179. }
  180. // --------------------------------------------------------------------
  181. /**
  182. * Delete all existing cache files
  183. *
  184. * @return void
  185. */
  186. public function delete_all()
  187. {
  188. delete_files($this->db->cachedir, TRUE, TRUE);
  189. }
  190. }