/**
  * Get the HTML fragment corresponding to the display of a table representing a set of objects
  * @param WebPage $oPage The page object is used for out-of-band information (mostly scripts) output
  * @param CMDBObjectSet The set of objects to display
  * @param Hash $aExtraParams Some extra configuration parameters to tweak the behavior of the display
  * @return String The HTML fragment representing the table of objects
  */
 public static function GetDisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
 {
     if ($oPage->IsPrintableVersion() || $oPage->is_pdf()) {
         return self::GetDisplaySetForPrinting($oPage, $oSet, $aExtraParams);
     }
     if (empty($aExtraParams['currentId'])) {
         $iListId = $oPage->GetUniqueId();
         // Works only if not in an Ajax page !!
     } else {
         $iListId = $aExtraParams['currentId'];
     }
     // Initialize and check the parameters
     $bViewLink = isset($aExtraParams['view_link']) ? $aExtraParams['view_link'] : true;
     $sLinkageAttribute = isset($aExtraParams['link_attr']) ? $aExtraParams['link_attr'] : '';
     $iLinkedObjectId = isset($aExtraParams['object_id']) ? $aExtraParams['object_id'] : 0;
     $sTargetAttr = isset($aExtraParams['target_attr']) ? $aExtraParams['target_attr'] : '';
     if (!empty($sLinkageAttribute)) {
         if ($iLinkedObjectId == 0) {
             // if 'links' mode is requested the id of the object to link to must be specified
             throw new ApplicationException(Dict::S('UI:Error:MandatoryTemplateParameter_object_id'));
         }
         if ($sTargetAttr == '') {
             // if 'links' mode is requested the d of the object to link to must be specified
             throw new ApplicationException(Dict::S('UI:Error:MandatoryTemplateParameter_target_attr'));
         }
     }
     $bDisplayMenu = isset($aExtraParams['menu']) ? $aExtraParams['menu'] == true : true;
     $bTruncated = isset($aExtraParams['truncated']) ? $aExtraParams['truncated'] == true : true;
     $bSelectMode = isset($aExtraParams['selection_mode']) ? $aExtraParams['selection_mode'] == true : false;
     $bSingleSelectMode = isset($aExtraParams['selection_type']) ? $aExtraParams['selection_type'] == 'single' : false;
     $aExtraFieldsRaw = isset($aExtraParams['extra_fields']) ? explode(',', trim($aExtraParams['extra_fields'])) : array();
     $aExtraFields = array();
     foreach ($aExtraFieldsRaw as $sFieldName) {
         // Ignore attributes not of the main queried class
         if (preg_match('/^(.*)\\.(.*)$/', $sFieldName, $aMatches)) {
             $sClassAlias = $aMatches[1];
             $sAttCode = $aMatches[2];
             if ($sClassAlias == $oSet->GetFilter()->GetClassAlias()) {
                 $aExtraFields[] = $sAttCode;
             }
         } else {
             $aExtraFields[] = $sFieldName;
         }
     }
     $sHtml = '';
     $oAppContext = new ApplicationContext();
     $sClassName = $oSet->GetFilter()->GetClass();
     $sZListName = isset($aExtraParams['zlist']) ? $aExtraParams['zlist'] : 'list';
     if ($sZListName !== false) {
         $aList = self::FlattenZList(MetaModel::GetZListItems($sClassName, $sZListName));
         $aList = array_merge($aList, $aExtraFields);
     } else {
         $aList = $aExtraFields;
     }
     // Filter the list to removed linked set since we are not able to display them here
     foreach ($aList as $index => $sAttCode) {
         $oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
         if ($oAttDef instanceof AttributeLinkedSet) {
             // Removed from the display list
             unset($aList[$index]);
         }
     }
     if (!empty($sLinkageAttribute)) {
         // The set to display is in fact a set of links between the object specified in the $sLinkageAttribute
         // and other objects...
         // The display will then group all the attributes related to the link itself:
         // | Link_attr1 | link_attr2 | ... || Object_attr1 | Object_attr2 | Object_attr3 | .. | Object_attr_n |
         $aDisplayList = array();
         $aAttDefs = MetaModel::ListAttributeDefs($sClassName);
         assert(isset($aAttDefs[$sLinkageAttribute]));
         $oAttDef = $aAttDefs[$sLinkageAttribute];
         assert($oAttDef->IsExternalKey());
         // First display all the attributes specific to the link record
         foreach ($aList as $sLinkAttCode) {
             $oLinkAttDef = $aAttDefs[$sLinkAttCode];
             if (!$oLinkAttDef->IsExternalKey() && !$oLinkAttDef->IsExternalField()) {
                 $aDisplayList[] = $sLinkAttCode;
             }
         }
         // Then display all the attributes neither specific to the link record nor to the 'linkage' object (because the latter are constant)
         foreach ($aList as $sLinkAttCode) {
             $oLinkAttDef = $aAttDefs[$sLinkAttCode];
             if ($oLinkAttDef->IsExternalKey() && $sLinkAttCode != $sLinkageAttribute || $oLinkAttDef->IsExternalField() && $oLinkAttDef->GetKeyAttCode() != $sLinkageAttribute) {
                 $aDisplayList[] = $sLinkAttCode;
             }
         }
         // First display all the attributes specific to the link
         // Then display all the attributes linked to the other end of the relationship
         $aList = $aDisplayList;
     }
     $sSelectMode = 'none';
     if ($bSelectMode) {
         $sSelectMode = $bSingleSelectMode ? 'single' : 'multiple';
     }
     $sClassAlias = $oSet->GetClassAlias();
     $bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true;
     $sTableId = isset($aExtraParams['table_id']) ? $aExtraParams['table_id'] : null;
     $aClassAliases = array($sClassAlias => $sClassName);
     $oDataTable = new DataTable($iListId, $oSet, $aClassAliases, $sTableId);
     $oSettings = DataTableSettings::GetDataModelSettings($aClassAliases, $bViewLink, array($sClassAlias => $aList));
     if ($bDisplayLimit) {
         $iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
         $oSettings->iDefaultPageSize = $iDefaultPageSize;
     } else {
         $oSettings->iDefaultPageSize = 0;
     }
     $oSettings->aSortOrder = MetaModel::GetOrderByDefault($sClassName);
     return $oDataTable->Display($oPage, $oSettings, $bDisplayMenu, $sSelectMode, $bViewLink, $aExtraParams);
 }
 public static function DisplaySet(WebPage $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
 {
     if ($oPage->is_pdf()) {
         $oPage->add(self::DisplaySetForPrinting($oPage, $oSet, $aExtraParams));
     } else {
         $oPage->add(self::GetDisplaySet($oPage, $oSet, $aExtraParams));
     }
 }