Exemple #1
0
        if ($r === true) {
            echo sprintf(NO_ENTRIES_BLAHBLAH, $serendipity['GET']['searchTerm']);
            break;
        }
        echo sprintf(YOUR_SEARCH_RETURNED_BLAHBLAH, $serendipity["GET"]["searchTerm"], count($r));
        serendipity_printEntries($r);
        break;
        // Show the archive
    // Show the archive
    case "archives":
        serendipity_printArchives();
        break;
        // Welcome screen or whatever
    // Welcome screen or whatever
    default:
        serendipity_printEntries(serendipity_fetchEntries(null, true, $serendipity['fetchLimit']));
}
?>
            <?php 
echo $CLOSESHADOW;
?>
        </td>
        <td valign="top" align="left" class="serendipitySideBar">
            <?php 
//              serendipity_plugin_api::generate_plugins('left', 'span');
serendipity_plugin_api::generate_plugins('right', 'span');
?>

        </td>
    </tr>
</table>
/**
 * Prints the content of the iframe.
 *
 * Called by serendipity_is_iframe, when preview is requested. Fetches data from session.
 * An iframe is used so that a single s9y page must not timeout on intensive operations,
 * and so that the frontend stylesheet can be embedded without screwing up the backend.
 *
 * @access private
 * @see serendipity_is_iframe()
 * @param   mixed   The entry array (comes from session variable)
 * @param   string  Indicates whether an entry is previewed or saved. Save performs XML-RPC calls.
 * @param   boolean Use smarty templating?
 * @return  boolean Indicates whether iframe data was printed
 */
function serendipity_iframe(&$entry, $mode = null)
{
    global $serendipity;
    if (empty($mode) || !is_array($entry)) {
        return false;
    }
    $data = array();
    $data['is_preview'] = true;
    $data['mode'] = $mode;
    switch ($mode) {
        case 'save':
            ob_start();
            $res = serendipity_updertEntry($entry);
            $data['updertHooks'] = ob_get_contents();
            ob_end_clean();
            if (is_string($res)) {
                $data['res'] = $res;
            }
            if (!empty($serendipity['lastSavedEntry'])) {
                $data['lastSavedEntry'] = $serendipity['lastSavedEntry'];
            }
            $data['entrylink'] = serendipity_archiveURL($res, $entry['title'], 'serendipityHTTPPath', true, array('timestamp' => $entry['timestamp']));
            break;
        case 'preview':
            $serendipity['smarty_preview'] = true;
            $data['preview'] = serendipity_printEntries(array($entry), $entry['extended'] != '' ? 1 : 0, true);
            break;
    }
    return serendipity_smarty_show('preview_iframe.tpl', $data);
}
/**
 * Prints the content of the iframe.
 *
 * Called by serendipity_is_iframe, when preview is requested. Fetches data from session.
 * An iframe is used so that a single s9y page must not timeout on intensive operations,
 * and so that the frontend stylesheet can be embedded without screwing up the backend.
 *
 * @access private
 * @see serendipity_is_iframe()
 * @param   mixed   The entry array (comes from session variable)
 * @param   string  Indicates whether an entry is previewed or saved. Save performs XML-RPC calls.
 * @param   boolean Use smarty templating?
 * @return  boolean Indicates whether iframe data was printed
 */
