m_aTags = array('itopblock', 'itoptabs', 'itoptab', 'itoptoggle'); $this->m_sTemplate = $sTemplate; } public function Render(web_page $oPage, $aParams = array()) { $this->ApplyParams($aParams); $iStart = 0; $iEnd = strlen($this->m_sTemplate); $iCount = 0; $iBeforeTagPos = $iStart; $iAfterTagPos = $iStart; while($sTag = $this->GetNextTag($iStart, $iEnd)) { $sContent = $this->GetTagContent($sTag, $iStart, $iEnd); $aAttributes = $this->GetTagAttributes($sTag, $iStart, $iEnd); //$oPage->p("Tag: $sTag - ($iStart, $iEnd)"); $oPage->add(substr($this->m_sTemplate, $iBeforeTagPos, $iStart - $iBeforeTagPos)); $this->RenderTag($oPage, $sTag, $aAttributes, $sContent); $iAfterTagPos = $iEnd + strlen(''); $iBeforeTagPos = $iAfterTagPos; $iStart = $iEnd; $iEnd = strlen($this->m_sTemplate); $iCount++; if ($iCount > 10) break; } $oPage->add(substr($this->m_sTemplate, $iAfterTagPos)); } /** * Replaces all the parameters by the values passed in the hash array */ public function ApplyParams($aParams) { $aSearches = array(); $aReplacements = array(); foreach($aParams as $sSearch => $sReplace) { $aSearches[] = '$'.$sSearch.'$'; $aReplacements[] = $sReplace; } $this->m_sTemplate = str_replace($aSearches, $aReplacements, $this->m_sTemplate); } public function GetNextTag(&$iStartPos, &$iEndPos) { $iChunkStartPos = $iStartPos; $sNextTag = null; $iStartPos = $iEndPos; foreach($this->m_aTags as $sTag) { // Search for the opening tag $iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.' ', $iChunkStartPos); if ($iOpeningPos === false) { $iOpeningPos = stripos($this->m_sTemplate, '<'.$sTag.'>', $iChunkStartPos); } if ($iOpeningPos !== false) { $iClosingPos = stripos($this->m_sTemplate, '', $iOpeningPos); } if ( ($iOpeningPos !== false) && ($iClosingPos !== false)) { if ($iOpeningPos < $iStartPos) { // This is the next tag $iStartPos = $iOpeningPos; $iEndPos = $iClosingPos; $sNextTag = $sTag; } } } return $sNextTag; } public function GetTagContent($sTag, $iStartPos, $iEndPos) { $sContent = ""; $iContentStart = strpos($this->m_sTemplate, '>', $iStartPos); // Content of tag start immediatly after the first closing bracket if ($iContentStart !== false) { $sContent = substr($this->m_sTemplate, 1+$iContentStart, $iEndPos - $iContentStart - 1); } return $sContent; } public function GetTagAttributes($sTag, $iStartPos, $iEndPos) { $aAttr = array(); $iAttrStart = strpos($this->m_sTemplate, ' ', $iStartPos); // Attributes start just after the first space $iAttrEnd = strpos($this->m_sTemplate, '>', $iStartPos); // Attributes end just before the first closing bracket if ( ($iAttrStart !== false) && ($iAttrEnd !== false) && ($iAttrEnd > $iAttrStart)) { $sAttributes = substr($this->m_sTemplate, 1+$iAttrStart, $iAttrEnd - $iAttrStart - 1); $aAttributes = explode(' ', $sAttributes); foreach($aAttributes as $sAttr) { if ( preg_match('/(.+) *= *"(.+)"$/', $sAttr, $aMatches) ) { $aAttr[strtolower($aMatches[1])] = $aMatches[2]; } } } return $aAttr; } protected function RenderTag($oPage, $sTag, $aAttributes, $sContent) { static $iTabContainerCount = 0; static $iBlockCount = 0; switch($sTag) { case 'itoptabs': $oPage->AddTabContainer('Tabs_'.$iTabContainerCount); $oPage->SetCurrentTabContainer('Tabs_'.$iTabContainerCount); $iTabContainerCount++; //$oPage->p('Content:
'.htmlentities($sContent).'
'); $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied $oPage->SetCurrentTabContainer(''); break; case 'itoptab': $oPage->SetCurrentTab($aAttributes['name']); $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied //$oPage->p('iTop Tab Content:
'.htmlentities($sContent).'
'); $oPage->SetCurrentTab(''); break; case 'itoptoggle': $oPage->StartCollapsibleSection($aAttributes['name']); $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied //$oPage->p('iTop Tab Content:
'.htmlentities($sContent).'
'); $oPage->EndCollapsibleSection(); break; case 'itopblock': // TO DO: Use DisplayBlock::FromTemplate here $sBlockClass = $aAttributes['blockclass']; $sBlockType = $aAttributes['type']; $aExtraParams = array(); if (isset($aAttributes['linkage'])) { $aExtraParams['linkage'] = $aAttributes['linkage']; } switch($aAttributes['encoding']) { case 'text/sibusql': $oFilter = CMDBSearchFilter::FromSibusQL($sContent); break; case 'text/oql': $oFilter = CMDBSearchFilter::FromOQL($sContent); break; case 'text/serialize': default: $oFilter = CMDBSearchFilter::unserialize($sContent); break; } $oBlock = new $sBlockClass($oFilter, $sBlockType, false, $aExtraParams); $oBlock->Display($oPage, 'block_'.$iBlockCount); $iBlockCount++; break; default: // Unknown tag, just ignore it or now -- output an HTML comment $oPage->add(""); } } /** * Unit test */ static public function UnitTest() { require_once('../application/startup.inc.php'); require_once("../application/itopwebpage.class.inc.php"); $sTemplate = ' bizNetworkDevice: pkey = $pkey$ bizInterface: device_id = $pkey$ bizContact: PKEY IS contact_id IN (ContactsLinks: object_id = $pkey$) bizDocument: PKEY IS doc_id IN (lnkDocumentRealObject: object_id = $pkey$) '; $oPage = new iTopWebPage('Unit Test', 3); //$oPage->add("Template content:
".htmlentities($sTemplate)."
\n"); $oTemplate = new DisplayTemplate($sTemplate); $oTemplate->Render($oPage, array('class'=>'Network device','pkey'=> 271, 'name' => 'deliversw01.mecanorama.fr', 'org_id' => 3)); $oPage->output(); } } //DisplayTemplate::UnitTest(); ?>