errors[]=strval($string);return true;}return false;}function hasErrors(){return(bool)count($this->errors);}function normilizeString($name){$name=strtolower(str_replace('\\','/', strval($name)));$matches=array();preg_match_all('/[-_a-z0-9 \/]+/',$name,$matches);$name=trim(implode('',$matches[0])," /.");return preg_replace('/-+/','-', preg_replace('/ +/','-',$name));}function toFileName($string){return str_replace('/','.', strval($string));}function alreadyExists(){if(strlen($this->saveFile)){return file_exists($this->saveFile);}return false;}}class TRMenu extends TRBase{var$name='';var$depth=0;var$possibleDepths=0;var$selected=false;var$class=false;var$style=false;var$data=array();var$reIndexMenus=false;var$params=array();function TRMenu($name,$possibleDepths=0){$this->name=$this->normilizeString($name);$this->possibleDepths=$possibleDepths;$this->saveFile=FILE_ROOT."/menu/{$this->name}.php";if(file_exists($this->saveFile)&&is_readable($this->saveFile)){$this->import(include $this->saveFile);}else{$this->addError("menu does not exist: '{$this->saveFile}'");}}function import($parts){$this->data=array();$this->depth=$parts['depth'];foreach($parts['data'] AS $key=>$array){if(key_exists('href',$array)&&key_exists('label',$array)){$this->data[]=$parts['data'][$key];}}}function setParams($params=array()){if(is_array($params)&&count($params)){foreach($params AS $param=>$value){$this->setParam($param,$value);}}}function setParam($param,$value=null){$this->params[$param]=$value;}function getParam($param=''){return key_exists($param,$this->params)?$this->params[$param]:null;}function render($nested=false,$showall=false,&$parent,$currentDepth=null){if(is_null($currentDepth)||false===$currentDepth){if(-1===($currentDepth=array_search($this->name,$parent->depthMap))){$currentDepth=0;}}if('true'===$nested){$nested=true;}elseif('false'===$nested){$nested=false;}elseif(is_numeric($nested)){$nested=intval($nested);}$items=array();$count=count($this->data);$i=1;$selectedId=(key_exists($currentDepth+1,$parent->depthMap)?$parent->depthMap[$currentDepth+1]:0);if(!$selectedId&&key_exists(intval($currentDepth),$parent->depthMap)&&$this->name==$parent->depthMap[$currentDepth]){$selectedId=$parent->depthMap[$currentDepth];}if(!($selected_class=$this->getParam('selected_class'))){$selected_class='selected';}foreach($this->data AS $item){$external=(key_exists('external',$item)&&'true'==$item['external']);$selected=false;$liExtra='';$classes=array('listItem');if(!$item['href']&&$external){$classes[]='listHeading';}if(1==$i){$classes[]='first';}elseif($count==$i){$classes[]='last';}if(key_exists('liclasses',$item)){$classes[]=$item['liclasses'];}if(!$external&&key_exists('childId',$item)&&$selectedId==$item['childId']){$selected=true;$classes[]=$selected_class;$classes[]=$item['liclasses'].'_'.$selected_class;}$liExtra.=" class=\"".implode(' ',$classes)."\" onmouseover=\"this.className += ' hover';\" onmouseout=\"this.className=this.className.replace(/[^a-zA-Z0-9]?hover/,'');\"";$items[]=$this->renderLi($item,$external,$selected,$liExtra,$nested,$showall,$currentDepth+1,$parent);$i++;}$ulClasses=array();if(false!==$this->class){$ulClasses[]=$this->class;}if(($ul_class=$this->getParam('ul_class'))){$ulClasses[]=$ul_class;}$ulExtra='';if(($ul_id=$this->getParam('ul_id'))){$ulExtra.=' id="'.$ul_id.'"';}if(count($ulClasses)){$ulExtra.=' class="'.implode(' ',$ulClasses).'"';}if(false!==$this->style){$ulExtra.=" style=\"{$this->style}\"";}return count($items)? "\n
\n\t".implode("\n\t",$items)."\n
":'';}function renderLi($link,$external=false,$selected=false,$liExtra='',$nested=false,$showall=false,$currentDepth=0,&$parent){$str=false;$hrefParts=array();if(key_exists('target',$link)&&strlen($link['target'])){$hrefParts[]='target="'.htmlentities($link['target']).'"';}if(key_exists('title',$link)&&strlen($link['title'])){$hrefParts[]='title="'.htmlentities($link['title']).'"';}$aClasses=array();if(key_exists('class',$link)&&strlen($link['class'])){$aClasses[]=htmlentities($link['class']);}if($selected){if(!($selected_class=$this->getParam('selected_class'))){$selected_class='selected';}$aClasses[]=$selected_class;}if(count($aClasses)){$hrefParts[]='class="'.implode(' ',$aClasses).'"';}$hrefExtras=count($hrefParts)?' '.implode(' ',$hrefParts):'';if(intval($this->name)!=intval($link['childId'])){if($selected&&!$external&&intval($nested) > 0&&$this->depth < $this->possibleDepths){$menu=new TRMenu($link['childId'],$this->possibleDepths);if($menu->alreadyExists()&&count($menu->data)){if($currentDepth){$menu->class="subMenu{$currentDepth}";}$menu->setParam('selected_class',$this->getParam('selected_class'));$liExtra=preg_replace('/(class="[^\"]+)"/','\1 has_submenu"',$liExtra);$str="\n"." buildURL($this->getLinkHref($link,$menu),$external)."\"{$hrefExtras}>".$link['label']."\n"." ".$menu->render((true===$nested?true:intval($nested)-1),$showall,$parent,$currentDepth)."\n"."";}}elseif($nested&&true===$showall&&!$external){$menu=new TRMenu($link['childId'],$this->possibleDepths);if($menu->alreadyExists()){if($currentDepth){$menu->class="subMenu{$currentDepth}";}$menu->setParam('selected_class',$this->getParam('selected_class'));$liExtra=preg_replace('/(class="[^\"]+)"/','\1 has_submenu"',$liExtra);$str="\n"." buildURL($this->getLinkHref($link,$menu),$external)."\"{$hrefExtras}>".$link['label']."\n"." ".$menu->render((true===$nested?true:intval($nested)-1),$showall,$parent,$currentDepth)."\n"."";}}unset($menu);}if(false!==$str){return $str;}return "".($external&&!$link['href'] ?"".$link['label']."" :"buildURL($this->getLinkHref($link),$external)."\"{$hrefExtras}>".$link['label']."")."";}function getLinkHref($link,$menu=null){if($link['placeholder']){if(is_null($menu)&&$link['childId']){$menu=new TRMenu($link['childId'],$this->possibleDepths);}if($menu){foreach($menu->data AS $item){if(!$item['external']&&!$item['placeholder']){return $item['href'];}}}}return $link['href'];}function buildURL($url,$external=false){return $external?str_replace(L_DELIM.'PUBLIC_PATH'.R_DELIM, htmlentities(PUBLIC_PATH),$url): PUBLIC_PATH.$url;}}class TRPage extends TRBase{var$page='';var$pageName='';var$depthMap=array();var$data=array('id'=>0,'title'=>'','metahtml'=>'','keywords'=>'','description'=>'','alias'=>'','template'=>'','templateName'=>'','content'=>array(0=>''),'section'=>'','pageName'=>'','path'=>'','parentName'=>0,'href'=>'','menuTitle'=>'','placeholder'=>false);var$menuCache=array();function TRPage($page,$basePage=false){$this->page=$this->normilizeString($page);$this->saveFile=FILE_ROOT.'/content/'.$this->toFileName($this->page).'.php';if(file_exists($this->saveFile)&&is_readable($this->saveFile)){$this->import(include $this->saveFile);if($basePage&&$this->data['placeholder']&&'#'!=($href=$this->getHref())){header('Location: '.$href);exit;}}else{header('HTTP/1.0 404 Not Found');exit;}}function import($parts){foreach($parts AS $key=>$value){if(key_exists($key,$this->data)){$this->data[$key]=$value;}}$this->depthMap=$parts['depthMap'];$this->pageName=$parts['pageName'];}function renderTemplate($tr_variables=array()){$strmap=array('"'=>'"');foreach($tr_variables AS $tr_var=>$tr_value){$$tr_var=$tr_value;}if(!$this->hasErrors()){$tr_templateFile=FILE_ROOT.'/templates/'.$this->data['template'].'.tpl.php';if(!file_exists($tr_templateFile)){$tr_newTemplateFile=FILE_ROOT.'/templates/'.FALLBACK_TEMPLATE.'.tpl.php';if(file_exists($tr_newTemplateFile)){$tr_templateFile=$tr_newTemplateFile;}}if(!is_readable($tr_templateFile)){return false;}if(strlen($tr_output=file_get_contents($tr_templateFile))){$tr_matches=array();$tr_replacements=array();if(preg_match_all('/('.L_DELIM.'[^'.substr(R_DELIM, 0, 1).']+'.R_DELIM.')/',$tr_output,$tr_matches, PREG_OFFSET_CAPTURE)){for($tr_i=0,$tr_c=count($tr_matches[1]);$tr_i < $tr_c;$tr_i++){$tr_variable=(substr($tr_matches[1][$tr_i][0], strlen(L_DELIM), -strlen(R_DELIM)));$tr_replace=false;if(!substr_count($tr_variable,':')){switch(strtoupper($tr_variable)){case'TITLE':$tr_replace=strtr($this->data['title'],$strmap);break;case'KEYWORDS':$tr_replace=strtr($this->data['keywords'],$strmap);break;case'DESCRIPTION':$tr_replace=strtr($this->data['description'],$strmap);break;case'ALIAS':$tr_replace=$this->data['alias'];break;case'PUBLIC_PATH':$tr_replace=PUBLIC_PATH;break;case'TEMPLATE_NAME':$tr_replace=$this->data['templateName'];break;case'RENDERMENU':$tr_replace=$this->renderMenu();break;case'RENDERCONTENT':$tr_replace=$this->getContent();break;case'METAHTML':$tr_replace=$this->renderContentArea($this->data['metahtml']);break;case'BREADCRUMBS':$tr_replace=$this->renderBreadCrumbs();break;case'SECTION':$tr_replace=$this->data['section'];break;case'PAGE_NAME':$tr_replace=$this->pageName;break;default:$tr_replace=$this->renderPlugin($tr_variable);break;}}else{$tr_command=substr($tr_variable, 0, strpos($tr_variable,':'));$tr_params=substr($tr_variable, strpos($tr_variable,':')+1);$tr_vars=explode(',',$tr_params);switch(strtoupper($tr_command)){case'RENDERMENU':$tr_replace=$this->renderMenu($tr_vars[0],$tr_vars[1],$tr_vars[2],$tr_vars[3]);break;case'RENDERCONTENT':$tr_replace=$this->getContent($tr_vars[0]);break;case'BREADCRUMBS':$tr_replace=$this->renderBreadCrumbs($tr_vars[0]);break;case'SNIPPET':$tr_replace=$this->getSnippet($tr_vars[0]);break;case'PLUGIN':$tr_plugin_info=$this->toPluginInfo($tr_params);$tr_replace=$this->renderPlugin($tr_plugin_info['name'],$tr_plugin_info['params']);break;case'INCLUDE':$tr_plugin_info=$this->toPluginInfo($tr_params);$tr_replace=tr_include($tr_plugin_info['name'],$tr_plugin_info['params'],$this->toPageArray());break;default:break;}}$tr_replacements[$tr_i]=false===$tr_replace?L_DELIM.$tr_variable.R_DELIM:$tr_replace;}}for($tr_i=count($tr_replacements)-1;$tr_i >= 0;$tr_i--){$tr_output=substr_replace($tr_output,$tr_replacements[$tr_i],$tr_matches[1][$tr_i][1], strlen($tr_matches[1][$tr_i][0]));}return $tr_output;}}return false;}function renderContentArea($tr_content){$tr_matches=array();$tr_replacements=array();if(preg_match_all('/('.L_DELIM.'[^'.substr(R_DELIM, 0, 1).']+'.R_DELIM.')/',$tr_content,$tr_matches, PREG_OFFSET_CAPTURE)){for($tr_i=0,$tr_c=count($tr_matches[1]);$tr_i < $tr_c;$tr_i++){$tr_code=$tr_matches[1][$tr_i][0];$tr_variable=(substr($tr_matches[1][$tr_i][0], strlen(L_DELIM), -strlen(R_DELIM)));$tr_replace=false;if(!substr_count($tr_variable,':')){switch(strtoupper($tr_variable)){case'TITLE': $tr_replace=htmlentities($this->data['title']);break;case'METAHTML': $tr_replace=$this->renderContentArea($this->data['metahtml']);break;case'KEYWORDS': $tr_replace=htmlentities($this->data['keywords']);break;case'DESCRIPTION': $tr_replace=htmlentities($this->data['description']);break;case'ALIAS': $tr_replace=htmlentities($this->data['alias']);break;case'PUBLIC_PATH': $tr_replace=htmlentities(PUBLIC_PATH);break;case'TEMPLATE_NAME': $tr_replace=htmlentities($this->data['templateName']);break;case'RENDERMENU': $tr_replace=$this->renderMenu();break;case'BREADCRUMBS': $tr_replace=$this->renderBreadCrumbs();break;case'SECTION': $tr_replace=$this->data['section'];break;case'PAGE_NAME': $tr_replace=$this->pageName;break;default:if(false===($tr_replace=$this->renderPlugin($tr_variable))){$tr_replace='(Not Recognized: '.htmlentities($tr_code).')';}break;}}else{$tr_command=substr($tr_variable, 0, strpos($tr_variable,':'));$tr_params=substr($tr_variable, strpos($tr_variable,':')+1);$tr_vars=explode(',',$tr_params);switch(strtoupper($tr_command)){case'RENDERMENU': $tr_replace=$this->renderMenu($tr_vars[0],$tr_vars[1],$tr_vars[2],$tr_vars[3]);break;case'BREADCRUMBS': $tr_replace=$this->renderBreadCrumbs($tr_vars[0]);break;case'SNIPPET': $tr_replace=$this->getSnippet($tr_vars[0]);break;case'PLUGIN':$tr_plugin_info=$this->toPluginInfo($tr_params);$tr_replace=$this->renderPlugin($tr_plugin_info['name'],$tr_plugin_info['params']);break;case'INCLUDE':$tr_plugin_info=$this->toPluginInfo($tr_params);$tr_replace=tr_include($tr_plugin_info['name'],$tr_plugin_info['params'],$this->toPageArray());break;default:break;}}$tr_replacements[$tr_i]=$tr_replace;}for($tr_i=count($tr_replacements)-1;$tr_i >= 0;$tr_i--){$tr_content=substr_replace($tr_content,$tr_replacements[$tr_i],$tr_matches[1][$tr_i][1], strlen($tr_matches[1][$tr_i][0]));}}return $tr_content;}function renderPlugin($tr_name,$tr_params=array()){$tr_name=strtolower(trim($tr_name));if(preg_match('/^[a-zA-Z][_a-zA-Z0-9]*$/',$tr_name)){$tr_function='typeroom_'.$tr_name;$tr_file1=FILE_ROOT."/../".TYPEROOM_PLUGINS_DIR."/{$tr_name}/{$tr_name}.php";$tr_file2=FILE_ROOT."/../".TYPEROOM_PLUGINS_DIR."/{$tr_name}.php";$tr_file=((file_exists($tr_file1)&&is_readable($tr_file1))?$tr_file1:((file_exists($tr_file2)&&is_readable($tr_file2))?$tr_file2:false));if(false!==$tr_file){TR_Plugin::start($tr_name);require_once $tr_file;if(function_exists($tr_function)){return $tr_function($this->toPageArray(),$tr_params);}}}return false;}function display($variables=array()){if(false!==($content=$this->renderTemplate($variables))){print $content;}else{header('HTTP/1.0 404 Not Found');exit;}}function getContent($name=''){if(!$name){$name=0;}if(key_exists($name,$this->data['content'])){return $this->renderContentArea($this->data['content'][$name]);}$this->addError("cannot get content for index '{$name}'");return '';}function getSnippet($name=''){if(strlen($name)&&false!==($content=@file_get_contents(FILE_ROOT."/snippets/{$name}.php"))){return $this->renderContentArea($content);}return '';}function &getMenu($name=null){if(is_null($name)){return false;}if(key_exists($name,$this->menuCache)){if($this->menuCache[$name]->hasErrors()){$false=false;return $false;}return $this->menuCache[$name];}$this->menuCache[$name]=new TRMenu($name, count($this->depthMap));return $this->getMenu($name);}function renderMenu($name='',$nested=false,$showall=false,$rawPrams=''){$cleanParams=array();foreach(explode('|',$rawPrams) AS $rawParam){if(false!==($pos=strpos($rawParam,'='))){$cleanParams[trim(substr($rawParam, 0,$pos))]=trim(substr($rawParam,$pos+1));}}$name=strval($name);$name=('*'==substr($name, 0, 1))?intval(substr($name, 1)):$this->depthMap[intval($name)];if(($menu =& $this->getMenu($name))){$showall=is_bool($showall)?$showall:'true'==$showall;$menu->setParams($cleanParams);return $menu->render($nested,$showall,$this);}return '';}function renderBreadCrumbs($separator='/'){$parts=array();$current =& $this;while ($current){$parts[]=''.$current->toString().'';$new=$current->data['parentName']?new TRPage($current->data['parentName']):false;unset($current);$current =& $new;unset($new);}return implode($separator, array_reverse($parts));}function getHref(){if($this->data['placeholder']){if(($menu =& $this->getMenu($this->data['id']))){foreach($menu->data AS $item){if(!$item['external']&&!$item['placeholder']){$href=$item['href'];break;}}}else{$href='#';}}else{$href=$this->data['href'];}return PUBLIC_PATH.$href;}function toString(){if(($title=$this->data['menuTitle'])){return $title;}elseif(($title=$this->data['title'])){return $title;}elseif(($title=$this->pageName)){if('main'==$title){return 'Home';}return $title;}return '';}function toPluginInfo($raw_params){$ret=array('name'=>'','params'=>array());$matches=array();if(preg_match('/^"([^"]+)"(.*)$/',$raw_params,$matches, PREG_OFFSET_CAPTURE)){$ret['name']=$matches[1][0];$subMatches=array();if(preg_match_all('/"(.+?[^\\\\])"="(.+?[^\\\\])";?/', ltrim($matches[2][0],','),$subMatches)){for($i=0,$c=count($subMatches[0]);$i < $c;$i++){$ret['params'][$this->unescape($subMatches[1][$i])]=$this->unescape($subMatches[2][$i]);}}}return $ret;}function unescape($str){return preg_replace('/\\\\([^\\\\])/','$1',$str);}function toPageArray(){return array('id'=>$this->data['id'],'pageName'=>$this->data['pageName'],'path'=>$this->data['path']);}}$includefile=dirname(__FILE__).'/common.php';if(file_exists($includefile)){require_once $includefile;}else{header('HTTP/1.0 404 Not Found');print('CMS Error');exit;}$cms=new TRPage((key_exists('tr_page_id',$_GET)&&strlen($_GET['tr_page_id'])?$_GET['tr_page_id']:'main'), true);unset($_GET['tr_page_id']);$cms->display();