This commit is contained in:
2024-04-27 09:23:34 +02:00
commit 11e713ca6f
11884 changed files with 3263371 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,435 @@
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
class ModuleScanner{
private $manifestMap = array(
'pre_execute'=>'pre_execute',
'install_mkdirs'=>'mkdir',
'install_copy'=>'copy',
'install_images'=>'image_dir',
'install_menus'=>'menu',
'install_userpage'=>'user_page',
'install_dashlets'=>'dashlets',
'install_administration'=>'administration',
'install_connectors'=>'connectors',
'install_vardefs'=>'vardefs',
'install_layoutdefs'=>'layoutdefs',
'install_layoutfields'=>'layoutfields',
'install_relationships'=>'relationships',
'install_languages'=>'language',
'install_logichooks'=>'logic_hooks',
'post_execute'=>'post_execute',
);
private $blackListExempt = array();
private $validExt = array('png', 'gif', 'jpg', 'css', 'js', 'php', 'txt', 'html', 'htm', 'tpl', 'pdf', 'md5', 'xml');
private $blackList = array(
'eval',
'exec',
'system',
'shell_exec',
'passthru',
'chgrp',
'chmod',
'chwown',
'file_put_contents',
'file',
'fileatime',
'filectime',
'filegroup',
'fileinode',
'filemtime',
'fileowner',
'fileperms',
'fopen',
'is_executable',
'is_writable',
'is_writeable',
'lchgrp',
'lchown',
'linkinfo',
'lstat',
'mkdir',
'parse_ini_file',
'rmdir',
'stat',
'tempnam',
'touch',
'unlink',
'getimagesize',
'call_user_func',
'call_user_func_array',
'create_function',
//mutliple files per function call
'copy',
'link',
'rename',
'symlink',
'move_uploaded_file',
'chdir',
'chroot',
'create_cache_directory',
'mk_temp_dir',
'write_array_to_file',
'write_encoded_file',
'create_custom_directory',
'sugar_rename',
'sugar_chown',
'sugar_fopen',
'sugar_mkdir',
'sugar_file_put_contents',
'sugar_chgrp',
'sugar_chmod',
'sugar_touch',
);
public function printToWiki(){
echo "'''Default Extensions'''<br>";
foreach($this->validExt as $b){
echo '#' . $b . '<br>';
}
echo "'''Default Black Listed Functions'''<br>";
foreach($this->blackList as $b){
echo '#' . $b . '<br>';
}
}
public function __construct(){
if(!empty($GLOBALS['sugar_config']['moduleInstaller']['blackListExempt'])){
$this->blackListExempt = array_merge($this->blackListExempt, $GLOBALS['sugar_config']['moduleInstaller']['blackListExempt']);
}
if(!empty($GLOBALS['sugar_config']['moduleInstaller']['blackList'])){
$this->blackList = array_merge($this->blackList, $GLOBALS['sugar_config']['moduleInstaller']['blackList']);
}
if(!empty($GLOBALS['sugar_config']['moduleInstaller']['validExt'])){
$this->validExt = array_merge($this->validExt, $GLOBALS['sugar_config']['moduleInstaller']['validExt']);
}
}
private $issues = array();
private $pathToModule = '';
/**
*returns a list of issues
*/
public function getIssues(){
return $this->issues;
}
/**
*returns true or false if any issues were found
*/
public function hasIssues(){
return !empty($this->issues);
}
/**
*Ensures that a file has a valid extension
*/
private function isValidExtension($file){
$file = strtolower($file);
$extPos = strrpos($file, '.');
//make sure they don't override the files.md5
if($extPos === false || $file == 'files.md5')return false;
$ext = substr($file, $extPos + 1);
return in_array($ext, $this->validExt);
}
/**
*Scans a directory and calls on scan file for each file
**/
public function scanDir($path){
static $startPath = '';
if(empty($startPath))$startPath = $path;
if(!is_dir($path))return false;
$d = dir($path);
while($e = $d->read()){
$next = $path . '/' . $e;
if(is_dir($next)){
if(substr($e, 0, 1) == '.')continue;
$this->scanDir($next);
}else{
$issues = $this->scanFile($next);
}
}
return true;
}
/**
* Given a file it will open it's contents and check if it is a PHP file (not safe to just rely on extensions) if it finds <?php tags it will use the tokenizer to scan the file
* $var() and ` are always prevented then whatever is in the blacklist.
* It will also ensure that all files are of valid extension types
*
*/
public function scanFile($file){
$issues = array();
if(!$this->isValidExtension($file)){
$issues[] = translate('ML_INVALID_EXT');
$this->issues['file'][$file] = $issues;
return $issues;
}
$contents = file_get_contents($file);
if(stripos($contents,'<?php') === false )return $issues;
$tokens = token_get_all($contents);
$checkFunction = false;
$possibleIssue = '';
$lastToken = false;
foreach($tokens as $index=>$token){
if(is_string($token[0])){
switch($token[0]){
case '`':
$issues['backtick'] = translate('ML_INVALID_FUNCTION') . " '`'";
case '(':
if($checkFunction)$issues[] = $possibleIssue;
break;
}
$checkFunction = false;
$possibleIssue = '';
}else{
$token['_msi'] = token_name($token[0]);
switch($token[0]){
case T_WHITESPACE: continue;
case T_EVAL:
if(in_array('eval', $this->blackList) && !in_array('eval', $this->blackListExempt))
$issues[]= translate('ML_INVALID_FUNCTION') . ' eval()';
break;
case T_STRING:
$token[1] = strtolower($token[1]);
if(!in_array($token[1], $this->blackList))break;
if(in_array($token[1], $this->blackListExempt))break;
if ($lastToken !== false &&
($lastToken[0] == T_NEW || $lastToken[0] == T_OBJECT_OPERATOR || $lastToken[0] == T_DOUBLE_COLON))
{
break;
}
case T_VARIABLE:
$checkFunction = true;
$possibleIssue = translate('ML_INVALID_FUNCTION') . ' ' . $token[1] . '()';
break;
default:
$checkFunction = false;
$possibleIssue = '';
}
if ($token[0] != T_WHITESPACE)
{
$lastToken = $token;
}
}
}
if(!empty($issues)){
$this->issues['file'][$file] = $issues;
}
return $issues;
}
/*
* checks files.md5 file to see if the file is from sugar
* ONLY WORKS ON FILES
*/
public function sugarFileExists($path){
static $md5 = array();
if(empty($md5)){
include('files.md5');
$md5 = $md5_string;
}
if(isset($md5['./' . $path]))return true;
}
/**
*This function will scan the Manifest for disabled actions specified in $GLOBALS['sugar_config']['moduleInstaller']['disableActions']
*if $GLOBALS['sugar_config']['moduleInstaller']['disableRestrictedCopy'] is set to false or not set it will call on scanCopy to ensure that it is not overriding files
*/
public function scanManifest($manifestPath){
$issues = array();
if(!file_exists($manifestPath)){
$this->issues['manifest'][$manifestPath] = translate('ML_NO_MANIFEST');
return $issues;
}
$fileIssues = $this->scanFile($manifestPath);
//if the manifest contains malicious code do not open it
if(!empty($fileIssues)){
return $fileIssues;
}
include($manifestPath);
//scan for disabled actions
if(isset($GLOBALS['sugar_config']['moduleInstaller']['disableActions'])){
foreach($GLOBALS['sugar_config']['moduleInstaller']['disableActions'] as $action){
if(isset($installdefs[$this->manifestMap[$action]])){
$issues[] = translate('ML_INVALID_ACTION_IN_MANIFEST') . $this->manifestMap[$action];
}
}
}
//now lets scan for files that will override our files
if(empty($GLOBALS['sugar_config']['moduleInstaller']['disableRestrictedCopy']) && isset($installdefs['copy'])){
foreach($installdefs['copy'] as $copy){
$from = str_replace('<basepath>', $this->pathToModule, $copy['from']);
$to = $copy['to'];
if(substr_count($from, '..')){
$this->issues['copy'][$from] = translate('ML_PATH_MAY_NOT_CONTAIN').' ".." -' . $from;
}
if(substr_count($to, '..')){
$this->issues['copy'][$to] = translate('ML_PATH_MAY_NOT_CONTAIN'). ' ".." -' . $to;
}
while(substr_count($from, '//')){
$from = str_replace('//', '/', $from);
}
while(substr_count($to, '//')){
$to = str_replace('//', '/', $to);
}
$this->scanCopy($from, $to);
}
}
if(!empty($issues)){
$this->issues['manifest'][$manifestPath] = $issues;
}
}
/**
* Takes in where the file will is specified to be copied from and to
* and ensures that there is no official sugar file there. If the file exists it will check
* against the MD5 file list to see if Sugar Created the file
*
*/
function scanCopy($from, $to){
//if the file doesn't exist for the $to then it is not overriding anything
if(!file_exists($to))return;
//if $to is a dir and $from is a file then make $to a full file path as well
if(is_dir($to) && is_file($from)){
if(substr($to,-1) === '/'){
$to = substr($to, 0 , strlen($to) - 1);
}
$to .= '/'. basename($from);
}
//if the $to is a file and it is found in sugarFileExists then don't allow overriding it
if(is_file($to) && $this->sugarFileExists($to)){
$this->issues['copy'][$from] = translate('ML_OVERRIDE_CORE_FILES') . '(' . $to . ')';
}
if(is_dir($from)){
$d = dir($from);
while($e = $d->read()){
if($e == '.' || $e == '..')continue;
$this->scanCopy($from .'/'. $e, $to .'/' . $e);
}
}
}
/**
*Main external function that takes in a path to a package and then scans
*that package's manifest for disabled actions and then it scans the PHP files
*for restricted function calls
*
*/
public function scanPackage($path){
$this->pathToModule = $path;
$this->scanManifest($path . '/manifest.php');
if(empty($GLOBALS['sugar_config']['moduleInstaller']['disableFileScan'])){
$this->scanDir($path);
}
}
/**
*This function will take all issues of the current instance and print them to the screen
**/
public function displayIssues($package='Package'){
echo '<h2>'.str_replace('{PACKAGE}' , $package ,translate('ML_PACKAGE_SCANNING')). '</h2><BR><h2 class="error">' . translate('ML_INSTALLATION_FAILED') . '</h2><br><p>' .str_replace('{PACKAGE}' , $package ,translate('ML_PACKAGE_NOT_CONFIRM')). '</p><ul><li>'. translate('ML_OBTAIN_NEW_PACKAGE') . '<li>' . translate('ML_RELAX_LOCAL').
'</ul></p><br>' . translate('ML_SUGAR_LOADING_POLICY') . ' <a href=" http://kb.sugarcrm.com/custom/module-loader-restrictions-for-sugar-open-cloud/">' . translate('ML_SUGAR_KB') . '</a>.'.
'<br>' . translate('ML_AVAIL_RESTRICTION'). ' <a href=" http://developers.sugarcrm.com/wordpress/2009/08/14/module-loader-restrictions/">' . translate('ML_SUGAR_DZ') . '</a>.<br><br>';
foreach($this->issues as $type=>$issues){
echo '<div class="error"><h2>'. ucfirst($type) .' ' . translate('ML_ISSUES') . '</h2> </div>';
echo '<div id="details' . $type . '" >';
foreach($issues as $file=>$issue){
$file = str_replace($this->pathToModule . '/', '', $file);
echo '<div style="position:relative;left:10px"><b>' . $file . '</b></div><div style="position:relative;left:20px">';
if(is_array($issue)){
foreach($issue as $i){
echo "$i<br>";
}
}else{
echo "$issue<br>";
}
echo "</div>";
}
echo '</div>';
}
echo "<br><input class='button' onclick='document.location.href=\"index.php?module=Administration&action=UpgradeWizard&view=module\"' type='button' value=\"" . translate('LBL_UW_BTN_BACK_TO_MOD_LOADER') . "\" />";
}
}
?>

