<?php /** * WBCE CMS * Way Better Content Editing. * Visit https://wbce.org to learn more and to join the community. * * @copyright Ryan Djurovich (2004-2009) * @copyright WebsiteBaker Org. e.V. (2009-2015) * @copyright WBCE Project (2015-) * @license GNU GPL2 (or any later version) */ //no direct file access if (count(get_included_files()) == 1) { die(header("Location: ../index.php", true, 301)); } // since we are in the FRONTEND set WB_FRONTEND constant defined('WB_FRONTEND') or define('WB_FRONTEND', true); // Compatibility mode for older versions. // (The News module still needs it for example.) if (isset($wb)) { $admin = $wb; } if (isset($wb->default_link)) { $default_link = $wb->default_link; } if (isset($wb->page_trail)) { $page_trail = $wb->page_trail; } if (isset($wb->page_description)) { $page_description = $wb->page_description; } if (isset($wb->page_keywords)) { $page_keywords = $wb->page_keywords; } if (isset($wb->link)) { $page_link = $wb->link; } // Load Snippet Type modules into the frontend $sSql = 'SELECT `directory` FROM `{TP}addons` WHERE `function` LIKE \'%snippet%\' '; if (($resSnippets = $database->query($sSql))) { while ($rec = $resSnippets->fetchRow()) { $sFile = WB_PATH . '/modules/' . $rec['directory'] . '/include.php'; if (file_exists($sFile)) { include $sFile; } } } // Frontend functions if (!function_exists('page_link')) { /** * @brief Generate full page_link based on the * `link` content from the `{TP}pages` table * * @param unspec $uLinkId * @return string */ function page_link($uLinkId = null) { return $GLOBALS['wb']->page_link($link); } } if (!function_exists('get_page_link')) { /** * @brief get `link` entry from database `{TP}pages` table using page_id * * @param int $id * @return string * @global object $database */ function get_page_link($page_id) { $sSql = 'SELECT `link` FROM `{TP}pages` WHERE `page_id` = %d'; return $GLOBALS['database']->get_one(sprintf($sSql, $page_id)); } } //function to highlight search results if (!function_exists('search_highlight')) { /** * * @staticvar bool $string_ul_umlaut * @staticvar bool $string_ul_regex * @param string $foo * @param array $arr_string * @return string */ function search_highlight($foo = '', $arr_string = array()) { require_once WB_PATH . '/framework/functions.php'; static $string_ul_umlaut = false; static $string_ul_regex = false; if ($string_ul_umlaut === false || $string_ul_regex === false) { require WB_PATH . '/search/search_convert.php'; } $foo = entities_to_umlauts($foo, 'UTF-8'); array_walk($arr_string, function (&$v, $k) { $v = preg_quote($v, '\'~\''); }); $search_string = implode("|", $arr_string); $string = str_replace($string_ul_umlaut, $string_ul_regex, $search_string); // the highlighting // match $string, but not inside <style>...</style>, <script>...</script>, <!--...--> or HTML-Tags // Also droplet tags are now excluded from highlighting. // split $string into pieces - "cut away" styles, scripts, comments, HTML-tags and eMail-addresses // we have to cut <pre> and <code> as well. // for HTML-Tags use <(?:[^<]|<.*>)*> which will match strings like <input ... value="<b>value</b>" > $matches = preg_split("~(\[\[.*\]\]|<style.*</style>|<script.*</script>|<pre.*</pre>|<code.*</code>|<!--.*-->|<(?:[^<]|<.*>)*>|\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,8}\b)~iUs", $foo, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)); if (is_array($matches) && $matches != array()) { $foo = ""; foreach ($matches as $match) { if ($match[0] != "<" && !preg_match('/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,8}$/i', $match) && !preg_match('~\[\[.*\]\]~', $match)) { $match = str_replace(array('<', '>', '&', '"', ''', ' '), array('<', '>', '&', '"', '\'', "\xC2\xA0"), $match); $match = preg_replace('~(' . $string . ')~ui', '_span class=_highlight__$1_/span_', $match); //$match = str_replace(array('&', '<', '>', '"', '\'', "\xC2\xA0"), array('&', '<', '>', '"', ''', ' '), $match); $match = str_replace(array('_span class=_highlight__', '_/span_'), array('<span class="highlight">', '</span>'), $match); } $foo .= $match; } } if (DEFAULT_CHARSET != 'utf-8') { $foo = umlauts_to_entities($foo, 'UTF-8'); } return $foo; } } if (!function_exists('get_block_id')) { /** * @brief Function to extract Block ID from Blockname * If fed whith an integer or numeric string it simply returns this as an integer. * If fed whith a string it tries to find this string in the $block[] array of the current template. * It returns the id if found otherwise it returns 1 (default template block) * * @param unspec $uMenu may be string or integer * @return int */ function get_block_id($uBlock) { if (is_int($uBlock) or preg_match("/^[0-9]+$/is", $uBlock)) { return (int)$uBlock; } else { require(WB_PATH . "/templates/" . TEMPLATE . "/info.php"); if ($key = array_search($uBlock, $block)) { return (int)$key; } else { return 1; } } } } if (!function_exists('get_menu_id')) { /** * @brief Function to extract Menu ID from Menuname * If fed whith an integer or numeric string it simply returns this as an integer. * If fed whith a string it tries to find this string in the $menu[] array of the current template. * It returns the id if found otherwise it returns 0 (default menu id) * * @param unspec $uMenu may be string or integer * @return integer */ function get_menu_id($uMenu) { if (is_int($uMenu) or preg_match("/^[0-9]+$/is", $uMenu)) { return (int)$uMenu; } else { require(WB_PATH . "/templates/" . TEMPLATE . "/info.php"); if ($key = array_search($uMenu, $menu)) { return (int)$key; } else { return 0; } } } } if (!function_exists('get_section_array')) { /** * @brief Get Array with all the details of a section by using the section_id. * * @param integer $iSectionID * @return array */ function get_section_array($iSectionID) { $aSection = array(); if (isset($iSectionID) && $iSectionID > 0) { global $database; $sSql = 'SELECT * FROM `{TP}sections` WHERE `section_id`=%d'; if ($rSections = $database->query(sprintf($sSql, (int)$iSectionID))) { $aSection = $rSections->fetchRow(MYSQLI_ASSOC); } } return $aSection; } } if (!function_exists('get_section_content')) { /** * @brief Get the actual content of a single section based on its ID. * It's possible to also add the SEC_ANCHOR (if set in settings), * and even to use a custom AnchorID if needed. * * @param integer $iSectionID * @param bool $bUseSecAnchor * @param string $sAnchorID * @return array * @global object $database * @global object $wb * @global array $globals several global vars * @global array $TEXT * @global array $MENU * @global array $HEADING * @global array $MESSAGE * */ function get_section_content($iSectionID, $bUseSecAnchor = false, $sAnchorID = "") { $sContent = ''; $aSection = get_section_array($iSectionID); // check if module exists $sModuleViewFile = WB_PATH . '/modules/' . $aSection['module'] . '/view.php'; if (is_readable($sModuleViewFile)) { ob_start(); $page_id = $iPageID = $aSection['page_id']; $section_id = $iSectionID; // we need those global vars to correctly operate the view.php global $database, $wb, $globals, $TEXT, $MENU, $HEADING, $MESSAGE; $admin = $wb; if (isset($globals) and is_array($globals)) { foreach ($globals as $sGlobalName) { global $$sGlobalName; } } require $sModuleViewFile; // fetch content using the view.php $sContent = ob_get_clean(); // use OPF hook if (function_exists('opf_apply_filters')) { $sContent = opf_controller('section', $sContent, $aSection['module'], $iPageID, $iSectionID); } if ($bUseSecAnchor == true || $sAnchorID != '') { $sAnchorTPL = '<a class="section_anchor" id="%s"></a>'; if (defined('SEC_ANCHOR') && SEC_ANCHOR != '') { $sSecAnchor = sprintf($sAnchorTPL, SEC_ANCHOR . $aSection['section_id']); } if ($sAnchorID != '') { $sSecAnchor = sprintf($sAnchorTPL, $sAnchorID); } $sContent = $sSecAnchor . $sContent; } $aToInsert = $GLOBALS['wb']->retrieve_modfiles_from_dir($aSection['module'], "frontend"); foreach ($aToInsert as $sModfileType => $sFile) { $sModfileType = strtolower($sModfileType); switch ($sModfileType) { case 'css': I::insertCssFile($sFile[0], 'HEAD MODFILES'); break; case 'js_head': I::insertJsFile($sFile[0], 'HEAD MODFILES'); break; case 'js_body': I::insertJsFile($sFile[0], 'BODY MODFILES'); break; default: break; } } } return $sContent; } } if (!function_exists('block_contents')) { /** * @brief This functions fetches the sections of a templates layout block * and retuns it as an array for further processing. * * @param unspec $uBlock Template layout block-name or block-id * @return array whole array of sections contained in a block * @global array $MESSAGE * * @global object $database * @global object $wb */ function block_contents($uBlock = 1) { global $database, $wb, $TEXT, $MESSAGE, $HEADING, $MENU; $admin = $wb; $iBlockID = is_numeric($uBlock) ? $uBlock : get_block_id($uBlock); $aBlockSections = array(); if ($wb->page_access_denied == true) { echo $MESSAGE['FRONTEND_SORRY_NO_VIEWING_PERMISSIONS']; return; } if ($wb->page_no_active_sections == true) { echo $MESSAGE['FRONTEND_SORRY_NO_ACTIVE_SECTIONS']; return; } // Include page content if (!defined('PAGE_CONTENT')) { // return if page is not visible if (($wb instanceof frontend) && !$wb->page_is_visible($wb->page)) { return; } // First get all sections for this page $sSql = 'SELECT `section_id` FROM `{TP}sections` WHERE `page_id`=%d AND `block`=%d ORDER BY `position`'; $iPageID = $page_id = $wb->page_id; if (!($rSections = $database->query(sprintf($sSql, $iPageID, $iBlockID)))) { return; // return if no results } // If no sections were found, check if default content is supposed to be shown if ($rSections->numRows() == 0) { if ($wb->default_block_content == 'none') { return; } $iPageID = $wb->default_page_id; if (is_numeric($wb->default_block_content)) { $iPageID = $wb->default_block_content; } if (!($rSections = $database->query(sprintf($sSql, $iPageID, $iBlockID)))) { return; } // Still no cotent found? Give it up, there's just nothing to show! if ($rSections->numRows() == 0) { return; } } // Loop through sections while ($row = $rSections->fetchRow(MYSQLI_ASSOC)) { $iSectionID = $row['section_id']; $aSection = get_section_array($iSectionID); // skip this section if it is out of publication date $now = time(); if (!( ($now <= $aSection['publ_end'] || (int)$aSection['publ_end'] == 0) && ($now >= $aSection['publ_start'] || (int)$aSection['publ_start'] == 0) )) { continue; } /** * here again the same as get_section_content() but we should * include the code here explicitly so that variables used by * the sections stay available for the next iteration of the loop */ $sContent = ''; $aSection = get_section_array($iSectionID); // check if module exists $sModuleViewFile = WB_PATH . '/modules/' . $aSection['module'] . '/view.php'; if (is_readable($sModuleViewFile)) { ob_start(); $page_id = $iPageID = $aSection['page_id']; $section_id = $iSectionID; // we need those global vars to correctly operate the view.php global $database, $wb, $globals, $TEXT, $MENU, $HEADING, $MESSAGE; $admin = $wb; if (isset($globals) and is_array($globals)) { foreach ($globals as $sGlobalName) { global $$sGlobalName; } } require $sModuleViewFile; // fetch content using the view.php $sContent = ob_get_clean(); // use OPF hook if (function_exists('opf_apply_filters')) { $sContent = opf_controller('section', $sContent, $aSection['module'], $iPageID, $iSectionID); } $aToInsert = $GLOBALS['wb']->retrieve_modfiles_from_dir($aSection['module'], "frontend"); foreach ($aToInsert as $sModfileType => $sFile) { $sModfileType = strtolower($sModfileType); switch ($sModfileType) { case 'css': I::insertCssFile($sFile[0], 'HEAD MODFILES'); break; case 'js_head': I::insertJsFile($sFile[0], 'HEAD MODFILES'); break; case 'js_body': I::insertJsFile($sFile[0], 'BODY MODFILES'); break; default: break; } } } if ($sContent == '') { continue; } $sec_anchor = ''; if (defined('SEC_ANCHOR') && SEC_ANCHOR != '') { $sec_anchor = '<a class="section_anchor" id="' . SEC_ANCHOR . $aSection['section_id'] . '" ></a>'; } // highlights searchresults if (isset($_GET['searchresult']) && is_numeric($_GET['searchresult']) && !isset($_GET['nohighlight']) && isset($_GET['sstring']) && !empty($_GET['sstring'])) { $sstringc = filter_input(INPUT_GET,"sstring",FILTER_SANITIZE_ENCODED); $sstringc = str_replace("%","",$sstringc); $arr_string = explode(" ", $sstringc); if ($_GET['searchresult'] == 2) { // exact match $arr_string[0] = str_replace("_", " ", $arr_string[0]); } $aBlockSections[]['content'] = search_highlight($sContent, $arr_string); } else { // OPF Hook, Apply Filters if (function_exists('opf_apply_filters')) { $sContent = opf_controller('special', $sContent); } $aBlockSections[$iSectionID]['position'] = $aSection['position']; $aBlockSections[$iSectionID]['section_id'] = $aSection['section_id']; $aBlockSections[$iSectionID]['module'] = $aSection['module']; $aBlockSections[$iSectionID]['section_name'] = $aSection['namesection']; $aBlockSections[$iSectionID]['evenodd'] = ($aSection['position'] % 2 == 1) ? 'even' : 'odd'; if ($sec_anchor != '') { $aBlockSections[$iSectionID]['content'] = PHP_EOL . $sec_anchor . PHP_EOL . $sContent; } else { $aBlockSections[$iSectionID]['content'] = $sContent; } } } } else { ob_start(); require PAGE_CONTENT; $aBlockSections[]['content'] = ob_get_clean(); } return $aBlockSections; } } if (!function_exists('page_content')) { /** * @brief print or return (e.g. into a variable for later use) * all the sections of one block into the template * It now alllows to enter block names as well as block numbers. * The second parameter lets the function return the result instead of printing it immediately. * * @param unspec $uBlock Block ID or Block name * @param bool $bPrint echo the contents * or set to 0 if you want to fetch the contents into a variable * @return string * @global object $wb | The global variables are * @global object $database | optional and will be used * @global array $globals | only in case PAGE_CONTENT * @global array $TEXT | (this are the special pages * @global array $MESSAGE | like search, account etc.) * @global array $HEADING | is defined. * @global array $MENU | * */ function page_content($uBlock = 1, $bPrint = 1) { $iBlockID = get_block_id($uBlock); $sRetVal = ''; if (!defined('PAGE_CONTENT')) { $aSections = block_contents($iBlockID); if (!empty($aSections)) { foreach ($aSections as $section) { $sRetVal .= $section['content']; } } } else { // PAGE_CONTENT is defined // it will go into the block with ID = 1 if ($iBlockID == 1) { ob_start(); global $wb, $database, $globals, $TEXT, $MESSAGE, $HEADING, $MENU; $admin = $wb; if (isset($globals) and is_array($globals)) { foreach ($globals as $sGlobalName) { global $$sGlobalName; } } require PAGE_CONTENT; $sRetVal .= ob_get_clean(); } } // echo or return if ($bPrint == 1) { echo $sRetVal; } else { return $sRetVal; } } } // Function for page title if (!function_exists('page_title')) { function page_title($spacer = ' - ', $template = '[WEBSITE_TITLE][SPACER][PAGE_TITLE]') { $vars = array('[WEBSITE_TITLE]', '[PAGE_TITLE]', '[MENU_TITLE]', '[SPACER]'); $values = array(WEBSITE_TITLE, PAGE_TITLE, MENU_TITLE, $spacer); echo str_replace($vars, $values, $template); } } // Function for page description if (!function_exists('page_description')) { function page_description() { global $wb; if ($wb->page_description != '') { echo $wb->page_description; } else { echo WEBSITE_DESCRIPTION; } } } // Function for page keywords if (!function_exists('page_keywords')) { function page_keywords() { global $wb; if ($wb->page_keywords != '') { echo $wb->page_keywords; } else { echo WEBSITE_KEYWORDS; } } } // Function for page header if (!function_exists('page_header')) { function page_header($date_format = 'Y') { echo WEBSITE_HEADER; } } // Function for page footer if (!function_exists('page_footer')) { function page_footer($date_format = 'Y') { global $starttime; $vars = array('[YEAR]', '[PROCESS_TIME]'); $processtime = array_sum(explode(" ", microtime())) - $starttime; $values = array(date($date_format), $processtime); echo str_replace($vars, $values, WEBSITE_FOOTER); } } // Function to add optional module Javascript or CSS stylesheets into the <head> section of the frontend if (!function_exists('register_frontend_modfiles')) { function register_frontend_modfiles($sModfileType = "css") { if ($sModfileType != 'jquery') { echo '<!--(PH) ' . strtoupper($sModfileType) . ' HEAD MODFILES -->' . PHP_EOL; } return $GLOBALS['wb']->register_modfiles($sModfileType, "frontend"); } } // Function to add optional module Javascript into the <body> section of the frontend if (!function_exists('register_frontend_modfiles_body')) { function register_frontend_modfiles_body($sModfileType = "js") { return; } }