';
}
//editable links only .. other editable_areas are handled by their output functions
if( $permission ){
if( isset($info['link']) ){
$label = $langmessage[$info['link']];
$edit_link = self::EditAreaLink(
$edit_index,
'Admin_Theme_Content/Edit/' . urlencode($page->gpLayout),
$langmessage['edit'],
'cmd=LayoutMenu&handle=' . $param,
['data-cmd' => 'gpabox', 'title' => $label ]
);
echo '';
echo $edit_link;
echo \gp\tool::Link(
'Admin/Menu',
$langmessage['file_manager'],
'',
['class' => 'nodisplay']
);
//call to current also not needed, there will only be 1 entry);
echo '';
self::$edit_area_id = 'ExtraEditArea'.$edit_index;
}elseif( isset($info['key']) && ($info['key'] == 'CustomMenu') ){
$edit_link = self::EditAreaLink(
$edit_index,
'Admin_Theme_Content/Edit/' . urlencode($page->gpLayout),
$langmessage['edit'],
'cmd=LayoutMenu&handle=' . $param,
['data-cmd' => 'gpabox', 'title' => $langmessage['Links']]
);
echo '';
echo $edit_link;
echo \gp\tool::Link(
'Admin/Menu',
$langmessage['file_manager'],
'',
['class' => 'nodisplay']
);
echo '';
self::$edit_area_id = 'ExtraEditArea' . $edit_index;
}
}
self::$editlinks .= ob_get_clean();
echo '
';
self::ExecArea($info);
echo '
';
$GP_ARRANGE = true;
$gp_current_container = false;
}
public static function ExecArea($info){
//retreive from gadget cache if set
if( isset($info['gpOutCmd']) ){
$gadget = $info['gpOutCmd'];
if( substr($gadget, 0, 7) == 'Gadget:' ){
$gadget = substr($gadget, 7);
}
if( isset(self::$gadget_cache[$gadget]) ){
echo self::$gadget_cache[$gadget];
return;
}
}
$info += ['arg' => ''];
$args = [$info['arg'], $info];
$info = \gp\tool\Plugins::Filter('ExecArea', [$info, $args]);
if( !$info ){
return;
}
self::ExecInfo($info, $args);
}
/**
* Execute a set of directives for theme areas, hooks and special pages
*
*/
public static function ExecInfo($info, $args=[]){
global $addonFolderName, $installed_addon, $page;
$args += ['page' => $page];
//addonDir is deprecated as of 2.0b3
$addon = false;
if( isset($info['addonDir']) ){
$addon = $info['addonDir'];
}elseif( isset($info['addon']) ){
$addon = $info['addon'];
}
if( $addon !== false ){
if( gp_safe_mode ){
return $args;
}
\gp\tool\Plugins::SetDataFolder($addon);
}
//if addon was just installed
if( $installed_addon && $installed_addon === $addonFolderName){
\gp\tool\Plugins::ClearDataFolder();
return $args;
}
// check for fatal errors
if( self::FatalNotice('exec', $info) ){
return $args;
}
try{
$args = self::_ExecInfo($info, $args);
}catch(\Throwable $e){
\showError(E_ERROR,
'ExecInfo() Fatal Error: ' . $e->getMessage(),
$e->GetFile(),
$e->GetLine(),
[],
$e->getTrace()
);
}
if( $addon !== false ){
\gp\tool\Plugins::ClearDataFolder();
}
self::PopCatchable();
return $args;
}
public static function _ExecInfo($info, $args=[]){
global $dataDir, $gp_overwrite_scripts;
// get data
if( !empty($info['data']) ){
IncludeScript($dataDir . $info['data'], 'include_if', ['page', 'dataDir', 'langmessage']);
}
// get script
$has_script = false;
if( !empty($info['script']) ){
if( is_array($gp_overwrite_scripts) && isset($gp_overwrite_scripts[$info['script']]) ){
$full_path = $gp_overwrite_scripts[$info['script']];
}else{
$full_path = $dataDir . $info['script'];
}
if( !file_exists($full_path) ){
self::ExecError(\CMS_NAME . ' Error: Addon hook script doesn\'t exist.', $info, 'script');
return $args;
}
if( IncludeScript($full_path, 'include_once', ['page', 'dataDir', 'langmessage']) ){
$has_script = true;
}
}
//class & method execution
if( !empty($info['class_admin']) && \gp\tool::LoggedIn() ){
return self::ExecClass($has_script, $info['class_admin'], $info, $args);
}elseif( !empty($info['class']) ){
return self::ExecClass($has_script, $info['class'], $info, $args);
}
//method execution
if( !empty($info['method']) ){
return self::ExecMethod($has_script, $info, $args);
}
return $args;
}
/**
* Execute hooks that have a ['class'] defined
*
*/
private static function ExecClass($has_script, $exec_class, $info, $args){
if( !class_exists($exec_class) ){
self::ExecError(\CMS_NAME . ' Error: Addon class doesn\'t exist.', $info, 'class');
return $args;
}
$object = new $exec_class($args);
if( !empty($info['method']) ){
if( method_exists($object, $info['method']) ){
$args[0] = call_user_func_array([$object, $info['method']], $args);
}elseif( $has_script ){
self::ExecError(\CMS_NAME . ' Error: Addon hook method doesn\'t exist (1).', $info, 'method');
}
}
return $args;
}
/**
* Execute hooks that have a ['method'] defined
*
*/
private static function ExecMethod($has_script, $info, $args){
$callback = $info['method'];
//object callbacks since 3.0
if( is_string($callback) && strpos($callback, '->') !== false ){
$has_script = true;
list($object, $method) = explode('->', $callback);
if( isset($GLOBALS[$object]) &&
is_object($GLOBALS[$object]) &&
method_exists($GLOBALS[$object], $method)
){
$callback = [$GLOBALS[$object], $method];
}
}
if( is_callable($callback) ){
$args[0] = call_user_func_array($callback, $args);
}elseif( $has_script ){
self::ExecError(\CMS_NAME.' Error: Addon hook method doesn\'t exist (2).', $info, 'method');
}
return $args;
}
/**
* Trigger an error
*
*/
public static function ExecError($msg, $exec_info, $error_info){
global $config, $addonFolderName;
// append addon name
if( !empty($addonFolderName) && isset($config['addons'][$addonFolderName]) ){
$msg .= ' Addon: ' . $config['addons'][$addonFolderName]['name'] . '. ';
}
// which piece of $exec_info is the problem
if( !isset($exec_info[$error_info]) ){
$msg .= $error_info;
}elseif( is_array($exec_info[$error_info]) ){
$msg .= $error_info . ': ' . implode('::', $exec_info[$error_info]);
}else{
$msg .= $error_info . ': ' . $exec_info[$error_info];
}
trigger_error($msg);
}
/**
* Check for fatal errors corresponing to $hash
* Notify administrators of disabled components
*
*/
public static function FatalNotice($type, $info){
global $dataDir, $page;
static $notified = false;
$info = (array)$info;
$info['catchable_type'] = $type;
$hash_dir = $dataDir . '/data/_site/fatal_' . $type . '_' . \gp\tool::ArrayHash($info);
$hash_request = $hash_dir . '/' . \gp\tool::ArrayHash($_REQUEST);
self::$catchable[$hash_request] = $info;
if( !self::FatalLimit($hash_dir) ){
return false;
}
if( !$notified ){
error_log( 'Warning: A component of this page has been disabled because it caused fatal errors' );
$notified = true;
}
self::PopCatchable();
return true;
}
/**
* Return true if the limit of fatal errors has been reached
*
*/
public static function FatalLimit($hash_dir){
//no folder = no fatal error
if( !file_exists($hash_dir) ){
return false;
}
// if the error didn't occur for the exact request and it hasn't happend a lot, allow the code to keep working
$fatal_hashes = scandir($hash_dir);
if( $fatal_hashes !== false && count($fatal_hashes) < (gp_allowed_fatal_errors + 3) ){
// add 3 for ".", ".." and "index.html" entries
return false;
}
return true;
}
public static function PopCatchable(){
array_pop(self::$catchable);
}
/**
* Determine if an inline edit link should be shown for the current user
*
* @param string $permission
* @return bool
*/
public static function ShowEditLink($permission=null){
if( !is_null($permission) ){
return !self::$nested_edit && \gp\tool::LoggedIn() && \gp\admin\Tools::HasPermission($permission);
}
return !self::$nested_edit && \gp\tool::LoggedIn();
}
/**
* @param int $index
* @param string $href
* @param string $label
* @param string $query
* @param string|array $attr
*
*/
public static function EditAreaLink(&$index, $href, $label, $query='', $attr=''){
self::$edit_index++;
$index = self::$edit_index; //since &$index is passed by reference
if( is_array($attr) ){
$attr += [
'class' => 'ExtraEditLink nodisplay',
'id' => 'ExtraEditLink' . $index,
'data-gp-area-id' => $index,
];
}else{
$attr .= ' class="ExtraEditLink nodisplay" ' .
'id="ExtraEditLink' . $index . '" ' .
'data-gp-area-id="' . $index . '"';
}
return \gp\tool::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 \gp\tool\Output::Get('GetAllGadgets')
* so that each individual gadget area can be used as a drag area
*
*/
public 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']) ){
self::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;
self::CallOutput($info, 'GetAllGadgets');
$count++;
}
}
if( $count ){
return;
}
}
//Show the area as editable if there isn't anything to show
$info = [];
$info['gpOutCmd'] = '';
self::CallOutput($info, 'GetAllGadgets');
}
/**
* Simply determine if a Gadget exists
* allows us to check whether a plugin gadget exists before loading it in template.php
* @since 5.2-rc
* @param string Gadget id
* @return boolean
*/
public static function GadgetExists($id){
global $config;
return isset($config['gadgets'][$id]);
}
/**
* Get a Single Gadget
* This method should be called using \gp\tool\Output::Fetch('Gadget',$gadget_name)
*
*/
public static function GetGadget($id){
global $config;
if( !isset($config['gadgets'][$id]) ){
return;
}
self::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
*/
public static function PrepGadgetContent(){
global $page;
//not needed for admin pages
if( $page->pagetype == 'admin_display' ){
return;
}
$gadget_info = self::WhichGadgets($page->gpLayout);
foreach($gadget_info as $gpOutCmd => $info){
if( !isset(self::$gadget_cache[$gpOutCmd]) ){
ob_start();
self::ExecArea($info);
self::$gadget_cache[$gpOutCmd] = ob_get_clean();
}
}
}
/**
* Return information about the gadgets being used in the current layout
* @return array
*/
public static function WhichGadgets($layout){
global $config, $gpLayouts;
$gadget_info = $temp_info = [];
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] = self::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] = self::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;
}
public static function GetExtra($name='Side_Menu', $info=[]){
echo \gp\tool\Output\Extra::GetExtra($name);
}
public static function GetImage($src, $attributes=[]){
global $page, $dataDir, $langmessage, $gpLayouts;
//$width,$height,$attributes = ''
$attributes = (array)$attributes;
$attributes += ['class' => ''];
$attributes['class'] .= 'GPAREA filetype-image';
unset($attributes['id']);
//default image information
$img_rel = dirname($page->theme_rel) . '/' . ltrim($src, '/');
//container id
$container_id = 'Image:' . $src;
$container_id = self::GetContainerID($container_id);
//select custom image
if( isset($gpLayouts[$page->gpLayout]) &&
isset($gpLayouts[$page->gpLayout]['images']) &&
isset($gpLayouts[$page->gpLayout]['images'][$container_id]) &&
is_array($gpLayouts[$page->gpLayout]['images'][$container_id])
){
//shuffle($gpLayouts[$page->gpLayout]['images'][$container_id]);
//Does not make sense ? There will always be only 1 entry in
//for this container as it is per img element
//call to current also not needed, there will only be 1 entry
$image = $gpLayouts[$page->gpLayout]['images'][$container_id][0];
$img_full = $dataDir.$image['img_rel'];
if( file_exists($img_full) ){
$img_rel = $image['img_rel'];
$attributes['width'] = $image['width'];
$attributes['height'] = $image['height'];
}
}
//attributes
if( !isset($attributes['alt']) ){
$attributes['alt'] = '';
}
//edit options
$editable = self::ShowEditLink('Admin_Theme_Content');
if( $editable ){
$edit_link = self::EditAreaLink(
$edit_index,
'Admin_Theme_Content/Image/' . $page->gpLayout,
$langmessage['edit'],
'file=' . rawurlencode($img_rel) . '&container=' . $container_id . '&time=' . time(),
['title' => 'Edit Image', 'data-cmd' => 'inline_edit_generic' ]
);
self::$editlinks .= '' .
$edit_link .
'';
$attributes['class'] .= ' editable_area';
$attributes['id'] = 'ExtraEditArea' . $edit_index;
}
//remove class if empty, commented because class will never be empty anymore because of filetype-image
// $attributes['class'] = trim($attributes['class']);
// if( empty($attributes['class']) ){
// unset($attributes['class']);
//}
//convert attributes to string
$str = '';
foreach($attributes as $key => $value){
$str .= ' ' . $key . '="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8', false) . '"';
}
echo '';
}
/*
*
* Output Additional Areas
*
*/
/* draggable html and editable text */
public static function Area($name,$html){
global $gpOutConf;
if( self::$out_started ){
trigger_error('\gp\tool\Output::Area() must be called before all other output functions');
return;
}
$name = '[text]' . $name;
$gpOutConf[$name] = [];
$gpOutConf[$name]['method'] = ['\\gp\\tool\\Output', 'GetAreaOut'];
$gpOutConf[$name]['html'] = $html;
}
public static function GetArea($name, $text){
$name = '[text]' . $name;
self::Get($name, $text);
}
public static function GetAreaOut($text,$info){
global $config, $langmessage, $page;
$html =& $info['html'];
$wrap = self::ShowEditLink('Admin_Theme_Content');
if( $wrap ){
self::$editlinks .= self::EditAreaLink(
$edit_index,
'Admin_Theme_Content/Text',
$langmessage['edit'],
'cmd=EditText&key=' . urlencode($text) . '&return=' . urlencode($page->title),
['title' => htmlspecialchars($text), 'data-cmd' => 'gpabox']
);
echo '
';
// class="edit_area" added by javascript
}
if( isset($config['customlang'][$text]) ){
$text = $config['customlang'][$text];
}elseif( isset($langmessage[$text]) ){
$text = $langmessage[$text];
}
echo str_replace('%s', $text, $html); //in case there's more than one %s
if( $wrap ){
echo '
';
}
}
/**
* Get additional CSS classes that can be added to the
* html or body elements' class atrribute
* e.g. to display an larger header only on the homepage
* Use in template.php:
* @since 5.2-rc
* @param boolean $echo_classes (defaults to true), output the class names as space-separated string
* @return array of css class names that apply
*
*/
public static function GetPageInfoClasses($echo_classes=true){
global $page;
$classes = [];
if( self::is_front_page() ){
$classes[] = 'is-homepage';
}
if( $page->pagetype == 'special_display' ){
$classes[] = 'is-special-page';
}
switch( $page->gp_index ){
case 'special_contact':
$classes[] = 'is-contactform-page';
break;
case 'special_galleries':
$classes[] = 'is-galleries-page';
break;
case 'special_gpsearch':
$classes[] = 'is-search-page';
break;
case 'special_missing':
$classes[] = 'is-missing-page';
break;
case 'special_blog':
$classes[] = 'is-blog-page';
if( isset($_GET['id']) ){
$classes[] = 'is-single-post-page';
}
break;
case 'special_blog_categories':
$classes[] = 'is-blog-page';
$classes[] = 'is-blog-categories-page';
if( isset($_GET['cat']) ){
$classes[] = 'is-single-category-page';
}
break;
}
if( $echo_classes && !empty($classes) ){
echo ' ' . implode(' ', $classes) . ' ';
}
return $classes;
}
/*
*
* editable text, not draggable
*
*
*/
/**
* similar to ReturnText() but links to script for editing all addon texts
* the $html parameter should primarily be used when the text is to be placed
* inside of a link or other element that cannot have a link and/or span as a child node
*/
public static function GetAddonText($key, $html='%s', $wrapper_class=''){
global $addonFolderName;
if( !$addonFolderName ){
return self::ReturnText($key, $html, $wrapper_class);
}
$query = 'cmd=AddonTextForm&addon=' . urlencode($addonFolderName) . '&key=' . urlencode($key);
return self::ReturnTextWorker($key, $html, $query, $wrapper_class);
}
public static function ReturnText($key,$html='%s', $wrapper_class=''){
$query = 'cmd=EditText&key='.urlencode($key);
return self::ReturnTextWorker($key, $html, $query, $wrapper_class);
}
public static function ReturnTextWorker($key, $html, $query, $wrapper_class=''){
global $langmessage;
$text = self::SelectText($key);
$result = str_replace('%s', $text, $html); //in case there's more than one %s
$editable = self::ShowEditLink('Admin_Theme_Content');
if( $editable ){
$title = htmlspecialchars(strip_tags($key));
if( strlen($title) > 20 ){
$title = substr($title, 0, 20) . '...'; //javscript may shorten it as well
}
self::$editlinks .= self::EditAreaLink(
$edit_index,
'Admin_Theme_Content/Text',
$langmessage['edit'],
$query,
['title' => $title, 'data-cmd' => 'gpabox']
);
return '' . $result . '';
}
if( $wrapper_class ){
return '' . $result . '';
}
return $result;
}
/**
* Returns the user translated string if it exists or
* $key (the untranslated string) if a translation doesn't exist
*
*/
public static function SelectText($key){
global $config,$langmessage;
$text = $key;
if( isset($config['customlang'][$key]) ){
$text = $config['customlang'][$key];
}elseif( isset($langmessage[$key]) ){
$text = $langmessage[$key];
}
return $text;
}
/*
*
* Generate and output the portion of the html document
*
*/
public static function GetHead(){
\gp\tool\Plugins::Action('GetHead');
self::PrepGadgetContent();
echo '';
}
public static function HeadContent(){
global $config, $page, $wbMessageBuffer;
//before ob_start() so plugins can get buffer content
\gp\tool\Plugins::Action('HeadContent');
if( \gp\tool::LoggedIn() ){
\gp\tool::AddColorBox();
}
//always include javascript when there are messages
if( $page->admin_js || !empty($page->jQueryCode) || !empty($wbMessageBuffer) || isset($_COOKIE['cookie_cmd']) ){
\gp\tool::LoadComponents('gp-main');
}
//defaults
\gp\tool::LoadComponents('jquery,gp-additional');
//get css and js info
$scripts = \gp\tool\Output\Combine::ScriptInfo( self::$components );
ob_start();
self::GetHead_TKD();
self::$head_content = ob_get_clean();
ob_start();
self::GetHead_CSS($scripts['css']); //css before js so it's available to scripts
self::$head_css = ob_get_clean();
//javascript
ob_start();
self::GetHead_Lang();
self::GetHead_JS($scripts['js']);
self::GetHead_InlineJS();
self::$head_js = ob_get_clean();
//gadget info
if( isset($config['addons']) ){
foreach($config['addons'] as $addon_info){
if( !empty($addon_info['html_head']) ){
self::MoveScript($addon_info['html_head']);
}
}
}
if( !empty($page->head) ){
self::MoveScript($page->head);
}
}
/**
* Move to self::$head_js
*
*/
public static function MoveScript($string){
//conditional comments with script tags
$patt = '#' . preg_quote('', '#') . '#s';
if( preg_match_all($patt,$string, $matches) ){
foreach($matches[0] as $match){
if( strpos($match,'' . "\n";
}
/**
* Add language values to the current page
* @static
*/
public static function GetHead_Lang(){
global $langmessage;
if( !count(self::$lang_values) ){
return;
}
echo "\n" . '";
}
/**
* Prepare and output the Javascript for the current page
* @static
*/
public static function GetHead_JS($scripts){
global $page, $config;
$combine = $config['combinejs'] && !\gp\tool::loggedIn() && ($page->pagetype !== 'admin_display');
$scripts = self::GetHead_CDN('js', $scripts);
//just local jquery
if( !count($page->head_js) && count($scripts) === 1 && isset($scripts['jquery']) ){
echo '';
return;
}
if( !$combine || $page->head_force_inline ){
echo "\n";
}
if( is_array($page->head_js) ){
$scripts += $page->head_js; //other js files
}else{
trigger_error('$page->head_js is not an array');
}
Output\Assets::CombineFiles($scripts, 'js', $combine);
}
/**
* Prepare and output the css for the current page
* @static
*/
public static function GetHead_CSS($to_add){
global $page, $config, $dataDir;
$scripts = [];
$to_add = self::GetHead_CDN('css', $to_add);
$scripts = Output\Assets::MergeScripts($scripts, $to_add);
if( isset($page->css_user) ){
$scripts = Output\Assets::MergeScripts($scripts, $page->css_user);
}
// add theme css
if( !empty($page->theme_name) && $page->get_theme_css === true ){
$scripts = Output\Assets::MergeScripts($scripts, Output\Assets::LayoutStyleFiles());
}
//styles that need to override admin.css should be added to $page->css_admin;
if( isset($page->css_admin) ){
$scripts = Output\Assets::MergeScripts($scripts, $page->css_admin);
}
// disable 'combine css' if 'create_css_sourcemaps' is set to true in /gpconfig.php
$combinecss = \create_css_sourcemaps ? false : $config['combinecss'];
Output\Assets::CombineFiles($scripts, 'css', $combinecss);
}
/**
* Add CDN hosted resources to the page
*
*/
public static function GetHead_CDN($type, $scripts){
global $config;
if( empty($config['cdn']) ){
return $scripts;
}
$cdn = $config['cdn'];
foreach($scripts as $key => $script_info){
if( !isset($script_info['cdn']) || !isset($script_info['cdn'][$cdn]) ){
continue;
}
$cdn_url = $script_info['cdn'][$cdn];
//remove packages
if( isset($script_info['package']) ){
foreach($scripts as $_key => $_info){
if( isset($_info['package']) && $_info['package'] == $script_info['package'] ){
unset($scripts[$_key]);
}
}
}
unset($scripts[$key]);
echo Output\Assets::FormatAsset($type,$cdn_url);
}
return $scripts;
}
/**
* Get the path for the custom css/scss/less file
*
*/
public static function CustomStyleFile($layout, $style_type){
global $dataDir;
if( $style_type == 'scss' ){
return $dataDir . '/data/_layouts/' . $layout . '/custom.scss';
}
return $dataDir . '/data/_layouts/' . $layout . '/custom.css';
}
/**
* Get the path for the customizer css/scss/less file
*
* @since 5.2
*/
public static function CustomizerStyleFile($layout, $style_type){
global $dataDir;
if( $style_type == 'scss' ){
return $dataDir . '/data/_layouts/' . $layout . '/customizer.scss';
}
return $dataDir . '/data/_layouts/' . $layout . '/customizer.css';
}
/**
* Get the path for the custom layout config file
*
* @since 5.2
*/
public static function LayoutConfigFile($layout){
global $dataDir;
return $dataDir . '/data/_layouts/' . $layout . '/config.php';
}
/**
* Get the filetype of the style.* file
*
* @return string
*/
public static function StyleType($dir){
$types = ['less','scss'];
foreach($types as $type){
$path = $dir . '/style.'.$type;
if( file_exists($path) ){
return $type;
}
}
return 'css';
}
/**
* Determines whether the passed directory qualifies as layout
* by checking whether a style.css, style.less or style.css file exists
* @return boolean
*/
public static function IsLayoutDir($dir){
$types = ['less','scss','css'];
foreach($types as $type){
$path = $dir . '/style.' . $type;
if( file_exists($path) ){
return true;
}
}
return false;
}
/**
* Complete the response by adding final content to the of the document
* @static
* @since 2.4.1
* @param string $buffer html content
* @return string finalized response
*/
public static function BufferOut($buffer){
global $config;
//add error notice if there was a fatal error
if( !ini_get('display_errors') ){
$last_error = self::LastFatal();
if( !empty($last_error) ){
self::RecordFatal($last_error);
$buffer .= self::FatalMessage($last_error);
}
}
//remove lock
if( defined('gp_has_lock') && \gp_has_lock ){
\gp\tool\Files::Unlock('write', \gp_random);
}
//make sure whe have a complete html request
$placeholder = '';
if( strpos($buffer,$placeholder) === false ){
return $buffer;
}
$replacements = [];
//performace stats
if( class_exists('admin_tools') ){
$replacements = self::PerformanceStats();
}
//head content
//add css to bottom of
if( \load_css_in_body ){
$buffer = self::AddToBody($buffer, self::$head_css);
$replacements[$placeholder] = self::$head_content;
}else{
$replacements[$placeholder] = self::$head_css . self::$head_content;
}
//add js to bottom of
$buffer = self::AddToBody($buffer, self::$head_js);
//add jquery if needed
$placeholder = '';
$replacement = '';
if( !empty(self::$head_js) || stripos($buffer, '';
}else{
$message .= '
If you are the site administrator, you can troubleshoot '
. 'the problem by changing php\'s display_errors setting to 1 in '
. 'the gpconfig.php file.
If the problem is being caused by an addon, '
. 'you may also be able to bypass the error by enabling ' . \CMS_NAME . '\'s '
. 'safe mode in the gpconfig.php file.
More information is available '
. 'in the Documentation.'
. '