View File

@@ -0,0 +1,71 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('include/ListView/ListViewSmarty.php');
class ListViewPackages extends ListViewSmarty{
var $secondaryDisplayColumns;
/**
* Constructor Call ListViewSmarty
*/
function ListViewPackages(){
parent::ListViewSmarty();
}
/**
* Override the setup method in ListViewSmarty since we are not passing in a bean
*
* @param data the data to display on the page
* @param file the template file to parse
*/
function setup($data, $file){
$this->data = $data;
$this->tpl = $file;
}
/**
* Override the display method
*/
function display(){
global $odd_bg, $even_bg, $app_strings;
$this->ss->assign('rowColor', array('oddListRow', 'evenListRow'));
$this->ss->assign('bgColor', array($odd_bg, $even_bg));
$this->ss->assign('displayColumns', $this->displayColumns);
$this->ss->assign('secondaryDisplayColumns', $this->secondaryDisplayColumns);
$this->ss->assign('data', $this->data);
return $this->ss->fetch($this->tpl);
}
}
?>

View File

@@ -0,0 +1,355 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('ModuleInstall/PackageManager/PackageManagerDisplay.php');
require_once('ModuleInstall/PackageManager/PackageManager.php');
class PackageController{
var $_pm;
/**
* Constructor: this class is called from the the ajax call and handles invoking the correct
* functionality on the server.
*/
function PackageController(){
$this->_pm = new PackageManager();
}
function performBasicSearch(){
$json = getJSONobj();
$search_term = '';
$node_id = '';
if(isset($_REQUEST['search_term'])) {
$search_term = nl2br($_REQUEST['search_term']);
}
if(isset($_REQUEST['node_id'])) {
$node_id = nl2br($_REQUEST['node_id']);
}
$xml = PackageManager::getPackages($node_id);
echo 'result = ' . $json->encode(array('packages' => $xml));
}
/**
* Retrieve a list of packages which belong to the corresponding category
*
* @param category_id this is passed via POST and is the category id of packages
* we wish to retrieve
* @return packages xml string consisting of the packages and releases which belong to
* the category
*/
function getPackages(){
$json = getJSONobj();
$category_id = '';
if(isset($_REQUEST['category_id'])) {
$category_id = nl2br($_REQUEST['category_id']);
}
$xml = PackageManager::getPackages($category_id);
echo 'result = ' . $json->encode(array('package_output' => $xml));
}
/**
* Obtain a list of releases from the server. This function is currently used for generating the patches/langpacks for upgrade wizard
* as well as during installation
*/
function getReleases(){
$json = getJSONobj();
$category_id = '';
$package_id = '';
$types = '';
if(isset($_REQUEST['category_id'])) {
$category_id = nl2br($_REQUEST['category_id']);
}
if(isset($_REQUEST['package_id'])) {
$package_id = nl2br($_REQUEST['package_id']);
}
if(isset($_REQUEST['types'])) {
$types = nl2br($_REQUEST['types']);
}
$types = explode(',', $types);
$filter = array();
$count = count($types);
$index = 1;
$type_str = '';
foreach($types as $type){
$type_str .= "'".$type."'";
if($index < $count)
$type_str .= ",";
$index++;
}
$filter = array('type' => $type_str);
$filter = PackageManager::toNameValueList($filter);
$releases = PackageManager::getReleases($category_id, $package_id, $filter);
$nodes = array();
$release_map = array();
foreach($releases['packages'] as $release){
$release = PackageManager::fromNameValueList($release);
$nodes[] = array('description' => $release['description'], 'version' => $release['version'], 'build_number' => $release['build_number'], 'id' => $release['id']);
$release_map[$release['id']] = array('package_id' => $release['package_id'], 'category_id' => $release['category_id']);
}
$_SESSION['ML_PATCHES'] = $release_map;
echo 'result = ' . $json->encode(array('releases' => $nodes));
}
/**
* Obtain a promotion from the depot
*/
function getPromotion(){
$json = getJSONobj();
$header = PackageManager::getPromotion();
echo 'result = ' . $json->encode(array('promotion' => $header));
}
/**
* Download the given release
*
* @param category_id this is passed via POST and is the category id of the release we wish to download
* @param package_id this is passed via POST and is the package id of the release we wish to download
* @param release_id this is passed via POST and is the release id of the release we wish to download
* @return bool true is successful in downloading, false otherwise
*/
function download(){
global $sugar_config;
$json = getJSONobj();
$package_id = '';
$category_id = '';
$release_id = '';
if(isset($_REQUEST['package_id'])) {
$package_id = nl2br($_REQUEST['package_id']);
}
if(isset($_REQUEST['category_id'])) {
$category_id = nl2br($_REQUEST['category_id']);
}
if(isset($_REQUEST['release_id'])) {
$release_id = nl2br($_REQUEST['release_id']);
}
$GLOBALS['log']->debug("PACKAGE ID: ".$package_id);
$GLOBALS['log']->debug("CATEGORY ID: ".$category_id);
$GLOBALS['log']->debug("RELEASE ID: ".$release_id);
$result = $this->_pm->download($category_id, $package_id, $release_id, getcwd().'/'.$sugar_config['upload_dir']);
$GLOBALS['log']->debug("RESULT: ".print_r($result,true));
$success = 'false';
if($result != null){
$GLOBALS['log']->debug("Performing Setup");
$this->_pm->performSetup($result, 'module', false);
$GLOBALS['log']->debug("Complete Setup");
$success = 'true';
}
echo 'result = ' . $json->encode(array('success' => $success));
}
/**
* Retrieve a list of categories that are subcategories to the selected category
*
* @param id - the id of the parent_category, -1 if this is the root
* @return array - a list of categories/nodes which are underneath this node
*/
function getCategories(){
$json = getJSONobj();
$node_id = '';
if(isset($_REQUEST['category_id'])) {
$node_id = nl2br($_REQUEST['category_id']);
}
$GLOBALS['log']->debug("NODE ID: ".$node_id);
$nodes = PackageManager::getCategories($node_id);
echo 'result = ' . $json->encode(array('nodes' => $nodes));
}
function getNodes(){
$json = getJSONobj();
$category_id = '';
if(isset($_REQUEST['category_id'])) {
$category_id = nl2br($_REQUEST['category_id']);
}
$GLOBALS['log']->debug("CATEGORY ID: ".$category_id);
$nodes = PackageManager::getModuleLoaderCategoryPackages($category_id);
$GLOBALS['log']->debug(var_export($nodes, true));
echo 'result = ' . $json->encode(array('nodes' => $nodes));
}
/**
* Check the SugarDepot for updates for the given type as passed in via POST
* @param type the type to check for
* @return array return an array of releases for each given installed object if an update is found
*/
function checkForUpdates(){
$json = getJSONobj();
$type = '';
if(isset($_REQUEST['type'])) {
$type = nl2br($_REQUEST['type']);
}
$pm = new PackageManager();
$updates = $pm->checkForUpdates();
$nodes = array();
$release_map = array();
if(!empty($updates)){
foreach($updates as $update){
$update = PackageManager::fromNameValueList($update);
$nodes[] = array('label' => $update['name'], 'description' => $update['description'], 'version' => $update['version'], 'build_number' => $update['build_number'], 'id' => $update['id'], 'type' => $update['type']);
$release_map[$update['id']] = array('package_id' => $update['package_id'], 'category_id' => $update['category_id'], 'type' => $update['type']);
}
}
//patches
$filter = array(array('name' => 'type', 'value' => "'patch'"));
$releases = $pm->getReleases('', '', $filter);
if(!empty($releases['packages'])){
foreach($releases['packages'] as $update){
$update = PackageManager::fromNameValueList($update);
$nodes[] = array('label' => $update['name'], 'description' => $update['description'], 'version' => $update['version'], 'build_number' => $update['build_number'], 'id' => $update['id'], 'type' => $update['type']);
$release_map[$update['id']] = array('package_id' => $update['package_id'], 'category_id' => $update['category_id'], 'type' => $update['type']);
}
}
$_SESSION['ML_PATCHES'] = $release_map;
echo 'result = ' . $json->encode(array('updates' => $nodes));
}
function getLicenseText(){
$json = getJSONobj();
$file = '';
if(isset($_REQUEST['file'])) {
$file = hashToFile($_REQUEST['file']);
}
$GLOBALS['log']->debug("FILE : ".$file);
echo 'result = ' . $json->encode(array('license_display' => PackageManagerDisplay::buildLicenseOutput($file)));
}
/**
* build the list of modules that are currently in the staging area waiting to be installed
*/
function getPackagesInStaging(){
$packages = $this->_pm->getPackagesInStaging('module');
$json = getJSONobj();
echo 'result = ' . $json->encode(array('packages' => $packages));
}
/**
* build the list of modules that are currently in the staging area waiting to be installed
*/
function performInstall(){
$file = '';
if(isset($_REQUEST['file'])) {
$file = hashToFile($_REQUEST['file']);
}
if(!empty($file)){
$this->_pm->performInstall($file);
}
$json = getJSONobj();
echo 'result = ' . $json->encode(array('result' => 'success'));
}
function authenticate(){
$json = getJSONobj();
$username = '';
$password = '';
$servername = '';
$terms_checked = '';
if(isset($_REQUEST['username'])) {
$username = nl2br($_REQUEST['username']);
}
if(isset($_REQUEST['password'])) {
$password = nl2br($_REQUEST['password']);
}
if(isset($_REQUEST['servername'])) {
$servername = $_REQUEST['servername'];
}
if(isset($_REQUEST['terms_checked'])) {
$terms_checked = $_REQUEST['terms_checked'];
if($terms_checked == 'on')
$terms_checked = true;
}
if(!empty($username) && !empty($password)){
$password = md5($password);
$result = PackageManager::authenticate($username, $password, $servername, $terms_checked);
if(!is_array($result) && $result == true)
$status = 'success';
else
$status = $result['faultstring'];
}else{
$status = 'failed';
}
echo 'result = ' . $json->encode(array('status' => $status));
}
function getDocumentation(){
$json = getJSONobj();
$package_id = '';
$release_id = '';
if(isset($_REQUEST['package_id'])) {
$package_id = nl2br($_REQUEST['package_id']);
}
if(isset($_REQUEST['release_id'])) {
$release_id = nl2br($_REQUEST['release_id']);
}
$documents = PackageManager::getDocumentation($package_id, $release_id);
$GLOBALS['log']->debug("DOCUMENTS: ".var_export($documents, true));
echo 'result = ' . $json->encode(array('documents' => $documents));
}
function downloadedDocumentation(){
$json = getJSONobj();
$document_id = '';
if(isset($_REQUEST['document_id'])) {
$document_id = nl2br($_REQUEST['document_id']);
}
$GLOBALS['log']->debug("Downloading Document: ".$document_id);
PackageManagerComm::downloadedDocumentation($document_id);
echo 'result = ' . $json->encode(array('result' => 'true'));
}
function remove(){
$json = getJSONobj();
$file = '';
if(isset($_REQUEST['file'])) {
$file = urldecode(hashToFile($_REQUEST['file']));
}
$GLOBALS['log']->debug("FILE TO REMOVE: ".$file);
if(!empty($file)){
unlink($file);
}
echo 'result = ' . $json->encode(array('result' => 'true'));
}
}
?>

View File

