advagg.cache.inc

  1. cis7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  2. cle7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  3. ecd7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  4. elmsmedia7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  5. harmony7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  6. icor7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  7. meedjum_blog7 sites/all/modules/ulmus/advagg/advagg.cache.inc
  8. mooc7 sites/all/modules/ulmus/advagg/advagg.cache.inc

Advanced CSS/JS aggregation module.

Functions used for clearing caches and killing files.

Functions

Namesort descending Description
advagg_cleanup_semaphore_table Delete orphaned/expired advagg locks from the semaphore database table.
advagg_delete_files_if_stale Given an array of files remove that file if atime is grater than 30 days.
advagg_delete_stale_aggregates Scan CSS/JS advagg dir & remove that file if atime is grater than 30 days.
advagg_flush_all_cache_bins Perform a cache_clear_all on all bins returned by advagg_flush_caches(TRUE).
advagg_get_aggregates_using_file Given a filename hash get back all aggregates that include it.
advagg_increment_global_counter Increment the advagg_global_counter variable by one.
advagg_push_new_changes Flush the correct caches so CSS/JS changes go live.
advagg_remove_all_aggregated_files Remove all files from the advagg CSS/JS directories.
advagg_remove_missing_files_from_db Scan for missing files and remove the associated entries in the database.
advagg_remove_old_unused_aggregates Delete aggregates that have not been accessed in the last 6 weeks.
advagg_scan_for_changes Uses the database to scan CSS/JS files for changes.

File

