393 lines
14 KiB
PHP
Executable File
393 lines
14 KiB
PHP
Executable File
<?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".
|
|
********************************************************************************/
|
|
|
|
|
|
class UpgradeMetaHelper{
|
|
|
|
var $upgrade_dir;
|
|
var $debug_mode;
|
|
var $upgrade_modules;
|
|
var $customized_modules;
|
|
var $source_dir;
|
|
var $dest_dir ;
|
|
var $evparser;
|
|
var $dvparser;
|
|
var $path_to_master_copy;
|
|
/**
|
|
* UpgradeMetaHelper
|
|
* This is the constructor for the UpgradeMetaHelper class
|
|
* @param $dir The root upgrade directory (where to copy working files)
|
|
* @param $masterCopyDirectory The root master directory (where SugarCRM 5.x files reside)
|
|
* @param $debugMode Debug mode, default is false
|
|
*
|
|
*/
|
|
function UpgradeMetaHelper($dir='upgrade', $masterCopyDirecotry='modules_50', $debugMode = false) {
|
|
$this->upgrade_dir = $dir;
|
|
$this->debug_mode = $debugMode;
|
|
$this->upgrade_modules = $this->getModifiedModules();
|
|
|
|
if(count($this->upgrade_modules) > 0) {
|
|
$_SESSION['Upgraded_Modules'] = $this->upgrade_modules;
|
|
$this->create_upgrade_directory();
|
|
$this->path_to_master_copy = $masterCopyDirecotry;
|
|
$this->runParser();
|
|
}
|
|
|
|
$this->customized_modules = $this->getAllCustomizedModulesBeyondStudio();
|
|
if(count($this->customized_modules) > 0) {
|
|
$_SESSION['Customized_Modules'] = $this->customized_modules;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* getModifiedModules
|
|
* This method returns a two-dimensional Array of Studio enabled
|
|
* modules that have been modified. The second Array index is an
|
|
* Array of files that do not match the md5 checksum for the module
|
|
* @return $return_array Two-dimensional Array of [module][modified file(s) Array]
|
|
*/
|
|
function getModifiedModules() {
|
|
|
|
$md5_string = array();
|
|
if(file_exists(clean_path(getcwd().'/files.md5'))){
|
|
require(clean_path(getcwd().'/files.md5'));
|
|
}
|
|
|
|
$return_array = array();
|
|
$modules = $this->loadStudioModules();
|
|
foreach($modules as $mod) {
|
|
|
|
$editView = "modules/$mod/EditView.html";
|
|
$detailView = "modules/$mod/DetailView.html";
|
|
$searchForm = "modules/$mod/SearchForm.html";
|
|
if(file_exists($editView) && isset($md5_string['./' . $editView])) {
|
|
$fileContents = file_get_contents($editView);
|
|
if(md5($fileContents) != $md5_string['./' . $editView]) {
|
|
$return_array[$mod][] = $editView;
|
|
}
|
|
}
|
|
|
|
if(file_exists($detailView) && isset($md5_string['./' . $detailView])) {
|
|
$fileContents = file_get_contents($detailView);
|
|
if(md5($fileContents) != $md5_string['./' . $detailView]) {
|
|
$return_array[$mod][] = $detailView;
|
|
}
|
|
}
|
|
|
|
if(file_exists($searchForm) && isset($md5_string['./' . $searchForm])) {
|
|
$fileContents = file_get_contents($searchForm);
|
|
if(md5($fileContents) != $md5_string['./' . $searchForm]) {
|
|
$return_array[$mod][] = $searchForm;
|
|
}
|
|
}
|
|
|
|
} //foreach
|
|
|
|
return $return_array;
|
|
}
|
|
|
|
function saveMatchingFilesQueries($currStep,$value){
|
|
$upgrade_progress_dir = getcwd().'/'.$GLOBALS['sugar_config']['upload_dir'].'upgrades/temp';
|
|
if(!is_dir($upgrade_progress_dir)){
|
|
mkdir($upgrade_progress_dir);
|
|
}
|
|
$file_queries_file = $upgrade_progress_dir.'/files_queries.php';
|
|
if(file_exists($file_queries_file)){
|
|
include($file_queries_file);
|
|
}
|
|
else{
|
|
if(function_exists('sugar_fopen')){
|
|
sugar_fopen($file_queries_file, 'w+');
|
|
}
|
|
else{
|
|
fopen($file_queries_file, 'w+');
|
|
}
|
|
}
|
|
if(!isset($files_queries) || $files_queries == NULL){
|
|
$files_queries = array();
|
|
}
|
|
$files_queries[$currStep]=$value;
|
|
if(is_writable($file_queries_file) && write_array_to_file( "file_queries", $file_queries,
|
|
$file_queries_file)) {
|
|
//writing to the file
|
|
}
|
|
}
|
|
|
|
function getAllCustomizedModulesBeyondStudio() {
|
|
|
|
require_once('modules/UpgradeWizard/uw_utils.php');
|
|
$md5_string = array();
|
|
if(file_exists(clean_path(getcwd().'/files.md5'))){
|
|
require(clean_path(getcwd().'/files.md5'));
|
|
}
|
|
$return_array = array();
|
|
$modules = $this->loadStudioModules();
|
|
$modulesAll = getAllModules(); //keep all modules as well
|
|
$allOtherModules = array_diff($modulesAll,$modules);
|
|
foreach($modules as $mod) {
|
|
if(!is_dir('modules/'.$mod)) continue;
|
|
$editView = "modules/$mod/EditView.html";
|
|
$detailView ="modules/$mod/DetailView.html";
|
|
$exclude_files[]=$editView;
|
|
$exclude_files[]=$detailView;
|
|
$allModFiles = array();
|
|
$allModFiles = findAllFiles('modules/'.$mod,$allModFiles);
|
|
foreach($allModFiles as $file){
|
|
//$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
|
|
if(file_exists($file) && !in_array($file,$exclude_files)){
|
|
if(isset($md5_string['./'.$file])) {
|
|
$fileContents = file_get_contents($file);
|
|
if(md5($fileContents) != $md5_string['./'.$file]) {
|
|
$return_array[$mod][] = $file;
|
|
}
|
|
else{
|
|
//keep in the array to be deleted later
|
|
$_SESSION['removeMd5MatchingFiles'][] = $file;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} //foreach
|
|
//also check out other non-studio modules by taking the difference between
|
|
//allMOdules and
|
|
foreach($allOtherModules as $mod) {
|
|
if(!is_dir('modules/'.$mod)) continue;
|
|
$allModFiles = array();
|
|
$allModFiles = findAllFiles('modules/'.$mod,$allModFiles);
|
|
foreach($allModFiles as $file){
|
|
//$file_md5_ref = str_replace(clean_path(getcwd()),'',$file);
|
|
if(file_exists($file)){
|
|
if(isset($md5_string['./'.$file])) {
|
|
$fileContents = file_get_contents($file);
|
|
if(md5($fileContents) == $md5_string['./'.$file]) {
|
|
$_SESSION['removeMd5MatchingFiles'][] = $file;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//Also store in a file
|
|
//saveMatchingFilesQueries('removeMd5MatchingFiles',$_SESSION['removeMd5MatchingFiles']);
|
|
return $return_array;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Get all the customized modules. Compare the file md5s with the base md5s
|
|
* If a file has been modified then put the module in the list of customized
|
|
* modules. Show the list in the preflight check UI.
|
|
*/
|
|
function getAllCustomizedModules() {
|
|
|
|
require_once('files.md5');
|
|
|
|
$return_array = array();
|
|
$modules = getAllModules();
|
|
foreach($modules as $mod) {
|
|
//find all files in each module if the files have been modified
|
|
//as compared to the base version then add the module to the
|
|
//customized modules array
|
|
$modFiles = findAllFiles(clean_path(getcwd())."/modules/$mod", array());
|
|
foreach($modFiles as $file){
|
|
$fileContents = file_get_contents($file);
|
|
$file = str_replace(clean_path(getcwd()),'',$file);
|
|
if($md5_string['./' . $file]){
|
|
if(md5($fileContents) != $md5_string['./' . $file]) {
|
|
//A file has been customized in the module. Put the module into the
|
|
// customized modules array.
|
|
echo 'Changed File'.$file;
|
|
$return_array[$mod];
|
|
break;
|
|
}
|
|
}
|
|
else{
|
|
// This is a new file in user's version and indicates that module has been
|
|
//customized. Put the module in the customized array.
|
|
echo 'New File'.$file;
|
|
$return_array[$mod];
|
|
break;
|
|
}
|
|
}
|
|
} //foreach
|
|
|
|
return $return_array;
|
|
}
|
|
|
|
/**
|
|
* loadStudioModules
|
|
* This method returns an Array of all modules where a studio.php file is
|
|
* present in the metadata directory of the module
|
|
* @return $modules Array of modules that are studio enabled
|
|
*/
|
|
function loadStudioModules() {
|
|
$modules = array();
|
|
$d = dir('modules');
|
|
while($e = $d->read()){
|
|
if(substr($e, 0, 1) == '.' || !is_dir('modules/' . $e))continue;
|
|
if(file_exists('modules/' . $e . '/metadata/studio.php')){
|
|
$modules[] = $e;
|
|
}
|
|
}
|
|
return $modules;
|
|
}
|
|
|
|
|
|
/**
|
|
* runParser
|
|
* This method creates the EditView and DetailView parser intances
|
|
* and runs the parsing for the modules to upgrade
|
|
*
|
|
*/
|
|
function runParser() {
|
|
require_once('include/SugarFields/Parsers/EditViewMetaParser.php');
|
|
require_once('include/SugarFields/Parsers/DetailViewMetaParser.php');
|
|
require_once('include/SugarFields/Parsers/SearchFormMetaParser.php');
|
|
|
|
$this->evparser = new EditViewMetaParser();
|
|
$this->dvparser = new DetailViewMetaParser();
|
|
$this->svparser = new SearchFormMetaParser();
|
|
|
|
|
|
foreach($this->upgrade_modules as $module_name=>$files) {
|
|
$this->parseFile($module_name, $files);
|
|
} //foreach
|
|
}
|
|
|
|
|
|
/**
|
|
* parseFile
|
|
* Hanldes parsing the files for given module where Studio or manual
|
|
* changes have been detected.
|
|
* @param $module_name The module to parse
|
|
* @param $files Array of files found to parse
|
|
*
|
|
*/
|
|
function parseFile($module_name, $files) {
|
|
global $beanList, $dictionary;
|
|
foreach($files as $file) {
|
|
if(preg_match('/(EditView|DetailView|SearchForm|QuickCreate)(\.html|\.tpl)$/s', $file, $matches)) {
|
|
$view = $matches[1];
|
|
|
|
switch($view) {
|
|
case 'EditView' : $parser = $this->evparser; break;
|
|
case 'DetailView' : $parser = $this->dvparser; break;
|
|
case 'SearchForm' : $parser = $this->svparser; break;
|
|
}
|
|
|
|
$lowerCaseView = $view == 'SearchForm' ? 'search' : strtolower($view);
|
|
|
|
include('modules/'.$module_name.'/vardefs.php');
|
|
$bean_name = $beanList[$module_name];
|
|
$newFile = $this->upgrade_dir.'/modules/'.$module_name.'/metadata/'.$lowerCaseView.'defs.php';
|
|
$evfp = fopen($newFile,'w');
|
|
|
|
$bean_name = $bean_name == 'aCase' ? 'Case' : $bean_name;
|
|
fwrite($evfp, $parser->parse($file,
|
|
$dictionary[$bean_name]['fields'],
|
|
$module_name,
|
|
true,
|
|
$this->path_to_master_copy.'/modules/'.$module_name.'/metadata/'.$lowerCaseView.'defs.php'));
|
|
fclose($evfp);
|
|
} //if
|
|
} //foreach
|
|
}
|
|
|
|
|
|
/**
|
|
* create_upgrade_directory
|
|
* Creates a directory called upgrade to house all the modules that are studio enabled.
|
|
* Also creates subdirectories for all studio enabled modules.
|
|
*
|
|
*/
|
|
function create_upgrade_directory() {
|
|
|
|
$dir = $this->upgrade_dir.'/modules';
|
|
if(!file_exists($this->upgrade_dir)) {
|
|
mkdir($this->upgrade_dir, 0755);
|
|
}
|
|
if(!file_exists($dir)) {
|
|
mkdir($dir, 0755);
|
|
}
|
|
|
|
foreach($this->upgrade_modules as $module=>$files){
|
|
if(!file_exists($dir.'/'.$module)) {
|
|
mkdir($dir.'/'.$module, 0755);
|
|
}
|
|
if(!file_exists($dir.'/'.$module.'/metadata')) {
|
|
mkdir($dir.'/'.$module.'/metadata', 0755);
|
|
}
|
|
|
|
foreach($files as $file) {
|
|
if(file_exists($file) && is_file($file)) {
|
|
copy($file, $this->upgrade_dir.'/'.$file);
|
|
} //if
|
|
} //foreach
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* verifyMetaData
|
|
* This function does some quick checks to make sure the metadataFile at
|
|
* least has an Array panel
|
|
*
|
|
* @param $metadataFile The path to the metadata file to verify
|
|
* @param $module The module to verify
|
|
* @param $view The view (EditView or DetailView)
|
|
* @return boolean true if verification check is okay; false otherwise
|
|
*/
|
|
function verifyMetaData($metadataFile, $module, $view) {
|
|
if(!file_exists($metadataFile) || !is_file($metadataFile)) {
|
|
return false;
|
|
}
|
|
|
|
include($metadataFile);
|
|
|
|
if(isset($viewdefs) && isset($viewdefs[$module][$view]['panels']) && is_array($viewdefs[$module][$view]['panels'])) {
|
|
return true;
|
|
}
|
|
|
|
if(isset($searchdefs) && isset($searchdefs[$module]) && is_array($searchdefs[$module])) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
?>
|