/
var
/
www
/
html
/
sugardemo
/
modules
/
ModuleBuilder
/
views
/
Upload File
HOME
<?php /* * Your installation or use of this SugarCRM file is subject to the applicable * terms available at * http://support.sugarcrm.com/Resources/Master_Subscription_Agreements/. * If you do not agree to all of the applicable terms or do not have the * authority to bind the entity as an authorized representative, then do not * install or use this SugarCRM file. * * Copyright (C) SugarCRM Inc. All rights reserved. */ require_once 'modules/ModuleBuilder/MB/ModuleBuilder.php'; require_once 'modules/ModuleBuilder/parsers/constants.php'; use Sugarcrm\Sugarcrm\AccessControl\AccessControlManager; class ViewRelationship extends SugarView { /** * @var \Sugar_Smarty|mixed */ public $smarty; /** * @var bool|mixed */ public $fromModuleBuilder; /** * @see SugarView::_getModuleTitleParams() */ protected function _getModuleTitleParams($browserTitle = false) { global $mod_strings; return [ translate('LBL_MODULE_NAME', 'Administration'), ModuleBuilderController::getModuleTitle(), ]; } public function overrideDefinitionFromPOST($definition) { foreach (AbstractRelationship::$definitionKeys as $key) { if (!empty($_REQUEST[$key])) { $reqVal = $this->request->getValidInputRequest($key); if (in_array($key, ['label', 'rhs_label', 'lhs_label'])) { if (empty($_REQUEST['ajaxLoad'])) { $definition[$key] = htmlspecialchars_decode($reqVal, ENT_QUOTES); } } else { $definition[$key] = $reqVal; } } } return $definition; } public function display() { global $locale; $selected_lang = $this->request->getValidInputRequest('relationship_lang'); if (empty($selected_lang)) { $selected_lang = $locale->getAuthenticatedUserLanguage(); } $viewModule = $this->request->getValidInputRequest('view_module', 'Assert\ComponentName'); $viewPackage = $this->request->getValidInputRequest('view_package', 'Assert\ComponentName'); if (!AccessControlManager::instance()->allowModuleAccess($viewModule)) { throw new SugarApiExceptionModuleDisabled(); } $this->smarty = new Sugar_Smarty(); $ac = new AjaxCompose(); $this->fromModuleBuilder = isset($_REQUEST['MB']) || (!empty($viewPackage) && $viewPackage != 'studio'); $this->smarty->assign('fromModuleBuilder', $this->fromModuleBuilder); if (!$this->fromModuleBuilder) { $module = StudioModuleFactory::getStudioModule($viewModule); $moduleName = $viewModule; $fields = $module->fields; $relatableModules = DeployedRelationships::findRelatableModules(); } else { $mb = new ModuleBuilder(); $mb->getPackages(); //display the latest module name rather than what is in or not in the loaded app_list_strings. $mb->getPackage($viewPackage)->loadModuleTitles(); $module = $mb->getPackageModule($viewPackage, $viewModule); $moduleName = empty($module->key_name) ? $module->getModuleName() : $module->key_name; $this->smarty->assign('view_package', $viewPackage); $mbvardefs = $module->getVardefs(); $fields = $mbvardefs['fields']; $relatableModules = UndeployedRelationships::findRelatableModules(); } ksort($relatableModules); $lhs_subpanels = $module->getProvidedSubpanels(); // Fix to re-add sorting of the subpanel names so that the 'default' // subpanel always appears first in the list. // This assumes that subpanels are usually named ForXYZ which is the // case currently, and hence 'default' will be sorted first. // If this assumption is incorrect, then a better solution would be to // remove 'default' from the subpanel list, then sort, and finally // array_unshift it back on. natcasesort($lhs_subpanels); $cardinality = [ MB_ONETOONE => translate('LBL_ONETOONE'), MB_ONETOMANY => translate('LBL_ONETOMANY'), MB_MANYTOONE => translate('LBL_MANYTOONE'), MB_MANYTOMANY => translate('LBL_MANYTOMANY'), ]; if (!$this->fromModuleBuilder) { unset($cardinality[MB_MANYTOONE]); } $relationshipName = $this->request->getValidInputRequest('relationship_name', 'Assert\ComponentName'); $relationships = $module->getRelationships($relationshipName); // if a description for this relationship already exists, then load it so it can be modified if (!empty($relationshipName)) { if (!AccessControlManager::instance()->allowFieldAccess($viewModule, $relationshipName)) { throw new SugarApiExceptionFieldDisabled(); } $relationship = $relationships->get($relationshipName); $relationship->setName($relationshipName); $definition = $relationship->getDefinition(); if (!$this->fromModuleBuilder) { $modStrings = return_module_language($selected_lang, $relationship->rhs_module, true); if (!empty($definition['lhs_vname'])) { $definition['lhs_label'] = translate($definition['lhs_vname']); } else { $definition['lhs_label'] = $modStrings[$relationship->getTitleKey()] ?? $relationship->lhs_module; } $modStrings = return_module_language($selected_lang, $relationship->lhs_module, true); if (!empty($definition['rhs_vname'])) { $definition['rhs_label'] = translate($definition['rhs_vname']); } else { $definition['rhs_label'] = $modStrings[$relationship->getTitleKey(true)] ?? $relationship->rhs_module; } } else { $reqRhsModule = $this->request->getValidInputRequest('rhs_module', 'Assert\ComponentName'); #30624 if (!empty($reqRhsModule)) { $definition['rhs_label'] = $reqRhsModule; } } } else { $definition = []; $definition['rhs_module'] = key($relatableModules); $definition['lhs_module'] = $moduleName; $definition['lhs_label'] = translate($moduleName); $definition['relationship_type'] = MB_MANYTOMANY; } // load the relationship from post - required as we can call view.relationship.php from Ajax when changing the rhs_module for example $definition = $this->overrideDefinitionFromPOST($definition); if (!AccessControlManager::instance()->allowModuleAccess($definition['rhs_module'])) { throw new SugarApiExceptionModuleDisabled(); } if (empty($definition ['rhs_label'])) { $definition['rhs_label'] = translate($definition['rhs_module']); } if (empty($definition['lhs_label'])) { $definition['lhs_label'] = translate($definition['lhs_module']); } $relationship = RelationshipFactory::newRelationship($definition); $rhs_subpanels = $relatableModules[$relationship->rhs_module]; // Fix to re-add sorting of the subpanel names so that the 'default' // subpanel always appears first in the list. This assumes that subpanels // are usually named ForXYZ which is the case currently, and hence // 'default' will be sorted first. If this assumption is incorrect, // then a better solution would be to remove 'default' from the subpanel // list, then sort, and finally array_unshift it back on. natcasesort($rhs_subpanels); if (empty($relationshipName)) { // tidy up the options for the view based on the modules participating // in the relationship and the cardinality some modules // (e.g., Knowledge Base/KBOLDDocuments) lack subpanels. That means they // can't be the lhs of a 1-many or many-many, or the rhs of a // many-many for example // fix up the available cardinality options if (safeCount($lhs_subpanels) == 0 || safeCount($rhs_subpanels) == 0) { unset($cardinality[MB_MANYTOMANY]); } if (safeCount($rhs_subpanels) == 0) { unset($cardinality[MB_ONETOMANY]); } if (isset($definition['rhs_module']) && $definition['rhs_module'] == 'Activities') { $cardinality = [MB_ONETOMANY => translate('LBL_ONETOMANY')]; } //Bug 23139, Campaigns module current cannot display custom subpanels, so we need to ban it from any //relationships that would require a new subpanel to be shown in Campaigns. if (isset($definition['lhs_module']) && $definition['lhs_module'] == 'Campaigns') { unset($cardinality[MB_MANYTOMANY]); unset($cardinality[MB_ONETOMANY]); } if (isset($definition['rhs_module']) && $definition['rhs_module'] == 'Campaigns' && isset($cardinality[MB_MANYTOMANY])) { unset($cardinality[MB_MANYTOMANY]); unset($cardinality[MB_MANYTOONE]); } if (!isset($cardinality[$relationship->getType()])) { $definition['relationship_type'] = array_key_last($cardinality); $relationship = RelationshipFactory::newRelationship($definition); } $this->smarty->assign('is_new', true); } else { $this->smarty->assign('is_new', false); } //Remove Activities if one-to-many is not availible if (!isset($cardinality[MB_ONETOMANY]) && isset($relatableModules['Activities'])) { unset($relatableModules['Activities']); } // now enforce the relationship_only requirement - that is, only construct the underlying relationship and link fields, and not the UI, if the subpanel code will have troubles displaying the UI $relationships->enforceRelationshipOnly($relationship); $this->smarty->assign('view_module', $viewModule); $this->smarty->assign('rel', $relationship->getDefinition()); $this->smarty->assign('mod_strings', $GLOBALS['mod_strings']); $this->smarty->assign('module_key', $relationship->lhs_module); $this->smarty->assign('cardinality', array_keys($cardinality)); $this->smarty->assign('translated_cardinality', $cardinality); $this->smarty->assign('selected_cardinality', translate($relationship->getType())); $relatable = []; foreach ($relatableModules as $name => $dummy) { // Clean up the relatable module name $relatable[$name] = $this->getModuleName($name); } natcasesort($relatable); $this->smarty->assign('relatable', array_keys($relatable)); $this->smarty->assign('translated_relatable', $relatable); $this->smarty->assign('rhspanels', $rhs_subpanels); $this->smarty->assign('lhspanels', $lhs_subpanels); $this->smarty->assign('selected_lang', $selected_lang); $this->smarty->assign('available_languages', get_languages()); switch ($relationship->relationship_type) { case MB_ONETOONE: break; case MB_ONETOMANY: if (empty($relationship->relationship_column_name)) { $validRoleColumnFields = []; foreach ($fields as $field) { $validRoleColumnFields[] = $field; } $this->smarty->assign('relationship_role_column_enum', $validRoleColumnFields); } if (!empty($relationship->relationship_role_column_value)) { $this->smarty->assign('relationship_role_column_value', $relationship->relationship_role_column_value); } break; case MB_MANYTOMANY: if (!empty($relationship->relationship_role_column_value)) { $this->smarty->assign('relationship_role_column_value', $relationship->relationship_role_column_value); } break; } //see if we use the new system if (isset($_REQUEST['json']) && $_REQUEST['json'] == 'false') { echo $this->smarty->fetch('modules/ModuleBuilder/tpls/studioRelationship.tpl'); } else { $ac->addSection('east', $module->name . ' ' . $GLOBALS['mod_strings']['LBL_RELATIONSHIPS'], $this->smarty->fetch('modules/ModuleBuilder/tpls/studioRelationship.tpl')); echo $ac->getJavascript(); } } /** * Gets a translated module name for both deployed and undeployed modules * * @param string $module The module to get a translated name for * @return string */ protected function getModuleName($module) { // If there is an object name for this (or bean name) assume this is a // deployed module and return the translated string if (BeanFactory::getObjectName($module)) { return translate($module); } // If we get here, then see if there is an undeployed module based on // all installed packages $mb = new ModuleBuilder(); $packages = $mb->getPackageList(); foreach ($packages as $package) { $mod = $mb->getPackage($package)->getModuleByFullName($module); if ($mod && !empty($mod->config['label'])) { // Since this is undeployed, there is no module "name" so rely on // the label in the module config return $mod->config['label']; } } // Hmmm, what really is this? Don't know, send it back as is return $module; } }