Passed
Push — scrutinizer-code-quality ( 09f5a1...c4c5fb )
by Adam
56:05 queued 14:08
created

UpgradeHistory::findByMd5()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

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