/** * Get site news. * * @return View_Topics_List */ public function section_news() { $section = new View_Topics_List(Model_Forum_Topic::factory()->find_news(5)); $section->title = __('News'); $section->aside = true; return $section; }
/** * Get prefixed forum title. * * @static * @param Model_Forum_Topic $topic * @return string */ public static function topic(Model_Forum_Topic $topic) { switch ($topic->status) { case Model_Forum_Topic::STATUS_LOCKED: $prefix = '<span class="locked">[' . __('Locked') . ']</span> '; break; case Model_Forum_Topic::STATUS_SINK: $prefix = '<span class="sink">[' . __('Sink') . ']</span> '; break; default: $prefix = ''; } if ($topic->sticky) { $prefix = '<span class="stick">[' . __('Sticky') . ']</span> ' . $prefix; } return $prefix . HTML::chars($topic->name()); }
/** * Create new topic. */ public function action_create() { $this->logged_in_required(); if (!$this->user->can('Forum_Topic_Create', array('category' => $this->category))) { throw HTTP_Exception::factory('403', 'Category is locked'); } if ($this->request->method() == HTTP_Request::POST) { try { $topic = new Model_Forum_Topic(); $topic->create_topic(array('category_id' => $this->category->id, 'user_id' => $this->user->id, 'title' => $this->request->post('title'), 'content' => $this->request->post('content')), array('category_id', 'user_id', 'title')); Hint::success('You have created a topic'); $this->redirect(Route::get('forum.topic')->uri(array('id' => $topic->id))); } catch (ORM_Validation_Exception $e) { Hint::error($e->errors('models')); } } $this->view = new View_Forum_Topic_Create(); $this->view->category = $this->category; }
/** * Get newsfeed item as HTML * * @static * @param Model_NewsfeedItem $item * @return string */ public static function get(Model_NewsFeedItem $item) { $text = ''; switch ($item->type) { case self::TYPE_REPLY: $topic = Model_Forum_Topic::factory($item->data['topic_id']); if ($topic->loaded()) { $text = __('replied to topic<br />:topic', array(':topic' => HTML::anchor(Route::get('forum_post')->uri(array('topic_id' => Route::model_id($topic), 'id' => $item->data['post_id'])) . '#post-' . $item->data['post_id'], '<i class="icon-comment icon-white"></i> ' . HTML::chars($topic->name), array('title' => $topic->name)))); } break; case self::TYPE_TOPIC: $topic = Model_Forum_Topic::factory($item->data['topic_id']); if ($topic->loaded()) { $text = __('started a new topic<br />:topic', array(':topic' => HTML::anchor(Route::model($topic), '<i class="icon-comment icon-white"></i> ' . HTML::chars($topic->name), array('title' => $topic->name)))); } break; } return $text; }
/** * Get anchor to newsfeed item target. * * @static * @param Model_NewsfeedItem $item * @return string */ public static function get_link(Model_NewsfeedItem $item) { $text = ''; switch ($item->type) { case self::TYPE_REPLY: $topic = Model_Forum_Topic::factory($item->data['topic_id']); if ($topic->loaded()) { $text = HTML::anchor(Route::get('forum_post')->uri(array('topic_id' => Route::model_id($topic), 'id' => $item->data['post_id'])) . '#post-' . $item->data['post_id'], '<i class="fa fa-comments"></i> ' . HTML::chars($topic->name), array('title' => $topic->name)); } break; case self::TYPE_TOPIC: $topic = Model_Forum_Topic::factory($item->data['topic_id']); if ($topic->loaded()) { $text = HTML::anchor(Route::model($topic), '<i class="fa fa-comments"></i> ' . HTML::chars($topic->name), array('title' => $topic->name)); } break; } return $text; }
/** * Get post view. * * @param Model_Forum_Topic $topic * @param Model_Forum_Post $post */ public function section_post(Model_Forum_Topic $topic, Model_Forum_Post $post) { $section = new View_Forum_Post($post, $topic); $section->nth = $topic->get_post_number($post->id) + 1; $section->private = $this->private; return $section; }
/** * Render view. * * @return string */ public function content() { ob_start(); $offset = $this->pagination->offset; $previous = null; foreach ($this->forum_topic->posts($offset, $this->pagination->items_per_page) as $post) { // Ignore if (!Permission::has($post, Model_Forum_Post::PERMISSION_READ, self::$_user)) { continue; } // Time difference between posts $current = strtotime($post->created); $difference = $previous && $current - $previous > Date::YEAR ? Date::fuzzy_span($previous, $current) : false; if ($difference) { ?> <div class="offset1 post-old"> <span class="label label-inverse muted">¡ <?php echo __('Previous post :ago', array(':ago' => $difference)); ?> !</span> </div> <?php } $previous = $current; $post = new View_Forum_Post($post, $this->forum_topic); $post->nth = ++$offset; $post->private = $this->private; echo $post; } ?> <script> head.ready('anqh', function() { // Edit post $('section.topic').on('click', 'a.post-edit', function _editPost(e) { e.preventDefault(); var href = $(this).attr('href') , post = href.match(/([0-9]*)\/edit/); $('#post-' + post[1] + ' .ago').fadeOut(); $.get(href, function _loaded(data) { $('#post-' + post[1] + ' .bubble').replaceWith(data); }); }); // Delete post $('a.post-delete').each(function deletePost() { var $action = $(this); $action.data('action', function addAction() { var post = $action.attr('href').match(/([0-9]*)\/delete/); if (post) { $('#post-' + post[1]).slideUp(); $.get($action.attr('href')); } }); }); // Quote post $('section.topic').on('click', 'a.post-quote', function _quotePost(e) { e.preventDefault(); var href = $(this).attr('href') , post = href.match(/([0-9]*)\/quote/) , $article = $(this).closest('article'); $('#post-' + post[1] + ' .ago').fadeOut(); $.get(href, function _loaded(data) { $article.after(data); // Scroll form to view var $quote = $article.next('article'); if ($quote.offset().top + $quote.outerHeight() > $(window).scrollTop() + $(window).height()) { window.scrollTo(0, $quote.offset().top + $quote.outerHeight() - $(window).height() ); } }); }); // Save post $('section.topic').on('submit', '.post form', function(e) { e.preventDefault(); var post = $(this).closest('article'); post.loading(); $.post($(this).attr('action'), $(this).serialize(), function(data) { post.replaceWith(data); }); }); // Cancel quote $('section.topic').on('click', '.quote a.cancel', function cancelQuote(e) { e.preventDefault(); var $quote = $(this).closest('article') , $article = $quote.prev('article'); $quote.slideUp(null, function slided() { $quote.remove(); }); $article.find('.ago').fadeIn(); }); // Cancel edit $('section.topic').on('click', '.post-edit a.cancel', function cancelEdit(e) { e.preventDefault(); var $post = $(this).closest('article'); if (!$post.hasClass('quote')) { $.get($(this).attr('href'), function loaded(data) { $post.replaceWith(data); }); } }); }); </script> <?php return ob_get_clean(); }
/** * Refresh area data. * Potentially heavy function, use with caution! * * @param boolean $save */ public function refresh($save = true) { if (!$this->loaded()) { return false; } // Get table names if ($this instanceof Anqh_Model_Forum_Area) { $topic_table = Model_Forum_Topic::factory()->get_table_name(); $post_table = Model_Forum_Post::factory()->get_table_name(); } else { $topic_table = Model_Forum_Private_Topic::factory()->get_table_name(); $post_table = Model_Forum_Private_Post::factory()->get_table_name(); } // Stats $this->topic_count = (int) DB::select(array(DB::expr('COUNT(id)'), 'topics'))->from($topic_table)->where('forum_area_id', '=', $this->id)->execute($this->_db)->get('topics'); $this->post_count = (int) DB::select(array(DB::expr('COUNT(id)'), 'posts'))->from($post_table)->where('forum_area_id', '=', $this->id)->execute($this->_db)->get('posts'); // Last topic $this->last_topic_id = (int) DB::select(array(DB::expr('MAX(id)'), 'topic_id'))->from($topic_table)->where('forum_area_id', '=', $this->id)->execute($this->_db)->get('topic_id'); if ($save) { $this->save(); } return true; }
/** * Destroy controller */ public function after() { if ($this->ajax || $this->internal) { // AJAX and HMVC requests $this->response->body($this->response->body() . ''); } else { if ($this->auto_render) { // Normal requests $session = Session::instance(); // Save current URI /* Moved to Controller if ($this->history && $this->response->status() < 400) { $uri = $this->request->current_uri(); unset($this->breadcrumb[$uri]); $this->breadcrumb = array_slice($this->breadcrumb, -9, 9, true); $this->breadcrumb[$uri] = $this->page_title; $session ->set('history', $uri . ($_GET ? URL::query($_GET) : '')) ->set('breadcrumb', $this->breadcrumb); } */ // Controller name as the default page id if none set empty($this->page_id) and $this->page_id = $this->request->controller(); // Stylesheets $styles = array('ui/boot.css' => null, 'ui/typo.css' => null, 'ui/base.css' => null, 'ui/jquery-ui.css' => null, 'http://fonts.googleapis.com/css?family=Nobile:regular,bold' => null); // Generic views Widget::add('breadcrumb', View::factory('generic/breadcrumb', array('breadcrumb' => $this->breadcrumb, 'last' => !$this->history))); Widget::add('actions', View::factory('generic/actions', array('actions' => $this->page_actions))); Widget::add('navigation', View::factory('generic/navigation', array('items' => Kohana::$config->load('site.menu'), 'selected' => $this->page_id))); if (!empty($this->tabs)) { Widget::add('subnavigation', View::factory('generic/navigation', array('items' => $this->tabs, 'selected' => $this->tab_id))); } /* Widget::add('tabs', View::factory('generic/tabs_top', array( 'tabs' => $this->tabs, 'selected' => $this->tab_id ))); */ // Footer Widget::add('footer', View_Module::factory('events/event_list', array('mod_id' => 'footer-events-new', 'mod_class' => 'article grid4 first cut events', 'mod_title' => __('New events'), 'events' => Model_Event::factory()->find_new(10)))); Widget::add('footer', View_Module::factory('forum/topiclist', array('mod_id' => 'footer-topics-active', 'mod_class' => 'article grid4 cut topics', 'mod_title' => __('New posts'), 'topics' => Model_Forum_Topic::factory()->find_by_latest_post(10)))); Widget::add('footer', View_Module::factory('blog/entry_list', array('mod_id' => 'footer-blog-entries', 'mod_class' => 'article grid4 cut blogentries', 'mod_title' => __('New blogs'), 'entries' => Model_Blog_Entry::factory()->find_new(10)))); // Skin $skins = Kohana::$config->load('site.skins'); $skin = 'dark'; //$session->get('skin', 'dark'); $skin_imports = array('ui/mixin.less', 'ui/grid.less', 'ui/layout.less', 'ui/widget.less', 'ui/custom.less'); // Dock $classes = array(); foreach ($skins as $skin_name => &$skin_config) { $skin_config['path'] = 'ui/' . $skin_name . '/skin.less'; $classes[] = HTML::anchor(Route::get('setting')->uri(array('action' => 'skin', 'value' => $skin_name)), $skin_config['name'], array('class' => 'theme', 'rel' => $skin_name)); } //Widget::add('dock', __('Theme') . ': ' . implode(', ', $classes)); // Language selection $available_languages = Kohana::$config->load('locale.languages'); if (count($available_languages)) { $languages = array(); foreach ($available_languages as $lang => $locale) { $languages[] = HTML::anchor('set/lang/' . $lang, HTML::chars($locale[2])); } // Widget::add('dock', ' | ' . __('Language: ') . implode(', ', $languages)); } // Search /* Widget::add('search', View_Module::factory('generic/search', array( 'mod_id' => 'search' ))); */ // Visitor card Widget::add('visitor', View::factory('generic/visitor', array('user' => self::$user))); // Time & weather Widget::add('dock', ' | ' . View::factory('generic/clock', array('user' => self::$user))); // Pin Widget::add('dock', ' | ' . HTML::anchor('#pin', '▲', array('title' => __('Lock menu'), 'class' => 'icon unlock', 'onclick' => '$("#header").toggleClass("pinned"); return false;'))); // End Widget::add('end', View::factory('generic/end')); // Analytics if ($google_analytics = Kohana::$config->load('site.google_analytics')) { Widget::add('head', HTML::script_source("\nvar tracker;\nhead.js(\n\t{ 'google-analytics': 'http://www.google-analytics.com/ga.js' },\n\tfunction() {\n\t\ttracker = _gat._getTracker('" . $google_analytics . "');\n\t\ttracker._trackPageview();\n\t}\n);\n")); } // Open Graph $og = array(); foreach ((array) Anqh::open_graph() as $key => $value) { $og[] = '<meta property="' . $key . '" content="' . HTML::chars($value) . '" />'; } if (!empty($og)) { Widget::add('head', implode("\n", $og)); } // Share if (Anqh::share()) { if ($share = Kohana::$config->load('site.share')) { // 3rd party share Widget::add('share', View_Module::factory('share/share', array('mod_class' => 'like', 'id' => $share))); Widget::add('foot', View::factory('share/foot', array('id' => $share))); } else { if ($facebook = Kohana::$config->load('site.facebook')) { // Facebook Like Widget::add('share', View_Module::factory('facebook/like')); Widget::add('ad_top', View::factory('facebook/connect', array('id' => $facebook))); } } } // Ads $ads = Kohana::$config->load('site.ads'); if ($ads && $ads['enabled']) { foreach ($ads['slots'] as $ad => $slot) { Widget::add($slot, View::factory('ads/' . $ad), Widget::MIDDLE); } } // And finally the profiler stats if (self::$user && self::$user->has_role('admin')) { //in_array(Kohana::$environment, array(Kohana::DEVELOPMENT, Kohana::TESTING))) { Widget::add('foot', View::factory('generic/debug')); Widget::add('foot', View::factory('profiler/stats')); } // Do some CSS magic to page class $page_class = explode(' ', $this->language . ' ' . $session->get('page_width', 'fixed') . ' ' . $session->get('page_main', 'left') . ' ' . $this->request->action() . ' ' . $this->page_class); // Controller set classes $page_class = implode(' ', array_unique(array_map('trim', $page_class))); // Bind the generic page variables $this->template->set('styles', $styles)->set('skin', $skin)->set('skins', $skins)->set('skin_imports', $skin_imports)->set('language', $this->language)->set('page_id', $this->page_id)->set('page_class', $page_class)->set('page_title', $this->page_title)->set('page_subtitle', $this->page_subtitle); // Add statistics $queries = 0; if (Kohana::$profiling) { foreach (Profiler::groups() as $group => $benchmarks) { if (strpos($group, 'database') === 0) { $queries += count($benchmarks); } } } $total = array('{memory_usage}' => number_format((memory_get_peak_usage() - KOHANA_START_MEMORY) / 1024, 2) . 'KB', '{execution_time}' => number_format(microtime(true) - KOHANA_START_TIME, 5), '{database_queries}' => $queries, '{included_files}' => count(get_included_files())); $this->template = strtr($this->template, $total); // Render page if ($this->auto_render === true) { $this->response->body($this->template); } } } return parent::after(); }
/** * Load topic by bound model * * @static * @param Model $bind_model Bound model * @param string $bind_name Bind config if multiple binds per model * @return Model_Forum_Topic */ public static function find_by_bind(Model $bind_model, $bind_name = null) { $model = Model::model_name($bind_model); // Get correct bind config if (!$bind_name) { foreach (Model_Forum_Area::get_binds(false) as $bind_name => $bind_config) { if ($bind_config['model'] == $model) { $config = $bind_config; break; } } } else { $config = Model_Forum_Area::get_binds($bind_name); } if ($config) { // Get area $area = Model_Forum_Area::factory(); $area = $area->load(DB::select_array($area->fields())->where('area_type', '=', Model_Forum_Area::TYPE_BIND)->where('bind', '=', $bind_name)); if ($area->loaded()) { // Get topic $topic = Model_Forum_Topic::factory(); $topic = $topic->load(DB::select_array($topic->fields())->where('forum_area_id', '=', $area->id)->where('bind_id', '=', $bind_model->id())); // If topic found, go there! if ($topic->loaded()) { return $topic; } } } return null; }
/** * Destroy controller. */ public function after() { if ($this->_request_type !== Controller::REQUEST_INITIAL) { // AJAX and HMVC requests $this->response->body((string) $this->response->body()); } else { if ($this->auto_render) { // Normal requests // Stylesheets $styles = array('ui/jquery-ui.css', 'http://fonts.googleapis.com/css?family=Terminal+Dosis'); // Skins $selected_skin = $this->session->get('skin', 'blue'); // Less files needed to build a skin $less_imports = array('ui/mixin.less', 'ui/anqh.less'); $skins = array(HTML::style('static/css/bootstrap.css'), HTML::style('static/css/bootstrap-responsive.css')); foreach (array('blue') as $skin) { $skinsi[] = Less::style('ui/' . $skin . '.less', array('title' => $skin, 'rel' => $skin == $selected_skin ? 'stylesheet' : 'alternate stylesheet'), false, $less_imports); } // Footer $section = new View_Events_List(); $section->class .= ' span4'; $section->title = __('New events'); $section->events = Model_Event::factory()->find_new(10); Widget::add('footer', $section); $section = new View_Topics_List(); $section->class .= ' span4'; $section->title = __('New posts'); $section->topics = Model_Forum_Topic::factory()->find_by_latest_post(10); Widget::add('footer', $section); $section = new View_Blogs_List(); $section->class .= ' span4'; $section->title = __('New blogs'); $section->blog_entries = Model_Blog_Entry::factory()->find_new(10); Widget::add('footer', $section); // Open Graph $og = array(); foreach ((array) Anqh::open_graph() as $key => $value) { $og[] = '<meta property="' . $key . '" content="' . HTML::chars($value) . '" />'; } if (!empty($og)) { Widget::add('head', implode("\n", $og)); } // Analytics if ($google_analytics = Kohana::$config->load('site.google_analytics')) { Widget::add('head', HTML::script_source("\nvar tracker;\nhead.js(\n\t{ 'google-analytics': 'http://www.google-analytics.com/ga.js' },\n\tfunction() {\n\t\ttracker = _gat._getTracker('" . $google_analytics . "');\n\t\ttracker._trackPageview();\n\t}\n);\n")); } // Ads /* $ads = Kohana::$config->load('site.ads'); if ($ads && $ads['enabled']) { foreach ($ads['slots'] as $ad => $slot) { if ($slot == 'side') { $this->view->add(View_Page::COLUMN_SIDE, View::factory('ads/' . $ad)); } else { Widget::add($slot, View::factory('ads/' . $ad), Widget::MIDDLE); } } }*/ // Do some CSS magic to page class $page_class = array_merge(array($this->language, $this->request->action(), self::$user ? 'authenticated' : 'unauthenticated'), explode(' ', $this->page_class)); $page_class = implode(' ', array_unique($page_class)); // Set the generic page variables $this->view->styles = $styles; $this->view->skins = $skins; $this->view->language = $this->language; $this->view->id = $this->page_id; $this->view->class = $page_class; if ($this->page_actions) { $this->view->tabs = $this->page_actions; } if ($this->page_breadcrumbs) { $this->view->breadcrumbs = $this->page_breadcrumbs; } // And finally the profiler stats if (self::$user && self::$user->has_role('admin')) { //in_array(Kohana::$environment, array(Kohana::DEVELOPMENT, Kohana::TESTING))) { Widget::add('foot', View::factory('generic/debug')); Widget::add('foot', View::factory('profiler/stats')); } } } parent::after(); }
/** * Check if the topic exists. * * @param int $id topic_id of the topic to check. * @return bool */ public static function topic_exists($id) { $topic = new Model_Forum_Topic($id); return $topic->loaded(); }
/** * Get area last topic * * @return Model_Forum_Topic */ public function last_topic() { return Model_Forum_Topic::factory($this->last_topic_id); }
/** * Destroy controller. */ public function after() { if ($this->_request_type !== Controller::REQUEST_INITIAL) { // AJAX and HMVC requests $this->response->body((string) $this->response->body()); } else { if ($this->auto_render) { // Normal requests // Footer $section = new View_Events_List(); $section->class .= ' col-sm-4'; $section->title = __('New events'); $section->events = Model_Event::factory()->find_new(10); $this->view->add(View_Page::COLUMN_FOOTER, $section); $section = new View_Topics_List(); $section->class .= ' col-sm-4'; $section->topics = Model_Forum_Topic::factory()->find_by_latest_post(10); $this->view->add(View_Page::COLUMN_FOOTER, $section); $section = new View_Blogs_List(); $section->class .= ' col-sm-4'; $section->title = __('New blogs'); $section->blog_entries = Model_Blog_Entry::factory()->find_new(10); $this->view->add(View_Page::COLUMN_FOOTER, $section); // Ads /* $ads = Kohana::$config->load('site.ads'); if ($ads && $ads['enabled']) { foreach ($ads['slots'] as $ad => $slot) { if ($slot == 'side') { $this->view->add(View_Page::COLUMN_SIDE, View::factory('ads/' . $ad)); } else { Widget::add($slot, View::factory('ads/' . $ad), Widget::MIDDLE); } } }*/ // Theme $theme = $this->session->get('theme'); //Arr::get($_COOKIE, 'theme'); if (!in_array($theme, array_keys(Kohana::$config->load('site.themes')))) { if (Visitor::$user) { $theme = Visitor::$user->setting('ui.theme'); } if (!$theme) { $theme = Kohana::$config->load('site.theme'); } $this->session->set('theme', $theme); } // Do some CSS magic to page class $page_class = array_merge(array('theme-' . $theme, Visitor::$user ? 'authenticated' : 'unauthenticated'), explode(' ', $this->page_class)); $page_class = implode(' ', array_unique($page_class)); // Set the generic page variables $this->view->language = $this->language; $this->view->id = $this->page_id; $this->view->class = $page_class; if ($this->page_actions) { $this->view->tabs = $this->page_actions; } if ($this->page_breadcrumbs) { $this->view->breadcrumbs = $this->page_breadcrumbs; } // Set meta data if (!Anqh::page_meta('title')) { Anqh::page_meta('title', $this->view->title ? $this->view->title : Kohana::$config->load('site.site_name')); } // And finally the profiler stats if (Visitor::$user && Visitor::$user->has_role('admin')) { Widget::add('foot', new View_Generic_Debug()); Widget::add('foot', View::factory('profiler/stats')); } } } parent::after(); }
/** * Side views. */ public function _side_views() { // New posts $section = $this->section_topic_list(Model_Forum_Topic::factory()->find_active(20)); $section->title = __('New posts'); $this->view->add(View_Page::COLUMN_SIDE, $section); // New topics // $section = $this->section_topic_list(Model_Forum_Topic::factory()->find_new(20)); // $section->title = __('New topics'); // $this->view->add(View_Page::COLUMN_SIDE, $section); }
/** * Check permission * * @param string $permission * @param Model_User $user * @return boolean */ public function has_permission($permission, $user) { switch ($permission) { case self::PERMISSION_DELETE: return $user && $user->has_role('admin'); case self::PERMISSION_POST: return ($this->status != self::STATUS_LOCKED || $user->has_role('admin')) && $this->has_permission(self::PERMISSION_READ, $user); case self::PERMISSION_READ: return $user && in_array($user->id, $this->recipients()); case self::PERMISSION_UPDATE: return $this->has_permission(self::PERMISSION_READ, $user) && parent::has_permission($permission, $user); } return false; }
/** * Move all topics for this category to the new category, delegates the work to Forum_Topic model. * * @see Model_Forum_Topic::move_all_topics_for_category * @param int $new_id category_id to move to. * @return mixed */ public function move_all_topics_to($new_id) { return Model_Forum_Topic::move_all_topics_for_category($this->id, $new_id); }