sites/all/modules/ulmus/advagg/advagg.cache.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Advanced CSS/JS aggregation module.
  5. *
  6. * Functions used for clearing caches and killing files.
  7. */
  8. // Cache and file flushing.
  9. /**
  10. * Uses the database to scan CSS/JS files for changes.
  11. *
  12. * @return array
  13. * array of files that have changed.
  14. */
  15. function advagg_scan_for_changes() {
  16. // Get all files stored in the database and filesystem.
  17. $files_that_have_changed = array();
  18. $result = db_select('advagg_files', 'af')
  19. ->fields('af')
  20. ->execute();
  21. if (!empty($result)) {
  22. module_load_include('inc', 'advagg', 'advagg');
  23. foreach ($result as $row) {
  24. $row = (array) $row;
  25. // Get filesystem data.
  26. $info = advagg_get_info_on_file($row['filename'], TRUE);
  27. // Select the keys to compare.
  28. $keys_to_compare = array(
  29. 'filesize',
  30. 'content_hash',
  31. 'linecount',
  32. );
  33. $changed = FALSE;
  34. foreach ($keys_to_compare as $key) {
  35. if ($row[$key] != $info[$key]) {
  36. $changed = TRUE;
  37. break;
  38. }
  39. }
  40. // Compare mtime if it is not zero.
  41. if (!$changed && !empty($info['mtime']) && $row['mtime'] != $info['mtime']) {
  42. $changed = TRUE;
  43. }
  44. if (!$changed) {
  45. // Call hook_advagg_scan_for_changes().
  46. $changes_array = module_invoke_all('advagg_scan_for_changes', $row['filename']);
  47. if (is_array($changes_array)) {
  48. foreach ($changes_array as $value) {
  49. if (!empty($value)) {
  50. $changed = TRUE;
  51. break;
  52. }
  53. }
  54. }
  55. }
  56. // If file has changed, add it to the array.
  57. if ($changed) {
  58. $files_that_have_changed[$row['filename']] = $info;
  59. // Remove non advagg core attributes so advagg contrib can react to new
  60. // changes to the file.
  61. $keys_to_keep = array(
  62. 'filesize' => 1,
  63. 'mtime' => 1,
  64. 'filename_hash' => 1,
  65. 'content_hash' => 1,
  66. 'linecount' => 1,
  67. );
  68. $info = array_intersect_key($info, $keys_to_keep);
  69. // Save results.
  70. $filename_hashes = &drupal_static('advagg_get_info_on_file');
  71. $cache_id = 'advagg:file:' . $info['filename_hash'];
  72. $filename_hashes[$cache_id] = $info;
  73. cache_set($cache_id, $info, 'cache_advagg_info', CACHE_PERMANENT);
  74. }
  75. }
  76. }
  77. return $files_that_have_changed;
  78. }
  79. /**
  80. * Flush the correct caches so CSS/JS changes go live.
  81. *
  82. * @return array
  83. * array of files that have changed and caches flushed.
  84. */
  85. function advagg_push_new_changes() {
  86. // Scan the file system for changes to CSS/JS files.
  87. $files = advagg_scan_for_changes();
  88. $results = array();
  89. // If something changed, flush the correct caches so that change goes out.
  90. if (!empty($files)) {
  91. $types = array();
  92. module_load_include('inc', 'advagg', 'advagg');
  93. foreach ($files as $filename => $meta_data) {
  94. $ext = pathinfo($filename, PATHINFO_EXTENSION);
  95. // Lookup the aggregates that use this file.
  96. $aggregates = advagg_get_aggregates_using_file($meta_data['filename_hash']);
  97. // Get the cache ids.
  98. $cache_ids = array();
  99. foreach ($aggregates as $row) {
  100. $cache_ids[] = $row['cid'];
  101. }
  102. $cache_hits = cache_get_multiple($cache_ids, 'cache_advagg_info');
  103. if (!empty($cache_hits)) {
  104. foreach ($cache_hits as $cid => $data) {
  105. cache_clear_all($cid, 'cache_advagg_info', FALSE);
  106. }
  107. }
  108. $types[$ext] = TRUE;
  109. $results[$filename] = array($aggregates, $cache_hits);
  110. // Update database.
  111. advagg_insert_update_files(array($filename => $meta_data), $ext);
  112. }
  113. // Let other modules know about the changed files.
  114. // Call hook_advagg_changed_files().
  115. module_invoke_all('advagg_changed_files', $files, $types);
  116. // Clear out the full aggregates cache.
  117. foreach ($types as $ext => $bool) {
  118. cache_clear_all('advagg:' . $ext . ':', 'cache_advagg_aggregates', TRUE);
  119. }
  120. }
  121. // Return what was done.
  122. return $results;
  123. }
  124. /**
  125. * Given a filename hash get back all aggregates that include it.
  126. *
  127. * @param string $filename_hash
  128. * hash of the filename.
  129. *
  130. * @return array
  131. * array of aggregates that use this file.
  132. */
  133. function advagg_get_aggregates_using_file($filename_hash) {
  134. // Create join query for the advagg_aggregates_versions table.
  135. $subquery_aggregates_versions = db_select('advagg_aggregates_versions', 'aav')
  136. ->fields('aav')
  137. ->condition('aav.atime', 0, '>');
  138. // Create main query for the advagg_aggregates table.
  139. $query = db_select('advagg_aggregates', 'aa')
  140. ->condition('aa.filename_hash', $filename_hash);
  141. $query->join($subquery_aggregates_versions, 'aav', 'aa.aggregate_filenames_hash=aav.aggregate_filenames_hash');
  142. $query->comment('Query called from ' . __FUNCTION__ . '()');
  143. $query = $query->fields('aav', array('aggregate_filenames_hash', 'aggregate_contents_hash'))
  144. ->execute();
  145. // Put results into $aggregates array.
  146. $aggregates = array();
  147. foreach ($query as $row) {
  148. $row = (array) $row;
  149. $row['cid'] = 'advagg:db:' . $row['aggregate_filenames_hash'] . ADVAGG_SPACE . $row['aggregate_contents_hash'];
  150. $aggregates[] = $row;
  151. }
  152. return $aggregates;
  153. }
  154. /**
  155. * Scan CSS/JS advagg dir & remove that file if atime is grater than 30 days.
  156. *
  157. * @return array
  158. * array of files that got removed.
  159. */
  160. function advagg_delete_stale_aggregates() {
  161. list($css_path, $js_path) = advagg_get_root_files_dir();
  162. // Get a list of files.
  163. $css_files = file_scan_directory($css_path[0], '/.*/', array('nomask' => '/(\.\.?|CVS|\.gz)$/'));
  164. $js_files = file_scan_directory($js_path[0], '/.*/', array('nomask' => '/(\.\.?|CVS|\.gz)/'));
  165. // Make the advagg_get_hashes_from_filename() function available.
  166. module_load_include('inc', 'advagg', 'advagg.missing');
  167. $css_files = advagg_delete_files_if_stale($css_files);
  168. $js_files = advagg_delete_files_if_stale($js_files);
  169. return array($css_files, $js_files);
  170. }
  171. /**
  172. * Given an array of files remove that file if atime is grater than 30 days.
  173. *
  174. * @param array $files
  175. * Array of files returned by file_scan_directory.
  176. *
  177. * @return array
  178. * array of files that got removed.
  179. */
  180. function advagg_delete_files_if_stale($files) {
  181. // Array used to record what files were deleted.
  182. $kill_list = array();
  183. foreach ($files as $uri => $file) {
  184. // Get info on file.
  185. $filename = $file->filename;
  186. $data = advagg_get_hashes_from_filename($filename);
  187. if (is_array($data)) {
  188. list($type, $aggregate_filenames_hash, $aggregate_contents_hash, $aggregate_settings) = $data;
  189. }
  190. else {
  191. // Can not get data on file, remove it.
  192. file_unmanaged_delete($uri);
  193. if (file_exists($uri . '.gz')) {
  194. file_unmanaged_delete($uri . '.gz');
  195. }
  196. $kill_list[] = $uri;
  197. continue;
  198. }
  199. // Get atime of file.
  200. $atime = advagg_get_atime($aggregate_filenames_hash, $aggregate_contents_hash, $uri);
  201. if (empty($atime)) {
  202. file_unmanaged_delete($uri);
  203. if (file_exists($uri . '.gz')) {
  204. file_unmanaged_delete($uri . '.gz');
  205. }
  206. $kill_list[] = $uri;
  207. continue;
  208. }
  209. // Default stale file threshold is 30 days.
  210. if (REQUEST_TIME - $atime > variable_get('drupal_stale_file_threshold', 2592000)) {
  211. file_unmanaged_delete($uri);
  212. if (file_exists($uri . '.gz')) {
  213. file_unmanaged_delete($uri . '.gz');
  214. }
  215. $kill_list[] = $uri;
  216. }
  217. }
  218. return $kill_list;
  219. }
  220. /**
  221. * Perform a cache_clear_all on all bins returned by advagg_flush_caches(TRUE).
  222. */
  223. function advagg_flush_all_cache_bins() {
  224. $bins = advagg_flush_caches(TRUE);
  225. foreach ($bins as $bin) {
  226. cache_clear_all('*', $bin, TRUE);
  227. }
  228. }
  229. /**
  230. * Remove all files from the advagg CSS/JS directories.
  231. *
  232. * @return array
  233. * array of all files removed.
  234. */
  235. function advagg_remove_all_aggregated_files() {
  236. list($css_path, $js_path) = advagg_get_root_files_dir();
  237. // Find all files in the advagg CSS/JS directories and delete them.
  238. $css_files = file_scan_directory($css_path[0], '/.*/', array('callback' => 'file_unmanaged_delete'));
  239. $js_files = file_scan_directory($js_path[0], '/.*/', array('callback' => 'file_unmanaged_delete'));
  240. return array($css_files, $js_files);
  241. }
  242. /**
  243. * Increment the advagg_global_counter variable by one.
  244. *
  245. * @todo Allow this value to be kept in sync across a multisite.
  246. *
  247. * @return int
  248. * New value of advagg_global_counter.
  249. */
  250. function advagg_increment_global_counter() {
  251. $new_value = advagg_get_global_counter() + 1;
  252. variable_set('advagg_global_counter', $new_value);
  253. return $new_value;
  254. }
  255. /**
  256. * Scan for missing files and remove the associated entries in the database.
  257. *
  258. * @return array
  259. * Array of what files were cleared out of the database.
  260. */
  261. function advagg_remove_missing_files_from_db() {
  262. $missing_files = array();
  263. $deleted = array();
  264. // Get all files stored in the database.
  265. $result = db_select('advagg_files', 'af')
  266. ->fields('af')
  267. ->execute();
  268. if (empty($result)) {
  269. return $deleted;
  270. }
  271. // Find missing files.
  272. module_load_include('inc', 'advagg', 'advagg');
  273. foreach ($result as $row) {
  274. $row = (array) $row;
  275. $info = advagg_get_info_on_file($row['filename'], TRUE);
  276. // Make sure file exists.
  277. if (empty($info['content_hash'])) {
  278. $info += advagg_get_aggregates_using_file($info['filename_hash']);
  279. $missing_files[$row['filename']] = $info;
  280. continue;
  281. }
  282. }
  283. if (empty($missing_files)) {
  284. return $deleted;
  285. }
  286. // Remove missing file database entries.
  287. $types = array();
  288. foreach ($missing_files as $filename => $data) {
  289. // Setup this run.
  290. $ext = pathinfo($filename, PATHINFO_EXTENSION);
  291. $advagg_files_del = 0;
  292. $advagg_aggregates_del = 0;
  293. $advagg_aggregates_versions_del = 0;
  294. $clean_sweep = TRUE;
  295. $filename_hash = '';
  296. // Scan the data.
  297. foreach ($data as $key => $values) {
  298. if (!is_numeric($key)) {
  299. $filename_hash = $values;
  300. }
  301. else {
  302. // Remove the entry from the database if this aggregate has not been
  303. // accessed in the last 2 weeks.
  304. $can_delete = db_delete('advagg_aggregates_versions')
  305. ->condition('aggregate_filenames_hash', $values['aggregate_filenames_hash'])
  306. ->condition('atime', REQUEST_TIME - 1209600, '<')
  307. ->execute();
  308. if ($can_delete > 0) {
  309. $advagg_aggregates_versions_del += $can_delete;
  310. $advagg_aggregates_del += db_delete('advagg_aggregates')
  311. ->condition('aggregate_filenames_hash', $values['aggregate_filenames_hash'])
  312. ->execute();
  313. }
  314. else {
  315. $clean_sweep = FALSE;
  316. }
  317. // Clear the cache.
  318. cache_clear_all($values['cid'], 'cache_advagg_info', FALSE);
  319. }
  320. }
  321. // Remove the file entry if all aggregates referencing it have been removed.
  322. if ($clean_sweep) {
  323. $advagg_files_del += db_delete('advagg_files')
  324. ->condition('filename_hash', $filename_hash)
  325. ->execute();
  326. }
  327. // Add info to array.
  328. $types[$ext] = TRUE;
  329. $deleted[$filename] = array(
  330. 'advagg_files' => $advagg_files_del,
  331. 'advagg_aggregates_versions' => $advagg_aggregates_versions_del,
  332. 'advagg_aggregates' => $advagg_aggregates_del,
  333. );
  334. }
  335. // If something was deleted, clear the full aggregates cache.
  336. if (!empty($deleted)) {
  337. foreach ($types as $ext => $bool) {
  338. cache_clear_all('advagg:' . $ext . ':', 'cache_advagg_aggregates', TRUE);
  339. }
  340. }
  341. // Return what was deleted.
  342. return $deleted;
  343. }
  344. /**
  345. * Delete aggregates that have not been accessed in the last 6 weeks.
  346. *
  347. * @return int
  348. * Count of the number of rows removed from the databases.
  349. */
  350. function advagg_remove_old_unused_aggregates() {
  351. $advagg_aggregates_versions_del = 0;
  352. $advagg_aggregates_del = 0;
  353. // Find orphaned aggregate versions entries.
  354. // Create join query.
  355. $subquery_aggregates = db_select('advagg_aggregates', 'aa')
  356. ->fields('aa', array('aggregate_filenames_hash'));
  357. // Create main query.
  358. $query = db_select('advagg_aggregates_versions', 'aav')
  359. ->fields('aav', array('aggregate_filenames_hash'))
  360. ->groupBy('aav.aggregate_filenames_hash');
  361. $query->leftjoin($subquery_aggregates, 'aa', 'aa.aggregate_filenames_hash=aav.aggregate_filenames_hash');
  362. $query->isNull('aa.aggregate_filenames_hash');
  363. $query->comment('Query called from ' . __FUNCTION__ . '()');
  364. $results = $query->execute();
  365. // If we have an orphaned db entry, delete it.
  366. if (!empty($results)) {
  367. foreach ($results as $row) {
  368. $advagg_aggregates_versions_del += db_delete('advagg_aggregates_versions')
  369. ->condition('aggregate_filenames_hash', $row->aggregate_filenames_hash)
  370. ->execute();
  371. }
  372. }
  373. // Delete aggregate versions that have not been accessed in the last 6 weeks.
  374. $advagg_aggregates_versions_del += db_delete('advagg_aggregates_versions')
  375. ->condition('atime', REQUEST_TIME - 3628800, '<')
  376. ->execute();
  377. // See if any aggregates are orphaned now.
  378. // Create join query.
  379. $subquery_aggregates_versions = db_select('advagg_aggregates_versions', 'aav')
  380. ->fields('aav', array('aggregate_filenames_hash'));
  381. // Create main query.
  382. $query = db_select('advagg_aggregates', 'aa')
  383. ->fields('aa', array('aggregate_filenames_hash'))
  384. ->groupBy('aa.aggregate_filenames_hash');
  385. $query->leftjoin($subquery_aggregates_versions, 'aav', 'aa.aggregate_filenames_hash=aav.aggregate_filenames_hash');
  386. $query->isNull('aav.aggregate_filenames_hash');
  387. $query->comment('Query called from ' . __FUNCTION__ . '()');
  388. $results = $query->execute();
  389. // If we have an orphaned db entry, delete it.
  390. if (!empty($results)) {
  391. foreach ($results as $row) {
  392. $advagg_aggregates_del += db_delete('advagg_aggregates')
  393. ->condition('aggregate_filenames_hash', $row->aggregate_filenames_hash)
  394. ->execute();
  395. }
  396. }
  397. // Return the total count of entires removed from the database.
  398. return $advagg_aggregates_versions_del + $advagg_aggregates_del;
  399. }
  400. /**
  401. * Delete orphaned/expired advagg locks from the semaphore database table.
  402. *
  403. * @return int
  404. * Count of the number of rows removed from the databases.
  405. */
  406. function advagg_cleanup_semaphore_table() {
  407. // Let expiration times vary by 5 minutes.
  408. $fuzz_factor = 300;
  409. $results = db_delete('semaphore')
  410. ->condition('name', db_like('advagg_') . '%', 'LIKE')
  411. ->condition('expire', REQUEST_TIME - $fuzz_factor, '<')
  412. ->execute();
  413. return $results;
  414. }
Error | ELMSLN API

Error

×

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/elmsln_community/api.elmsln.org/includes/common.inc:2791) in drupal_send_headers() (line 1499 of /var/www/html/elmsln_community/api.elmsln.org/includes/bootstrap.inc).
  • Error: Call to undefined function apc_delete() in DrupalAPCCache->clear() (line 289 of /var/www/html/elmsln_community/api.elmsln.org/sites/all/modules/apc/drupal_apc_cache.inc).
The website encountered an unexpected error. Please try again later.