function serendipity_iframe(&$entry, $mode = null, $use_smarty = true)
{
    global $serendipity;
    if (empty($mode) || !is_array($entry)) {
        return false;
    }
    if (!serendipity_checkFormToken()) {
        return false;
    }
    if ($use_smarty) {
        $serendipity['smarty_raw_mode'] = true;
        // Force output of Smarty stuff in the backend
        $serendipity['smarty_preview'] = true;
        serendipity_smarty_init();
        $serendipity['smarty']->assign('is_preview', true);
        ob_start();
    }
    $show = false;
    switch ($mode) {
        case 'save':
            echo '<div style="float: left; height: 75px"></div>';
            $res = serendipity_updertEntry($entry);
            if (is_string($res)) {
                echo '<div class="serendipity_msg_error">' . ERROR . ': <b>' . $res . '</b></div>';
            } else {
                if (!empty($serendipity['lastSavedEntry'])) {
                    // Last saved entry must be propagated to entry form so that if the user re-edits it,
                    // it needs to be stored with the new ID.
                    echo '<script type="text/javascript">parent.document.forms[\'serendipityEntry\'][\'serendipity[id]\'].value = "' . $serendipity['lastSavedEntry'] . '";</script>';
                }
                $entrylink = serendipity_archiveURL($res, $entry['title'], 'serendipityHTTPPath', true, array('timestamp' => $entry['timestamp']));
                echo '<div class="serendipityAdminMsgSuccess"><img style="height: 22px; width: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="' . serendipity_getTemplateFile('admin/img/admin_msg_success.png') . '" alt="" />' . ENTRY_SAVED . ' (<a href="' . $entrylink . '" target="_blank">' . VIEW . '</a>)</div>';
            }
            echo '<br style="clear: both" />';
            $show = true;
            break;
        case 'preview':
            echo '<div id="serendipity_preview_spacer" style="float: left; height: 225px"></div>';
            serendipity_printEntries(array($entry), $entry['extended'] != '' ? 1 : 0, true);
            echo '<br id="serendipity_preview_spacer2" style="clear: both" />';
            $show = true;
            break;
    }
    if ($use_smarty) {
        $preview = ob_get_contents();
        ob_end_clean();
        $serendipity['smarty']->assign_by_ref('preview', $preview);
        $serendipity['smarty']->display(serendipity_getTemplateFile('preview_iframe.tpl', 'serendipityPath'));
    }
    return $show;
}
    function event_hook($event, &$bag, &$eventData, $addlData = null)
    {
        global $serendipity;
        $hooks =& $bag->get('event_hooks');
        // I'm not really certain why this is here (since we only get called
        // for the events we hooked), but Garvin uses it, so it must be
        // important.
        if (isset($hooks[$event])) {
            $content_type = $this->get_config('content_type', 'categories');
            $placement = $this->get_config('placement', 'entry top');
            $news_cats = $this->get_config('news_cats');
            switch ($event) {
                case 'genpage':
                    // Is this the frontpage? (Garvin's algorythm; works
                    // for all cases except index.html, on my server)
                    if ($addlData['startpage']) {
                        $this->isFrontPage = true;
                    } else {
                        $this->isFrontPage = false;
                        return true;
                    }
                    // Get this newsbox's entries
                    //
                    // Hidden newsboxes don't need to waste time doing this.
                    if ($placement == 'hidden') {
                        return true;
                    }
                    // If I don't contain categories, I don't generate HTML from categories.
                    if ($content_type != 'categories') {
                        return true;
                    }
                    // If this newsbox is empty, we'd get an SQL error.
                    if (empty($news_cats)) {
                        $this->html = '<div class="newsbox"><i>No ' . $this->get_config('title', PLUGIN_EVENT_NEWSBOX_DEFAULT_TITLE) . ' today.</i></div>';
                        return true;
                    }
                    // Smarty isn't initialized yet.
                    serendipity_smarty_init();
                    // Create the SQL to fetch my entries
                    $sql = "\n" . ' e.id IN ' . "\n" . '(SELECT entryid FROM ' . $serendipity['dbPrefix'] . 'entrycat' . "\n" . ' WHERE categoryid IN (' . $news_cats . ')' . "\n" . ')';
                    // We don't want our exclusion logic to execute on *this*
                    // fetchEntries call!
                    $serendipity['newsbox'] = 'no_exclude';
                    //--JAM: yeah, it looks like a bug to me.  I wonder what else gets accidentally overwritten?
                    $oldLimit = $serendipity['fetchLimit'];
                    // We want the number of entries configurable
                    $max_entries = $this->get_config('max_entries', 5);
                    if (!is_numeric($max_entries)) {
                        $max_entries = 5;
                    }
                    $entries = serendipity_fetchEntries(null, true, $max_entries, false, false, 'timestamp DESC', $sql);
                    $serendipity['fetchLimit'] = $oldLimit;
                    unset($serendipity['newsbox']);
                    // Process our input data with new printEntries:
                    // $entries, no extended, no preview, block NEWSBOX, no smarty fetch, no hooks, footer
                    serendipity_printEntries($entries, 0, false, 'NEWSBOX', false, false, false);
                    $newsbox_data = array();
                    $newsbox_data['title'] = $this->get_config('title', PLUGIN_EVENT_NEWSBOX_DEFAULT_TITLE);
                    $newsbox_data['cats'] = explode(',', $news_cats);
                    $newsbox_data['content_type'] = $content_type;
                    $newsbox_data['isContainer'] = $content_type != 'categories';
                    $newsbox_data['multicat_action'] = $serendipity['baseURL'] . $serendipity['indexFile'];
                    $serendipity['smarty']->assign('newsbox_data', $newsbox_data);
                    $nb = serendipity_getTemplateFile('newsbox.tpl');
                    if ($nb && $nb != 'newsbox.tpl') {
                        // Template is obviously newsbox-aware
                        $this->html = serendipity_smarty_fetch('NEWSBOX', 'newsbox.tpl', false);
                    } else {
                        // Set the newsbox variable for the template, in case it's newsbox-aware
                        $serendipity['smarty']->assign('isNewsbox', true);
                        // Modify the footer link
                        $more = '<form style="display:inline;" action="' . $serendipity['baseURL'] . $serendipity['indexFile'] . '" method="post">';
                        foreach (explode(',', $news_cats) as $cat) {
                            $more .= '<input type="hidden" name="serendipity[multiCat][]" value="' . $cat . '">';
                        }
                        $more .= '<input class="serendipityPrettyButton input_button" type="submit" name="serendipity[isMultiCat]" value="More ' . $this->get_config('title', PLUGIN_EVENT_NEWSBOX_DEFAULT_TITLE) . '"></form>';
                        $serendipity['smarty']->assign('footer_info', $more);
                        // Get the HTML
                        $serendipity['skip_smarty_hooks'] = true;
                        // Don't call entries_header from the template!
                        $this->html = serendipity_smarty_fetch('NEWSBOX', 'entries.tpl', false);
                        unset($serendipity['skip_smarty_hooks']);
                        // Don't leave the newsbox variable set for the regular fetch
                        $serendipity['smarty']->clear_assign('isNewsbox');
                        // Check if the template supports newsboxes
                        // Matches class = "whatever_newsbox_whatever", taking care to allow
                        // whitespace where legal and match quote types (I don't think you
                        // can use a quote in a class name, but hey...)
                        if (preg_match('/class\\s*=\\s*(["\'])[^\\1]*newsbox/', $this->html) == 0) {
                            // Add the div; give it the default class "newsbox" and a title
                            $title = $this->get_config('title');
                            $this->html = "\n<div class=\"newsbox\"><h3 class=\"newsbox_title\">{$title}</h3>\n" . $this->html . "\n</div><!--newsbox-->\n";
                        }
                    }
                    // Done processing the newsbox
                    break;
                case 'frontend_fetchentries':
                    // Only on the frontpage
                    if (!$this->isFrontPage) {
                        return true;
                    }
                    // Don't even call this hook if we're already in this hook
                    if (isset($serendipity['newsbox']) && $serendipity['newsbox'] == 'no_exclude') {
                        return true;
                    }
                    // If we don't contain categories, we don't want to
                    // exclude categories accidentally
                    if ($content_type != 'categories') {
                        return true;
                    }
                    // Don't restrict the calendar, etc; only the main listing
                    $source = $addlData['source'];
                    if ($source != 'entries') {
                        return true;
                    }
                    // No joins required!
                    // $joins = array();
                    $conds = array();
                    if (isset($news_cats) && !empty($news_cats)) {
                        // Exclude entries in the newbox
                        $conds[] = ' (e.id NOT IN (SELECT entryid from ' . $serendipity['dbPrefix'] . 'entrycat' . ' WHERE categoryid IN (' . $news_cats . ')))';
                    }
                    if (count($conds) > 0) {
                        $cond = implode(' AND ', $conds);
                        if (empty($eventData['and'])) {
                            $eventData['and'] = " WHERE {$cond} ";
                        } else {
                            $eventData['and'] .= " AND {$cond} ";
                        }
                    }
                    return true;
                    break;
                case 'css':
                    // Can't tell if this is the fronpage or not.  Better
                    // generate the CSS, just in case.
                    if (strpos($eventData, 'newsbox') !== false) {
                        // This CSS is already newsbox-aware.
                        return true;
                    }
                    $eventData = $eventData . '
.newsbox
{
  border: 1px solid black;
  padding: 2px;
  margin-bottom: 4px;
}
.newsbox_title
{
  font-style: italic;
}
.newsbox_container
{
  border: 1px solid black;
  padding: 2px;
  margin-bottom: 4px;
  text-align: center;
  margin: 2px auto;
}
.newsbox_container .newsbox
{
  border: none;
  width: 48%;
  float: left;
  text-align: left;
  margin: 2px;
  display: inline;
}
                    ';
                    return true;
                    break;
                    // Placement cases: if configured placement equals the hook,
                    // print my HTML.  Hidden takes care of itself: there is no
                    // matching hook, so it never gets printed.  Contained
                    // newsboxes will also never match a hook; their HTML is
                    // requested by the containing newsbox.
                // Placement cases: if configured placement equals the hook,
                // print my HTML.  Hidden takes care of itself: there is no
                // matching hook, so it never gets printed.  Contained
                // newsboxes will also never match a hook; their HTML is
                // requested by the containing newsbox.
                case 'frontend_header':
                    if ($this->isFrontPage && $placement == 'page header') {
                        echo $this->getHTML();
                    }
                    return true;
                    break;
                case 'entries_header':
                    if ($this->isFrontPage && $placement == 'entry top') {
                        echo $this->getHTML();
                    }
                    return true;
                    break;
                case 'entries_footer':
                    if ($this->isFrontPage && $placement == 'entry bottom') {
                        // Entry footer markup is ugly.  Close the div.
                        echo '</div>';
                        echo $this->getHTML();
                        // Reopen the div we closed to avoid bad markup.
                        echo '<div>';
                    }
                    return true;
                    break;
                case 'frontend_footer':
                    if ($this->isFrontPage && $placement == 'page footer') {
                        echo $this->getHTML();
                    }
                    return true;
                    break;
                case 'newsbox:get_content':
                    // Custom hook to retrieve data for contained newsboxes.
                    // If the container asking for content is my container,
                    // add my content to the data array.
                    if ($addlData['id'] == $placement) {
                        // 1. Avoid recursion.
                        // 2. Go to step 1.
                        if (!$this->got_content[$addlData['id']]) {
                            $this->got_content[$addlData['id']] = true;
                            $eventData[] = $this->getHTML();
                        }
                        return true;
                    }
                    break;
                case 'newsbox:get_containers':
                    // Custom hook to find newsbox containers.  If I'm a newsbox
                    // container, return my instance ID.
                    if ($addlData['id'] != $this->instance && $this->get_config('content_type', 'categories') == 'newsboxes') {
                        $eventData[] = array('id' => $this->instance, 'name' => 'Newsbox: ' . $this->get_config('title', PLUGIN_EVENT_NEWSBOX_DEFAULT_TITLE));
                        return true;
                    }
                    break;
                default:
                    return false;
                    break;
            }
        } else {
            return false;
        }
        return true;
    }