@@ -0,0 +1,866 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
define("CREDENTIAL_CATEGORY", "ml");
define("CREDENTIAL_USERNAME", "username");
define("CREDENTIAL_PASSWORD", "password");
require_once('include/nusoap/nusoap.php');
require_once('include/utils/zip_utils.php');
require_once('ModuleInstall/PackageManager/PackageManagerDisplay.php');
require_once('ModuleInstall/ModuleInstaller.php');
require_once('include/entryPoint.php');
require_once('ModuleInstall/PackageManager/PackageManagerComm.php');
class PackageManager{
var $soap_client;
/**
* Constructor: In this method we will initialize the nusoap client to point to the hearbeat server
*/
function PackageManager(){
$this->db = & DBManagerFactory::getInstance();
}
function initializeComm(){
}
/**
* Obtain a promotion from SugarDepot
* @return string the string from the promotion
*/
function getPromotion(){
$name_value_list = PackageManagerComm::getPromotion();
if(!empty($name_value_list)){
$name_value_list = PackageManager::fromNameValueList($name_value_list);
return $name_value_list['description'];
}else {
return '';
}
}
/**
* Obtain a list of category/packages/releases for use within the module loader
*/
function getModuleLoaderCategoryPackages($category_id = ''){
$filter = array();
$filter = array('type' => "'module', 'theme', 'langpack'");
$filter = PackageManager::toNameValueList($filter);
return PackageManager::getCategoryPackages($category_id, $filter);
}
/**
* Obtain the list of category_packages from SugarDepot
* @return category_packages
*/
function getCategoryPackages($category_id = '', $filter = array()){
$results = PackageManagerComm::getCategoryPackages($category_id, $filter);
PackageManagerComm::errorCheck();
$nodes = array();
$nodes[$category_id]['packages'] = array();
if(!empty($results['categories'])){
foreach($results['categories'] as $category){
$mycat = PackageManager::fromNameValueList($category);
$nodes[$mycat['id']] = array('id' => $mycat['id'], 'label' => $mycat['name'], 'description' => $mycat['description'], 'type' => 'cat', 'parent' => $mycat['parent_id']);
$nodes[$mycat['id']]['packages'] = array();
}
}
if(!empty($results['packages'])){
$uh = new UpgradeHistory();
foreach($results['packages'] as $package){
$mypack = PackageManager::fromNameValueList($package);
$nodes[$mypack['category_id']]['packages'][$mypack['id']] = array('id' => $mypack['id'], 'label' => $mypack['name'], 'description' => $mypack['description'], 'category_id' => $mypack['category_id'], 'type' => 'package');
$releases = PackageManager::getReleases($category_id, $mypack['id'], $filter);
$arr_releases = array();
$nodes[$mypack['category_id']]['packages'][$mypack['id']]['releases'] = array();
if(!empty($releases['packages'])){
foreach($releases['packages'] as $release){
$myrelease = PackageManager::fromNameValueList($release);
//check to see if we already this one installed
$result = $uh->determineIfUpgrade($myrelease['id_name'], $myrelease['version']);
$enable = false;
if($result == true || is_array($result))
$enable = true;
$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);
}
}
//array_push($nodes[$mypack['category_id']]['packages'], $package_arr);
}
}
$GLOBALS['log']->debug("NODES". var_export($nodes, true));
return $nodes;
}
/**
* Get a list of categories from the SugarDepot
* @param category_id the category id of parent to obtain
* @param filter an array of filters to pass to limit the query
* @return array an array of categories for display on the client
*/
function getCategories($category_id, $filter = array()){
$nodes = array();
$results = PackageManagerComm::getCategories($category_id, $filter);
PackageManagerComm::errorCheck();
if(!empty($results['categories'])){
foreach($results['categories'] as $category){
$mycat = PackageManager::fromNameValueList($category);
$nodes[] = array('id' => $mycat['id'], 'label' => $mycat['name'], 'description' => $mycat['description'], 'type' => 'cat', 'parent' => $mycat['parent_id']);
}
}
return $nodes;
}
function getPackages($category_id, $filter = array()){
$nodes = array();
$results = PackageManagerComm::getPackages($category_id, $filter);
PackageManagerComm::errorCheck();
$packages = array();
//$xml = '';
//$xml .= '<packages>';
if(!empty($results['packages'])){
foreach($results['packages'] as $package){
$mypack = PackageManager::fromNameValueList($package);
$packages[$mypack['id']] = array('package_id' => $mypack['id'], 'name' => $mypack['name'], 'description' => $mypack['description'], 'category_id' => $mypack['category_id']);
$releases = PackageManager::getReleases($category_id, $mypack['id']);
$arr_releases = array();
foreach($releases['packages'] as $release){
$myrelease = PackageManager::fromNameValueList($release);
$arr_releases[$myrelease['id']] = array('release_id' => $myrelease['id'], 'version' => $myrelease['version'], 'description' => $myrelease['description'], 'category_id' => $mypack['category_id'], 'package_id' => $mypack['id']);
}
$packages[$mypack['id']]['releases'] = $arr_releases;
}
}
return $packages;
}
function getReleases($category_id, $package_id, $filter = array()){
$releases = PackageManagerComm::getReleases($category_id, $package_id, $filter);
PackageManagerComm::errorCheck();
return $releases;
}
/**
* Retrieve the package as specified by the $id from the heartbeat server
*
* @param category_id the category_id to which the release belongs
* @param package_id the package_id to which the release belongs
* @param release_id the release_id to download
* @return filename - the path to which the zip file was saved
*/
function download($category_id, $package_id, $release_id, $save_dir = ''){
$GLOBALS['log']->debug('RELEASE _ID: '.$release_id);
if(!empty($release_id)){
$filename = PackageManagerComm::addDownload($category_id, $package_id, $release_id);
if($filename){
$GLOBALS['log']->debug('RESULT: '.$filename);
PackageManagerComm::errorCheck();
$filepath = PackageManagerComm::performDownload($filename, $save_dir);
return $filepath;
/*if(!empty($result) && !empty($result['filename']) && !empty($save_dir)){
$GLOBALS['log']->debug('Saving Package to: '.$save_dir);
$GLOBALS['log']->debug('Saving package to the local file system:'.$result['filename']);
return write_encoded_file ($result, $save_dir);
}else{
return null;
}*/
}
}else{
return null;
}
}
/**
* Given the Mambo username, password, and download key attempt to authenticate, if
* successful then store these credentials
*
* @param username Mambo username
* @param password Mambo password
* @param systemname the user's download key
* @return true if successful, false otherwise
*/
function authenticate($username, $password, $systemname='', $terms_checked = true){
PackageManager::setCredentials($username, $password, $systemname);
PackageManagerComm::clearSession();
$result = PackageManagerComm::login($terms_checked);
if(is_array($result))
return $result;
else
return true;
}
function setCredentials($username, $password, $systemname){
$admin = new Administration();
$admin->retrieveSettings();
$admin->saveSetting(CREDENTIAL_CATEGORY, CREDENTIAL_USERNAME, $username);
$admin->saveSetting(CREDENTIAL_CATEGORY, CREDENTIAL_PASSWORD, $password);
if(!empty($systemname)){
$admin->saveSetting('system', 'name', $systemname);
}
}
function getCredentials(){
$admin = new Administration();
$admin->retrieveSettings(CREDENTIAL_CATEGORY, true);
$credentials = array();
$credentials['username'] = '';
$credentials['password'] = '';
$credentials['system_name'] = '';
if(!empty($admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_USERNAME])){
$credentials['username'] = $admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_USERNAME];
}
if(!empty($admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_USERNAME])){
$credentials['password'] = $admin->settings[CREDENTIAL_CATEGORY.'_'.CREDENTIAL_PASSWORD];
}
if(!empty($admin->settings['system_name'])){
$credentials['system_name'] = $admin->settings['system_name'];
}
return $credentials;
}
function getTermsAndConditions(){
return PackageManagerComm::getTermsAndConditions();
}
/**
* Retrieve documentation for the given release or package
*
* @param package_id the specified package to retrieve documentation
* @param release_id the specified release to retrieve documentation
*
* @return documents
*/
function getDocumentation($package_id, $release_id){
if(!empty($release_id) || !empty($package_id)){
$documents = PackageManagerComm::getDocumentation($package_id, $release_id);
return $documents;
}else{
return null;
}
}
/**
* Grab the list of installed modules and send that list to the depot.
* The depot will then send back a list of modules that need to be updated
*/
function checkForUpdates(){
$lists = $this->buildInstalledReleases(array('module'), true);
$updates = array();
if(!empty($lists)){
$updates = PackageManagerComm::checkForUpdates($lists);
}//fi
return $updates;
}
////////////////////////////////////////////////////////
/////////// HELPER FUNCTIONS
function toNameValueList($array){
$list = array();
foreach($array as $name=>$value){
$list[] = array('name'=>$name, 'value'=>$value);
}
return $list;
}
function toNameValueLists($arrays){
$lists = array();
foreach($arrays as $array){
$lists[] = PackageManager::toNameValueList($array);
}
return $lists;
}
function fromNameValueList($nvl){
$array = array();
foreach($nvl as $list){
$array[$list['name']] = $list['value'];
}
return $array;
}
function buildInstalledReleases($types = array('module')){
//1) get list of installed modules
$installeds = $this->getInstalled($types);
$releases = array();
foreach($installeds as $installed){
$releases[] = array('name' => $installed->name, 'id_name' => $installed->id_name, 'version' => $installed->version, 'filename' => $installed->filename, 'type' => $installed->type);
}
$lists = array();
$name_value_list = array();
if(!empty($releases)){
$lists = $this->toNameValueLists($releases);
}//fi
return $lists;
}
function buildPackageXML($package, $releases = array()){
$xml = '<package>';
$xml .= '<package_id>'.$package['id'].'</package_id>';
$xml .= '<name>'.$package['name'].'</name>';
$xml .= '<description>'.$package['description'].'</description>';
if(!empty($releases)){
$xml .= '<releases>';
foreach($releases['packages'] as $release){
$myrelease = PackageManager::fromNameValueList($release);
$xml .= '<release>';
$xml .= '<release_id>'.$myrelease['id'].'</release_id>';
$xml .= '<version>'.$myrelease['version'].'</version>';
$xml .= '<description>'.$myrelease['description'].'</description>';
$xml .= '<package_id>'.$package['id'].'</package_id>';
$xml .= '<category_id>'.$package['category_id'].'</category_id>';
$xml .= '</release>';
}
$xml .= '</releases>';
}
$xml .= '</package>';
return $xml;
}
//////////////////////////////////////////////////////////////////////
/////////// INSTALL SECTION
function extractFile( $zip_file, $file_in_zip, $base_tmp_upgrade_dir){
$my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
return( "$my_zip_dir/$file_in_zip" );
}
function extractManifest( $zip_file,$base_tmp_upgrade_dir ) {
global $sugar_config;
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
return( $this->extractFile( $zip_file, "manifest.php",$base_tmp_upgrade_dir ) );
}
function validate_manifest( $manifest ){
// takes a manifest.php manifest array and validates contents
global $subdirs;
global $sugar_version;
global $sugar_flavor;
global $mod_strings;
if( !isset($manifest['type']) ){
die($mod_strings['ERROR_MANIFEST_TYPE']);
}
$type = $manifest['type'];
$GLOBALS['log']->debug("Getting InstallType");
if( $this->getInstallType( "/$type/" ) == "" ){
$GLOBALS['log']->debug("Error with InstallType".$type);
die($mod_strings['ERROR_PACKAGE_TYPE']. ": '" . $type . "'." );
}
$GLOBALS['log']->debug("Passed with InstallType");
if( isset($manifest['acceptable_sugar_versions']) ){
$version_ok = false;
$matches_empty = true;
if( isset($manifest['acceptable_sugar_versions']['exact_matches']) ){
$matches_empty = false;
foreach( $manifest['acceptable_sugar_versions']['exact_matches'] as $match ){
if( $match == $sugar_version ){
$version_ok = true;
}
}
}
if( !$version_ok && isset($manifest['acceptable_sugar_versions']['regex_matches']) ){
$matches_empty = false;
foreach( $manifest['acceptable_sugar_versions']['regex_matches'] as $match ){
if( preg_match( "/$match/", $sugar_version ) ){
$version_ok = true;
}
}
}
if( !$matches_empty && !$version_ok ){
die( $mod_strings['ERROR_VERSION_INCOMPATIBLE'] . $sugar_version );
}
}
if( isset($manifest['acceptable_sugar_flavors']) && sizeof($manifest['acceptable_sugar_flavors']) > 0 ){
$flavor_ok = false;
foreach( $manifest['acceptable_sugar_flavors'] as $match ){
if( $match == $sugar_flavor ){
$flavor_ok = true;
}
}
if( !$flavor_ok ){
//die( $mod_strings['ERROR_FLAVOR_INCOMPATIBLE'] . $sugar_flavor );
}
}
}
function getInstallType( $type_string ){
// detect file type
global $subdirs;
$subdirs = array('full', 'langpack', 'module', 'patch', 'theme', 'temp');
foreach( $subdirs as $subdir ){
if( preg_match( "#/$subdir/#", $type_string ) ){
return( $subdir );
}
}
// return empty if no match
return( "" );
}
function performSetup($tempFile, $view = 'module', $display_messages = true){
global $sugar_config;
$base_filename = urldecode($tempFile);
$GLOBALS['log']->debug("BaseFileName: ".$base_filename);
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
$manifest_file = $this->extractManifest( $base_filename,$base_tmp_upgrade_dir);
$GLOBALS['log']->debug("Manifest: ".$manifest_file);
if($view == 'module')
$license_file = $this->extractFile($base_filename, 'LICENSE.txt', $base_tmp_upgrade_dir);
if(is_file($manifest_file)){
$GLOBALS['log']->debug("VALIDATING MANIFEST". $manifest_file);
require_once( $manifest_file );
$this->validate_manifest($manifest );
$upgrade_zip_type = $manifest['type'];
$GLOBALS['log']->debug("VALIDATED MANIFEST");
// exclude the bad permutations
if( $view == "module" ){
if ($upgrade_zip_type != "module" && $upgrade_zip_type != "theme" && $upgrade_zip_type != "langpack"){
$this->unlinkTempFiles();
if($display_messages)
die($mod_strings['ERR_UW_NOT_ACCEPTIBLE_TYPE']);
}
}elseif( $view == "default" ){
if($upgrade_zip_type != "patch" ){
$this->unlinkTempFiles();
if($display_messages)
die($mod_strings['ERR_UW_ONLY_PATCHES']);
}
}
$base_filename = preg_replace( "#\\\\#", "/", $base_filename );
$base_filename = basename( $base_filename );
mkdir_recursive( "$base_upgrade_dir/$upgrade_zip_type" );
$target_path = "$base_upgrade_dir/$upgrade_zip_type/$base_filename";
$target_manifest = remove_file_extension( $target_path ) . "-manifest.php";
if( isset($manifest['icon']) && $manifest['icon'] != "" ){
$icon_location = $this->extractFile( $tempFile ,$manifest['icon'], $base_tmp_upgrade_dir );
$path_parts = pathinfo( $icon_location );
copy( $icon_location, remove_file_extension( $target_path ) . "-icon." . $path_parts['extension'] );
}
if( copy( $tempFile , $target_path ) ){
copy( $manifest_file, $target_manifest );
if($display_messages)
$messages = '<script>ajaxStatus.flashStatus("' .$base_filename.$mod_strings['LBL_UW_UPLOAD_SUCCESS'] . ', 5000");</script>';
}else{
if($display_messages)
$messages = '<script>ajaxStatus.flashStatus("' .$mod_strings['ERR_UW_UPLOAD_ERROR'] . ', 5000");</script>';
}
}//fi
else{
$this->unlinkTempFiles();
if($display_messages)
die($mod_strings['ERR_UW_NO_MANIFEST']);
}
if(isset($messages))
return $messages;
}
function unlinkTempFiles() {
global $sugar_config;
@unlink($_FILES['upgrade_zip']['tmp_name']);
@unlink(getcwd().'/'.$sugar_config['upload_dir'].$_FILES['upgrade_zip']['name']);
}
function performInstall($file, $silent=true){
global $sugar_config;
global $mod_strings;
global $current_language;
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
if(!file_exists($base_tmp_upgrade_dir)){
mkdir_recursive($base_tmp_upgrade_dir, true);
}
$GLOBALS['log']->debug("INSTALLING: ".$file);
$mi = new ModuleInstaller();
$mi->silent = $silent;
$mod_strings = return_module_language($current_language, "Administration");
$GLOBALS['log']->debug("ABOUT TO INSTALL: ".$file);
if(preg_match("#.*\.zip\$#", $file)) {
$GLOBALS['log']->debug("1: ".$file);
// handle manifest.php
$target_manifest = remove_file_extension( $file ) . '-manifest.php';
include($target_manifest);
$GLOBALS['log']->debug("2: ".$file);
$unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
unzip($file, $unzip_dir );
$GLOBALS['log']->debug("3: ".$unzip_dir);
$id_name = $installdefs['id'];
$version = $manifest['version'];
$uh = new UpgradeHistory();
$previous_install = array();
if(!empty($id_name) & !empty($version))
$previous_install = $uh->determineIfUpgrade($id_name, $version);
$previous_version = (empty($previous_install['version'])) ? '' : $previous_install['version'];
$previous_id = (empty($previous_install['id'])) ? '' : $previous_install['id'];
if(!empty($previous_version)){
$mi->install($unzip_dir, true, $previous_version);
}else{
$mi->install($unzip_dir);
}
$GLOBALS['log']->debug("INSTALLED: ".$file);
$new_upgrade = new UpgradeHistory();
$new_upgrade->filename = $file;
$new_upgrade->md5sum = md5_file($file);
$new_upgrade->type = $manifest['type'];
$new_upgrade->version = $manifest['version'];
$new_upgrade->status = "installed";
//$new_upgrade->author = $manifest['author'];
$new_upgrade->name = $manifest['name'];
$new_upgrade->description = $manifest['description'];
$new_upgrade->id_name = $id_name;
$serial_manifest = array();
$serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
$serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
$serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
$new_upgrade->manifest = base64_encode(serialize($serial_manifest));
//$new_upgrade->unique_key = (isset($manifest['unique_key'])) ? $manifest['unique_key'] : '';
$new_upgrade->save();
//unlink($file);
}//fi
}
function performUninstall($name){
$uh = new UpgradeHistory();
$uh->name = $name;
$uh->id_name = $name;
$found = $uh->checkForExisting($uh);
if($found != null){
global $sugar_config;
global $mod_strings;
global $current_language;
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
if(!isset($GLOBALS['mi_remove_tables']))$GLOBALS['mi_remove_tables'] = true;
$unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
unzip($found->filename, $unzip_dir );
$mi = new ModuleInstaller();
$mi->silent = true;
$mi->uninstall( "$unzip_dir");
$found->delete();
unlink(remove_file_extension( $found->filename ) . '-manifest.php');
unlink($found->filename);
}
}
function getUITextForType( $type ){
if( $type == "full" ){
return( "Full Upgrade" );
}
if( $type == "langpack" ){
return( "Language Pack" );
}
if( $type == "module" ){
return( "Module" );
}
if( $type == "patch" ){
return( "Patch" );
}
if( $type == "theme" ){
return( "Theme" );
}
}
function getImageForType( $type ){
$icon = "";
switch( $type ){
case "full":
$icon = SugarThemeRegistry::current()->getImage("Upgrade", "" );
break;
case "langpack":
$icon = SugarThemeRegistry::current()->getImage("LanguagePacks", "" );
break;
case "module":
$icon = SugarThemeRegistry::current()->getImage("ModuleLoader", "" );
break;
case "patch":
$icon = SugarThemeRegistry::current()->getImage("PatchUpgrades", "" );
break;
case "theme":
$icon = SugarThemeRegistry::current()->getImage("Themes", "" );
break;
default:
break;
}
return( $icon );
}
function getPackagesInStaging($view = 'module'){
global $sugar_config;
global $current_language;
$uh = new UpgradeHistory();
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
$uContent = findAllFiles( "$base_upgrade_dir", array() , false, 'zip',$base_tmp_upgrade_dir);
//other variations of zip file i.e. ZIP, zIp,zIP,Zip,ZIp,ZiP
$extns = array( 'ZIP','ZIp','ZiP','Zip','zIP','zIp','ziP');
foreach($extns as $extn){
$uContent = array_merge($uContent,findAllFiles( "$base_upgrade_dir", array() , false, $extn,$base_tmp_upgrade_dir));
}
$upgrade_contents = array();
$content_values = array_values($uContent);
$alreadyProcessed = array();
foreach($content_values as $val){
if(empty($alreadyProcessed[$val])){
$upgrade_contents[] = $val;
$alreadyProcessed["$val"] = true;
}
}
$upgrades_available = 0;
$packages = array();
$mod_strings = return_module_language($current_language, "Administration");
foreach($upgrade_contents as $upgrade_content)
{
if(!preg_match("#.*\.zip\$#", strtolower($upgrade_content)) || preg_match("#.*./zips/.*#", strtolower($upgrade_content)))
{
continue;
}
$upgrade_content = clean_path($upgrade_content);
// Bug 22285 - fix for UNC paths
if ( substr($upgrade_content,0,2) == '\\\\' )
$upgrade_content = '\\\\'.$upgrade_content;
$the_base = basename($upgrade_content);
$the_md5 = md5_file($upgrade_content);
$md5_matches = $uh->findByMd5($the_md5);
$file_install = $upgrade_content;
if(0 == sizeof($md5_matches))
{
$target_manifest = remove_file_extension( $upgrade_content ) . '-manifest.php';
require_once($target_manifest);
$name = empty($manifest['name']) ? $upgrade_content : $manifest['name'];
$version = empty($manifest['version']) ? '' : $manifest['version'];
$published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
$icon = '';
$description = empty($manifest['description']) ? 'None' : $manifest['description'];
$uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
$type = $this->getUITextForType( $manifest['type'] );
$manifest_type = $manifest['type'];
$dependencies = array();
if( isset( $manifest['dependencies']) ){
$dependencies = $manifest['dependencies'];
}
//check dependencies first
if(!empty($dependencies)){
$uh = new UpgradeHistory();
$not_found = $uh->checkDependencies($dependencies);
if(!empty($not_found) && count($not_found) > 0){
$file_install = 'errors_'.$mod_strings['ERR_UW_NO_DEPENDENCY']."[".implode(',', $not_found)."]";
}//fi
}
if($view == 'default' && $manifest_type != 'patch')
{
continue;
}
if($view == 'module'
&& $manifest_type != 'module' && $manifest_type != 'theme' && $manifest_type != 'langpack')
{
continue;
}
if(empty($manifest['icon'])){
$icon = $this->getImageForType( $manifest['type'] );
}else{
$path_parts = pathinfo( $manifest['icon'] );
$icon = "<img src=\"" . remove_file_extension( $upgrade_content ) . "-icon." . $path_parts['extension'] . "\">";
}
$upgrades_available++;
// uploaded file in cache/upload
$fileS = explode('/', $upgrade_content);
$c = count($fileS);
$fileName = (isset($fileS[$c-1]) && !empty($fileS[$c-1])) ? $fileS[$c-1] : $fileS[$c-2];
$upload_file = $sugar_config['upload_dir'].$fileName;
$upgrade_content = urlencode($upgrade_content);
$upload_content = urlencode($upload_file);
$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);
}//fi
}//rof
return $packages;
}
function getLicenseFromFile($file){
global $sugar_config;
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
$license_file = $this->extractFile($file, 'LICENSE.txt', $base_tmp_upgrade_dir);
if(is_file($license_file)){
$fh = sugar_fopen($license_file, 'r');
$contents = fread($fh, filesize($license_file));
fclose($fh);
return $contents;
}else{
return null;
}
}
/**
* Run the query to obtain the list of installed types as specified by the type param
*
* @param type an array of types you would like to search for
* type options include (theme, langpack, module, patch)
*
* @return an array of installed upgrade_history objects
*/
function getInstalled($types = array('module')){
$uh = new UpgradeHistory();
$in = "";
for($i = 0; $i < count($types); $i++){
$in .= "'".$types[$i]."'";
if(($i+1) < count($types)){
$in .= ",";
}
}
$query = "SELECT * FROM ".$uh->table_name." WHERE type IN (".$in.")";
return $uh->getList($query);
}
function getinstalledPackages($types = array('module', 'langpack')){
global $sugar_config;
$installeds = $this->getInstalled($types);
$packages = array();
$upgrades_installed = 0;
$uh = new UpgradeHistory();
$base_upgrade_dir = $sugar_config['upload_dir'] . "/upgrades";
$base_tmp_upgrade_dir = "$base_upgrade_dir/temp";
foreach($installeds as $installed)
{
$populate = false;
$filename = from_html($installed->filename);
$date_entered = $installed->date_entered;
$type = $installed->type;
$version = $installed->version;
$uninstallable = false;
$link = "";
$description = $installed->description;
$name = $installed->name;
$enabled = true;
$enabled_string = 'ENABLED';
//if the name is empty then we should try to pull from manifest and populate upgrade_history_table
if(empty($name)){
$populate = true;
}
$upgrades_installed++;
switch($type)
{
case "theme":
case "langpack":
case "module":
case "patch":
if($populate){
$manifest_file = $this->extractManifest($filename, $base_tmp_upgrade_dir);
require_once($manifest_file);
$GLOBALS['log']->info("Filling in upgrade_history table");
$populate = false;
if( isset( $manifest['name'] ) ){
$name = $manifest['name'];
$installed->name = $name;
}
if( isset( $manifest['description'] ) ){
$description = $manifest['description'];
$installed->description = $description;
}
if(isset($installdefs) && isset( $installdefs['id'] ) ){
$id_name = $installdefs['id'];
$installed->id_name = $id_name;
}
$serial_manifest = array();
$serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
$serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
$serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
$installed->manifest = base64_encode(serialize($serial_manifest));
$installed->save();
}else{
$serial_manifest = unserialize(base64_decode($installed->manifest));
$manifest = $serial_manifest['manifest'];
}
if(($upgrades_installed==0 || $uh->UninstallAvailable($installeds, $installed))
&& is_file($filename) && !empty($manifest['is_uninstallable']))
{
$uninstallable = true;
}
$enabled = $installed->enabled;
if(!$enabled)
$enabled_string = 'DISABLED';
$file_uninstall = $filename;
if(!$uninstallable){
$file_uninstall = 'UNINSTALLABLE';
$enabled_string = 'UNINSTALLABLE';
}
$packages[] = array('name' => $name, 'version' => $version, 'type' => $type, 'published_date' => $date_entered, 'description' => $description, 'uninstallable' =>$uninstallable, 'file_install' => fileToHash($filename), 'file' => fileToHash( $file_uninstall ), 'enabled' => $enabled_string);
break;
default:
break;
}
}//rof
return $packages;
}
}
?>

