* @author Romain Quetiez * @author Denis Flaven * @license http://www.opensource.org/licenses/gpl-3.0.html GPL */ class DataTable { protected $iListId; // Unique ID inside the web page protected $sTableId; // identifier for sqve the settings (combined with the class aliases) protected $oSet; // The set of objects to display protected $aClassAliases; // The aliases (alias => class) inside the set protected $iNbObjects; // Total number of objects inthe set protected $bUseCustomSettings; // Whether or not the current display uses custom settings protected $oDefaultSettings; // the default settings for displaying such a list /** * @param $iListId mixed Unique ID for this div/table in the page * @param $oSet DBObjectSet The set of data to display * @param $aClassAliases Hash The list of classes/aliases to be displayed in this set $sAlias => $sClassName * @param $sTableId mixed A string (or null) identifying this table in order to persist its settings */ public function __construct($iListId, $oSet, $aClassAliases, $sTableId = null) { $this->iListId = $iListId; $this->oSet = $oSet; $this->aClassAliases = $aClassAliases; $this->sTableId = $sTableId; $this->iNbObjects = $oSet->Count(); $this->bUseCustomSettings = false; $this->oDefaultSettings = null; } public function Display(WebPage $oPage, DataTableSettings $oSettings, $bActionsMenu, $sSelectMode, $bViewLink, $aExtraParams) { $this->oDefaultSettings = $oSettings; // Identified tables can have their own specific settings $oCustomSettings = DataTableSettings::GetTableSettings($this->aClassAliases, $this->sTableId); if ($oCustomSettings != null) { // Custom settings overload the default ones $this->bUseCustomSettings = true; } else { $oCustomSettings = $oSettings; } if ($oCustomSettings->iDefaultPageSize > 0) { $this->oSet->SetLimit($oCustomSettings->iDefaultPageSize); } $this->oSet->SetOrderBy($oCustomSettings->GetSortOrder()); $bToolkitMenu = true; if (UserRights::IsPortalUser()) { // Portal users have a limited access to data, for now they can only see what's configured for them $bToolkitMenu = false; } return $this->GetAsHTML($oPage, $oCustomSettings->iDefaultPageSize, $oCustomSettings->iDefaultPageSize, 0, $oCustomSettings->aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams); } public function GetAsHTML(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex, $aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams) { $sObjectsCount = $this->GetObjectCount($oPage, $sSelectMode); $sPager = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex); $sActionsMenu = ''; $sToolkitMenu = ''; if ($bActionsMenu) { $sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams); } if ($bToolkitMenu) { $sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams); } $sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams); $sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize); $sHtml = "iListId}\" class=\"datatable\">"; $sHtml .= ""; $sHtml .= ""; $sHtml .= "
"; $sHtml .= ""; $sHtml .= ""; $sHtml .= "$sPager"; $sHtml .= "
$sObjectsCount$sToolkitMenu $sActionsMenu
"; $sHtml .= "
$sDataTable
\n"; $oPage->add_at_the_end($sConfigDlg); $aOptions = array( 'sPersistentId' => '', 'sFilter' => $this->oSet->GetFilter()->serialize(), 'oColumns' => $aColumns, 'sSelectMode' => $sSelectMode, 'sViewLink' => ($bViewLink ? 'true' : 'false'), 'iNbObjects' => $this->iNbObjects, 'iDefaultPageSize' => $iDefaultPageSize, 'iPageSize' => $iPageSize, 'iPageIndex' => $iPageIndex, 'oClassAliases' => $this->aClassAliases, 'sTableId' => $this->sTableId, 'oExtraParams' => $aExtraParams, 'sRenderUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', 'oRenderParameters' => array('str' => ''), // Forces JSON to encode this as a object... 'oDefaultSettings' => array('str' => ''), // Forces JSON to encode this as a object... 'oLabels' => array('moveup' => Dict::S('UI:Button:MoveUp'), 'movedown' => Dict::S('UI:Button:MoveDown')), ); if($this->oDefaultSettings != null) { $aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings); } $sJSOptions = json_encode($aOptions); $oPage->add_ready_script("$('#datatable_{$this->iListId}').datatable($sJSOptions);"); return $sHtml; } /** * When refreshing the body of a paginated table, get the rows of the table (inside the TBODY) * return string The HTML rows to insert inside the node */ public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams) { $aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink); $aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams); $sHtml = ''; foreach($aValues as $aRow) { $sHtml .= $oPage->GetTableRow($aRow, $aAttribs); } return $sHtml; } protected function GetObjectCount(WebPage $oPage, $sSelectMode) { if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) { $sHtml = '
'.Dict::Format('UI:Pagination:HeaderSelection', ''.$this->iNbObjects.'', '0').'
'; } else { $sHtml = '
'.Dict::Format('UI:Pagination:HeaderNoSelection', ''.$this->iNbObjects.'').'
'; } return $sHtml; } protected function GetPager(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex) { $sHtml = ''; if ($iPageSize < 1) // Display all { $sPagerStyle = 'style="display:none"'; // no limit: display the full table, so hide the "pager" UI } else { $sPagerStyle = ''; } $sCombo = ''; $sPages = Dict::S('UI:Pagination:PagesLabel'); $sPageSizeCombo = Dict::Format('UI:Pagination:PageSize', $sCombo); $iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize); if ($iNbPages == 1) { // No need to display the pager $sPagerStyle = 'style="display:none"'; } $aPagesToDisplay = array(); for($idx = 0; $idx <= min(4, $iNbPages-1); $idx++) { if ($idx == 0) { $aPagesToDisplay[$idx] = '1'; } else { $aPagesToDisplay[$idx] = "".(1+$idx).""; } } $iLastPageIdx = $iNbPages - 1; if (!isset($aPagesToDisplay[$iLastPageIdx])) { unset($aPagesToDisplay[$idx - 1]); // remove the last page added to make room for the very last page $aPagesToDisplay[$iLastPageIdx] = "... $iNbPages"; } $sPagesLinks = implode('', $aPagesToDisplay); $sPagesList = '['.implode(',', array_keys($aPagesToDisplay)).']'; $sSelectionMode = ($iNbPages == 1) ? '' : 'positive'; $sHtml = <<
$sPages $sPagesLinks $sPageSizeCombo  
EOF; return $sHtml; } protected function GetActionsMenu(WebPage $oPage, $aExtraParams) { $oMenuBlock = new MenuBlock($this->oSet->GetFilter(), 'list'); $sHtml = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId); return $sHtml; } protected function GetToolkitMenu(WebPage $oPage, $aExtraParams) { $sMenuTitle = Dict::S('UI:ConfigureThisList'); $sHtml = ''; //$oPage->add_ready_script("$('#tk_{$this->iListId} > ul').popupmenu();"); return $sHtml; } protected function GetTableConfigDlg(WebPage $oPage, $aColumns, $bViewLink, $iDefaultPageSize) { $sHtml = "
iListId}\" style=\"display: none;\">"; $sHtml .= "
"; $sChecked = ($this->bUseCustomSettings) ? '' : 'checked'; $sHtml .= "