/**
 * Smarty Function: Fetch and print a single or multiple entries
 *
 * @access public
 * @param   array       Smarty parameter input array:
 *                      [FETCHING]
 *                          category:        (int)     The category ID (seperate multiple with ";") to fetch entries from
 *                          viewAuthor:      (int)     The author ID (seperate multiple with ";") to fetch entries from
 *                          page:            (int)     The number of the page for paginating entries
 *                          id:              (int)     The ID of an entry. If given, only a single entry will be fetched. If left empty, multiple entries are fetched.
 *                          range:           (mixed)   Restricts fetching entries to a specific timespan. Behaves differently depending on the type:
 *                                           Numeric:
 *                                            YYYYMMDD - Shows all entries from YYYY-MM-DD.
 *                                            If DD is "00", it will show all entries from that month.
 *                                            If DD is any other number, it will show entries of that specific day.
 *                                           2-Dimensional Array:
 *                                            Key #0   - Specifies the start timestamp (unix seconds)
 *                                            Key #1   - Specifies the end timestamp (unix seconds)
 *                                           Other (null, 3-dimensional Array, ...):
 *                                            Entries newer than $modified_since will be fetched
 *                          full             (boolean) Indicates if the full entry will be fetched (body+extended: TRUE), or only the body (FALSE).
 *                          limit            (string)  Holds a "Y" or "X, Y" string that tells which entries to fetch. X is the first entry offset, Y is number of entries. If not set, the global fetchLimit will be applied (15 entries by default)
 *                          fetchDrafts      (boolean) Indicates whether drafts should be fetched (TRUE) or not
 *                          modified_since   (int)     Holds a unix timestamp to be used in conjunction with $range, to fetch all entries newer than this timestamp
 *                          orderby          (string)  Holds the SQL "ORDER BY" statement.
 *                          filter_sql       (string)  Can contain any SQL code to inject into the central SQL statement for fetching the entry
 *                          noCache          (boolean) If set to TRUE, all entries will be fetched from scratch and any caching is ignored
 *                          noSticky         (boolean) If set to TRUE, all sticky entries will NOT be fetched.
 *                          select_key       (string)  Can contain a SQL statement on which keys to select. Plugins can also set this, pay attention!
 *                          group_by         (string)  Can contain a SQL statement on how to group the query. Plugins can also set this, pay attention!
 *                          returncode       (string)  If set to "array", the array of entries will be returned. "flat-array" will only return the articles without their entryproperties. "single" will only return a 1-dimensional array. "query" will only return the used SQL.
 *                          joinauthors      (bool)    Should an SQL-join be made to the AUTHORS DB table?
 *                          joincategories   (bool)    Should an SQL-join be made to the CATEGORIES DB table?
 *                          joinown          (string)  SQL-Parts to add to the "JOIN" query
 *                          entryprops       (string)  Condition list of commaseparated entryproperties that an entry must have to be displayed (example: "ep_CustomField='customVal',ep_CustomField2='customVal2'")
 *
 *                      [PRINTING]
 *                          template:          (string)  Name of the template file to print entries with
 *                          preview:           (boolean) Indicates if this is a preview
 *                          block              (string   The name of the SMARTY block that this gets parsed into
 *                          use_hooks          (boolean  Indicates whether to apply footer/header event hooks
 *                          use_footer         (boolean  Indicates whether the pagination footer should be displayed
 *                          groupmode          (string   Indicates whether the input $entries array is already grouped in preparation for the smarty $entries output array [TRUE], or if it shall be grouped by date [FALSE]
 *                          skip_smarty_hooks  (boolean) If TRUE, no plugins will be executed at all
 *                          skip_smarty_hook   (mixed)   Can be set to an array of plugin hooks to NOT execute
 *                          prevent_reset      (boolean) If set to TRUE, the smarty $entries array will NOT be cleared. (to prevent possible duplicate output of entries)
 * @param   object      Smarty object
 * @return  string      The Smarty HTML response
 */
