2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4 * SugarCRM Community Edition is a customer relationship management program developed by
5 * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Affero General Public License version 3 as published by the
9 * Free Software Foundation with the addition of the following permission added
10 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19 * You should have received a copy of the GNU Affero General Public License along with
20 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU Affero General Public License version 3.
31 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34 * technical reasons, the Appropriate Legal Notices must display the words
35 * "Powered by SugarCRM".
36 ********************************************************************************/
45 protected $module_list_from_cache;
47 public function repairAndClearAll($selected_actions, $modules, $autoexecute=false, $show_output=true)
50 $this->module_list= $modules;
51 $this->show_output = $show_output;
52 $this->actions = $selected_actions;
53 $this->actions[] = 'repairDatabase';
54 $this->execute=$autoexecute;
56 //clear vardefs always..
57 $this->clearVardefs();
58 //first clear the language cache.
59 $this->clearLanguageCache();
60 foreach ($this->actions as $current_action)
61 switch($current_action)
63 case 'repairDatabase':
64 if(in_array($mod_strings['LBL_ALL_MODULES'], $this->module_list))
65 $this->repairDatabase();
67 $this->repairDatabaseSelectModules();
69 case 'rebuildExtensions':
70 $this->rebuildExtensions();
76 $this->clearJsFiles();
79 $this->clearDashlets();
81 case 'clearSugarFeedCache':
82 $this->clearSugarFeedCache();
84 case 'clearThemeCache':
85 $this->clearThemeCache();
88 $this->clearVardefs();
90 case 'clearJsLangFiles':
91 $this->clearJsLangFiles();
93 case 'rebuildAuditTables':
94 $this->rebuildAuditTables();
96 case 'clearSearchCache':
97 $this->clearSearchCache();
101 $this->clearJsFiles();
102 $this->clearVardefs();
103 $this->clearJsLangFiles();
104 $this->clearLanguageCache();
105 $this->clearDashlets();
106 $this->clearSugarFeedCache();
107 $this->clearSmarty();
108 $this->clearThemeCache();
109 $this->clearXMLfiles();
110 $this->clearSearchCache();
111 $this->clearExternalAPICache();
112 $this->rebuildExtensions();
113 $this->rebuildAuditTables();
114 $this->repairDatabase();
122 public function repairDatabase()
124 global $dictionary, $mod_strings;
125 if(false == $this->show_output)
126 $_REQUEST['repair_silent']='1';
127 $_REQUEST['execute']=$this->execute;
128 $GLOBALS['reload_vardefs'] = true;
129 $hideModuleMenu = true;
130 include_once('modules/Administration/repairDatabase.php');
133 public function repairDatabaseSelectModules()
135 global $current_user, $mod_strings, $dictionary;
136 set_time_limit(3600);
138 include('include/modules.php'); //bug 15661
139 $db = DBManagerFactory::getInstance();
141 if (is_admin($current_user) || is_admin_for_any_module($current_user))
144 if($this->show_output) echo getClassicModuleTitle($mod_strings['LBL_REPAIR_DATABASE'], array($mod_strings['LBL_REPAIR_DATABASE']), false);
145 if($this->show_output) {
146 echo "<h1 id=\"rdloading\">{$mod_strings['LBL_REPAIR_DATABASE_PROCESSING']}</h1>";
150 if($this->module_list && !in_array($mod_strings['LBL_ALL_MODULES'],$this->module_list))
152 $repair_related_modules = array_keys($dictionary);
154 $dm = inDeveloperMode();
155 $GLOBALS['sugar_config']['developerMode'] = true;
156 foreach($this->module_list as $bean_name)
159 if (isset($beanFiles[$bean_name]) && file_exists($beanFiles[$bean_name]))
161 require_once($beanFiles[$bean_name]);
162 $GLOBALS['reload_vardefs'] = true;
163 $focus = new $bean_name ();
165 if($focus->disable_vardefs == false) {
166 include('modules/' . $focus->module_dir . '/vardefs.php');
169 if($this->show_output)
170 print_r("<p>" .$mod_strings['LBL_REPAIR_DB_FOR'].' '. $bean_name . "</p>");
171 $sql .= $db->repairTable($focus, $this->execute);
176 $GLOBALS['sugar_config']['developerMode'] = $dm;
178 if ($this->show_output) echo "<script type=\"text/javascript\">document.getElementById('rdloading').style.display = \"none\";</script>";
179 if (isset ($sql) && !empty ($sql))
182 foreach (explode("\n", $sql) as $line) {
183 if (!empty ($line) && substr($line, -2) != "*/") {
187 $qry_str .= $line . "\n";
189 if ($this->show_output){
190 echo "<h3>{$mod_strings['LBL_REPAIR_DATABASE_DIFFERENCES']}</h3>";
191 echo "<p>{$mod_strings['LBL_REPAIR_DATABASE_TEXT']}</p>";
193 echo "<form method=\"post\" action=\"index.php?module=Administration&action=repairDatabase\">";
194 echo "<textarea name=\"sql\" rows=\"24\" cols=\"150\" id=\"repairsql\">$qry_str</textarea>";
195 echo "<br /><input type=\"submit\" value=\"".$mod_strings['LBL_REPAIR_DATABASE_EXECUTE']."\" name=\"raction\" /> <input type=\"submit\" name=\"raction\" value=\"".$mod_strings['LBL_REPAIR_DATABASE_EXPORT']."\" />";
199 if ($this->show_output) echo "<h3>{$mod_strings['LBL_REPAIR_DATABASE_SYNCED']}</h3>";
204 sugar_die($GLOBALS['app_strings']['ERR_NOT_ADMIN']);
208 public function rebuildExtensions()
211 if($this->show_output) echo $mod_strings['LBL_QR_REBUILDEXT'];
212 global $current_user;
213 require_once('ModuleInstall/ModuleInstaller.php');
214 $mi = new ModuleInstaller();
215 $mi->rebuild_all(!$this->show_output);
217 // Remove the "Rebuild Extensions" red text message on admin logins
219 if($this->show_output) echo $mod_strings['LBL_REBUILD_REL_UPD_WARNING'];
221 // clear the database row if it exists (just to be sure)
222 $query = "DELETE FROM versions WHERE name='Rebuild Extensions'";
223 $GLOBALS['log']->info($query);
224 $GLOBALS['db']->query($query);
226 // insert a new database row to show the rebuild extensions is done
228 $gmdate = gmdate('Y-m-d H:i:s');
229 $date_entered = db_convert("'$gmdate'", 'datetime');
230 $query = 'INSERT INTO versions (id, deleted, date_entered, date_modified, modified_user_id, created_by, name, file_version, db_version) '
231 . "VALUES ('$id', '0', $date_entered, $date_entered, '1', '1', 'Rebuild Extensions', '4.0.0', '4.0.0')";
232 $GLOBALS['log']->info($query);
233 $GLOBALS['db']->query($query);
235 // unset the session variable so it is not picked up in DisplayWarnings.php
236 if(isset($_SESSION['rebuild_extensions'])) {
237 unset($_SESSION['rebuild_extensions']);
241 //Cache Clear Methods
242 public function clearSmarty()
245 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARSMARTY']}</h3>";
246 $this->_clearCache(sugar_cached('smarty/templates_c'), '.tpl.php');
248 public function clearXMLfiles()
251 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_XMLFILES']}</h3>";
252 $this->_clearCache(sugar_cached("xml"), '.xml');
254 include('modules/Versions/ExpectedVersions.php');
256 global $expect_versions;
258 if (isset($expect_versions['Chart Data Cache'])) {
259 $version = new Version();
260 $version->retrieve_by_string_fields(array('name'=>'Chart Data Cache'));
262 $version->name = $expect_versions['Chart Data Cache']['name'];
263 $version->file_version = $expect_versions['Chart Data Cache']['file_version'];
264 $version->db_version = $expect_versions['Chart Data Cache']['db_version'];
268 public function clearDashlets()
271 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARDASHLET']}</h3>";
272 $this->_clearCache(sugar_cached('dashlets'), '.php');
274 public function clearThemeCache()
277 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARTHEMECACHE']}</h3>";
278 SugarThemeRegistry::clearAllCaches();
280 public function clearSugarFeedCache()
283 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARSUGARFEEDCACHE']}</h3>";
285 SugarFeed::flushBackendCache();
287 public function clearTpls()
290 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARTEMPLATE']}</h3>";
291 if(!in_array( translate('LBL_ALL_MODULES'),$this->module_list) && !empty($this->module_list))
293 foreach($this->module_list as $module_name_singular )
294 $this->_clearCache(sugar_cached('modules/').$this->_getModuleNamePlural($module_name_singular), '.tpl');
297 $this->_clearCache(sugar_cached('modules/'), '.tpl');
299 public function clearVardefs()
302 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARVADEFS']}</h3>";
303 if(!empty($this->module_list) && is_array($this->module_list) && !in_array( translate('LBL_ALL_MODULES'),$this->module_list))
305 foreach($this->module_list as $module_name_singular )
306 $this->_clearCache(sugar_cached('modules/').$this->_getModuleNamePlural($module_name_singular), 'vardefs.php');
309 $this->_clearCache(sugar_cached('modules/'), 'vardefs.php');
311 public function clearJsFiles()
314 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARJS']}</h3>";
316 if(!in_array( translate('LBL_ALL_MODULES'),$this->module_list) && !empty($this->module_list))
318 foreach($this->module_list as $module_name_singular )
319 $this->_clearCache(sugar_cached('modules/').$this->_getModuleNamePlural($module_name_singular), '.js');
323 $this->_clearCache(sugar_cached('modules/'), '.js');
326 public function clearJsLangFiles()
329 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARJSLANG']}</h3>";
330 if(!in_array(translate('LBL_ALL_MODULES'),$this->module_list ) && !empty($this->module_list))
332 foreach($this->module_list as $module_name_singular )
333 $this->_clearCache(sugar_cached('jsLanguage/').$this->_getModuleNamePlural($module_name_singular), '.js');
336 $this->_clearCache(sugar_cached('jsLanguage'), '.js');
339 * Remove the language cache files from cache/modules/<module>/language
341 public function clearLanguageCache()
345 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARLANG']}</h3>";
346 //clear cache using the list $module_list_from_cache
347 if ( !empty($this->module_list) && is_array($this->module_list) ) {
348 if( in_array(translate('LBL_ALL_MODULES'), $this->module_list))
350 LanguageManager::clearLanguageCache();
352 else { //use the modules selected thrut the select list.
353 foreach($this->module_list as $module_name)
354 LanguageManager::clearLanguageCache($module_name);
357 // Clear app* cache values too
358 if(!empty($GLOBALS['sugar_config']['languages'])) {
359 $languages = $GLOBALS['sugar_config']['languages'];
361 $languages = array($GLOBALS['current_language'] => $GLOBALS['current_language']);
363 foreach(array_keys($languages) as $language) {
364 sugar_cache_clear('app_strings.'.$language);
365 sugar_cache_clear('app_list_strings.'.$language);
371 * Remove the cached unified_search_modules.php file
373 public function clearSearchCache() {
374 global $mod_strings, $sugar_config;
375 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEARSEARCH']}</h3>";
376 $search_dir=sugar_cached('');
377 $src_file = $search_dir . 'modules/unified_search_modules.php';
378 if(file_exists($src_file)) {
379 unlink( "$src_file" );
382 public function clearExternalAPICache()
384 global $mod_strings, $sugar_config;
385 if($this->show_output) echo "<h3>{$mod_strings['LBL_QR_CLEAR_EXT_API']}</h3>";
386 require_once('include/externalAPI/ExternalAPIFactory.php');
387 ExternalAPIFactory::clearCache();
390 //////////////////////////////////////////////////////////////
391 /////REPAIR AUDIT TABLES
392 public function rebuildAuditTables()
395 include('include/modules.php'); //bug 15661
396 if($this->show_output) echo "<h3> {$mod_strings['LBL_QR_REBUILDAUDIT']}</h3>";
398 if(!in_array( translate('LBL_ALL_MODULES'), $this->module_list) && !empty($this->module_list))
400 foreach ($this->module_list as $bean_name){
401 if( isset($beanFiles[$bean_name]) && file_exists($beanFiles[$bean_name])) {
402 require_once($beanFiles[$bean_name]);
403 $this->_rebuildAuditTablesHelper(new $bean_name());
406 } else if(in_array(translate('LBL_ALL_MODULES'), $this->module_list)) {
407 foreach ($beanFiles as $bean => $file){
408 if( file_exists($file)) {
410 $this->_rebuildAuditTablesHelper(new $bean());
414 if($this->show_output) echo $mod_strings['LBL_DONE'];
417 private function _rebuildAuditTablesHelper($focus)
421 // skip if not a SugarBean object
422 if ( !($focus instanceOf SugarBean) )
425 if ($focus->is_AuditEnabled()) {
426 if (!$focus->db->tableExists($focus->get_audit_table_name())) {
427 if($this->show_output) echo $mod_strings['LBL_QR_CREATING_TABLE']." ".$focus->get_audit_table_name().' '.$mod_strings['LBL_FOR'].' '. $focus->object_name.'.<br/>';
428 $focus->create_audit_table();
430 if($this->show_output){
431 $echo=str_replace('%1$',$focus->object_name,$mod_strings['LBL_REBUILD_AUDIT_SKIP']);
436 if($this->show_output) echo $focus->object_name.$mod_strings['LBL_QR_NOT_AUDIT_ENABLED'];
439 ///////////////////////////////////////////////////////////////
440 ////END REPAIR AUDIT TABLES
443 ///////////////////////////////////////////////////////////////
444 //// Recursively unlink all files of the given $extension in the given $thedir.
446 private function _clearCache($thedir, $extension)
448 if ($current = @opendir($thedir)) {
449 while (false !== ($children = readdir($current))) {
450 if ($children != "." && $children != "..") {
451 if (is_dir($thedir . "/" . $children)) {
452 $this->_clearCache($thedir . "/" . $children, $extension);
454 elseif (is_file($thedir . "/" . $children) && (substr_count($children, $extension))) {
455 unlink($thedir . "/" . $children);
461 /////////////////////////////////////////////////////////////
463 private function _getModuleNamePlural($module_name_singular)
466 while ($curr_module = current($beanList))
468 if ($curr_module == $module_name_singular)
469 return key($beanList); //name of the module, plural.