iListId}\" type=\"radio\" name=\"settings\" $sChecked value=\"defaults\">

'; $sHtml .= "
"; $sChecked = ($this->bUseCustomSettings) ? 'checked': ''; $sHtml .= "iListId}\" type=\"radio\" class=\"specific_settings\" name=\"settings\" $sChecked value=\"specific\">"; $sHtml .= Dict::S('UI:ColumnsAndSortOrder').'
    '; $sHtml .= '

    '.Dict::Format('UI:Display_X_ItemsPerPage', '').'

    '; $sHtml .= "
    "; $sHtml .= "
    "; $sSaveChecked = ($this->sTableId != null) ? 'checked' : ''; $sCustomDisabled = ($this->sTableId == null) ? 'disabled="disabled" stay-disabled="true" ' : ''; $sCustomChecked = ($this->sTableId != null) ? 'checked' : ''; $sGenericChecked = ($this->sTableId == null) ? 'checked' : ''; $sHtml .= "iListId}\" type=\"checkbox\" $sSaveChecked name=\"save_settings\">"; $sHtml .= "

    iListId}\" type=\"radio\" name=\"scope\" $sCustomChecked $sCustomDisabled value=\"this_list\">    '; $sHtml .= "iListId}\" type=\"radio\" name=\"scope\" $sGenericChecked value=\"defaults\">

    '; $sHtml .= "
    "; $sHtml .= '
    '; $sHtml .= ''; $sHtml .= ''; $sHtml .= ''; $sHtml .= '
    '; $sHtml .= "
    "; $sHtml .= "
    "; $sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle')); $oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#datatable_{$this->iListId}').datatable('onDlgCancel'); } });"); return $sHtml; } public function GetAsHash($oSetting) { $aSettings = array('iDefaultPageSize' => $oSetting->iDefaultPageSize, 'oColumns' => $oSetting->aColumns); return $aSettings; } protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink) { $aAttribs = array(); if ($sSelectMode == 'multiple') { $aAttribs['form::select'] = array('label' => "iListId}:not(:disabled)', this.checked);\" class=\"checkAll\">", 'description' => Dict::S('UI:SelectAllToggle+')); } else if ($sSelectMode == 'single') { $aAttribs['form::select'] = array('label' => "", 'description' => ''); } foreach($this->aClassAliases as $sAlias => $sClassName) { foreach($aColumns[$sAlias] as $sAttCode => $aData) { if ($aData['checked']) { if ($sAttCode == '_key_') { $aAttribs['key_'.$sAlias] = array('label' => MetaModel::GetName($sClassName), 'description' => ''); } else { $oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode); $aAttribs[$sAttCode.'_'.$sAlias] = array('label' => MetaModel::GetLabel($sClassName, $sAttCode), 'description' => $oAttDef->GetOrderByHint()); } } } } return $aAttribs; } protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams) { $aValues = array(); $this->oSet->Seek(0); $iMaxObjects = $iPageSize; while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0)) { $bFirstObject = true; $aRow = array(); foreach($this->aClassAliases as $sAlias => $sClassName) { $sHilightClass = $aObjects[$sAlias]->GetHilightClass(); if ($sHilightClass != '') { $aRow['@class'] = $sHilightClass; } if ((($sSelectMode == 'single') || ($sSelectMode == 'multiple')) && $bFirstObject) { if (array_key_exists('selection_enabled', $aExtraParams) && isset($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()])) { $sDisabled = ($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]) ? '' : ' disabled="disabled"'; } else { $sDisabled = ''; } if ($sSelectMode == 'single') { $aRow['form::select'] = "iListId}\" name=\"selectObject\" value=\"".$aObjects[$sAlias]->GetKey()."\">"; } else { $aRow['form::select'] = "iListId}\" name=\"selectObject[]\" value=\"".$aObjects[$sAlias]->GetKey()."\">"; } } foreach($aColumns[$sAlias] as $sAttCode => $aData) { if ($aData['checked']) { if ($sAttCode == '_key_') { $aRow['key_'.$sAlias] = $aObjects[$sAlias]->GetHyperLink(); } else { $aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode); } } } $bFirstObject = false; } $aValues[] = $aRow; $iMaxObjects--; } return $aValues; } public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams) { $iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize); if ($iPageSize < 1) { $iPageSize = -1; // convention: no pagination } $aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink); $aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams); $sHtml = ''; foreach($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue) { $aExtraParams['query_params'][$sName] = $sValue; } $sHtml .= "'; $sHtml .= '
    "; $sHtml .= $oPage->GetTable($aAttribs, $aValues); $sHtml .= '
    '; $iCount = $this->iNbObjects; $aArgs = $this->oSet->GetArgs(); $sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them $sSelectModeJS = ''; $sHeaders = ''; if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) { $sSelectModeJS = $sSelectMode; $sHeaders = 'headers: { 0: {sorter: false}},'; } $sDisplayKey = ($bViewLink) ? 'true' : 'false'; // Protect against duplicate elements in the Zlist $aUniqueOrderedList = array(); foreach($this->aClassAliases as $sAlias => $sClassName) { foreach($aColumns[$sAlias] as $sAttCode => $aData) { if ($aData['checked']) { $aUniqueOrderedList[$sAttCode] = true; } } } $aUniqueOrderedList = array_keys($aUniqueOrderedList); $sJSColumns = json_encode($aColumns); $sJSClassAliases = json_encode($this->aClassAliases); $sCssCount = isset($aExtraParams['cssCount']) ? ", cssCount: '{$aExtraParams['cssCount']}'" : ''; $this->oSet->ApplyParameters(); // Display the actual sort order of the table $aRealSortOrder = $this->oSet->GetRealSortOrder(); $aDefaultSort = array(); $iColOffset = 0; if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) { $iColOffset += 1; } if ($bViewLink) { // $iColOffset += 1; } foreach($aRealSortOrder as $sColCode => $bAscending) { $iPos = array_search($sColCode, $aUniqueOrderedList); if ($iPos !== false) { $aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]"; } else if (($iPos = array_search(preg_replace('/_friendlyname$/', '', $sColCode), $aUniqueOrderedList)) !== false) { // if sorted on the friendly name of an external key, then consider it sorted on the column that shows the links $aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]"; } else if($sColCode == 'friendlyname' && $bViewLink) { $aDefaultSort[] = "[".($iColOffset).",".($bAscending ? '0' : '1')."]"; } } $sSortList = ''; if (count($aDefaultSort) > 0) { $sSortList = ', sortList: ['.implode(',', $aDefaultSort).']'; } $sOQL = addslashes($this->oSet->GetFilter()->serialize()); $oPage->add_ready_script( <<iListId} table.listResults'); oTable.tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList'] $sSortList} ).tablesorterPager({container: $('#pager{$this->iListId}'), totalRows:$iCount, size: $iPageSize, filter: '$sOQL', extra_params: '$sExtraParams', select_mode: '$sSelectModeJS', displayKey: $sDisplayKey, columns: $sJSColumns, class_aliases: $sJSClassAliases $sCssCount}); EOF ); //if ($iNbPages == 1) if (false) { if (isset($aExtraParams['cssCount'])) { $sCssCount = $aExtraParams['cssCount']; if ($sSelectMode == 'single') { $sSelectSelector = ":radio[name^=selectObj]"; } else if ($sSelectMode == 'multiple') { $sSelectSelector = ":checkbox[name^=selectObj]"; } $oPage->add_ready_script( <<iListId} table.listResults $sSelectSelector').change(function() { var c = $('{$sCssCount}'); var v = $('#{$this->iListId} table.listResults $sSelectSelector:checked').length; c.val(v); $('#{$this->iListId} .selectedCount').text(v); c.trigger('change'); }); EOF ); } } return $sHtml; } public function UpdatePager(WebPage $oPage, $iDefaultPageSize, $iStart) { $iPageSize = ($iDefaultPageSize < 1) ? 1 : $iDefaultPageSize; $iPageIndex = 1 + floor($iStart / $iPageSize); $sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex); $oPage->add_ready_script("$('#pager{$this->iListId}').html('".str_replace("\n", ' ', addslashes($sHtml))."');"); if ($iDefaultPageSize < 1) { $oPage->add_ready_script("$('#pager{$this->iListId}').parent().hide()"); } else { $oPage->add_ready_script("$('#pager{$this->iListId}').parent().show()"); } } } class DataTableSettings implements Serializable { public $aClassAliases; public $sTableId; public $iDefaultPageSize; public $aColumns; public function __construct($aClassAliases, $sTableId = null) { $this->aClassAliases = $aClassAliases; $this->sTableId = $sTableId; $this->iDefaultPageSize = 10; $this->aColumns = array(); } protected function Init($iDefaultPageSize, $aSortOrder, $aColumns) { $this->iDefaultPageSize = $iDefaultPageSize; $this->aColumns = $aColumns; $this->FixVisibleColumns(); } public function serialize() { // Save only the 'visible' columns $aColumns = array(); foreach($this->aClassAliases as $sAlias => $sClass) { $aColumns[$sAlias] = array(); foreach($this->aColumns[$sAlias] as $sAttCode => $aData) { unset($aData['label']); // Don't save the display name unset($aData['alias']); // Don't save the alias (redundant) unset($aData['code']); // Don't save the code (redundant) if ($aData['checked']) { $aColumns[$sAlias][$sAttCode] = $aData; } } } return serialize( array( 'iDefaultPageSize' => $this->iDefaultPageSize, 'aColumns' => $aColumns, ) ); } public function unserialize($sData) { $aData = unserialize($sData); $this->iDefaultPageSize = $aData['iDefaultPageSize']; $this->aColumns = $aData['aColumns']; foreach($this->aClassAliases as $sAlias => $sClass) { foreach($this->aColumns[$sAlias] as $sAttCode => $aData) { $aFieldData = false; if ($sAttCode == '_key_') { $aFieldData = $this->GetFieldData($sAlias, $sAttCode, null, true /* bChecked */, $aData['sort']); } else if (MetaModel::isValidAttCode($sClass, $sAttCode)) { $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); $aFieldData = $this->GetFieldData($sAlias, $sAttCode, $oAttDef, true /* bChecked */, $aData['sort']); } if ($aFieldData) { $this->aColumns[$sAlias][$sAttCode] = $aFieldData; } else { unset($this->aColumns[$sAlias][$sAttCode]); } } } $this->FixVisibleColumns(); } static public function GetDataModelSettings($aClassAliases, $bViewLink, $aDefaultLists) { $oSettings = new DataTableSettings($aClassAliases); // Retrieve the class specific settings for each class/alias based on the 'list' ZList //TODO let the caller pass some other default settings (another Zlist, extre fields...) $aColumns = array(); foreach($aClassAliases as $sAlias => $sClass) { if ($aDefaultLists == null) { $aList = cmdbAbstract::FlattenZList(MetaModel::GetZListItems($sClass, 'list')); } else { $aList = $aDefaultLists[$sAlias]; } $aSortOrder = MetaModel::GetOrderByDefault($sClass); if ($bViewLink) { $sSort = 'none'; if(array_key_exists('friendlyname', $aSortOrder)) { $sSort = $aSortOrder['friendlyname'] ? 'asc' : 'desc'; } $aColumns[$sAlias]['_key_'] = $oSettings->GetFieldData($sAlias, '_key_', null, true /* bChecked */, $sSort); } foreach($aList as $sAttCode) { $sSort = 'none'; if(array_key_exists($sAttCode, $aSortOrder)) { $sSort = $aSortOrder[$sAttCode] ? 'asc' : 'desc'; } $oAttDef = Metamodel::GetAttributeDef($sClass, $sAttCode); $aFieldData = $oSettings->GetFieldData($sAlias, $sAttCode, $oAttDef, true /* bChecked */, $sSort); if ($aFieldData) $aColumns[$sAlias][$sAttCode] = $aFieldData; } } $iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit()); $oSettings->Init($iDefaultPageSize, $aSortOrder, $aColumns); return $oSettings; } protected function FixVisibleColumns() { foreach($this->aClassAliases as $sAlias => $sClass) { foreach($this->aColumns[$sAlias] as $sAttCode => $aData) { // Remove non-existent columns // TODO: check if the existing ones are still valid (in case their type changed) if (($sAttCode != '_key_') && (!MetaModel::IsValidAttCode($sClass, $sAttCode))) { unset($this->aColumns[$sAlias][$sAttCode]); } } $aList = MetaModel::ListAttributeDefs($sClass); // Add the other (non visible ones), sorted in alphabetical order $aTempData = array(); foreach($aList as $sAttCode => $oAttDef) { if ( (!array_key_exists($sAttCode, $this->aColumns[$sAlias])) && (!$oAttDef instanceof AttributeLinkSet)) { $aFieldData = $this->GetFieldData($sAlias, $sAttCode, $oAttDef, false /* bChecked */, 'none'); if ($aFieldData) $aTempData[$aFieldData['label']] = $aFieldData; } } ksort($aTempData); foreach($aTempData as $sLabel => $aFieldData) { $this->aColumns[$sAlias][$aFieldData['code']] = $aFieldData; } } } static public function GetTableSettings($aClassAliases, $sTableId = null) { $pref = null; $oSettings = new DataTableSettings($aClassAliases, $sTableId); if ($sTableId != null) { // An identified table, let's fetch its own settings (if any) $pref = appUserPreferences::GetPref($oSettings->GetPrefsKey($sTableId), null); } if ($pref == null) { // Try the global preferred values for this class / set of classes $pref = appUserPreferences::GetPref($oSettings->GetPrefsKey(null), null); if ($pref == null) { // no such settings, use the default values provided by the data model return null; } } $oSettings->unserialize($pref); return $oSettings; } public function GetSortOrder() { $aSortOrder = array(); foreach($this->aColumns as $sAlias => $aColumns) { foreach($aColumns as $aColumn) { if ($aColumn['sort'] != 'none') { $sCode = ($aColumn['code'] == '_key_') ? 'friendlyname' : $aColumn['code']; $aSortOrder[$sCode] = ($aColumn['sort']=='asc'); // true for ascending, false for descending } } break; // TODO: For now the Set object supports only sorting on the first class of the set } return $aSortOrder; } public function Save() { if ($this->sTableId == null) return false; // Cannot save, the table is not identified, use SaveAsDefault instead $sSettings = $this->serialize(); appUserPreferences::SetPref($this->GetPrefsKey($this->sTableId), $sSettings); return true; } public function SaveAsDefault() { $sSettings = $this->serialize(); appUserPreferences::SetPref($this->GetPrefsKey(null), $sSettings); return true; } /** * Clear the preferences for this particular table * @param $bResetAll boolean If true,the settings for all tables of the same class(es)/alias(es) are reset */ public function ResetToDefault($bResetAll) { if (($this->sTableId == null) && (!$bResetAll)) return false; // Cannot reset, the table is not identified, use force $bResetAll instead if ($bResetAll) { // Turn the key into a suitable PCRE pattern $sKey = $this->GetPrefsKey(null); $sPattern = str_replace(array('|'), array('\\|'), $sKey); // escape the | character $sPattern = '#^'.str_replace(array('*'), array('.*'), $sPattern).'$#'; // Don't use slash as the delimiter since it's used in our key to delimit aliases appUserPreferences::UnsetPref($sPattern, true); } else { appUserPreferences::UnsetPref($this->GetPrefsKey($this->sTableId), false); } return true; } protected function GetPrefsKey($sTableId = null) { if ($sTableId == null) $sTableId = '*'; $aKeys = array(); foreach($this->aClassAliases as $sAlias => $sClass) { $aKeys[] = $sAlias.'-'.$sClass; } return implode('/', $aKeys).'|'.$sTableId; } protected function GetFieldData($sAlias, $sAttCode, $oAttDef, $bChecked, $sSort) { $ret = false; if ($sAttCode == '_key_') { $sLabel = Dict::Format('UI:ExtKey_AsLink', MetaModel::GetName($this->aClassAliases[$sAlias])); $ret = array( 'label' => $sLabel, 'checked' => true, 'disabled' => true, 'alias' => $sAlias, 'code' => $sAttCode, 'sort' => $sSort, ); } else if (!$oAttDef->IsLinkSet()) { $sLabel = $oAttDef->GetLabel(); if ($oAttDef->IsExternalKey()) { $sLabel = Dict::Format('UI:ExtKey_AsLink', $oAttDef->GetLabel()); } else if ($oAttDef->IsExternalField()) { $oExtAttDef = $oAttDef->GetExtAttDef(); $sLabel = Dict::Format('UI:ExtField_AsRemoteField', $oAttDef->GetLabel(), $oExtAttDef->GetLabel()); } elseif ($oAttDef instanceof AttributeFriendlyName) { $sLabel = Dict::Format('UI:ExtKey_AsFriendlyName', $oAttDef->GetLabel()); } $ret = array( 'label' => $sLabel, 'checked' => $bChecked, 'disabled' => false, 'alias' => $sAlias, 'code' => $sAttCode, 'sort' => $sSort, ); } return $ret; } }