/craft/app/helpers/UpdateHelper.php

https://gitlab.com/madebycloud/derekman · PHP · 326 lines · 192 code · 39 blank · 95 comment · 26 complexity · 11e7776ad931a4b065d3fbc0d8ac6c1f MD5 · raw file

  1. <?php
  2. namespace Craft;
  3. /**
  4. * Class UpdateHelper
  5. *
  6. * @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
  7. * @copyright Copyright (c) 2014, Pixel & Tonic, Inc.
  8. * @license http://buildwithcraft.com/license Craft License Agreement
  9. * @see http://buildwithcraft.com
  10. * @package craft.app.helpers
  11. * @since 1.0
  12. */
  13. class UpdateHelper
  14. {
  15. // Properties
  16. // =========================================================================
  17. /**
  18. * @var
  19. */
  20. private static $_manifestData;
  21. // Public Methods
  22. // =========================================================================
  23. /**
  24. * @param $manifestData
  25. *
  26. * @return null
  27. */
  28. public static function rollBackFileChanges($manifestData)
  29. {
  30. foreach ($manifestData as $row)
  31. {
  32. if (static::isManifestVersionInfoLine($row))
  33. {
  34. continue;
  35. }
  36. if (static::isManifestMigrationLine($row))
  37. {
  38. continue;
  39. }
  40. $rowData = explode(';', $row);
  41. $file = IOHelper::normalizePathSeparators(craft()->path->getAppPath().$rowData[0]);
  42. // It's a folder
  43. if (static::isManifestLineAFolder($file))
  44. {
  45. $folderPath = static::cleanManifestFolderLine($file);
  46. if (IOHelper::folderExists($folderPath.'.bak'))
  47. {
  48. IOHelper::rename($folderPath, $folderPath.'-tmp');
  49. IOHelper::rename($folderPath.'.bak', $folderPath);
  50. IOHelper::clearFolder($folderPath.'-tmp');
  51. IOHelper::deleteFolder($folderPath.'-tmp');
  52. }
  53. }
  54. // It's a file.
  55. else
  56. {
  57. if (IOHelper::fileExists($file.'.bak'))
  58. {
  59. IOHelper::rename($file.'.bak', $file);
  60. }
  61. }
  62. }
  63. }
  64. /**
  65. * Rolls back any changes made to the DB during the update process.
  66. *
  67. * @param $backupPath
  68. *
  69. * @return null
  70. */
  71. public static function rollBackDatabaseChanges($backupPath)
  72. {
  73. $dbBackup = new DbBackup();
  74. $fullBackupPath = craft()->path->getDbBackupPath().$backupPath.'.sql';
  75. $dbBackup->restore($fullBackupPath);
  76. }
  77. /**
  78. * @param $manifestData
  79. * @param $sourceTempFolder
  80. *
  81. * @return bool
  82. */
  83. public static function doFileUpdate($manifestData, $sourceTempFolder)
  84. {
  85. try
  86. {
  87. foreach ($manifestData as $row)
  88. {
  89. if (static::isManifestVersionInfoLine($row))
  90. {
  91. continue;
  92. }
  93. $folder = false;
  94. $rowData = explode(';', $row);
  95. if (static::isManifestLineAFolder($rowData[0]))
  96. {
  97. $folder = true;
  98. $tempPath = static::cleanManifestFolderLine($rowData[0]);
  99. }
  100. else
  101. {
  102. $tempPath = $rowData[0];
  103. }
  104. $destFile = IOHelper::normalizePathSeparators(craft()->path->getAppPath().$tempPath);
  105. $sourceFile = IOHelper::getRealPath(IOHelper::normalizePathSeparators($sourceTempFolder.'/app/'.$tempPath));
  106. switch (trim($rowData[1]))
  107. {
  108. // update the file
  109. case PatchManifestFileAction::Add:
  110. {
  111. if ($folder)
  112. {
  113. Craft::log('Updating folder: '.$destFile, LogLevel::Info, true);
  114. $tempFolder = rtrim($destFile, '/').StringHelper::UUID().'/';
  115. $tempTempFolder = rtrim($destFile, '/').'-tmp/';
  116. IOHelper::createFolder($tempFolder);
  117. IOHelper::copyFolder($sourceFile, $tempFolder);
  118. IOHelper::rename($destFile, $tempTempFolder);
  119. IOHelper::rename($tempFolder, $destFile);
  120. IOHelper::clearFolder($tempTempFolder);
  121. IOHelper::deleteFolder($tempTempFolder);
  122. }
  123. else
  124. {
  125. Craft::log('Updating file: '.$destFile, LogLevel::Info, true);
  126. IOHelper::copyFile($sourceFile, $destFile);
  127. }
  128. break;
  129. }
  130. }
  131. }
  132. }
  133. catch (\Exception $e)
  134. {
  135. Craft::log('Error updating files: '.$e->getMessage(), LogLevel::Error);
  136. UpdateHelper::rollBackFileChanges($manifestData);
  137. return false;
  138. }
  139. return true;
  140. }
  141. /**
  142. * @param $line
  143. *
  144. * @return bool
  145. */
  146. public static function isManifestVersionInfoLine($line)
  147. {
  148. if ($line[0] == '#' && $line[1] == '#')
  149. {
  150. return true;
  151. }
  152. return false;
  153. }
  154. /**
  155. * Returns the local build number from the given manifest file.
  156. *
  157. * @param $manifestData
  158. *
  159. * @return bool|string
  160. */
  161. public static function getLocalBuildFromManifest($manifestData)
  162. {
  163. if (static::isManifestVersionInfoLine($manifestData[0]))
  164. {
  165. $parts = explode(';', $manifestData[0]);
  166. $index = mb_strrpos($parts[0], '.');
  167. $version = mb_substr($parts[0], $index + 1);
  168. return $version;
  169. }
  170. return false;
  171. }
  172. /**
  173. * Returns the local version number from the given manifest file.
  174. *
  175. * @param $manifestData
  176. *
  177. * @return bool|string
  178. */
  179. public static function getLocalVersionFromManifest($manifestData)
  180. {
  181. if (static::isManifestVersionInfoLine($manifestData[0]))
  182. {
  183. $parts = explode(';', $manifestData[0]);
  184. $index = mb_strrpos($parts[0], '.');
  185. $build = mb_substr($parts[0], 2, $index - 2);
  186. return $build;
  187. }
  188. return false;
  189. }
  190. /**
  191. * Return true if line is a manifest migration line.
  192. *
  193. * @param $line
  194. *
  195. * @return bool
  196. */
  197. public static function isManifestMigrationLine($line)
  198. {
  199. if (mb_strpos($line, 'migrations/') !== false)
  200. {
  201. return true;
  202. }
  203. return false;
  204. }
  205. /**
  206. * Returns the relevant lines from the update manifest file starting with the current local version/build.
  207. *
  208. * @param $manifestDataPath
  209. *
  210. * @throws Exception
  211. * @return array
  212. */
  213. public static function getManifestData($manifestDataPath)
  214. {
  215. if (static::$_manifestData == null)
  216. {
  217. if (IOHelper::fileExists($manifestDataPath.'/craft_manifest'))
  218. {
  219. // get manifest file
  220. $manifestFileData = IOHelper::getFileContents($manifestDataPath.'/craft_manifest', true);
  221. if ($manifestFileData === false)
  222. {
  223. throw new Exception(Craft::t('There was a problem reading the update manifest data.'));
  224. }
  225. // Remove any trailing empty newlines
  226. if ($manifestFileData[count($manifestFileData) - 1] == '')
  227. {
  228. array_pop($manifestFileData);
  229. }
  230. $manifestData = array_map('trim', $manifestFileData);
  231. $updateModel = craft()->updates->getUpdates();
  232. // Only use the manifest data starting from the local version
  233. for ($counter = 0; $counter < count($manifestData); $counter++)
  234. {
  235. if (mb_strpos($manifestData[$counter], '##'.$updateModel->app->localVersion.'.'.$updateModel->app->localBuild) !== false)
  236. {
  237. break;
  238. }
  239. }
  240. $manifestData = array_slice($manifestData, $counter);
  241. static::$_manifestData = $manifestData;
  242. }
  243. }
  244. return static::$_manifestData;
  245. }
  246. /**
  247. * @param $uid
  248. *
  249. * @return string
  250. */
  251. public static function getUnzipFolderFromUID($uid)
  252. {
  253. return craft()->path->getTempPath().$uid.'/';
  254. }
  255. /**
  256. * @param $uid
  257. *
  258. * @return string
  259. */
  260. public static function getZipFileFromUID($uid)
  261. {
  262. return craft()->path->getTempPath().$uid.'.zip';
  263. }
  264. /**
  265. * @param $line
  266. *
  267. * @return bool
  268. */
  269. public static function isManifestLineAFolder($line)
  270. {
  271. if (mb_substr($line, -1) == '*')
  272. {
  273. return true;
  274. }
  275. return false;
  276. }
  277. /**
  278. * @param $line
  279. *
  280. * @return string
  281. */
  282. public static function cleanManifestFolderLine($line)
  283. {
  284. $line = rtrim($line, '*');
  285. return rtrim($line, '/');
  286. }
  287. }