PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_akeeba/akeeba/utils/statistics.php

https://bitbucket.org/kraymitchell/saiu
PHP | 206 lines | 116 code | 29 blank | 61 comment | 19 complexity | f52fd372b5174ad51690d84dfffa1186 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0, BSD-3-Clause, LGPL-2.1, GPL-3.0
  1. <?php
  2. /**
  3. * Akeeba Engine
  4. * The modular PHP5 site backup engine
  5. * @copyright Copyright (c)2009-2012 Nicholas K. Dionysopoulos
  6. * @license GNU GPL version 3 or, at your option, any later version
  7. * @package akeebaengine
  8. *
  9. */
  10. // Protection against direct access
  11. defined('AKEEBAENGINE') or die();
  12. class AEUtilStatistics extends AEAbstractObject
  13. {
  14. /** @var bool used to block multipart updating initializing the backup */
  15. private $multipart_lock = true;
  16. /** @var int The statistics record number of the current backup attempt */
  17. private $statistics_id = null;
  18. /** @var array Local cache of the stat record data */
  19. private $cached_data = array();
  20. /**
  21. * Releases the initial multipart lock
  22. */
  23. public function release_multipart_lock()
  24. {
  25. $this->multipart_lock = false;
  26. }
  27. /**
  28. * Updates the multipart status of the current backup attempt's statistics record
  29. * @param int $multipart The new multipart status
  30. */
  31. public function updateMultipart( $multipart )
  32. {
  33. if( $this->multipart_lock ) return;
  34. AEUtilLogger::WriteLog(_AE_LOG_DEBUG,'Updating multipart status to '.$multipart);
  35. // Cache this change and commit to db only after the backup is done, or failed
  36. $registry = AEFactory::getConfiguration();
  37. $registry->set('volatile.statistics.multipart', $multipart);
  38. }
  39. /**
  40. * Sets or updates the statistics record of the current backup attempt
  41. * @param array $data
  42. */
  43. public function setStatistics($data)
  44. {
  45. $ret = AEPlatform::getInstance()->set_or_update_statistics($this->statistics_id, $data, $this);
  46. if($ret !== false) {
  47. if(!is_null($ret)) {
  48. $this->statistics_id = $ret;
  49. }
  50. $this->cached_data = array_merge($this->cached_data, $data);
  51. $result = true;
  52. } elseif($ret === false) {
  53. $result = false;
  54. }
  55. return $result;
  56. }
  57. /**
  58. * Returns the statistics record ID (used in DB backup classes)
  59. * @return int
  60. */
  61. public function getId()
  62. {
  63. return $this->statistics_id;
  64. }
  65. /**
  66. * Returns a copy of the cached data
  67. * @return array
  68. */
  69. public function getRecord()
  70. {
  71. return $this->cached_data;
  72. }
  73. /**
  74. * Returns all the filenames of the backup archives for the specified stat record,
  75. * or null if the backup type is wrong or the file doesn't exist. It takes into
  76. * account the multipart nature of Split Backup Archives.
  77. *
  78. * @param array $stat The backup statistics record
  79. * @param bool $skipNonComplete Skips over backups with no files produced
  80. * @return array|null The filenames or null if it's not applicable
  81. */
  82. public static function get_all_filenames( $stat, $skipNonComplete = true )
  83. {
  84. // Shortcut for database entries marked as having no files
  85. if($stat['filesexist'] == 0) { return array(); }
  86. // Initialize
  87. $base_directory = @dirname( $stat['absolute_path'] );
  88. $base_filename = $stat['archivename'];
  89. $filenames = array( $base_filename );
  90. if(empty($base_filename))
  91. {
  92. // This is a backup with a writer which doesn't store files on the server
  93. return null;
  94. }
  95. // Calculate all the filenames for this backup
  96. if($stat['multipart'] > 1)
  97. {
  98. // Find the base filename and extension
  99. $dotpos = strrpos($base_filename, '.');
  100. $extension = substr($base_filename, $dotpos);
  101. $basefile = substr($base_filename, 0, $dotpos);
  102. // Calculate the multiple names
  103. $multipart = $stat['multipart'];
  104. for($i = 1; $i < $multipart; $i++ )
  105. {
  106. // Note: For $multipart = 10, it will produce i.e. .z01 through .z10
  107. // This is intentional. If the backup aborts and multipart=1, we
  108. // might be stuck with a .z01 file instead of a .zip. So do not
  109. // change the less than or equal with a straight less than.
  110. $filenames[] = $basefile.substr($extension,0,2).sprintf('%02d', $i);
  111. }
  112. }
  113. // Check if the files exist, otherwise attempt to provide relocated filename
  114. $ret = array();
  115. $ds = DIRECTORY_SEPARATOR;
  116. // $test_file is the first file which must have been created
  117. $test_file = count($filenames) == 1 ? $filenames[0] : $filenames[1];
  118. if (
  119. (!@file_exists($base_directory.$ds.$test_file)) ||
  120. (!is_dir($base_directory))
  121. )
  122. {
  123. // The test file wasn't detected. Use the configured output directory.
  124. $registry = AEFactory::getConfiguration();
  125. $base_directory = $registry->get('akeeba.basic.output_directory');
  126. }
  127. foreach($filenames as $filename)
  128. {
  129. // Turn relative path to absolute
  130. $filename = $base_directory.$ds.$filename;
  131. // Return the new filename IF IT EXISTS!
  132. if(!@file_exists($filename)) $filename = '';
  133. // Do not return filename for invalid backups
  134. if( !empty($filename) )
  135. {
  136. $ret[] = $filename;
  137. }
  138. }
  139. // Edge case: still running backups, we have to brute force the scan
  140. // of existing files (multipart may be lying)
  141. if($stat['status'] == 'run') {
  142. $base_filename = $stat['archivename'];
  143. $dotpos = strrpos($base_filename, '.');
  144. $extension = substr($base_filename, $dotpos);
  145. $basefile = substr($base_filename, 0, $dotpos);
  146. $registry = AEFactory::getConfiguration();
  147. $dirs = array(
  148. @dirname( $stat['absolute_path'] ),
  149. $registry->get('akeeba.basic.output_directory')
  150. );
  151. // Look for base file
  152. foreach($dirs as $dir) {
  153. if(@file_exists($dir.$ds.$base_filename)) {
  154. $ret[] = $dir.$ds.$base_filename;
  155. break;
  156. }
  157. }
  158. // Look for added files
  159. $found = true;
  160. $i = 0;
  161. while($found) {
  162. $i++;
  163. $found = false;
  164. $part_file_name = $basefile.substr($extension,0,2).sprintf('%02d', $i);
  165. foreach($dirs as $dir) {
  166. if(@file_exists($dir.$ds.$part_file_name)) {
  167. $ret[] = $dir.$ds.$part_file_name;
  168. $found = true;
  169. break;
  170. }
  171. }
  172. }
  173. }
  174. if((count($ret) == 0) && $skipNonComplete) $ret = null;
  175. return $ret;
  176. }
  177. }