]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - ModuleInstall/PackageManager/PackageManager.php
Release 6.4.0
[Github/sugarcrm.git] / ModuleInstall / PackageManager / PackageManager.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37
38 define("CREDENTIAL_CATEGORY", "ml");
39 define("CREDENTIAL_USERNAME", "username");
40 define("CREDENTIAL_PASSWORD", "password");
41
42 require_once('include/nusoap/nusoap.php');
43 require_once('include/utils/zip_utils.php');
44 require_once('ModuleInstall/PackageManager/PackageManagerDisplay.php');
45 require_once('ModuleInstall/ModuleInstaller.php');
46 require_once('include/entryPoint.php');
47 require_once('ModuleInstall/PackageManager/PackageManagerComm.php');
48
49 class PackageManager{
50     var $soap_client;
51
52     /**
53      * Constructor: In this method we will initialize the nusoap client to point to the hearbeat server
54      */
55     function PackageManager(){
56         $this->db = DBManagerFactory::getInstance();
57     }
58
59     function initializeComm(){
60
61     }
62
63     /**
64      * Obtain a promotion from SugarDepot
65      * @return string   the string from the promotion
66      */
67     function getPromotion(){
68         $name_value_list = PackageManagerComm::getPromotion();
69         if(!empty($name_value_list)){
70             $name_value_list = PackageManager::fromNameValueList($name_value_list);
71             return $name_value_list['description'];
72         }else {
73            return '';
74         }
75     }
76
77     /**
78      * Obtain a list of category/packages/releases for use within the module loader
79      */
80     function getModuleLoaderCategoryPackages($category_id = ''){
81         $filter = array();
82         $filter = array('type' => "'module', 'theme', 'langpack'");
83         $filter = PackageManager::toNameValueList($filter);
84         return PackageManager::getCategoryPackages($category_id, $filter);
85     }
86
87     /**
88      * Obtain the list of category_packages from SugarDepot
89      * @return category_packages
90      */
91     function getCategoryPackages($category_id = '', $filter = array()){
92          $results = PackageManagerComm::getCategoryPackages($category_id, $filter);
93          PackageManagerComm::errorCheck();
94          $nodes = array();
95
96         $nodes[$category_id]['packages'] = array();
97         if(!empty($results['categories'])){
98                  foreach($results['categories'] as $category){
99                     $mycat = PackageManager::fromNameValueList($category);
100                     $nodes[$mycat['id']] = array('id' => $mycat['id'], 'label' => $mycat['name'], 'description' => $mycat['description'], 'type' => 'cat', 'parent' => $mycat['parent_id']);
101                     $nodes[$mycat['id']]['packages'] = array();
102                  }
103         }
104          if(!empty($results['packages'])){
105                 $uh = new UpgradeHistory();
106                  foreach($results['packages'] as $package){
107                     $mypack = PackageManager::fromNameValueList($package);
108                     $nodes[$mypack['category_id']]['packages'][$mypack['id']] = array('id' => $mypack['id'], 'label' => $mypack['name'], 'description' => $mypack['description'], 'category_id' => $mypack['category_id'], 'type' => 'package');
109                     $releases = PackageManager::getReleases($category_id, $mypack['id'], $filter);
110                     $arr_releases = array();
111                     $nodes[$mypack['category_id']]['packages'][$mypack['id']]['releases'] = array();
112                     if(!empty($releases['packages'])){
113                             foreach($releases['packages'] as $release){
114                                  $myrelease = PackageManager::fromNameValueList($release);
115                                  //check to see if we already this one installed
116                                  $result = $uh->determineIfUpgrade($myrelease['id_name'], $myrelease['version']);
117                                  $enable = false;
118                                  if($result == true || is_array($result))
119                                          $enable = true;
120                                  $nodes[$mypack['category_id']]['packages'][$mypack['id']]['releases'][$myrelease['id']] = array('id' => $myrelease['id'], 'version' => $myrelease['version'], 'label' => $myrelease['description'], 'category_id' => $mypack['category_id'], 'package_id' => $mypack['id'], 'type' => 'release', 'enable' => $enable);
121                                 }
122                     }
123                     //array_push($nodes[$mypack['category_id']]['packages'], $package_arr);
124                  }
125          }
126          $GLOBALS['log']->debug("NODES". var_export($nodes, true));
127         return $nodes;
128     }
129
130     /**
131      * Get a list of categories from the SugarDepot
132      * @param category_id   the category id of parent to obtain
133      * @param filter        an array of filters to pass to limit the query
134      * @return array        an array of categories for display on the client
135      */
136     function getCategories($category_id, $filter = array()){
137         $nodes = array();
138         $results = PackageManagerComm::getCategories($category_id, $filter);
139         PackageManagerComm::errorCheck();
140         if(!empty($results['categories'])){
141                 foreach($results['categories'] as $category){
142                     $mycat = PackageManager::fromNameValueList($category);
143                     $nodes[] = array('id' => $mycat['id'], 'label' => $mycat['name'], 'description' => $mycat['description'], 'type' => 'cat', 'parent' => $mycat['parent_id']);
144                 }
145         }
146         return $nodes;
147     }
148
149     function getPackages($category_id, $filter = array()){
150         $nodes = array();
151         $results = PackageManagerComm::getPackages($category_id, $filter);
152         PackageManagerComm::errorCheck();
153         $packages = array();
154         //$xml = '';
155         //$xml .= '<packages>';
156         if(!empty($results['packages'])){
157                 foreach($results['packages'] as $package){
158                     $mypack = PackageManager::fromNameValueList($package);
159                     $packages[$mypack['id']] = array('package_id' => $mypack['id'], 'name' => $mypack['name'], 'description' => $mypack['description'], 'category_id' => $mypack['category_id']);
160                     $releases = PackageManager::getReleases($category_id, $mypack['id']);
161                     $arr_releases = array();
162                     foreach($releases['packages'] as $release){
163                          $myrelease = PackageManager::fromNameValueList($release);
164                          $arr_releases[$myrelease['id']]  = array('release_id' => $myrelease['id'], 'version' => $myrelease['version'], 'description' => $myrelease['description'], 'category_id' => $mypack['category_id'], 'package_id' => $mypack['id']);
165                     }
166                     $packages[$mypack['id']]['releases'] = $arr_releases;
167                 }
168         }
169         return $packages;
170     }
171
172     function getReleases($category_id, $package_id, $filter = array()){
173         $releases = PackageManagerComm::getReleases($category_id, $package_id, $filter);
174         PackageManagerComm::errorCheck();
175         return $releases;
176     }
177
178     /**
179      * Retrieve the package as specified by the $id from the heartbeat server
180      *
181      * @param category_id   the category_id to which the release belongs
182      * @param package_id    the package_id to which the release belongs
183      * @param release_id    the release_id to download
184      * @return filename - the path to which the zip file was saved
185      */
186     public function download($category_id, $package_id, $release_id)
187     {
188         $GLOBALS['log']->debug('RELEASE _ID: '.$release_id);
189         if(!empty($release_id)){
190             $filename = PackageManagerComm::addDownload($category_id, $package_id, $release_id);
191             if($filename){
192                     $GLOBALS['log']->debug('RESULT: '.$filename);
193                     PackageManagerComm::errorCheck();
194                         $filepath = PackageManagerComm::performDownload($filename);
195                         return $filepath;
196             }
197         }else{
198             return null;
199         }
200     }
201
202     /**
203      * Given the Mambo username, password, and download key attempt to authenticate, if
204      * successful then store these credentials
205      *
206      * @param username      Mambo username
207      * @param password      Mambo password
208      * @param systemname   the user's download key
209      * @return              true if successful, false otherwise
210      */
211     function authenticate($username, $password, $systemname='', $terms_checked = true){
212         PackageManager::setCredentials($username, $password, $systemname);
213         PackageManagerComm::clearSession();
214         $result = PackageManagerComm::login($terms_checked);
215         if(is_array($result))
216                 return $result;
217         else
218                 return true;
219     }
220
221     function setCredentials($username, $password, $systemname){
222
223         $admin = new Administration();
224         $admin->retrieveSettings();
225          $admin->saveSetting(CREDENTIAL_CATEGORY, CREDENTIAL_USERNAME, $username);
226          $admin->saveSetting(CREDENTIAL_CATEGORY, CREDENTIAL_PASSWORD, $password);
227          if(!empty($systemname)){
228                 $admin->saveSetting('system', 'name', $systemname);
229          }
230     }
231
232     function getCredentials(){
233
234         $admin = new Administration();
235         $admin->retrieveSettings(CREDENTIAL_CATEGORY, true);
236         $credentials = array();
237         $credentials['username'] = '';
238         $credentials['password'] = '';
239                 $credentials['system_name'] = '';
240         if(!empty($admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_USERNAME])){
241            $credentials['username'] = $admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_USERNAME];
242         }
243         if(!empty($admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_USERNAME])){
244            $credentials['password'] = $admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_PASSWORD];
245         }
246         if(!empty($admin->settings['system_name'])){
247            $credentials['system_name'] = $admin->settings['system_name'];
248         }
249         return $credentials;
250     }
251
252     function getTermsAndConditions(){
253         return PackageManagerComm::getTermsAndConditions();
254
255     }
256
257     /**
258      * Retrieve documentation for the given release or package
259      *
260      * @param package_id        the specified package to retrieve documentation
261      * @param release_id        the specified release to retrieve documentation
262      *
263      * @return documents
264      */
265     function getDocumentation($package_id, $release_id){
266          if(!empty($release_id) || !empty($package_id)){
267             $documents = PackageManagerComm::getDocumentation($package_id, $release_id);
268             return $documents;
269         }else{
270             return null;
271         }
272     }
273
274     /**
275      * Grab the list of installed modules and send that list to the depot.
276      * The depot will then send back a list of modules that need to be updated
277      */
278     function checkForUpdates(){
279         $lists = $this->buildInstalledReleases(array('module'), true);
280                 $updates = array();
281                 if(!empty($lists)){
282                         $updates = PackageManagerComm::checkForUpdates($lists);
283                 }//fi
284                 return $updates;
285     }
286
287      ////////////////////////////////////////////////////////
288      /////////// HELPER FUNCTIONS
289     function toNameValueList($array){
290                 $list = array();
291                 foreach($array as $name=>$value){
292                         $list[] = array('name'=>$name, 'value'=>$value);
293                 }
294                 return $list;
295         }
296
297         function toNameValueLists($arrays){
298                 $lists = array();
299                 foreach($arrays as $array){
300                         $lists[] = PackageManager::toNameValueList($array);
301                 }
302                 return $lists;
303         }
304
305      function fromNameValueList($nvl){
306         $array = array();
307         foreach($nvl as $list){
308             $array[$list['name']] = $list['value'];
309         }
310         return $array;
311     }
312
313     function buildInstalledReleases($types = array('module')){
314         //1) get list of installed modules
315                 $installeds = $this->getInstalled($types);
316                 $releases = array();
317                 foreach($installeds as $installed){
318                         $releases[] = array('name' => $installed->name, 'id_name' => $installed->id_name, 'version' => $installed->version, 'filename' => $installed->filename, 'type' => $installed->type);
319                 }
320
321                 $lists = array();
322                 $name_value_list = array();
323                 if(!empty($releases)){
324                         $lists = $this->toNameValueLists($releases);
325                 }//fi
326                 return $lists;
327     }
328
329     function buildPackageXML($package, $releases = array()){
330         $xml = '<package>';
331         $xml .= '<package_id>'.$package['id'].'</package_id>';
332         $xml .= '<name>'.$package['name'].'</name>';
333         $xml .= '<description>'.$package['description'].'</description>';
334         if(!empty($releases)){
335              $xml .= '<releases>';
336              foreach($releases['packages'] as $release){
337
338                  $myrelease = PackageManager::fromNameValueList($release);
339                  $xml .= '<release>';
340                  $xml .= '<release_id>'.$myrelease['id'].'</release_id>';
341                  $xml .= '<version>'.$myrelease['version'].'</version>';
342                  $xml .= '<description>'.$myrelease['description'].'</description>';
343                  $xml .= '<package_id>'.$package['id'].'</package_id>';
344                  $xml .= '<category_id>'.$package['category_id'].'</category_id>';
345                  $xml .= '</release>';
346              }
347              $xml .= '</releases>';
348         }
349         $xml .= '</package>';
350         return $xml;
351     }
352
353     //////////////////////////////////////////////////////////////////////
354     /////////// INSTALL SECTION
355     function extractFile( $zip_file, $file_in_zip, $base_tmp_upgrade_dir){
356         $my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
357         unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
358         return( "$my_zip_dir/$file_in_zip" );
359     }
360
361     function extractManifest( $zip_file,$base_tmp_upgrade_dir ) {
362         global $sugar_config;
363         $base_upgrade_dir       = sugar_cached("/upgrades");
364         $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
365         return $this->extractFile( $zip_file, "manifest.php",$base_tmp_upgrade_dir );
366     }
367
368     function validate_manifest( $manifest ){
369     // takes a manifest.php manifest array and validates contents
370     global $subdirs;
371     global $sugar_version;
372     global $sugar_flavor;
373     global $mod_strings;
374
375     if( !isset($manifest['type']) ){
376         die($mod_strings['ERROR_MANIFEST_TYPE']);
377     }
378     $type = $manifest['type'];
379     $GLOBALS['log']->debug("Getting InstallType");
380     if( $this->getInstallType( "/$type/" ) == "" ){
381         $GLOBALS['log']->debug("Error with InstallType".$type);
382         die($mod_strings['ERROR_PACKAGE_TYPE']. ": '" . $type . "'." );
383     }
384     $GLOBALS['log']->debug("Passed with InstallType");
385     if( isset($manifest['acceptable_sugar_versions']) ){
386             $version_ok = false;
387             $matches_empty = true;
388             if( isset($manifest['acceptable_sugar_versions']['exact_matches']) ){
389                 $matches_empty = false;
390                 foreach( $manifest['acceptable_sugar_versions']['exact_matches'] as $match ){
391                     if( $match == $sugar_version ){
392                         $version_ok = true;
393                     }
394                 }
395             }
396             if( !$version_ok && isset($manifest['acceptable_sugar_versions']['regex_matches']) ){
397                 $matches_empty = false;
398                 foreach( $manifest['acceptable_sugar_versions']['regex_matches'] as $match ){
399                     if( preg_match( "/$match/", $sugar_version ) ){
400                         $version_ok = true;
401                     }
402                 }
403             }
404
405             if( !$matches_empty && !$version_ok ){
406                 die( $mod_strings['ERROR_VERSION_INCOMPATIBLE'] . $sugar_version );
407             }
408         }
409
410      if( isset($manifest['acceptable_sugar_flavors']) && sizeof($manifest['acceptable_sugar_flavors']) > 0 ){
411             $flavor_ok = false;
412             foreach( $manifest['acceptable_sugar_flavors'] as $match ){
413                 if( $match == $sugar_flavor ){
414                     $flavor_ok = true;
415                 }
416             }
417             if( !$flavor_ok ){
418                 //die( $mod_strings['ERROR_FLAVOR_INCOMPATIBLE'] . $sugar_flavor );
419             }
420         }
421     }
422
423     function getInstallType( $type_string ){
424         // detect file type
425         global $subdirs;
426         $subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
427
428
429         foreach( $subdirs as $subdir ){
430             if( preg_match( "#/$subdir/#", $type_string ) ){
431                 return( $subdir );
432             }
433         }
434         // return empty if no match
435         return( "" );
436     }
437
438     function performSetup($tempFile, $view = 'module', $display_messages = true){
439         global $sugar_config;
440         $base_filename = urldecode($tempFile);
441         $GLOBALS['log']->debug("BaseFileName: ".$base_filename);
442         $base_upgrade_dir       = sugar_cached("/upgrades");
443         $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
444         $manifest_file = $this->extractManifest( $base_filename,$base_tmp_upgrade_dir);
445          $GLOBALS['log']->debug("Manifest: ".$manifest_file);
446         if($view == 'module')
447             $license_file = $this->extractFile($base_filename, 'LICENSE.txt', $base_tmp_upgrade_dir);
448         if(is_file($manifest_file)){
449             $GLOBALS['log']->debug("VALIDATING MANIFEST". $manifest_file);
450             require_once( $manifest_file );
451             $this->validate_manifest($manifest );
452             $upgrade_zip_type = $manifest['type'];
453             $GLOBALS['log']->debug("VALIDATED MANIFEST");
454             // exclude the bad permutations
455             if( $view == "module" ){
456                 if ($upgrade_zip_type != "module" && $upgrade_zip_type != "theme" && $upgrade_zip_type != "langpack"){
457                     $this->unlinkTempFiles();
458                     if($display_messages)
459                         die($mod_strings['ERR_UW_NOT_ACCEPTIBLE_TYPE']);
460                 }
461             }elseif( $view == "default" ){
462                 if($upgrade_zip_type != "patch" ){
463                     $this->unlinkTempFiles();
464                     if($display_messages)
465                         die($mod_strings['ERR_UW_ONLY_PATCHES']);
466                 }
467             }
468
469             $base_filename = preg_replace( "#\\\\#", "/", $base_filename );
470             $base_filename = basename( $base_filename );
471             mkdir_recursive( "$base_upgrade_dir/$upgrade_zip_type" );
472             $target_path = "$base_upgrade_dir/$upgrade_zip_type/$base_filename";
473             $target_manifest = remove_file_extension( $target_path ) . "-manifest.php";
474
475             if( isset($manifest['icon']) && $manifest['icon'] != "" ){
476                 $icon_location = $this->extractFile( $tempFile ,$manifest['icon'], $base_tmp_upgrade_dir );
477                 $path_parts = pathinfo( $icon_location );
478                 copy( $icon_location, remove_file_extension( $target_path ) . "-icon." . $path_parts['extension'] );
479             }
480
481             if( copy( $tempFile , $target_path ) ){
482                 copy( $manifest_file, $target_manifest );
483                 if($display_messages)
484                     $messages = '<script>ajaxStatus.flashStatus("' .$base_filename.$mod_strings['LBL_UW_UPLOAD_SUCCESS'] . ', 5000");</script>';
485             }else{
486                 if($display_messages)
487                         $messages = '<script>ajaxStatus.flashStatus("' .$mod_strings['ERR_UW_UPLOAD_ERROR'] . ', 5000");</script>';
488             }
489         }//fi
490         else{
491             $this->unlinkTempFiles();
492             if($display_messages)
493                 die($mod_strings['ERR_UW_NO_MANIFEST']);
494         }
495         if(isset($messages))
496             return $messages;
497     }
498
499     function unlinkTempFiles() {
500         global $sugar_config;
501         @unlink($_FILES['upgrade_zip']['tmp_name']);
502         @unlink("upload://".$_FILES['upgrade_zip']['name']);
503     }
504
505     function performInstall($file, $silent=true){
506         global $sugar_config;
507         global $mod_strings;
508         global $current_language;
509         $base_upgrade_dir       = sugar_cached("/upgrades");
510         $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
511         if(!file_exists($base_tmp_upgrade_dir)){
512             mkdir_recursive($base_tmp_upgrade_dir, true);
513         }
514
515         $GLOBALS['log']->debug("INSTALLING: ".$file);
516         $mi = new ModuleInstaller();
517         $mi->silent = $silent;
518         $mod_strings = return_module_language($current_language, "Administration");
519              $GLOBALS['log']->debug("ABOUT TO INSTALL: ".$file);
520         if(preg_match("#.*\.zip\$#", $file)) {
521              $GLOBALS['log']->debug("1: ".$file);
522             // handle manifest.php
523             $target_manifest = remove_file_extension( $file ) . '-manifest.php';
524             include($target_manifest);
525             $GLOBALS['log']->debug("2: ".$file);
526             $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
527             unzip($file, $unzip_dir );
528             $GLOBALS['log']->debug("3: ".$unzip_dir);
529             $id_name = $installdefs['id'];
530                         $version = $manifest['version'];
531                         $uh = new UpgradeHistory();
532                         $previous_install = array();
533                 if(!empty($id_name) & !empty($version))
534                         $previous_install = $uh->determineIfUpgrade($id_name, $version);
535                 $previous_version = (empty($previous_install['version'])) ? '' : $previous_install['version'];
536                 $previous_id = (empty($previous_install['id'])) ? '' : $previous_install['id'];
537
538             if(!empty($previous_version)){
539                 $mi->install($unzip_dir, true, $previous_version);
540             }else{
541                 $mi->install($unzip_dir);
542             }
543             $GLOBALS['log']->debug("INSTALLED: ".$file);
544             $new_upgrade = new UpgradeHistory();
545             $new_upgrade->filename      = $file;
546             $new_upgrade->md5sum        = md5_file($file);
547             $new_upgrade->type          = $manifest['type'];
548             $new_upgrade->version       = $manifest['version'];
549             $new_upgrade->status        = "installed";
550             //$new_upgrade->author        = $manifest['author'];
551             $new_upgrade->name          = $manifest['name'];
552             $new_upgrade->description   = $manifest['description'];
553             $new_upgrade->id_name               = $id_name;
554                         $serial_manifest = array();
555                         $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
556                         $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
557                         $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
558                         $new_upgrade->manifest          = base64_encode(serialize($serial_manifest));
559             //$new_upgrade->unique_key    = (isset($manifest['unique_key'])) ? $manifest['unique_key'] : '';
560             $new_upgrade->save();
561                     //unlink($file);
562         }//fi
563     }
564
565     function performUninstall($name){
566         $uh = new UpgradeHistory();
567         $uh->name = $name;
568         $uh->id_name = $name;
569         $found = $uh->checkForExisting($uh);
570         if($found != null){
571
572                 global $sugar_config;
573                 global $mod_strings;
574                 global $current_language;
575                 $base_upgrade_dir       = sugar_cached("/upgrades");
576                 $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
577                 if(!isset($GLOBALS['mi_remove_tables']))$GLOBALS['mi_remove_tables'] = true;
578                 $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
579                 unzip($found->filename, $unzip_dir );
580                 $mi = new ModuleInstaller();
581                 $mi->silent = true;
582                 $mi->uninstall( "$unzip_dir");
583                 $found->delete();
584                 unlink(remove_file_extension( $found->filename ) . '-manifest.php');
585                 unlink($found->filename);
586         }
587     }
588
589     function getUITextForType( $type ){
590         if( $type == "full" ){
591             return( "Full Upgrade" );
592         }
593         if( $type == "langpack" ){
594             return( "Language Pack" );
595         }
596         if( $type == "module" ){
597             return( "Module" );
598         }
599         if( $type == "patch" ){
600             return( "Patch" );
601         }
602         if( $type == "theme" ){
603             return( "Theme" );
604         }
605     }
606
607     function getImageForType( $type ){
608
609         $icon = "";
610         switch( $type ){
611             case "full":
612                 $icon = SugarThemeRegistry::current()->getImage("Upgrade", "" ,null,null,'.gif', "Upgrade");
613
614                 break;
615             case "langpack":
616                 $icon = SugarThemeRegistry::current()->getImage("LanguagePacks", "",null,null,'.gif',"Language Packs" );
617
618                 break;
619             case "module":
620                 $icon = SugarThemeRegistry::current()->getImage("ModuleLoader", "" ,null,null,'.gif', "Module Loader");
621
622                 break;
623             case "patch":
624                 $icon = SugarThemeRegistry::current()->getImage("PatchUpgrades", "",null,null,'.gif', "Patch Upgrades" );
625
626                 break;
627             case "theme":
628                 $icon = SugarThemeRegistry::current()->getImage("Themes", "",null,null,'.gif', "Themes" );
629
630                 break;
631             default:
632                 break;
633         }
634         return( $icon );
635     }
636
637     function getPackagesInStaging($view = 'module'){
638         global $sugar_config;
639         global $current_language;
640         $uh = new UpgradeHistory();
641         $base_upgrade_dir       = "upload://upgrades";
642         $base_tmp_upgrade_dir   = sugar_cached("upgrades/temp");
643         $uContent = findAllFiles( $base_upgrade_dir, array() , false, 'zip');
644         $upgrade_contents = array();
645         $content_values = array_values($uContent);
646         $alreadyProcessed = array();
647         foreach($content_values as $val){
648                 if(empty($alreadyProcessed[$val])){
649                         $upgrade_contents[] = $val;
650                         $alreadyProcessed[$val] = true;
651                 }
652         }
653
654         $upgrades_available = 0;
655         $packages = array();
656         $mod_strings = return_module_language($current_language, "Administration");
657         foreach($upgrade_contents as $upgrade_content) {
658             if(!preg_match('#.*\.zip$#', strtolower($upgrade_content)) || preg_match("#.*./zips/.*#", strtolower($upgrade_content))) {
659                 continue;
660             }
661
662             $the_base = basename($upgrade_content);
663             $the_md5 = md5_file($upgrade_content);
664             $md5_matches = $uh->findByMd5($the_md5);
665                 $file_install = $upgrade_content;
666             if(empty($md5_matches))
667             {
668                 $target_manifest = remove_file_extension( $upgrade_content ) . '-manifest.php';
669                 require_once($target_manifest);
670
671                 $name = empty($manifest['name']) ? $upgrade_content : $manifest['name'];
672                 $version = empty($manifest['version']) ? '' : $manifest['version'];
673                 $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
674                 $icon = '';
675                 $description = empty($manifest['description']) ? 'None' : $manifest['description'];
676                 $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
677                 $type = $this->getUITextForType( $manifest['type'] );
678                 $manifest_type = $manifest['type'];
679                 $dependencies = array();
680                 if( isset( $manifest['dependencies']) ){
681                                 $dependencies    = $manifest['dependencies'];
682                                 }
683
684                                 //check dependencies first
685                                 if(!empty($dependencies)) {
686                                         $uh = new UpgradeHistory();
687                                         $not_found = $uh->checkDependencies($dependencies);
688                                         if(!empty($not_found) && count($not_found) > 0){
689                                                         $file_install = 'errors_'.$mod_strings['ERR_UW_NO_DEPENDENCY']."[".implode(',', $not_found)."]";
690                                         }
691                                 }
692
693                 if($view == 'default' && $manifest_type != 'patch') {
694                     continue;
695                 }
696
697                 if($view == 'module'
698                     && $manifest_type != 'module' && $manifest_type != 'theme' && $manifest_type != 'langpack') {
699                     continue;
700                 }
701
702                 if(empty($manifest['icon'])) {
703                     $icon = $this->getImageForType( $manifest['type'] );
704                 } else {
705                     $path_parts = pathinfo( $manifest['icon'] );
706                     $icon = "<img src=\"" . remove_file_extension( $upgrade_content ) . "-icon." . $path_parts['extension'] . "\">";
707                 }
708
709                 $upgrades_available++;
710
711                 $packages[] = array('name' => $name, 'version' => $version, 'published_date' => $published_date,
712                         'description' => $description, 'uninstallable' =>$uninstallable, 'type' => $type,
713                         'file' => fileToHash($upgrade_content), 'file_install' => fileToHash($upgrade_content));
714             }//fi
715         }//rof
716         return $packages;
717     }
718
719     function getLicenseFromFile($file){
720         global $sugar_config;
721         $base_upgrade_dir       = sugar_cached("/upgrades");
722         $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
723         $license_file = $this->extractFile($file, 'LICENSE.txt', $base_tmp_upgrade_dir);
724         if(is_file($license_file)){
725             $contents = file_get_contents($license_file);
726             return $contents;
727         }else{
728             return null;
729         }
730     }
731
732     /**
733      * Run the query to obtain the list of installed types as specified by the type param
734      *
735      * @param type      an array of types you would like to search for
736      *                          type options include (theme, langpack, module, patch)
737      *
738      * @return an array of installed upgrade_history objects
739      */
740     function getInstalled($types = array('module')){
741         $uh = new UpgradeHistory();
742         $in = "";
743         for($i = 0; $i < count($types); $i++){
744                 $in .= "'".$types[$i]."'";
745                 if(($i+1) < count($types)){
746                         $in .= ",";
747                 }
748         }
749         $query = "SELECT * FROM ".$uh->table_name."      WHERE type IN (".$in.")";
750         return $uh->getList($query);
751     }
752
753     function getinstalledPackages($types = array('module', 'langpack')){
754         global $sugar_config;
755         $installeds = $this->getInstalled($types);
756         $packages = array();
757         $upgrades_installed = 0;
758         $uh = new UpgradeHistory();
759         $base_upgrade_dir       = sugar_cached("/upgrades");
760         $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
761         foreach($installeds as $installed)
762                 {
763                         $populate = false;
764                         $filename = from_html($installed->filename);
765                         $date_entered = $installed->date_entered;
766                         $type = $installed->type;
767                         $version = $installed->version;
768                         $uninstallable = false;
769                         $link = "";
770                         $description = $installed->description;
771                         $name = $installed->name;
772                         $enabled = true;
773                         $enabled_string = 'ENABLED';
774                         //if the name is empty then we should try to pull from manifest and populate upgrade_history_table
775                         if(empty($name)){
776                                 $populate = true;
777                         }
778                         $upgrades_installed++;
779                         switch($type)
780                         {
781                                 case "theme":
782                                 case "langpack":
783                                 case "module":
784                                 case "patch":
785                                         if($populate){
786                                                 $manifest_file = $this->extractManifest($filename, $base_tmp_upgrade_dir);
787                                                 require_once($manifest_file);
788                                                 $GLOBALS['log']->info("Filling in upgrade_history table");
789                                                 $populate = false;
790                                                 if( isset( $manifest['name'] ) ){
791                                                 $name = $manifest['name'];
792                                                 $installed->name = $name;
793                                                 }
794                                                 if( isset( $manifest['description'] ) ){
795                                                     $description = $manifest['description'];
796                                                     $installed->description = $description;
797                                                 }
798                                                 if(isset($installdefs) && isset( $installdefs['id'] ) ){
799                                                     $id_name  = $installdefs['id'];
800                                                     $installed->id_name = $id_name;
801                                                 }
802
803                                                 $serial_manifest = array();
804                                                 $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
805                                                 $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
806                                                 $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
807                                                 $installed->manifest = base64_encode(serialize($serial_manifest));
808                                                 $installed->save();
809                                         }else{
810                                                 $serial_manifest = unserialize(base64_decode($installed->manifest));
811                                                 $manifest = $serial_manifest['manifest'];
812                                         }
813                                         if(($upgrades_installed==0 || $uh->UninstallAvailable($installeds, $installed))
814                                                 && is_file($filename) && !empty($manifest['is_uninstallable']))
815                                         {
816                                                 $uninstallable = true;
817                                         }
818                                         $enabled = $installed->enabled;
819                                         if(!$enabled)
820                                                 $enabled_string = 'DISABLED';
821                                         $file_uninstall = $filename;
822                                         if(!$uninstallable){
823                                                 $file_uninstall = 'UNINSTALLABLE';
824                                                 $enabled_string = 'UNINSTALLABLE';
825                                         } else {
826                                                 $file_uninstall = fileToHash( $file_uninstall );
827                                         }
828
829                                 $packages[] = array(
830                                     'name' => $name,
831                                     'version' => $version,
832                                     'type' => $type,
833                                     'published_date' => $date_entered,
834                                     'description' => $description,
835                                     'uninstallable' =>$uninstallable,
836                                     'file_install' =>  $file_uninstall ,
837                                     'file' =>  fileToHash($filename),
838                                     'enabled' => $enabled_string
839                                 );
840                                 break;
841                                 default:
842                                 break;
843                         }
844
845                 }//rof
846                 return $packages;
847     }
848  }
849 ?>