PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/ModuleInstall/PackageManager/PackageManager.php

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