* @license PHP License * @package WB * @subpackage content */ /** * Load base class */ WBClass::load('WBContent'); /** * Content component: Blog * * Display and manage user blog * * @todo refactor using filter * @version 0.7.2 * @package WB * @subpackage content */ class WBContent_Blog extends WBContent { /** * my parameter list * @var array */ protected $config = array( 'action' => 'list', 'id' => '', 'title' => '', 'category' => '', 'goto' => '0', 'limit' => null, 'requiredgroup' => 'blogeditor', 'requiredgroupmanager' => 'blogadmin', 'vfs-user' => '0' ); /** * table * @var WBDatasource_Table */ protected $table; /** * list of blog entries * @var array */ protected $list = array(); /** * pager information * @var array */ protected $pagerInfo = array(); /** * foreign key identifing owning user * @var string */ protected $foreign; /** * blog tools * @var WBBlog_Tool */ private $blog; /** * 2nd constructor * * Called after configuration was done */ protected function init() { $this->table = WBClass::create('WBDatasource_Table'); $this->blog = WBClass::create('WBBlog_Tool'); } /** * run * * run component * * @todo become user-aware for blog categories * @return array parameter list */ public function run() { // shared VFS? if (!empty($this->config['vfs-user']) && strval($this->config['vfs-user']) != '0' ) { $this->sess->set('vfsfile_user', $this->config['vfs-user']); } else { $this->sess->clear('vfsfile_user'); } if ('list' == $this->config['action']) { $this->config['id'] = ''; } $manager = $this->isUserInGroup($this->config['requiredgroupmanager']); if ($manager) { $this->tmpl->addGlobalVar('blog_manager', 1); } if (!in_array($this->config['action'], array('add', 'edit', 'rm'))) { $this->loadArticles(); if (is_array($this->config['category'])) { $this->config['category'] = implode(',', $this->config['category']); } $this->addConfigAsGlobalVars(); return $this->config; } $this->foreign = $this->user->getId(); if (empty($this->foreign) && in_array($this->config['action'], array('rm', 'edit'))) { $this->foreign = '__does_not_exist__'; } if ($manager) { $this->foreign = null; } $this->loadArticles(); if (empty($this->list) && !in_array($this->config['action'], array('add', 'list'))) { $this->config['id'] = ''; $this->config['action'] = 'list'; } if (is_array($this->config['category'])) { $this->config['category'] = implode(',', $this->config['category']); } $this->addConfigAsGlobalVars(); return $this->config; } /** * receive output * * fetch output of this content component * * @return string */ public function getString() { switch ($this->config['action']) { case 'rm': // delete? $this->tmpl->addGlobalVars($this->list[0]); if ('yes' == $this->req->get('force', 'no')) { $this->table->delete('blog', $this->config['id'], $this->foreign); $this->loadTemplates('rmDeleted'); $change = array('draft', 'deleted'); if (isset($this->list[0]['published']) && $this->list[0]['published']) { $change[0] = 'public'; } $eData = $this->list[0]; $eData['change'] = $change; WBEvent::trigger('blog:article:deleted', 'Deleted blog record {TITLE}.', $eData); break; } $this->loadTemplates('rm'); break; case 'add': case 'edit': $this->processForm('edit', $this->list[0]); break; case 'display': $this->loadTemplates('display'); break; default: $this->tmpl->addGlobalVars($this->pagerInfo, 'pager_'); $this->loadTemplates('list'); break; } if ($this->tmpl->exists('list_entry')) { $this->tmpl->addRows('list_entry', $this->list); } return $this->tmpl->getParsedTemplate('snippet'); } /** * load blog articles * * @todo put bubble-stuff in parent class in a more generic manner */ protected function loadArticles() { $this->list = array(); if ('add' == $this->config['action']) { $this->list = array(array()); $this->config['id'] = ''; return; } if ('edit' == $this->config['action'] && empty($this->config['id'])) { $this->list = array(array()); $this->config['id'] = ''; $this->config['action'] = 'add'; return; } $clause = array(); $this->injectSearch($clause); $this->injectCategory($clause); if (!$this->isUserInGroup($this->config['requiredgroupmanager'])) { // only published or user owned records $c = array(); $c[0] = array(); if ($this->user->isAuthenticated()) { $c[1] = array( 'field' => $this->table->getIdentifier('user'), 'value' => $this->user->getId() ); } // take care for drafts $c[0] = array( 'field' => 'published', 'value' => 1 ); $clause[] = array( 'type' => 'complex', 'bond' => 'or', 'clause' => $c ); // consider future records $c[0] = array( 'field' => 'created', 'relation' => 'le', 'value' => gmdate('Y-m-d H:i:s') ); $clause[] = array( 'type' => 'complex', 'bond' => 'or', 'clause' => $c ); } // try to load single blog entry if (!empty($this->config['id'])) { if (strstr($this->config['id'], '-')) { // load by date and check title if date has more than one record $created = strtotime($this->config['id']); $lClause = $clause; $lClause[] = array( 'field' => 'created', 'relation' => 'ge', 'value' => gmdate('Y-m-d', $created) ); $created += 86400; // plus one day 60 * 60 * 24 $lClause[] = array( 'field' => 'created', 'relation' => 'le', 'value' => gmdate('Y-m-d', $created) ); $options = array('limit' => 100); $this->list = $this->table->get('blog', null, $this->foreign, $lClause, $options); } else { $this->list = $this->table->get('blog', $this->config['id'], $this->foreign, $clause); } // fuzzy select: verify with title if (count($this->list) > 1 && !empty($this->config['title'])) { $title = strtolower(urldecode($this->config['title'])); foreach ($this->list as $l) { if (strtolower($l['title']) == $title) { $this->list = array($l); break; } $length = min(strlen($title), strlen($l['title'])); if (0 == strncmp(strtolower($l['title']), $title, $length)) { $this->list = array($l); break; } } } if (count($this->list) == 1) { $this->config['title'] = ''; // build URL using date instead of id $this->blog->loadArticleByData($this->list[0]); $this->list[0]['url'] = $this->blog->getArticleUrl(); $this->bubbles['url_type'] = 'article'; $this->bubbles['url'] = $this->list[0]['url']; $this->bubbles['title'] = $this->list[0]['title']; $this->blog->addOpenGraph($this->bubbles, 'image'); $this->blog->addOpenGraph($this->bubbles, 'description'); $this->blog->addOpenGraph($this->bubbles, 'created'); switch ($this->config['action']) { case 'edit': case 'rm': case 'display': break; default: $this->config['action'] = 'display'; break; } return; } } $this->config['title'] = ''; $this->config['id'] = ''; $this->config['action'] = 'list'; $options = array(); if ($this->config['limit']) { $options['limit'] = $this->config['limit']; } $pager = $this->table->getPager($this->part . __CLASS__, 'blog', null, $clause, $options); $this->pagerInfo = $pager->browse($this->config['goto']); $this->list = $pager->get(); $this->bubbles['url_type'] = 'blog'; $this->bubbles['url'] = $this->blog->getListUrl(); foreach($this->list as &$l) { $this->blog->loadArticleByData($l); $l['url'] = $this->blog->getArticleUrl(); } if (1 == $this->pagerInfo['total']) { $this->bubbles['url_type'] = 'article'; $this->bubbles['url'] = $this->list[0]['url']; $this->bubbles['title'] = $this->list[0]['title']; } } /** * Inject a category restriction * * @param array $clause */ private function injectCategory(&$clause) { if (!empty($this->config['category'])) { if (!is_array($this->config['category'])) { $this->config['category'] = explode(',', $this->config['category']); } $clause[] = array( 'field' => $this->table->getIdentifier('blogcategory'), 'relation' => 'in', 'value' => $this->config['category'] ); } } /** * Inject Search * * @param array $clause */ private function injectSearch(&$clause) { $query = trim($this->req->get('searchquery', '')); if (empty($query)) { return; } $tmplVars = array(); $query = urldecode($query); // normalize query $query = explode(' ', $query); $query = array_map('trim', $query); foreach ($query as $i => $q) { if (empty($q) || 3 > strlen($q)) { unset($query[$i]); } } $query = array_values($query); $searchquery = implode(' ', $query); $this->tmpl->addGlobalVar('search_query', $searchquery); $this->tmpl->addGlobalVar('search_query_url', urlencode($searchquery)); // search for strings in all searchfields $searchfields = array('title', 'body'); foreach ($query as $q) { $c = array(); foreach ($searchfields as $f) { $c[] = array( 'field' => $f, 'relation' => 'like', 'value' => $q ); } $clause[] = array( 'type' => 'complex', 'bond' => 'or', 'clause' => $c ); } } /** * Save blog entry * * Store record in database and add user id for new records * * @param patForms $form * @param array $values */ public function onEditValid($form, $values) { $id = $this->config['id']; $new = 0; if (empty($id)) { $new = 1; $id = '__new'; $uPrimary = $this->table->getIdentifier('user'); if (!isset($values[$uPrimary]) || empty($values[$uPrimary])) { $values[$uPrimary] = $this->user->getId(); } } $values['id'] = $this->table->save('blog', $id, $values); $change = array('draft', 'draft'); if (isset($this->list[0]['published']) && $this->list[0]['published']) { $change[0] = 'public'; } if (isset($values['published']) && $values['published']) { $change[1] = 'public'; } $values[$this->table->getIdentifier('blog')] = $values['id']; $this->list[0] = array_merge($this->list[0], $values); // trigger event $eData = $this->list[0]; $eData['new'] = $new; $eData['change']= $change; WBEvent::trigger('blog:article:saved', 'Saved blog record {TITLE}.', $eData); $this->loadTemplates('editValid'); return false; } /** * location of form config * * Return sub directory where form element definitions are located * * @return string folder */ protected function getFormConfigDir() { return 'blog'; } }