function init($module_name, $subPanelName) { $GLOBALS['log']->debug("in ParserModifySubPanel: module_name={$module_name} child_module={$subPanelName}"); $this->moduleName = $module_name; $this->subPanelName = $subPanelName; global $beanList, $beanFiles; // Sometimes we receive a module name which is not in the correct CamelCase, so shift to lower case for all beanList lookups $beanListLower = array_change_key_case($beanList); // Retrieve the definitions for all the available subpanels for this module $class = $beanListLower[strtolower($this->moduleName)]; require_once $beanFiles[$class]; $module = new $class(); require_once 'include/SubPanel/SubPanelDefinitions.php'; $spd = new SubPanelDefinitions($module); // Get the lists of fields already in the subpanel and those that can be added in // Get the fields lists from an aSubPanel object describing this subpanel from the SubPanelDefinitions object $this->originalListViewDefs = array(); if (array_key_exists(strtolower($this->subPanelName), $spd->layout_defs['subpanel_setup'])) { $originalPanel = $spd->load_subpanel($this->subPanelName, true); $this->originalListViewDefs = $originalPanel->get_list_fields(); $this->panel = $spd->load_subpanel($subPanelName, false); $this->listViewDefs = $this->panel->get_list_fields(); // Retrieve a copy of the bean for the parent module of this subpanel - so we can find additional fields for the layout $subPanelParentModuleName = $this->panel->get_module_name(); $this->subPanelParentModule = null; if (!empty($subPanelParentModuleName) && isset($beanListLower[strtolower($subPanelParentModuleName)])) { $class = $beanListLower[strtolower($subPanelParentModuleName)]; if (isset($beanFiles[$class])) { require_once $beanFiles[$class]; $this->subPanelParentModule = new $class(); } } } $this->language_module = $this->panel->template_instance->module_dir; }
public function testHistorySubpanel() { $subpanelDefs = new SubPanelDefinitions($this->contact); $subpanel = $subpanelDefs->load_subpanel('history'); $prop = $subpanel->get_inst_prop_value('collection_list'); $this->assertArrayHasKey('notes_parent', $prop, 'Should have notes_parent key defined for history'); }
function SubPanel($module, $record_id, $subpanel_id, $subpanelDef, $layout_def_key = '') { global $theme, $focus, $app_strings; $this->subpanel_defs = $subpanelDef; $this->subpanel_id = $subpanel_id; $this->parent_record_id = $record_id; $this->parent_module = $module; $this->layout_def_key = $layout_def_key; $result = $this->parent_bean = $focus; if (empty($result)) { $result = $this->parent_bean = BeanFactory::getBean($module, $this->parent_record_id); } if ($record_id != 'fab4' && $result == null) { sugar_die($app_strings['ERROR_NO_RECORD']); } if (empty($subpanelDef)) { //load the subpanel by name. if (!class_exists('MyClass')) { require_once 'include/SubPanel/SubPanelDefinitions.php'; } $panelsdef = new SubPanelDefinitions($result, $layout_def_key); $subpanelDef = $panelsdef->load_subpanel($subpanel_id); $this->subpanel_defs = $subpanelDef; } }
function loadSubpanel($module_name, $child_module) { $this->parent_module = $module_name; $this->child_module = $child_module; global $beanList, $beanFiles; $class = $beanList[$module_name]; require_once $beanFiles[$class]; require_once 'include/SubPanel/SubPanelDefinitions.php'; $mod = new $class(); $spd = new SubPanelDefinitions($mod); $spd->open_layout_defs(true); $panel = $spd->load_subpanel($child_module, true); $this->panel = $panel; $subpanel = new SubPanel($module_name, 'fab4', $child_module, $panel); $subpanel->setTemplateFile('include/SubPanel/SubPanelDynamic.html'); $oldcontents = ob_get_contents(); ob_clean(); $subpanel->display(); $this->curText = ob_get_contents(); ob_clean(); echo $oldcontents; $this->subpanel = $subpanel; $this->form = <<<EOQ \t\t</form> \t\t<form name='studio' method='POST'> \t\t\t<input type='hidden' name='action' value='saveSubpanel'> \t\t\t<input type='hidden' name='module' value='Studio'> \t\t\t<input type='hidden' name='subpanel' value='{$child_module}'> EOQ; }
public function testSugarWidgetSubpanelTopButtonQuickCreate() { $defines = array(); $defines['focus'] = $this->account; $defines['module'] = 'Accounts'; $defines['action'] = 'DetailView'; $subpanel_definitions = new SubPanelDefinitions(new Contact()); $contactSubpanelDef = $subpanel_definitions->load_subpanel('contacts'); $subpanel = new SubPanel('Accounts', $this->account->id, 'contacts', $contactSubpanelDef, 'Accounts'); $defines['subpanel_definition'] = $subpanel->subpanel_defs; $button = new SugarWidgetSubPanelTopButtonQuickCreate(); $code = $button->_get_form($defines); $this->assertRegExp('/\\<input[^\\>]*?name=\\"return_name\\"/', $code, "Assert that the hidden input field return_name was created"); }
function set_subpanel($module_name, $child_module) { $this->parent_module = $module_name; $this->child_module = $child_module; global $beanList, $beanFiles; $class = $beanList[$module_name]; require_once $beanFiles[$class]; require_once 'include/SubPanel/SubPanelDefinitions.php'; $mod = new $class(); $spd = new SubPanelDefinitions($mod); $spd->open_layout_defs(true); $panel = $spd->load_subpanel($child_module, true); $this->panel = $panel; $subpanel = new SubPanel($module_name, 'fab4', $child_module, $panel); $subpanel->setTemplateFile('include/SubPanel/SubPanelDynamic.html'); ob_flush(); ob_clean(); $subpanel->display(); $this->contents = ob_get_contents(); ob_clean(); $this->subpanel = $subpanel; }
function __construct($module, $record_id, $subpanel_id, $subpanelDef, $layout_def_key = '', $collections = array()) { global $beanList, $beanFiles, $focus, $app_strings; $this->subpanel_defs = $subpanelDef; $this->subpanel_id = $subpanel_id; $this->parent_record_id = $record_id; $this->parent_module = $module; $this->layout_def_key = $layout_def_key; $this->collections = $collections; $this->parent_bean = $focus; $result = $focus; if (empty($result)) { $parent_bean_name = $beanList[$module]; $parent_bean_file = $beanFiles[$parent_bean_name]; require_once $parent_bean_file; $this->parent_bean = new $parent_bean_name(); $this->parent_bean->retrieve($this->parent_record_id); $result = $this->parent_bean; } if ($record_id != 'fab4' && $result == null) { sugar_die($app_strings['ERROR_NO_RECORD']); } $this->buildSearchQuery(); if (!empty($subpanelDef)) { //load the subpanel by name. $panelsdef = new SubPanelDefinitions($result, $layout_def_key); $subpanelDef = $panelsdef->load_subpanel($subpanel_id, false, false, $this->search_query, $collections); $this->subpanel_defs = $subpanelDef; } }
private static function identifySubpanel($thisModuleName, $sourceModuleName) { $module = get_module_info($thisModuleName); require_once 'include/SubPanel/SubPanelDefinitions.php'; $spd = new SubPanelDefinitions($module); $subpanelNames = $spd->get_available_tabs(); // actually these are the displayed subpanels $subPanels = array(); foreach ($subpanelNames as $key => $name) { $GLOBALS['log']->debug($thisModuleName . " " . $name); $subPanel = $spd->load_subpanel($name); if (!isset($subPanel->_instance_properties['collection_list'])) { if ($sourceModuleName == $subPanel->_instance_properties['module']) { return $subPanel->_instance_properties['subpanel_name']; } } } return null; }
/** * For a specific module get any existing Subpanel Definitions it may have * @param string $moduleName * @return array */ public function getSubpanelDefs($moduleName) { $parent_bean = BeanFactory::getBean($moduleName); //Hack to allow the SubPanelDefinitions class to check the correct module dir if (!$parent_bean) { $parent_bean = (object) array('module_dir' => $moduleName); } $spd = new SubPanelDefinitions($parent_bean, '', '', $this->platforms[0]); $layout_defs = $spd->layout_defs; if (is_array($layout_defs) && isset($layout_defs['subpanel_setup'])) { foreach ($layout_defs['subpanel_setup'] as $name => $subpanel_info) { $aSubPanel = $spd->load_subpanel($name, false, false, true); if (!$aSubPanel) { continue; } if ($aSubPanel->isCollection()) { $collection = array(); foreach ($aSubPanel->sub_subpanels as $key => $subpanel) { $collection[$key] = $subpanel->panel_definition; } $layout_defs['subpanel_setup'][$name]['panel_definition'] = $collection; } else { $layout_defs['subpanel_setup'][$name]['panel_definition'] = $aSubPanel->panel_definition; } } } return $layout_defs; }
function __construct($subpanelName, $moduleName) { $GLOBALS['log']->debug(get_class($this) . "->__construct({$subpanelName} , {$moduleName})"); $this->_subpanelName = $subpanelName; $this->_moduleName = $moduleName; $module = BeanFactory::getBean($moduleName); // BEGIN ASSERTIONS if (empty($module)) { sugar_die(get_class($this) . ": Modulename {$moduleName} is not a Deployed Module"); } // END ASSERTIONS $this->historyPathname = 'custom/history/modules/' . $moduleName . '/subpanels/' . $subpanelName . '/' . self::HISTORYFILENAME; $this->_history = new History($this->historyPathname); require_once 'include/SubPanel/SubPanelDefinitions.php'; // retrieve the definitions for all the available subpanels for this module from the subpanel $spd = new SubPanelDefinitions($module); // Get the lists of fields already in the subpanel and those that can be added in // Get the fields lists from an aSubPanel object describing this subpanel from the SubPanelDefinitions object $this->_viewdefs = array(); $this->_fielddefs = array(); $this->_language = ''; if (!empty($spd->layout_defs)) { if (array_key_exists(strtolower($subpanelName), $spd->layout_defs['subpanel_setup'])) { //First load the original defs from the module folder $originalSubpanel = $spd->load_subpanel($subpanelName, false, true); $this->_fullFielddefs = $originalSubpanel ? $originalSubpanel->get_list_fields() : array(); $this->_mergeFielddefs($this->_fielddefs, $this->_fullFielddefs); $this->_aSubPanelObject = $spd->load_subpanel($subpanelName); // now check if there is a restored subpanel in the history area - if there is, then go ahead and use it if (file_exists($this->historyPathname)) { // load in the subpanelDefOverride from the history file $GLOBALS['log']->debug(get_class($this) . ": loading from history"); require $this->historyPathname; $this->_viewdefs = $layout_defs; } else { $this->_viewdefs = $this->_aSubPanelObject->get_list_fields(); } // don't attempt to access the template_instance property if our subpanel represents a collection, as it won't be there - the sub-sub-panels get this value instead if (!$this->_aSubPanelObject->isCollection()) { $this->_language = $this->_aSubPanelObject->template_instance->module_dir; } // Retrieve a copy of the bean for the parent module of this subpanel - so we can find additional fields for the layout $subPanelParentModuleName = $this->_aSubPanelObject->get_module_name(); $beanListLower = array_change_key_case($GLOBALS['beanList']); if (!empty($subPanelParentModuleName) && isset($beanListLower[strtolower($subPanelParentModuleName)])) { $subPanelParentModule = get_module_info($subPanelParentModuleName); // Run through the preliminary list, keeping only those fields that are valid to include in a layout foreach ($subPanelParentModule->field_defs as $key => $def) { $key = strtolower($key); if (AbstractMetaDataParser::validField($def)) { if (!isset($def['label'])) { $def['label'] = $def['name']; } $this->_fielddefs[$key] = $def; } } } $this->_mergeFielddefs($this->_fielddefs, $this->_viewdefs); } } }
$subpanel = $_REQUEST['subpanel']; $record = $_REQUEST['record']; $module = $_REQUEST['module']; $layout_def_key = $_REQUEST['layout_def_key']; if (empty($_REQUEST['inline'])) { insert_popup_header($theme); } // need to load the subpanel definition here and manipulate the 'where clause' if (($result = BeanFactory::getBean($module, $record)) === FALSE) { die("'{$module}' is not a valid module"); } if (!class_exists('MyClass')) { require_once 'include/SubPanel/SubPanelDefinitions.php'; } $panelsdef = new SubPanelDefinitions($result, $layout_def_key); $subpanelDef = $panelsdef->load_subpanel($subpanel); // create or append subpanel definition where clause for the filter if (!isset($subpanelDef->panel_definition['where']) || $subpanelDef->panel_definition['where'] == '') { $subpanelDef->panel_definition['where'] = ''; } else { $subpanelDef->panel_definition['where'] .= ' AND '; } if ($_REQUEST['search_params'] && $_REQUEST['search_params'] != '') { foreach ($subpanelDef->sub_subpanels as $key => $value) { $module_name = $subpanelDef->sub_subpanels[$key]->_instance_properties['module']; global $beanList, $beanFiles; $class_name = $beanList[$module_name]; //require_once($beanFiles[$class_name]); $class_name = new $class_name(); $table = $class_name->table_name; //run through every sub_subpanel
/** * @group 53223 */ public function testOneToManyRelationshipModule2Modult() { $_REQUEST['relate_id'] = $this->parentAccount->id; $_REQUEST['relate_to'] = $this->relationship->getName(); // create new account $objAccount = new Account(); $objAccount->name = "AccountBug53223" . $_REQUEST['relate_to'] . time(); $objAccount->save(); SugarTestAccountUtilities::setCreatedAccount(array($objAccount->id)); // Retrieve new data $this->parentAccount->retrieve($this->parentAccount->id); $objAccount->retrieve($objAccount->id); $this->parentAccount->load_relationship($this->relationship->getName()); $objAccount->load_relationship($this->relationship->getName()); // Getting data of subpanel of parent bean $_REQUEST['module'] = 'Accounts'; $_REQUEST['action'] = 'DetailView'; $_REQUEST['record'] = $this->parentAccount->id; $_SERVER['REQUEST_METHOD'] = 'GET'; unset($GLOBALS['focus']); $subpanels = new SubPanelDefinitions($this->parentAccount, 'Accounts'); $subpanelDef = $subpanels->load_subpanel($this->relationship->getName() . 'accounts_ida'); $subpanel = new SubPanel('Accounts', $this->parentAccount->id, 'default', $subpanelDef); $subpanel->setTemplateFile('include/SubPanel/SubPanelDynamic.html'); $subpanel->display(); $actual = $this->getActualOutput(); $this->assertContains($objAccount->name, $actual, 'Account name is not displayed in subpanel of parent account'); ob_clean(); // Getting data of subpanel of child bean $_REQUEST['module'] = 'Accounts'; $_REQUEST['action'] = 'DetailView'; $_REQUEST['record'] = $objAccount->id; $_SERVER['REQUEST_METHOD'] = 'GET'; unset($GLOBALS['focus']); $subpanels = new SubPanelDefinitions($objAccount, 'Accounts'); $subpanelDef = $subpanels->load_subpanel($this->relationship->getName() . 'accounts_ida'); $subpanel = new SubPanel('Accounts', $objAccount->id, 'default', $subpanelDef); $subpanel->setTemplateFile('include/SubPanel/SubPanelDynamic.html'); $subpanel->display(); $actual = $this->getActualOutput(); $this->assertNotContains($this->parentAccount->name, $actual, 'Parent account name is displayed in subpanel of child aaccount'); }
$_REQUEST['collection_basic'] = explode(',', $_REQUEST['collection_basic'][0]); $collection = $_REQUEST['collection_basic']; } if (empty($_REQUEST['inline'])) { insert_popup_header($theme); } //require_once('include/SubPanel/SubPanelDefinitions.php'); //require_once($beanFiles[$beanList[$_REQUEST['module']]]); //$focus=new $beanList[$_REQUEST['module']]; //$focus->retrieve($record); include 'include/SubPanel/SubPanel.php'; $layout_def_key = ''; if (!empty($_REQUEST['layout_def_key'])) { $layout_def_key = $_REQUEST['layout_def_key']; } require_once 'include/SubPanel/SubPanelDefinitions.php'; // retrieve the definitions for all the available subpanels for this module from the subpanel $bean = BeanFactory::getBean($module); $spd = new SubPanelDefinitions($bean); $aSubPanelObject = $spd->load_subpanel($subpanel); $subpanel_object = new SubPanel($module, $record, $subpanel, $aSubPanelObject, $layout_def_key, $collection); $subpanel_object->setTemplateFile('include/SubPanel/SubPanelDynamic.html'); echo empty($_REQUEST['inline']) ? $subpanel_object->get_buttons() : ''; $subpanel_object->display(); $jsAlerts = new jsAlerts(); if (!isset($_SESSION['isMobile'])) { echo $jsAlerts->getScript(); } if (empty($_REQUEST['inline'])) { insert_popup_footer($theme); }
function get_list_view_data() { global $app_strings; global $mod_strings; $field_list = $this->get_list_view_array(); $bean = BeanFactory::getBean('xeBayOrders'); $bean->retrieve($field_list['ID']); require_once 'include/SubPanel/SubPanelDefinitions.php'; $subpanel_definitions = new SubPanelDefinitions($bean); $subpanel_definitions->layout_defs['subpanel_setup']['xebaytransactions']['subpanel_name'] = "ForOrderSimple"; $thisPanel = $subpanel_definitions->load_subpanel("xebaytransactions"); ob_start(); include_once 'include/SubPanel/SubPanel.php'; $subpanel_object = new SubPanel('xeBayOrders', $field_list['ID'], 'all', $thisPanel); $subpanel_object->setTemplateFile('modules/xeBayTransactions/SubPanelDynamic.html'); $subpanel_object->display(); $subpanel_data = ob_get_contents(); @ob_end_clean(); $order_details .= '<p style="margin: 8px 0px 8px 0px;">'; $order_details .= $field_list['BUYER_USER_ID']; $order_details .= '</p>'; $order_details .= $subpanel_data; $field_list['ORDER_DETAILS'] = $order_details; if (!empty($field_list['BUYER_CHECKOUT_MESSAGE'])) { $message = "<img alt='{$mod_strings['LBL_MESSAGE']}' style='padding: 0px 5px 0px 2px' border='0' onclick=\"SUGAR.util.getStaticAdditionalDetails(this,'"; $message .= str_replace(array("'"), array("\\'"), $field_list['BUYER_CHECKOUT_MESSAGE']); // $message .= $field_list['BUYER_CHECKOUT_MESSAGE']; $message .= "','<div style=\\'float:left\\'>{$mod_strings['LBL_MESSAGE']}</div><div style=\\'float: right\\'>"; $closeVal = "false"; $message .= "'," . $closeVal . ")\" src='" . SugarThemeRegistry::current()->getImageURL('AlertEmailTemplates.gif') . "' class='info'>"; $field_list['BUYER_CHECKOUT_MESSAGE'] = $message; } if ($field_list['PRINT_STATUS']) { $field_list['PRINT_STATUS_ICON'] = "<img alt='Print status' border='0' src='" . SugarThemeRegistry::current()->getImageURL('Print_Email.gif') . "'>"; } return $field_list; }
/** * If a subpanel cannot be found in sidecar, try to find it in legacy * and convert it * @return bool */ protected function fixUpSubpanel() { // getting here usually means that the link passed in is from an oldschool layoutdef // get the name, get the key, get the link, then we work the magic $spd = new SubPanelDefinitions(BeanFactory::getBean($this->loadedModule)); if (!empty($spd->layout_defs)) { if (array_key_exists(strtolower($this->linkName), $spd->layout_defs['subpanel_setup'])) { $aSubPanelObject = $spd->load_subpanel($this->linkName); $this->_moduleName = $aSubPanelObject->get_module_name(); $this->bean = BeanFactory::getBean($this->_moduleName); // convert the old viewdef on the fly $this->convertLegacyViewDef($aSubPanelObject->get_list_fields()); return true; } } return false; }
function getTabs($tabs, $showTabs = true, $selectedGroup = 'All') { //WDong Bug: 12258 "All" tab in the middle of a record's detail view is not localized. if ($selectedGroup == 'All') { $selectedGroup = translate('LBL_TABGROUP_ALL'); } require_once 'include/SubPanel/SubPanelDefinitions.php'; $spd = new SubPanelDefinitions($this->focus); // Set up a mapping from subpanelID, found in the $tabs list, to the source module name // As the $GLOBALS['tabStructure'] array holds the Group Tabs by module name we need to efficiently convert between the two // when constructing the subpanel tabs // Note that we can't use the very similar GroupedTabStructure class as it lacks this mapping, and logically, it is designed // for use when constructing the module by module tabs, not the subpanel tabs, as we move away from using module names to represent // subpanels, and use unique subpanel IDs instead. $moduleNames = array(); foreach ($tabs as $subpanelID) { $subpanel = $spd->load_subpanel($subpanelID); if ($subpanel !== false) { $moduleNames[$subpanelID] = $subpanel->get_module_name(); } } $groups = array(); $found = array(); foreach ($GLOBALS['tabStructure'] as $mainTab => $subModules) { foreach ($subModules['modules'] as $key => $subModule) { foreach ($tabs as $subpanelID) { if (isset($moduleNames[$subpanelID]) && strcasecmp($subModule, $moduleNames[$subpanelID]) === 0) { $groups[translate($mainTab)]['modules'][$key] = $subpanelID; $found[$subpanelID] = true; break; } } } } // Put all the remaining subpanels into the 'Other' tab. foreach ($tabs as $subpanelID) { if (!isset($found[$subpanelID])) { $groups[translate('LBL_TABGROUP_OTHER')]['modules'][] = $subpanelID; } } /* Move history to same tab as activities */ if (in_array('history', $tabs) && in_array('activities', $tabs)) { foreach ($groups as $mainTab => $group) { if (in_array('activities', array_map('strtolower', $group['modules']))) { if (!in_array('history', array_map('strtolower', $group['modules']))) { /* Move hist from there to here */ $groups[$mainTab]['modules'][] = 'history'; } } else { if (false !== ($i = array_search('history', array_map('strtolower', $group['modules'])))) { unset($groups[$mainTab]['modules'][$i]); if (empty($groups[$mainTab]['modules'])) { unset($groups[$mainTab]); } } } } } /* Add the 'All' group. * Note that if a tab group already exists with the name 'All', * it will be overwritten in this union operation. */ if (count($groups) <= 1) { $groups = array(translate('LBL_TABGROUP_ALL') => array('label' => translate('LBL_TABGROUP_ALL'), 'modules' => $tabs)); } else { $groups = array(translate('LBL_TABGROUP_ALL') => array('label' => translate('LBL_TABGROUP_ALL'), 'modules' => $tabs)) + $groups; } /* Note - all $display checking and array_intersects with $tabs * are now redundant (thanks to GroupedTabStructure), and could * be removed for performance, but for now can stay to help ensure * that the tabs get renedered correctly. */ $retTabs = array(); if ($showTabs) { require_once 'include/SubPanel/SugarTab.php'; $sugarTab = new SugarTab(); $displayTabs = array(); $otherTabs = array(); foreach ($groups as $key => $tab) { $display = false; foreach ($tab['modules'] as $subkey => $subtab) { if (in_array(strtolower($subtab), $tabs)) { $display = true; break; } } $selected = ''; if ($selectedGroup == $key) { $selected = 'current'; } if ($display) { $relevantTabs = SubPanelTilesTabs::applyUserCustomLayoutToTabs($tabs, $key); $sugarTabs[$key] = array('label' => !empty($tab['label']) ? $tab['label'] : $key, 'type' => $selected); $otherTabs[$key] = array('key' => $key, 'tabs' => array()); $orderedTabs = array_intersect($relevantTabs, array_map('strtolower', $groups[$key]['modules'])); foreach ($orderedTabs as $subkey => $subtab) { $otherTabs[$key]['tabs'][$subkey] = array('key' => $subtab, 'label' => translate($this->subpanel_definitions->layout_defs['subpanel_setup'][$subtab]['title_key'])); } if ($selectedGroup == $key) { $displayTabs = $otherTabs[$key]['tabs']; $retTabs = $orderedTabs; } } } if (empty($displayTabs) && !empty($otherTabs)) { //WDong Bug: 12258 "All" tab in the middle of a record's detail view is not localized. $selectedGroup = translate('LBL_TABGROUP_ALL'); $displayTabs = $otherTabs[$selectedGroup]['tabs']; $sugarTabs[$selectedGroup]['type'] = 'current'; $retTabs = array_intersect($tabs, array_map('strtolower', $groups[$selectedGroup]['modules'])); } if (!empty($sugarTabs) || !empty($otherTabs)) { $sugarTab->setup($sugarTabs, $otherTabs, $displayTabs, $selectedGroup); $sugarTab->display(); } } else { $tabs = SubPanelTilesTabs::applyUserCustomLayoutToTabs($tabs, $selectedGroup); $retTabs = array_intersect($tabs, array_map('strtolower', $groups[$selectedGroup]['modules'])); } return $retTabs; }
protected static function loadSubpanelDefs($bean) { $module = $bean->module_dir; if (!isset(static::$subpanelDefs[$module])) { static::$subpanelDefs[$module] = array(); $spd = new SubPanelDefinitions($bean); $subpanelNames = $spd->get_available_tabs(); // actually these are the displayed subpanels foreach ($subpanelNames as $key => $name) { static::$subpanelDefs[$module][$name] = $spd->load_subpanel($name); } } return static::$subpanelDefs[$module]; }