PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/system/expressionengine/libraries/File_integrity.php

https://bitbucket.org/studiobreakfast/sync
PHP | 247 lines | 141 code | 42 blank | 64 comment | 24 complexity | cd85cfcc0361bfca41b08b06a978b5bb MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author EllisLab Dev Team
  7. * @copyright Copyright (c) 2003 - 2012, EllisLab, Inc.
  8. * @license http://expressionengine.com/user_guide/license.html
  9. * @link http://expressionengine.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine Core File Integrity Class
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Core
  19. * @category Core
  20. * @author EllisLab Dev Team
  21. * @link http://expressionengine.com
  22. */
  23. class File_integrity {
  24. var $emailed = array();
  25. var $checksums = array();
  26. /**
  27. * Constructor
  28. *
  29. * @access public
  30. */
  31. function __construct()
  32. {
  33. $this->EE =& get_instance();
  34. }
  35. // --------------------------------------------------------------------
  36. /**
  37. * Check all bootstrap files
  38. *
  39. * @access public
  40. */
  41. function check_bootstrap_files($return_site_id = FALSE)
  42. {
  43. $this->EE->load->model('site_model');
  44. $sites = $this->EE->site_model->get_site();
  45. $sites = $sites->result_array();
  46. $bootstraps = array();
  47. // Retrieve all of the bootstrap files
  48. foreach($sites as $site)
  49. {
  50. if ( ! isset($site['site_bootstrap_checksums']))
  51. {
  52. continue;
  53. }
  54. $data = base64_decode($site['site_bootstrap_checksums']);
  55. if ( ! is_string($data) OR substr($data, 0, 2) != 'a:')
  56. {
  57. continue;
  58. }
  59. $data = unserialize($data);
  60. if ( ! isset($data['emailed']) OR ! is_array($data['emailed']))
  61. {
  62. $data['emailed'] = array();
  63. }
  64. $bootstraps[$site['site_id']] = $data;
  65. }
  66. $altered = array();
  67. $removed = array();
  68. $update_db = array();
  69. // Check them all
  70. foreach($bootstraps as $site_id => $checksums)
  71. {
  72. foreach($checksums as $path => $checksum)
  73. {
  74. if ($path == 'emailed')
  75. {
  76. continue;
  77. }
  78. if ( ! file_exists($path))
  79. {
  80. $removed[$site_id][] = $path;
  81. }
  82. else
  83. {
  84. $this->checksums[$site_id][$path] = $checksum;
  85. $current = md5_file($path);
  86. if ($current != $checksum)
  87. {
  88. if ($return_site_id)
  89. {
  90. $altered[$site_id][] = $path;
  91. }
  92. else
  93. {
  94. $altered[] = $path;
  95. }
  96. }
  97. elseif (($email_key = array_search($path, $checksums['emailed'])) !== FALSE)
  98. {
  99. // they were emailed about it and restored it without
  100. // hitting the 'accept changes' link on the homepage
  101. unset($bootstraps[$site_id]['emailed'][$email_key]);
  102. $update_db[] = $site_id;
  103. }
  104. }
  105. }
  106. $this->emailed = array_unique(array_merge($this->emailed, $bootstraps[$site_id]['emailed']));
  107. }
  108. // Remove obsolete files from the db
  109. foreach($removed as $site_id => $paths)
  110. {
  111. foreach($paths as $path)
  112. {
  113. if (isset($bootstraps[$site_id][$path]))
  114. {
  115. unset($bootstraps[$site_id][$path]);
  116. $update_db[] = $site_id;
  117. }
  118. }
  119. }
  120. // Update the db if we detected changes
  121. foreach(array_unique($update_db) as $site_id)
  122. {
  123. $this->_update_config($bootstraps[$site_id], $site_id);
  124. }
  125. // Any changes? report them
  126. if (count($altered))
  127. {
  128. return $altered;
  129. }
  130. return FALSE;
  131. }
  132. // --------------------------------------------------------------------
  133. /**
  134. * Add a bootstrap file we didn't know about, or explicitly update
  135. * a checksum (when accepting a change).
  136. *
  137. * @access public
  138. */
  139. function send_site_admin_warning($altered)
  140. {
  141. $affected_paths = array_diff($altered, $this->emailed);
  142. if (count($affected_paths))
  143. {
  144. $this->EE->load->library('notifications');
  145. $this->EE->notifications->send_checksum_notification($affected_paths);
  146. // add them to the existing emailed and update
  147. $affected_paths = array_unique(array_merge($this->emailed, $affected_paths));
  148. foreach($this->checksums as $site_id => $checksums)
  149. {
  150. $checksum_paths = array_keys($checksums);
  151. // did we send emails for this site id?
  152. $old_emailed = array_intersect($checksum_paths, $this->emailed);
  153. $new_emailed = array_intersect($checksum_paths, $affected_paths);
  154. if (count($new_emailed))
  155. {
  156. $checksums['emailed'] = array_unique(array_merge($old_emailed, $new_emailed));
  157. $this->_update_config($checksums, $site_id);
  158. }
  159. }
  160. }
  161. }
  162. // --------------------------------------------------------------------
  163. /**
  164. * Add a bootstrap file we didn't know about, or explicitly update
  165. * a checksum (when accepting a change).
  166. *
  167. * @access public
  168. */
  169. function create_bootstrap_checksum($path = '', $site_id = '')
  170. {
  171. $checksums = $this->EE->config->item('site_bootstrap_checksums');
  172. $site_id = ($site_id != '') ? $site_id : $this->EE->config->item('site_id');
  173. if (REQ == 'CP' && $path && file_exists($path))
  174. {
  175. $checksums = $this->checksums[$site_id]; // should already have called check_bootstrap_files
  176. $checksums[$path] = md5_file($path);
  177. $checksums['emailed'] = array();
  178. $this->_update_config($checksums, $site_id);
  179. }
  180. elseif (REQ != 'CP' && ! array_key_exists(FCPATH.SELF, $checksums))
  181. {
  182. $checksums[FCPATH.SELF] = md5_file(FCPATH.SELF);
  183. $this->_update_config($checksums, $site_id);
  184. }
  185. }
  186. // --------------------------------------------------------------------
  187. /**
  188. * Update the bootstrap column in the db
  189. *
  190. * @access private
  191. */
  192. function _update_config($checksums, $site_id)
  193. {
  194. if ($site_id == $this->EE->config->item('site_id'))
  195. {
  196. $this->EE->config->config['site_bootstrap_checksums'] = $checksums;
  197. }
  198. $this->EE->db->query($this->EE->db->update_string('exp_sites',
  199. array('site_bootstrap_checksums' => base64_encode(serialize($checksums))),
  200. "site_id = '".$this->EE->db->escape_str($site_id)."'"));
  201. }
  202. }
  203. // END File_integrity class
  204. /* End of file File_integrity.php */
  205. /* Location: ./system/expressionengine/libraries/File_integrity.php */