View File

@@ -0,0 +1,308 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('include/nusoap/nusoap.php');
require_once('ModuleInstall/PackageManager/PackageManagerDownloader.php');
define("HTTPS_URL", "https://depot.sugarcrm.com/depot/SugarDepotSoap.php");
define("ACTIVE_STATUS", "ACTIVE");
class PackageManagerComm{
/**
* Initialize the soap client and store in the $GLOBALS object for use
*
* @param login designates whether we want to try to login after we initialize or not
*/
function initialize($login = true){
if(empty($GLOBALS['SugarDepot'])){
$GLOBALS['log']->debug('USING HTTPS TO CONNECT TO HEARTBEAT');
$soap_client = new nusoapclient(HTTPS_URL, false);
$ping = $soap_client->call('sugarPing', array());
$GLOBALS['SugarDepot'] = $soap_client;
}
//if we do not have a session, then try to login
if($login && empty($_SESSION['SugarDepotSessionID'])){
PackageManagerComm::login();
}
}
/**
* Check for errors in the response or error_str
*/
function errorCheck(){
if(!empty($GLOBALS['SugarDepot']->error_str)){
$GLOBALS['log']->fatal($GLOBALS['SugarDepot']->error_str);
$GLOBALS['log']->fatal($GLOBALS['SugarDepot']->response);
}
}
/**
* Set the credentials for use during login
*
* @param username Mambo username
* @param password Mambo password
* @param download_key User's download key
*/
function setCredentials($username, $password, $download_key){
$_SESSION['SugarDepotUsername'] = $username;
$_SESSION['SugarDepotPassword'] = $password;
$_SESSION['SugarDepotDownloadKey'] = $download_key;
}
/**
* Clears out the session so we can reauthenticate.
*/
function clearSession(){
$_SESSION['SugarDepotSessionID'] = null;
unset($_SESSION['SugarDepotSessionID']);
}
/////////////////////////////////////////////////////////
////////// BEGIN: Base Functions for Communicating with the depot
/**
* Login to the depot
*
* @return true if successful, false otherwise
*/
function login($terms_checked = true){
if(empty($_SESSION['SugarDepotSessionID'])){
global $license;
$GLOBALS['log']->debug("Begin SugarDepot Login");
PackageManagerComm::initialize(false);
require('sugar_version.php');
require('config.php');
$credentials = PackageManager::getCredentials();
if(empty($license))loadLicense();
$info = sugarEncode('2813', serialize(getSystemInfo(true)));
$pm = new PackageManager();
$installed = $pm->buildInstalledReleases();
$installed = base64_encode(serialize($installed));
$params = array('installed_modules' => $installed, 'terms_checked' => $terms_checked, 'system_name' => $credentials['system_name']);
$terms_version = (!empty($_SESSION['SugarDepot_TermsVersion']) ? $_SESSION['SugarDepot_TermsVersion'] : '');
if(!empty($terms_version))
$params['terms_version'] = $terms_version;
$result = $GLOBALS['SugarDepot']->call('depotLogin', array(array('user_name' => $credentials['username'], 'password' => $credentials['password']),'info'=>$info, 'params' => $params));
PackageManagerComm::errorCheck();
if(!is_array($result))
$_SESSION['SugarDepotSessionID'] = $result;
$GLOBALS['log']->debug("End SugarDepot Login");
return $result;
}
else
return $_SESSION['SugarDepotSessionID'];
}
/**
* Logout from the depot
*/
function logout(){
PackageManagerComm::initialize();
$result = $GLOBALS['SugarDepot']->call('depotLogout', array('session_id' => $_SESSION['SugarDepotSessionID']));
}
/**
* Get all promotions from the depot
*/
function getPromotion(){
PackageManagerComm::initialize();
//check for fault first and then return
$name_value_list = $GLOBALS['SugarDepot']->call('depotGetPromotion', array('session_id' => $_SESSION['SugarDepotSessionID']));
return $name_value_list;
}
/**
* A generic function which given a category_id some filter will
* return an object which contains categories and packages
*
* @param category_id the category_id to fetch
* @param filter a filter which will limit theh number of results returned
* @return categories_and_packages
* @see categories_and_packages
*/
function getCategoryPackages($category_id, $filter = array()){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotGetCategoriesPackages', array('session_id' => $_SESSION['SugarDepotSessionID'], 'category_id' => $category_id, 'filter' => $filter));
}
/**
* Return a list of child categories to the parent specified in category_id
*
* @param category_id the parent category_id
* @param filter a filter which will limit theh number of results returned
* @return categories_and_packages
* @see categories_and_packages
*/
function getCategories($category_id, $filter = array()){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotGetCategories', array('session_id' => $_SESSION['SugarDepotSessionID'], 'category_id' => $category_id, 'filter' => $filter));
}
/**
* Return a list of packages which belong to the parent category_id
*
* @param category_id the category_id to fetch
* @param filter a filter which will limit theh number of results returned
* @return packages
* @see packages
*/
function getPackages($category_id, $filter = array()){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotGetPackages', array('session_id' => $_SESSION['SugarDepotSessionID'], 'category_id' => $category_id, 'filter' => $filter));
}
/**
* Return a list of releases belong to a package
*
* @param category_id the category_id to fetch
* @param package_id the package id which the release belongs to
* @return packages
* @see packages
*/
function getReleases($category_id, $package_id, $filter = array()){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotGetReleases', array('session_id' => $_SESSION['SugarDepotSessionID'], 'category_id' => $category_id, 'package_id' => $package_id, 'filter' => $filter));
}
/**
* Download a given release
*
* @param category_id the category_id to fetch
* @param package_id the package id which the release belongs to
* @param release_id the release we want to download
* @return download
* @see download
*/
function download($category_id, $package_id, $release_id){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotDownloadRelease', array('session_id' => $_SESSION['SugarDepotSessionID'], 'category_id' => $category_id, 'package_id' => $package_id, 'release_id' => $release_id));
}
/**
* Add a requested download to the queue
*
* @param category_id the category_id to fetch
* @param package_id the package id which the release belongs to
* @param release_id the release we want to download
* @return the filename to download
*/
function addDownload($category_id, $package_id, $release_id){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotAddDownload', array('session_id' => $_SESSION['SugarDepotSessionID'], 'category_id' => $category_id, 'package_id' => $package_id, 'release_id' => $release_id, 'download_key' => '123'));
}
/**
* Call the PackageManagerDownloader function which uses curl in order to download the specified file
*
* @param filename the file to download
* @return path to downloaded file
*/
function performDownload($filename, $save_dir){
PackageManagerComm::initialize();
//check for fault
$GLOBALS['log']->debug("Performing download from depot: Session ID: ".$_SESSION['SugarDepotSessionID']." Filename: ".$filename);
return PackageManagerDownloader::download($_SESSION['SugarDepotSessionID'], $filename, $save_dir);
}
/**
* Retrieve documentation for the given release or package
*
* @param package_id the specified package to retrieve documentation
* @param release_id the specified release to retrieve documentation
*
* @return documents
*/
function getDocumentation($package_id, $release_id){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotGetDocumentation', array('session_id' => $_SESSION['SugarDepotSessionID'], 'package_id' => $package_id, 'release_id' => $release_id));
}
function getTermsAndConditions(){
PackageManagerComm::initialize(false);
return $GLOBALS['SugarDepot']->call('depotTermsAndConditions',array());
}
/**
* Log that the user has clicked on a document
*
* @param document_id the document the user has clicked on
*/
function downloadedDocumentation($document_id){
PackageManagerComm::initialize();
//check for fault
$GLOBALS['log']->debug("Logging Document: ".$document_id);
$GLOBALS['SugarDepot']->call('depotDownloadedDocumentation', array('session_id' => $_SESSION['SugarDepotSessionID'], 'document_id' => $document_id));
}
/**
* Send the list of installed objects, could be patches, or modules, .. to the depot and allow the depot to send back
* a list of corresponding updates
*
* @param objects_to_check an array of name_value_lists which contain the appropriate values
* which will allow the depot to check for updates
*
* @return array of name_value_lists of corresponding updates
*/
function checkForUpdates($objects_to_check){
PackageManagerComm::initialize();
//check for fault
return $GLOBALS['SugarDepot']->call('depotCheckForUpdates', array('session_id' => $_SESSION['SugarDepotSessionID'], 'objects' => $objects_to_check));
}
/**
* Ping the server to determine if we have established proper communication
*
* @return true if we can communicate with the server and false otherwise
*/
function isAlive(){
PackageManagerComm::initialize(false);
$status = $GLOBALS['SugarDepot']->call('sugarPing', array());
if(empty($status) || $GLOBALS['SugarDepot']->getError() || $status != ACTIVE_STATUS){
return false;
}else{
return true;
}
}
////////// END: Base Functions for Communicating with the depot
////////////////////////////////////////////////////////
}
?>

