function displayUserList()
 {
     global $serendipity;
     $userlist = serendipity_fetchUsers();
     $content = "";
     foreach ($userlist as $user) {
         if (function_exists('serendipity_authorURL')) {
             $entryLink = serendipity_authorURL($user);
         } else {
             $entryLink = serendipity_rewriteURL(PATH_AUTHORS . '/' . serendipity_makePermalink(PERM_AUTHORS, array('id' => $user['authorid'], 'title' => $user['realname'])));
         }
         $content .= sprintf("<a href=\"%s\" title=\"%s\">%s</a><br />\n", $entryLink, function_exists('serendipity_specialchars') ? serendipity_specialchars($user['realname']) : htmlspecialchars($user['realname'], ENT_COMPAT, LANG_CHARSET), function_exists('serendipity_specialchars') ? serendipity_specialchars($user['realname']) : htmlspecialchars($user['realname'], ENT_COMPAT, LANG_CHARSET));
     }
     return $content;
 }
 function generate_content(&$title)
 {
     global $serendipity;
     $title = $this->get_config('title', $this->title);
     $authors_query = "SELECT realname, username, authorid FROM {$serendipity['dbPrefix']}authors";
     $row_authors = serendipity_db_query($authors_query);
     echo '<ul class="plainList">';
     foreach ($row_authors as $entry) {
         if (function_exists('serendipity_authorURL')) {
             $entryLink = serendipity_authorURL($entry);
         } else {
             $entryLink = serendipity_rewriteURL(PATH_AUTHORS . '/' . serendipity_makePermalink(PERM_AUTHORS, array('id' => $entry['authorid'], 'title' => $entry['realname'])));
         }
         echo '<li><a href="' . $entryLink . '">' . $entry['realname'] . '</a></li>';
     }
     echo '</ul>';
 }
 function generateSitemap(&$bag)
 {
     global $serendipity;
     // decide which NULL-function to use
     switch ($serendipity['dbType']) {
         case 'postgres':
             $sqlnullfunction = 'COALESCE';
             break;
         case 'sqlite':
         case 'mysql':
         case 'mysqli':
             $sqlnullfunction = 'IFNULL';
             break;
         default:
             $sqlnullfunction = '';
     }
     $hooks =& $bag->get('event_hooks');
     $do_pingback = serendipity_db_bool($this->get_config('sitemap_pingback', false));
     $pingback_url = $this->get_config('sitemap_pingback_urls', false);
     // start the xml
     $sitemap_xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
     $sitemap_xml .= "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n";
     $sitemap_xml .= "\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
     $sitemap_xml .= "\txsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n";
     $sitemap_xml .= "\t\t\thttp://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">\n";
     // add link to the main page
     $this->addtoxml($sitemap_xml, $serendipity['baseURL'], time(), 0.6);
     // fetch all entries from the db (tested with: mysql, sqlite, postgres)
     $entries = serendipity_db_query('SELECT
                             entries.id AS id,
                             entries.title AS title,
                             ' . $sqlnullfunction . '(entries.last_modified,0) AS timestamp_1,
                             ' . $sqlnullfunction . '(MAX(comments.timestamp),0) AS timestamp_2
                         FROM ' . $serendipity['dbPrefix'] . 'entries entries
                         LEFT JOIN ' . $serendipity['dbPrefix'] . 'comments comments
                         ON entries.id = comments.entry_id
                         WHERE entries.isdraft = \'false\'
                         GROUP BY entries.id, entries.title, entries.last_modified
                         ORDER BY entries.id', false, 'assoc');
     if (is_array($entries)) {
         // add entries
         foreach ($entries as $entry) {
             $max = max($entry['timestamp_1'] + 0, $entry['timestamp_2'] + 0);
             $url = serendipity_archiveURL($entry['id'], $entry['title']);
             $this->addtoxml($sitemap_xml, $url, $max, 0.7);
         }
     }
     // add possible perm links
     $permlink = serendipity_db_query('SELECT entryid, timestamp, value
                          FROM ' . $serendipity['dbPrefix'] . 'entryproperties AS entryproperties,
                               ' . $serendipity['dbPrefix'] . 'entries AS entries
                          WHERE entryproperties.property = \'permalink\'
                                AND entries.id=entryproperties.entryid', false, 'assoc');
     if (is_array($permlink)) {
         foreach ($permlink as $cur) {
             $path_quoted = preg_quote($serendipity['serendipityHTTPPath'], '#');
             $url = $serendipity['baseURL'] . preg_replace("#{$path_quoted}#", '', $cur['value'], 1);
             $cur_time = $cur['timestamp'] == 0 ? null : (int) $cur['timestamp'];
             $this->addtoxml($sitemap_xml, $url, $cur_time, 0.8);
         }
         // check for the right order of plugins
         $order = serendipity_db_query('SELECT name, sort_order
                          FROM ' . $serendipity['dbPrefix'] . 'plugins plugins
                          WHERE plugins.name LIKE \'%serendipity_event_mobile_output%\'
                             OR plugins.name LIKE \'%serendipity_event_custom_permalinks%\'
                          ORDER BY plugins.sort_order', false, 'assoc');
         if (is_array($order)) {
             if (strpos($order[0]['name'], 'serendipity_event_custom_permalinks') === FALSE) {
                 echo '<br/>' . PLUGIN_EVENT_MOBILE_OUTPUT_SITEMAP_PERMALINK_WARNING . '<br/>';
             }
         }
     }
     // fetch categories and their last entry date (tested with: mysql, sqlite, postgres)
     $q = 'SELECT
                             category.categoryid AS id,
                             category_name,
                             category_description,
                             MAX(entries.last_modified) AS last_mod
                         FROM
                             ' . $serendipity['dbPrefix'] . 'category category,
                             ' . $serendipity['dbPrefix'] . 'entrycat entrycat,
                             ' . $serendipity['dbPrefix'] . 'entries entries
                         WHERE
                             category.categoryid = entrycat.categoryid
                             AND
                             entrycat.entryid = entries.id
                         GROUP BY
                             category.categoryid,
                             category.category_name,
                             category.category_description
                         ORDER BY category.categoryid';
     $categories = serendipity_db_query($q, false, 'assoc');
     // add categories
     if (is_array($categories)) {
         foreach ($categories as $category) {
             $max = 0 + $category['last_mod'];
             /* v0.9 */
             if (version_compare((double) $serendipity['version'], '0.9', '>=')) {
                 $data = array('categoryid' => $category['id'], 'category_name' => $category['category_name'], 'category_description' => $category['category_description']);
                 $url = serendipity_categoryURL($data);
             } else {
                 $url = serendipity_rewriteURL(PATH_CATEGORIES . '/' . serendipity_makePermalink(PERM_CATEGORIES, array('id' => $category['id'], 'title' => $category['category_name'])));
             }
             $this->addtoxml($sitemap_xml, $url, $max, 0.4);
         }
     } else {
         $categories = array();
     }
     // finish the xml
     $sitemap_xml .= "</urlset>\n";
     $do_gzip = serendipity_db_bool($this->get_config('gzip_sitemap', true));
     // decide whether to use gzip-output or not
     if ($do_gzip && function_exists('gzencode')) {
         $filename = '/mobile_sitemap.xml.gz';
         $temp = gzencode($sitemap_xml);
         // only use the compressed data and filename if no error occured
         if (!($temp === FALSE)) {
             $sitemap_xml = $temp;
         } else {
             $filename = '/mobile_sitemap.xml';
         }
     } else {
         $filename = '/mobile_sitemap.xml';
     }
     // write result to file
     $outfile = fopen($serendipity['serendipityPath'] . $filename, 'w');
     if ($outfile === false) {
         echo '<strong>' . PLUGIN_EVENT_MOBILE_OUTPUT_SITEMAP_FAILEDOPEN . '</strong>';
         return false;
     }
     flock($outfile, LOCK_EX);
     fputs($outfile, $sitemap_xml);
     flock($outfile, LOCK_UN);
     fclose($outfile);
     // Walk through the list of pingback-URLs
     foreach (explode(';', $pingback_url) as $cur_pingback_url) {
         $pingback_name = PLUGIN_EVENT_MOBILE_OUTPUT_SITEMAP_UNKNOWN_HOST;
         $cur_url = sprintf($cur_pingback_url, rawurlencode($serendipity['baseURL'] . $filename));
         // extract domain-portion from URL
         if (preg_match('@^https?://([^/]+)@', $cur_pingback_url, $matches) > 0) {
             $pingback_name = $matches[1];
         }
         if (!serendipity_db_bool($eventData['isdraft']) && $do_pingback && $cur_url) {
             $answer = $this->send_ping($cur_url);
             if ($answer) {
                 printf(PLUGIN_EVENT_MOBILE_OUTPUT_SITEMAP_REPORT_OK, $pingback_name);
             } else {
                 printf(PLUGIN_EVENT_MOBILE_OUTPUT_SITEMAP_REPORT_ERROR, $pingback_name, $cur_url);
             }
         } else {
             printf(PLUGIN_EVENT_MOBILE_OUTPUT_SITEMAP_REPORT_MANUAL, $pingback_name, $cur_url);
         }
     }
     return true;
 }
/**
 * Create a permalink for an RSS authors' feed permalink
 *
 * @access public
 * @param   array   The entry data
 * @param   string  The base URL/path key
 * @param   boolean Shall the link be rewritten to a pretty URL?
 * @return  string  The permalink
 */
function serendipity_feedAuthorURL(&$data, $key = 'baseURL', $checkrewrite = true)
{
    global $serendipity;
    $path = serendipity_makePermalink($serendipity['permalinkFeedAuthorStructure'], $data, 'author');
    if ($checkrewrite) {
        $path = serendipity_rewriteURL($path, $key);
    }
    return $path;
}
 /**
  * Creates a DHTML menu of serendipity categories.
  *
  * The menu is echoed out.
  *
  * @param  string $title  (Serves as the top level menu item if present)
  * @return void
  * @see    http://pear.php.net/HTML_TreeMenu  PEAR::HTML_TreeMenu
  */
 function generate_content(&$title)
 {
     global $serendipity;
     $title = $this->get_config('title', $this->title);
     // may want to put this in bundled_libs or a sub directory of this directory
     $pear = false;
     if (@(include_once 'HTML/TreeMenu.php')) {
         $pear = true;
     } elseif (@(include_once 'HTML_TreeMenu/TreeMenu.php')) {
         $pear = true;
     }
     if ($pear) {
         $which_category = $this->get_config('authorid');
         // build an accessible array of categories
         foreach (serendipity_fetchCategories(empty($which_category) ? 'all' : $which_category) as $cat) {
             if (!is_array($cat) || !isset($cat['categoryid'])) {
                 continue;
             }
             $categories[$cat['categoryid']] = $cat;
         }
         // create an array of numbers of entries per category
         $cat_count = array();
         if (serendipity_db_bool($this->get_config('show_count'))) {
             $cat_sql = "SELECT c.categoryid, c.category_name, count(e.id) as postings\n                                                FROM {$serendipity['dbPrefix']}entrycat ec,\n                                                     {$serendipity['dbPrefix']}category c,\n                                                     {$serendipity['dbPrefix']}entries e\n                                                WHERE ec.categoryid = c.categoryid\n                                                  AND ec.entryid = e.id\n                                                  AND e.isdraft = 'false'\n                                                      " . (!serendipity_db_bool($serendipity['showFutureEntries']) ? " AND e.timestamp  <= " . serendipity_db_time() : '') . "\n                                                GROUP BY c.categoryid, c.category_name\n                                                ORDER BY postings DESC";
             $category_rows = serendipity_db_query($cat_sql);
             if (is_array($category_rows)) {
                 foreach ($category_rows as $cat) {
                     $cat_count[$cat['categoryid']] = $cat['postings'];
                 }
             }
         }
         $image = $this->get_config('image', serendipity_getTemplateFile('img/xml.gif'));
         $image = $image == "'none'" || $image == 'none' ? '' : $image;
         // create nodes
         foreach ($categories as $cid => $cat) {
             if (function_exists('serendipity_categoryURL')) {
                 $link = serendipity_categoryURL($cat, 'serendipityHTTPPath');
             } else {
                 $link = serendipity_rewriteURL(PATH_CATEGORIES . '/' . serendipity_makePermalink(PERM_CATEGORIES, array('id' => $cat['categoryid'], 'title' => $cat['category_name'])), 'serendipityHTTPPath');
             }
             if (!empty($cat_count[$cat['categoryid']])) {
                 // $categories[$cid]['true_category_name'] = $cat['category_name'];
                 $cat['category_name'] .= ' (' . $cat_count[$cat['categoryid']] . ')';
                 // $categories[$cid]['article_count'] = $cat_count[$cat['categoryid']];
             }
             if (!empty($image)) {
                 $feedURL = serendipity_feedCategoryURL($cat, 'serendipityHTTPPath');
                 $feed = '<a class="serendipity_xml_icon" href="' . $feedURL . '"><img src="' . $image . '" alt="XML" style="border: 0px;vertical-align:middle"/></a> ';
                 $link = '<a href="' . $link . '" target="_self"><span>' . $cat['category_name'] . '</span></a>';
                 // work around a problem in HTML_TreeNode: when there is a href in 'text', 'link' is not converted to a link.
                 $cat_nodes[$cat['categoryid']] = new HTML_TreeNode(array('text' => $feed . $link));
             } else {
                 $cat_nodes[$cat['categoryid']] = new HTML_TreeNode(array('text' => $feed . $cat['category_name'], 'link' => $link));
             }
         }
         // create a top level for "all categories"
         // this serves as the title
         $cat_nodes[0] = new HTML_TreeNode(array('text' => ALL_CATEGORIES, 'link' => $serendipity['baseURL']));
         // nest nodes (thanks to PHP references)
         foreach ($categories as $category) {
             $cat_nodes[$category['parentid']]->addItem($cat_nodes[$category['categoryid']]);
         }
         // nest the "all categories" category
         $menu = new HTML_TreeMenu();
         $menu->addItem($cat_nodes[0]);
         $tree = new HTML_TreeMenu_DHTML($menu, array('images' => $serendipity['baseURL'] . $this->get_config('image_path')));
         // Add heading for block
         #$output = '<h2 class="serendipitySideBarTitle" style="font-weight: bold;">'.$title.'</h2><br />';
         // Put inside a div with "overflow:hidden" to avoid items of the sidebar plugin running outside the blog
         // Maybe we can put a config setting to choose if the block should be displayed with or without overflow setting.
         $output .= '<div style="overflow: hidden;">';
         $output .= $tree->toHTML();
         $output .= '</div>';
         echo '<script type="text/javascript" src="' . $serendipity['baseURL'] . $this->get_config('script_path') . '"></script>';
     } else {
         $output .= "Please install PEAR package HTML_TreeMenu to enable this plugin.";
     }
     echo $output;
 }
 function add_feeds(&$sitemap_xml)
 {
     global $serendipity;
     // add the category-newsfeed URLs
     if ($this->should_add('sm_categories')) {
         foreach ($this->categories as $category) {
             $max = 0 + $category['last_mod'];
             // v0.9
             if (version_compare((double) $serendipity['version'], '0.9', '>=')) {
                 $data = array('categoryid' => $category['id'], 'category_name' => $category['category_name'], 'category_description' => $category['category_description']);
                 $url = serendipity_feedCategoryURL($data);
             } else {
                 $url = serendipity_rewriteURL(PATH_FEEDS . '/' . PATH_CATEGORIES . '/' . serendipity_makePermalink(PERM_FEEDS_CATEGORIES, array('id' => $category['id'], 'title' => $category['category_name'])));
             }
             $this->addtoxml($sitemap_xml, $url, $max, 0.0);
         }
     }
     // add the global newsfeed URLs
     if ($this->should_add('sm_feeds')) {
         $filelist = array('/index.rss', '/index.rss1', '/index.rss2', '/atom.xml');
         foreach ($filelist as $curfile) {
             $url = serendipity_rewriteURL(PATH_FEEDS . $curfile);
             $this->addtoxml($sitemap_xml, $url, $max, 0.0);
         }
     }
 }
 function event_hook($event, &$bag, &$eventData, $addData = null)
 {
     global $serendipity;
     if ($event == 'frontend_header') {
         $start_url = $serendipity['baseURL'];
         $start_title = $serendipity['blogTitle'];
         echo '<link rel="start" href="' . $start_url . '" title="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($start_title) : htmlspecialchars($start_title, ENT_COMPAT, LANG_CHARSET)) . '" />' . "\n";
         if ($serendipity['GET']['action'] == 'read' && !empty($serendipity['GET']['id'])) {
             // Article detail view
             echo '<link rel="up" href="' . $start_url . '" title="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($start_title) : htmlspecialchars($start_title, ENT_COMPAT, LANG_CHARSET)) . '" />' . "\n";
             $this->backAndForth($this->showPaging($serendipity['GET']['id']));
             // END article detail view
             echo '<link rel="canonical" href="' . $this->getEntry($serendipity['GET']['id']) . '" />' . "\n";
         } elseif ($serendipity['GET']['action'] == 'read' && is_array($serendipity['range'])) {
             // Specific Date Archives view
             echo '<link rel="up" href="' . serendipity_rewriteURL(PATH_ARCHIVE) . '" title="' . ARCHIVES . '" />' . "\n";
             echo '<link rel="canonical" href="' . $this->getArchiveParameters() . '" />' . "\n";
             $links = array();
             $add_query = '';
             $year = date('Y', $serendipity['range'][0]);
             $month = date('m', $serendipity['range'][0]);
             $day = date('d', $serendipity['range'][0]);
             $pageMonthNext = array('day' => '1', 'month' => $month + 1, 'year' => $year);
             $pageMonthPrev = array('day' => '1', 'month' => $month - 1, 'year' => $year);
             $pageDayNext = array('day' => $day + 1, 'month' => $month, 'year' => $year);
             $pageDayPrev = array('day' => $day - 1, 'month' => $month, 'year' => $year);
             $diff = $serendipity['range'][1] - $serendipity['range'][0];
             if (isset($serendipity['GET']['category'])) {
                 $categoryid = (int) serendipity_db_escape_string($serendipity['GET']['category']);
                 $add_query = '/C' . $categoryid;
             }
             if ($diff < 86400) {
                 // Paging day by day
                 $ts = mktime(0, 0, 0, $pageDayPrev['month'], $pageDayPrev['day'], $pageDayPrev['year']);
                 $links['prev'] = array('link' => serendipity_archiveDateUrl(sprintf('%4d/%02d/%02d', date('Y', $ts), date('m', $ts), date('d', $ts))), 'title' => sprintf(ENTRIES_FOR, serendipity_formatTime(DATE_FORMAT_ENTRY, $ts, false)));
                 $ts = mktime(0, 0, 0, $pageDayNext['month'], $pageDayNext['day'], $pageDayNext['year']);
                 $links['next'] = array('link' => serendipity_archiveDateUrl(sprintf('%4d/%02d/%02d', date('Y', $ts), date('m', $ts), date('d', $ts))), 'title' => sprintf(ENTRIES_FOR, serendipity_formatTime(DATE_FORMAT_ENTRY, $ts, false)));
             } elseif ($diff < 86400 * 28) {
                 // Paging by week
                 // TODO - Don't know :-)
             } else {
                 // Paging by month
                 $ts = mktime(0, 0, 0, $pageMonthPrev['month'], $pageMonthPrev['day'], $pageMonthPrev['year']);
                 $links['prev'] = array('link' => serendipity_archiveDateUrl(sprintf('%4d/%02d', date('Y', $ts), date('m', $ts))), 'title' => sprintf(ENTRIES_FOR, serendipity_formatTime('%B %Y', $ts, false)));
                 $ts = mktime(0, 0, 0, $pageMonthNext['month'], $pageMonthNext['day'], $pageMonthNext['year']);
                 $links['next'] = array('link' => serendipity_archiveDateUrl(sprintf('%4d/%02d', date('Y', $ts), date('m', $ts))), 'title' => sprintf(ENTRIES_FOR, serendipity_formatTime('%B %Y', $ts, false)));
             }
             $this->backAndForth($links);
             // END Specific Date Archives view
         } elseif ($serendipity['GET']['action'] == 'archives') {
             // Full month/year archives overview
             echo '<link rel="up" href="' . serendipity_rewriteURL(PATH_ARCHIVE) . '" title="' . ARCHIVES . '" />' . "\n";
             // END Full month/year archives overview
             echo '<link rel="canonical" href="' . $this->getArchiveParameters() . '" />' . "\n";
         } elseif (!empty($serendipity['GET']['category'])) {
             // Category based view
             $cInfo = serendipity_fetchCategoryInfo($serendipity['GET']['category']);
             if (function_exists('serendipity_categoryURL')) {
                 $categories_url = serendipity_categoryURL($cInfo, 'serendipityHTTPPath');
             } else {
                 $categories_url = serendipity_rewriteURL(PATH_CATEGORIES . '/' . serendipity_makePermalink(PERM_CATEGORIES, array('id' => $cInfo['categoryid'], 'title' => $cInfo['category_name'])), 'serendipityHTTPPath');
             }
             echo '<link rel="up" href="' . $categories_url . '" title="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($cInfo['category_name']) : htmlspecialchars($cInfo['category_name'], ENT_COMPAT, LANG_CHARSET)) . '" />' . "\n";
             echo '<link rel="canonical" href="' . $categories_url . '" />' . "\n";
             $categories = serendipity_fetchCategories('all');
             $links = array();
             if (is_array($categories) && count($categories)) {
                 $categories = serendipity_walkRecursive($categories, 'categoryid', 'parentid', VIEWMODE_THREADED);
                 $capture_next = false;
                 foreach ($categories as $cat) {
                     if ($capture_next) {
                         $links['next'] = $this->getCat($cat);
                         break;
                     }
                     if (is_array($prev_cat) && $cat['categoryid'] == $serendipity['GET']['category']) {
                         $links['prev'] = $this->getCat($prev_cat);
                         $capture_next = true;
                     }
                     $prev_cat = $cat;
                 }
             }
             $this->backAndForth($links);
             // END Category based view
         } elseif (!empty($serendipity['GET']['viewAuthor'])) {
             // User view
             $uInfo = serendipity_fetchUsers();
             $links = array();
             if (is_array($uInfo)) {
                 $capture_next = false;
                 foreach ($uInfo as $user) {
                     if ($capture_next) {
                         $links['next'] = $this->getUser($user);
                         break;
                     }
                     if ($user['authorid'] == $serendipity['GET']['viewAuthor']) {
                         $authors_url = $this->getUser($user);
                         echo '<link rel="up" href="' . $authors_url['link'] . '" title="' . $authors_url['title'] . '" />' . "\n";
                         echo '<link rel="canonical" href="' . $authors_url['link'] . '" />' . "\n";
                         if (is_array($prev_user)) {
                             $links['prev'] = $this->getUser($prev_user);
                             $capture_next = true;
                         }
                     }
                     $prev_user = $user;
                 }
                 $this->backAndForth($links);
             }
             // END User view
         } else {
             // Frontpage
             $this->backAndForth();
             // END Frontpage
             if ($serendipity['view'] == 'start') {
                 echo '<link rel="canonical" href="' . $serendipity['baseURL'] . '" />' . "\n";
             }
         }
     }
 }