Файл: core/classes/page.class.php
Строк: 492
<?php
/******************************************************************************/
// //
// InstantCMS v1.10 //
// http://www.instantcms.ru/ //
// //
// written by InstantCMS Team, 2007-2012 //
// produced by InstantSoft, (www.instantsoft.ru) //
// //
// LICENSED BY GNU/GPL v2 //
// //
/******************************************************************************/
class cmsPage {
public $title = '';
public $is_ajax = false;
public $page_head = array();
public $page_keys = '';
public $page_desc = '';
public $page_body = '';
public $pathway = array();
private $modules;
public $captcha_count = 1;
private static $instance;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private function __construct() {
$this->title = $this->homeTitle();
$this->addHeadJS('includes/jquery/jquery.js');
$this->addHeadJS('core/js/common.js');
}
private function __clone() {}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self;
}
return self::$instance;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Добавляет указанный тег в <head> страницы
* @param string $tag
* @return true
*/
public function addHead($tag){
if (!in_array($tag, $this->page_head)){ $this->page_head[] = $tag; }
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Добавляет тег <script> с указанным путем
* @param string $src - Первый слеш не требуется
* @return true
*/
public function addHeadJS($src){
$js_tag = '<script language="JavaScript" type="text/javascript" src="/'.$src.'"></script>';
if($this->is_ajax) { echo $js_tag; return true; }
$this->addHead($js_tag);
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Добавляет тег <link> с указанным путем к CSS-файлу
* @param string $src - Первый слеш не требуется
* @return true
*/
public function addHeadCSS($src){
$css_tag = '<link href="/'.$src.'" rel="stylesheet" type="text/css" />';
$this->addHead($css_tag);
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает заголовок главной страницы
* @return string
*/
public function homeTitle(){
$inConf = cmsConfig::getInstance();
if (isset($inConf->hometitle)) {
if ($inConf->hometitle) { return htmlspecialchars($inConf->hometitle); }
else { return htmlspecialchars($inConf->sitename); }
}
else { return htmlspecialchars($inConf->sitename); }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Устанавливает заголовок страницы
*/
public function setTitle($title=''){
$this->title = strip_tags($title);
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Устанавливает ключевые слова страницы
*/
public function setKeywords($keywords){
$this->page_keys = strip_tags($keywords);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Устанавливает описание страницы
*/
public function setDescription($text){
$this->page_desc = strip_tags($text);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Печатает название сайта из конфига
* @return true
*/
public static function printSitename(){
echo cmsConfig::getConfig('sitename');
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Печатает головную область страницы
*/
public function printHead(){
$inCore = cmsCore::getInstance();
$inConf = cmsConfig::getInstance();
$this->page_head = cmsCore::callEvent('PRINT_PAGE_HEAD', $this->page_head);
ob_start();
//Заголовок
$title = htmlspecialchars($this->title);
// Если есть пагинация и страница больше первой, добавляем "страница №"
if($inConf->title_and_page){
$page=cmsCore::request('page', 'int', 1);
if($page > 1){
global $_LANG;
$title = $title.' — '.$_LANG['PAGE'].' №'.$page;
}
}
$title = ($inCore->menuId()==1 ? $this->homeTitle() : $title.($inConf->title_and_sitename ? ' — '.$inConf->sitename : ''));
echo '<title>'.$title.'</title>' ."n";
//Ключевые слова
if (!$this->page_keys) { $this->page_keys = $inConf->keywords; }
echo '<meta name="keywords" content="'.htmlspecialchars($this->page_keys).'" />' ."n";
//Описание
if (!$this->page_desc) { $this->page_desc = $inConf->metadesc; }
echo '<meta name="description" content="'.htmlspecialchars($this->page_desc).'" />' ."n";
//Генератор
echo '<meta name="generator" content="InstantCMS - www.instantcms.ru"/>' ."n";
//Оставшиеся теги
foreach($this->page_head as $key=>$value) { echo "t". $this->page_head[$key] ."n"; }
echo ob_get_clean();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Выводит тело страницы (результат работы компонента)
*/
public function printBody(){
if (cmsConfig::getConfig('slight')){
$searchquery = cmsUser::sessionGet('searchquery');
if ($searchquery){
if ($_REQUEST['view']!='search'){
$this->page_body = str_ireplace($searchquery, '<span class="search_match">'.$searchquery.'</span>', $this->page_body);
cmsUser::sessionDel('searchquery');
}
}
}
$this->page_body = cmsCore::callEvent('PRINT_PAGE_BODY', $this->page_body);
echo $this->page_body;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Печатает глубиномер
* @param string $separator
*/
public function printPathway($separator='→'){
$inCore = cmsCore::getInstance();
$inConf = cmsConfig::getInstance();
//Проверяем, на главной мы или нет
if (($inCore->menuId()==1 && !$inConf->index_pw) || !$inConf->show_pw) { return false; }
if ($inConf->short_pw){ unset($this->pathway[sizeof($this->pathway)-1]); }
if (is_array($this->pathway)){
echo '<div class="pathway">';
foreach($this->pathway as $key => $value){
echo '<a href="'.$this->pathway[$key]['link'].'" class="pathwaylink">'.$this->pathway[$key]['title'].'</a> ';
if ($key<sizeof($this->pathway)-1) {
echo ' '.$separator.' ';
}
}
echo '</div>';
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Добавляет звено к глубиномеру
* @param string $title
* @param string $link
* @return bool
*/
public function addPathway($title, $link=''){
//Если ссылка не указана, берем текущий URI
if (empty($link)) { $link = htmlspecialchars($_SERVER['REQUEST_URI']); }
//Проверяем, есть ли уже в глубиномере такое звено
$already = false;
foreach($this->pathway as $key => $val){
if ($this->pathway[$key]['link'] == $link){
$already = true;
}
}
//Если такого звена еще нет, добавляем его
if(!$already){
// проверяем нет ли на ссылку пункта меню, если есть, меняем заголовок
$title = ($menu_title = cmsCore::getInstance()->getLinkInMenu($link)) ? $menu_title : $title;
$this->pathway[] = array('title'=>$title, 'link'=>$link);
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Выводит на экран шаблон сайта
* Какой именно шаблон выводить определяют константы TEMPLATE и TEMPLATE_DIR
* Эти константы задаются в файле /index.php
*/
public function showTemplate(){
$inCore = cmsCore::getInstance();
global $_LANG;
$menu_template = $inCore->menuTemplate($inCore->menuId());
if ($menu_template && file_exists(PATH.'/templates/'.$menu_template.'/template.php')){
require(PATH.'/templates/'.$menu_template.'/template.php');
return;
}
if (file_exists(TEMPLATE_DIR.'template.php')){
require(TEMPLATE_DIR.'template.php');
return;
}
cmsCore::halt($_LANG['TEMPLATE'].' "'.TEMPLATE.'" '.$_LANG['NOT_FOUND']);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Подключает файл из папки с шаблоном
* Если в папке текущего шаблона такой файл не найден, ищет в дефолтном
* @param string $file, например "special/error404.html"
* @return <type>
*/
public static function includeTemplateFile($file, $data=array()){
extract($data);
if (file_exists(TEMPLATE_DIR.$file)){
include(TEMPLATE_DIR.$file);
return true;
}
if (file_exists(DEFAULT_TEMPLATE_DIR.$file)){
include(DEFAULT_TEMPLATE_DIR.$file);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static function showSplash(){
if (self::includeTemplateFile('splash/splash.php')){
cmsCore::setCookie('splash', md5('splash'), time()+60*60*24*30);
$_SESSION['splash'] = 1;
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Загружает все модули для данного пункта меню
* @return bool
*/
private function loadModulesForMenuItem() {
if(isset($this->modules)){ return true; }
$modules = array();
$inCore = cmsCore::getInstance();
$inDB = cmsDatabase::getInstance();
if (!$inCore->isMenuIdStrict()){ $strict_sql = "AND (m.is_strict_bind = 0)"; } else { $strict_sql = ''; }
$menuid = $inCore->menuId();
$sql = "SELECT m.*, mb.position as mb_position
FROM cms_modules m
INNER JOIN cms_modules_bind mb ON mb.module_id = m.id AND mb.menu_id IN ($menuid, 0)
WHERE m.published = 1 $strict_sql
ORDER BY m.ordering ASC";
$result = $inDB->query($sql);
if(!$inDB->num_rows($result)){ $this->modules = $modules; return false; }
while ($mod = $inDB->fetch_assoc($result)){
if (!cmsCore::checkContentAccess($mod['access_list'])) { continue; }
// список модулей на позицию
$modules[$mod['mb_position']][] = $mod;
// общий список модулей
$modules['all_modules'][] = $mod;
}
$this->modules = $modules;
return true;
}
public function countModules($position){
$this->loadModulesForMenuItem();
if(!isset($this->modules[$position])){ return 0; }
return sizeof($this->modules[$position]);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Выводит модули для указанной позиции и текущего пункта меню
* @param string $position
* @return html
*/
public function printModules($position){
$this->loadModulesForMenuItem();
if(!isset($this->modules[$position])){ return false; }
$inCore = cmsCore::getInstance();
$inUser = cmsUser::getInstance();
global $_LANG;
foreach ($this->modules[$position] as $mod) {
$modulefile = PATH.'/modules/'.$mod['content'].'/module.php';
$callback = true;
if (!$mod['user']) { cmsCore::loadLanguage('modules/'.$mod['content']); }
// Собственный модуль, созданный в админке
if( !$mod['is_external'] ){
$mod['content'] = cmsCore::processFilters($mod['content']);
$mod['body'] = $mod['content'];
}
// Отдельный модуль
if( $mod['is_external'] ){
if (file_exists($modulefile)){
require_once $modulefile;
// Если есть кеш, берем тело модуля из него
if ($mod['cache'] && cmsCore::isCached('module', $mod['id'], $mod['cachetime'], $mod['cacheint'])){
$mod['body'] = cmsCore::getCache('module', $mod['id']);
$callback = true;
} else {
$config = cmsCore::yamlToArray($mod['config']);
$inCore->cacheModuleConfig($mod['id'], $config);
ob_start();
$callback = $mod['content']($mod['id']);
$mod['body'] = ob_get_clean();
if($mod['cache']) { cmsCore::saveCache('module', $mod['id'], $mod['body']); }
}
}
}
// выводим модуль в шаблоне
if ( $callback ){
$smarty = $inCore->initSmartyModule();
if (cmsConfig::getConfig('fastcfg') && $inUser->is_admin){
$smarty->assign('cfglink', true);
}
$smarty->assign('mod', $mod);
$module_tpl = file_exists($smarty->template_dir.'/'.$mod['template']) ? $mod['template'] : 'module.tpl';
$smarty->display($module_tpl);
}
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает html-код каптчи
* @param string $input_name
* @return html
*/
public static function getCaptcha($input_name='code'){
ob_start();
$captcha_count = self::getInstance()->captcha_count;
$input_id = 'kcaptcha' . $captcha_count;
self::includeTemplateFile('special/captcha.php', array('input_id' => $input_id, 'input_name' => $input_name));
self::getInstance()->captcha_count += 1;
return ob_get_clean();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Разбивает текст на слова и делает каждое слово ссылкой, добавляя в его начало $link
* @param string $link
* @param string $text
* @return html
*/
public static function getMetaSearchLink($link, $text){
if(!$text) { return ''; }
$text = html_entity_decode(trim(trim(strip_tags($text)), '.'));
if (!mb_strstr($text, ',')){
$html = '<a href="'.$link.urlencode($text).'">'.$text.'</a>';
} else {
$text = str_replace(', ', ',', $text);
$words = explode(',', $text);
$html = '';
foreach($words as $value){
$value = str_replace("r", '', $value);
$value = str_replace("n", '', $value);
$value = trim($value, '.');
$html .= '<a href="'.$link.urlencode($value).'">'.$value.'</a>, ';
}
$html = rtrim($html, ', ');
}
return $html;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает html-код панели для вставки BBCode
* @param string $field_id
* @param bool $images
* @param string $placekind
* @return html
*/
public static function getBBCodeToolbar($field_id, $images=0, $component='forum', $target='post', $target_id=0){
// Поддержка плагинов панели ббкодов (ее замены)
$p_toolbar = cmsCore::callEvent('REPLACE_BBCODE_BUTTONS', array('html' => '',
'field_id' => $field_id,
'images' => $images,
'component' => $component,
'target' => $target,
'target_id' => $target_id));
if($p_toolbar['html']){ return $p_toolbar['html']; }
$inPage = self::getInstance();
$inPage->addHeadJS('core/js/smiles.js');
if($images){
$inPage->addHeadJS('includes/jquery/upload/ajaxfileupload.js');
}
ob_start();
self::includeTemplateFile('special/bbcode_panel.php', array('field_id' => $field_id,
'images' => $images,
'component' => $component,
'target' => $target,
'target_id' => $target_id));
return cmsCore::callEvent('GET_BBCODE_BUTTON', ob_get_clean());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает html-код панели со смайлами
* @param string $for_field_id
* @return html
*/
public static function getSmilesPanel($for_field_id){
$p_html = cmsCore::callEvent('REPLACE_SMILES', array('html' => '', 'for_field_id'=>$for_field_id));
if($p_html['html']){ return $p_html['html']; }
$html = '<div class="usr_msg_smilebox" id="smilespanel-'.$for_field_id.'" style="display:none">';
if ($handle = opendir(PATH.'/images/smilies')) {
while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..' && mb_strstr($file, '.gif')){
$tag = str_replace('.gif', '', $file);
$dir = '/images/smilies/';
$html .= '<a href="javascript:addSmile(''.$tag.'', ''.$for_field_id.'');"><img src="'.$dir.$file.'" border="0" /></a> ';
}
}
closedir($handle);
}
$html .= '</div>';
return $html;
}
// AUTOCOMPLETE PLUGIN /////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Подключает JS и CSS для автокомплита
*/
public function initAutocomplete(){
$this->addHeadJS('includes/jquery/autocomplete/jquery.autocomplete.min.js');
$this->addHeadCSS('includes/jquery/autocomplete/jquery.autocomplete.css');
}
/**
* Возвращает JS-код инициализации автокомплита для указанного поля ввода и скрипта
* @param string $script
* @param string $field_id
* @param bool $multiple
* @return js
*/
public function getAutocompleteJS($script, $field_id='tags', $multiple=true){
$multiple = $multiple ? 'true' : 'false';
return '$("#'.$field_id.'").autocomplete(
"/core/ajax/'.$script.'.php",
{
width: 280,
selectFirst: false,
multiple: '.$multiple.'
}
);';
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает код панели для постраничной навигации
* @param int $total
* @param int $page
* @param int $perpage
* @param string $link
* @param array $params
* @return html
*/
public static function getPagebar($total, $page, $perpage, $link, $params=array()){
$pagebar = cmsCore::callEvent('GET_PAGEBAR', array($total, $page, $perpage, $link, $params));
if(!is_array($pagebar) && $pagebar) { return $pagebar; }
global $_LANG;
$html = '<div class="pagebar">';
$html .= '<span class="pagebar_title"><strong>'.$_LANG['PAGES'].': </strong></span>';
$total_pages = ceil($total / $perpage);
if ($total_pages < 2) { return; }
//if more than one page of results
if($total_pages!=1){
//configure for the starting links per page
$max = 4;
//used in the loop
$max_links = $max+1;
$h=1;
//if page is above max link
if($page>$max_links){
//start of loop
$h=(($h+$page)-$max_links);
}
//if page is not page one
if($page>=1){
//top of the loop extends
$max_links = $max_links+($page-1);
}
//if the top page is visible then reset the top of the loop to the $total_pages
if($max_links>$total_pages){
$max_links=$total_pages+1;
}
//next and prev buttons
if($page>1){
$href = $link;
if (is_array($params)){
foreach($params as $param=>$value){
$href = str_replace('%'.$param.'%', $value, $href);
}
}
$html .= ' <a href="'.str_replace('%page%', 1, $href).'" class="pagebar_page">'.$_LANG['FIRST'].'</a> ';
$html .= ' <a href="'.str_replace('%page%', ($page-1), $href).'" class="pagebar_page">'.$_LANG['PREVIOUS'].'</a> ';
}
//create the page links
for ($i=$h;$i<$max_links;$i++){
if($i==$page){
$html .= '<span class="pagebar_current">'.$i.'</span>';
}
else{
$href = $link;
if (is_array($params)){
foreach($params as $param=>$value){
$href = str_replace('%'.$param.'%', $value, $href);
}
}
$href = str_replace('%page%', $i, $href);
$html .= ' <a href="'.$href.'" class="pagebar_page">'.$i.'</a> ';
}
}
//Next and last buttons
if(($page >= 1)&&($page!=$total_pages)){
$href = $link;
if (is_array($params)){
foreach($params as $param=>$value){
$href = str_replace('%'.$param.'%', $value, $href);
}
}
$html .= ' <a href="'.str_replace('%page%', ($page+1), $href).'" class="pagebar_page">'.$_LANG['NEXT'].'</a> ';
$html .= ' <a href="'.str_replace('%page%', $total_pages, $href).'" class="pagebar_page">'.$_LANG['LAST'].'</a> ';
}
}
//if one page of results
else{
$href = $link;
if (is_array($params)){
foreach($params as $param=>$value){
$href = str_replace('%'.$param.'%', $value, $href);
}
}
$href = str_replace('%page%', 1, $href);
$html .= ' <a href="'.$href.'" class="pagebar_page">1</a> ';
}
$html.='</div>';
return $html;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static function getModuleTemplates() {
$tpl_dir = is_dir(TEMPLATE_DIR.'modules') ? TEMPLATE_DIR.'modules' : PATH.'/templates/_default_/modules';
$pdir = opendir($tpl_dir);
$templates = array();
while ($nextfile = readdir($pdir)){
if (
($nextfile != '.') &&
($nextfile != '..') &&
!is_dir($tpl_dir.'/'.$nextfile) &&
($nextfile!='.svn') &&
(mb_substr($nextfile, 0, 6)=='module')
) {
$templates[$nextfile] = $nextfile;
}
}
if (!sizeof($templates)){ return false; }
return $templates;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
?>