View File

@@ -0,0 +1,607 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
require_once('ModuleInstall/PackageManager/PackageManager.php');
require_once('include/ytree/Tree.php');
require_once('include/ytree/Node.php');
require_once('ModuleInstall/PackageManager/ListViewPackages.php');
class PackageManagerDisplay{
/**
* A Static method to Build the display for the package manager
*
* @param String form1 - the form to display for manual downloading
* @param String hidden_fields - the hidden fields related to downloading a package
* @param String form_action - the form_action to be used when downloading from the server
* @param String types - the types of objects we will request from the server
* @param String active_form - the form to display first
* @return String - a string of html which will be used to display the forms
*/
function buildPackageDisplay($form1, $hidden_fields, $form_action, $types = array('module'), $active_form = 'form1', $install = false){
global $current_language;
$mod_strings = return_module_language($current_language, "Administration");
global $app_strings;
global $sugar_version, $sugar_config;
$app_strings = return_application_language($current_language);
$ss = new Sugar_Smarty();
$ss->assign('FORM_1_PLACE_HOLDER', $form1);
$ss->assign('form_action', $form_action);
$ss->assign('hidden_fields', $hidden_fields);
$result = PackageManagerDisplay::getHeader();
$header_text = $result['text'];
$isAlive = $result['isAlive'];
$show_login = $result['show_login'];
$mi_errors = ModuleInstaller::getErrors();
$error_html = "";
if(!empty($mi_errors)){
$error_html = "<tr><td><span>";
foreach($mi_errors as $error){
$error_html .= "<font color='red'>".$error."</font><br>";
}
$error_html .= "</span></td></tr>";
}
$form2 = "<table class='tabForm' width='100%' cellpadding='0' cellspacing='0' width='100%' border='0'>";
$form2 .= $error_html;
if(!$isAlive)
$form2 .= "<tr><td><span id='span_display_html'>".$header_text."</span></td></tr>";
$form2 .= "</table>";
$tree = null;
//if($isAlive){
$tree = PackageManagerDisplay::buildTreeView('treeview', $isAlive);
$tree->tree_style= 'include/ytree/TreeView/css/check/tree.css';
$ss->assign('TREEHEADER',$tree->generate_header());
//}
//$form2 .= PackageManagerDisplay::buildLoginPanel($mod_strings);
$form2 .= "<table class='tabForm' cellpadding='0' cellspacing='0' width='100%' border='0'>";
$form2 .= "<tr><td></td><td align='left'>";
if($isAlive){
$form2 .= "<input type='button' id='modifCredentialsBtn' class='button' onClick='PackageManager.showLoginDialog(true);' value='".$mod_strings['LBL_MODIFY_CREDENTIALS']."'>";
}else{
$form2 .= "<input type='button' id='modifCredentialsBtn' class='button' onClick='PackageManager.showLoginDialog(true);' value='".$mod_strings['LBL_MODIFY_CREDENTIALS']."'style='display:none;'>";
}
$form2 .= "</td><td align='left'><div id='workingStatusDiv' style='display:none;'>".SugarThemeRegistry::current()->getImage("sqsWait","border='0' align='bottom'")."</div></td><td align='right'>";
if($isAlive){
$form2 .= "<slot><a class=\"listViewTdToolsS1\" id='href_animate' onClick=\"PackageManager.toggleDiv('span_animate_server_div', 'catview');\"><span id='span_animate_server_div'><img src='".SugarThemeRegistry::current()->getImageURL('basic_search.gif')."' width='8' height='8' border='0'>&nbsp;Collapse</span></a></slot>";
}else{
$form2 .= "<slot><a class=\"listViewTdToolsS1\" id='href_animate' onClick=\"PackageManager.toggleDiv('span_animate_server_div', 'catview');\"><span id='span_animate_server_div' style='display:none;'><img src='".SugarThemeRegistry::current()->getImageURL('basic_search.gif')."' width='8' height='8' border='0'>&nbsp;Collapse</span></a></slot>";
}
$form2 .= "</td></tr></table>";
$form2 = ''; //Commenting out the form as part of sugar depot hiding.
$ss->assign('installation', ($install ? 'true' : 'false'));
$mod_strings = return_module_language($current_language, "Administration");
$ss->assign('MOD', $mod_strings);
$ss->assign('module_load', 'true');
$ss->assign('scripts', PackageManagerDisplay::getDisplayScript($install));
$show_login = false; //hiding install from sugar
$ss->assign('MODULE_SELECTOR', PackageManagerDisplay::buildGridOutput($tree, $mod_strings, $isAlive, $show_login));
$ss->assign('FORM_2_PLACE_HOLDER', $form2);
$ss->assign('MOD', $mod_strings);
$descItemsInstalled = $mod_strings['LBL_UW_DESC_MODULES_INSTALLED'];
$ss->assign('INSTALLED_PACKAGES_HOLDER', PackageManagerDisplay::buildInstalledGrid($mod_strings, $types));
$str = $ss->fetch('ModuleInstall/PackageManager/tpls/PackageForm.tpl');
return $str;
}
/**
* A Static method to Build the display for the package manager
*
* @param String form1 - the form to display for manual downloading
* @param String hidden_fields - the hidden fields related to downloading a package
* @param String form_action - the form_action to be used when downloading from the server
* @param String types - the types of objects we will request from the server
* @param String active_form - the form to display first
* @return String - a string of html which will be used to display the forms
*/
function buildPatchDisplay($form1, $hidden_fields, $form_action, $types = array('module'), $active_form = 'form1'){
global $current_language;
$mod_strings = return_module_language($current_language, "Administration");
$ss = new Sugar_Smarty();
$ss->assign('FORM_1_PLACE_HOLDER', $form1);
$ss->assign('form_action', $form_action);
$ss->assign('hidden_fields', $hidden_fields);
$mod_strings = return_module_language($current_language, "Administration");
$ss->assign('MOD', $mod_strings);
$result = PackageManagerDisplay::getHeader();
$header_text = $result['text'];
$isAlive = $result['isAlive'];
$show_login = $result['show_login'];
$display = 'none';
//if($isAlive){
$display = 'block';
//}
$form2 = "<table class='tabForm' width='100%' cellpadding='0' cellspacing='0' width='100%' border='0'>";
if(!$isAlive)
$form2 .= "<tr><td><span id='span_display_html'>".$header_text."</span></td></tr>";
$form2 .= "</table>";
$form2 .= "<table width='100%'><tr><td align='left'>";
if($show_login){
$form2 .= "<input type='button' class='button' onClick='PackageManager.showLoginDialog(true);' value='".$mod_strings['LBL_MODIFY_CREDENTIALS']."'>";
}
$form2 .= "</td><td align='right'><div id='workingStatusDiv' style='display:none;'>".SugarThemeRegistry::current()->getImage("sqsWait","border='0' align='bottom'")."</div></td></tr><tr><td colspan='2'>";
$loginViewStyle = ($isAlive ? 'none' : 'block');
$selectViewStyle = ($isAlive ? 'block' : 'none');
$form2 .= "<div id='selectView' style='display:".$selectViewStyle."'>";
$form2 .= " <div id='patch_downloads' class='ygrid-mso' style='height:205px; display: ".$display.";'></div>";
$form2 .= "</div>";
if(!$show_login)
$loginViewStyle = 'none';
//$form2 .= "<div id='loginView' style='display:".$loginViewStyle."'>";
//$form2 .= PackageManagerDisplay::buildLoginPanel($mod_strings, $isAlive);
//$form2 .= "</div>";
$form2 .= "</td></tr></table>";
$form2 = '';
$packages = array();
$releases = array();
if($isAlive){
$filter = array();
$count = count($types);
$index = 1;
$type_str = '"';
foreach($types as $type){
$type_str .= "'".$type."'";
if($index < $count)
$type_str .= ",";
$index++;
}
$type_str .= '"';
$filter = array('type' => $type_str);
$filter = PackageManager::toNameValueList($filter);
$pm = new PackageManager();
/*if(in_array('patch', $types)){
$releases = $pm->getReleases('3', '3', $filter);
}else{
$releases = $pm->getReleases('', '', $filter);
}*/
}
if($form_action == 'install.php' && (empty($releases) || count($releases['packages']) == 0)){
//return false;
}
$tree = PackageManagerDisplay::buildTreeView('treeview', $isAlive);
$tree->tree_style= 'include/ytree/TreeView/css/check/tree.css';
$ss->assign('TREEHEADER',$tree->generate_header());
$ss->assign('module_load', 'false');
$ss->assign('MODULE_SELECTOR', PackageManagerDisplay::buildGridOutput($tree, $mod_strings, $isAlive, $show_login));
$ss->assign('FORM_2_PLACE_HOLDER', $form2);
$ss->assign('scripts', PackageManagerDisplay::getDisplayScript(false, 'patch', $releases, $types, $isAlive));
$str = $ss->fetch('ModuleInstall/PackageManager/tpls/PackageForm.tpl');
return $str;
}
function buildInstalledGrid($mod_strings, $types = array('modules')){
$descItemsInstalled = $mod_strings['LBL_UW_DESC_MODULES_INSTALLED'];
$output = '<table width="100%" border="0" cellspacing="0" cellpadding="0" ><tr><td align="left">'.$descItemsInstalled.'</td>';
$output .= '</td></tr></table>';
$output .= "<table width='100%'><tr><td ><div id='installed_grid' class='ygrid-mso' style='height:205px;'></div></td></tr></table>";
return $output;
}
function buildLoginPanel($mod_strings, $display_cancel){
$credentials = PackageManager::getCredentials();
$output = "<div id='login_panel'><div class='hd'><b>".$mod_strings['HDR_LOGIN_PANEL']."</b></div>";
$output .= "<div class='bd'><form><table><tr><td>".$mod_strings['LBL_USERNAME']."</td><td><input type='text' name='login_panel_username' id='login_panel_username' value='".$credentials['username']."'></td><td><a href='http://www.sugarcrm.com/crm/index.php?option=com_registration&task=register' target='blank'>".$mod_strings['LNK_NEW_ACCOUNT']."</a></td>";
$output .= "</tr><tr><td>".$mod_strings['LBL_PASSWORD']."</td><td><input type='password' name='login_panel_password' id='login_panel_password'></td><td><a href='http://www.sugarcrm.com/crm/component/option,com_registration/Itemid,0/task,lostPassword/' target='blank'>".$mod_strings['LNK_FORGOT_PASS']."</a></td>";
$terms = PackageManager::getTermsAndConditions();
$output .= "</tr><tr><td colspan='6' valign='top'><b>".$mod_strings['LBL_TERMS_AND_CONDITIONS']."</b><br><textarea readonly cols=80 rows=8>" . $terms['terms'] . '</textarea></td>';
$_SESSION['SugarDepot_TermsVersion'] = (!empty($terms['version']) ? $terms['version'] : '');
$output .= "</td></tr><tr><td colspan='6'><input class='checkbox' type='checkbox' name='cb_terms' id='cb_terms' onclick='if(this.checked){this.form.panel_login_button.disabled=false;}else{this.form.panel_login_button.disabled=true;}'>".$mod_strings['LBL_ACCEPT_TERMS']."</td></tr><tr>";
$output .= "<td align='left'>";
$output .= "<input type='button' id='panel_login_button' name='panel_login_button' value='Login' class='button' onClick='PackageManager.authenticate(this.form.login_panel_username.value, this.form.login_panel_password.value, \"\",\"" . $terms['version'] . "\");' disabled>";
if($display_cancel){
$output .= "&nbsp;<input type='button' id='panel_cancel_button' value='Cancel' class='button' onClick='PackageManager.showLoginDialog(false);'>";
}
$output .= "</td><td></td></tr>";
$output .= "<tr></td><td></td></tr>";
$output .= "</table></div>";
$output .= "<div class='ft'></div></form></div>";
return $output;
}
/**
* Build html in order to display the grids relevant for module loader
*
* @param Tree tree - the tree which we are using to display the categories
* @param Array mod_strings - the local mod strings to display
* @return String - a string of html
*/
function buildGridOutput($tree, $mod_strings, $display = true, $show_login = true){
$output = "<div id='catview'>";
$loginViewStyle = ($display ? 'none' : 'block');
$selectViewStyle = ($display ? 'block' : 'none');
$output .= "<div id='selectView' style='display:".$selectViewStyle."'>";
//if($display){
$output .= "<table border=0 width='100%' class='moduleTitle'><tr><td width='100%' valign='top'>";
$output .= "<div id='treeview'>";
$output .= $tree->generate_nodes_array();
$output .= "</div>";
$output .= "</td></tr>";
$output .= "<tr><td width='100%'>";
$output .= "<div id='tabs1'></div>";
$output .= "</td></tr>";
$output .= "<tr><td width='100%' align='left'>";
$output .= "<input type='button' class='button' value='Download Selected' onClick='PackageManager.download();'>";
$output .= "</td></tr></table>";
// }
$output .= "</div>";
if(!$show_login)
$loginViewStyle = 'none';
// $output .= "<div id='loginView' style='display:".$loginViewStyle."'>";
// jchi ,#24296 :commented code because we are currently not using depot, in the future this may change so you can put this code back in.
//$output .= PackageManagerDisplay::buildLoginPanel($mod_strings, $display);
//$output .= "</div>";
//$output .= "<table width='100%' class='moduleTitle' border=1><tr><td><div id='patch_downloads' class='ygrid-mso' style='height:205px;'></div></td></tr></table>";
$output .= "</div>";
return $output;
}
/**
* A Static method used to build the initial treeview when the page is first displayed
*
* @param String div_id - this div in which to display the tree
* @return Tree - the tree that is built
*/
function buildTreeView($div_id, $isAlive = true){
$tree = new Tree($div_id);
$nodes = array();
if($isAlive)
$nodes = PackageManager::getCategories('');
foreach($nodes as $arr_node){
$node = new Node($arr_node['id'], $arr_node['label']);
$node->dynamicloadfunction = 'PackageManager.loadDataForNodeForPackage';
$node->expanded = false;
$node->dynamic_load = true;
$node->set_property('href',"javascript:PackageManager.catClick('treeview');");
$tree->add_node($node);
$node->set_property('description', $arr_node['description']);
}
return $tree;
}
/**
* A Static method used to obtain the div for the license
*
* @param String license_file - the path to the license file
* @param String form_action - the form action when accepting the license file
* @param String next_step - the value for the next step in the installation process
* @param String zipFile - a string representing the path to the zip file
* @param String type - module/patch....
* @param String manifest - the path to the manifest file
* @param String modify_field - the field to update when the radio button is changed
* @return String - a form used to display the license
*/
function getLicenseDisplay($license_file, $form_action, $next_step, $zipFile, $type, $manifest, $modify_field){
global $current_language;
$mod_strings = return_module_language($current_language, "Administration");
$fh = sugar_fopen($license_file, 'r');
$contents = fread($fh, filesize($license_file));
fclose($fh);
$div_id = urlencode($zipFile);
$display = "<form name='delete{$zipFile}' action='{$form_action}' method='POST'>";
$display .= "<input type='hidden' name='current_step' value='{$next_step}'>";
$display .= "<input type='hidden' name='languagePackAction' value='{$type}'>";
$display .= "<input type='hidden' name='manifest' value='\".urlencode($manifest).\"'>";
$display .= "<input type='hidden' name='zipFile' value='\".urlencode($zipFile).\"'>";
$display .= "<table><tr>";
$display .= "<td align=\"left\" valign=\"top\" colspan=2>";
$display .= "<b><font color='red' >{$mod_strings['LBL_MODULE_LICENSE']}</font></b>";
$display .= "</td>";
$display .= "<td>";
$display .= "<slot><a class=\"listViewTdToolsS1\" id='href_animate' onClick=\"PackageManager.toggleLowerDiv('span_animate_div_$div_id', 'span_license_div_$div_id', 350, 0);\"><span id='span_animate_div_$div_id'<img src='".SugarThemeRegistry::current()->getImageURL('advanced_search.gif')."' width='8' height='8' alt='Advanced' border='0'>&nbsp;Expand</span></a></slot></td>";
$display .= "</td>";
$display .= "</tr>";
$display .= "</table>";
$display .= "<div id='span_license_div_$div_id' style=\"display: none;\">";
$display .= "<table>";
$display .= "<tr>";
$display .= "<td align=\"left\" valign=\"top\" colspan=2>";
$display .= "<textarea cols=\"100\" rows=\"8\">{$contents}</textarea>";
$display .= "</td>";
$display .= "</tr>";
$display .= "<tr>";
$display .= "<td align=\"left\" valign=\"top\" colspan=2>";
$display .= "<input type='radio' id='radio_license_agreement_accept' name='radio_license_agreement' value='accept' onClick=\"document.getElementById('$modify_field').value = 'yes';\">{$mod_strings['LBL_ACCEPT']}&nbsp;";
$display .= "<input type='radio' id='radio_license_agreement_reject' name='radio_license_agreement' value='reject' checked onClick=\"document.getElementById('$modify_field').value = 'no';\">{$mod_strings['LBL_DENY']}";
$display .= "</td>";
$display .= "</tr>";
$display .= "</table>";
$display .= "</div>";
$display .= "</form>";
return $display;
}
/**
* A Static method used to generate the javascript for the page
*
* @return String - the javascript required for the page
*/
function getDisplayScript($install = false, $type = 'module', $releases = null, $types = array(), $isAlive = true){
global $sugar_version, $sugar_config;
global $current_language;
$mod_strings = return_module_language($current_language, "Administration");
$ss = new Sugar_Smarty();
$ss->assign('MOD', $mod_strings);
if(!$install){
$install = 0;
}
$ss->assign('INSTALLATION', $install);
$ss->assign('WAIT_IMAGE', SugarThemeRegistry::current()->getImage("loading","border='0' align='bottom'"));
$ss->assign('sugar_version', $sugar_version);
$ss->assign('js_custom_version', $sugar_config['js_custom_version']);
$ss->assign('IS_ALIVE', $isAlive);
//if($type == 'patch' && $releases != null){
if($type == 'patch'){
$ss->assign('module_load', 'false');
$patches = PackageManagerDisplay::createJavascriptPackageArray($releases);
$ss->assign('PATCHES', $patches);
$ss->assign('GRID_TYPE', implode(',', $types));
}else{
$pm = new PackageManager();
$releases = $pm->getPackagesInStaging();
$patches = PackageManagerDisplay::createJavascriptModuleArray($releases);
$ss->assign('PATCHES', $patches);
$installeds = $pm->getinstalledPackages();
$patches = PackageManagerDisplay::createJavascriptModuleArray($installeds, 'mti_installed_data');
$ss->assign('INSTALLED_MODULES', $patches);
$ss->assign('UPGARDE_WIZARD_URL', 'index.php?module=UpgradeWizard&action=index');
$ss->assign('module_load', 'true');
}
if(!empty($GLOBALS['ML_STATUS_MESSAGE']))
$ss->assign('ML_STATUS_MESSAGE',$GLOBALS['ML_STATUS_MESSAGE']);
//Bug 24064. Checking and Defining labels since these might not be cached during Upgrade
if(!isset($mod_strings['LBL_ML_INSTALL']) || empty($mod_strings['LBL_ML_INSTALL'])){
$mod_strings['LBL_ML_INSTALL'] = 'Install';
}
if(!isset($mod_strings['LBL_ML_ENABLE_OR_DISABLE']) || empty($mod_strings['LBL_ML_ENABLE_OR_DISABLE'])) {
$mod_strings['LBL_ML_ENABLE_OR_DISABLE'] = 'Enable/Disable';
}
if(!isset($mod_strings['LBL_ML_DELETE'])|| empty($mod_strings['LBL_ML_DELETE'])){
$mod_strings['LBL_ML_DELETE'] = 'Delete';
}
//Add by jchi 6/23/2008 to fix the bug 21667
$filegrid_column_ary = array(
'Name' => $mod_strings['LBL_ML_NAME'],
'Install' => $mod_strings['LBL_ML_INSTALL'],
'Delete' => $mod_strings['LBL_ML_DELETE'],
'Type' => $mod_strings['LBL_ML_TYPE'],
'Version' => $mod_strings['LBL_ML_VERSION'],
'Published' => $mod_strings['LBL_ML_PUBLISHED'],
'Uninstallable' => $mod_strings['LBL_ML_UNINSTALLABLE'],
'Description' => $mod_strings['LBL_ML_DESCRIPTION']
);
$filegridinstalled_column_ary = array(
'Name' => $mod_strings['LBL_ML_NAME'],
'Install' => $mod_strings['LBL_ML_INSTALL'],
'Action' => $mod_strings['LBL_ML_ACTION'],
'Enable_Or_Disable' => $mod_strings['LBL_ML_ENABLE_OR_DISABLE'],
'Type' => $mod_strings['LBL_ML_TYPE'],
'Version' => $mod_strings['LBL_ML_VERSION'],
'Date_Installed' => $mod_strings['LBL_ML_INSTALLED'],
'Uninstallable' => $mod_strings['LBL_ML_UNINSTALLABLE'],
'Description' => $mod_strings['LBL_ML_DESCRIPTION']
);
$ss->assign('ML_FILEGRID_COLUMN',$filegrid_column_ary);
$ss->assign('ML_FILEGRIDINSTALLED_COLUMN',$filegridinstalled_column_ary);
//end
$str = $ss->fetch('ModuleInstall/PackageManager/tpls/PackageManagerScripts.tpl');
return $str;
}
function createJavascriptPackageArray($releases){
$output = "var mti_data = [";
$count = count($releases);
$index = 1;
if(!empty($releases['packages'])){
foreach($releases['packages'] as $release){
$release = PackageManager::fromNameValueList($release);
$output .= "[";
$output .= "'".$release['description']."', '".$release['version']."', '".$release['build_number']."', '".$release['id']."'";
$output .= "]";
if($index < $count)
$output .= ",";
$index++;
}
}
$output .= "]\n;";
return $output;
}
function createJavascriptModuleArray($modules, $variable_name = 'mti_data'){
$output = "var ".$variable_name." = [";
$count = count($modules);
$index = 1;
if(!empty($modules)){
foreach($modules as $module){
$output .= "[";
$output .= "'".$module['name']."', '".$module['file_install']."', '".$module['file']."', '";
if(!empty($module['enabled']))
$output .= $module['enabled'].'_'.$module['file']."', '";
$description = js_escape($module['description']);
$output .= $module['type']."', '".$module['version']."', '".$module['published_date']."', '".$module['uninstallable']."', '".$description."'".(isset($module['upload_file'])?" , '".$module['upload_file']."']":"]");
if($index < $count)
$output .= ",";
$index++;
}
}
$output .= "]\n;";
return $output;
}
/**
* This method is meant to be used to display the license agreement inline on the page
* if the system would like to perform the installation on the same page via an Ajax call
*/
function buildLicenseOutput($file){
global $current_language;
$mod_strings = return_module_language($current_language, "Administration");
$contents = '';
$pm = new PackageManager();
$contents = $pm->getLicenseFromFile($file);
$ss = new Sugar_Smarty();
$ss->assign('MOD', $mod_strings);
$ss->assign('LICENSE_CONTENTS', $contents);
$ss->assign('FILE', $file);
$str = $ss->fetch('ModuleInstall/PackageManagerLicense.tpl');
$GLOBALS['log']->debug('LICENSE OUTPUT: '.$str);
return $str;
}
function getHeader(){
global $current_language;
$mod_strings = return_module_language($current_language, "Administration");
$header_text = '';
$isAlive = false;
$show_login = false;
if(!function_exists('curl_init') && $show_login){
$header_text = "<font color='red'><b>".$mod_strings['ERR_ENABLE_CURL']."</b></font>";
$show_login = false;
}else{
$credentials = PackageManager::getCredentials();
if(empty($credentials['username']) || empty($credentials['password'])){
//$header_text = "<font color='red'><b>".$mod_strings['ERR_CREDENTIALS_MISSING']."</b></font>";
}
else{
$result = PackageManagerComm::login();
if((is_array($result) && !empty($result['faultcode'])) || $result == false){
$header_text = "<font color='red'><b>".$result['faultstring']."</b></font>";
}else{
$header_text = PackageManager::getPromotion();
$isAlive = true;
}
}
}
return array('text' => $header_text, 'isAlive' => $isAlive, 'show_login' => $show_login);
}
function buildInstallGrid($view){
$uh = new UpgradeHistory();
$installeds = $uh->getAll();
$upgrades_installed = 0;
$installed_objects = array();
foreach($installeds as $installed)
{
$filename = from_html($installed->filename);
$date_entered = $installed->date_entered;
$type = $installed->type;
$version = $installed->version;
$upgrades_installed++;
$link = "";
switch($type)
{
case "theme":
case "langpack":
case "module":
case "patch":
$manifest_file = extractManifest($filename);
require_once($manifest_file);
$name = empty($manifest['name']) ? $filename : $manifest['name'];
$description = empty($manifest['description']) ? $mod_strings['LBL_UW_NONE'] : $manifest['description'];
if(($upgrades_installed==0 || $uh->UninstallAvailable($installeds, $installed))
&& is_file($filename) && !empty($manifest['is_uninstallable']))
{
$link = urlencode( $filename );
}
else
{
$link = 'false';
}
break;
default:
break;
}
if($view == 'default' && $type != 'patch')
{
continue;
}
if($view == 'module'
&& $type != 'module' && $type != 'theme' && $type != 'langpack')
{
continue;
}
$target_manifest = remove_file_extension( $filename ) . "-manifest.php";
require_once( "$target_manifest" );
if(isset($manifest['icon']) && $manifest['icon'] != "")
{
$manifest_copy_files_to_dir = isset($manifest['copy_files']['to_dir']) ? clean_path($manifest['copy_files']['to_dir']) : "";
$manifest_copy_files_from_dir = isset($manifest['copy_files']['from_dir']) ? clean_path($manifest['copy_files']['from_dir']) : "";
$manifest_icon = clean_path($manifest['icon']);
$icon = "<img src=\"" . $manifest_copy_files_to_dir . ($manifest_copy_files_from_dir != "" ? substr($manifest_icon, strlen($manifest_copy_files_from_dir)+1) : $manifest_icon ) . "\">";
}
else
{
$icon = getImageForType( $manifest['type'] );
}
$installed_objects[] = array('icon' => $icon, 'name' => $name, 'type' => $type, 'version' => $version, 'date_entered' => $date_entered, 'description' => $description, 'file' => $link);
//print( "<form action=\"" . $form_action . "_prepare\" method=\"post\">\n" );
//print( "<tr><td>$icon</td><td>$name</td><td>$type</td><td>$version</td><td>$date_entered</td><td>$description</td><td>$link</td></tr>\n" );
//print( "</form>\n" );
}
}
}
?>