function serendipity_smarty_fetchPrintEntries($params, &$smarty)
{
    global $serendipity;
    static $entrycount = 0;
    static $restore_var_GET_keys = array('category', 'viewAuthor', 'page', 'hide_category');
    // A counter variable to not assign template files multiple times
    $entrycount++;
    // Default values for function calls
    if (empty($params['template'])) {
        $params['template'] = 'entries.tpl';
    }
    if (empty($params['range'])) {
        $params['range'] = null;
    }
    if (empty($params['full'])) {
        $params['full'] = true;
    }
    if (empty($params['fetchDrafts'])) {
        $params['fetchDrafts'] = false;
    }
    if (!empty($params['entryprops'])) {
        if (preg_match_all('@(.*)(!)?=[\'"]*([^\'"]+)[\'"]*(,|$)@imsU', $params['entryprops'], $m)) {
            foreach ($m[0] as $idx => $p) {
                $params['joinown'] .= "\n JOIN {$serendipity['dbPrefix']}entryproperties \n                                          AS ep" . $idx . " \n                                          ON (ep" . $idx . ".entryid = e.id AND \n                                              ep" . $idx . ".property = '" . serendipity_db_escape_string($m[1][$idx]) . "' AND \n                                              ep" . $idx . ".value " . $m[2][$idx] . "= '" . serendipity_db_escape_string($m[3][$idx]) . "') \n";
            }
        }
    }
    if (empty($params['modified_since'])) {
        $params['modified_since'] = false;
    }
    if (empty($params['orderby'])) {
        $params['orderby'] = 'timestamp DESC';
    }
    if (empty($params['noCache'])) {
        $params['noCache'] = false;
    }
    if (empty($params['noSticky'])) {
        $params['noSticky'] = false;
    }
    if (empty($params['preview'])) {
        $params['preview'] = false;
    }
    if (empty($params['block'])) {
        $params['block'] = 'smarty_entries_' . $entrycount;
    }
    if (empty($params['use_hooks'])) {
        $params['use_hooks'] = false;
    }
    if (empty($params['use_footer'])) {
        $params['use_footer'] = false;
    }
    if (empty($params['groupmode'])) {
        $params['groupmode'] = 'date';
    }
    if (empty($params['skip_smarty_hooks'])) {
        $params['skip_smarty_hooks'] = true;
    }
    if (empty($params['skip_smarty_hook'])) {
        $params['skip_smarty_hook'] = array();
    }
    if (empty($params['prevent_reset'])) {
        $params['prevent_reset'] = false;
    }
    if (empty($params['select_key'])) {
        $params['select_key'] = null;
    }
    if (empty($params['group_by'])) {
        $params['group_by'] = null;
    }
    if (empty($params['returncode'])) {
        $params['returncode'] = 'array';
    }
    if (empty($params['joinauthors'])) {
        $params['joinauthors'] = true;
    }
    if (empty($params['joincategories'])) {
        $params['joincategories'] = true;
    }
    // Some functions deal with the $serendipity array. To modify them, we need to store
    // their original contents.
    $old_var = array();
    if (!empty($params['short_archives'])) {
        $old_var['short_archives'] = $serendipity['short_archives'];
        $serendipity['short_archives'] = $params['short_archives'];
    }
    $old_var['skip_smarty_hooks'] = $serendipity['skip_smarty_hooks'];
    $serendipity['skip_smarty_hooks'] = $params['skip_smarty_hooks'];
    $old_var['skip_smarty_hook'] = $serendipity['skip_smarty_hook'];
    $serendipity['skip_smarty_hook'] = $params['skip_smarty_hook'];
    foreach ($restore_var_GET_keys as $key) {
        if (!empty($params[$key])) {
            $old_var['GET'][$key] = $serendipity['GET'][$key];
            $serendipity['GET'][$key] = $params[$key];
        }
    }
    if (!empty($params['id'])) {
        $entry = serendipity_fetchEntry('id', (int) $params['id'], $params['full'], $params['fetchDrafts']);
    } else {
        $entry = serendipity_fetchEntries($params['range'], $params['full'], $params['limit'], $params['fetchDrafts'], $params['modified_since'], $params['orderby'], $params['filter_sql'], $params['noCache'], $params['noSticky'], $params['select_key'], $params['group_by'], $params['returncode'], $params['joinauthors'], $params['joincategories'], $params['joinown']);
        // Check whether the returned entries shall be grouped specifically
        switch ($params['groupmode']) {
            case 'date':
                // No regrouping required, printEntries() does it for us.
                break;
            case 'category':
                // Regroup by primary category
                $groupdata = array();
                foreach ($entry as $k => $_entry) {
                    if (is_array($entry['categories'])) {
                        $groupkey = $entry['categories'][0];
                    } else {
                        $groupkey = 'none';
                    }
                    $groupdata[$groupkey]['entries'] =& $_entry;
                }
                $entry =& $groupdata;
                break;
        }
    }
    if ($params['returncode'] == 'query') {
        return print_r($entry, true);
    }
    serendipity_printEntries($entry, !empty($params['id']) ? true : false, $params['preview'], 'ENTRIES', false, $params['use_hooks'], $params['use_footer'], $params['groupmode'] == 'date' ? false : true);
    // Restore the $serendipity array after our modifications.
    if (isset($old_var['short_archives'])) {
        $serendipity['short_archives'] = $old_var['short_archives'];
    }
    if (is_array($old_var['GET'])) {
        foreach ($old_var['GET'] as $key => $val) {
            $serendipity['GET'][$key] = $val;
        }
    }
    $out = serendipity_smarty_fetch($params['block'], $params['template']);
    // Reset array list, because we might be in a nested code call.
    if ($params['prevent_reset'] == false) {
        $serendipity['smarty']->assign('entries', array());
    }
    $serendipity['skip_smarty_hook'] = $old_var['skip_smarty_hook'];
    $serendipity['skip_smarty_hooks'] = $old_var['skip_smarty_hooks'];
    return $out;
}
 function smarty_customArchive($params, &$smarty)
 {
     global $serendipity;
     if (isset($serendipity['GET']['filter'])) {
         $params['filter'] = $serendipity['GET']['filter'];
     }
     if (isset($serendipity['POST']['filter'])) {
         $params['filter'] = $serendipity['POST']['filter'];
     }
     if (isset($serendipity['GET']['mode'])) {
         $params['mode'] = $serendipity['GET']['mode'];
     }
     if (isset($serendipity['POST']['mode'])) {
         $params['mode'] = $serendipity['POST']['mode'];
     }
     if (strtolower($params['mode']) != 'asc' && strtolower($params['mode'] != 'desc')) {
         $params['mode'] = 'asc';
     }
     if (empty($params['template'])) {
         $params['template'] = 'customarchive.tpl';
     }
     $_key_props = explode(',', $params['entryprops']);
     $key_props = array();
     $add_props = array();
     $valid_filter = false;
     foreach ($_key_props as $prop) {
         $propparts = explode(':', trim($prop));
         $prop = $propparts[0];
         if (isset($propparts[1])) {
             $add_props['ep_' . $prop] = $propparts[1];
         }
         $key_props[] = 'ep_' . $prop;
         if (empty($params['filter'])) {
             $params['filter'] = $prop;
         }
         if ($prop == $params['filter']) {
             $valid_filter = true;
         }
     }
     $props = explode(',', $params['sortfields']);
     $name_props = array();
     foreach ($props as $prop) {
         $propparts = explode(':', trim($prop));
         if (isset($propparts[1])) {
             $name_props['ep_' . $propparts[0]] = $propparts[1];
         } else {
             $name_props['ep_' . $propparts[0]] = $propparts[0];
         }
     }
     $props = explode(',', $params['searchfields']);
     $search_props = array();
     foreach ($props as $prop) {
         $propparts = explode(':', trim($prop));
         $sfields = explode('+', $propparts[0]);
         foreach ($sfields as $sfield) {
             $search_props[$propparts[2]]['fields']['ep_' . $sfield] = true;
         }
         $search_props[$propparts[2]]['type'] = strtolower($propparts[1]);
         $search_props[$propparts[2]]['key'] = md5($propparts[0]);
     }
     $searchdata = $serendipity['POST']['search'];
     if (!is_array($searchdata)) {
         $searchdata = array();
     }
     $props = explode(',', $params['valuelimit']);
     $values_props = array();
     foreach ($props as $prop) {
         $propparts = explode(':', trim($prop));
         $sfields = explode('-', $propparts[1]);
         $values_props['ep_' . $propparts[0]]['from'] = $sfields[0];
         $values_props['ep_' . $propparts[0]]['to'] = $sfields[1];
     }
     $serendipity['smarty']->assign('customarchive_props', $name_props);
     $serendipity['smarty']->assign('customarchive_keyprops', $key_props);
     $serendipity['smarty']->assign('customarchive_infoprops', $add_props);
     $serendipity['smarty']->assign('customarchive_filter', $params['filter']);
     $serendipity['smarty']->assign('customarchive_teaser', 'ep_' . $params['teaser']);
     $serendipity['smarty']->assign('customarchive_subpage', $serendipity['GET']['subpage']);
     $serendipity['smarty']->assign('customarchive_picture', 'ep_' . $params['picture']);
     $serendipity['smarty']->assign('customarchive_nextmode', strtolower($params['mode']) == 'desc' ? 'asc' : 'desc');
     $serendipity['smarty']->assign('customarchive_mode', strtolower($params['mode']));
     $serendipity['smarty']->assign('customarchive_search', $search_props);
     $serendipity['smarty']->assign('customarchive_searchdata', $searchdata);
     $lookup = array();
     foreach ($key_props as $idx => $prop) {
         $and = '';
         $lookup[$prop] = 'ep' . $idx;
         if ($prop == 'ep_' . $params['filter'] && $valid_filter) {
             $filteridx = $idx;
             $params['joinown'] .= "\n JOIN {$serendipity['dbPrefix']}entryproperties\n                                          AS ep" . $idx . "\n                                          ON (ep" . $idx . ".entryid = e.id AND\n                                              ep" . $idx . ".property = '" . serendipity_db_escape_string($prop) . "' {$and}) \n";
         } else {
             $params['joinown'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}entryproperties\n                                          AS ep" . $idx . "\n                                          ON (ep" . $idx . ".entryid = e.id AND\n                                              ep" . $idx . ".property = '" . serendipity_db_escape_string($prop) . "' {$and}) \n";
         }
     }
     $sql_where = '';
     $sql_where_parts = array();
     $searchdata_from = $searchdata_to = array();
     if (is_array($serendipity['POST']['search'])) {
         foreach ($serendipity['POST']['search'] as $skey => $sdata) {
             if (!is_array($sdata)) {
                 $sdata = trim($sdata);
             }
             if (empty($sdata)) {
                 continue;
             }
             foreach ($search_props as $sdesc => $sdata2) {
                 if ($sdata2['key'] == $skey) {
                     if ($sdata2['type'] == 'text') {
                         $parts = array();
                         foreach ($sdata2['fields'] as $fieldkey => $fieldval) {
                             $parts[] = $lookup[$fieldkey] . '.value LIKE "%' . serendipity_db_escape_string($sdata) . '%"';
                         }
                         $sql_where_parts[] .= "\n(" . implode(' OR ', $parts) . ")\n";
                     } elseif ($sdata2['type'] == 'int') {
                         $parts = array();
                         foreach ($sdata2['fields'] as $fieldkey => $fieldval) {
                             if (!empty($sdata['from'])) {
                                 $parts[] = 'CAST(' . $lookup[$fieldkey] . '.value AS unsigned) >= ' . serendipity_db_escape_string($sdata['from']);
                             }
                             if (!empty($sdata['to'])) {
                                 $parts[] = 'CAST(' . $lookup[$fieldkey] . '.value AS unsigned) <= ' . serendipity_db_escape_string($sdata['to']);
                             }
                             $searchdata_from[$sdata2['key']] = $sdata['from'];
                             $searchdata_to[$sdata2['key']] = $sdata['to'];
                         }
                         if (count($parts) > 0) {
                             $sql_where_parts[] .= "\n(" . implode(' AND ', $parts) . ")\n";
                         }
                     }
                 }
             }
         }
         $sql_where = implode(" AND ", $sql_where_parts);
     } elseif (count($values_props) > 0) {
         $sql_where_parts = array();
         foreach ($values_props as $vfieldname => $vfieldvals) {
             $sql_where_parts[] = '(CAST(' . $lookup[$vfieldname] . '.value AS unsigned) >= ' . $vfieldvals['from'] . ' 
                                    AND CAST(' . $lookup[$vfieldname] . '.value AS unsigned) <= ' . $vfieldvals['to'] . ')' . "\n";
         }
         $sql_where .= implode(" AND ", $sql_where_parts);
     }
     $serendipity['smarty']->assign('customarchive_searchdata_from', $searchdata_from);
     $serendipity['smarty']->assign('customarchive_searchdata_to', $searchdata_to);
     if (empty($filteridx)) {
         $filteridx = 0;
     }
     $cat = $serendipity['GET']['category'];
     unset($serendipity['GET']['category']);
     #if ($sql_where != '') $GLOBALS['Dbdie'] = true;
     $entries = serendipity_fetchEntries(null, true, $params['limit'], false, false, 'CAST(ep' . $filteridx . '.value AS UNSIGNED) ' . $params['mode'], $sql_where, false, false, null, null, 'array', true, true, $params['joinown']);
     $dategroup = array(0 => array('entries' => $entries, 'timestamp' => time()));
     $GLOBALS['DBTEST'] = true;
     $entries = serendipity_printEntries($dategroup, true, false, 'CUSTOMARCHIVE_ENTRIES', 'return', false, false, true);
     if (!empty($cat)) {
         $serendipity['GET']['category'] = $cat;
     }
     $serendipity['smarty']->assign('customarchive_entries', $entries);
     $filename = basename($params['template']);
     $tfile = serendipity_getTemplateFile($filename, 'serendipityPath');
     if (!$tfile || $tfile == $filename) {
         $tfile = dirname(__FILE__) . '/' . $filename;
     }
     $inclusion = $serendipity['smarty']->security_settings[INCLUDE_ANY];
     $serendipity['smarty']->security_settings[INCLUDE_ANY] = true;
     $content = $serendipity['smarty']->fetch('file:' . $tfile);
     $serendipity['smarty']->security_settings[INCLUDE_ANY] = $inclusion;
     $serendipity['smarty']->assign('ENTRIES', 'xxx');
     return $content;
 }
    function event_hook($event, &$bag, &$eventData, $addData = null)
    {
        global $serendipity;
        $hooks =& $bag->get('event_hooks');
        $links = array();
        if (isset($hooks[$event])) {
            $sort_order = array('timestamp' => DATE, 'isdraft' => PUBLISH . '/' . DRAFT, 'a.realname' => AUTHOR, 'category_name' => CATEGORY, 'last_modified' => LAST_UPDATED, 'title' => TITLE);
            $per_page_max = 50;
            $per_page = array('12', '16', '25', $per_page_max);
            switch ($event) {
                case 'frontend_fetchentries':
                    if ($this->fetchLimit > 0) {
                        $serendipity['fetchLimit'] = $this->fetchLimit;
                    }
                    break;
                case 'frontend_configure':
                    $_SERVER['REQUEST_URI'] = str_replace('%2Fplugin%2Ffilter%2F', '/plugin/filter/', $_SERVER['REQUEST_URI']);
                    break;
                case 'entries_footer':
                    $link = $serendipity['baseURL'] . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] . '?/' : '') . 'plugin/filter/';
                    ?>
<div id="filter_entries_container">
    <br />
    <hr />
    <form action="<?php 
                    echo $link;
                    ?>
" method="get">

    <?php 
                    if ($serendipity['rewrite'] == 'none') {
                        ?>
    <input type="hidden" name="/plugin/filter/" value="" />
    <?php 
                    }
                    ?>
    <table width="100%">
        <tr>
            <td colspan="6" style="text-align: left"><strong><?php 
                    echo FILTERS;
                    ?>
</strong> - <?php 
                    echo FIND_ENTRIES;
                    ?>
</td>
        </tr>
        <tr>
            <td width="80"><?php 
                    echo AUTHOR;
                    ?>
</td>
            <td>
                <select name="filter[author]">
                    <option value="">--</option>
<?php 
                    $users = serendipity_fetchUsers();
                    if (is_array($users)) {
                        foreach ($users as $user) {
                            echo '<option value="' . $user['authorid'] . '" ' . (isset($_SESSION['filter']['author']) && $_SESSION['filter']['author'] == $user['authorid'] ? 'selected="selected"' : '') . '>' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($user['realname']) : htmlspecialchars($user['realname'], ENT_COMPAT, LANG_CHARSET)) . '</option>' . "\n";
                        }
                    }
                    ?>
              </select>
            </td>
            <td width="80"><?php 
                    echo CATEGORY;
                    ?>
