/** * Get tags for the blog/headlines handler in the * Dynamic Objects dialog. */ function blog_get_tags() { $out = array((object) array('key' => '', 'value' => __('- select -'))); $tags = blog\Post::tags(); foreach ($tags as $tag => $count) { $out[] = (object) array('key' => $tag, 'value' => $tag . ' (' . $count . ')'); } return $out; }
<?php /** * Background saving for `Save & Keep Editing` in forms. */ $page->layout = false; header('Content-Type: application/json'); if (!User::require_admin()) { $res = new StdClass(); $res->success = false; $res->error = 'Authorization required.'; echo json_encode($res); return; } $error = false; $o = new blog\Post($_GET['id']); if ($o->error) { $error = $o->error; } else { foreach ($_POST as $k => $v) { if ($k != $o->key && isset($o->data[$k])) { $o->{$k} = $v; } } if (!$o->put()) { $error = $o->error; } else { Versions::add($o); require_once 'apps/blog/lib/Filters.php'; $_POST['page'] = 'blog/post/' . $o->id . '/' . URLify::filter($o->title); $this->hook('blog/edit', $_POST);
<?php /** * Admin page where you can edit posts and create new ones. */ $page->layout = 'admin'; if (!User::require_admin()) { $this->redirect('/admin'); } require_once 'apps/blog/lib/Filters.php'; $limit = 20; $_GET['offset'] = isset($_GET['offset']) ? $_GET['offset'] : 0; $lock = new Lock(); $posts = blog\Post::query('id, title, ts, author, published')->order('ts desc')->fetch_orig($limit, $_GET['offset']); $count = blog\Post::query()->count(); foreach ($posts as $k => $p) { $posts[$k]->locked = $lock->exists('Blog', $p->id); } $page->title = i18n_get('Blog Posts'); echo $tpl->render('blog/admin', array('posts' => $posts, 'count' => $count, 'offset' => $_GET['offset'], 'more' => $count > $_GET['offset'] + $limit ? true : false, 'prev' => $_GET['offset'] - $limit, 'next' => $_GET['offset'] + $limit));
$q_fields = array('title', 'author', 'tags', 'body'); $q_exact = array('author', 'published'); $m = isset($_GET['m']) ? $_GET['m'] : ''; // month query $url = '/blog/admin?q=' . urlencode($q) . '&m=' . urlencode($m) . '&offset=%d'; $lock = new Lock(); // adds yyyy-mm range to query, called via closure function blog_admin_where_month($q, $m) { if (preg_match('/^[0-9]{4}-[0-9]{2}$/', $m)) { $start = $m . '-01 00:00:00'; $end = $m . '-' . gmdate('t', strtotime($start)) . ' 23:59:59'; $q->where('ts >= ?', $start); $q->and_where('ts <= ?', $end); } else { $q->where('1 = 1'); } } $posts = blog\Post::query('id, title, ts, author, published, tags')->where_search($q, $q_fields, $q_exact)->and_where(function ($q) use($m) { blog_admin_where_month($q, $m); })->order('ts desc')->fetch_orig($limit, $offset); $count = blog\Post::query()->where_search($q, $q_fields, $q_exact)->and_where(function ($q) use($m) { blog_admin_where_month($q, $m); })->count(); foreach ($posts as $k => $p) { $posts[$k]->locked = $lock->exists('Blog', $p->id); $posts[$k]->tags = preg_split('/, ?/', $posts[$k]->tags); } $page->title = __('Blog Posts'); echo $tpl->render('blog/admin', array('limit' => $limit, 'total' => $count, 'posts' => $posts, 'count' => count($posts), 'url' => $url, 'q' => $q, 'm' => $m, 'archives' => blog\Post::archive_months(false), 'months' => explode(' ', __('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'))));
if ($f->submit()) { if (move_uploaded_file($_FILES['import_file']['tmp_name'], 'cache/blog_' . $_FILES['import_file']['name'])) { $file = 'cache/blog_' . $_FILES['import_file']['name']; $imported = 0; try { $posts = new SimpleXMLElement(file_get_contents($file)); foreach ($posts->channel->item as $entry) { $dc = $entry->children('http://purl.org/dc/elements/1.1/'); $content = $entry->children('http://purl.org/rss/1.0/modules/content/'); $post = array('title' => (string) $entry->title, 'author' => (string) $dc->creator, 'ts' => gmdate('Y-m-d H:i:s', strtotime($entry->pubDate)), 'published' => $_POST['published'], 'body' => str_replace("\n", "<br />\n", (string) $content->encoded), 'tags' => ''); $sep = ''; for ($i = 0; $i < count($entry->category); $i++) { $post['tags'] .= $sep . $entry->category[$i]->attributes()->nicename; $sep = ', '; } $p = new blog\Post($post); if ($p->put()) { Versions::add($p); $imported++; } } echo '<p>' . i18n_getf('Imported %d posts.', $imported) . '</p>'; echo '<p><a href="/blog/admin">' . i18n_get('Continue') . '</a></p>'; } catch (Exception $e) { echo '<p><strong>' . i18n_get('Error importing file') . ': ' . $e->getMessage() . '</strong></p>'; echo '<p><a href="/blog/admin">' . i18n_get('Back') . '</a></p>'; } return; } else { echo '<p><strong>' . i18n_get('Error uploading file.') . '</strong></p>'; }
/** * Blog post delete handler. */ $this->require_acl('admin', 'admin/delete', 'blog'); $page->layout = 'admin'; if (!isset($_POST['id'])) { $this->redirect('/blog/admin'); } $lock = new Lock('Blog', $_POST['id']); if ($lock->exists()) { $page->title = __('Editing Locked'); echo $tpl->render('admin/locked', $lock->info()); return; } require_once 'apps/blog/lib/Filters.php'; $p = new blog\Post($_POST['id']); $tags = $p->tags; $title = $p->title; $_POST = array_merge($_POST, (array) $p->orig()); if (!$p->remove()) { $page->title = __('An Error Occurred'); echo __('Error Message') . ': ' . $u->error; return; } // reset blog rss cache $cache->delete('blog_rss'); DB::execute('delete from #prefix#blog_post_tag where post_id = ?', $_POST['id']); $_POST['page'] = 'blog/post/' . $_POST['id'] . '/' . URLify::filter($title); $_POST['url'] = '/' . $_POST['page']; $this->hook('blog/delete', $_POST); $this->add_notification(__('Blog post deleted.'));
<?php /** * Show related posts. Called internally by blog/post. */ $id = $data['id']; $tags = explode(',', $data['tags']); $posts = blog\Post::query('id, thumbnail, title, ts')->where('published', 'yes')->where('id != ?', $id)->and_where(function ($q) use($tags) { foreach ($tags as $n => $tag) { $tag = trim($tag); if ($n === 0) { $q->where('tags like ?', '%' . $tag . '%'); } else { $q->or_where('tags like ?', '%' . $tag . '%'); } } })->order('ts', 'desc')->fetch_orig(3); $this->run('admin/util/minimal-grid'); $page->add_script('/apps/blog/css/related.css'); echo $tpl->render('blog/related', array('posts' => $posts));
*/ if ($appconf['Custom Handlers']['blog/index'] != 'blog/index') { if (!$appconf['Custom Handlers']['blog/index']) { echo $this->error(404, i18n_get('Not found'), i18n_get('The page you requested could not be found.')); return; } $extra = count($this->params) > 0 ? '/' . $this->params[0] : ''; echo $this->run($appconf['Custom Handlers']['blog/index'] . $extra, $data); return; } $page->layout = $appconf['Blog']['layout']; require_once 'apps/blog/lib/Filters.php'; $page->limit = 10; $page->num = count($this->params) > 0 && is_numeric($this->params[0]) ? $this->params[0] - 1 : 0; $page->offset = $page->num * $page->limit; $p = new blog\Post(); $posts = $p->latest($page->limit, $page->offset); $page->count = $p->query()->where('published', 'yes')->count(); $page->last = $page->offset + count($posts); $page->more = $page->count > $page->last ? true : false; $page->next = $page->num + 2; if (!is_array($posts) || count($posts) === 0) { echo '<p>' . i18n_get('No posts yet... :(') . '</p>'; if (User::require_admin()) { echo '<p><a href="/blog/add">' . i18n_get('Add Blog Post') . '</a></p>'; } } else { if (User::require_admin()) { echo '<p><a href="/blog/add">' . i18n_get('Add Blog Post') . '</a></p>'; } foreach ($posts as $post) {
<?php /** * Renders a tag cloud, with more frequently used tags appearing larger. */ if (!$this->internal) { $page->layout = $appconf['Blog']['layout']; $page->title = i18n_get('Tags'); } $pg->limit = 10; $pg->tags = blog\Post::tags(); foreach ($pg->tags as $k => $v) { $pg->tags[$k] = $v / 10 < 2 ? $v / 10 + 0.9 : ($v / 10 >= 2 ? 3 : $v / 10); } echo $tpl->render('blog/tags', $pg); $page->add_script(sprintf('<link rel="alternate" type="application/rss+xml" href="http://%s/blog/rss" />', $_SERVER['HTTP_HOST']));
<?php /** * Blog post edit form. */ $page->layout = 'admin'; $this->require_acl('admin', 'blog'); $lock = new Lock('Blog', $_GET['id']); if ($lock->exists()) { $page->title = __('Editing Locked'); echo $tpl->render('admin/locked', $lock->info()); return; } else { $lock->add(); } $p = new blog\Post($_GET['id']); $f = new Form('post', 'blog/edit'); $f->verify_csrf = false; if ($f->submit()) { $p->title = $_POST['title']; $p->author = $_POST['author']; $p->ts = $_POST['ts']; $p->published = $_POST['published']; $p->body = $_POST['body']; $p->tags = $_POST['tags']; $p->thumbnail = $_POST['thumbnail']; $p->update_extended(); $p->put(); Versions::add($p); if (!$p->error) { $this->add_notification(__('Blog post saved.'));
/** * Displays a month of blog posts from the archive. */ $page->id = 'blog'; $page->layout = $appconf['Blog']['layout']; require_once 'apps/blog/lib/Filters.php'; $preview_chars = (int) Appconf::blog('Blog', 'preview_chars') ? (int) Appconf::blog('Blog', 'preview_chars') : false; if (!isset($this->params[1])) { $this->redirect('/blog'); } $page->limit = 10; $year = urldecode($this->params[0]); $month = urldecode($this->params[1]); $page->num = count($this->params) > 2 && is_numeric($this->params[2]) ? $this->params[2] - 1 : 0; $page->offset = $page->num * $page->limit; $p = new blog\Post(); $posts = $p->archive($year, $month, $page->limit, $page->offset); $page->count = $p->count_by_month($year, $month, $page->limit, $page->offset); $page->last = $page->offset + count($posts); $page->more = $page->count > $page->last ? true : false; $page->next = $page->num + 2; $page->year = $year; $page->month = str_pad($month, 2, '0', STR_PAD_LEFT); $footer = Appconf::blog('Blog', 'post_footer'); $footer_stripped = strip_tags($footer); $footer = $footer && !empty($footer_stripped) ? $tpl->run_includes($footer) : false; if (Appconf::blog('Blog', 'post_format') === 'markdown') { require_once 'apps/blog/lib/markdown.php'; } foreach ($posts as $post) { $post->url = '/blog/post/' . $post->id . '/';
<?php /** * Publish scheduled blog posts. Use via cron like this: * * 0,15,30,45 * * * * /var/www/elefant blog/publish-queue */ if (!$this->cli) { die('Must be run from the command line.'); } $page->layout = false; // fetch queued posts $posts = blog\Post::query()->where('published', 'que')->where('ts <= ?', gmdate('Y-m-d H:i:s'))->fetch(); // publish posts foreach ($posts as $post) { $post->published = 'yes'; $post->put(); Versions::add($post); }
<?php require_once ('apps/blog/lib/Filters.php'); $preview_chars = (int) Appconf::blog('Blog', 'preview_chars') ? (int) Appconf::blog('Blog', 'preview_chars') : false; if ($data['number'] !== '') { $limit = $data['number']; } else { $limit = 5; } $offset = 0; $p = new blog\Post; if (isset ($data['tag']) && $data['tag'] !== '') { $posts = $p->tagged ($data['tag'], $limit, $offset); } else { $posts = $p->latest ($limit, $offset); } $page->count = $p->query ()->where ('published', 'yes')->count (); if (Appconf::blog ('Blog', 'post_format') === 'markdown') { require_once ('apps/blog/lib/markdown.php'); } if (! is_array ($posts) || count ($posts) === 0) { echo '<p>' . __ ('No posts yet... :(') . '</p>'; if (User::require_admin ()) { echo '<p class="hide-in-preview"><a href="/blog/add">' . __ ('Add Blog Post') . '</a></p>'; }
* In PHP code, call it like this: * * echo $this->run ('blog/headlines'); * * In a view template, call it like this: * * {! blog/headlines !} * * Parameters: * * - `limit` - Number of posts to show (default=10) * - `tag` - Show posts with this tag only (optional) * - `dates` - Show post dates (yes, no, default=no) * * Also available in the dynamic objects menu as "Blog: Headlines". */ if (!$this->internal) { $page->id = 'blog'; $page->layout = $appconf['Blog']['layout']; $page->title = __('Latest Posts'); } require_once 'apps/blog/lib/Filters.php'; $limit = isset($data['limit']) ? $data['limit'] : 10; $p = new blog\Post(); if (isset($data['tag']) && $data['tag'] !== '') { $posts = $p->tagged($data['tag']); } else { $posts = $p->headlines($limit); } $dates = isset($data['dates']) && $data['dates'] === 'yes' ? true : false; echo $tpl->render('blog/headlines', array('posts' => $posts, 'dates' => $dates));
<?php $this->cache = 3600; $res = blog\Post::archive_months(); $months = explode(' ', __('January February March April May June July August September October November December')); echo $tpl->render('blog/archives', array('months' => $months, 'archives' => $res));
<?php /** * Displays a single blog post. */ // Check for a custom handler override $res = $this->override ('blog/post'); if ($res) { echo $res; return; } $page->id = 'blog'; $page->layout = Appconf::blog ('Blog', 'post_layout'); require_once ('apps/blog/lib/Filters.php'); $p = new blog\Post ($this->params[0]); // post not found if ($p->error) { return $this->error (404, __ ('Post not found'), '<p>' . __ ('Hmm, we can\'t seem to find the post you wanted at the moment.') . '</p>'); } if ($p->published === 'no' && ! User::require_acl ('admin', 'blog')) { return $this->error (404, __ ('Post not found'), '<p>' . __ ('Hmm, we can\'t seem to find the post you wanted at the moment.') . '</p>'); } // published if it was scheduled and it's time if ($p->published === 'que') { if ($p->ts <= gmdate ('Y-m-d H:i:s')) { $p->published = 'yes'; $p->put ();
<?php /** * Blog post delete handler. */ $page->layout = 'admin'; if (!User::require_admin()) { $this->redirect('/admin'); } $lock = new Lock('Blog', $_GET['id']); if ($lock->exists()) { $page->title = i18n_get('Editing Locked'); echo $tpl->render('admin/locked', $lock->info()); return; } require_once 'apps/blog/lib/Filters.php'; $p = new blog\Post($_GET['id']); $tags = $p->tags; $title = $p->title; if (!$p->remove()) { $page->title = 'An Error Occurred'; echo 'Error Message: ' . $u->error; return; } // reset blog rss cache $memcache->delete('blog_rss'); DB::execute('delete from blog_post_tag where post_id = ?', $_GET['id']); $_GET['page'] = 'blog/post/' . $_GET['id'] . '/' . URLify::filter($title); $this->hook('blog/delete', $_GET); $this->add_notification(i18n_get('Blog post deleted.')); $this->redirect('/blog/admin');
<?php /** * Renders the RSS feed for the blog. */ $res = $memcache->get('_blog_rss'); if (!$res) { require_once 'apps/blog/lib/Filters.php'; $p = new blog\Post(); $page->posts = $p->latest(10, 0); $page->title = $appconf['Blog']['title']; $page->date = gmdate('Y-m-d\\TH:i:s'); foreach ($page->posts as $k => $post) { $page->posts[$k]->url = '/blog/post/' . $post->id . '/' . URLify::filter($post->title); } $res = $tpl->render('blog/rss', $page); $memcache->set('_blog_rss', $res, 1800); // half an hour } $page->layout = false; header('Content-Type: text/xml'); echo $res;
<?php /** * Displays a single blog post. */ if ($appconf['Custom Handlers']['blog/post'] != 'blog/post') { if (!$appconf['Custom Handlers']['blog/post']) { echo $this->error(404, i18n_get('Not found'), i18n_get('The page you requested could not be found.')); return; } echo $this->run($appconf['Custom Handlers']['blog/post'] . '/' . $this->params[0], $data); return; } $page->layout = $appconf['Blog']['post_layout']; require_once 'apps/blog/lib/Filters.php'; $p = new blog\Post($this->params[0]); $page->title = $appconf['Blog']['title']; $post = $p->orig(); $post->full = true; $post->url = '/blog/post/' . $post->id . '/' . URLify::filter($post->title); $post->tag_list = explode(',', $post->tags); $post->body = $tpl->run_includes($post->body); $post->social_buttons = $appconf['Social Buttons']; echo $tpl->render('blog/post', $post); switch ($appconf['Blog']['comments']) { case 'disqus': echo $this->run('blog/disqus/comments', $post); break; case 'facebook': echo $this->run('social/facebook/comments', $post); break;
/** * Displays a list of blog posts by author. */ $page->id = 'blog'; $page->layout = $appconf['Blog']['layout']; require_once 'apps/blog/lib/Filters.php'; $preview_chars = (int) Appconf::blog('Blog', 'preview_chars') ? (int) Appconf::blog('Blog', 'preview_chars') : false; $page->limit = 10; $page->author = urldecode($this->params[0]); if (!$page->author) { $this->redirect('/blog'); } $page->num = count($this->params) > 1 && is_numeric($this->params[1]) ? $this->params[1] - 1 : 0; $page->offset = $page->num * $page->limit; $p = new blog\Post(); $posts = $p->by($page->author, $page->limit, $page->offset); $page->count = $p->query()->where('published', 'yes')->where('author', $page->author)->count(); $page->last = $page->offset + count($posts); $page->more = $page->count > $page->last ? true : false; $page->next = $page->num + 2; $footer = Appconf::blog('Blog', 'post_footer'); $footer_stripped = strip_tags($footer); $footer = $footer && !empty($footer_stripped) ? $tpl->run_includes($footer) : false; if (Appconf::blog('Blog', 'post_format') === 'markdown') { require_once 'apps/blog/lib/markdown.php'; } foreach ($posts as $post) { $post->url = '/blog/post/' . $post->id . '/' . URLify::filter($post->title); $post->tag_list = strlen($post->tags) > 0 ? explode(',', $post->tags) : array(); $post->social_buttons = $appconf['Social Buttons'];
/** * Displays a list of blog posts by tag. */ $page->id = 'blog'; $page->layout = $appconf['Blog']['layout']; require_once 'apps/blog/lib/Filters.php'; $preview_chars = (int) Appconf::blog('Blog', 'preview_chars') ? (int) Appconf::blog('Blog', 'preview_chars') : false; $page->limit = 10; $page->tag = urldecode($this->params[0]); if (!$page->tag) { $this->redirect('/blog'); } $page->num = count($this->params) > 1 && is_numeric($this->params[1]) ? $this->params[1] - 1 : 0; $page->offset = $page->num * $page->limit; $p = new blog\Post(); $posts = $p->tagged($page->tag, $page->limit, $page->offset); $page->count = $p->count_by_tag($page->tag); $page->last = $page->offset + count($posts); $page->more = $page->count > $page->last ? true : false; $page->next = $page->num + 2; $footer = Appconf::blog('Blog', 'post_footer'); $footer_stripped = strip_tags($footer); $footer = $footer && !empty($footer_stripped) ? $tpl->run_includes($footer) : false; if (Appconf::blog('Blog', 'post_format') === 'markdown') { require_once 'apps/blog/lib/markdown.php'; } foreach ($posts as $post) { $post->url = '/blog/post/' . $post->id . '/' . URLify::filter($post->title); $post->tag_list = strlen($post->tags) > 0 ? explode(',', $post->tags) : array(); $post->social_buttons = $appconf['Social Buttons'];