View File

@@ -0,0 +1,71 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
define('PACKAGE_MANAGER_DOWNLOAD_SERVER', 'https://depot.sugarcrm.com/depot/');
define('PACKAGE_MANAGER_DOWNLOAD_PAGE', 'download.php');
define('PACKAGE_MANAGER_DOWNLOAD_PATH', '../'.$GLOBALS['sugar_config']['upload_dir']);
class PackageManagerDownloader{
/**
* Using curl we will download the file from the depot server
*
* @param session_id the session_id this file is queued for
* @param file_name the file_name to download
* @param save_dir (optional) if specified it will direct where to save the file once downloaded
* @param download_sever (optional) if specified it will direct the url for the download
*
* @return the full path of the saved file
*/
function download($session_id, $file_name, $save_dir = '', $download_server = ''){
if(empty($save_dir)){
$save_dir = PACKAGE_MANAGER_DOWNLOAD_PATH;
}
if(empty($download_server)){
$download_server = PACKAGE_MANAGER_DOWNLOAD_SERVER;
}
$download_server .= PACKAGE_MANAGER_DOWNLOAD_PAGE;
$ch = curl_init($download_server . '?filename='. $file_name);
$fp = sugar_fopen($save_dir . $file_name, 'w');
curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID='.$session_id. ';');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
return $save_dir . $file_name;
}
}
?>

