PageRenderTime 25ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/Administration/UpgradeHistory.php

https://github.com/jacknicole/sugarcrm_dev
PHP | 288 lines | 189 code | 30 blank | 69 comment | 49 complexity | c8ad1608fb9e6d3cf345145bf6710cd1 MD5 | raw file
  1. <?php
  2. if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
  3. /*********************************************************************************
  4. * SugarCRM Community Edition is a customer relationship management program developed by
  5. * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it under
  8. * the terms of the GNU Affero General Public License version 3 as published by the
  9. * Free Software Foundation with the addition of the following permission added
  10. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  11. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  12. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  13. *
  14. * This program is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License along with
  20. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  21. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  22. * 02110-1301 USA.
  23. *
  24. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  25. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  26. *
  27. * The interactive user interfaces in modified source and object code versions
  28. * of this program must display Appropriate Legal Notices, as required under
  29. * Section 5 of the GNU Affero General Public License version 3.
  30. *
  31. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  32. * these Appropriate Legal Notices must retain the display of the "Powered by
  33. * SugarCRM" logo. If the display of the logo is not reasonably feasible for
  34. * technical reasons, the Appropriate Legal Notices must display the words
  35. * "Powered by SugarCRM".
  36. ********************************************************************************/
  37. // The history of upgrades on the system
  38. class UpgradeHistory extends SugarBean
  39. {
  40. var $new_schema = true;
  41. var $module_dir = 'Administration';
  42. // Stored fields
  43. var $id;
  44. var $filename;
  45. var $md5sum;
  46. var $type;
  47. var $version;
  48. var $status;
  49. var $date_entered;
  50. var $name;
  51. var $description;
  52. var $id_name;
  53. var $manifest;
  54. var $enabled;
  55. var $table_name = "upgrade_history";
  56. var $object_name = "UpgradeHistory";
  57. var $column_fields = Array( "id", "filename", "md5sum", "type", "version", "status", "date_entered" );
  58. var $disable_custom_fields = true;
  59. function delete()
  60. {
  61. $this->dbManager->query( "delete from " . $this->table_name . " where id = '" . $this->id . "'" );
  62. }
  63. function UpgradeHistory()
  64. {
  65. parent::SugarBean();
  66. $this->disable_row_level_security = true;
  67. }
  68. function getAllOrderBy($orderBy){
  69. $query = "SELECT id FROM " . $this->table_name . " ORDER BY ".$orderBy;
  70. return $this->getList($query);
  71. }
  72. /**
  73. * Given a name check if it exists in the table
  74. * @param name the unique key from the manifest
  75. * @param id the id of the item you are comparing to
  76. * @return upgrade_history object if found, null otherwise
  77. */
  78. function checkForExisting($patch_to_check){
  79. $uh = new UpgradeHistory();
  80. if($patch_to_check != null){
  81. if(empty($patch_to_check->id_name)){
  82. $where = " WHERE name = '$patch_to_check->name' ";
  83. }else{
  84. $where = " WHERE id_name = '$patch_to_check->id_name' ";
  85. }
  86. if(!empty($patch_to_check->id)){
  87. $where .= " AND id != '$patch_to_check->id' ";
  88. }else{
  89. $where .= " AND id is not null ";
  90. }
  91. $query = "SELECT id FROM " . $this->table_name . " ". $where;
  92. $result = $uh->db->query($query);
  93. if(empty($result)){
  94. return null;
  95. }
  96. $row = $uh->db->fetchByAssoc($result);
  97. if(empty($row)){
  98. return null;
  99. }
  100. if(!empty($row['id'])){
  101. return $uh->retrieve($row['id']);
  102. }
  103. }
  104. return null;
  105. }
  106. /**
  107. * Check if this is an upgrade, if it is then return the latest version before this installation
  108. */
  109. function determineIfUpgrade($id_name, $version){
  110. $query = "SELECT id, version FROM " . $this->table_name . " WHERE id_name = '$id_name' ORDER BY date_entered DESC";
  111. $result = $this->db->query($query);
  112. if(empty($result)){
  113. return null;
  114. }else{
  115. $temp_version = 0;
  116. $id = '';
  117. while($row = $this->db->fetchByAssoc($result))
  118. {
  119. if(!$this->is_right_version_greater(explode('.', $row['version']), explode('.', $temp_version))){
  120. $temp_version = $row['version'];
  121. $id = $row['id'];
  122. }
  123. }//end while
  124. if($this->is_right_version_greater(explode('.', $temp_version), explode('.', $version), false))
  125. return array('id' => $id, 'version' => $temp_version);
  126. else
  127. return null;
  128. }
  129. }
  130. function getAll()
  131. {
  132. $query = "SELECT id FROM " . $this->table_name . " ORDER BY date_entered desc";
  133. return $this->getList($query);
  134. }
  135. function getList($query){
  136. return( parent::build_related_list( $query, $this ) );
  137. }
  138. function findByMd5( $var_md5 )
  139. {
  140. $query = "SELECT id FROM " . $this->table_name . " where md5sum = '$var_md5'";
  141. return( parent::build_related_list( $query, $this ) );
  142. }
  143. function UninstallAvailable($patch_list, $patch_to_check)
  144. {
  145. //before we even go through the list, let us try to see if we find a match.
  146. $history_object = $this->checkForExisting($patch_to_check);
  147. if($history_object != null){
  148. if((!empty($history_object->id_name) && !empty($patch_to_check->id_name) && strcmp($history_object->id_name, $patch_to_check->id_name) == 0) || strcmp($history_object->name, $patch_to_check->name) == 0){
  149. //we have found a match
  150. //if the patch_to_check version is greater than the found version
  151. return ($this->is_right_version_greater(explode('.', $history_object->version), explode('.', $patch_to_check->version)));
  152. }else{
  153. return true;
  154. }
  155. }
  156. //we will only go through this loop if we have not found another UpgradeHistory object
  157. //with a matching unique_key in the database
  158. foreach($patch_list as $more_recent_patch)
  159. {
  160. if($more_recent_patch->id == $patch_to_check->id)
  161. break;
  162. //we will only resort to checking the files if we cannot find the unique_keys
  163. //or the unique_keys do not match
  164. $patch_to_check_backup_path = clean_path(remove_file_extension(from_html($patch_to_check->filename))).'-restore';
  165. $more_recent_patch_backup_path = clean_path(remove_file_extension(from_html($more_recent_patch->filename))).'-restore';
  166. if($this->foundConflict($patch_to_check_backup_path, $more_recent_patch_backup_path) &&
  167. ($more_recent_patch->date_entered >= $patch_to_check->date_entered)){
  168. return false;
  169. }
  170. }
  171. return true;
  172. }
  173. function foundConflict($check_path, $recent_path)
  174. {
  175. if(is_file($check_path))
  176. {
  177. if(file_exists($recent_path))
  178. return true;
  179. else
  180. return false;
  181. }
  182. elseif(is_dir($check_path))
  183. {
  184. $status = false;
  185. $d = dir( $check_path );
  186. while( $f = $d->read() )
  187. {
  188. if( $f == "." || $f == ".." )
  189. continue;
  190. $status = $this->foundConflict("$check_path/$f", "$recent_path/$f");
  191. if($status)
  192. break;
  193. }
  194. $d->close();
  195. return( $status );
  196. }
  197. return false;
  198. }
  199. /**
  200. * Given a left version and a right version, determine if the right hand side is greater
  201. *
  202. * @param left the client sugar version
  203. * @param right the server version
  204. *
  205. * return true if the right version is greater or they are equal
  206. * false if the left version is greater
  207. */
  208. function is_right_version_greater($left, $right, $equals_is_greater = true){
  209. if(count($left) == 0 && count($right) == 0){
  210. return $equals_is_greater;
  211. }
  212. else if(count($left) == 0 || count($right) == 0){
  213. return true;
  214. }
  215. else if($left[0] == $right[0]){
  216. array_shift($left);
  217. array_shift($right);
  218. return $this->is_right_version_greater($left, $right, $equals_is_greater);
  219. }
  220. else if($left[0] < $right[0]){
  221. return true;
  222. }
  223. else
  224. return false;
  225. }
  226. /**
  227. * Given an array of id_names and versions, check if the dependencies are installed
  228. *
  229. * @param dependencies an array of id_name, version to check if these dependencies are installed
  230. * on the system
  231. *
  232. * @return not_found an array of id_names that were not found to be installed on the system
  233. */
  234. function checkDependencies($dependencies = array()){
  235. $not_found = array();
  236. foreach($dependencies as $dependent){
  237. $found = false;
  238. $query = "SELECT id FROM $this->table_name WHERE id_name = '".$dependent['id_name']."'";
  239. $matches = $this->getList($query);
  240. if(0 != sizeof($matches)){
  241. foreach($matches as $match){
  242. if($this->is_right_version_greater(explode('.', $match->version), explode('.', $dependent['version']))){
  243. $found = true;
  244. break;
  245. }//fi
  246. }//rof
  247. }//fi
  248. if(!$found){
  249. $not_found[] = $dependent['id_name'];
  250. }//fi
  251. }//rof
  252. return $not_found;
  253. }
  254. function retrieve($id = -1, $encode=true,$deleted=true) {
  255. return parent::retrieve($id,$encode,false); //ignore the deleted filter. the table does not have the deleted column in it.
  256. }
  257. }
  258. ?>