</td>
            <td>
                <select name="filter[category]">
                    <option value="">--</option>
<?php 
                    $categories = serendipity_fetchCategories();
                    $categories = serendipity_walkRecursive($categories, 'categoryid', 'parentid', VIEWMODE_THREADED);
                    foreach ($categories as $cat) {
                        echo '<option value="' . $cat['categoryid'] . '"' . ($_SESSION['filter']['category'] == $cat['categoryid'] ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp;', $cat['depth']) . $cat['category_name'] . '</option>' . "\n";
                    }
                    ?>
              </select>
            </td>
            <td width="80"><?php 
                    echo CONTENT;
                    ?>
</td>
            <td><input size="10" type="text" name="filter[body]" value="<?php 
                    echo isset($_SESSION['filter']['body']) ? function_exists('serendipity_specialchars') ? serendipity_specialchars($_SESSION['filter']['body']) : htmlspecialchars($_SESSION['filter']['body'], ENT_COMPAT, LANG_CHARSET) : '';
                    ?>
" /></td>
        </tr>
        <tr>
            <td colspan="6" style="text-align: left"><strong><?php 
                    echo SORT_ORDER;
                    ?>
</strong></td>
        </tr>
        <tr>
            <td><?php 
                    echo SORT_BY;
                    ?>
</td>
            <td>
                <select name="sort[order]">
<?php 
                    foreach ($sort_order as $so_key => $so_val) {
                        echo '<option value="' . $so_key . '" ' . (isset($_SESSION['sort']['order']) && $_SESSION['sort']['order'] == $so_key ? 'selected="selected"' : '') . '>' . $so_val . '</option>' . "\n";
                    }
                    ?>
              </select>
            </td>
            <td><?php 
                    echo SORT_ORDER;
                    ?>
</td>
            <td>
                <select name="sort[ordermode]">
                    <option value="DESC" <?php 
                    echo isset($_SESSION['sort']['ordermode']) && $_SESSION['sort']['ordermode'] == 'DESC' ? 'selected="selected"' : '';
                    ?>
><?php 
                    echo SORT_ORDER_DESC;
                    ?>
</option>
                    <option value="ASC" <?php 
                    echo isset($_SESSION['sort']['ordermode']) && $_SESSION['sort']['ordermode'] == 'ASC' ? 'selected="selected"' : '';
                    ?>
><?php 
                    echo SORT_ORDER_ASC;
                    ?>
</option>
                </select>
            </td>
            <td><?php 
                    echo ENTRIES_PER_PAGE;
                    ?>
</td>
            <td>
                <select name="sort[perPage]">
<?php 
                    foreach ($per_page as $per_page_nr) {
                        echo '<option value="' . $per_page_nr . '"   ' . (isset($_SESSION['sort']['perPage']) && $_SESSION['sort']['perPage'] == $per_page_nr ? 'selected="selected"' : '') . '>' . $per_page_nr . '</option>' . "\n";
                    }
                    ?>
                </select>
            </td>
        </tr>
        <tr>
            <td align="right" colspan="6"><input type="submit" name="go" value="<?php 
                    echo GO;
                    ?>
" class="serendipityPrettyButton" /></td>
        </tr>
    </table>
</form>
</div>
<?php 
                    return true;
                    break;
                case 'external_plugin':
                    $uri_parts = explode('?', str_replace('&amp;', '&', $eventData));
                    $parts = explode('/', $uri_parts[0]);
                    $plugincode = $parts[0];
                    unset($parts[0]);
                    $uri = $_SERVER['REQUEST_URI'];
                    $puri = parse_url($uri);
                    $queries = explode('&', str_replace(array('%5B', '%5D'), array('[', ']'), $puri['query']));
                    foreach ($queries as $query_part) {
                        $query = explode('=', $query_part);
                        switch ($query[0]) {
                            case 'filter[author]':
                                $_GET['filter']['author'] = urldecode($query[1]);
                                break;
                            case 'filter[category]':
                                $_GET['filter']['category'] = urldecode($query[1]);
                                break;
                            case 'filter[body]':
                                $_GET['filter']['body'] = urldecode($query[1]);
                                break;
                            case 'sort[order]':
                                $_GET['sort']['order'] = urldecode($query[1]);
                                break;
                            case 'sort[ordermode]':
                                $_GET['sort']['ordermode'] = urldecode($query[1]);
                                break;
                            case 'sort[perPage]':
                                $_GET['sort']['perPage'] = urldecode($query[1]);
                                break;
                        }
                    }
                    if (is_array($_GET['filter'])) {
                        $_SESSION['filter'] = $_GET['filter'];
                    }
                    if (is_array($_GET['sort'])) {
                        $_SESSION['sort'] = $_GET['sort'];
                    }
                    /* Attempt to locate hidden variables within the URI */
                    foreach ($serendipity['uriArguments'] as $k => $v) {
                        if ($v[0] == 'P') {
                            /* Page */
                            $page = substr($v, 1);
                            if (is_numeric($page)) {
                                $serendipity['GET']['page'] = $page;
                                unset($serendipity['uriArguments'][$k]);
                            }
                        }
                    }
                    switch ($plugincode) {
                        case 'filter':
                            $perPage = (int) (!empty($_SESSION['sort']['perPage']) ? $_SESSION['sort']['perPage'] : $per_page[0]);
                            if ($perPage > $per_page_max) {
                                $perPage = $per_page_max;
                            }
                            $serendipity['fetchLimit'] = $perPage;
                            $this->fetchLimit = $perPage;
                            $page = (int) $serendipity['GET']['page'];
                            if ($page == 0) {
                                $page = 1;
                            }
                            $offSet = $perPage * ($page - 1);
                            if (empty($_SESSION['sort']['ordermode']) || $_SESSION['sort']['ordermode'] != 'ASC') {
                                $_SESSION['sort']['ordermode'] = 'DESC';
                            }
                            if (!empty($_SESSION['sort']['order']) && !empty($sort_order[$_SESSION['sort']['order']])) {
                                $orderby = serendipity_db_escape_string($_SESSION['sort']['order'] . ' ' . $_SESSION['sort']['ordermode']);
                            } else {
                                $orderby = 'timestamp ' . serendipity_db_escape_string($_SESSION['sort']['ordermode']);
                            }
                            $filter = array();
                            if (!empty($_SESSION['filter']['author'])) {
                                $filter[] = "e.authorid = '" . serendipity_db_escape_string($_SESSION['filter']['author']) . "'";
                            }
                            if (!empty($_SESSION['filter']['category'])) {
                                $filter[] = "ec.categoryid = '" . serendipity_db_escape_string($_SESSION['filter']['category']) . "'";
                            }
                            if (!empty($_SESSION['filter']['body'])) {
                                if ($serendipity['dbType'] == 'mysql') {
                                    $filter[] = "MATCH (title,body,extended) AGAINST ('" . serendipity_db_escape_string($_SESSION['filter']['body']) . "')";
                                    $full = true;
                                }
                            }
                            $filter_sql = implode(' AND ', $filter);
                            // Fetch the entries
                            $entries = serendipity_fetchEntries(false, false, serendipity_db_limit($offSet, $perPage), true, false, $orderby, $filter_sql);
                            $serendipity['smarty_raw_mode'] = true;
                            include_once S9Y_INCLUDE_PATH . 'include/genpage.inc.php';
                            serendipity_printEntries($entries);
                            $raw_data = ob_get_contents();
                            ob_end_clean();
                            $serendipity['smarty']->assign('CONTENT', $raw_data);
                            $serendipity['smarty']->assign('is_raw_mode', false);
                            serendipity_gzCompression();
                            $serendipity['smarty']->display(serendipity_getTemplateFile($serendipity['smarty_file'], 'serendipityPath'));
                            break;
                    }
                    return true;
                    break;
                default:
                    return false;
                    break;
            }
        } else {
            return false;
        }
    }