/** * Display a content hierarchy as list with chapters and posts * * @param array Params */ function display_hierarchy($params = array()) { $params = array_merge(array('block_start' => '', 'block_end' => '', 'block_body_start' => '', 'block_body_end' => '', 'list_start' => '<ul class="chapters_list">', 'list_end' => '</ul>', 'list_subs_start' => '<ul>', 'list_subs_end' => '</ul>', 'item_start' => '<li>', 'item_end' => '</li>', 'item_before_opened' => '', 'item_before_closed' => '', 'item_before_post' => '', 'class_opened' => 'opened', 'class_closed' => 'closed', 'class_selected' => 'selected', 'class_post' => 'post', 'display_blog_title' => true, 'open_children_levels' => 0, 'list_posts' => true), $params); global $blog, $cat, $Item; $BlogCache =& get_BlogCache(); $ChapterCache =& get_ChapterCache(); if (!empty($this->disp_params['blog_ID'])) { // Set a Blog from widget setting $this->Blog =& $BlogCache->get_by_ID(intval($this->disp_params['blog_ID']), false, false); } if (empty($this->Blog) && !empty($blog)) { // Use current Blog $this->Blog =& $BlogCache->get_by_ID($blog, false, false); } if (empty($this->Blog)) { // No Blog, Exit here return; } $chapter_path = array(); if (!empty($cat)) { // A category is opened $params['chapter_path'] = $ChapterCache->get_chapter_path($this->Blog->ID, $cat); } elseif (!empty($Item) && !$Item->is_intro()) { // A post is opened (Ignore intro posts) $params['chapter_path'] = $ChapterCache->get_chapter_path($this->Blog->ID, $Item->main_cat_ID); } echo $params['block_body_start']; echo $params['list_start']; if ($params['display_blog_title']) { // Display blog title echo str_replace('>', ' class="title ' . $params['class_selected'] . '">', $params['item_start']); echo '<a href="' . $this->Blog->get('url') . '" class="link">' . $this->Blog->get('name') . '</a>'; echo $params['item_end']; } $callbacks = array('line' => array($this, 'display_chapter'), 'before_level' => array($this, 'cat_before_level'), 'after_level' => array($this, 'cat_after_level'), 'posts' => array($this, 'display_post_row')); echo $ChapterCache->recurse($callbacks, $this->Blog->ID, NULL, 0, 0, $params); echo $params['list_end']; echo $params['block_body_end']; }
/** * Check whether the main category and the extra categories are valid * in a Blog's context and try to fix errors. * * @author Tilman BLUMENBACH / Tblue * * @param integer The main category to check (by reference). * @param object The Blog to which the category is supposed to belong to (by reference). * @param array Extra categories for the post (by reference). * * @return boolean False on error (use xmlrpcs_resperror() to return it), true on success. */ function xmlrpcs_check_cats(&$maincat, &$Blog, &$extracats) { global $xmlrpcs_errcode, $xmlrpcs_errmsg, $xmlrpcerruser; // Trim $maincat and $extracats (qtm sends whitespace before the cat IDs): $maincat = trim($maincat); $extracats = array_map('trim', $extracats); $ChapterCache =& get_ChapterCache(); // ---- CHECK MAIN CATEGORY ---- if ($ChapterCache->get_by_ID($maincat, false) === false) { // Category does not exist! // Remove old category from extra cats: if (($key = array_search($maincat, $extracats)) !== false) { unset($extracats[$key]); } // Set new category (blog default): $maincat = $Blog->get_default_cat_ID(); logIO('Invalid main cat ID - new ID: ' . $maincat); } else { if (get_allow_cross_posting() < 2 && get_catblog($maincat) != $Blog->ID) { // We cannot use a maincat of another blog than the current one: $xmlrpcs_errcode = $xmlrpcerruser + 11; $xmlrpcs_errmsg = 'Current crossposting setting does not allow moving posts to a different blog.'; return false; } } // ---- CHECK EXTRA CATEGORIES ---- foreach ($extracats as $ecat) { if ($ecat == $maincat) { // We already checked the maincat above (or reset it): continue; } logIO('Checking extra cat: ' . $ecat); if ($ChapterCache->get_by_ID($ecat, false) === false) { // Extra cat does not exist: $xmlrpcs_errcode = $xmlrpcerruser + 11; $xmlrpcs_errmsg = 'Extra category ' . (int) $ecat . ' not found in requested blog.'; return false; } } if (!in_array($maincat, $extracats)) { logIO('$maincat was not found in $extracats array - adding.'); $extracats[] = $maincat; } return true; }
/** * Initialize internal states for the most common skin displays. * * For more specific skins, this function may not be called and * equivalent code may be customized within the skin. * * @param string What are we going to display. Most of the time the global $disp should be passed. */ function skin_init($disp) { /** * @var Blog */ global $Blog; /** * @var Item */ global $Item; /** * @var Skin */ global $Skin; global $robots_index; global $seo_page_type; global $redir, $ReqURL, $ReqURI, $m, $w, $preview; global $Chapter; global $Debuglog; /** * @var ItemList2 */ global $MainList; /** * This will give more detail when $disp == 'posts'; otherwise it will have the same content as $disp * @var string */ global $disp_detail, $Settings; global $Timer; global $Messages, $PageCache; global $Session, $current_User; $Timer->resume('skin_init'); if (empty($disp_detail)) { $disp_detail = $disp; } $Debuglog->add('skin_init: $disp=' . $disp, 'skins'); // This is the main template; it may be used to display very different things. // Do inits depending on current $disp: switch ($disp) { case 'front': case 'posts': case 'single': case 'page': case 'terms': case 'download': case 'feedback-popup': // We need to load posts for this display: if ($disp == 'terms') { // Initialize the redirect param to know what page redirect after accepting of terms: param('redirect_to', 'url', ''); } // Note: even if we request the same post as $Item above, the following will do more restrictions (dates, etc.) // Init the MainList object: init_MainList($Blog->get_setting('posts_per_page')); // Init post navigation $post_navigation = $Skin->get_post_navigation(); if (empty($post_navigation)) { $post_navigation = $Blog->get_setting('post_navigation'); } if (!empty($MainList) && $MainList->single_post && ($single_Item =& mainlist_get_item())) { // If we are currently viewing a single post // We assume the current user will have read the entire post and all its current comments: $single_Item->update_read_timestamps(true, true); // Restart the items list: $MainList->restart(); } break; case 'search': // Searching post, comments and categories load_funcs('collections/_search.funcs.php'); // Check previous search keywords so it can be displayed in the search input box param('s', 'string', '', true); break; } // SEO stuff & redirects if necessary: $seo_page_type = NULL; switch ($disp) { // CONTENT PAGES: case 'single': case 'page': case 'terms': if ($disp == 'terms' && !$Item) { // Wrong post ID for terms page: global $disp; $disp = '404'; $Messages->add(sprintf(T_('Terms not found. (post ID #%s)'), get_param('p')), 'error'); break; } if (!$preview && empty($Item)) { // No Item, incorrect request and incorrect state of the application, a 404 redirect should have already happened //debug_die( 'Invalid page URL!' ); } if ($disp == 'single') { $seo_page_type = 'Single post page'; } else { $seo_page_type = '"Page" page'; } if (!$preview) { // Check if item has a goal to insert a hit into DB $Item->check_goal(); } // Check if the post has 'redirected' status: if (!$preview && $Item->status == 'redirected' && $redir == 'yes') { // $redir=no here allows to force a 'single post' URL for commenting // Redirect to the URL specified in the post: $Debuglog->add('Redirecting to post URL [' . $Item->url . '].'); header_redirect($Item->url, true, true); } // Check if we want to redirect to a canonical URL for the post // Please document encountered problems. if (!$preview && ($Blog->get_setting('canonical_item_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_item_urls'))) { // We want to redirect to the Item's canonical URL: $canonical_url = $Item->get_permanent_url('', '', '&'); if (preg_match('|[&?](page=\\d+)|', $ReqURI, $page_param)) { // A certain post page has been requested, keep only this param and discard all others: $canonical_url = url_add_param($canonical_url, $page_param[1], '&'); } if (preg_match('|[&?](mode=quote&[qcp]+=\\d+)|', $ReqURI, $page_param)) { // A quote of comment/post, keep only these params and discard all others: $canonical_url = url_add_param($canonical_url, $page_param[1], '&'); } if (!is_same_url($ReqURL, $canonical_url)) { // The requested URL does not look like the canonical URL for this post... // url difference was resolved $url_resolved = false; // Check if the difference is because of an allowed post navigation param if (preg_match('|[&?]cat=(\\d+)|', $ReqURI, $cat_param)) { // A category post navigation param is set $extended_url = ''; if ($post_navigation == 'same_category' && isset($cat_param[1])) { // navigatie through posts from the same category $category_ids = postcats_get_byID($Item->ID); if (in_array($cat_param[1], $category_ids)) { // cat param is one of this Item categories $extended_url = $Item->add_navigation_param($canonical_url, $post_navigation, $cat_param[1], '&'); // Set MainList navigation target to the requested category $MainList->nav_target = $cat_param[1]; } } $url_resolved = is_same_url($ReqURL, $extended_url); } if (preg_match('|[&?]tag=([^&A-Z]+)|', $ReqURI, $tag_param)) { // A tag post navigation param is set $extended_url = ''; if ($post_navigation == 'same_tag' && isset($tag_param[1])) { // navigatie through posts from the same tag $tag_names = $Item->get_tags(); if (in_array($tag_param[1], $tag_names)) { // tag param is one of this Item tags $extended_url = $Item->add_navigation_param($canonical_url, $post_navigation, $tag_param[1], '&'); // Set MainList navigation target to the requested tag $MainList->nav_target = $tag_param[1]; } } $url_resolved = is_same_url($ReqURL, $extended_url); } if (!$url_resolved && $Blog->get_setting('canonical_item_urls') && $redir == 'yes' && !$Item->check_cross_post_nav('auto', $Blog->ID)) { // REDIRECT TO THE CANONICAL URL: $Debuglog->add('Redirecting to canonical URL [' . $canonical_url . '].'); header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } // EXITED. } } if (!$MainList->result_num_rows) { // There is nothing to display for this page, don't index it! $robots_index = false; } break; case 'download': if (empty($Item)) { // No Item, incorrect request and incorrect state of the application, a 404 redirect should have already happened debug_die('Invalid page URL!'); } $download_link_ID = param('download', 'integer', 0); // Check if we can allow to download the selected file $LinkCache =& get_LinkCache(); if (!(($download_Link =& $LinkCache->get_by_ID($download_link_ID, false, false)) && ($LinkItem =& $download_Link->get_LinkOwner()) && ($LinkItem->Item && $LinkItem->Item->ID == $Item->ID) && ($download_File =& $download_Link->get_File()) && $download_File->exists())) { // Bad request, Redirect to Item permanent url $Messages->add(T_('The requested file is not available for download.'), 'error'); $canonical_url = $Item->get_permanent_url('', '', '&'); $Debuglog->add('Redirecting to canonical URL [' . $canonical_url . '].'); header_redirect($canonical_url, true); } // Save the downloading Link to the global vars $GLOBALS['download_Link'] =& $download_Link; // Save global $Item to $download_Item, because $Item can be rewritten by function get_featured_Item() in some skins $GLOBALS['download_Item'] =& $Item; init_ajax_forms('blog'); // auto requires jQuery // Initialize JavaScript to download file after X seconds add_js_headline(' jQuery( document ).ready( function () { jQuery( "#download_timer_js" ).show(); } ); var b2evo_download_timer = ' . intval($Blog->get_setting('download_delay')) . '; var downloadInterval = setInterval( function() { jQuery( "#download_timer" ).html( b2evo_download_timer ); if( b2evo_download_timer == 0 ) { // Stop timer and download a file clearInterval( downloadInterval ); jQuery( "#download_help_url" ).show(); } b2evo_download_timer--; }, 1000 );'); // Use meta tag to download file when JavaScript is NOT enabled add_headline('<meta http-equiv="refresh" content="' . intval($Blog->get_setting('download_delay')) . '; url=' . $download_Link->get_download_url(array('type' => 'action')) . '" />'); $seo_page_type = 'Download page'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'posts': init_ajax_forms('blog'); // auto requires jQuery // fp> if we add this here, we have to exetnd the inner if() // init_ratings_js( 'blog' ); // Get list of active filters: $active_filters = $MainList->get_active_filters(); if (!empty($active_filters)) { // The current page is being filtered... if (array_diff($active_filters, array('page')) == array()) { // This is just a follow "paged" page $disp_detail = 'posts-next'; $seo_page_type = 'Next page'; if ($Blog->get_setting('paged_noindex')) { // We prefer robots not to index category pages: $robots_index = false; } } elseif (array_diff($active_filters, array('cat_array', 'cat_modifier', 'cat_focus', 'posts', 'page')) == array()) { // This is a category page $disp_detail = 'posts-cat'; $seo_page_type = 'Category page'; if ($Blog->get_setting('chapter_noindex')) { // We prefer robots not to index category pages: $robots_index = false; } global $cat, $catsel; if (empty($catsel) && preg_match('~^[0-9]+$~', $cat)) { // We are on a single cat page: // NOTE: we must have selected EXACTLY ONE CATEGORY through the cat parameter // BUT: - this can resolve to including children // - selecting exactly one cat through catsel[] is NOT OK since not equivalent (will exclude children) // echo 'SINGLE CAT PAGE'; if ($Blog->get_setting('canonical_cat_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_cat_urls')) { // Check if the URL was canonical: if (!isset($Chapter)) { $ChapterCache =& get_ChapterCache(); /** * @var Chapter */ $Chapter =& $ChapterCache->get_by_ID($MainList->filters['cat_array'][0], false); } if ($Chapter) { if ($Chapter->parent_ID) { // This is a sub-category page (i-e: not a level 1 category) $disp_detail = 'posts-subcat'; } $canonical_url = $Chapter->get_permanent_url(NULL, NULL, $MainList->get_active_filter('page'), NULL, '&'); if (!is_same_url($ReqURL, $canonical_url)) { // fp> TODO: we're going to lose the additional params, it would be better to keep them... // fp> what additional params actually? if ($Blog->get_setting('canonical_cat_urls') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canonical": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } else { // If the requested chapter was not found display 404 page $Messages->add(T_('The requested chapter was not found')); global $disp; $disp = '404'; break; } } if ($post_navigation == 'same_category') { // Category is set and post navigation should go through the same category, set navigation target param $MainList->nav_target = $cat; } } } elseif (array_diff($active_filters, array('tags', 'posts', 'page')) == array()) { // This is a tag page $disp_detail = 'posts-tag'; $seo_page_type = 'Tag page'; if ($Blog->get_setting('tag_noindex')) { // We prefer robots not to index tag pages: $robots_index = false; } if ($Blog->get_setting('canonical_tag_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_tag_urls')) { // Check if the URL was canonical: $canonical_url = $Blog->gen_tag_url($MainList->get_active_filter('tags'), $MainList->get_active_filter('page'), '&'); if (!is_same_url($ReqURL, $canonical_url)) { if ($Blog->get_setting('canonical_tag_urls') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } $tag = $MainList->get_active_filter('tags'); if ($post_navigation == 'same_tag' && !empty($tag)) { // Tag is set and post navigation should go through the same tag, set navigation target param $MainList->nav_target = $tag; } } elseif (array_diff($active_filters, array('ymdhms', 'week', 'posts', 'page')) == array()) { // This is an archive page // echo 'archive page'; $disp_detail = 'posts-date'; $seo_page_type = 'Date archive page'; if ($Blog->get_setting('canonical_archive_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_archive_urls')) { // Check if the URL was canonical: $canonical_url = $Blog->gen_archive_url(substr($m, 0, 4), substr($m, 4, 2), substr($m, 6, 2), $w, '&', $MainList->get_active_filter('page')); if (!is_same_url($ReqURL, $canonical_url)) { if ($Blog->get_setting('canonical_archive_urls') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } if ($Blog->get_setting('archive_noindex')) { // We prefer robots not to index archive pages: $robots_index = false; } } else { // Other filtered pages: // pre_dump( $active_filters ); $disp_detail = 'posts-filtered'; $seo_page_type = 'Other filtered page'; if ($Blog->get_setting('filtered_noindex')) { // We prefer robots not to index other filtered pages: $robots_index = false; } } } elseif ($Blog->get_setting('front_disp') == 'posts') { // This is the default blog page only if the 'front_disp' is set to 'posts' $disp_detail = 'posts-default'; $seo_page_type = 'Default page'; if ($Blog->get_setting('default_noindex')) { // We prefer robots not to index archive pages: $robots_index = false; } } break; case 'search': $seo_page_type = 'Search page'; if ($Blog->get_setting('filtered_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; // SPECIAL FEATURE PAGES: // SPECIAL FEATURE PAGES: case 'feedback-popup': $seo_page_type = 'Comment popup'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'arcdir': $seo_page_type = 'Date archive directory'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'catdir': $seo_page_type = 'Category directory'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'msgform': global $disp; // get expected message form type $msg_type = param('msg_type', 'string', ''); // initialize $recipient_User = NULL; $Comment = NULL; $allow_msgform = NULL; // get possible params $recipient_id = param('recipient_id', 'integer', 0, true); $comment_id = param('comment_id', 'integer', 0, true); $post_id = param('post_id', 'integer', 0, true); $subject = param('subject', 'string', ''); // try to init recipient_User if (!empty($recipient_id)) { $UserCache =& get_UserCache(); $recipient_User =& $UserCache->get_by_ID($recipient_id); } elseif (!empty($comment_id)) { // comment id is set, try to get comment author user $CommentCache =& get_CommentCache(); $Comment = $CommentCache->get_by_ID($comment_id, false); if ($Comment = $CommentCache->get_by_ID($comment_id, false)) { $recipient_User =& $Comment->get_author_User(); if (empty($recipient_User) && $Comment->allow_msgform && is_email($Comment->get_author_email())) { // set allow message form to email because comment author (not registered) accepts email $allow_msgform = 'email'; param('recipient_address', 'string', $Comment->get_author_email()); param('recipient_name', 'string', $Comment->get_author_name()); } } } else { // Recipient was not defined, try set the blog owner as recipient global $Blog; if (empty($Blog)) { // Blog is not set, this is an invalid request debug_die('Invalid send message request!'); } $recipient_User = $Blog->get_owner_User(); } if ($recipient_User) { // recipient User is set // get_msgform_possibility returns NULL (false), only if there is no messaging option between current_User and recipient user $allow_msgform = $recipient_User->get_msgform_possibility(); if ($msg_type == 'email' && $recipient_User->get_msgform_possibility(NULL, 'email') != 'email') { // User doesn't want to receive email messages, Restrict if this was requested by wrong url: $msg_type = ''; } if ($allow_msgform == 'login') { // user must login first to be able to send a message to this User $disp = 'login'; param('action', 'string', 'req_login'); // override redirect to param param('redirect_to', 'url', regenerate_url(), true, true); if (($msg_Blog =& get_setting_Blog('msg_blog_ID')) && $Blog->ID != $msg_Blog->ID) { // Redirect to special blog for messaging actions if it is defined in general settings header_redirect(url_add_param($msg_Blog->get('msgformurl', array('glue' => '&')), 'redirect_to=' . rawurlencode($redirect_to), '&')); } $Messages->add(T_('You must log in before you can contact this user')); } elseif ($allow_msgform == 'PM' && check_user_status('can_be_validated')) { // user is not activated if ($recipient_User->accepts_email()) { // recipient User accepts email allow to send email $allow_msgform = 'email'; $msg_type = 'email'; $activateinfo_link = 'href="' . get_activate_info_url(NULL, '&') . '"'; $Messages->add(sprintf(T_('You must activate your account before you can send a private message to %s. However you can send them an email if you\'d like. <a %s>More info »</a>'), $recipient_User->get('login'), $activateinfo_link), 'warning'); } else { // Redirect to the activate info page for not activated users $Messages->add(T_('You must activate your account before you can contact a user. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } } elseif ($msg_type == 'PM' && $allow_msgform == 'email') { // only email is allowed but user expect private message form if (!empty($current_User) && $recipient_id == $current_User->ID) { $Messages->add(T_('You cannot send a private message to yourself. However you can send yourself an email if you\'d like.'), 'warning'); } else { $Messages->add(sprintf(T_('You cannot send a private message to %s. However you can send them an email if you\'d like.'), $recipient_User->get('login')), 'warning'); } } elseif ($msg_type != 'email' && $allow_msgform == 'PM') { // private message form should be displayed, change display to create new individual thread with the given recipient user // check if creating new PM is allowed if (check_create_thread_limit(true)) { // thread limit reached header_redirect(); // exited here } global $edited_Thread, $edited_Message, $recipients_selected; // Load classes load_class('messaging/model/_thread.class.php', 'Thread'); load_class('messaging/model/_message.class.php', 'Message'); // Set global variable to auto define the FB autocomplete plugin field $recipients_selected = array(array('id' => $recipient_User->ID, 'title' => $recipient_User->login)); init_tokeninput_js('blog'); $disp = 'threads'; $edited_Thread = new Thread(); $edited_Message = new Message(); $edited_Message->Thread =& $edited_Thread; $edited_Thread->recipients = $recipient_User->login; param('action', 'string', 'new', true); param('thrdtype', 'string', 'individual', true); } if ($allow_msgform == 'email') { // set recippient user param set_param('recipient_id', $recipient_User->ID); } } if ($allow_msgform == NULL) { // should be Prevented by UI if (!empty($recipient_User)) { $Messages->add(sprintf(T_('The user "%s" does not want to be contacted through the message form.'), $recipient_User->get('login')), 'error'); } elseif (!empty($Comment)) { $Messages->add(T_('This commentator does not want to get contacted through the message form.'), 'error'); } $blogurl = $Blog->gen_blogurl(); // If it was a front page request or the front page is set to 'msgform' then we must not redirect to the front page because it is forbidden for the current User $redirect_to = is_front_page() || $Blog->get_setting('front_disp') == 'msgform' ? url_add_param($blogurl, 'disp=403', '&') : $blogurl; header_redirect($redirect_to, 302); // exited here } if ($allow_msgform == 'PM' || $allow_msgform == 'email') { // Some message form is available // Get the suggested subject for the email: if (empty($subject)) { // no subject provided by param: global $DB; if (!empty($comment_id)) { // fp>TODO there should be NO SQL in this file. Make a $ItemCache->get_by_comment_ID(). $row = $DB->get_row(' SELECT post_title FROM T_items__item, T_comments WHERE comment_ID = ' . $DB->quote($comment_id) . ' AND post_ID = comment_item_ID'); if ($row) { $subject = T_('Re:') . ' ' . sprintf(T_('Comment on %s'), $row->post_title); } } if (empty($subject) && !empty($post_id)) { // fp>TODO there should be NO SQL in this file. Use $ItemCache->get_by_ID. $row = $DB->get_row(' SELECT post_title FROM T_items__item WHERE post_ID = ' . $post_id); if ($row) { $subject = T_('Re:') . ' ' . $row->post_title; } } } if ($allow_msgform == 'PM' && isset($edited_Thread)) { $edited_Thread->title = $subject; } else { param('subject', 'string', $subject, true); } } if (($msg_Blog =& get_setting_Blog('msg_blog_ID')) && $Blog->ID != $msg_Blog->ID) { // Redirect to special blog for messaging actions if it is defined in general settings header_redirect($msg_Blog->get('msgformurl', array('glue' => '&'))); } $seo_page_type = 'Contact form'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'messages': case 'contacts': case 'threads': switch ($disp) { case 'messages': // Actions ONLY for disp=messages // fp> The correct place to get thrd_ID is here, because we want it in redirect_to in case we need to ask for login. $thrd_ID = param('thrd_ID', 'integer', '', true); if (!is_logged_in()) { // Redirect to the login page for anonymous users $Messages->add(T_('You must log in to read your messages.')); header_redirect(get_login_url('cannot see messages'), 302); // will have exited } // check if user status allow to view messages if (!$current_User->check_status('can_view_messages')) { // user status does not allow to view messages if ($current_User->check_status('can_be_validated')) { // user is logged in but his/her account is not activate yet $Messages->add(T_('You must activate your account before you can read & send messages. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } $Messages->add('You are not allowed to view Messages!'); header_redirect($Blog->gen_blogurl(), 302); // will have exited } // check if user permissions allow to view messages if (!$current_User->check_perm('perm_messaging', 'reply')) { // Redirect to the blog url for users without messaging permission $Messages->add('You are not allowed to view Messages!'); header_redirect($Blog->gen_blogurl(), 302); // will have exited } if (!empty($thrd_ID)) { // if this thread exists and current user is part of this thread update status because won't be any unread messages on this conversation // we need to mark this early to make sure the unread message count will be correct in the evobar mark_as_read_by_user($thrd_ID, $current_User->ID); } if (($unsaved_message_params = get_message_params_from_session()) !== NULL) { // set Message and Thread saved params from Session global $edited_Message, $action; load_class('messaging/model/_message.class.php', 'Message'); $edited_Message = new Message(); $edited_Message->text = $unsaved_message_params['message']; $edited_Message->original_text = $unsaved_message_params['message_original']; $edited_Message->set_renderers($unsaved_message_params['renderers']); $edited_Message->thread_ID = $thrd_ID; $action = $unsaved_message_params['action']; } break; case 'contacts': // Actions ONLY for disp=contacts if (!is_logged_in()) { // Redirect to the login page for anonymous users $Messages->add(T_('You must log in to manage your contacts.')); header_redirect(get_login_url('cannot see contacts'), 302); // will have exited } if (!$current_User->check_status('can_view_contacts')) { // user is logged in, but his status doesn't allow to view contacts if ($current_User->check_status('can_be_validated')) { // user is logged in but his/her account was not activated yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can manage your contacts. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } // Redirect to the blog url for users without messaging permission $Messages->add('You are not allowed to view Contacts!'); $blogurl = $Blog->gen_blogurl(); // If it was a front page request or the front page is set to display 'contacts' then we must not redirect to the front page because it is forbidden for the current User $redirect_to = is_front_page() || $Blog->get_setting('front_disp') == 'contacts' ? url_add_param($blogurl, 'disp=403', '&') : $blogurl; header_redirect($redirect_to, 302); } if (has_cross_country_restriction('any') && empty($current_User->ctry_ID)) { // User may browse/contact other users only from the same country $Messages->add(T_('Please specify your country before attempting to contact other users.')); header_redirect(get_user_profile_url()); } // Get action parameter from request: $action = param_action(); if (!$current_User->check_perm('perm_messaging', 'reply')) { // Redirect to the blog url for users without messaging permission $Messages->add('You are not allowed to view Contacts!'); $blogurl = $Blog->gen_blogurl(); // If it was a front page request or the front page is set to display 'contacts' then we must not redirect to the front page because it is forbidden for the current User $redirect_to = is_front_page() || $Blog->get_setting('front_disp') == 'contacts' ? url_add_param($blogurl, 'disp=403', '&') : $blogurl; header_redirect($redirect_to, 302); // will have exited } switch ($action) { case 'add_user': // Add user to contacts list // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('messaging_contacts'); $user_ID = param('user_ID', 'integer', 0); if ($user_ID > 0) { // Add user to contacts if (create_contacts_user($user_ID)) { // Add user to the group $group_ID = param('group_ID', 'string', ''); if ($result = create_contacts_group_users($group_ID, $user_ID, 'group_ID_combo')) { // User has been added to the group $Messages->add(sprintf(T_('User has been added to the «%s» group.'), $result['group_name']), 'success'); } else { // User has been added ONLY to the contacts list $Messages->add('User has been added to your contacts.', 'success'); } } header_redirect($Blog->get('userurl', array('url_suffix' => 'user_ID=' . $user_ID, 'glue' => '&'))); } break; case 'unblock': // Unblock user // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('messaging_contacts'); $user_ID = param('user_ID', 'integer', 0); if ($user_ID > 0) { set_contact_blocked($user_ID, 0); $Messages->add(T_('Contact was unblocked.'), 'success'); } break; case 'remove_user': // Remove user from contacts group // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('messaging_contacts'); $view = param('view', 'string', 'profile'); $user_ID = param('user_ID', 'integer', 0); $group_ID = param('group_ID', 'integer', 0); if ($user_ID > 0 && $group_ID > 0) { // Remove user from selected group if (remove_contacts_group_user($group_ID, $user_ID)) { // User has been removed from the group if ($view == 'contacts') { // Redirect to the contacts list header_redirect($Blog->get('contactsurl', array('glue' => '&'))); } else { // Redirect to the user profile page header_redirect($Blog->get('userurl', array('url_suffix' => 'user_ID=' . $user_ID, 'glue' => '&'))); } } } break; case 'add_group': // Add users to the group // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('messaging_contacts'); $group = param('group', 'string', ''); $users = param('users', 'string', ''); if ($result = create_contacts_group_users($group, $users)) { // Users have been added to the group $Messages->add(sprintf(T_('%d contacts have been added to the «%s» group.'), $result['count_users'], $result['group_name']), 'success'); $redirect_to = $Blog->get('contactsurl', array('glue' => '&')); $item_ID = param('item_ID', 'integer', 0); if ($item_ID > 0) { $redirect_to = url_add_param($redirect_to, 'item_ID=' . $item_ID, '&'); } header_redirect($redirect_to); } break; case 'rename_group': // Rename the group // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('messaging_contacts'); $group_ID = param('group_ID', 'integer', true); if (rename_contacts_group($group_ID)) { $item_ID = param('item_ID', 'integer', 0); $redirect_to = url_add_param($Blog->get('contactsurl', array('glue' => '&')), 'g=' . $group_ID, '&'); if ($item_ID > 0) { $redirect_to = url_add_param($redirect_to, 'item_ID=' . $item_ID, '&'); } $Messages->add(T_('The group has been renamed.'), 'success'); header_redirect($redirect_to); } break; case 'delete_group': // Delete the group // Check that this action request is not a CSRF hacked request: $Session->assert_received_crumb('messaging_contacts'); $group_ID = param('group_ID', 'integer', true); if (delete_contacts_group($group_ID)) { $item_ID = param('item_ID', 'integer', 0); $redirect_to = $Blog->get('contactsurl', array('glue' => '&')); if ($item_ID > 0) { $redirect_to = url_add_param($redirect_to, 'item_ID=' . $item_ID, '&'); } $Messages->add(T_('The group has been deleted.'), 'success'); header_redirect($redirect_to); } break; } modules_call_method('switch_contacts_actions', array('action' => $action)); break; case 'threads': // Actions ONLY for disp=threads if (!is_logged_in()) { // Redirect to the login page for anonymous users $Messages->add(T_('You must log in to read your messages.')); header_redirect(get_login_url('cannot see messages'), 302); // will have exited } if (!$current_User->check_status('can_view_threads')) { // user status does not allow to view threads if ($current_User->check_status('can_be_validated')) { // user is logged in but his/her account is not activate yet $Messages->add(T_('You must activate your account before you can read & send messages. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } $Messages->add('You are not allowed to view Messages!'); $blogurl = $Blog->gen_blogurl(); // If it was a front page request or the front page is set to display 'threads' then we must not redirect to the front page because it is forbidden for the current User $redirect_to = is_front_page() || $Blog->get_setting('front_disp') == 'threads' ? url_add_param($blogurl, 'disp=404', '&') : $blogurl; header_redirect($redirect_to, 302); // will have exited } if (!$current_User->check_perm('perm_messaging', 'reply')) { // Redirect to the blog url for users without messaging permission $Messages->add('You are not allowed to view Messages!'); $blogurl = $Blog->gen_blogurl(); // If it was a front page request or the front page is set to display 'threads' then we must not redirect to the front page because it is forbidden for the current User $redirect_to = is_front_page() || $Blog->get_setting('front_disp') == 'threads' ? url_add_param($blogurl, 'disp=403', '&') : $blogurl; header_redirect($redirect_to, 302); // will have exited } $action = param('action', 'string', 'view'); if ($action == 'new') { // Before new message form is displayed ... if (has_cross_country_restriction('contact') && empty($current_User->ctry_ID)) { // Cross country contact restriction is enabled, but user country is not set yet $Messages->add(T_('Please specify your country before attempting to contact other users.')); header_redirect(get_user_profile_url()); } elseif (check_create_thread_limit(true)) { // don't allow to create new thread, because the new thread limit was already reached set_param('action', 'view'); } } // Load classes load_class('messaging/model/_thread.class.php', 'Thread'); load_class('messaging/model/_message.class.php', 'Message'); // Get action parameter from request: $action = param_action('view'); switch ($action) { case 'new': // Check permission: $current_User->check_perm('perm_messaging', 'reply', true); global $edited_Thread, $edited_Message; $edited_Thread = new Thread(); $edited_Message = new Message(); $edited_Message->Thread =& $edited_Thread; modules_call_method('update_new_thread', array('Thread' => &$edited_Thread)); if (($unsaved_message_params = get_message_params_from_session()) !== NULL) { // set Message and Thread saved params from Session $edited_Message->text = $unsaved_message_params['message']; $edited_Message->original_text = $unsaved_message_params['message_original']; $edited_Message->set_renderers($unsaved_message_params['renderers']); $edited_Thread->title = $unsaved_message_params['subject']; $edited_Thread->recipients = $unsaved_message_params['thrd_recipients']; $edited_Message->Thread = $edited_Thread; global $thrd_recipients_array, $thrdtype, $action, $creating_success; $thrd_recipients_array = $unsaved_message_params['thrd_recipients_array']; $thrdtype = $unsaved_message_params['thrdtype']; $action = $unsaved_message_params['action']; $creating_success = !empty($unsaved_message_params['creating_success']) ? $unsaved_message_params['creating_success'] : false; } else { if (empty($edited_Thread->recipients)) { $edited_Thread->recipients = param('thrd_recipients', 'string', ''); } if (empty($edited_Thread->title)) { $edited_Thread->title = param('subject', 'string', ''); } } break; default: // Check permission: $current_User->check_perm('perm_messaging', 'reply', true); break; } break; } // Actions for disp = messages, contacts, threads: if (($msg_Blog =& get_setting_Blog('msg_blog_ID')) && $Blog->ID != $msg_Blog->ID) { // Redirect to special blog for messaging actions if it is defined in general settings $blog_url_params = array('glue' => '&'); if (!empty($thrd_ID)) { // Don't forget the important param on redirect $blog_url_params['url_suffix'] = 'thrd_ID=' . $thrd_ID; } header_redirect($msg_Blog->get($disp . 'url', $blog_url_params)); } // just in case some robot would be logged in: $seo_page_type = 'Messaging module'; $robots_index = false; // Display messages depending on user email status display_user_email_status_message(); break; case 'login': global $Plugins, $transmit_hashed_password; if (is_logged_in()) { // User is already logged in if ($current_User->check_status('can_be_validated')) { // account is not active yet, redirect to the account activation page $Messages->add(T_('You are logged in but your account is not activated. You will find instructions about activating your account below:')); header_redirect(get_activate_info_url(), 302); // will have exited } // User is already logged in, redirect to "redirect_to" page $Messages->add(T_('You are already logged in.'), 'note'); $redirect_to = param('redirect_to', 'url', NULL); if (empty($redirect_to)) { // If empty redirect to referer page $redirect_to = ''; } header_redirect($redirect_to, 302); // will have exited } if (($login_Blog =& get_setting_Blog('login_blog_ID')) && $Blog->ID != $login_Blog->ID) { // Redirect to special blog for login/register actions if it is defined in general settings header_redirect($login_Blog->get('loginurl', array('glue' => '&'))); } $seo_page_type = 'Login form'; $robots_index = false; break; case 'register': if (is_logged_in()) { // If user is logged in the register form should not be displayed. In this case redirect to the blog home page. $Messages->add(T_('You are already logged in.'), 'note'); header_redirect($Blog->gen_blogurl(), false); } if (($login_Blog =& get_setting_Blog('login_blog_ID')) && $Blog->ID != $login_Blog->ID) { // Redirect to special blog for login/register actions if it is defined in general settings header_redirect($login_Blog->get('registerurl', array('glue' => '&'))); } $seo_page_type = 'Register form'; $robots_index = false; // Check invitation code if it exists and registration is enabled global $display_invitation; $display_invitation = check_invitation_code(); break; case 'lostpassword': if (is_logged_in()) { // If user is logged in the lost password form should not be displayed. In this case redirect to the blog home page. $Messages->add(T_('You are already logged in.'), 'note'); header_redirect($Blog->gen_blogurl(), false); } if (($login_Blog =& get_setting_Blog('login_blog_ID')) && $Blog->ID != $login_Blog->ID) { // Redirect to special blog for login/register actions if it is defined in general settings header_redirect($login_Blog->get('lostpasswordurl', array('glue' => '&'))); } $seo_page_type = 'Lost password form'; $robots_index = false; break; case 'activateinfo': if (!is_logged_in()) { // Redirect to the login page for anonymous users $Messages->add(T_('You must log in before you can activate your account.')); header_redirect(get_login_url('cannot see messages'), 302); // will have exited } if (!$current_User->check_status('can_be_validated')) { // don't display activateinfo screen $after_email_validation = $Settings->get('after_email_validation'); if ($after_email_validation == 'return_to_original') { // we want to return to original page after account activation // check if Session 'validatemail.redirect_to' param is still set $redirect_to = $Session->get('core.validatemail.redirect_to'); if (empty($redirect_to)) { // Session param is empty try to get general redirect_to param $redirect_to = param('redirect_to', 'url', ''); } else { // cleanup validateemail.redirect_to param from session $Session->delete('core.validatemail.redirect_to'); } } else { // go to after email validation url which is set in the user general settings form $redirect_to = $after_email_validation; } if (empty($redirect_to) || preg_match('#disp=activateinfo#', $redirect_to)) { // redirect_to is pointing to the activate info display or is empty // redirect to referer page $redirect_to = ''; } if ($current_User->check_status('is_validated')) { $Messages->add(T_('Your account has already been activated.')); } header_redirect($redirect_to, 302); // will have exited } if (($login_Blog =& get_setting_Blog('login_blog_ID')) && $Blog->ID != $login_Blog->ID) { // Redirect to special blog for login/register actions if it is defined in general settings header_redirect($login_Blog->get('activateinfourl', array('glue' => '&'))); } break; case 'profile': case 'avatar': $action = param_action(); if ($action == 'crop' && is_logged_in()) { // Check data for crop action: global $current_User, $cropped_File; $file_ID = param('file_ID', 'integer'); if (!($cropped_File = $current_User->get_File_by_ID($file_ID, $error_code))) { // Current user cannot crop this file set_param('action', ''); } } case 'pwdchange': case 'userprefs': case 'subs': $seo_page_type = 'Special feature page'; if ($Blog->get_setting('special_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } // Display messages depending on user email status display_user_email_status_message(); break; case 'users': if (!is_logged_in() && !$Settings->get('allow_anonymous_user_list')) { // Redirect to the login page if not logged in and allow anonymous user setting is OFF $Messages->add(T_('You must log in to view the user directory.')); header_redirect(get_login_url('cannot see user'), 302); // will have exited } if (is_logged_in() && !check_user_status('can_view_users')) { // user status doesn't permit to view users list if (check_user_status('can_be_validated')) { // user is logged in but his/her account is not active yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can view the user directory. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } // set where to redirect $error_redirect_to = empty($Blog) ? $baseurl : $Blog->gen_blogurl(); $Messages->add(T_('Your account status currently does not permit to view the user directory.')); header_redirect($error_redirect_to, 302); // will have exited } if (has_cross_country_restriction('users', 'list') && empty($current_User->ctry_ID)) { // User may browse other users only from the same country $Messages->add(T_('Please specify your country before attempting to contact other users.')); header_redirect(get_user_profile_url()); } $seo_page_type = 'Users list'; $robots_index = false; break; case 'user': // get user_ID because we want it in redirect_to in case we need to ask for login. $user_ID = param('user_ID', 'integer', '', true); // set where to redirect in case of error $error_redirect_to = empty($Blog) ? $baseurl : $Blog->gen_blogurl(); if (!is_logged_in()) { // Redirect to the login page if not logged in and allow anonymous user setting is OFF $user_available_by_group_level = true; if (!empty($user_ID)) { $UserCache =& get_UserCache(); if ($User =& $UserCache->get_by_ID($user_ID, false)) { // If user exists we can check if the anonymous users have an access to view the user by group level limitation $User->get_Group(); $user_available_by_group_level = $User->Group->level >= $Settings->get('allow_anonymous_user_level_min') && $User->Group->level <= $Settings->get('allow_anonymous_user_level_max'); } } if (!$Settings->get('allow_anonymous_user_profiles') || !$user_available_by_group_level || empty($user_ID)) { // If this user is not available for anonymous users $Messages->add(T_('You must log in to view this user profile.')); header_redirect(get_login_url('cannot see user'), 302); // will have exited } } if (is_logged_in() && !check_user_status('can_view_user', $user_ID)) { // user is logged in, but his/her status doesn't permit to view user profile if (check_user_status('can_be_validated')) { // user is logged in but his/her account is not active yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can view this user profile. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } $Messages->add(T_('Your account status currently does not permit to view this user profile.')); header_redirect($error_redirect_to, 302); // will have exited } if (!empty($user_ID)) { $UserCache =& get_UserCache(); $User =& $UserCache->get_by_ID($user_ID, false); if (empty($User)) { $Messages->add(T_('The requested user does not exist!')); header_redirect($error_redirect_to); // will have exited } if ($User->check_status('is_closed')) { $Messages->add(T_('The requested user account is closed!')); header_redirect($error_redirect_to); // will have exited } if (has_cross_country_restriction('any')) { if (empty($current_User->ctry_ID)) { // Current User country is not set $Messages->add(T_('Please specify your country before attempting to contact other users.')); header_redirect(get_user_profile_url()); // will have exited } if (has_cross_country_restriction('users', 'profile') && $current_User->ctry_ID !== $User->ctry_ID) { // Current user country is different then edited user country and cross country user browsing is not enabled. $Messages->add(T_('You don\'t have permission to view this user profile.')); header_redirect(url_add_param($error_redirect_to, 'disp=403', '&')); // will have exited } } } // Initialize users list from session cache in order to display prev/next links: // It is used to navigate between users load_class('users/model/_userlist.class.php', 'UserList'); global $UserList; $UserList = new UserList(); $UserList->memorize = false; $UserList->load_from_Request(); $seo_page_type = 'User display'; break; case 'edit': global $current_User, $post_ID; // Post ID, go from $_GET when we edit a post from Front-office // or from $_POST when we switch from Back-office $post_ID = param('p', 'integer', empty($post_ID) ? 0 : $post_ID, true); if (!is_logged_in()) { // Redirect to the login page if not logged in and allow anonymous user setting is OFF $redirect_to = url_add_param($Blog->gen_blogurl(), 'disp=edit'); $Messages->add(T_('You must log in to create & edit posts.')); header_redirect(get_login_url('cannot edit posts', $redirect_to), 302); // will have exited } if (!$current_User->check_status('can_edit_post')) { if ($current_User->check_status('can_be_validated')) { // user is logged in but his/her account was not activated yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can create & edit posts. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } // Redirect to the blog url for users without messaging permission $Messages->add(T_('You are not allowed to create & edit posts!')); header_redirect($Blog->gen_blogurl(), 302); } // user logged in and the account was activated check_item_perm_edit($post_ID); if (!blog_has_cats($Blog->ID)) { // No categories are in this blog $error_message = T_('Since this blog has no categories, you cannot post into it.'); if ($current_User->check_perm('blog_cats', 'edit', false, $Blog->ID)) { // If current user has a permission to create a category global $admin_url; $error_message .= ' ' . sprintf(T_('You must <a %s>create categories</a> first.'), 'href="' . $admin_url . '?ctrl=chapters&blog=' . $Blog->ID . '"'); } $Messages->add($error_message, 'error'); header_redirect($Blog->gen_blogurl(), 302); } // Prepare the 'In-skin editing': init_inskin_editing(); break; case 'edit_comment': global $current_User, $edited_Comment, $comment_Item, $Item, $comment_title, $comment_content, $display_params; // comment ID $comment_ID = param('c', 'integer', 0, true); if (!is_logged_in()) { // Redirect to the login page if not logged in and allow anonymous user setting is OFF $redirect_to = url_add_param($Blog->gen_blogurl(), 'disp=edit_comment'); $Messages->add(T_('You must log in to edit comments.')); header_redirect(get_login_url('cannot edit comments', $redirect_to), 302); // will have exited } if (!$current_User->check_status('can_edit_comment')) { if ($current_User->check_status('can_be_validated')) { // user is logged in but his/her account was not activated yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can edit comments. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } // Redirect to the blog url for users without messaging permission $Messages->add('You are not allowed to edit comments!'); header_redirect($Blog->gen_blogurl(), 302); } if (empty($comment_ID)) { // Can't edit a not exisiting comment $Messages->add('Invalid comment edit URL!'); global $disp; $disp = 404; break; } $CommentCache =& get_CommentCache(); $edited_Comment = $CommentCache->get_by_ID($comment_ID); $comment_Item = $edited_Comment->get_Item(); if (!$current_User->check_perm('comment!CURSTATUS', 'edit', false, $edited_Comment)) { // If User has no permission to edit comments with this comment status: $Messages->add('You are not allowed to edit the previously selected comment!'); header_redirect($Blog->gen_blogurl(), 302); } $comment_title = ''; $comment_content = htmlspecialchars_decode($edited_Comment->content); // Format content for editing, if we were not already in editing... $Plugins_admin =& get_Plugins_admin(); $comment_Item->load_Blog(); $params = array('object_type' => 'Comment', 'object_Blog' => &$comment_Item->Blog); $Plugins_admin->unfilter_contents($comment_title, $comment_content, $edited_Comment->get_renderers_validated(), $params); $Item = $comment_Item; $display_params = array(); break; case 'useritems': case 'usercomments': global $display_params, $viewed_User; // get user_ID because we want it in redirect_to in case we need to ask for login. $user_ID = param('user_ID', 'integer', true, true); if (empty($user_ID)) { bad_request_die(sprintf(T_('Parameter «%s» is required!'), 'user_ID')); } // set where to redirect in case of error $error_redirect_to = empty($Blog) ? $baseurl : $Blog->gen_blogurl(); if (!is_logged_in()) { // Redirect to the login page if not logged in and allow anonymous user setting is OFF $Messages->add(T_('You must log in to view this user profile.')); header_redirect(get_login_url('cannot see user'), 302); // will have exited } if (is_logged_in() && !check_user_status('can_view_user', $user_ID)) { // user is logged in, but his/her status doesn't permit to view user profile if (check_user_status('can_be_validated')) { // user is logged in but his/her account is not active yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can view this user profile. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } $Messages->add(T_('Your account status currently does not permit to view this user profile.')); header_redirect($error_redirect_to, 302); // will have exited } if (!empty($user_ID)) { $UserCache =& get_UserCache(); $viewed_User = $UserCache->get_by_ID($user_ID, false); if (empty($viewed_User)) { $Messages->add(T_('The requested user does not exist!')); header_redirect($error_redirect_to); // will have exited } if ($viewed_User->check_status('is_closed')) { $Messages->add(T_('The requested user account is closed!')); header_redirect($error_redirect_to); // will have exited } } $display_params = !empty($Skin) ? $Skin->get_template('Results') : NULL; if ($disp == 'useritems') { // Init items list global $user_ItemList; $useritems_Blog = NULL; $user_ItemList = new ItemList2($useritems_Blog, NULL, NULL, NULL, 'ItemCache', 'useritems_'); $user_ItemList->load_from_Request(); $user_ItemList->set_filters(array('authors' => $user_ID), true, true); $user_ItemList->query(); } else { // Init comments list global $user_CommentList; $user_CommentList = new CommentList2(NULL, NULL, 'CommentCache', 'usercmts_'); $user_CommentList->load_from_Request(); $user_CommentList->set_filters(array('author_IDs' => $user_ID), true, true); $user_CommentList->query(); } break; case 'comments': if (!$Blog->get_setting('comments_latest')) { // If latest comments page is disabled - Display 404 page with error message $Messages->add(T_('This feature is disabled.'), 'error'); global $disp; $disp = '404'; } break; case 'closeaccount': global $current_User; if (!$Settings->get('account_close_enabled') || is_logged_in() && $current_User->check_perm('users', 'edit', false) || !is_logged_in() && !$Session->get('account_closing_success')) { // If an account closing page is disabled - Display 404 page with error message // Don't allow admins close own accounts from front office // Don't display this message for not logged in users, except of one case to display a bye message after account closing global $disp; $disp = '404'; } elseif ($Session->get('account_closing_success')) { // User has closed the account global $account_closing_success; $account_closing_success = $Session->get('account_closing_success'); // Unset this temp session var to don't display the message twice $Session->delete('account_closing_success'); if (is_logged_in()) { // log out current User logout(); } } break; case 'tags': $seo_page_type = 'Tags'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; } $Debuglog->add('skin_init: $disp=' . $disp . ' / $disp_detail=' . $disp_detail . ' / $seo_page_type=' . $seo_page_type, 'skins'); // Make this switch block special only for 404 page switch ($disp) { case '404': // We have a 404 unresolved content error // How do we want do deal with it? skin_404_header(); // This MAY or MAY not have exited -- will exit on 30x redirect, otherwise will return here. // Just in case some dumb robot needs extra directives on this: $robots_index = false; break; } global $Hit, $check_browser_version; if ($check_browser_version && $Hit->get_browser_version() > 0 && $Hit->is_IE(9, '<')) { // Display info message if browser IE < 9 version and it is allowed by config var: global $debug; $Messages->add(T_('Your web browser is too old. For this site to work correctly, we recommend you use a more recent browser.'), 'note'); if ($debug) { $Messages->add('User Agent: ' . $Hit->get_user_agent(), 'note'); } } // dummy var for backward compatibility with versions < 2.4.1 -- prevents "Undefined variable" global $global_Cache, $credit_links; $credit_links = $global_Cache->get('creds'); $Timer->pause('skin_init'); // Check if user is logged in with a not active account, and display an error message if required check_allow_disp($disp); // initialize Blog enabled widgets, before displaying anything init_blog_widgets($Blog->ID); // Initialize displaying.... $Timer->start('Skin:display_init'); $Skin->display_init(); $Timer->pause('Skin:display_init'); // Send default headers: // See comments inside of this function: headers_content_mightcache('text/html'); // In most situations, you do NOT want to cache dynamic content! // Never allow Messages to be cached! if ($Messages->count() && !empty($PageCache)) { // Abort PageCache collect $PageCache->abort_collect(); } }
/** * Load items by the given categories or collection ID * After the Items are loaded create a map of loaded items by categories * * @param array of category ids * @param integer collection ID * @return boolean true if load items was required and it was loaded successfully, false otherwise */ function load_by_categories($cat_array, $coll_ID) { global $DB, $posttypes_specialtypes; if (empty($cat_array) && empty($coll_ID)) { // Nothing to load return false; } // In case of an empty cat_array param, use categoriesfrom the given collection if (empty($cat_array)) { // Get all categories from the given subset $ChapterCache =& get_ChapterCache(); $subset_chapters = $ChapterCache->get_chapters_by_subset($coll_ID); $cat_array = array(); foreach ($subset_chapters as $Chapter) { $cat_array[] = $Chapter->ID; } } // Check which category is not loaded $not_loaded_cat_ids = array(); foreach ($cat_array as $cat_ID) { if (!isset($this->items_by_cat_map[$cat_ID])) { // This category is not loaded $not_loaded_cat_ids[] = $cat_ID; // Initialize items_by_cat_map for this cat_ID $this->items_by_cat_map[$cat_ID] = array('items' => array(), 'sorted' => false); } } if (empty($not_loaded_cat_ids)) { // Requested categories items are all loaded return false; } // Query to load all Items from the given categories $sql = 'SELECT postcat_cat_ID as cat_ID, postcat_post_ID as post_ID FROM T_postcats WHERE postcat_cat_ID IN ( ' . implode(', ', $not_loaded_cat_ids) . ' ) ORDER BY postcat_post_ID'; $cat_posts = $DB->get_results($sql, ARRAY_A, 'Get all category post ids pair by category'); // Initialize $Blog from coll_ID $BlogCache =& get_BlogCache(); $Blog = $BlogCache->get_by_ID($coll_ID); $visibility_statuses = is_admin_page() ? get_visibility_statuses('keys', array('trash')) : get_inskin_statuses($coll_ID, 'post'); // Create ItemQuery for loading visible items $ItemQuery = new ItemQuery($this->dbtablename, $this->dbprefix, $this->dbIDname); // Set filters what to select $ItemQuery->SELECT($this->dbtablename . '.*'); $ItemQuery->where_chapter2($Blog, $not_loaded_cat_ids, ""); $ItemQuery->where_visibility($visibility_statuses); $ItemQuery->where_datestart(NULL, NULL, NULL, NULL, $Blog->get_timestamp_min(), $Blog->get_timestamp_max()); $ItemQuery->where_types('-' . implode(',', $posttypes_specialtypes)); // Clear previous items from the cache and load by the defined SQL $this->clear(true); $this->load_by_sql($ItemQuery); foreach ($cat_posts as $row) { // Iterate through the post - cat pairs and fill the map if (empty($this->cache[$row['post_ID']])) { // The Item was not loaded because it does not correspond to the defined filters continue; } // Add to the map $this->items_by_cat_map[$row['cat_ID']]['items'][] = $this->get_by_ID($row['post_ID']); } }
/** * Display button to create a new post * * @param integer Chapter ID */ function display_post_button($chapter_ID, $Item = NULL) { global $Blog; $post_button = ''; $chapter_is_locked = false; $write_new_post_url = $Blog->get_write_item_url($chapter_ID); if ($write_new_post_url != '') { // Display button to write a new post $post_button = '<a href="' . $write_new_post_url . '"><span class="ficon newTopic" title="' . T_('Post new topic') . '"></span></a>'; } else { // If a creating of new post is unavailable $ChapterCache =& get_ChapterCache(); $current_Chapter = $ChapterCache->get_by_ID($chapter_ID, false, false); if ($current_Chapter && $current_Chapter->lock) { // Display icon to inform that this forum is locked $post_button = '<span class="ficon locked" title="' . T_('This forum is locked: you cannot post, reply to, or edit topics.') . '"></span>'; $chapter_is_locked = true; } } if (!empty($Item)) { if ($Item->comment_status == 'closed' || $Item->comment_status == 'disabled' || $Item->is_locked()) { // Display icon to inform that this topic is locked for comments if (!$chapter_is_locked) { // Display this button only when chapter is not locked, to avoid a duplicate button $post_button .= ' <span class="ficon locked" title="' . T_('This topic is locked: you cannot edit posts or make replies.') . '"></span>'; } } else { // Display button to post a reply $post_button .= ' <a href="' . $Item->get_feedback_url() . '#form_p' . $Item->ID . '"><span class="ficon postReply" title="' . T_('Reply to topic') . '"></span></a>'; } } if (!empty($post_button)) { // Display button echo '<div class="post_button">'; echo $post_button; echo '</div>'; } }
/** * Get ready for displaying the skin. * * This may register some CSS or JS... */ function display_init() { global $Messages, $disp, $debug; // Request some common features that the parent function (Skin::display_init()) knows how to provide: parent::display_init(array('jquery', 'font_awesome', 'bootstrap', 'bootstrap_evo_css', 'bootstrap_messages', 'style_css', 'colorbox', 'bootstrap_init_tooltips', 'disp_auto')); // Skin specific initializations: // Add custom CSS: $custom_css = ''; // Custom background color: if ($color = $this->get_setting('bg_color')) { $custom_css = 'body { background: ' . $color . " }\n"; } // Custom text color: if ($color = $this->get_setting('text_color')) { $custom_css .= '.main, .content blockquote, .content address, .content p, .content li, .content td, .content dd, .result_content, .search_title, .main textarea { color: ' . $color . " }\n"; } // Custom headings color: if ($color = $this->get_setting('headings_color')) { $custom_css .= '.content h1, .content h2, .content h3, .content h4, .content h5, .content h6, .content cite, .main .title { color: ' . $color . " }\n"; $custom_css .= '.content cite { border-bottom: 2px solid ' . $color . " }\n"; } // Custom link color: if ($color = $this->get_setting('link_color')) { $custom_css .= '.main a, .main .nav > li a, .main .pagination>li>a, .main .panel-default>.panel-heading a, .main .panel-default>.panel-heading .panel-icon, .main .panel-title, .main .evo_post_more_link, .main .evo_comment .panel-heading .evo_comment_title { color: ' . $color . " }\n"; } // Custom link hover color: if ($color = $this->get_setting('link_h_color')) { $custom_css .= '.content a:hover, .color-hover a:hover, .main .nav > li a:hover, .main .pagination>li>a:hover, .main .pagination>li>span:hover, .main .pagination>li.active>span, .main .pager li>a, .main .pager li>span, .profile_column_right .panel-default .panel-heading, .main .panel-title a, .main .evo_post_more_link a, .main .evo_post__excerpt_more_link a, .main .evo_comment .panel-heading a:hover, .main .evo_comment .panel-heading a, profile_column_left h1, .profile_column_left .profile_buttons .btn-primary, .profile_column_left .profile_buttons .btn-primary button, .profile_column_left h1, .main button, .main input.submit, .main input.preview, .main input[type="reset"], .main input[type="submit"] { color: ' . $color . " }\n"; $custom_css .= '#bCalendarToday { background: ' . $color . " }\n"; } // Sections background color: if ($color = $this->get_setting('section_bg')) { $custom_css .= '.main .nav > li a, .main .pager li>a, .main .pager li>span, .featured_post, .main .panel-default>.panel-heading, .main .evo_post_more_link a, .main .evo_post__excerpt_more_link a, .evo_comment_footer small a { background: ' . $color . " }\n"; $custom_css .= '.main .pagination>li>a, .main .pagination>li>span, .small >span, .profile_column_left .profile_buttons .btn-group a, .profile_column_left .profile_buttons p a button, .main .input.submit, .main input[type="button"]:focus, .main input[type="reset"]:focus, .main input[type="submit"]:focus, .main button:active, .main input[type="button"]:active, .main input[type="reset"]:active, .main input[type="submit"]:active, .main input[type="submit"] { background: ' . $color . " !important }\n"; } // Divider color: if ($color = $this->get_setting('divider_color')) { $custom_css .= '.post, .main .panel-group .panel li, .content ul li, .main .evo_comment { border-bottom: 1px solid ' . $color . " }\n"; $custom_css .= '.post, .main .panel-group .panel li ul, .content ul li ul { border-top: 1px solid ' . $color . " }\n"; $custom_css .= 'input[type="text"], input[type="email"], input[type="url"], input[type="password"], input[type="search"], textarea, input[type="text"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="password"]:focus, input[type="search"]:focus, textarea:focus { border: 2px solid ' . $color . " !important }\n"; } // Custom link hover color: if ($color = $this->get_setting('header_bg')) { $custom_css .= '.masterhead { background-color: ' . $color . " }\n"; } // Custom link hover color: if ($color = $this->get_setting('header_color')) { $custom_css .= '.masterhead, .masterhead .widget_core_coll_title a, .masterhead .widget_core_coll_title a:hover { color: ' . $color . "}\n"; } // Limit images by max height: $max_image_height = intval($this->get_setting('max_image_height')); if ($max_image_height > 0) { add_css_headline('.evo_image_block img { max-height: ' . $max_image_height . 'px; width: auto; }'); } // Initialize a template depending on current page switch ($disp) { case 'front': // Init star rating for intro posts: init_ratings_js('blog', true); break; case 'posts': global $cat, $bootstrap_manual_posts_text; // Init star rating for intro posts: init_ratings_js('blog', true); $bootstrap_manual_posts_text = T_('Posts'); if (!empty($cat)) { // Init the <title> for categories page: $ChapterCache =& get_ChapterCache(); if ($Chapter =& $ChapterCache->get_by_ID($cat, false)) { $bootstrap_manual_posts_text = $Chapter->get('name'); } } break; } if ($this->is_left_navigation_visible() && $this->get_setting('left_navigation') == true) { // Include JS code for left navigation panel only when it is displayed: require_js($this->get_url() . 'left_navigation.js'); } // Function for custom css if (!empty($custom_css)) { $custom_css = '<style type="text/css"> <!-- ' . $custom_css . ' --> </style>'; add_headline($custom_css); } }
/** * Get chapters * * @param integer Chapter parent ID */ function get_chapters($parent_ID = 0) { global $Blog, $skin_chapters_cache; if (isset($skin_chapters_cache)) { // Get chapters from cache return $skin_chapters_cache; } $skin_chapters_cache = array(); if ($parent_ID > 0) { // Get children of selected chapter global $DB, $Settings; $skin_chapters_cache = array(); $SQL = new SQL(); $SQL->SELECT('cat_ID'); $SQL->FROM('T_categories'); $SQL->WHERE('cat_parent_ID = ' . $DB->quote($parent_ID)); if ($Settings->get('chapter_ordering') == 'manual') { // Manual order $SQL->ORDER_BY('cat_meta, cat_order'); } else { // Alphabetic order $SQL->ORDER_BY('cat_meta, cat_name'); } $ChapterCache =& get_ChapterCache(); $categories = $DB->get_results($SQL->get()); foreach ($categories as $c => $category) { $skin_chapters_cache[$c] = $ChapterCache->get_by_ID($category->cat_ID); // Get children $SQL->WHERE('cat_parent_ID = ' . $DB->quote($category->cat_ID)); $children = $DB->get_results($SQL->get()); foreach ($children as $child) { $skin_chapters_cache[$c]->children[] = $ChapterCache->get_by_ID($child->cat_ID); } } } else { // Get the all chapters for current blog $ChapterCache =& get_ChapterCache(); $ChapterCache->load_subset($Blog->ID); if (isset($ChapterCache->subset_cache[$Blog->ID])) { $skin_chapters_cache = $ChapterCache->subset_cache[$Blog->ID]; foreach ($skin_chapters_cache as $c => $Chapter) { // Init children foreach ($skin_chapters_cache as $child) { // Again go through all chapters to find a children for current chapter if ($Chapter->ID == $child->get('parent_ID')) { // Add to array of children $skin_chapters_cache[$c]->children[] = $child; } } } foreach ($skin_chapters_cache as $c => $Chapter) { // Unset the child chapters if ($Chapter->get('parent_ID')) { unset($skin_chapters_cache[$c]); } } } } return $skin_chapters_cache; }
/** * Display chapters list * * @param array Params */ function manual_display_chapters($params = array()) { global $Blog, $blog, $cat_ID; if (empty($Blog) && !empty($blog)) { // Set Blog if it still doesn't exist $BlogCache =& get_BlogCache(); $Blog =& $BlogCache->get_by_ID($blog, false); } if (empty($Blog)) { // No Blog, Exit here return; } $ChapterCache =& get_ChapterCache(); $chapter_path = array(); if (!empty($cat_ID)) { // A category is opened $chapter_path = $ChapterCache->get_chapter_path($Blog->ID, $cat_ID); } $callbacks = array('line' => 'manual_display_chapter_row', 'posts' => 'manual_display_post_row'); $params = array_merge(array('sorted' => true, 'expand_all' => false, 'chapter_path' => $chapter_path), $params); $ChapterCache->recurse($callbacks, $Blog->ID, NULL, 0, 0, $params); }
/** * Callback: Generate category line when it has children * * @param object Chapter we want to display * @param integer Level of the category in the recursive tree * @return string HTML */ function cat_line($Chapter, $level) { global $cat_array; if (!isset($cat_array)) { $cat_array = array(); } $exclude_cats = sanitize_id_list($this->disp_params['exclude_cats'], true); if (in_array($Chapter->ID, $exclude_cats)) { // Cat ID is excluded, skip it return; } // ID of the current selected category $first_selected_cat_ID = isset($cat_array[0]) ? $cat_array[0] : 0; if (!isset($this->disp_params['current_parents'])) { // Try to find the parent categories in order to select it because of widget setting is enabled $this->disp_params['current_all_cats'] = array(); // All children of the root parent of the selcted category $this->disp_params['current_parents'] = array(); // All parents of the selected category $this->disp_params['current_selected_level'] = 0; // Level of the selected category if ($first_selected_cat_ID > 0) { $this->disp_params['current_selected_level'] = $this->disp_params['current_selected_level'] + 1; $ChapterCache =& get_ChapterCache(); $parent_Chapter =& $ChapterCache->get_by_ID($first_selected_cat_ID, false, false); while ($parent_Chapter !== NULL) { // Go up to the first/root category $root_parent_ID = $parent_Chapter->ID; if ($parent_Chapter =& $parent_Chapter->get_parent_Chapter()) { $this->disp_params['current_parents'][] = $parent_Chapter->ID; $this->disp_params['current_all_cats'][] = $parent_Chapter->ID; $this->disp_params['current_selected_level'] = $this->disp_params['current_selected_level'] + 1; } } // Load all categories of the current selected path (these categories should be visible on page) $this->disp_params['current_all_cats'] = $cat_array; $this->load_category_children($root_parent_ID, $this->disp_params['current_all_cats'], $this->disp_params['current_parents']); } } $parent_cat_is_visible = isset($this->disp_params['parent_cat_is_visible']) ? $this->disp_params['parent_cat_is_visible'] : false; $start_level = intval($this->disp_params['start_level']); if ($start_level > 1 && ($start_level > $level + 1 || !in_array($Chapter->ID, $this->disp_params['current_all_cats']) && !$this->disp_params['parent_cat_is_visible'] || $this->disp_params['current_selected_level'] < $level && !$this->disp_params['parent_cat_is_visible'])) { // Don't show this item because of level restriction $this->disp_params['parent_cat_is_visible'] = false; //return '<span style="font-size:10px">hidden: ('.$level.'|'.$this->disp_params['current_selected_level'].')</span>'; return ''; } elseif (!isset($this->disp_params['current_cat_level'])) { // Save level of the current selected category $this->disp_params['current_cat_level'] = $level; $this->disp_params['parent_cat_is_visible'] = true; } if ($this->disp_params['mark_first_selected'] && $Chapter->ID == $first_selected_cat_ID || $this->disp_params['mark_children'] && $Chapter->ID != $first_selected_cat_ID && in_array($Chapter->ID, $cat_array) || $this->disp_params['mark_parents'] && $Chapter->ID != $first_selected_cat_ID && in_array($Chapter->ID, $this->disp_params['current_parents'])) { // This category should be selected $start_tag = $this->disp_params['item_selected_start']; } else { if (empty($Chapter->children)) { // This category has no children $start_tag = $this->disp_params['item_last_start']; } else { $start_tag = $this->disp_params['item_start']; } } if ($Chapter->meta) { // Add class name "meta" for meta categories $start_tag = $this->add_cat_class_attr($start_tag, 'meta'); } $r = $start_tag; if ($this->disp_params['use_form'] || $this->disp_params['display_checkboxes']) { // We want to add form fields: $cat_checkbox_params = ''; if ($Chapter->meta) { // Disable the checkbox of meta category ( and hide it by css ) $cat_checkbox_params = ' disabled="disabled"'; } $r .= '<label><input type="checkbox" name="catsel[]" value="' . $Chapter->ID . '" class="checkbox middle"'; if (in_array($Chapter->ID, $cat_array)) { // This category is in the current selection $r .= ' checked="checked"'; } $r .= $cat_checkbox_params . ' /> '; } $cat_name = $Chapter->dget('name'); if ($Chapter->lock && isset($this->disp_params['show_locked']) && $this->disp_params['show_locked']) { $cat_name .= '<span style="padding:0 5px;" >' . get_icon('file_not_allowed', 'imgtag', array('title' => T_('Locked'))) . '</span>'; } // Make a link from category name $r .= '<a href="'; if ($this->disp_params['link_type'] == 'context') { // We want to preserve current browsing context: $r .= regenerate_url('cats,catsel', 'cat=' . $Chapter->ID); } else { $r .= $Chapter->get_permanent_url(); } $r .= '">' . $cat_name . '</a>'; if ($this->disp_params['use_form'] || $this->disp_params['display_checkboxes']) { // We want to add form fields: $r .= '</label>'; } // End the line even if it has children, since this is the end of one single item // To close the whole group of categories with all of it's children see @cat_before_level and @cat_after_level // Note: If this solution will not work, and we can't add the 'item_end' here, then create new after_line callback, // which then must be called from a the ChapterCache recurse method $r .= $this->disp_params['item_end']; return $r; }
/** * Get name for a given cat ID. * * @return string Cat name in case of success, false on failure. */ function get_catname($cat_ID) { $ChapterCache =& get_ChapterCache(); $Chapter =& $ChapterCache->get_by_ID($cat_ID); return $Chapter->name; }
/** * */ function &get_parent_Chapter() { if (!isset($this->parent_Chapter)) { // Not resoleved yet! if (empty($this->parent_ID)) { $this->parent_Chapter = NULL; } else { $ChapterCache =& get_ChapterCache(); $this->parent_Chapter =& $ChapterCache->get_by_ID($this->parent_ID, false); } } return $this->parent_Chapter; }
/** * Get ready for displaying the skin. * * This may register some CSS or JS... */ function display_init() { global $Messages, $disp, $debug; // Request some common features that the parent function (Skin::display_init()) knows how to provide: parent::display_init(array('jquery', 'font_awesome', 'bootstrap', 'bootstrap_evo_css', 'bootstrap_messages', 'style_css', 'colorbox', 'bootstrap_init_tooltips', 'disp_auto')); // Skin specific initializations: // Limit images by max height: $max_image_height = intval($this->get_setting('max_image_height')); if ($max_image_height > 0) { add_css_headline('.evo_image_block img { max-height: ' . $max_image_height . 'px; width: auto; }'); } // Initialize a template depending on current page switch ($disp) { case 'front': // Init star rating for intro posts: init_ratings_js('blog', true); break; case 'posts': global $cat, $bootstrap_manual_posts_text; // Init star rating for intro posts: init_ratings_js('blog', true); $bootstrap_manual_posts_text = T_('Posts'); if (!empty($cat)) { // Init the <title> for categories page: $ChapterCache =& get_ChapterCache(); if ($Chapter =& $ChapterCache->get_by_ID($cat, false)) { $bootstrap_manual_posts_text = $Chapter->get('name'); } } break; } if ($this->is_left_navigation_visible()) { // Include JS code for left navigation panel only when it is displayed: require_js($this->get_url() . 'left_navigation.js'); } }
/** * Display the widget! * * @param array MUST contain at least the basic display params */ function display($params) { global $cat_modifier; global $Blog; $this->init_display($params); /** * @var ChapterCache */ $ChapterCache =& get_ChapterCache(); $callbacks = array('line' => array($this, 'cat_line'), 'no_children' => array($this, 'cat_no_children'), 'before_level' => array($this, 'cat_before_level'), 'after_level' => array($this, 'cat_after_level')); if (!empty($params['callback_posts'])) { $callbacks['posts'] = $params['callback_posts']; } // START DISPLAY: echo $this->disp_params['block_start']; // Display title if requested $this->disp_title(); if ($this->disp_params['use_form']) { // We want a complete form: echo '<form method="get" action="' . $Blog->gen_blogurl() . '">'; } $aggregate_coll_IDs = $Blog->get_setting('aggregate_coll_IDs'); if (empty($aggregate_coll_IDs)) { // ____________________ We want to display cats for ONE blog ____________________ $tmp_disp = ''; if ($this->disp_params['option_all']) { // We want to display a link to all cats: $tmp_disp .= $this->disp_params['item_start'] . '<a href="'; if ($this->disp_params['link_type'] == 'context') { // We want to preserve current browsing context: $tmp_disp .= regenerate_url('cats,catsel'); } else { $tmp_disp .= $Blog->gen_blogurl(); } $tmp_disp .= '">' . $this->disp_params['option_all'] . '</a>'; $tmp_disp .= $this->disp_params['item_end']; } $r = $tmp_disp . $ChapterCache->recurse($callbacks, $Blog->ID); if (!empty($r)) { echo $this->disp_params['list_start']; echo $r; echo $this->disp_params['list_end']; } } else { // ____________________ We want to display cats for SEVERAL blogs ____________________ $BlogCache =& get_BlogCache(); // Make sure everything is loaded at once (vs multiple queries) // fp> TODO: scaling $ChapterCache->load_all(); echo $this->disp_params['collist_start']; if ($aggregate_coll_IDs == '*') { $BlogCache->load_all(); $coll_ID_array = $BlogCache->get_ID_array(); } else { $coll_ID_array = sanitize_id_list($aggregate_coll_IDs, true); } foreach ($coll_ID_array as $curr_blog_ID) { // Get blog: $loop_Blog =& $BlogCache->get_by_ID($curr_blog_ID, false); if (empty($loop_Blog)) { // That one doesn't exist (any more?) continue; } // Display blog title, if requested: if ($this->disp_params['disp_names_for_coll_list']) { echo $this->disp_params['coll_start']; echo '<a href="'; if ($this->disp_params['link_type'] == 'context') { // We want to preserve current browsing context: echo regenerate_url('blog,cats,catsel', 'blog=' . $curr_blog_ID); } else { $loop_Blog->disp('url', 'raw'); } echo '">'; $loop_Blog->disp('name'); echo '</a>'; echo $this->disp_params['coll_end']; } $r = $ChapterCache->recurse($callbacks, $curr_blog_ID); if (!empty($r)) { echo $this->disp_params['list_start']; echo $r; echo $this->disp_params['list_end']; } } } if ($this->disp_params['use_form'] || $this->disp_params['display_checkboxes']) { // We want to add form fields: ?> <div class="tile"> <input type="radio" name="cat" value="" id="catANY" class="radio" <?php if ($cat_modifier != '-' && $cat_modifier != '*') { echo 'checked="checked" '; } ?> /> <label for="catANY"><?php echo T_('ANY'); ?> </label> </div> <div class="tile"> <input type="radio" name="cat" value="-" id="catANYBUT" class="radio" <?php if ($cat_modifier == '-') { echo 'checked="checked" '; } ?> /> <label for="catANYBUT"><?php echo T_('ANY BUT'); ?> </label> </div> <div class="tile"> <input type="radio" name="cat" value="*" id="catALL" class="radio" <?php if ($cat_modifier == '*') { echo 'checked="checked" '; } ?> /> <label for="catALL"><?php echo T_('ALL'); ?> </label> </div> <?php if ($this->disp_params['use_form']) { // We want a complete form: ?> <div class="tile"> <input type="submit" value="<?php echo T_('Filter categories'); ?> " /> </div> </form> <?php } } echo $this->disp_params['block_end']; return true; }
function cats_optionslist($forcat) { global $cache_blogs, $cache_optionslist, $cat_name_id_associations; if (!isset($cat_name_id_associations)) { // Create a map fro the category name-id associations to populate during optionlist initialization $cat_name_id_associations = array(); } if (!isset($cache_optionslist)) { $ChapterCache =& get_ChapterCache(); $ChapterCache->reveal_children(NULL, true); $callbacks = array('line' => 'proces_cat_line'); $cache_optionslist = ''; foreach ($cache_blogs as $i_blog) { $cache_optionslist .= '<option value="#NEW#' . $i_blog->blog_ID . '">[-- create in blog ' . $i_blog->blog_shortname . ' --]:</option>'; $cache_optionslist .= $ChapterCache->recurse($callbacks, $i_blog->blog_ID, NULL, 0, 0, array('sorted' => true)); } } $cat_id = isset($cat_name_id_associations[$forcat]) ? $cat_name_id_associations[$forcat] : false; if ($cat_id) { echo str_replace('<option value="' . $cat_id . '">', '<option value="' . $cat_id . '" selected="selected">', $cache_optionslist); } else { echo $cache_optionslist; } }
/** * Compiles the cat array from $cat (recursive + optional modifiers) and $catsel[] (non recursive) * * @param string * @param array * @param array by ref, will be modified * @param string by ref, will be modified * @param integer blog number to restrict to */ function compile_cat_array($cat, $catsel, &$cat_array, &$cat_modifier, $restrict_to_blog = 0) { // echo '$cat='.$cat; // pre_dump( $catsel ); // echo '$restrict_to_blog'.$restrict_to_blog; $cat_array = array(); $cat_modifier = ''; // Check for cat string (which will be handled recursively) if ($cat != 'all' && !empty($cat)) { // specified a category string: $cat_modifier = substr($cat, 0, 1); // echo 'cats['.$first_char.']'; if ($cat_modifier == '*' || $cat_modifier == '-' || $cat_modifier == '|') { $cat = substr($cat, 1); } else { $cat_modifier = ''; } if (strlen($cat)) { // There are some values to explode... $req_cat_array = explode(',', $cat); // Getting required sub-categories: // and add everything to cat array // ----------------- START RECURSIVE CAT LIST ---------------- $ChapterCache =& get_ChapterCache(); if ($restrict_to_blog > 0) { // Load all Chapters from the given blog $ChapterCache->reveal_children($restrict_to_blog, true); } else { // Load all chapters $ChapterCache->reveal_children(NULL, true); } foreach ($req_cat_array as $cat_ID) { // run recursively through the cats $current_Chapter = $ChapterCache->get_by_ID($cat_ID, false); if (empty($current_Chapter)) { // The requested Chapter doesn't exists in the given context continue; } if (!in_array($cat_ID, $cat_array)) { // Not already in list $cat_array[] = $cat_ID; $ChapterCache->iterate_through_category_children($current_Chapter, array('line' => 'cat_req'), true, array('sorted' => true)); } } // ----------------- END RECURSIVE CAT LIST ---------------- } } // Add explicit selections: if (!empty($catsel)) { // echo "Explicit selections!<br />"; $cat_array = array_merge($cat_array, $catsel); $cat_array = array_unique($cat_array); } // echo '$cat_modifier='.$cat_modifier; // pre_dump( $cat_array ); }
/** * Delete the comments * * @param string Type of deleting: * 'recycle' - to move into recycle bin * 'delete' - to delete permanently * @param string sql query to get deletable comment ids */ function comment_mass_delete_process($mass_type, $deletable_comments_query) { if ($mass_type != 'recycle' && $mass_type != 'delete') { // Incorrect action return; } global $DB, $cache_comments_has_replies, $user_post_read_statuses, $cache_postcats; /** * Disable log queries because it increases the memory and stops the process with error "Allowed memory size of X bytes exhausted..." */ $DB->log_queries = false; $Form = new Form(); $Form->begin_form('fform'); $Form->begin_fieldset(T_('Mass deleting log')); echo T_('The comments are deleting...'); evo_flush(); $CommentCache =& get_CommentCache(); $ItemCache =& get_ItemCache(); $ChapterCache =& get_ChapterCache(); // Get the comments by 1000 to avoid an exhausting of memory $deletable_comment_ids = $DB->get_col($deletable_comments_query . ' LIMIT 1000'); while (!empty($deletable_comment_ids)) { // Get the first slice of the deletable comment ids list $ids = array_splice($deletable_comment_ids, 0, 100); // Make sure the CommentCache is empty $CommentCache->clear(); // Load deletable comment ids $CommentCache->load_list($ids); while (($iterator_Comment =& $CommentCache->get_next()) != NULL) { // Delete all comments from CommentCache $iterator_Comment->dbdelete($mass_type == 'delete'); } // Display progress dot echo ' .'; evo_flush(); if (empty($deletable_comment_ids)) { // Clear all caches to save memory $ItemCache->clear(); $ChapterCache->clear(); $cache_comments_has_replies = array(); $user_post_read_statuses = array(); $cache_postcats = array(); // Get new portion of deletable comments $deletable_comment_ids = $DB->get_col($deletable_comments_query . ' LIMIT 1000'); } } echo ' OK'; $Form->end_form(); // Clear a comment cache $CommentCache->clear(); }
/** * Get an array with chapters ID that located in current path * * @param integer Chapter ID * @return array Chapters ID */ function manual_get_chapter_path($chapter_ID) { global $blog; $ChapterCache =& get_ChapterCache(); $ChapterCache->load_subset($blog); $chapter_path = array($chapter_ID); if (isset($ChapterCache->subset_cache[$blog])) { $chapters = $ChapterCache->subset_cache[$blog]; if (isset($chapters[$chapter_ID])) { $Chapter = $chapters[$chapter_ID]; while ($Chapter->get('parent_ID') > 0) { $chapter_path[] = $Chapter->get('parent_ID'); // Select a parent chapter $Chapter = $chapters[$Chapter->get('parent_ID')]; } } } return $chapter_path; }
/** * Create a new Item/Post and insert it into the DB * * This function has to handle all needed DB dependencies! * * @deprecated Use set() + dbinsert() instead */ function insert($author_user_ID, $post_title, $post_content, $post_timestamp, $main_cat_ID = 1, $extra_cat_IDs = array(), $post_status = 'published', $post_locale = '#', $post_urltitle = '', $post_url = '', $post_comment_status = 'open', $post_renderers = array('default'), $item_typ_ID = 1, $item_st_ID = NULL, $post_order = NULL) { global $DB, $query, $UserCache; global $default_locale; if ($item_typ_ID == 1) { // Try to set default post type ID from blog setting $ChapterCache =& get_ChapterCache(); if (($Chapter =& $ChapterCache->get_by_ID($main_cat_ID, false, false)) && ($Blog =& $Chapter->get_Blog())) { // Use default post type what used for the blog $item_typ_ID = $Blog->get_setting('default_post_type'); } } if ($post_locale == '#') { $post_locale = $default_locale; } // echo 'INSERTING NEW POST '; if (isset($UserCache)) { // If not in install procedure... $this->set_creator_User($UserCache->get_by_ID($author_user_ID)); } else { $this->set($this->creator_field, $author_user_ID); } $this->set($this->lasteditor_field, $this->{$this->creator_field}); $this->set('title', $post_title); $this->set('urltitle', $post_urltitle); $this->set('content', $post_content); $this->set('datestart', $post_timestamp); $this->set('main_cat_ID', $main_cat_ID); $this->set('extra_cat_IDs', $extra_cat_IDs); $this->set('status', $post_status); $this->set('locale', $post_locale); $this->set('url', $post_url); $this->set('comment_status', $post_comment_status); $this->set_renderers($post_renderers); $this->set('ityp_ID', $item_typ_ID); $this->set('pst_ID', $item_st_ID); $this->set('order', $post_order); // INSERT INTO DB: $this->dbinsert(); return $this->ID; }
/** * Get url to redirect after chapter editing * * @param string Redirect Page: 'front', 'manual', 'list' * @param integer Parent ID * @param integer Chapter ID * @return string URL */ function get_chapter_redirect_url($redirect_page, $parent_ID, $chapter_ID = 0) { global $admin_url, $blog; if ($redirect_page == 'front' || $redirect_page == 'parent') { // Get Chapter for front page redirect if (empty($chapter_ID)) { // Chapter ID is invalid, redirect to chapters list $redirect_page = 'list'; } else { $ChapterCache =& get_ChapterCache(); $Chapter =& $ChapterCache->get_by_ID($chapter_ID, false, false); if ($Chapter === false) { // Chapter doesn't exist anymore, redirect to chapters list $redirect_page = 'list'; } } } switch ($redirect_page) { case 'parent': // Redirect to parent chapter on front-office: if ($parent_Chapter =& $Chapter->get_parent_Chapter()) { // If $redirect_url = $parent_Chapter->get_permanent_url(NULL, NULL, 1, NULL, '&'); break; } // else redirect to permanent url of current chapter: // else redirect to permanent url of current chapter: case 'front': // Redirect to front-office $redirect_url = $Chapter->get_permanent_url(NULL, NULL, 1, NULL, '&'); break; case 'manual': // Redirect to manual pages $redirect_url = $admin_url . '?ctrl=items&blog=' . $blog . '&tab=manual'; if (!empty($parent_ID)) { // Open parent category to display new created category $redirect_url .= '&cat_ID=' . $parent_ID; } break; default: // 'list' // Redirect to chapters list $redirect_url = $admin_url . '?ctrl=chapters&blog=' . $blog; break; } return $redirect_url; }
/** * Get HTML code of button to create a new post * * @param integer Chapter ID * @param object Item * @return string */ function get_post_button($chapter_ID, $Item = NULL, $params = array()) { global $Blog; $params = array_merge(array('group_class' => '', 'button_class' => ''), $params); $post_button = ''; $chapter_is_locked = false; $write_new_post_url = $Blog->get_write_item_url($chapter_ID); if ($write_new_post_url != '') { // Display button to write a new post $post_button = '<a href="' . $write_new_post_url . '" class="btn btn-primary ' . $params['button_class'] . '" title="' . T_('Post new topic') . '"><i class="fa fa-pencil"></i> ' . T_('New topic') . '</a>'; } else { // If a creating of new post is unavailable $ChapterCache =& get_ChapterCache(); $current_Chapter = $ChapterCache->get_by_ID($chapter_ID, false, false); if ($current_Chapter && $current_Chapter->lock) { // Display icon to inform that this forum is locked $post_button = '<span title="' . T_('This forum is locked: you cannot post, reply to, or edit topics.') . '"><i class="icon fa fa-lock"></i> ' . T_('Locked') . '</span>'; $chapter_is_locked = true; } } if (!empty($Item)) { if ($Item->comment_status == 'closed' || $Item->comment_status == 'disabled' || $Item->is_locked()) { // Display icon to inform that this topic is locked for comments if (!$chapter_is_locked) { // Display this button only when chapter is not locked, to avoid a duplicate button $post_button .= ' <span title="' . T_('This topic is locked: you cannot edit posts or make replies.') . '"><i class="icon fa fa-lock"></i> ' . T_('Locked') . '</span>'; } } else { // Display button to post a reply $post_button .= ' <a href="' . $Item->get_feedback_url() . '#form_p' . $Item->ID . '" class="btn btn-default ' . $params['button_class'] . '" title="' . T_('Reply to topic') . '"><i class="fa fa-reply"></i> ' . T_('Reply') . '</a>'; } } if (!empty($post_button)) { // Display button return '<div class="post_button btn-group ' . $params['group_class'] . '">' . $post_button . '</div>'; } }
/** * Template tag. Initializes internal states for the most common skin displays. * * For more specific skins, this function should not be called and * equivalent code should be customized within the skin. * * @param string What are we going to display. Most of the time the global $disp should be passed. */ function skin_init($disp) { /** * @var Blog */ global $Blog; /** * @var Item */ global $Item; /** * @var Skin */ global $Skin; global $robots_index; global $seo_page_type; global $redir, $ReqURL, $ReqURI, $m, $w, $preview; global $Chapter; global $Debuglog; /** * @var ItemList2 */ global $MainList; /** * This will give more detail when $disp == 'posts'; otherwise it will have the same content as $disp * @var string */ global $disp_detail, $Settings; global $Timer; global $Messages, $PageCache; $Timer->resume('skin_init'); if (empty($disp_detail)) { $disp_detail = $disp; } $Debuglog->add('skin_init: ' . $disp, 'skins'); // This is the main template; it may be used to display very different things. // Do inits depending on current $disp: switch ($disp) { case 'posts': case 'single': case 'page': case 'feedback-popup': case 'search': // We need to load posts for this display: // Note: even if we request the same post as $Item above, the following will do more restrictions (dates, etc.) // Init the MainList object: init_MainList($Blog->get_setting('posts_per_page')); // Init post navigation $post_navigation = $Skin->get_post_navigation(); if (empty($post_navigation)) { $post_navigation = $Blog->get_setting('post_navigation'); } break; } // SEO stuff & redirects if necessary: $seo_page_type = NULL; switch ($disp) { // CONTENT PAGES: case 'single': case 'page': init_ajax_forms(); // auto requires jQuery init_ratings_js(); init_voting_comment_js(); init_scrollwide_js(); // Add jQuery Wide Scroll plugin if ($disp == 'single') { $seo_page_type = 'Single post page'; } else { $seo_page_type = '"Page" page'; } // Check if the post has 'redirected' status: if (!$preview && $Item->status == 'redirected' && $redir == 'yes') { // $redir=no here allows to force a 'single post' URL for commenting // Redirect to the URL specified in the post: $Debuglog->add('Redirecting to post URL [' . $Item->url . '].'); header_redirect($Item->url, true); } // Check if we want to redirect to a canonical URL for the post // Please document encountered problems. if (!$preview && ($Blog->get_setting('canonical_item_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_item_urls'))) { // We want to redirect to the Item's canonical URL: $canonical_url = $Item->get_permanent_url('', '', '&'); if (preg_match('|[&?](page=\\d+)|', $ReqURI, $page_param)) { // A certain post page has been requested, keep only this param and discard all others: $canonical_url = url_add_param($canonical_url, $page_param[1], '&'); } if (preg_match('|[&?](mode=quote&[qcp]+=\\d+)|', $ReqURI, $page_param)) { // A quote of comment/post, keep only these params and discard all others: $canonical_url = url_add_param($canonical_url, $page_param[1], '&'); } if (!is_same_url($ReqURL, $canonical_url)) { // The requested URL does not look like the canonical URL for this post... // url difference was resolved $url_resolved = false; // Check if the difference is because of an allowed post navigation param if (preg_match('|[&?]cat=(\\d+)|', $ReqURI, $cat_param)) { // A category post navigation param is set $extended_url = ''; if ($post_navigation == 'same_category' && isset($cat_param[1])) { // navigatie through posts from the same category $category_ids = postcats_get_byID($Item->ID); if (in_array($cat_param[1], $category_ids)) { // cat param is one of this Item categories $extended_url = $Item->add_navigation_param($canonical_url, $post_navigation, $cat_param[1], '&'); // Set MainList navigation target to the requested category $MainList->nav_target = $cat_param[1]; } } $url_resolved = is_same_url($ReqURL, $extended_url); } if (!$url_resolved && $Blog->get_setting('canonical_item_urls') && $redir == 'yes' && !$Item->check_cross_post_nav('auto', $Blog->ID)) { // REDIRECT TO THE CANONICAL URL: $Debuglog->add('Redirecting to canonical URL [' . $canonical_url . '].'); header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } // EXITED. } } if (!$MainList->result_num_rows) { // There is nothing to display for this page, don't index it! $robots_index = false; } break; case 'posts': init_ajax_forms('blog'); // auto requires jQuery init_scrollwide_js('blog'); // Add jQuery Wide Scroll plugin // fp> if we add this here, we have to exetnd the inner if() // init_ratings_js( 'blog' ); // Get list of active filters: $active_filters = $MainList->get_active_filters(); if (!empty($active_filters)) { // The current page is being filtered... if (array_diff($active_filters, array('page')) == array()) { // This is just a follow "paged" page $disp_detail = 'posts-next'; $seo_page_type = 'Next page'; if ($Blog->get_setting('paged_noindex')) { // We prefer robots not to index category pages: $robots_index = false; } } elseif (array_diff($active_filters, array('cat_array', 'cat_modifier', 'cat_focus', 'posts', 'page')) == array()) { // This is a category page $disp_detail = 'posts-cat'; $seo_page_type = 'Category page'; if ($Blog->get_setting('chapter_noindex')) { // We prefer robots not to index category pages: $robots_index = false; } global $cat, $catsel; if (empty($catsel) && preg_match('~[0-9]+~', $cat)) { // We are on a single cat page: // NOTE: we must have selected EXACTLY ONE CATEGORY through the cat parameter // BUT: - this can resolve to including children // - selecting exactly one cat through catsel[] is NOT OK since not equivalent (will exclude children) // echo 'SINGLE CAT PAGE'; if ($Blog->get_setting('canonical_cat_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_cat_urls')) { // Check if the URL was canonical: if (!isset($Chapter)) { $ChapterCache =& get_ChapterCache(); /** * @var Chapter */ $Chapter =& $ChapterCache->get_by_ID($MainList->filters['cat_array'][0], false); } if ($Chapter) { if ($Chapter->parent_ID) { // This is a sub-category page (i-e: not a level 1 category) $disp_detail = 'posts-subcat'; } $canonical_url = $Chapter->get_permanent_url(NULL, NULL, $MainList->get_active_filter('page'), NULL, '&'); if (!is_same_url($ReqURL, $canonical_url)) { // fp> TODO: we're going to lose the additional params, it would be better to keep them... // fp> what additional params actually? if ($Blog->get_setting('canonical_cat_urls') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canonical": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } } if ($post_navigation == 'same_category') { // Category is set and post navigation should go through the same category, set navigation target param $MainList->nav_target = $cat; } } } elseif (array_diff($active_filters, array('tags', 'posts', 'page')) == array()) { // This is a tag page $disp_detail = 'posts-tag'; $seo_page_type = 'Tag page'; if ($Blog->get_setting('tag_noindex')) { // We prefer robots not to index tag pages: $robots_index = false; } if ($Blog->get_setting('canonical_tag_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_tag_urls')) { // Check if the URL was canonical: $canonical_url = $Blog->gen_tag_url($MainList->get_active_filter('tags'), $MainList->get_active_filter('page'), '&'); if (!is_same_url($ReqURL, $canonical_url)) { if ($Blog->get_setting('canonical_tag_urls') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } } elseif (array_diff($active_filters, array('ymdhms', 'week', 'posts', 'page')) == array()) { // This is an archive page // echo 'archive page'; $disp_detail = 'posts-date'; $seo_page_type = 'Date archive page'; if ($Blog->get_setting('canonical_archive_urls') && $redir == 'yes' || $Blog->get_setting('relcanonical_archive_urls')) { // Check if the URL was canonical: $canonical_url = $Blog->gen_archive_url(substr($m, 0, 4), substr($m, 4, 2), substr($m, 6, 2), $w, '&', $MainList->get_active_filter('page')); if (!is_same_url($ReqURL, $canonical_url)) { if ($Blog->get_setting('canonical_archive_urls') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } if ($Blog->get_setting('archive_noindex')) { // We prefer robots not to index archive pages: $robots_index = false; } } else { // Other filtered pages: // pre_dump( $active_filters ); $disp_detail = 'posts-filtered'; $seo_page_type = 'Other filtered page'; if ($Blog->get_setting('filtered_noindex')) { // We prefer robots not to index other filtered pages: $robots_index = false; } } } else { // This is the default blog page $disp_detail = 'posts-default'; $seo_page_type = 'Default page'; if ($Blog->get_setting('canonical_homepage') && $redir == 'yes' || $Blog->get_setting('relcanonical_homepage')) { // Check if the URL was canonical: $canonical_url = $Blog->gen_blogurl(); if (!is_same_url($ReqURL, $canonical_url)) { if ($Blog->get_setting('canonical_homepage') && $redir == 'yes') { // REDIRECT TO THE CANONICAL URL: header_redirect($canonical_url, true); } else { // Use rel="canoncial": add_headline('<link rel="canonical" href="' . $canonical_url . '" />'); } } } if ($Blog->get_setting('default_noindex')) { // We prefer robots not to index archive pages: $robots_index = false; } } break; case 'search': $seo_page_type = 'Search page'; if ($Blog->get_setting('filtered_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; // SPECIAL FEATURE PAGES: // SPECIAL FEATURE PAGES: case 'feedback-popup': $seo_page_type = 'Comment popup'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'arcdir': $seo_page_type = 'Date archive directory'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'catdir': $seo_page_type = 'Category directory'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'msgform': init_ajax_forms('blog'); // auto requires jQuery $seo_page_type = 'Contact form'; if ($Blog->get_setting($disp . '_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'messages': case 'contacts': case 'threads': init_results_js('blog'); // Add functions to work with Results tables // just in case some robot would be logged in: $seo_page_type = 'Messaging module'; $robots_index = false; break; case 'login': global $Plugins, $transmit_hashed_password; $seo_page_type = 'Login form'; $robots_index = false; require_js('functions.js', 'blog'); $transmit_hashed_password = (bool) $Settings->get('js_passwd_hashing') && !(bool) $Plugins->trigger_event_first_true('LoginAttemptNeedsRawPassword'); if ($transmit_hashed_password) { // Include JS for client-side password hashing: require_js('sha1_md5.js', 'blog'); } break; case 'register': if (is_logged_in()) { // If user is logged in the register form should not be displayed. In this case redirect to the blog home page. $Messages->add(T_('You are already logged in.'), 'note'); header_redirect($Blog->gen_blogurl(), false); } $seo_page_type = 'Register form'; $robots_index = false; break; case 'lostpassword': if (is_logged_in()) { // If user is logged in the lost password form should not be displayed. In this case redirect to the blog home page. $Messages->add(T_('You are already logged in.'), 'note'); header_redirect($Blog->gen_blogurl(), false); } $seo_page_type = 'Lost password form'; $robots_index = false; break; case 'profile': global $rsc_url; require_css($rsc_url . 'css/jquery/smoothness/jquery-ui.css'); init_userfields_js('blog'); case 'avatar': case 'pwdchange': case 'userprefs': case 'subs': $seo_page_type = 'Special feature page'; if ($Blog->get_setting('special_noindex')) { // We prefer robots not to index these pages: $robots_index = false; } break; case 'users': $seo_page_type = 'Users list'; $robots_index = false; global $rsc_url; require_css($rsc_url . 'css/jquery/smoothness/jquery-ui.css'); init_results_js('blog'); // Add functions to work with Results tables break; case 'user': $seo_page_type = 'User display'; if (is_logged_in()) { // Used for combo_box contacts groups require_js('form_extensions.js', 'blog'); } break; case 'edit': init_datepicker_js('blog'); require_js('admin.js', 'blog'); init_inskin_editing('blog'); init_plugins_js('blog'); break; case 'edit_comment': init_plugins_js('blog'); break; case 'useritems': case 'usercomments': global $inc_path, $display_params, $viewed_User; // get user_ID because we want it in redirect_to in case we need to ask for login. $user_ID = param('user_ID', 'integer', true, true); if (empty($user_ID)) { bad_request_die(sprintf(T_('Parameter «%s» is required!'), 'user_ID')); } // set where to redirect in case of error $error_redirect_to = empty($Blog) ? $baseurl : $Blog->gen_blogurl(); if (!is_logged_in()) { // Redirect to the login page if not logged in and allow anonymous user setting is OFF $Messages->add(T_('You must log in to view this user profile.')); header_redirect(get_login_url('cannot see user'), 302); // will have exited } if (is_logged_in() && !check_user_status('can_view_user', $user_ID)) { // user is logged in, but his/her status doesn't permit to view user profile if (check_user_status('can_be_validated')) { // user is logged in but his/her account is not active yet // Redirect to the account activation page $Messages->add(T_('You must activate your account before you can view this user profile. <b>See below:</b>')); header_redirect(get_activate_info_url(), 302); // will have exited } $Messages->add(T_('Your account status currently does not permit to view this user profile.')); header_redirect($error_redirect_to, 302); // will have exited } if (!empty($user_ID)) { $UserCache =& get_UserCache(); $viewed_User = $UserCache->get_by_ID($user_ID, false); if (empty($viewed_User)) { $Messages->add(T_('The requested user does not exist!')); header_redirect($error_redirect_to); // will have exited } if ($viewed_User->check_status('is_closed')) { $Messages->add(T_('The requested user account is closed!')); header_redirect($error_redirect_to); // will have exited } } // Require results.css to display thread query results in a table require_css('results.css'); // Results/tables styles // Require functions.js to show/hide a panel with filters require_js('functions.js', 'blog'); // Include this file to expand/collapse the filters panel when JavaScript is disabled require_once $inc_path . '_filters.inc.php'; $display_params = !empty($Skin) ? $Skin->get_template('Results') : NULL; if ($disp == 'useritems') { // Init items list global $user_ItemList; $param_prefix = 'useritems_'; $page = param($param_prefix . 'paged', 'integer', 1); $orderby = param($param_prefix . 'orderby', 'string', $Blog->get_setting('orderby')); $order = param($param_prefix . 'order', 'string', $Blog->get_setting('orderdir')); $useritems_Blog = NULL; $user_ItemList = new ItemList2($useritems_Blog, NULL, NULL, NULL, 'ItemCache', $param_prefix); $user_ItemList->load_from_Request(); $user_ItemList->set_filters(array('page' => $page, 'authors' => $user_ID, 'orderby' => str_replace($param_prefix, '', $orderby), 'order' => str_replace($param_prefix, '', $order))); $user_ItemList->query(); } else { // Init comments list global $user_CommentList; $param_prefix = 'usercmts_'; $page = param($param_prefix . 'paged', 'integer', 1); $orderby = param($param_prefix . 'orderby', 'string', 'date'); $order = param($param_prefix . 'order', 'string', $Blog->get_setting('orderdir')); $user_CommentList = new CommentList2(NULL, NULL, 'CommentCache', $param_prefix); $user_CommentList->load_from_Request(); $user_CommentList->set_filters(array('page' => $page, 'author_IDs' => $user_ID, 'orderby' => str_replace($param_prefix, '', $orderby), 'order' => str_replace($param_prefix, '', $order))); $user_CommentList->query(); } break; case 'comments': if (!$Blog->get_setting('comments_latest')) { // If latest comments page is disabled - Display 404 page with error message $Messages->add(T_('This feature is disabled.'), 'error'); global $disp; $disp = '404'; } else { break; } case '404': // We have a 404 unresolved content error // How do we want do deal with it? skin_404_header(); // This MAY or MAY not have exited -- will exit on 30x redirect, otherwise will return here. // Just in case some dumb robot needs extra directives on this: $robots_index = false; break; } if (!empty($_SERVER['HTTP_USER_AGENT'])) { // Detect IE browser version preg_match('/msie (\\d+)/i', $_SERVER['HTTP_USER_AGENT'], $browser_ie); if (count($browser_ie) == 2 && $browser_ie[1] < 7) { // IE < 7 require_css('ie6.css', 'relative'); $Messages->add(T_('Your web browser is too old. For this site to work correctly, we recommend you use a more recent browser.'), 'note'); } } // dummy var for backward compatibility with versions < 2.4.1 -- prevents "Undefined variable" global $global_Cache, $credit_links; $credit_links = $global_Cache->get('creds'); $Timer->pause('skin_init'); // Check if user is logged in with a not active account, and display an error message if required check_allow_disp($disp); // initialize Blog enabled widgets, before displaying anything init_blog_widgets($Blog->ID); // Initialize displaying.... $Timer->start('Skin:display_init'); $Skin->display_init(); $Timer->pause('Skin:display_init'); // Send default headers: // See comments inside of this function: headers_content_mightcache('text/html'); // In most situations, you do NOT want to cache dynamic content! // Never allow Messages to be cached! if ($Messages->count() && !empty($PageCache)) { // Abort PageCache collect $PageCache->abort_collect(); } }
function search_result_block($params = array()) { global $Blog, $Session, $debug; $search_keywords = param('s', 'string', '', true); // Try to load existing search results from Session: $search_params = $Session->get('search_params'); $search_result = $Session->get('search_result'); $search_result_loaded = false; if (empty($search_params) || $search_params['search_keywords'] != $search_keywords || $search_params['search_blog'] != $Blog->ID || $search_result === NULL) { // We need to perform a new search: if ($debug) { echo '<p class="text-muted">Starting a new search...</p>'; } // Flush first part of the page before starting search, which can be long... evo_flush(); $search_params = array('search_keywords' => $search_keywords, 'search_blog' => $Blog->ID); // Perform new search: $search_result = perform_scored_search($search_keywords); // Save results into session: $Session->set('search_params', $search_params); $Session->set('search_result', $search_result); $search_result_loaded = true; } else { // We found the desired saved search results in the Session: if ($debug) { // Display counts echo '<div class="text-muted">'; echo '<p>We found the desired saved search results in the Session:</p>'; echo '<ul><li>' . sprintf('%d posts', $search_result[0]['nr_of_items']) . '</li>'; echo '<li>' . sprintf('%d comments', $search_result[0]['nr_of_comments']) . '</li>'; echo '<li>' . sprintf('%d chapters', $search_result[0]['nr_of_cats']) . '</li>'; echo '<li>' . sprintf('%d tags', $search_result[0]['nr_of_tags']) . '</li></ul>'; echo '</div>'; } // Flush first part of the page before starting search, which can be long... evo_flush(); } // Make sure we are not missing any display params: $params = array_merge(array('no_match_message' => '<p class="alert alert-info msg_nothing" style="margin: 2em 0">' . T_('Sorry, we could not find anything matching your request, please try to broaden your search.') . '<p>', 'title_suffix_post' => ' (' . T_('Post') . ')', 'title_suffix_comment' => ' (' . T_('Comment') . ')', 'title_suffix_category' => ' (' . T_('Category') . ')', 'title_suffix_tag' => ' (' . T_('Tag') . ')', 'block_start' => '', 'block_end' => '', 'pagination' => array(), 'use_editor' => false, 'author_format' => 'avatar_name', 'date_format' => locale_datefmt()), $params); $search_result = $Session->get('search_result'); if (empty($search_result)) { echo $params['no_match_message']; return; } // Prepare pagination: $result_count = count($search_result); $result_per_page = $Blog->get_setting('search_per_page'); if ($result_count > $result_per_page) { // We will have multiple search result pages: $current_page = param('page', 'integer', 1); $total_pages = ceil($result_count / $result_per_page); if ($current_page > $total_pages) { $current_page = $total_pages; } $page_params = array_merge(array('total' => $result_count, 'current_page' => $current_page, 'total_pages' => $total_pages, 'list_span' => 11), $params['pagination']); search_page_links($page_params); } else { // Only one page of results: $current_page = 1; $total_pages = 1; } // Set current page indexes: $from = ($current_page - 1) * $result_per_page; $to = $current_page < $total_pages ? $from + $result_per_page : $result_count; // Init caches $ItemCache =& get_ItemCache(); $CommentCache =& get_CommentCache(); $ChapterCache =& get_ChapterCache(); if (!$search_result_loaded) { // Search result objects are not loaded into memory yet, load them // Group required object ids by type: $required_ids = array(); for ($index = $from; $index < $to; $index++) { $row = $search_result[$index]; if (isset($required_ids[$row['type']])) { $required_ids[$row['type']][] = $row['ID']; } else { $required_ids[$row['type']] = array($row['ID']); } } // Load each required object into the corresponding cache: foreach ($required_ids as $type => $object_ids) { switch ($type) { case 'item': $ItemCache->load_list($object_ids); break; case 'comment': $CommentCache->load_list($object_ids); break; case 'category': $ChapterCache->load_list($object_ids); break; // TODO: we'll probably load "tag" objects once we support tag-synonyms. // TODO: we'll probably load "tag" objects once we support tag-synonyms. default: // Not handled search result type break; } } } // ----------- Display ------------ echo $params['block_start']; // Memorize best scores: $max_percentage = $search_result[0]['percentage']; $max_score = $search_result[0]['score']; // Display results for current page: for ($index = $from; $index < $to; $index++) { $row = $search_result[$index]; switch ($row['type']) { case 'item': // Prepare to display an Item: $Item = $ItemCache->get_by_ID($row['ID'], false); if (empty($Item)) { // This Item was deleted, since the search process was executed continue 2; // skip from switch and skip to the next item in loop } $display_params = array('title' => $Item->get_title(array('link_type' => 'permalink')) . $params['title_suffix_post'], 'excerpt' => $Item->get_excerpt2(), 'chapter' => sprintf(T_('In %s'), $Item->get_chapter_links())); if ($params['use_editor']) { // Get editor info to display: $lastedit_User =& $Item->get_lastedit_User(); if (empty($lastedit_User)) { // If editor is not defined yet then use author $lastedit_User =& $Item->get_creator_User(); } $display_params = array_merge(array('editor' => $lastedit_User->get_identity_link(array('link_text' => $params['author_format'])), 'lastedit_date' => mysql2date($params['date_format'], empty($Item->datemodified) ? $Item->datecreated : $Item->datemodified)), $display_params); } else { // Get author info to display: $creator_User =& $Item->get_creator_User(); $display_params = array_merge(array('author' => $creator_User->get_identity_link(array('link_text' => $params['author_format'])), 'creation_date' => mysql2date($params['date_format'], $Item->datecreated), 'lastedit_date' => mysql2date($params['date_format'], $Item->datemodified)), $display_params); } break; case 'comment': // Prepare to display a Comment: $Comment = $CommentCache->get_by_ID($row['ID'], false); if (empty($Comment) || $Comment->status == 'trash') { // This Comment was deleted, since the search process was executed continue 2; // skip from switch and skip to the next item in loop } $display_params = array('title' => $Comment->get_permanent_link('#item#') . $params['title_suffix_comment'], 'excerpt' => excerpt($Comment->content), 'author' => $Comment->get_author(array('link_text' => $params['author_format'], 'thumb_size' => 'crop-top-15x15', 'thumb_class' => 'avatar_before_login')), 'creation_date' => mysql2date($params['date_format'], $Comment->date)); break; case 'category': // Prepare to display a Category: $Chapter = $ChapterCache->get_by_ID($row['ID'], false); if (empty($Chapter)) { // This Chapter was deleted, since the search process was executed continue 2; // skip from switch and skip to the next item in loop } $display_params = array('title' => '<a href="' . $Chapter->get_permanent_url() . '">' . $Chapter->get_name() . '</a>' . $params['title_suffix_category'], 'excerpt' => excerpt($Chapter->get('description'))); break; case 'tag': // Prepare to display a Tag: list($tag_name, $post_count) = explode(':', $row['ID']); $display_params = array('title' => '<a href="' . url_add_param($Blog->gen_blogurl(), 'tag=' . $tag_name) . '">' . $tag_name . '</a>' . $params['title_suffix_tag'], 'excerpt' => sprintf(T_('%d posts are tagged with \'%s\''), $post_count, $tag_name)); break; default: // Other type of result is not implemented // TODO: maybe find collections (especially in case of aggregation)? users? files? continue 2; } // Common display params for all types: $display_params['score'] = $row['score']; $display_params['percentage'] = isset($row['percentage']) ? $row['percentage'] : round($row['score'] * $max_percentage / $max_score); $display_params['scores_map'] = $row['scores_map']; $display_params['type'] = $row['type']; $display_params['best_result'] = $index == 0; $display_params['max_score'] = sprintf(floor($max_score) != $max_score ? '%.2f' : '%d', $max_score); $display_params['max_percentage'] = $max_percentage; // Display one search result: display_search_result(array_merge($params, $display_params)); } echo $params['block_end']; // Display pagination: if ($result_count > $result_per_page) { search_page_links($page_params); } }
/** * Generate a title for the current list, depending on its filtering params * * @todo cleanup some displays * @todo implement HMS part of YMDHMS * * @return array List of titles to display, which are escaped for HTML display * (dh> only checked this for 'authors'/?authors=, where the output was not escaped) */ function get_filter_titles($ignore = array(), $params = array()) { global $month; $params = array_merge(array('category_text' => T_('Category') . ': ', 'categories_text' => T_('Categories') . ': ', 'tags_text' => T_('Tags') . ': '), $params); if (empty($this->filters)) { // Filters have no been set before, we'll use the default filterset: // echo ' setting default filterset '; $this->set_filters($this->default_filters); } $title_array = array(); if ($this->single_post) { // We have requested a specific post: // Should be in first position $Item =& $this->get_by_idx(0); if (is_null($Item)) { $title_array[] = T_('Invalid request'); } else { $title_array[] = $Item->get_titletag(); } return $title_array; } // CATEGORIES: if (!empty($this->filters['cat_array'])) { // We have requested specific categories... $cat_names = array(); $ChapterCache =& get_ChapterCache(); foreach ($this->filters['cat_array'] as $cat_ID) { if (($my_Chapter =& $ChapterCache->get_by_ID($cat_ID, false)) !== false) { // It is almost never meaningful to die over an invalid cat when generating title $cat_names[] = $my_Chapter->name; } } if ($this->filters['cat_modifier'] == '*') { $cat_names_string = implode(' + ', $cat_names); } else { $cat_names_string = implode(', ', $cat_names); } if (!empty($cat_names_string)) { if ($this->filters['cat_modifier'] == '-') { $cat_names_string = T_('All but ') . ' ' . $cat_names_string; $title_array['cats'] = $params['categories_text'] . $cat_names_string; } else { if (count($this->filters['cat_array']) > 1) { $title_array['cats'] = $params['categories_text'] . $cat_names_string; } else { $title_array['cats'] = $params['category_text'] . $cat_names_string; } } } } // ARCHIVE TIMESLOT: if (!empty($this->filters['ymdhms'])) { // We have asked for a specific timeframe: $my_year = substr($this->filters['ymdhms'], 0, 4); if (strlen($this->filters['ymdhms']) > 4) { // We have requested a month too: $my_month = T_($month[substr($this->filters['ymdhms'], 4, 2)]); } else { $my_month = ''; } // Requested a day? $my_day = substr($this->filters['ymdhms'], 6, 2); $arch = T_('Archives for') . ': ' . $my_month . ' ' . $my_year; if (!empty($my_day)) { // We also want to display a day $arch .= ', ' . $my_day; } if (!empty($this->filters['week']) || $this->filters['week'] === 0) { // We also want to display a week number $arch .= ', ' . T_('week') . ' ' . $this->filters['week']; } $title_array['ymdhms'] = $arch; } // KEYWORDS: if (!empty($this->filters['keywords'])) { $title_array['keywords'] = T_('Keyword(s)') . ': ' . $this->filters['keywords']; } // TAGS: if (!empty($this->filters['tags'])) { $title_array[] = $params['tags_text'] . $this->filters['tags']; } // AUTHORS: if (!empty($this->filters['authors']) || !empty($this->filters['authors_login'])) { $authors = trim($this->filters['authors'] . ',' . get_users_IDs_by_logins($this->filters['authors_login']), ','); $authors = preg_split('~\\s*,\\s*~', $authors, -1, PREG_SPLIT_NO_EMPTY); $author_names = array(); if ($authors) { $UserCache =& get_UserCache(); foreach ($authors as $author_ID) { if ($tmp_User = $UserCache->get_by_ID($author_ID, false, false)) { $author_names[] = $tmp_User->get_identity_link(array('link_text' => 'login')); } } } $title_array[] = T_('Author(s)') . ': ' . implode(', ', $author_names); } // ASSIGNEES: if (!empty($this->filters['assignees']) || !empty($this->filters['assignees_login'])) { if ($this->filters['assignees'] == '-') { $title_array[] = T_('Not assigned'); } else { $assignees = trim($this->filters['assignees'] . ',' . get_users_IDs_by_logins($this->filters['assignees_login']), ','); $assignees = preg_split('~\\s*,\\s*~', $assignees, -1, PREG_SPLIT_NO_EMPTY); $assignees_names = array(); if ($assignees) { $UserCache =& get_UserCache(); foreach ($assignees as $user_ID) { if ($tmp_User =& $UserCache->get_by_ID($user_ID, false, false)) { $assignees_names[] = $tmp_User->get_identity_link(array('link_text' => 'login')); } } } $title_array[] = T_('Assigned to') . ': ' . implode(', ', $assignees_names); } } // LOCALE: if ($this->filters['lc'] != 'all') { $title_array[] = T_('Locale') . ': ' . $this->filters['lc']; } // EXTRA STATUSES: if (!empty($this->filters['statuses'])) { if ($this->filters['statuses'] == '-') { $title_array[] = T_('Without status'); } else { $title_array[] = T_('Status(es)') . ': ' . $this->filters['statuses']; } } // SHOW STATUSES if (count($this->filters['visibility_array']) < 5 && !in_array('visibility', $ignore)) { $post_statuses = get_visibility_statuses(); $status_titles = array(); foreach ($this->filters['visibility_array'] as $status) { $status_titles[] = $post_statuses[$status]; } $title_array[] = T_('Visibility') . ': ' . implode(', ', $status_titles); } // START AT if (!empty($this->filters['ymdhms_min'])) { $title_array['ymdhms_min'] = T_('Start at') . ': ' . $this->filters['ymdhms_min']; } if (!empty($this->filters['ts_min'])) { if ($this->filters['ts_min'] == 'now') { $title_array['ts_min'] = T_('Hide past'); } else { $title_array['ts_min'] = T_('Start at') . ': ' . $this->filters['ts_min']; } } // STOP AT if (!empty($this->filters['ymdhms_max'])) { $title_array['ymdhms_max'] = T_('Stop at') . ': ' . $this->filters['ymdhms_max']; } if (!empty($this->filters['ts_max'])) { if ($this->filters['ts_max'] == 'now') { if (!in_array('hide_future', $ignore)) { $title_array['ts_max'] = T_('Hide future'); } } else { $title_array['ts_max'] = T_('Stop at') . ': ' . $this->filters['ts_max']; } } // LIMIT TO if ($this->single_post) { // Single post: no paging required! } elseif (!empty($this->filters['ymdhms'])) { // no restriction if we request a month... some permalinks may point to the archive! } elseif ($this->filters['unit'] == 'posts' || $this->filters['unit'] == 'all') { // We're going to page, so there's no real limit here... } elseif ($this->filters['unit'] == 'days') { // We are going to limit to x days: // echo 'LIMIT DAYS '; if (empty($this->filters['ymdhms_min'])) { // We have no start date, we'll display the last x days: if (!empty($this->filters['keywords']) || !empty($this->filters['cat_array']) || !empty($this->filters['authors'])) { // We are in DAYS mode but we can't restrict on these! (TODO: ?) } else { // We are going to limit to LAST x days: // TODO: rename 'posts' to 'limit' $title_array['posts'] = sprintf(T_('Limited to %d last days'), $this->limit); } } else { // We have a start date, we'll display x days starting from that point: $title_array['posts'] = sprintf(T_('Limited to %d days'), $this->limit); } } else { debug_die('Unhandled LIMITING mode in ItemList:' . $this->filters['unit'] . ' (paged mode is obsolete)'); } return $title_array; }
/** * Read messages from server and create posts * * @param resource $mbox created by pbm_connect() (by reference) * @param integer the number of messages to process * @return boolean true on success */ function pbm_process_messages(&$mbox, $limit) { global $Settings; global $pbm_item_files, $pbm_messages, $pbm_items, $post_cntr, $del_cntr, $is_cron_mode; // No execution time limit set_max_execution_time(0); // Are we in test mode? $test_mode_on = $Settings->get('eblog_test_mode'); $post_cntr = 0; $del_cntr = 0; for ($index = 1; $index <= $limit; $index++) { pbm_msg('<hr /><h3>Processing message #' . $index . ':</h3>'); $strbody = ''; $hasAttachment = false; $hasRelated = false; $pbm_item_files = array(); // reset the value for each new Item // Save email to hard drive, otherwise attachments may take a lot of RAM if (!($tmpMIME = tempnam(sys_get_temp_dir(), 'b2evoMail'))) { pbm_msg(T_('Could not create temporary file.'), true); continue; } imap_savebody($mbox, $tmpMIME, $index); // Create random temp directory for message parts $tmpDirMIME = pbm_tempdir(sys_get_temp_dir(), 'b2evo_'); $mimeParser = new mime_parser_class(); $mimeParser->mbox = 0; // Set to 0 for parsing a single message file $mimeParser->decode_headers = 1; $mimeParser->ignore_syntax_errors = 1; $mimeParser->extract_addresses = 0; $MIMEparameters = array('File' => $tmpMIME, 'SaveBody' => $tmpDirMIME, 'SkipBody' => 1); if (!$mimeParser->Decode($MIMEparameters, $decodedMIME)) { pbm_msg(sprintf('MIME message decoding error: %s at position %d.', $mimeParser->error, $mimeParser->error_position), true); rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } else { pbm_msg('MIME message decoding successful'); if (!$mimeParser->Analyze($decodedMIME[0], $parsedMIME)) { pbm_msg(sprintf('MIME message analyse error: %s', $mimeParser->error), true); rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } // Get message $subject and $post_date from headers (by reference) if (!pbm_process_header($parsedMIME, $subject, $post_date)) { // Couldn't process message headers rmdir_r($tmpDirMIME); unlink($tmpMIME); continue; } // TODO: handle type == "message" recursively // sam2kb> For some reason imap_qprint() demages HTML text... needs more testing if ($parsedMIME['Type'] == 'html') { // Mail is HTML if ($Settings->get('eblog_html_enabled')) { // HTML posting enabled pbm_msg('HTML message part saved as ' . $parsedMIME['DataFile']); $html_body = file_get_contents($parsedMIME['DataFile']); } foreach ($parsedMIME['Alternative'] as $alternative) { // First try to get HTML alternative (when possible) if ($alternative['Type'] == 'html' && $Settings->get('eblog_html_enabled')) { // HTML text pbm_msg('HTML alternative message part saved as ' . $alternative['DataFile']); // sam2kb> TODO: we may need to use $html_body here instead $strbody = file_get_contents($alternative['DataFile']); break; // stop after first alternative } elseif ($alternative['Type'] == 'text') { // Plain text pbm_msg('Text alternative message part saved as ' . $alternative['DataFile']); $strbody = imap_qprint(file_get_contents($alternative['DataFile'])); break; // stop after first alternative } } } elseif ($parsedMIME['Type'] == 'text') { // Mail is plain text pbm_msg('Plain-text message part saved as ' . $parsedMIME['DataFile']); $strbody = imap_qprint(file_get_contents($parsedMIME['DataFile'])); } // Check for attachments if (!empty($parsedMIME['Attachments'])) { $hasAttachment = true; foreach ($parsedMIME['Attachments'] as $file) { pbm_msg('Attachment: ' . $file['FileName'] . ' stored as ' . $file['DataFile']); } } // Check for inline images if (!empty($parsedMIME['Related'])) { $hasRelated = true; foreach ($parsedMIME['Related'] as $file) { pbm_msg('Related file with content ID: ' . $file['ContentID'] . ' stored as ' . $file['DataFile']); } } if (count($mimeParser->warnings) > 0) { pbm_msg(sprintf('<h4>%d warnings during decode:</h4>', count($mimeParser->warnings))); foreach ($mimeParser->warnings as $k => $v) { pbm_msg('Warning: ' . $v . ' at position ' . $k); } } } unlink($tmpMIME); if (empty($html_body)) { // Plain text message pbm_msg('Message type: TEXT'); pbm_msg('Message body: <pre style="font-size:10px">' . htmlspecialchars($strbody) . '</pre>'); // Process body. First fix different line-endings (dos, mac, unix), remove double newlines $content = str_replace(array("\r", "\n\n"), "\n", trim($strbody)); // First see if there's an <auth> tag with login and password if (($auth = pbm_get_auth_tag($content)) === false) { // No <auth> tag, let's detect legacy "username:password" on the first line $a_body = explode("\n", $content, 2); // tblue> splitting only into 2 parts allows colons in the user PW // Note: login and password cannot include '<' ! $auth = explode(':', strip_tags($a_body[0]), 2); // Drop the first line with username and password $content = $a_body[1]; } } else { // HTML message pbm_msg('Message type: HTML'); if (($parsed_message = pbm_prepare_html_message($html_body)) === false) { // No 'auth' tag provided, skip to the next message rmdir_r($tmpDirMIME); continue; } list($auth, $content) = $parsed_message; } // TODO: dh> should the password really get trimmed here?! $user_pass = isset($auth[1]) ? trim(remove_magic_quotes($auth[1])) : NULL; $user_login = trim(evo_strtolower(remove_magic_quotes($auth[0]))); if (empty($user_login) || empty($user_pass)) { pbm_msg(sprintf(T_('Please add username and password in message body in format %s.'), '"<auth>username:password</auth>"'), true); rmdir_r($tmpDirMIME); continue; } // Authenticate user pbm_msg('Authenticating user: «' . $user_login . '»'); $pbmUser =& pbm_validate_user_password($user_login, $user_pass); if (!$pbmUser) { pbm_msg(sprintf(T_('Authentication failed for user «%s»'), htmlspecialchars($user_login)), true); rmdir_r($tmpDirMIME); continue; } $pbmUser->get_Group(); // Load group if (!empty($is_cron_mode)) { // Assign current User if we are in cron mode. This is needed in order to check user permissions global $current_User; $current_User = duplicate($pbmUser); } // Activate User's locale locale_activate($pbmUser->get('locale')); pbm_msg('<b class="green">Success</b>'); if ($post_categories = xmlrpc_getpostcategories($content)) { $main_cat_ID = array_shift($post_categories); $extra_cat_IDs = $post_categories; pbm_msg('Extra categories: ' . implode(', ', $extra_cat_IDs)); } else { $main_cat_ID = $Settings->get('eblog_default_category'); $extra_cat_IDs = array(); } pbm_msg('Main category ID: ' . $main_cat_ID); $ChapterCache =& get_ChapterCache(); $pbmChapter =& $ChapterCache->get_by_ID($main_cat_ID, false, false); if (empty($pbmChapter)) { pbm_msg(sprintf(T_('Requested category %s does not exist!'), $main_cat_ID), true); rmdir_r($tmpDirMIME); continue; } $blog_ID = $pbmChapter->blog_ID; pbm_msg('Blog ID: ' . $blog_ID); $BlogCache =& get_BlogCache(); $pbmBlog =& $BlogCache->get_by_ID($blog_ID, false, false); if (empty($pbmBlog)) { pbm_msg(sprintf(T_('Requested blog %s does not exist!'), $blog_ID), true); rmdir_r($tmpDirMIME); continue; } // Check permission: pbm_msg(sprintf('Checking permissions for user «%s» to post to Blog #%d', $user_login, $blog_ID)); if (!$pbmUser->check_perm('blog_post!published', 'edit', false, $blog_ID)) { pbm_msg(T_('Permission denied.'), true); rmdir_r($tmpDirMIME); continue; } if (($hasAttachment || $hasRelated) && !$pbmUser->check_perm('files', 'add', false, $blog_ID)) { pbm_msg(T_('You have no permission to add/upload files.'), true); rmdir_r($tmpDirMIME); continue; } pbm_msg('<b class="green">Success</b>'); // Remove content after terminator $eblog_terminator = $Settings->get('eblog_body_terminator'); if (!empty($eblog_terminator) && ($os_terminator = evo_strpos($content, $eblog_terminator)) !== false) { $content = evo_substr($content, 0, $os_terminator); } $post_title = pbm_get_post_title($content, $subject); // Remove 'title' and 'category' tags $content = xmlrpc_removepostdata($content); // Remove <br> tags from string start and end // We do it here because there might be extra <br> left after deletion of <auth>, <category> and <title> tags $content = preg_replace(array('~^(\\s*<br[\\s/]*>\\s*){1,}~i', '~(\\s*<br[\\s/]*>\\s*){1,}$~i'), '', $content); if ($hasAttachment || $hasRelated) { // Handle attachments if (isset($GLOBALS['files_Module'])) { if ($mediadir = $pbmBlog->get_media_dir()) { if ($hasAttachment) { pbm_process_attachments($content, $parsedMIME['Attachments'], $mediadir, $pbmBlog->get_media_url(), $Settings->get('eblog_add_imgtag'), 'attach'); } if ($hasRelated) { pbm_process_attachments($content, $parsedMIME['Related'], $mediadir, $pbmBlog->get_media_url(), true, 'related'); } } else { pbm_msg(T_('Unable to access media directory. No attachments processed.'), true); } } else { pbm_msg(T_('Files module is disabled or missing!'), true); } } // CHECK and FORMAT content global $Plugins; $renderer_params = array('Blog' => &$pbmBlog, 'setting_name' => 'coll_apply_rendering'); $renderers = $Plugins->validate_renderer_list($Settings->get('eblog_renderers'), $renderer_params); pbm_msg('Applying the following text renderers: ' . implode(', ', $renderers)); // Do some optional filtering on the content // Typically stuff that will help the content to validate // Useful for code display // Will probably be used for validation also $Plugins_admin =& get_Plugins_admin(); $params = array('object_type' => 'Item', 'object_Blog' => &$pbmBlog); $Plugins_admin->filter_contents($post_title, $content, $renderers, $params); pbm_msg('Filtered post content: <pre style="font-size:10px">' . htmlspecialchars($content) . '</pre>'); $context = $Settings->get('eblog_html_tag_limit') ? 'commenting' : 'posting'; $post_title = check_html_sanity($post_title, $context, $pbmUser); $content = check_html_sanity($content, $context, $pbmUser); global $Messages; if ($Messages->has_errors()) { // Make it easier for user to find and correct the errors pbm_msg("\n" . sprintf(T_('Processing message: %s'), $post_title), true); pbm_msg($Messages->get_string(T_('Cannot post, please correct these errors:'), 'error'), true); $Messages->clear(); rmdir_r($tmpDirMIME); continue; } if ($test_mode_on) { // Test mode pbm_msg('<b class="green">It looks like the post can be successfully saved in the database. However we will not do it in test mode.</b>'); } else { load_class('items/model/_item.class.php', 'Item'); global $pbm_items, $DB, $localtimenow; $post_status = 'published'; pbm_msg(sprintf('<h4>Saving item "%s" in the database</h4>', $post_title)); // INSERT NEW POST INTO DB: $edited_Item = new Item(); $edited_Item->set_creator_User($pbmUser); $edited_Item->set($edited_Item->lasteditor_field, $pbmUser->ID); $edited_Item->set('title', $post_title); $edited_Item->set('content', $content); $edited_Item->set('datestart', $post_date); $edited_Item->set('datemodified', date('Y-m-d H:i:s', $localtimenow)); $edited_Item->set('main_cat_ID', $main_cat_ID); $edited_Item->set('extra_cat_IDs', $extra_cat_IDs); $edited_Item->set('status', $post_status); $edited_Item->set('locale', $pbmUser->locale); $edited_Item->set('renderers', $renderers); // INSERT INTO DB: $edited_Item->dbinsert('through_email'); pbm_msg(sprintf('Item created?: ' . (isset($edited_Item->ID) ? 'yes' : 'no'))); // Execute or schedule notifications & pings: $edited_Item->handle_post_processing(true); if (!empty($pbm_item_files)) { // Attach files $FileCache =& get_FileCache(); $order = 1; foreach ($pbm_item_files as $filename) { pbm_msg(sprintf('Saving file "%s" in the database', $filename)); $pbmFile =& $FileCache->get_by_root_and_path('collection', $pbmBlog->ID, $filename); $pbmFile->meta = 'notfound'; // Save time and don't try to load meta from DB, it's not there anyway $pbmFile->dbsave(); pbm_msg(sprintf('File saved?: ' . (isset($pbmFile->ID) ? 'yes' : 'no'))); pbm_msg(sprintf('Attaching file "%s" to the post', $filename)); // Let's make the link! $pbmLink = new Link(); $pbmLink->set('itm_ID', $edited_Item->ID); $pbmLink->set('file_ID', $pbmFile->ID); $pbmLink->set('position', 'aftermore'); $pbmLink->set('order', $order++); $pbmLink->dbinsert(); pbm_msg(sprintf('File attached?: ' . (isset($pbmLink->ID) ? 'yes' : 'no'))); } } // Save posted items sorted by author user for reports $pbm_items['user_' . $pbmUser->ID][] = $edited_Item; ++$post_cntr; } pbm_msg('Message posting successful'); // Delete temporary directory rmdir_r($tmpDirMIME); if (!$test_mode_on && $Settings->get('eblog_delete_emails')) { pbm_msg('Marking message for deletion from inbox: ' . $index); imap_delete($mbox, $index); ++$del_cntr; } } // Expunge messages marked for deletion imap_expunge($mbox); return true; }
/** * Generate a title for the current list, depending on its filtering params * * @todo cleanup some displays * @todo implement HMS part of YMDHMS * * @return array List of titles to display, which are escaped for HTML display * (dh> only checked this for 'authors'/?authors=, where the output was not escaped) */ function get_filter_titles($ignore = array(), $params = array()) { global $month, $disp_detail; $params = array_merge(array('category_text' => T_('Category') . ': ', 'categories_text' => T_('Categories') . ': ', 'categories_nor_text' => T_('All but '), 'tag_text' => T_('Tag') . ': ', 'tags_text' => T_('Tags') . ': ', 'author_text' => T_('Author') . ': ', 'authors_text' => T_('Authors') . ': ', 'authors_nor_text' => T_('All authors except') . ': ', 'visibility_text' => T_('Visibility') . ': ', 'keyword_text' => T_('Keyword') . ': ', 'keywords_text' => T_('Keywords') . ': ', 'keywords_exact_text' => T_('Exact match') . ' ', 'status_text' => T_('Status') . ': ', 'statuses_text' => T_('Statuses') . ': ', 'archives_text' => T_('Archives for') . ': ', 'assignes_text' => T_('Assigned to') . ': ', 'group_mask' => '$group_title$$filter_items$', 'filter_mask' => '"$filter_name$"', 'filter_mask_nogroup' => '"$filter_name$"', 'before_items' => '', 'after_items' => '', 'separator_and' => ' ' . T_('and') . ' ', 'separator_or' => ' ' . T_('or') . ' ', 'separator_nor' => ' ' . T_('or') . ' ', 'separator_comma' => ', ', 'display_category' => true, 'display_archive' => true, 'display_keyword' => true, 'display_tag' => true, 'display_author' => true, 'display_assignee' => true, 'display_locale' => true, 'display_status' => true, 'display_visibility' => true, 'display_time' => true, 'display_limit' => true), $params); if (empty($this->filters)) { // Filters have no been set before, we'll use the default filterset: // echo ' setting default filterset '; $this->set_filters($this->default_filters); } $title_array = array(); if ($this->single_post) { // We have requested a specific post: // Should be in first position $Item =& $this->get_by_idx(0); if (is_null($Item)) { $title_array[] = T_('Invalid request'); } else { $title_array[] = $Item->get_titletag(); } return $title_array; } // Check if the filter mask has an icon to clear the filter item $clear_icon = strpos($params['filter_mask'], '$clear_icon$') !== false; $filter_classes = array('green'); $filter_class_i = 0; if (strpos($params['filter_mask'], '$filter_class$') !== false) { // Initialize array with available classes for filter items $filter_classes = array('green', 'yellow', 'orange', 'red', 'magenta', 'blue'); } // CATEGORIES: if ($params['display_category']) { if (!empty($this->filters['cat_array'])) { // We have requested specific categories... $cat_names = array(); $ChapterCache =& get_ChapterCache(); $catsel_param = get_param('catsel'); foreach ($this->filters['cat_array'] as $cat_ID) { if (($tmp_Chapter =& $ChapterCache->get_by_ID($cat_ID, false)) !== false) { // It is almost never meaningful to die over an invalid cat when generating title $cat_clear_url = regenerate_url((empty($catsel_param) ? 'cat=' : 'catsel=') . $cat_ID); if ($disp_detail == 'posts-subcat' || $disp_detail == 'posts-cat') { // Remove category url from $ReqPath when we use the cat url instead of cat ID $cat_clear_url = str_replace('/' . $tmp_Chapter->get_url_path(), '', $cat_clear_url); } $cat_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', $cat_clear_url) : ''; $cat_names[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['category_text'], $tmp_Chapter->name, $cat_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } } $filter_class_i++; if ($this->filters['cat_modifier'] == '*') { // Categories with "AND" condition $cat_names_string = implode($params['separator_and'], $cat_names); } elseif ($this->filters['cat_modifier'] == '-') { // Categories with "NOR" condition $cat_names_string = implode($params['separator_nor'], $cat_names); } else { // Categories with "OR" condition $cat_names_string = implode($params['separator_or'], $cat_names); } if (!empty($cat_names_string)) { if ($this->filters['cat_modifier'] == '-') { // Categories with "NOR" condition $cat_names_string = $params['categories_nor_text'] . $cat_names_string; $params['category_text'] = $params['categories_text']; } $title_array['cats'] = str_replace(array('$group_title$', '$filter_items$'), count($this->filters['cat_array']) > 1 ? array($params['categories_text'], $params['before_items'] . $cat_names_string . $params['after_items']) : array($params['category_text'], $cat_names_string), $params['group_mask']); } } } // ARCHIVE TIMESLOT: if ($params['display_archive']) { if (!empty($this->filters['ymdhms'])) { // We have asked for a specific timeframe: $my_year = substr($this->filters['ymdhms'], 0, 4); if (strlen($this->filters['ymdhms']) > 4) { // We have requested a month too: $my_month = T_($month[substr($this->filters['ymdhms'], 4, 2)]); } else { $my_month = ''; } // Requested a day? $my_day = substr($this->filters['ymdhms'], 6, 2); $arch = $my_month . ' ' . $my_year; if (!empty($my_day)) { // We also want to display a day $arch .= ', ' . $my_day; } if (!empty($this->filters['week']) || $this->filters['week'] === 0) { // We also want to display a week number $arch .= ', ' . T_('week') . ' ' . $this->filters['week']; } $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; $arch_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'm')) : ''; $arch = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['archives_text'], $arch, $arch_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); $title_array['ymdhms'] = str_replace(array('$group_title$', '$filter_items$'), array($params['archives_text'], $arch), $params['group_mask']); $filter_class_i++; } } // KEYWORDS: if ($params['display_keyword']) { if (!empty($this->filters['keywords'])) { if ($this->filters['phrase'] == 'OR' || $this->filters['phrase'] == 'AND') { // Search by each keyword $keywords = trim(preg_replace('/("|, *)/', ' ', $this->filters['keywords'])); $keywords = explode(' ', $keywords); } else { // Exact match (Single keyword) $keywords = array($this->filters['keywords']); } $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; $keyword_names = array(); foreach ($keywords as $keyword) { $word_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 's=' . $keyword)) : ''; $keyword_names[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['keyword_text'], $keyword, $word_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } $filter_class_i++; $keywords = ($this->filters['exact'] ? $params['keywords_exact_text'] : '') . implode($this->filters['phrase'] == 'OR' ? $params['separator_or'] : $params['separator_and'], $keyword_names); $title_array[] = str_replace(array('$group_title$', '$filter_items$'), count($keyword_names) > 1 ? array($params['keywords_text'], $params['before_items'] . $keywords . $params['after_items']) : array($params['keyword_text'], $keywords), $params['group_mask']); } } // TAGS: if ($params['display_tag']) { if (!empty($this->filters['tags'])) { $tags = explode(',', $this->filters['tags']); $tag_names = array(); $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; foreach ($tags as $tag) { $tag_clear_url = regenerate_url($this->param_prefix . 'tag=' . $tag); if ($disp_detail == 'posts-tag') { // Remove tag url from $ReqPath when we use tag url instead of tag ID $tag_clear_url = str_replace('/' . $tag . ':', '', $tag_clear_url); } $tag_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', $tag_clear_url) : ''; $tag_names[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['tag_text'], $tag, $tag_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } $filter_class_i++; $tags = implode($params['separator_comma'], $tag_names); $title_array[] = str_replace(array('$group_title$', '$filter_items$'), count($tag_names) > 1 ? array($params['tags_text'], $params['before_items'] . $tags . $params['after_items']) : array($params['tag_text'], $tags), $params['group_mask']); } } // AUTHORS: if ($params['display_author']) { if (!empty($this->filters['authors']) || !empty($this->filters['authors_login'])) { $authors = trim($this->filters['authors'] . ',' . get_users_IDs_by_logins($this->filters['authors_login']), ','); $exclude_authors = false; if (substr($authors, 0, 1) == '-') { // Authors are excluded $authors = substr($authors, 1); $exclude_authors = true; } $authors = preg_split('~\\s*,\\s*~', $authors, -1, PREG_SPLIT_NO_EMPTY); $author_names = array(); if ($authors) { $UserCache =& get_UserCache(); $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; foreach ($authors as $author_ID) { if ($tmp_User = $UserCache->get_by_ID($author_ID, false, false)) { $user_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'author=' . $author_ID)) : ''; $author_names[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['author_text'], $tmp_User->get('login'), $user_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } } $filter_class_i++; } if (count($author_names) > 0) { // Display info of filter by authors if ($exclude_authors) { // Exclude authors $author_names_string = $params['authors_nor_text'] . implode($params['separator_nor'], $author_names); } else { // Filter by authors $author_names_string = implode($params['separator_comma'], $author_names); } $title_array[] = str_replace(array('$group_title$', '$filter_items$'), count($author_names) > 1 ? array($params['authors_text'], $params['before_items'] . $author_names_string . $params['after_items']) : array($params['author_text'], $author_names_string), $params['group_mask']); } } } // ASSIGNEES: if ($params['display_assignee']) { if (!empty($this->filters['assignees']) || !empty($this->filters['assignees_login'])) { $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; if ($this->filters['assignees'] == '-') { $user_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'assgn')) : ''; $title_array[] = str_replace(array('$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Not assigned'), $user_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask_nogroup']); } else { $assignees = trim($this->filters['assignees'] . ',' . get_users_IDs_by_logins($this->filters['assignees_login']), ','); $assignees = preg_split('~\\s*,\\s*~', $assignees, -1, PREG_SPLIT_NO_EMPTY); $assignees_names = array(); if ($assignees) { $UserCache =& get_UserCache(); foreach ($assignees as $user_ID) { if ($tmp_User =& $UserCache->get_by_ID($user_ID, false, false)) { $user_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'assgn=' . $user_ID)) : ''; $assignees_names[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['assignes_text'], $tmp_User->get_identity_link(array('link_text' => 'name')), $user_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } } } $title_array[] = str_replace(array('$group_title$', '$filter_items$'), count($assignees_names) > 1 ? array($params['assignes_text'], $params['before_items'] . implode($params['separator_comma'], $assignees_names) . $params['after_items']) : array($params['assignes_text'], implode($params['separator_comma'], $assignees_names)), $params['group_mask']); } $filter_class_i++; } } // LOCALE: if ($params['display_locale']) { if ($this->filters['lc'] != 'all') { $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; $user_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'lc')) : ''; $loc = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Locale') . ': ', $this->filters['lc'], $user_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); $title_array[] = str_replace(array('$group_title$', '$filter_items$'), array(T_('Locale') . ': ', $loc), $params['group_mask']); $filter_class_i++; } } // EXTRA STATUSES: if ($params['display_status']) { if (!empty($this->filters['statuses'])) { $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; if ($this->filters['statuses'] == '-') { $status_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'status=-')) : ''; $title_array[] = str_replace(array('$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Without status'), $status_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask_nogroup']); } else { $status_IDs = explode(',', $this->filters['statuses']); $ItemStatusCache =& get_ItemStatusCache(); $statuses = array(); foreach ($status_IDs as $status_ID) { if ($ItemStatus =& $ItemStatusCache->get_by_ID($status_ID)) { $status_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'status=' . $status_ID)) : ''; $statuses[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['status_text'], $ItemStatus->get_name(), $status_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } } $title_array[] = str_replace(array('$group_title$', '$filter_items$'), count($statuses) > 1 ? array($params['statuses_text'], $params['before_items'] . implode($params['separator_comma'], $statuses) . $params['after_items']) : array($params['status_text'], implode($params['separator_comma'], $statuses)), $params['group_mask']); } $filter_class_i++; } } // VISIBILITY (SHOW STATUSES): if ($params['display_visibility']) { if (!in_array('visibility', $ignore)) { $post_statuses = get_visibility_statuses(); if (count($this->filters['visibility_array']) != count($post_statuses)) { // Display it only when visibility filter is changed $status_titles = array(); $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; foreach ($this->filters['visibility_array'] as $status) { $vis_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'show_statuses=' . $status)) : ''; $status_titles[] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array($params['visibility_text'], $post_statuses[$status], $vis_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } $filter_class_i++; $title_array[] = str_replace(array('$group_title$', '$filter_items$'), count($status_titles) > 1 ? array($params['visibility_text'], $params['before_items'] . implode($params['separator_comma'], $status_titles) . $params['after_items']) : array($params['visibility_text'], implode($params['separator_comma'], $status_titles)), $params['group_mask']); } } } if ($params['display_time']) { // START AT: if (!empty($this->filters['ymdhms_min']) || !empty($this->filters['ts_min'])) { $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; if (!empty($this->filters['ymdhms_min'])) { $time_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'dstart')) : ''; $title_array['ts_min'] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Start at') . ': ', date2mysql($this->filters['ymdhms_min']), $time_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } else { if ($this->filters['ts_min'] == 'now') { $time_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'show_future')) : ''; $title_array['ts_min'] = str_replace(array('$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Hide past'), $time_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask_nogroup']); } else { $time_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'show_future')) : ''; $title_array['ts_min'] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Start at') . ': ', date2mysql($this->filters['ts_min']), $time_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } } $filter_class_i++; } // STOP AT: if (!empty($this->filters['ymdhms_max']) || !empty($this->filters['ts_max'])) { $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; if (!empty($this->filters['ymdhms_max'])) { $time_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'dstop')) : ''; $title_array['ts_max'] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Stop at') . ': ', date2mysql($this->filters['ymdhms_max']), $time_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } else { if ($this->filters['ts_max'] == 'now') { if (!in_array('hide_future', $ignore)) { $time_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'show_past')) : ''; $title_array['ts_max'] = str_replace(array('$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Hide future'), $time_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask_nogroup']); } } else { $time_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'show_past')) : ''; $title_array['ts_max'] = str_replace(array('$group_title$', '$filter_name$', '$clear_icon$', '$filter_class$'), array(T_('Stop at') . ': ', date2mysql($this->filters['ts_max']), $time_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask']); } } $filter_class_i++; } } // LIMIT TO: if ($params['display_limit']) { if ($this->single_post) { // Single post: no paging required! } elseif (!empty($this->filters['ymdhms'])) { // no restriction if we request a month... some permalinks may point to the archive! } elseif ($this->filters['unit'] == 'posts' || $this->filters['unit'] == 'all') { // We're going to page, so there's no real limit here... } elseif ($this->filters['unit'] == 'days') { // We are going to limit to x days: // echo 'LIMIT DAYS '; $filter_class_i = $filter_class_i > count($filter_classes) - 1 ? 0 : $filter_class_i; if (empty($this->filters['ymdhms_min'])) { // We have no start date, we'll display the last x days: if (!empty($this->filters['keywords']) || !empty($this->filters['cat_array']) || !empty($this->filters['authors'])) { // We are in DAYS mode but we can't restrict on these! (TODO: ?) } else { // We are going to limit to LAST x days: // TODO: rename 'posts' to 'limit' $unit_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'unit')) : ''; $title_array['posts'] = str_replace(array('$filter_name$', '$clear_icon$', '$filter_class$'), array(sprintf(T_('Limited to last %d days'), $this->limit), $unit_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask_nogroup']); } } else { // We have a start date, we'll display x days starting from that point: $unit_clear_icon = $clear_icon ? action_icon(T_('Remove this filter'), 'remove', regenerate_url($this->param_prefix . 'unit')) : ''; $title_array['posts'] = str_replace(array('$filter_name$', '$clear_icon$', '$filter_class$'), array(sprintf(T_('Limited to %d days'), $this->limit), $unit_clear_icon, $filter_classes[$filter_class_i]), $params['filter_mask_nogroup']); } $filter_class_i++; } else { debug_die('Unhandled LIMITING mode in ItemList:' . $this->filters['unit'] . ' (paged mode is obsolete)'); } } return $title_array; }
/** * Get url to write a new Post * * @param integer Category ID * @param string Post title * @param string Post urltitle * @param string Post type * @return string Url to write a new Post */ function get_write_item_url($cat_ID = 0, $post_title = '', $post_urltitle = '', $post_type = '') { $url = ''; if (is_logged_in(false)) { // Only logged in and activated users can write a Post global $current_User; $ChapterCache =& get_ChapterCache(); $selected_Chapter = $ChapterCache->get_by_ID($cat_ID, false, false); if ($selected_Chapter && $selected_Chapter->lock) { // This category is locked, don't allow to create new post with this cat return ''; } if ($current_User->check_perm('blog_post_statuses', 'edit', false, $this->ID)) { // We have permission to add a post with at least one status: if ($this->get_setting('in_skin_editing') && !is_admin_page()) { // We have a mode 'In-skin editing' for the current Blog // User must have a permission to publish a post in this blog $cat_url_param = ''; if ($cat_ID > 0) { // Link to create a Item with predefined category $cat_url_param = '&cat=' . $cat_ID; } $url = url_add_param($this->get('url'), 'disp=edit' . $cat_url_param); } elseif ($current_User->check_perm('admin', 'restricted')) { // Edit a post from Back-office global $admin_url; $url = $admin_url . '?ctrl=items&action=new&blog=' . $this->ID; if (!empty($cat_ID)) { // Add category param to preselect category on the form $url = url_add_param($url, 'cat=' . $cat_ID); } } if (!empty($post_title)) { // Append a post title $url = url_add_param($url, 'post_title=' . $post_title); } if (!empty($post_urltitle)) { // Append a post urltitle $url = url_add_param($url, 'post_urltitle=' . $post_urltitle); } if (!empty($post_type)) { // Append a post type $url = url_add_param($url, 'post_type=' . $post_type); } } } return $url; }
skin_include('_item_content.inc.php', $params); // Note: You can customize the default item content by copying the generic // /skins/_item_content.inc.php file into the current skin folder. // -------------------------- END OF POST CONTENT ------------------------- locale_restore_previous(); // Restore previous locale (Blog locale) ?> </div> <?php // ------------------------------- END OF INTRO-FRONT POST ------------------------------- } // --------------------------------- START OF POSTS ------------------------------------- // Display message if no post: $params_no_content = array('before' => '<div class="msg_nothing">', 'after' => '</div>', 'msg_empty_logged_in' => T_('Sorry, there is nothing to display...'), 'msg_empty_not_logged_in' => T_('This site has no public contents.')); // Get only root categories of this blog $ChapterCache =& get_ChapterCache(); $chapters = $ChapterCache->get_chapters($Blog->ID, 0, true); // Boolean var to know when at least one post is displayed $no_content_to_display = true; if (!empty($chapters)) { // Display the posts with chapters foreach ($chapters as $Chapter) { // Get the posts of current category $ItemList = new ItemList2($Blog, $Blog->get_timestamp_min(), $Blog->get_timestamp_max()); $ItemList->set_filters(array('cat_array' => array($Chapter->ID), 'cat_modifier' => NULL, 'unit' => 'all')); $ItemList->query(); if ($ItemList->result_num_rows > 0) { $no_content_to_display = false; ?> <div class="posts_list"> <div class="category_title clear"><h2><a href="<?php
/** * Render content of Item, Comment, Message * * @todo get rid of global $blog * * @param string Content * @param object Blog * @param boolean Allow empty Blog * return boolean */ function render_content(&$content, $item_Blog = NULL, $allow_null_blog = false) { global $ItemCache, $admin_url, $blog, $evo_charset; $regexp_modifier = ''; if ($evo_charset == 'utf-8') { // Add this modifier to work with UTF-8 strings correctly $regexp_modifier = 'u'; } // Regular links: $search = array('#\\[\\[((https?|mailto)://((?:[^<>{}\\s\\]]|,(?!\\s))+?))\\]\\]#i', '#\\[\\[((https?|mailto)://([^<>{}\\s\\]]+)) ([^\\n\\r]+?)\\]\\]#i', '#\\(\\(((https?|mailto)://((?:[^<>{}\\s\\]]|,(?!\\s))+?))\\)\\)#i', '#\\(\\(((https?|mailto)://([^<>{}\\s\\]]+)) ([^\\n\\r]+?)\\)\\)#i'); $replace = array('<a href="$1">$1</a>', '<a href="$1">$4</a>', '<a href="$1">$1</a>', '<a href="$1">$4</a>'); $content = replace_content_outcode($search, $replace, $content); /* QUESTION: fplanque, implementation of this planned? then use make_clickable() - or remove this comment $ret = preg_replace("#([\n ])aim:([^,< \n\r]+)#i", "\\1<a href=\"aim:goim?screenname=\\2\\3&message=Hello\">\\2\\3</a>", $ret); $ret = preg_replace("#([\n ])icq:([^,< \n\r]+)#i", "\\1<a href=\"http://wwp.icq.com/scripts/search.dll?to=\\2\\3\">\\2\\3</a>", $ret); $ret = preg_replace("#([\n ])www\.([a-z0-9\-]+)\.([a-z0-9\-.\~]+)((?:/[^,< \n\r]*)?)#i", "\\1<a href=\"http://www.\\2.\\3\\4\">www.\\2.\\3\\4</a>", $ret); $ret = preg_replace("#([\n ])([a-z0-9\-_.]+?)@([^,< \n\r]+)#i", "\\1<a href=\"mailto:\\2@\\3\">\\2@\\3</a>", $ret); */ // To use function replace_special_chars() load_funcs('locales/_charset.funcs.php'); // WIKIWORDS: $search_wikiwords = array(); $replace_links = array(); if ($this->get_coll_setting('link_without_brackets', $item_Blog, $allow_null_blog)) { // Create the links from standalone WikiWords // STANDALONE WIKIWORDS: $search = '/ (?<= \\s | ^ ) # Lookbehind for whitespace ([\\p{Lu}]+[\\p{Ll}0-9_]+([\\p{Lu}]+[\\p{L}0-9_]+)+) # WikiWord or WikiWordLong (?= [\\.,:;!\\?] \\s | \\s | $ ) # Lookahead for whitespace or punctuation /x' . $regexp_modifier; // x = extended (spaces + comments allowed) if (preg_match_all($search, $content, $matches, PREG_SET_ORDER)) { // Construct array of wikiwords to look up in post urltitles $wikiwords = array(); foreach ($matches as $match) { // Convert the WikiWord to an urltitle $WikiWord = $match[0]; $Wiki_Word = preg_replace('*([^\\p{Lu}_])([\\p{Lu}])*' . $regexp_modifier, '$1-$2', $WikiWord); $wiki_word = evo_strtolower($Wiki_Word); // echo '<br />Match: [', $WikiWord, '] -> [', $wiki_word, ']'; $wiki_word = replace_special_chars($wiki_word); $wikiwords[$WikiWord] = $wiki_word; } // Lookup all urltitles at once in DB and preload cache: $ItemCache =& get_ItemCache(); $ItemCache->load_urltitle_array($wikiwords); // Construct arrays for replacing wikiwords by links: foreach ($wikiwords as $WikiWord => $wiki_word) { // WikiWord $search_wikiwords[] = '/ (?<= \\s | ^ ) # Lookbehind for whitespace or start (?<! <span\\ class="NonExistentWikiWord"> ) ' . $WikiWord . ' # Specific WikiWord to replace (?= [\\.,:;!\\?] \\s | \\s | $ ) # Lookahead for whitespace or end of string /sx'; // s = dot matches newlines, x = extended (spaces + comments allowed) // Find matching Item: if (($Item =& $ItemCache->get_by_urltitle($wiki_word, false)) !== false) { // Item Found $permalink = $Item->get_permanent_url(); // WikiWord $replace_links[] = '<a href="' . $permalink . '">' . $Item->get('title') . '</a>'; } else { // Item not found $create_link = isset($blog) ? '<a href="' . $admin_url . '?ctrl=items&action=new&blog=' . $blog . '&post_title=' . preg_replace('*([^\\p{Lu}_])([\\p{Lu}])*' . $regexp_modifier, '$1%20$2', $WikiWord) . '&post_urltitle=' . $wiki_word . '" title="Create...">?</a>' : ''; // WikiWord $replace_links[] = '<span class="NonExistentWikiWord">' . $WikiWord . $create_link . '</span>'; } } } } // BRACKETED WIKIWORDS: $search = '/ (?<= \\(\\( | \\[\\[ ) # Lookbehind for (( or [[ ([\\p{L}0-9]+[\\p{L}0-9_\\-]*) # Anything from Wikiword to WikiWordLong (?= ( \\s .*? )? ( \\)\\) | \\]\\] ) ) # Lookahead for )) or ]] /x' . $regexp_modifier; // x = extended (spaces + comments allowed) if (preg_match_all($search, $content, $matches, PREG_SET_ORDER)) { // Construct array of wikiwords to look up in post urltitles $wikiwords = array(); foreach ($matches as $match) { // Convert the WikiWord to an urltitle $WikiWord = $match[0]; if (preg_match('/^[\\p{Ll}0-9_\\-]+$/' . $regexp_modifier, $WikiWord)) { // This WikiWord already matches a slug format $Wiki_Word = $WikiWord; $wiki_word = $Wiki_Word; } else { // Convert WikiWord to slug format $Wiki_Word = preg_replace(array('*([^\\p{Lu}_])([\\p{Lu}])*' . $regexp_modifier, '*([^0-9])([0-9])*' . $regexp_modifier), '$1-$2', $WikiWord); $wiki_word = evo_strtolower($Wiki_Word); } // echo '<br />Match: [', $WikiWord, '] -> [', $wiki_word, ']'; $wiki_word = replace_special_chars($wiki_word); $wikiwords[$WikiWord] = $wiki_word; } // Lookup all urltitles at once in DB and preload cache: $ChapterCache =& get_ChapterCache(); $ChapterCache->load_urlname_array($wikiwords); $ItemCache =& get_ItemCache(); $ItemCache->load_urltitle_array($wikiwords); // Construct arrays for replacing wikiwords by links: foreach ($wikiwords as $WikiWord => $wiki_word) { // [[WikiWord text]] $search_wikiwords[] = '* \\[\\[ ' . $WikiWord . ' # Specific WikiWord to replace \\s (.+?) \\]\\] *sx'; // s = dot matches newlines, x = extended (spaces + comments allowed) // ((WikiWord text)) $search_wikiwords[] = '* \\(\\( ' . $WikiWord . ' # Specific WikiWord to replace \\s (.+?) \\)\\) *sx'; // s = dot matches newlines, x = extended (spaces + comments allowed) // [[Wikiword]] $search_wikiwords[] = '* \\[\\[ ' . $WikiWord . ' # Specific WikiWord to replace \\]\\] *sx'; // s = dot matches newlines, x = extended (spaces + comments allowed) // ((Wikiword)) $search_wikiwords[] = '* \\(\\( ' . $WikiWord . ' # Specific WikiWord to replace \\)\\) *sx'; // s = dot matches newlines, x = extended (spaces + comments allowed) // Find matching Chapter or Item: $permalink = ''; $link_text = preg_replace(array('*([^\\p{Lu}_])([\\p{Lu}])*' . $regexp_modifier, '*([^0-9])([0-9])*' . $regexp_modifier), '$1 $2', $WikiWord); $link_text = ucwords(str_replace('-', ' ', $link_text)); if (($Chapter =& $ChapterCache->get_by_urlname($wiki_word, false)) !== false) { // Chapter is found $permalink = $Chapter->get_permanent_url(); $existing_link_text = $Chapter->get('name'); } elseif (($Item =& $ItemCache->get_by_urltitle($wiki_word, false)) !== false) { // Item is found $permalink = $Item->get_permanent_url(); $existing_link_text = $Item->get('title'); } if (!empty($permalink)) { // Chapter or Item are found // [[WikiWord text]] $replace_links[] = '<a href="' . $permalink . '">$1</a>'; // ((WikiWord text)) $replace_links[] = '<a href="' . $permalink . '">$1</a>'; // [[Wikiword]] $replace_links[] = '<a href="' . $permalink . '">' . $existing_link_text . '</a>'; // ((Wikiword)) $replace_links[] = '<a href="' . $permalink . '">' . $link_text . '</a>'; } else { // Chapter and Item are not found $create_link = isset($blog) ? '<a href="' . $admin_url . '?ctrl=items&action=new&blog=' . $blog . '&post_title=' . preg_replace('*([^\\p{Lu}_])([\\p{Lu}])*' . $regexp_modifier, '$1%20$2', $WikiWord) . '&post_urltitle=' . $wiki_word . '" title="Create...">?</a>' : ''; // [[WikiWord text]] $replace_links[] = '<span class="NonExistentWikiWord">$1' . $create_link . '</span>'; // ((WikiWord text)) $replace_links[] = '<span class="NonExistentWikiWord">$1' . $create_link . '</span>'; // [[Wikiword]] $replace_links[] = '<span class="NonExistentWikiWord">' . $link_text . $create_link . '</span>'; // ((Wikiword)) $replace_links[] = '<span class="NonExistentWikiWord">' . $link_text . $create_link . '</span>'; } } } // echo '<br />---'; // pre_dump( $search_wikiwords ); $content = replace_content_outcode($search_wikiwords, $replace_links, $content); return true; }
/** * Get the main Chapter. * * @return Chapter */ function &get_main_Chapter() { if (is_null($this->main_Chapter)) { $ChapterCache =& get_ChapterCache(); /** * @var Chapter */ $this->main_Chapter =& $ChapterCache->get_by_ID($this->main_cat_ID, false); if (empty($this->main_Chapter)) { // If main chapter is broken we should get it from one of extra chapters $chapters = $this->get_Chapters(); foreach ($chapters as $Chapter) { if (!empty($Chapter)) { // We have found a valid Chapter... $this->main_Chapter =& $Chapter; $this->main_cat_ID = $Chapter->ID; break; } } } if (empty($this->main_Chapter)) { // If we still don't have a valid Chapter, display clean error and die(). global $admin_url, $Blog, $blog; if (empty($Blog)) { if (!empty($blog)) { $BlogCache =& get_BlogCache(); $Blog =& $BlogCache->get_by_ID($blog, false); } } $url_to_edit_post = $admin_url . '?ctrl=items&action=edit&p=' . $this->ID; if (!empty($Blog)) { $url_to_edit_post .= '&blog=' . $Blog->ID; if (is_admin_page()) { // Try to set a main category $default_cat_ID = $Blog->get_setting('default_cat_ID'); if (!empty($default_cat_ID)) { // If default category is set $this->main_cat_ID = $default_cat_ID; $this->main_Chapter =& $ChapterCache->get_by_ID($this->main_cat_ID, false); } else { // Set from first chapter of the blog $ChapterCache->clear(); $ChapterCache->load_subset($Blog->ID); if ($Chapter =& $ChapterCache->get_next()) { $this->main_cat_ID = $Chapter->ID; $this->main_Chapter =& $Chapter; } } } } $message = sprintf('Item with ID <a %s>%s</a> has an invalid main category ID %s.', 'href="' . $url_to_edit_post . '"', $this->ID, $this->main_cat_ID); if (empty($Blog)) { // No blog defined $message .= ' In addition we cannot fallback to the default category because no valid blog ID has been specified.'; } if (empty($this->main_Chapter)) { // Main chapter is not defined, because blog doesn't have the default cat ID and even blog doesn't have any categories debug_die($message); } else { // Main chapter is defined, we can show the page global $Messages; $Messages->add($message); } } } return $this->main_Chapter; }
/** * Display the widget! * * @param array MUST contain at least the basic display params */ function display($params) { global $Blog, $cat, $disp; $params = array_merge(array('item_mask' => '<a href="$url$">$title$</a>', 'item_active_mask' => '$title$', 'suffix_text' => ''), $params); $this->init_display($params); $breadcrumbs = array(); if (!empty($this->disp_params['suffix_text'])) { // Append custom breadcrumb item at the end: $breadcrumbs[] = array('title' => $this->disp_params['suffix_text']); } if (!empty($disp) && $disp == 'single') { // Include current post global $Item; if (!empty($Item)) { $breadcrumbs[] = array('title' => $Item->dget('title')); } } if (!empty($cat)) { // Include full path of the selected chapter $ChapterCache =& get_ChapterCache(); $chapter_ID = $cat; do { // Get all parent chapters if ($Chapter =& $ChapterCache->get_by_ID($chapter_ID, false)) { $breadcrumbs[] = array('title' => $Chapter->dget('name'), 'url' => $Chapter->get_permanent_url()); $chapter_ID = $Chapter->get('parent_ID'); } else { // No parent chapter else, Stop here break; } } while (!empty($chapter_ID)); } if ($this->disp_params['start_with'] == 'blog') { // Include Blog name $breadcrumbs[] = array('title' => $Blog->get('name'), 'url' => $Blog->get('blogurl')); } if (empty($breadcrumbs)) { // Nothing to display return; } echo $this->disp_params['block_start']; // Print out the breadcrumbs $breadcrumbs = array_reverse($breadcrumbs); foreach ($breadcrumbs as $b => $breadcrumb) { if ($b == count($breadcrumbs) - 1) { // Last crumb is active echo str_replace('$title$', $breadcrumb['title'], $params['item_active_mask']); } else { // All other crumbs are not active echo str_replace(array('$url$', '$title$'), array($breadcrumb['url'], $breadcrumb['title']), $params['item_mask']); // Separator echo $this->disp_params['separator']; } } echo $this->disp_params['block_end']; return true; }