/** {@inheritDoc} */ public function getPath() { $paths = MetaDataFiles::getPaths(); if (!isset($paths[$this->location])) { throw new Exception("Deployed metadata location {$this->location} is not recognized"); } $path = $this->file->getPath(); if ($paths[$this->location]) { $path = array_merge(explode('/', trim($paths[$this->location], '/')), $path); } return $path; }
/** {@inheritDoc} */ public function getPath() { $names = MetaDataFiles::getNames(); //In a deployed module, we can check for a studio module with file name overrides. $sm = StudioModuleFactory::getStudioModule($this->module); foreach ($sm->sources as $file => $def) { if (!empty($def['view'])) { $names[$def['view']] = substr($file, 0, strlen($file) - 4); } } if (!isset($names[$this->view])) { sugar_die("View {$this->view} is not recognized"); } return array('modules', $this->module, $names[$this->view]); }
/** * Merge the new style extensions * @param string $module_path Path to the module's directory. */ public function mergeExtensionFiles($module_path) { $php_tags = array('<?php', '?>', '<?PHP', '<?'); $path = "custom/Extension/{$module_path}/Ext/clients"; $clients = MetaDataFiles::getClients(); foreach ($clients as $client) { foreach (glob("{$path}/{$client}/*", GLOB_ONLYDIR | GLOB_NOSORT) as $layout) { $layoutType = basename($layout); foreach (glob("{$layout}/*", GLOB_ONLYDIR | GLOB_NOSORT) as $subLayout) { $subLayoutFileName = basename($subLayout); $extension = "<?php\n// WARNING: The contents of this file are auto-generated.\n"; $override = array(); foreach (glob("{$subLayout}/*.php") as $file) { $basenameFile = basename($file); if (substr($basenameFile, 0, 9) == '_override') { $override[] = $file; } else { $fileContents = file_get_contents($file); $extension .= "\n" . str_replace($php_tags, '', $fileContents); } } foreach ($override as $file) { $fileContents = file_get_contents($file); $extension .= "\n" . str_replace($php_tags, '', $fileContents); } $cachePath = "custom/{$module_path}/Ext/clients/{$client}/{$layoutType}/{$subLayoutFileName}"; if (!is_dir($cachePath)) { sugar_mkdir($cachePath, null, true); } SugarAutoLoader::put("{$cachePath}/{$subLayoutFileName}.ext.php", $extension, true); } } } }
/** * Clears mobile and portal metadata caches that have been created by the API * to allow immediate rendering of changes at the client */ protected function _clearCaches() { if ($this->implementation->isDeployed()) { MetaDataFiles::clearModuleClientCache($this->_moduleName, 'view'); // Clear out the cache just for the platform we are on $client = empty($this->client) ? 'base' : $this->client; MetaDataManager::refreshModulesCache(array($this->_moduleName), array($client), $this->implementation->getParams()); parent::_clearCaches(); } }
public function action_searchViewSave() { $packageName = isset($_REQUEST['view_package']) ? $_REQUEST['view_package'] : null; // Bug 56789 - Set the client from the view to ensure the proper viewdef file $client = MetaDataFiles::getClientByView($_REQUEST['view']); if (isModuleBWC($_REQUEST['view_module'])) { $parser = new SearchViewMetaDataParser($_REQUEST['view'], $_REQUEST['view_module'], $packageName, $client); } else { $client = empty($client) ? 'base' : $client; $parser = new SidecarFilterLayoutMetaDataParser($_REQUEST['view_module'], $packageName, $client); } $parser->handleSave(); //Repair or create a custom SearchFields.php file as needed $module_name = $_REQUEST['view_module']; global $beanList; if (isset($beanList[$module_name]) && $beanList[$module_name] != "") { $objectName = BeanFactory::getObjectName($module_name); //Load the vardefs for the module to pass to TemplateRange VardefManager::loadVardef($module_name, $objectName, true); global $dictionary; $vardefs = $dictionary[$objectName]['fields']; TemplateRange::repairCustomSearchFields($vardefs, $module_name, $packageName); } $this->view = 'searchView'; }
/** * Gets the panel defs from the viewdef array * * @param array $viewdef The view def array * @return array */ protected function getPanelsFromViewDef($viewdef) { if (isset($viewdef['panels'])) { $panels = $viewdef['panels']; } else { $defs = MetaDataFiles::mapArrayToPath(MetaDataFiles::getViewDefVar($this->_view), $viewdef); $panels = isset($defs['panels']) ? $defs['panels'] : null; } return $panels; }
/** * Adds a path => array(files) to the excluded client file path array * * @param array $pathArray Array of files keyed on a base path */ public static function addExcludedClientFilePath(array $pathArray) { self::$excludedClientFilePaths = array_merge(self::$excludedClientFilePaths, $pathArray); }
public function getFileName($view, $moduleName, $packageName, $type = MB_BASEMETADATALOCATION, $client = null) { if ($client === null) { $client = $this->_viewClient; } return MetaDataFiles::getUndeployedFileName($view, $moduleName, $packageName, $type, $client); }
/** * Converts the legacy Grid metadata to Sidecar style */ public function convertLegacyViewDefsToSidecar() { if (empty($this->legacyViewdefs)) { return; } // If this module is undeployed and doesn't have a base set of metadata, // we should just end things right now. It's not you, it's me. if (!$this->deployed && $this->package) { // This is the marker that decides our fate $found = false; // The undeployed implementation uses history then working, where // working translates to the base file and history translates to // working. $types = array(MB_HISTORYMETADATALOCATION, MB_WORKINGMETADATALOCATION); // Check each type for file existence. This is done similarly to the // implementation, without the overhead of constructing that object // or the parser just yet. foreach ($types as $type) { $file = MetaDataFiles::getUndeployedFileName($this->viewtype, $this->module, $this->package, $type, $this->client); if (file_exists($file)) { $found = true; break; } } // If neither of the files we needed are found, bail now since without // these the upgrade process breaks if (!$found) { $this->logUpgradeStatus("Required {$this->client} {$this->viewtype} metadata for {$this->module} is missing... aborting merge upgrade"); return; } } $this->logUpgradeStatus('Converting ' . $this->client . ' ' . $this->viewtype . ' view defs for ' . $this->module); // Holds merged defs and final defs $newdefs = $tempdefs = $finaldefs = array(); // This needs to be called before the parser is instantiated to prevent // custom metadata from being created from basic module template $defaultDefs = $this->loadDefaultMetadata(); // Get the parser now that default metadata has been fetched $parser = ParserFactory::getParser($this->viewtype, $this->module, $this->package, null, $this->client); // Get the fields that are on the default defs panels since we may need // those as well $defaultDefsFields = $parser->getFieldsFromPanels($defaultDefs['panels']); // Go through merge views, add fields added to detail view to base panel // and fields added to edit view not in detail view or hidden panel $customFields = array(); foreach ($this->legacyViewdefs as $lViewtype => $data) { // We will need a parser no matter what if ($this->sidecar) { $legacyParser = ParserFactory::getParser($lViewtype, $this->module, $this->package, null, $this->client); } else { $legacyParser = ParserFactory::getParser($lViewtype, $this->module, $this->package); } // Step 1, handle tabDef changes $hasTabDefCustomizations = $this->hasTabDefCustomizations($lViewtype); // Tabdefs holds tab def customizations. If there are tab customizations // then the defaultDefs need to be derived from the customize layout // instead of the default viewdef $tabdefs = array(); if ($hasTabDefCustomizations) { // Used for converting tab names. Tabs and panels need to match // and that matching gets handled here and in handleConversion $c = 0; // pull out the tab definitions from the originals, put them into the Canonical Form foreach ($data['templateMeta']['tabDefs'] as $tabName => $tabContent) { // Handle panel labels for matching later $panelNames = $this->getConvertedPanelName($tabName, $c); $tabName = $panelNames['label']; // Save these for later to prevent conflict with new panels later $tabdefs[$tabName] = array('newTab' => $tabContent['newTab'], 'panelDefault' => $tabContent['panelDefault']); // Increment the counter $c++; } // Intermediate step here needed for tabdef customizations... what is // needed is to convert the old panels to new style, then inject the // defaultDef header panel into the newly converted panel set before // continuing on $headerPanel = $defaultDefs['panels'][0]; $defaultDefs = $this->handleConversion($data, 'panels', true); array_unshift($defaultDefs['panels'], $headerPanel); } // TemplateMeta needs to be added if it isn't, to both the default defs // and the parser viewdefs if (isset($data['templateMeta'])) { if (!isset($defaultDefs['templateMeta'])) { $defaultDefs['templateMeta'] = $data['templateMeta']; } else { $defaultDefs['templateMeta'] = array_merge($defaultDefs['templateMeta'], $data['templateMeta']); } if (!isset($parser->_viewdefs['templateMeta'])) { $parser->_viewdefs['templateMeta'] = $defaultDefs['templateMeta']; } else { $parser->_viewdefs['templateMeta'] = array_merge($parser->_viewdefs['templateMeta'], $defaultDefs['templateMeta']); } } // Make a header fields array so that fields that may be in legacy // defs can be plucked out $headerFields = array(); foreach ($defaultDefs['panels'][0]['fields'] as $hField) { // Handle array type fields first if (is_array($hField)) { // But only if there is a name element of the array if (isset($hField['name'])) { // First set from the name of the field we are on $headerFields[$hField['name']] = $hField['name']; // Now if there are fields for this field (fieldset), grab those too if (isset($hField['fields']) && is_array($hField['fields'])) { foreach ($hField['fields'] as $hFieldName) { // Some modules have header field fieldset defs that are arrays if (is_array($hFieldName) && isset($hFieldName['name'])) { $headerFields[$hFieldName['name']] = $hFieldName['name']; } else { $headerFields[$hFieldName] = $hFieldName; } } } } } else { // This will be a string, take it as is $headerFields[$hField] = $hField; } } // Step 2, convert panels if there are any to handle if (!empty($data['panels'])) { // Add spans fields as needed $maxSpan = $parser->getMaxSpan(); // Need to send the entire data array as we need templateData.maxColumns $data = $this->addSpansToFields($data, $maxSpan); $legacyPanelFields = $legacyParser->getFieldsFromPanels($data['panels']); foreach ($legacyPanelFields as $fieldname => $fielddef) { // Handle removal of fields from customFields (legacy defs) as needed $skip = false; if (empty($fieldname) || !$this->isValidField($fieldname)) { // Definitely skip keeping empty and invalid field names. $skip = true; } else { // Is this field already in the customFields collection? $cf = isset($customFields[$fieldname]); // Or perhaps it is explicitly in the removeFields array? $rf = isset($this->removeFields[$fieldname]); // Or maybe it is in the headerFields array? $hf = isset($headerFields[$fieldname]); // If this field is any of the arrays above, skip it if ($cf || $rf || $hf) { $skip = true; } } if ($skip) { continue; } $customFields[$fieldname] = array('data' => $fielddef, 'source' => $lViewtype); } } // Handle field conversion and renames from previous versions $customFields = $this->applyFieldConversionPatches($customFields); // Grab our twitter conversion flag early since twitter_id could be // an array as a field $convertTwitter = $this->needsTwitterConversion(); // Handle unsetting of header fields from non header panels and handle // email1 <=> email conversion foreach ($defaultDefs['panels'] as $panelIndex => $panel) { foreach ($panel['fields'] as $fieldIndex => $fieldName) { // Turn a field name into a string for searching convenience if (is_array($fieldName)) { $lookupFieldName = isset($fieldName['name']) ? $fieldName['name'] : null; } else { $lookupFieldName = $fieldName; } // Handle fields that are not meant to be here, like header // fields, but only if we are not in the header panel if ($panelIndex > 0) { if (isset($lookupFieldName) && isset($headerFields[$lookupFieldName])) { // Remove this field from the defs and move on unset($defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex]); continue; } } // Delete 'team_name' from the layout if module doesn't implement team-security, otherwise leave it; // the field is a part of 'basic' template by default, but module may not implement team-security if (isset($lookupFieldName) && $lookupFieldName == 'team_name' && !$this->isValidField($fieldName)) { unset($defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex]); } // Hack email field into submission if (isset($lookupFieldName) && $lookupFieldName == 'email1') { if (is_array($fieldName)) { $fieldName['name'] = 'email'; $defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex] = $fieldName; } else { $defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex] = 'email'; } } // Handle twitter_id to twitter renaming if (isset($lookupFieldName) && $lookupFieldName == 'twitter_id' && $convertTwitter) { // If twitter is already on the defaults, remove twitter_id entirely, // otherwise rename twitter_id if (isset($defaultDefsFields['twitter'])) { unset($defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex]); } elseif (is_array($fieldName)) { $fieldName['name'] = 'twitter'; $defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex] = $fieldName; } else { $defaultDefs['panels'][$panelIndex]['fields'][$fieldIndex] = 'twitter'; } } } // Reset the array indexes $defaultDefs['panels'][$panelIndex]['fields'] = array_values($defaultDefs['panels'][$panelIndex]['fields']); } // End email1 => email hack // Make sure the array pointer for the panels is back at the start. // This is needed to allow canonical conversion to pick up the right // header panel reset($defaultDefs['panels']); $origFields = array(); // replace viewdefs with defaults, since parser's viewdefs can be already customized by other parts // of the upgrade $parser->_viewdefs['panels'] = $parser->convertFromCanonicalForm($defaultDefs['panels'], $parser->_fielddefs); // get field list $origData = $parser->getFieldsFromPanels($defaultDefs['panels'], $parser->_fielddefs); // Go through existing fields and remove those not in the new data foreach ($origData as $fname => $fielddef) { if (!$this->isValidField($fname)) { continue; } if (is_array($fielddef) && !empty($fielddef['fields'])) { // fieldsets - iterate over each field $setExists = false; if (!empty($customFields[$fielddef['name']])) { $setExists = true; } else { foreach ($fielddef['fields'] as $setfielddef) { if (!is_array($setfielddef)) { $setfname = $setfielddef; } else { // skip weird nameless ones if (empty($setfielddef['name'])) { continue; } $setfname = $setfielddef['name']; } // if we have one field - we take all set if (isset($customFields[$setfname])) { $setExists = true; break; } } } if ($setExists) { $origFields[$fielddef['name']] = $fielddef; // if fields exist, we take all the set as existing fields foreach ($fielddef['fields'] as $setfielddef) { if (!is_array($setfielddef)) { $setfname = $setfielddef; } else { // skip werid nameless ones if (empty($setfielddef['name'])) { continue; } $setfname = $setfielddef['name']; } $origFields[$setfname] = $fielddef; } } else { // else we delete the set but only if it isn't a header field if (!isset($headerFields[$fname])) { $parser->removeField($fname); } } } else { // if it's a regular field, check against existing field in new data if (!isset($customFields[$fname]) && !isset($headerFields[$fname])) { // not there - remove it $parser->removeField($fname); } else { // otherwise - keep as existing $origFields[$fname] = $fielddef; } } } // now go through new fields and add those not in original data // $customFields is legacy defs, $origFields are Sugar7 OOTB defs foreach ($customFields as $fieldname => $data) { if (isset($origFields[$fieldname])) { // If the field is special, massage it into latest format being // sure to maintain its current position in the layout if ($this->isSpecialField($fieldname)) { $fielddata = $this->convertFieldData($fieldname, $data['data']); $this->updateField($parser, $fieldname, $fielddata); } } else { $fielddata = $this->convertFieldData($fieldname, $data['data']); // FIXME: hack since addField cuts field defs if ($this->isSpecialField($fieldname) && empty($parser->_originalViewDef[$fielddata['name']])) { $parser->_originalViewDef[$fielddata['name']] = $fielddata; } $parser->addField($fielddata, $this->getPanelName($parser->_viewdefs['panels'], $data['source'])); } } // Convert the panels array to something useful $panels = $parser->convertToCanonicalForm($parser->_viewdefs['panels'], $parser->_fielddefs); // Add back in tabDefs on the panels if there are any if (!empty($tabdefs)) { foreach ($panels as $key => $panel) { if (!empty($panel['label']) && isset($tabdefs[$panel['label']])) { $panels[$key]['newTab'] = $tabdefs[$panel['label']]['newTab']; $panels[$key]['panelDefault'] = $tabdefs[$panel['label']]['panelDefault']; } } } // There needs to be two different arrays here to allow for non-recursive // but nested array merges. This allows for detail views to be upgraded // first followed by edit views while still maintaining tab definitions // for detail views if (empty($newdefs['panels'])) { $newdefs = $parser->_viewdefs; $newdefs['panels'] = $panels; } else { $tempdefs = $parser->_viewdefs; $tempdefs['panels'] = $panels; } // After all iterations, this will be the final, merged layout def $finaldefs = $this->mergeLayoutDefs($newdefs, $tempdefs); } //Finally re-add any fields that are on the OOB sidecar view but not on the OOB Legacy views $finaldefs = $this->addNewFieldsToLayout($finaldefs); $this->sidecarViewdefs[$this->getNormalizedModuleName()][$this->client]['view'][MetaDataFiles::getName($this->viewtype)] = $finaldefs; }
public function getNewFileContents($viewname) { $module = $this->getNormalizedModuleName(); $viewname = MetaDataFiles::getName($viewname); $client = $this->client == 'wireless' ? 'mobile' : $this->client; $out = "<?php\n\$viewdefs['{$module}']['{$client}']['filter']['default'] = " . var_export($this->sidecarViewdefs, true) . ";\n"; return $out; }
/** * Gets the metadata from various non module locations as a fallback. If * no metadata file is found, will log an error and return an empty set of * viewdefs. * * @param string $marker The property to set when metadata is found * @return array */ public function getFallbackMetadata($marker = 'loadedMetadataFile') { // Prepare the return $viewdefs = array(); // Get our module type $sm = new StudioModule($this->_moduleName); $template = $sm->getType(); // Build an array of files to search defs for $files = array(); if (!$this->_viewClient !== 'base') { // This is the OOTB file for this module in the base client $files[] = $this->getMetadataFilename(MB_BASEMETADATALOCATION, null, 'base'); } // This is the metadata file for this module type $files[] = $this->getMetadataFilename('', $template, 'base'); if ($template !== 'basic') { // This is the metadata file for basic modules $files[] = $this->getMetadataFilename('', 'basic', 'base'); } // Used for logging $found = false; // Loop and set foreach ($files as $file) { if (file_exists($file)) { require $file; if (!empty($viewdefs)) { // This needs to be done in the event we have a SugarObject template file in use $viewdefs = MetaDataFiles::getModuleMetaDataDefsWithReplacements($this->bean, $viewdefs); if (isset($viewdefs[$this->_moduleName])) { $this->{$marker} = $file; $found = true; break; } } } } // If we found nothing, log it if (!$found) { $GLOBALS['log']->error("Could not find a filter file for {$this->_moduleName}"); } return $viewdefs; }
/** * Cleans out current metadata cache and rebuilds it for * each platform and visibility */ public function repairMetadataAPICache($section = '') { // Refresh metadata for selected modules only if there selected modules if (is_array($this->module_list) && !empty($this->module_list) && !in_array(translate('LBL_ALL_MODULES'), $this->module_list)) { MetaDataFiles::clearModuleClientCache($this->module_list); MetaDataManager::refreshModulesCache($this->module_list); } // If there is a section named (like 'fields') refresh that section if (!empty($section)) { MetaDataManager::refreshSectionCache($section); } else { // Otherwise if the section is not a false nuke all caches and rebuild // the base metadata cache if ($section !== false) { MetaDataManager::clearAPICache(true, true); MetaDataManager::setupMetadata(); } } }
/** * Load current Sugar metadata for this module * * @return array */ protected function loadDefaultMetadata() { $client = $this->client == 'wireless' ? 'mobile' : $this->client; // The new defs array - this should contain OOTB defs for the module $newdefs = $viewdefs = array(); $viewname = MetaDataFiles::getName($this->viewtype); if (!$viewname) { $viewname = $this->viewtype; } // Bug 55568 - new metadata was not included for custom metadata // conversion from pre-6.6 installations. // Grab the new metadata for this module. For undeployed modules we // need to get the metadata from the SugarObject type. // If there are defs for this module, grab them $this->defsfile = 'modules/' . $this->module . '/clients/' . $client . '/views/' . $viewname . '/' . $viewname . '.php'; if (file_exists($this->defsfile)) { require $this->defsfile; if (isset($viewdefs[$this->module][$client]['view'][$viewname])) { $newdefs = $viewdefs[$this->module][$client]['view'][$viewname]; } } // Fallback to the object type if there were no defs found // Bug 57216 - Upgrade wizard was dying on undeployed modules getType if (empty($newdefs)) { if ($this->deployed) { require_once 'modules/ModuleBuilder/Module/StudioModuleFactory.php'; $sm = StudioModuleFactory::getStudioModule($this->module); $moduleType = $sm->getType(); } elseif ($this->package) { require_once 'modules/ModuleBuilder/MB/ModuleBuilder.php'; $mb = new ModuleBuilder(); $package = $mb->getPackage($this->package); $module = $package->getModule($this->module); $moduleType = $module->getModuleType(); } if (!empty($moduleType)) { $this->base_defsfile = 'include/SugarObjects/templates/' . $moduleType . '/clients/' . $client . '/views/' . $viewname . '/' . $viewname . '.php'; if (file_exists($this->base_defsfile)) { require $this->base_defsfile; } else { $this->base_defsfile = 'include/SugarObjects/templates/basic/clients/' . $client . '/views/' . $viewname . '/' . $viewname . '.php'; if (file_exists($this->base_defsfile)) { require $this->base_defsfile; } else { $this->logUpgradeStatus("Could not find basic {$viewname} template for module {$this->module} type {$moduleType}"); } } // See if there are viewdefs defined that we can use if (isset($viewdefs['<module_name>'][$client]['view'][$viewname])) { //Need to perform variable replacement for some field defs $module = $this->getNormalizedModuleName(); $convertedDefs = MetaDataFiles::getModuleMetaDataDefsWithReplacements($module, $viewdefs); if (isset($convertedDefs[$module][$client]['view'][$viewname])) { $newdefs = $convertedDefs[$module][$client]['view'][$viewname]; } else { $newdefs = $viewdefs['<module_name>'][$client]['view'][$viewname]; } } // Only write a defs file for deployed modules if ($newdefs && $this->deployed) { // If we used the template, create the basic one $this->logUpgradeStatus(get_class($this) . ": Copying template defs {$this->base_defsfile} to {$this->defsfile}"); mkdir_recursive(dirname($this->defsfile)); $viewname = pathinfo($this->defsfile, PATHINFO_FILENAME); $export = var_export($newdefs, true); $data = <<<END <?php /* Generated by SugarCRM Upgrader */ \$viewdefs['{$this->module}']['{$client}']['view']['{$viewname}'] = {$export}; END; sugar_file_put_contents($this->defsfile, $data); } } } return $newdefs; }
/** * Get the link name for a subpanel using witchcraft and wizardry * @param string $subpanelName - this is the name of the subpanel * @param string $loadedModule - this is the name of the module that is loaded * @return string the linkname for the subpanel */ protected function getLinkName($subpanelName, $loadedModule) { if (isModuleBWC($loadedModule) && !file_exists("modules/{$loadedModule}/clients/" . $this->getViewClient() . "/layouts/subpanels/subpanels.php")) { @(include "modules/{$loadedModule}/metadata/subpaneldefs.php"); if (empty($layout_defs[$loadedModule]['subpanel_setup'])) { $GLOBALS['log']->error("Cannot find subpanel layout defs for {$loadedModule}"); return $subpanelName; } foreach ($layout_defs[$loadedModule]['subpanel_setup'] as $linkName => $def) { if ($def['module'] == $subpanelName) { return $linkName; } } } $viewdefs = MetaDataFiles::getClientFileContents(MetaDataFiles::getClientFiles(array($this->getViewClient()), 'layout', $loadedModule), 'layout', $loadedModule); if (empty($viewdefs['subpanels'])) { return $subpanelName; } $legacyDefs = $this->mdc->toLegacySubpanelLayoutDefs($viewdefs['subpanels']['meta']['components'], BeanFactory::newBean($loadedModule)); if (empty($legacyDefs['subpanel_setup'])) { $GLOBALS['log']->error("Could not convert subpanels for subpanel: {$subpanelName} - {$loadedModule}"); return $subpanelName; } foreach ($legacyDefs['subpanel_setup'] as $linkName => $def) { if ($def['module'] == $subpanelName) { return $linkName; } } return $subpanelName; }
/** * Removes the metadata files for all known studio layouts. * * @return html output record of the files deleted */ function removeCustomLayouts() { $module = StudioModuleFactory::getStudioModule($this->module); $sources = $module->getViewMetadataSources(); $out = ""; // list of existing platforms including BWC $platforms = MetaDataManager::getPlatformList(); array_unshift($platforms, ''); // Flag to tell the autoloader whether to save itself or not when done $saveMap = false; foreach ($sources as $view) { foreach ($platforms as $platform) { $file = MetaDataFiles::getDeployedFileName($view['type'], $this->module, MB_CUSTOMMETADATALOCATION, $platform); // Ensure we are working on files that the autoloader knows about if (SugarAutoLoader::fileExists($file)) { // Since we are in a loop inside of a loop do NOT send the // save flag as true to unlink() but be sure to save the file // map after the process is finished so that all changes to // the map are saved. SugarAutoLoader::unlink($file); $out .= "Removed layout {$view['type']}.php<br/>"; // Tell the autoloader to save itself $saveMap = true; } } } // now clear the cache include_once 'include/TemplateHandler/TemplateHandler.php'; TemplateHandler::clearCache($this->module); // If the file map needs saving, handle that now if ($saveMap) { SugarAutoLoader::saveMap(); } return $out; }
/** * Returns editable dropdown filters * * @param array $data Existing data * @param MetaDataContextInterface $context Metadata context * * @return array */ public function getEditableDropdownFilters($data = array(), MetaDataContextInterface $context = null) { if ($this->public) { return array(); } if (is_null($context)) { $context = $this->getCurrentUserContext(); } $platform = $this->platforms[0]; $files = array_map(function ($file) use($platform) { $info = pathinfo($file); return array('path' => $file, 'file' => $info['basename'], 'subPath' => $info['dirname'], 'platform' => $platform, 'params' => MetaDataFiles::getClientFileParams($file)); }, glob('custom/application/Ext/DropdownFilters/roles/*/dropdownfilters.ext.php')); $files = array_filter($files, function (array $file) use($context) { return $context->isValid($file); }); uasort($files, function ($a, $b) use($context) { return $context->compare($a, $b); }); if (!count($files)) { return array(); } $filters = array(); foreach ($files as $file) { $fileFilters = $this->readDropdownFilterFile($file['path']); foreach ($fileFilters as $fieldName => $filter) { // make sure first file wins and its metadata doesn't get overridden if (!isset($filters[$fieldName])) { $filters[$fieldName] = $this->fixDropdownFilter($filter, $fieldName); //To preserve order in JSON, we need to return the filters as tuples. $filters[$fieldName] = array_map(null, array_keys($filters[$fieldName]), $filters[$fieldName]); } } } return $filters; }
/** * Sets the view client for the metadata * * @return void */ public function setViewClientFromView() { if (!empty($this->_view)) { /* if (strpos($this->_view, 'portal') !== false) { $this->_viewClient = 'portal'; } elseif (strpos($this->_view, 'wireless') !== false || strpos($this->_view, 'mobile') !== false) { $this->_viewClient = 'mobile'; } else { $this->_viewClient = 'base'; } */ $this->_viewClient = MetaDataFiles::getViewClient($this->_view); } }
function deploy($defs) { // first sort out the historical record... write_array_to_file(self::HISTORYVARIABLENAME, $this->_viewdefs, $this->historyPathname, 'w', ''); $this->_history->append($this->historyPathname); $this->_viewdefs = $defs; require_once 'include/SubPanel/SubPanel.php'; $subpanel = new SubPanel($this->_moduleName, 'fab4', $this->_subpanelName, $this->_aSubPanelObject); $subpanel->saveSubPanelDefOverride($this->_aSubPanelObject, 'list_fields', $defs); // now clear the cache so that the results are immediately visible MetaDataFiles::clearModuleClientCache($this->_aSubPanelObject->template_instance->module_name, 'view'); MetaDataFiles::clearModuleClientCache($this->_moduleName, 'layout'); include_once 'include/TemplateHandler/TemplateHandler.php'; TemplateHandler::clearCache($this->_moduleName); }
/** * Resets user specific metadata to default */ public function resetToDefault() { if (count($this->params) > 0) { $fileName = $this->getFileNameNoDefault($this->_view, $this->_moduleName); if (file_exists($fileName)) { $this->saveHistory(); SugarAutoLoader::unlink($fileName, true); MetaDataFiles::clearModuleClientCache($this->_moduleName, 'view'); // Clear out the cache just for the platform we are on $client = empty($this->client) ? 'base' : $this->client; MetaDataManager::refreshModulesCache(array($this->_moduleName), array($client), $this->params); } } }