public function action_savelanguages() { global $sugar_config; $toDecode = html_entity_decode($_REQUEST['disabled_langs'], ENT_QUOTES); $disabled_langs = json_decode($toDecode); $toDecode = html_entity_decode($_REQUEST['enabled_langs'], ENT_QUOTES); $enabled_langs = json_decode($toDecode); if (count($sugar_config['languages']) === count($disabled_langs)) { sugar_die(translate('LBL_CAN_NOT_DISABLE_ALL_LANG')); } else { $cfg = new Configurator(); if (in_array($sugar_config['default_language'], $disabled_langs)) { reset($enabled_langs); $cfg->config['default_language'] = current($enabled_langs); } if (in_array($GLOBALS['current_user']->preferred_language, $disabled_langs)) { $GLOBALS['current_user']->preferred_language = current($enabled_langs); $GLOBALS['current_user']->save(); } $cfg->config['disabled_languages'] = join(',', $disabled_langs); // TODO: find way to enforce order $cfg->handleOverride(); // Clear the metadata cache so changes to languages are picked up right away MetaDataManager::refreshLanguagesCache($enabled_langs); require_once 'modules/Administration/QuickRepairAndRebuild.php'; $repair = new RepairAndClear(); $repair->clearLanguageCache(); } //Call Ping API to refresh the language list. die("\n <script>\n var app = window.parent.SUGAR.App;\n app.api.call('read', app.api.buildURL('ping'));\n app.router.navigate('#bwc/index.php?module=Administration&action=Languages', {trigger:true, replace:true});\n </script>"); }
/** * Add a set of labels to the language pack for a module, deployed or undeployed * * @param string $language Language key, for example 'en_us' * @param array $labels The labels to add in the form of an array of System label => Display label pairs * @param string $moduleName Name of the module to which to add these labels * @param string $basepath Basepath to the file to be written to */ public static function addLabels($language, $labels, $moduleName, $basepath = null) { $GLOBALS['log']->debug("ParserLabel->addLabels({$language}, \$labels, {$moduleName}, {$basepath});"); $GLOBALS['log']->debug("\$labels:" . print_r($labels, true)); $deployedModule = false; if (is_null($basepath)) { $deployedModule = true; $basepath = "custom/Extension/modules/{$moduleName}/Ext/Language"; if (!SugarAutoLoader::fileExists($basepath)) { mkdir_recursive($basepath); } } $filename = "{$basepath}/{$language}.lang.php"; $mod_strings = array(); $changed = false; if (SugarAutoLoader::fileExists($basepath)) { if (SugarAutoLoader::fileExists($filename)) { // Get the current $mod_strings include $filename; } foreach ($labels as $key => $value) { if (!isset($mod_strings[$key]) || strcmp($value, $mod_strings[$key]) != 0) { // Must match encoding used in view.labels.php $mod_strings[$key] = to_html(strip_tags(from_html($value))); $changed = true; } } } else { $changed = true; } if (!empty($mod_strings) && $changed) { $GLOBALS['log']->debug("ParserLabel->addLabels: writing new mod_strings to {$filename}"); $GLOBALS['log']->debug("ParserLabel->addLabels: mod_strings=" . print_r($mod_strings, true)); $write = "<?php\n// WARNING: The contents of this file are auto-generated.\n"; // We can't use normal array writing here since multiple files can be // structured differently. This is dirty, yes, but necessary. foreach ($mod_strings as $k => $v) { $write .= "\$mod_strings['{$k}'] = " . var_export($v, 1) . ";\n"; } if (!SugarAutoLoader::put($filename, $write, true)) { $GLOBALS['log']->fatal("Could not write {$filename}"); } else { // if we have a cache to worry about, then clear it now if ($deployedModule) { SugarCache::cleanOpcodes(); $GLOBALS['log']->debug("PaserLabel->addLabels: clearing language cache"); self::rebuildLanguageExtensions($language, $moduleName); $cache_key = "module_language." . $language . $moduleName; sugar_cache_clear($cache_key); LanguageManager::clearLanguageCache($moduleName, $language); MetaDataManager::refreshLanguagesCache($language); } } } return true; }
function build() { $modulesToBuild = array(); if (!isset($this->relationships[$this->newRelationshipName])) { $GLOBALS['log']->fatal("Could not find a relationship by the name of {$this->newRelationshipName}, you will have to quick repair and rebuild to get the new relationship added."); } else { $newRel = $this->relationships[$this->newRelationshipName]; $newRelDef = $newRel->getDefinition(); $modulesToBuild[$newRelDef['rhs_module']] = true; $modulesToBuild[$newRelDef['lhs_module']] = true; } $basepath = "custom/Extension/modules"; $this->activitiesToAdd = false; // and mark all as built so that the next time we come through we'll know and won't build again foreach ($this->relationships as $name => $relationship) { if ($relationship->readonly()) { continue; } $definition = $relationship->getDefinition(); // activities will always appear on the rhs only - lhs will be always be this module in MB if (strtolower($definition['rhs_module']) == 'activities') { $this->activitiesToAdd = true; $relationshipName = $definition['relationship_name']; foreach (self::$activities as $activitiesSubModuleLower => $activitiesSubModuleName) { $definition['rhs_module'] = $activitiesSubModuleName; $definition['for_activities'] = true; $definition['relationship_name'] = $relationshipName . '_' . $activitiesSubModuleLower; $this->relationships[$definition['relationship_name']] = RelationshipFactory::newRelationship($definition); } unset($this->relationships[$name]); } } $GLOBALS['log']->info(get_class($this) . "->build(): installing relationships"); $MBModStrings = $GLOBALS['mod_strings']; $adminModStrings = return_module_language('', 'Administration'); // required by ModuleInstaller foreach ($this->relationships as $name => $relationship) { if ($relationship->readonly()) { continue; } $relationship->setFromStudio(); $GLOBALS['mod_strings'] = $MBModStrings; $installDefs = parent::build($basepath, "<basepath>", array($name => $relationship)); // and mark as built so that the next time we come through we'll know and won't build again $relationship->setReadonly(); $this->relationships[$name] = $relationship; // now install the relationship - ModuleInstaller normally only does this as part of a package load where it installs the relationships defined in the manifest. However, we don't have a manifest or a package, so... // If we were to chose to just use the Extension mechanism, without using the ModuleInstaller install_...() methods, we must : // 1) place the information for each side of the relationship in the appropriate Ext directory for the module, which means specific $this->save...() methods for DeployedRelationships, and // 2) we must also manually add the relationship into the custom/application/Ext/TableDictionary/tabledictionary.ext.php file as install_relationship doesn't handle that (install_relationships which requires the manifest however does) // Relationships must be in tabledictionary.ext.php for the Admin command Rebuild Relationships to reliably work: // Rebuild Relationships looks for relationships in the modules vardefs.php, in custom/modules/<modulename>/Ext/vardefs/vardefs.ext.php, and in modules/TableDictionary.php and custom/application/Ext/TableDictionary/tabledictionary.ext.php // if the relationship is not defined in one of those four places it could be deleted during a rebuilt, or during a module installation (when RebuildRelationships.php deletes all entries in the Relationships table) // So instead of doing this, we use common save...() methods between DeployedRelationships and UndeployedRelationships that will produce installDefs, // and rather than building a full manifest file to carry them, we manually add these installDefs to the ModuleInstaller, and then // individually call the appropriate ModuleInstaller->install_...() methods to take our relationship out of our staging area and expand it out to the individual module Ext areas $GLOBALS['mod_strings'] = $adminModStrings; require_once 'ModuleInstall/ModuleInstaller.php'; $mi = new ModuleInstaller(); $mi->id_name = 'custom' . $name; // provide the moduleinstaller with a unique name for this relationship - normally this value is set to the package key... $mi->installdefs = $installDefs; $mi->base_dir = $basepath; $mi->silent = true; VardefManager::clearVardef(); $mi->install_relationships(); $mi->install_languages(); $mi->install_vardefs(); $mi->install_layoutdefs(); $mi->install_extensions(); $mi->install_client_files(); } $GLOBALS['mod_strings'] = $MBModStrings; // finally, restore the ModuleBuilder mod_strings // Anything that runs in-process needs to reload their vardefs $GLOBALS['reload_vardefs'] = true; // save out the updated definitions so that we keep track of the change in built status // sending false so we don't rebuild relationshsips for a third time. $this->save(false); $mi = new ModuleInstaller(); $mi->silent = true; $mi->rebuild_relationships($modulesToBuild); // now clear all caches so that our changes are visible require_once 'modules/Administration/QuickRepairAndRebuild.php'; $rac = new RepairAndClear(); $rac->module_list = $modulesToBuild; $rac->clearJsFiles(); $rac->clearVardefs(); $rac->clearJsLangFiles(); $rac->clearLanguageCache(); $rac->rebuildExtensions(array_keys($modulesToBuild)); $rac->clearVardefs(); foreach ($rac->module_list as $moduleName => $ignore) { // Now rebuild the vardefs in memory $bean = BeanFactory::newBean($moduleName); VardefManager::loadVardef($bean->module_dir, $bean->object_name, true, array('bean' => $bean)); } foreach (array_keys($modulesToBuild) as $module) { unset($GLOBALS['dictionary'][BeanFactory::getObjectName($module)]); } SugarRelationshipFactory::rebuildCache(); MetaDataManager::refreshLanguagesCache(array($GLOBALS['current_language'])); MetaDataManager::refreshSectionCache(array(MetaDataManager::MM_RELATIONSHIPS)); MetaDataManager::refreshModulesCache(array_keys($modulesToBuild)); $GLOBALS['log']->info(get_class($this) . "->build(): finished relationship installation"); }
/** * Clears the js cache and rebuilds the language files * * @param string $lang - language to be rebuilt, and cache cleared */ public function finalize($lang) { $mi = new ModuleInstaller(); $mi->silent = true; $mi->rebuild_languages(array($lang => $lang)); sugar_cache_reset(); sugar_cache_reset_full(); clearAllJsAndJsLangFilesWithoutOutput(); // Clear out the api metadata languages cache for selected language MetaDataManager::refreshLanguagesCache($lang); }