View File

@@ -0,0 +1,63 @@
<?php
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
$listViewDefs['module_loader']['packages'] = array(
'name' => array(
'width' => '5',
'label' => 'LBL_LIST_NAME',
'link' => false,
'default' => true,
'show' => true),
'description' => array(
'width' => '32',
'label' => 'LBL_ML_DESCRIPTION',
'default' => true,
'link' => false,
'show' => true),
);
$listViewDefs['module_loader']['releases'] = array(
'description' => array(
'width' => '32',
'label' => 'LBL_LIST_SUBJECT',
'default' => true,
'link' => false),
'version' => array(
'width' => '32',
'label' => 'LBL_LIST_SUBJECT',
'default' => true,
'link' => false),
);
?>

View File

@@ -0,0 +1,96 @@
{*
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
*}
<table id='fileviewtable'>
<tr height='20'>
{counter start=0 name="colCounter" print=false assign="colCounter"}
<th scope='col' width='5' nowrap="nowrap">view/hide</th>
{foreach from=$displayColumns key=colHeader item=params}
{if $params.show}
<th scope='col' width='{$params.width}%' nowrap="nowrap">
<span sugar="sugar{$colCounter}"><div style='white-space: nowrap;'width='100%' align='{$params.align|default:'left'}'>
{sugar_translate label=$params.label module='Administration'}
</div></span sugar='sugar{$colCounter}'>
</th>
{/if}
{counter name="colCounter"}
{/foreach}
<th scope='col' width='5' nowrap="nowrap">Select</th>
</tr>
{foreach name=rowIteration from=$data key=package_id item=package}
{if $smarty.foreach.rowIteration.iteration is odd}
{assign var='_bgColor' value=$bgColor[0]}
{assign var='_rowColor' value=$rowColor[0]}
{else}
{assign var='_bgColor' value=$bgColor[1]}
{assign var='_rowColor' value=$rowColor[1]}
{/if}
<tr id='package_tr_{$package_id}' height='20' class='{$_rowColor}S1'>
<td scope='row' align='left' valign='top'><a class="listViewTdToolsS1" onclick="PackageManager.toggle_div('{$package_id}')" valign='top'><span id='span_toggle_package_{$package_id}'><img src='{sugar_getimagepath file="advanced_search.gif"}' width='8' height='8' alt='Advanced' border='0'>&nbsp;</span></a></td>
{counter start=0 name="colCounter" print=false assign="colCounter"}
{foreach from=$displayColumns key=col item=params}
<td scope='row' align='{$params.align|default:'left'}' valign='top'><span sugar="sugar{$colCounter}b">
{if $params.show}
{$package.$col}
{/if}
</span sugar='sugar{$colCounter}b'>
</td>
{counter name="colCounter"}
{/foreach}
<td scope='row' align='left' valign='top'><a class="listViewTdToolsS1" onclick="PackageManager.select_package('{$package_id}')" valign='top'>Select</a></td>
</tr>
<tr><td colspan="5"><table id='release_table_{$package_id}' style='display:none'>
{foreach name=releaseIteration from=$package.releases key=release_id item=release}
<tr id='release_tr_{$release_id}' height='20' class='{$_rowColor}S1'>
{counter start=0 name="colCounter" print=false assign="colCounter"}
{foreach from=$secondaryDisplayColumns key=col item=params}
<td scope='row' align='{$params.align|default:'left'}' valign='top'><span sugar="sugar{$colCounter}b">
{$release.$col}
</span sugar='sugar{$colCounter}b'>
</td>
{counter name="colCounter"}
{/foreach}
<td scope='row' align='left' valign='top'><a class="listViewTdToolsS1" onclick="PackageManager.select_release('{$release_id}')" valign='top'>Select</a></td>
</tr>
{/foreach}
</table></td></tr>
{/foreach}
</table>

