rewrite_urls) ){
return;
}
ini_set('arg_separator.output', '&');
foreach($page->rewrite_urls as $key => $value){
output_add_rewrite_var($key,$value);
}
}
/**
* Send only messages and the content buffer to the client
* @static
*/
static function Flush(){
global $page;
self::StandardHeaders();
echo GetMessages();
echo $page->contentBuffer;
}
static function Content(){
global $page;
self::StandardHeaders();
echo GetMessages();
$page->GetGpxContent();
}
static function StandardHeaders(){
header('Content-Type: text/html; charset=utf-8');
Header('Vary: Accept,Accept-Encoding');// for proxies
}
/**
* Send only the messages and content as a simple html document
* @static
*/
static function BodyAsHTML(){
global $page;
$page->head_script .= 'var gp_bodyashtml = true;';
gpOutput::TemplateSettings();
self::StandardHeaders();
echo '
';
gpOutput::getHead();
echo '';
$class = 'gpbody';
if( common::RequestType() == 'admin' ){
$class .= ' gp_full_size';
}
echo '';
echo GetMessages();
$page->GetGpxContent();
echo '';
echo '';
gpOutput::HeadContent();
}
/**
* Send all content according to the current layout
* @static
*
*/
static function Template(){
global $page, $GP_ARRANGE, $GP_STYLES, $get_all_gadgets_called, $addon_current_id, $GP_MENU_LINKS, $GP_MENU_CLASS, $GP_MENU_CLASSES, $GP_MENU_ELEMENTS;
$get_all_gadgets_called = false;
if( isset($page->theme_addon_id) ){
$addon_current_id = $page->theme_addon_id;
}
gpOutput::TemplateSettings();
self::StandardHeaders();
$path = $page->theme_dir.'/template.php';
$return = IncludeScript($path,'require',array('page','GP_ARRANGE','GP_MENU_LINKS','GP_MENU_CLASS','GP_MENU_CLASSES','GP_MENU_ELEMENTS'));
//return will be false if there's a fatal error with the template.php file
if( $return === false ){
gpOutput::BodyAsHtml();
}
gpPlugin::ClearDataFolder();
gpOutput::HeadContent();
}
/**
* Get the settings for the current theme if settings.php exists
* @static
*/
static function TemplateSettings(){
global $page;
$path = $page->theme_dir.'/settings.php';
IncludeScript($path,'require_if',array('page','GP_GETALLGADGETS'));
}
/**
* Add a Header to the response
* The header will be discarded if it's an ajax request or similar
* @static
*/
static function AddHeader($header, $replace = true, $code = false){
if( !empty($_REQUEST['gpreq']) ){
return false;
}
if( $code ){
common::status_header($code,$header);
}else{
header($header,$replace);
}
return true;
}
/*
*
* Content Area Functions
*
*/
static function GetContainerID($name,$arg=false){
static $indices;
$name = str_replace(array('+','/','='),array('','',''),base64_encode($name));
if( !isset($indices[$name]) ){
$indices[$name] = 0;
}else{
$indices[$name]++;
}
return $name.'_'.$indices[$name];
}
/**
* Fetch the output and return as a string
*
*/
static function Fetch($default,$arg=''){
ob_start();
gpOutput::Get($default,$arg);
return ob_get_clean();
}
static function Get($default='',$arg=''){
global $page,$gpLayouts,$gpOutConf;
$outSet = false;
$outKeys = false;
$layout_info =& $gpLayouts[$page->gpLayout];
//container id
$container_id = $default.':'.substr($arg,0,10);
$container_id = self::GetContainerID($container_id);
if( isset($layout_info) && isset($layout_info['handlers']) ){
$handlers =& $layout_info['handlers'];
if( isset($handlers[$container_id]) ){
$outKeys = $handlers[$container_id];
$outSet = true;
}
}
//default values
if( !$outSet && isset($gpOutConf[$default]) ){
$outKeys[] = trim($default.':'.$arg,':');
}
gpOutput::ForEachOutput($outKeys,$container_id);
}
static function ForEachOutput($outKeys,$container_id){
if( !is_array($outKeys) || (count($outKeys) == 0) ){
$info = array();
$info['gpOutCmd'] = '';
gpOutput::CallOutput($info,$container_id);
return;
}
foreach($outKeys as $gpOutCmd){
$info = gpOutput::GetgpOutInfo($gpOutCmd);
if( $info === false ){
trigger_error('gpOutCmd '.$gpOutCmd.' not set');
continue;
}
$info['gpOutCmd'] = $gpOutCmd;
gpOutput::CallOutput($info,$container_id);
}
}
/* static */
static function GetgpOutInfo($gpOutCmd){
global $gpOutConf,$config;
$key = $gpOutCmd = trim($gpOutCmd,':');
$info = false;
$arg = '';
$pos = mb_strpos($key,':');
if( $pos > 0 ){
$arg = mb_substr($key,$pos+1);
$key = mb_substr($key,0,$pos);
}
if( isset($gpOutConf[$key]) ){
$info = $gpOutConf[$key];
}elseif( isset($config['gadgets'][$key]) ){
$info = $config['gadgets'][$key];
$info['is_gadget'] = true;
}else{
return false;
}
$info['key'] = $key;
$info['arg'] = $arg;
$info['gpOutCmd'] = $gpOutCmd;
return $info;
}
/* static */
static function GpOutLabel($key){
global $langmessage;
$info = gpOutput::GetgpOutInfo($key);
$label = $key;
if( isset($info['link']) && isset($langmessage[$info['link']]) ){
$label = $langmessage[$info['link']];
}
return str_replace(array(' ','_',':'),array(' ',' ',': '),$label);
}
static function CallOutput($info,$container_id){
global $GP_ARRANGE, $page, $langmessage, $GP_MENU_LINKS, $GP_MENU_CLASS, $GP_MENU_CLASSES, $gp_current_container;
$gp_current_container = $container_id;
self::$out_started = true;
self::$edit_area_id = '';
if( isset($info['disabled']) ){
return;
}
//gpOutCmd identifies the output function used, there can only be one
if( !isset($info['gpOutCmd']) ){
trigger_error('gpOutCmd not set for $info in CallOutput()');
return;
}
$param = $container_id.'|'.$info['gpOutCmd'];
$class = 'gpArea_'.str_replace(array(':',','),array('_',''),trim($info['gpOutCmd'],':'));
$permission = gpOutput::ShowEditLink('Admin_Theme_Content');
ob_start();
//for theme content arrangement
if( $GP_ARRANGE && $permission && isset($GLOBALS['GP_ARRANGE_CONTENT']) ){
$empty_container = empty($info['gpOutCmd']); //empty containers can't be removed and don't have labels
$class .= ' gp_output_area';
echo '
';
msg( $message );
self::$fatal_notices[$info_hash] = $error_text;
}
}
self::PopCatchable();
//echo pre($info);
//die();
return true;
}
static function PopCatchable(){
array_pop(self::$catchable);
}
static function ShowEditLink($permission=false){
global $GP_NESTED_EDIT;
if( $permission ){
return !$GP_NESTED_EDIT && common::LoggedIn() && admin_tools::HasPermission($permission);
}
return !$GP_NESTED_EDIT && common::LoggedIn();
}
static function EditAreaLink(&$index,$href,$label,$query='',$attr=''){
static $count = 0;
$count++;
$index = $count; //since &$index is passed by reference
if( is_array($attr) ){
$attr += array('class'=>'ExtraEditLink nodisplay','id'=>'ExtraEditLink'.$index);
}else{
$attr .= ' class="ExtraEditLink nodisplay" id="ExtraEditLink'.$index.'"';
}
return common::Link($href,$label,$query,$attr);
}
/**
* Unless the gadget area is customized by the user, this function will output all active gadgets
* If the area has been reorganized, it will output the customized areas
* This function is not called from gpOutput::Get('GetAllGadgets') so that each individual gadget area can be used as a drag area
*
*/
static function GetAllGadgets(){
global $config, $page, $gpLayouts, $get_all_gadgets_called;
$get_all_gadgets_called = true;
//if we have handler info
if( isset($gpLayouts[$page->gpLayout]['handlers']['GetAllGadgets']) ){
gpOutput::ForEachOutput($gpLayouts[$page->gpLayout]['handlers']['GetAllGadgets'],'GetAllGadgets');
return;
}
//show all gadgets if no changes have been made
if( !empty($config['gadgets']) ){
$count = 0;
foreach($config['gadgets'] as $gadget => $info){
if( isset($info['addon']) ){
$info['gpOutCmd'] = $info['key'] = $gadget;
gpOutput::CallOutput($info,'GetAllGadgets');
$count++;
}
}
if( $count ){
return;
}
}
//Show the area as editable if there isn't anything to show
$info = array();
$info['gpOutCmd'] = '';
gpOutput::CallOutput($info,'GetAllGadgets');
}
/**
* Get a Single Gadget
* This method should be called using gpOutput::Fetch('Gadget',$gadget_name)
*
*/
static function GetGadget($id){
global $config;
if( !isset($config['gadgets'][$id]) ){
return;
}
gpOutput::ExecArea($config['gadgets'][$id]);
}
/**
* Prepare the gadget content before getting template.php so that gadget functions can add css and js to the head
* @return null
*/
static function PrepGadgetContent(){
global $page;
$gadget_info = gpOutput::WhichGadgets($page->gpLayout);
foreach($gadget_info as $gpOutCmd => $info){
if( !isset(self::$gadget_cache[$gpOutCmd]) ){
ob_start();
gpOutput::ExecArea($info);
self::$gadget_cache[$gpOutCmd] = ob_get_clean();
}
}
}
/**
* Return information about the gadgets being used in the current layout
* @return array
*/
static function WhichGadgets($layout){
global $config,$gpLayouts;
$gadget_info = $temp_info = array();
if( !isset($config['gadgets']) ){
return $gadget_info;
}
$layout_info = & $gpLayouts[$layout];
$GetAllGadgets = true;
if( isset($layout_info['all_gadgets']) && !$layout_info['all_gadgets'] ){
$GetAllGadgets = false;
}
if( isset($layout_info['handlers']) ){
foreach($layout_info['handlers'] as $handler => $out_cmds){
//don't prep even if GetAllGadgets is set in the layout's config
if( $handler == 'GetAllGadgets' && !$GetAllGadgets ){
continue;
}
foreach($out_cmds as $gpOutCmd){
$temp_info[$gpOutCmd] = gpOutput::GetgpOutInfo($gpOutCmd);
}
}
}
//add all gadgets if $GetAllGadgets is true and the GetAllGadgets handler isn't overwritten
if( $GetAllGadgets && !isset($layout_info['handlers']['GetAllGadgets']) ){
foreach($config['gadgets'] as $gadget => $temp){
if( isset($temp['addon']) ){
$temp_info[$gadget] = gpOutput::GetgpOutInfo($gadget);
}
}
}
foreach($temp_info as $gpOutCmd => $info){
if( isset($info['is_gadget'])
&& $info['is_gadget']
&& !isset($info['disabled'])
){
$gadget_info[$gpOutCmd] = $info;
}
}
return $gadget_info;
}
/**
* @param string $arg comma seperated argument list: $top_level, $bottom_level, $options
* $top_level (int) The upper level of the menu to show, if deeper (in this case > ) than 0, only the submenu is shown
* $bottom_level (int) The lower level of menu to show
* $expand_level (int) The upper level from where to start expanding sublinks, if -1 no expansion
* $expand_all (int) Whether or not to expand all levels below $expand_level (defaults to 0)
* $source_menu (string) Which menu to use
*
*/
static function CustomMenu($arg,$title=false){
global $page, $gp_index;
//from output functions
if( is_array($title) ){
$title = $page->title;
}
$title_index = false;
if( isset($gp_index[$title]) ){
$title_index = $gp_index[$title];
}
$args = explode(',',$arg);
$args += array( 0=>0, 1=>3, 2=>-1, 3=>1, 4=>'' ); //defaults
list($top_level,$bottom_level,$expand_level,$expand_all,$source_menu) = $args;
//get menu array
$source_menu_array = gpOutput::GetMenuArray($source_menu);
//reduce array to $title => $level
$menu = array();
foreach($source_menu_array as $temp_key => $titleInfo){
if( !isset($titleInfo['level']) ){
break;
}
$menu[$temp_key] = $titleInfo['level'];
}
//Reduce for expansion
//first reduction
//message('expand level: '.$expand_level);
if( (int)$expand_level >= 1 ){
if( $expand_all ){
$menu = gpOutput::MenuReduce_ExpandAll($menu,$expand_level,$title_index,$top_level);
}else{
$menu = gpOutput::MenuReduce_Expand($menu,$expand_level,$title_index,$top_level);
}
}
//Reduce if $top_level >= 0
//second reduction
if( (int)$top_level > 0 ){
//echo 'top level: '.$top_level;
//message('top: '.$top_level);
$menu = gpOutput::MenuReduce_Top($menu,$top_level,$title_index);
}else{
$top_level = 0;
}
//Reduce by trimming off titles below $bottom_level
// last reduction : in case the selected link is below $bottom_level
if( $bottom_level > 0 ){
//message('bottom: '.$bottom_level);
$menu = gpOutput::MenuReduce_Bottom($menu,$bottom_level);
}
gpOutput::OutputMenu($menu,$top_level,$source_menu_array);
}
/**
* Return the data for the requested menu, return the main menu if the requested menu doesn't exist
* @param string $id String identifying the requested menu
* @return array menu data
*/
static function GetMenuArray($id){
global $dataDir, $gp_menu, $config;
$menu_file = $dataDir.'/data/_menus/'.$id.'.php';
if( !file_exists($menu_file) ){
return gpPlugin::Filter('GetMenuArray',array($gp_menu));
}
$menu = array();
$fileVersion = false;
require($menu_file);
if( $fileVersion && version_compare($fileVersion,'3.0b1','<') ){
$menu = gpOutput::FixMenu($menu);
}
return gpPlugin::Filter('GetMenuArray',array($menu));
}
/**
* Update menu entries to gpEasy 3.0 state
* .. htmlspecialchars label for external links
* @since 3.0b1
*/
static function FixMenu($menu){
//fix external links, prior to 3.0, escaping was done when the menu was output
foreach($menu as $key => $value){
if( !isset($value['url']) ){
continue;
}
//make sure it has a label
if( empty($value['label']) ){
$menu[$key]['label'] = $value['url'];
}
//make sure the title attr is escaped
if( !empty($value['title_attr']) ){
$menu[$key]['title_attr'] = htmlspecialchars($menu[$key]['title_attr']);
}
//make sure url and label are escape
$menu[$key]['url'] = htmlspecialchars($menu[$key]['url']);
$menu[$key]['label'] = htmlspecialchars($menu[$key]['label']);
}
return $menu;
}
static function MenuReduce_ExpandAll($menu,$expand_level,$curr_title_key,$top_level){
$result_menu = array();
$submenu = array();
$foundGroup = false;
foreach($menu as $title_key => $level){
if( $level < $expand_level ){
$submenu = array();
$foundGroup = false;
}
if( $title_key == $curr_title_key ){
$foundGroup = true;
$result_menu = $result_menu + $submenu; //not using array_merge because of numeric indexes
}
if( $foundGroup ){
$result_menu[$title_key] = $level;
}elseif( $level < $expand_level ){
$result_menu[$title_key] = $level;
}else{
$submenu[$title_key] = $level;
}
}
return $result_menu;
}
//Reduce titles deeper than $expand_level || $current_level
static function MenuReduce_Expand($menu,$expand_level,$curr_title_key,$top_level){
$result_menu = array();
$submenu = array();
//if $top_level is set, we need to take it into consideration
$expand_level = max( $expand_level, $top_level);
//titles higher than the $expand_level
$good_titles = array();
foreach($menu as $title_key => $level){
if( $level < $expand_level ){
$good_titles[$title_key] = $level;
}
}
if( isset($menu[$curr_title_key]) ){
$curr_level = $menu[$curr_title_key];
$good_titles[$curr_title_key] = $menu[$curr_title_key];
//titles below selected
// cannot use $submenu because $foundTitle may require titles above the $submenu threshold
$foundTitle = false;
foreach($menu as $title_key => $level){
if( $title_key == $curr_title_key ){
$foundTitle = true;
continue;
}
if( !$foundTitle ){
continue;
}
if( ($curr_level+1) == $level ){
$good_titles[$title_key] = $level;
}elseif( $curr_level < $level ){
continue;
}else{
break;
}
}
//$start_time = microtime();
//reduce the menu to the current group
$submenu = gpOutput::MenuReduce_Group($menu,$curr_title_key,$expand_level,$curr_level);
//message('group: ('.count($submenu).') '.showArray($submenu));
// titles even-with selected title within group
$even_temp = array();
$even_group = false;
foreach($submenu as $title_key => $level){
if( $title_key == $curr_title_key ){
$even_group = true;
$good_titles = $good_titles + $even_temp;
continue;
}
if( $level < $curr_level ){
if( $even_group ){
$even_group = false; //done
}else{
$even_temp = array(); //reset
}
}
if( $level == $curr_level ){
if( $even_group ){
$good_titles[$title_key] = $level;
}else{
$even_temp[$title_key] = $level;
}
}
}
// titles above selected title, deeper than $expand_level, and within the group
gpOutput::MenuReduce_Sub($good_titles,$submenu,$curr_title_key,$expand_level,$curr_level);
gpOutput::MenuReduce_Sub($good_titles,array_reverse($submenu),$curr_title_key,$expand_level,$curr_level);
//message('time: '.microtime_diff($start_time,microtime()));
}
//rebuild $good_titles in order
// array_intersect_assoc() would be useful here, it's php4.3+ and there's no indication if the order of the first argument is preserved
foreach($menu as $title => $level){
if( isset($good_titles[$title]) ){
$result_menu[$title] = $level;
}
}
return $result_menu;
}
// reduce the menu to the group
static function MenuReduce_Group($menu,$curr_title_key,$expand_level,$curr_level){
$result = array();
$group_temp = array();
$found_title = false;
foreach($menu as $title_key => $level){
//back at the top
if( $level < $expand_level ){
$group_temp = array();
$found_title = false;
}
if( $title_key == $curr_title_key ){
$found_title = true;
$result = $group_temp;
}
if( $level >= $expand_level ){
if( $found_title ){
$result[$title_key] = $level;
}else{
$group_temp[$title_key] = $level;
}
}
}
return $result;
}
// titles above selected title, deeper than $expand_level, and within the group
static function MenuReduce_Sub(&$good_titles,$menu,$curr_title_key,$expand_level,$curr_level){
$found_title = false;
$test_level = $curr_level;
foreach($menu as $title_key => $level){
if( $title_key == $curr_title_key ){
$found_title = true;
$test_level = $curr_level;
continue;
}
//after the title is found
if( !$found_title ){
continue;
}
if( $level < $expand_level ){
break;
}
if( ($level >= $expand_level) && ($level < $test_level ) ){
$test_level = $level+1; //prevent showing an adjacent menu trees
$good_titles[$title_key] = $level;
}
}
}
//Reduce the menu to titles deeper than ($show_level-1)
static function MenuReduce_Top($menu,$show_level,$curr_title_key){
$result_menu = array();
$foundGroup = false;
//current title not in menu, so there won't be a submenu
if( !isset($menu[$curr_title_key]) ){
return $result_menu;
}
$top_level = $show_level-1;
foreach($menu as $title_key => $level){
//no longer in subgroup, we can stop now
if( $foundGroup && ($level <= $top_level) ){
//message('no long in subgroup: '.$title_key);
break;
}
if( $title_key == $curr_title_key ){
//message('found: '.$title_key);
$foundGroup = true;
}
//we're back at the $top_level, start over
if( $level <= $top_level ){
$result_menu = array();
//message('start over: '.$title_key);
//message('start over: '.showArray($result_menu));
continue;
}
//we're at the correct level, put titles in $result_menu in case $page->title is found
if( $level > $top_level ){
$result_menu[$title_key] = $level;
}
}
if( !$foundGroup ){
return array();
}
return $result_menu;
}
//Reduce the menu to titles above $bottom_level value
static function MenuReduce_Bottom($menu,$bottom_level){
$result_menu = array();
foreach($menu as $title => $level){
if( $level < $bottom_level ){
$result_menu[$title] = $level;
}
}
return $result_menu;
}
static function GetExtra($name='Side_Menu',$info=array()){
global $dataDir,$langmessage;
includeFile('tool/SectionContent.php');
$name = str_replace(' ','_',$name);
$extra_content = self::ExtraContent( $name, $file_stats );
$wrap = gpOutput::ShowEditLink('Admin_Extra');
if( $wrap ){
ob_start();
$edit_link = gpOutput::EditAreaLink($edit_index,'Admin_Extra',$langmessage['edit'],'cmd=edit&file='.$name,array('title'=>$name,'data-cmd'=>'inline_edit_generic'));
echo '';
echo $edit_link;
echo common::Link('Admin_Extra',$langmessage['theme_content'],'',' class="nodisplay"');
echo '';
gpOutput::$editlinks .= ob_get_clean();
echo '
'; // class="edit_area" added by javascript
echo section_content::RenderSection($extra_content,0,'',$file_stats);
echo '