]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Administration/UpgradeHistory.php
Release 6.1.4
[Github/sugarcrm.git] / modules / Administration / UpgradeHistory.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM 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
38
39
40
41
42 // The history of upgrades on the system
43 class UpgradeHistory extends SugarBean
44 {
45         var $new_schema = true;
46         var $module_dir = 'Administration';
47         
48         // Stored fields
49         var $id;
50         var $filename;
51         var $md5sum;
52         var $type;
53         var $version;
54         var $status;
55         var $date_entered;
56     var $name;
57     var $description;
58     var $id_name;
59     var $manifest;
60     var $enabled;
61         
62         var $table_name = "upgrade_history";
63         var $object_name = "UpgradeHistory";
64         var $column_fields = Array( "id", "filename", "md5sum", "type", "version", "status", "date_entered" );
65
66         function delete()
67         {
68                 $this->dbManager->query( "delete from " . $this->table_name . " where id = '" . $this->id . "'" );
69         }
70         
71         function UpgradeHistory()
72         {
73                 parent::SugarBean();
74         $this->disable_row_level_security = true;
75         }
76     
77     function getAllOrderBy($orderBy){
78         $query = "SELECT id FROM " . $this->table_name . " ORDER BY ".$orderBy; 
79         return $this->getList($query);
80     }
81     /**
82      * Given a name check if it exists in the table
83      * @param name    the unique key from the manifest
84      * @param id      the id of the item you are comparing to
85      * @return upgrade_history object if found, null otherwise
86      */
87     function checkForExisting($patch_to_check){
88         $uh = new UpgradeHistory();
89         if($patch_to_check != null){
90                 
91                 if(empty($patch_to_check->id_name)){
92                 $where = " WHERE name = '$patch_to_check->name' ";
93             }else{
94                 $where = " WHERE id_name = '$patch_to_check->id_name' ";        
95             }
96             
97             if(!empty($patch_to_check->id)){
98                         $where .= "  AND id != '$patch_to_check->id'  ";                        
99                 }else{
100                         $where .= "  AND id is not null  ";
101                 }
102                 
103                 $query = "SELECT id FROM " . $this->table_name . " ". $where;
104                 
105             $result = $uh->db->query($query);
106             if(empty($result)){
107                 return null;
108             }
109             $row = $uh->db->fetchByAssoc($result);
110             if(empty($row)){
111                 return null;
112             }
113             if(!empty($row['id'])){
114                 return $uh->retrieve($row['id']);    
115             }
116         }
117         return null;
118     }
119     
120     /**
121      * Check if this is an upgrade, if it is then return the latest version before this installation
122      */
123     function determineIfUpgrade($id_name, $version){
124         $query = "SELECT id, version FROM " . $this->table_name . " WHERE id_name = '$id_name' ORDER BY date_entered DESC";
125          $result = $this->db->query($query);
126          if(empty($result)){
127                 return null;
128          }else{
129                 $temp_version = 0;
130                 $id = '';
131                 while($row = $this->db->fetchByAssoc($result))
132                 {
133                         if(!$this->is_right_version_greater(explode('.', $row['version']), explode('.', $temp_version))){
134                                 $temp_version = $row['version'];
135                                 $id = $row['id'];
136                         }
137                 }//end while
138                 if($this->is_right_version_greater(explode('.', $temp_version), explode('.', $version), false))
139                         return array('id' => $id, 'version' => $temp_version);
140                 else
141                         return null;      
142          }
143     }
144
145         function getAll()
146         {
147                 $query = "SELECT id FROM " . $this->table_name . " ORDER BY date_entered desc";
148                 return $this->getList($query);
149         }
150     
151     function getList($query){
152         return( parent::build_related_list( $query, $this ) );    
153     }
154         
155         function findByMd5( $var_md5 )
156         {
157                 $query = "SELECT id FROM " . $this->table_name . " where md5sum = '$var_md5'";
158                 return( parent::build_related_list( $query, $this ) );
159         }
160         
161         function UninstallAvailable($patch_list, $patch_to_check)
162         {
163         //before we even go through the list, let us try to see if we find a match.
164         $history_object = $this->checkForExisting($patch_to_check);
165         if($history_object != null){
166             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){                
167                 //we have found a match
168                 //if the patch_to_check version is greater than the found version
169                 return ($this->is_right_version_greater(explode('.', $history_object->version), explode('.', $patch_to_check->version)));      
170             }else{
171                 return true;
172             }        
173         }
174         //we will only go through this loop if we have not found another UpgradeHistory object
175         //with a matching unique_key in the database
176                 foreach($patch_list as $more_recent_patch)
177                 {
178                         if($more_recent_patch->id == $patch_to_check->id)
179                                 break;
180                         
181             //we will only resort to checking the files if we cannot find the unique_keys
182             //or the unique_keys do not match
183                         $patch_to_check_backup_path    = clean_path(remove_file_extension(from_html($patch_to_check->filename))).'-restore';
184                         $more_recent_patch_backup_path = clean_path(remove_file_extension(from_html($more_recent_patch->filename))).'-restore';
185                         if($this->foundConflict($patch_to_check_backup_path, $more_recent_patch_backup_path) &&
186                          ($more_recent_patch->date_entered >= $patch_to_check->date_entered)){
187                              return false;
188                         }
189                 }
190                 
191                 return true;
192         }
193
194         function foundConflict($check_path, $recent_path)
195         {
196                 if(is_file($check_path))
197                 {
198                         if(file_exists($recent_path))
199                                 return true;
200                         else
201                                 return false;
202                 }
203                 elseif(is_dir($check_path))
204                 {
205                         $status = false;
206                         
207                         $d = dir( $check_path );
208                         while( $f = $d->read() )
209                         {
210                                 if( $f == "." || $f == ".." )
211                                         continue;
212                                 
213                                 $status = $this->foundConflict("$check_path/$f", "$recent_path/$f");
214                                 
215                                 if($status)
216                                         break;
217                         }
218                         
219                         $d->close();
220                         return( $status );
221                 }
222                 
223                 return false;
224         }
225     
226     /**
227      * Given a left version and a right version, determine if the right hand side is greater
228      * 
229      * @param left           the client sugar version
230      * @param right          the server version
231      *
232      * return               true if the right version is greater or they are equal
233      *                      false if the left version is greater
234      */
235     function is_right_version_greater($left, $right, $equals_is_greater = true){
236         if(count($left) == 0 && count($right) == 0){
237             return $equals_is_greater;   
238         }
239         else if(count($left) == 0 || count($right) == 0){
240             return true;
241         }
242         else if($left[0] == $right[0]){
243             array_shift($left);
244             array_shift($right);
245             return $this->is_right_version_greater($left, $right, $equals_is_greater);
246         }
247         else if($left[0] < $right[0]){
248            return true;
249         }
250         else
251             return false;
252     }
253     
254     /**
255      * Given an array of id_names and versions, check if the dependencies are installed
256      * 
257      * @param dependencies      an array of id_name, version to check if these dependencies are installed
258      *                                          on the system
259      * 
260      * @return not_found        an array of id_names that were not found to be installed on the system
261      */
262     function checkDependencies($dependencies = array()){
263                 $not_found = array();
264                 foreach($dependencies as $dependent){
265                         $found = false;
266                         $query = "SELECT id FROM $this->table_name WHERE id_name = '".$dependent['id_name']."'";
267                         $matches = $this->getList($query);
268                         if(0 != sizeof($matches)){
269                                 foreach($matches as $match){
270                                         if($this->is_right_version_greater(explode('.', $match->version), explode('.', $dependent['version']))){
271                                                 $found = true;
272                                                 break;
273                                         }//fi
274                                 }//rof
275                         }//fi
276                         if(!$found){
277                                 $not_found[] = $dependent['id_name'];
278                         }//fi
279                 }//rof
280                 return $not_found;
281     }
282     function retrieve($id = -1, $encode=true,$deleted=true) {
283         return parent::retrieve($id,$encode,false);  //ignore the deleted filter. the table does not have the deleted column in it.
284     } 
285
286 }
287 ?>