View File

@@ -0,0 +1,105 @@
{*
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
*}
{$scripts}
{$TREEHEADER}
{literal}
<style type="text/css">
#demo { width:100%; }
#demo .yui-content {
padding:1em; /* pad content container */
}
.list {list-style:square;width:500px;padding-left:16px;}
.list li{padding:2px;font-size:8pt;}
/* hide the tab content while loading */
.tab-content{display:none;}
pre {
font-size:11px;
}
#tabs1 {width:100%;}
#tabs1 .yui-ext-tabbody {border:1px solid #999;border-top:none;}
#tabs1 .yui-ext-tabitembody {display:none;padding:10px;}
/* default loading indicator for ajax calls */
.loading-indicator {
font-size:8pt;
background-image:url('../../resources/images/grid/loading.gif');
background-repeat: no-repeat;
background-position: left;
padding-left:20px;
}
/* height of the rows in the grids */
.ygrid-row {
height:27px;
}
.ygrid-col {
height:27px !important;
}
</style>
{/literal}
{$INSTALLED_PACKAGES_HOLDER}
<br>
<form action='{$form_action}' method="post" name="installForm">
<input type=hidden name="release_id">
{$hidden_fields}
<div id='server_upload_div'>
{$FORM_2_PLACE_HOLDER}
{$MODULE_SELECTOR}
<div id='search_results_div'></div>
</div>
</form>
<div id='local_upload_div'>
{$FORM_1_PLACE_HOLDER}
</div>
{if $module_load == 'true'}
<div id='upload_table'>
<table width='100%'><tr><td><div id='patch_downloads' class='ygrid-mso' style='height:205px;'></div></td></tr></table>
</div>
{literal}<script>
//PackageManager.toggleView('browse');
</script>
{/literal}
{/if}

View File

@@ -0,0 +1,50 @@
{*
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
*}
<table>
<tr>
<td>{$MOD.LBL_MODULE_LICENSE}</td>
</tr>
<tr>
<td><textarea id='license' cols='75' rows='8'>{$LICENSE_CONTENTS}</textarea></td>
</tr>
<tr>
<td><input type='radio' id='radio_license_agreement_accept' name='radio_license_agreement' value='accept'>{$MOD.LBL_ACCEPT}&nbsp;<input type='radio' id='radio_license_agreement_reject' name='radio_license_agreement' value='reject'>{$MOD.LBL_DENY}</td>
</tr>
<tr>
<tr><td><input type='button' id='btnLicense' value='OK' onClick='PackageManager.processLicense("{$FILE}");' class='button'></td>
</tr>
</table>

File diff suppressed because it is too large Load Diff