/** * Handle GET requests for /admin/tags to display the tags. */ public function get_tags() { $this->theme->wsse = Utils::WSSE(); $this->theme->tags = Tags::vocabulary()->get_tree('term_display asc'); $this->theme->max = Tags::vocabulary()->max_count(); $this->theme->min = Tags::vocabulary()->min_count(); $form = new FormUI('tags'); $form->append(FormControlFacet::create('search')->set_property('data-facet-config', array('onsearch' => 'deselect_all(); $("#tag_collection").manager("update", self.data("visualsearch").searchQuery.facets());', 'facetsURL' => URL::get('admin_ajax_facets', array('context' => 'facets', 'page' => 'tags', 'component' => 'facets')), 'valuesURL' => URL::get('admin_ajax_facets', array('context' => 'facets', 'page' => 'tags', 'component' => 'values'))))); $aggregate = FormControlAggregate::create('selected_items')->set_selector("#tag_collection input")->label('0 Selected'); $aggr_wrap = FormControlWrapper::create('tag_controls_aggregate')->add_class('aggregate_wrapper'); $aggr_wrap->append($aggregate); $delete = FormControlDropbutton::create('delete_dropbutton'); $delete->append(FormControlButton::create('action')->set_caption(_t('Delete selected'))->set_properties(array('title' => _t('Delete selected'), 'value' => 'delete'))); $rename_text = FormControlText::create('rename_text'); $rename = FormControlDropbutton::create('rename_dropbutton'); $rename->append(FormControlButton::create('action')->set_caption(_t('Rename selected'))->set_properties(array('title' => _t('Rename selected'), 'value' => 'rename'))); $tag_controls = $form->append(FormControlWrapper::create('tag_controls'))->add_class("container tag_controls"); $tag_controls->append($aggr_wrap); $tag_controls->append($rename_text); $tag_controls->append($rename); $tag_controls->append($delete); $tag_controls->append(FormControlWrapper::create('selected_tags')->set_setting('wrap_element', 'ul')->set_property('id', 'selected_tags')); if (count($this->theme->tags) > 0) { $tag_collection = $form->append(FormControlWrapper::create('tag_collection')->add_class('container items')->set_setting('wrap_element', 'ul')->set_property('id', 'tag_collection')); $listitems = $this->get_tag_listitems(); foreach ($listitems as $item) { $tag_collection->append($item); } } else { $tag_collection = $form->append(FormControlStatic::create('<p>' . _t('No tags could be found to match the query criteria.') . '</p>')); } $form->on_success(array($this, 'process_tags')); $this->theme->form = $form; Stack::add('admin_header_javascript', 'visualsearch'); Stack::add('admin_header_javascript', 'manage-js'); Stack::add('admin_stylesheet', 'visualsearch-css'); Stack::add('admin_stylesheet', 'visualsearch-datauri-css'); $this->display('tags'); }
_e('Search for other items from %s', array($post->pubdate->get('M, Y'))); ?> "><?php $post->pubdate->out(DateTime::get_default_date_format()); ?> </a></span> <span class="time"><?php _e('at'); ?> <?php $post->pubdate->out(DateTime::get_default_time_format()); ?> </span> <div class="actions"> <?php $post_actions = FormControlDropbutton::create('post' . $post->id . '_postactions'); $post_actions->append(FormControlSubmit::create('edit')->set_caption(_t('Edit'))->set_url(URL::get('display_publish', $post, false))->set_property('title', _t('Edit \'%s\'', array($post->title)))->set_enable(function ($control) use($post) { return ACL::access_check($post->get_access(), 'edit'); })); $post_actions->append(FormControlSubmit::create('view')->set_caption(_t('View'))->set_url($post->permalink . '?preview=1')->set_property('title', _t('View \'%s\'', array($post->title)))); $post_actions->append(FormControlSubmit::create('delete')->set_caption(_t('Delete'))->set_url('javascript:itemManage.remove(' . $post->id . ', \'post\');')->set_property('title', _t('Delete \'%s\'', array($post->title)))->set_enable(function ($control) use($post) { return ACL::access_check($post->get_access(), 'delete'); })); Plugins::act('post_actions', $post_actions, $post); echo $post_actions->pre_out(); echo $post_actions->get($theme); ?> </div> </div> </div> <div class="content">
private function fetch_logs() { // load all the values for our filter drop-downs $dates = $this->fetch_log_dates(); $users = $this->fetch_log_users(); $ips = $this->fetch_log_ips(); extract($this->fetch_log_modules_types()); // $modules and $types $severities = LogEntry::list_severities(); // parse out the arguments we'll fetch logs for // the initial arguments $arguments = array('limit' => Controller::get_var('limit', 20), 'offset' => Controller::get_var('offset', 0)); // filter for the search field $search = Controller::get_var('search', ''); if ($search != '') { $arguments['criteria'] = $search; } // filter by date $date = Controller::get_var('date', 'any'); if ($date != 'any') { $d = DateTime::create($date); // ! means fill any non-specified pieces with default Unix Epoch ones $arguments['year'] = $d->format('Y'); $arguments['month'] = $d->format('m'); } // filter by user $user = Controller::get_var('user', 'any'); if ($user != 'any') { $arguments['user_id'] = $user; } // filter by ip $ip = Controller::get_var('address', 'any'); if ($ip != 'any') { $arguments['ip'] = $ip; } // filter modules and types // @todo get events of a specific type in a specific module, instead of either of the two // the interface doesn't currently make any link between module and type, so we won't worry about it for now $module = Controller::get_var('module', 'any'); $type = Controller::get_var('type', 'any'); if ($module != 'any') { // we get a slugified key back, get the actual module name $arguments['module'] = $modules[$module]; } if ($type != 'any') { // we get a slugified key back, get the actual type name $arguments['type'] = $types[$type]; } // filter by severity $severity = Controller::get_var('severity', 0); if ($severity != 0) { $arguments['severity'] = $severity; } // get the logs! $logs = EventLog::get($arguments); // last, but not least, generate the list of years used for the timeline $months = EventLog::get(array_merge($arguments, array('month_cts' => true))); $years = array(); foreach ($months as $m) { $years[$m->year][] = $m; } // assign all our theme values in one spot // first the filter options $this->theme->dates = $dates; $this->theme->users = $users; $this->theme->addresses = $ips; $this->theme->modules = $modules; $this->theme->types = $types; $this->theme->severities = $severities; // next the filter criteria we used $this->theme->search_args = $search; $this->theme->date = $date; $this->theme->user = $user; $this->theme->address = $ip; $this->theme->module = $module; $this->theme->type = $type; $this->theme->severity = $severity; $this->theme->logs = $logs; $this->theme->years = $years; $form = new FormUI('logs_batch', 'logs_batch'); $form->append(FormControlAggregate::create('entries')->set_selector('.log_entry')->set_value(array())->label('None Selected')); $form->append($actions = FormControlDropbutton::create('actions')); $actions->append(FormControlSubmit::create('delete_selected')->on_success(function (FormUI $form) { $ids = $form->entries->value; $count = 0; /** @var LogEntry $log */ foreach ($ids as $id) { $logs = EventLog::get(array('id' => $id)); foreach ($logs as $log) { $log->delete(); $count++; } } Session::notice(_t('Deleted %d logs.', array($count))); $form->bounce(false); })->set_caption(_t('Delete Selected'))); $actions->append(FormControlSubmit::create('purge_logs')->on_success(function (FormUI $form) { if (EventLog::purge()) { Session::notice(_t('Logs purged.')); } else { Session::notice(_t('There was a problem purging the event logs.')); } $form->bounce(false); })->set_caption(_t('Purge Logs'))); $this->theme->form = $form; $this->theme->wsse = Utils::WSSE(); // prepare a WSSE token for any ajax calls }
echo $group->id; ?> "> <div> <h4><a href="<?php echo URL::get('display_group', 'id=' . $group->id); ?> " title="<?php _e('Edit group'); ?> "><?php echo $group->name; ?> </a></h4> <?php $group_actions = FormControlDropbutton::create('group_actions'); $group_actions->append(FormControlSubmit::create('edit')->set_caption(_t('Edit'))->set_url(URL::get('display_group', 'id=' . $group->id))->set_property('title', _t('Edit \'%s\'', array($group->title)))->set_enable(function ($control) { return User::identify()->can('manage_groups'); })); $group_actions->append(FormControlSubmit::create('delete')->set_caption(_t('Delete'))->set_url('javascript:itemManage.remove(' . $group->id . ', \'group\');')->set_property('title', _t('Delete \'%s\'', array($group->name)))->set_enable(function ($control) { return User::identify()->can('manage_groups'); })); echo $group_actions->pre_out(); echo $group_actions->get($theme); // @todo Add back in filtering of group actions // $actions = Plugins::filter('group_actions', $actions); ?> </div> <?php if (count($users) > 0) { ?>
<p class="legacy"><?php _e('Legacy theme.'); ?> </p> <?php } elseif (isset($inactive_theme['req_parent'])) { ?> <p class="legacy"><?php _e('This theme requires the parent theme named "%s".', array($inactive_theme['req_parent'])); ?> </p> <?php } else { ?> <?php $dbtn = FormControlDropbutton::create('actions'); $dbtn->append(FormControlSubmit::create('activate')->set_url(URL::get('activate_theme', 'theme_dir=' . $inactive_theme['dir'] . '&theme_name=' . $inactive_theme['info']->name))->set_caption(_t('Activate'))); if ($previewed == $inactive_theme['dir']) { $dbtn->append(FormControlSubmit::create('end_preview')->set_url(URL::get('preview_theme', 'theme_dir=' . $inactive_theme['dir'] . '&theme_name=' . $inactive_theme['info']->name))->set_caption(_t('End Preview'))); } else { $dbtn->append(FormControlSubmit::create('preview')->set_url(URL::get('preview_theme', 'theme_dir=' . $inactive_theme['dir'] . '&theme_name=' . $inactive_theme['info']->name))->set_caption(_t('Preview'))); } echo $dbtn->pre_out(); echo $dbtn->get($theme); ?> <?php } ?> </div> <div class="clearfix"> <div class="thumb columns four">
/** * Display the login form * * @param string $name Pre-fill the name field with this name */ protected function login_form() { // Build theme and login page template $this->setup_theme(); if (!$this->theme->template_exists('login')) { $this->theme = Themes::create('admin', 'RawPHPEngine', Site::get_dir('admin_theme', true)); $this->theme->assign('admin_page', 'login'); } // Build the login form $form = new FormUI('habari_login'); //$form->on_success( array( $this, 'loginform_success' ) ); $login_form_title = _t('<h1><a href="%1$s" title="%2$s"><img alt="%2$s" src="%3$s" style="height:1em;margin-right:10px;vertical-align:top;">%4$s</a></h1>', array(Site::get_url('site'), _t('Go to Site'), Site::get_url('habari', '/system/admin/images/habari.logo.png'), Options::get('title'))); $form->append(FormControlStatic::create('title')->set_static($login_form_title)); $form->append(FormControlStatic::create('reset_message')->set_static('<p id="reset_message" class="on_reset">' . _t('Please enter the username you wish to reset the password for. A unique password reset link will be emailed to that user.') . '</p>')); $form->append(FormControlLabel::wrap(_t('Name'), FormControlText::create('habari_username')->set_property('autofocus', 'autofocus'))->set_template('control.label.outsideleft')); $form->append(FormControlLabel::wrap(_t('Password'), FormControlPassword::create('habari_password', null, array('class' => 'off_reset')))->set_template('control.label.outsideleft')->set_properties(array('class' => 'off_reset'))); $form->append($drop_button = FormControlDropbutton::create('submit_button')->add_template_class('ul', 'off_reset')); $drop_button->append(FormControlSubmit::create('login')->on_success(array($this, 'loginform_do_login'))->set_caption(_t('Login'))); $form->append(FormControlStatic::create('reset_link')->set_static('<a href="#" class="off_reset reset_link">' . _t('Reset password') . '</a>')); $form->append(FormControlStatic::create('login_link')->set_static('<a href="#" class="on_reset reset_link">' . _t('Login') . '</a>')); $form->append(FormControlSubmit::create('reset_button')->set_caption(_t('Reset password'))->set_properties(array('class' => 'on_reset'))->on_success(array($this, 'loginform_do_reset'))); // Use the dropbutton's visualizer to select the primary action for form submission upon pressing enter $form->set_settings(array('prefix_html' => '<script>$(function(){$("body").on("keypress", "form[name=' . $form->input_name() . ']", function(e){if(e.which==13){$(this).find("#' . $form->submit_button->get_visualizer() . ' .primary").click();return e.preventDefault()&&false;}});})</script>')); // Let plugins alter this form Plugins::act('form_login', $form); // Assign login form and display the page $this->theme->form = $form; $this->display('login'); return true; }
/** * Retrieve comments. */ public function fetch_comments($params = array()) { // Make certain handler_vars local with defaults, and add them to the theme output $locals = array('do_delete' => false, 'do_spam' => false, 'do_approve' => false, 'do_unapprove' => false, 'comment_ids' => null, 'nonce' => '', 'timestamp' => '', 'password_digest' => '', 'mass_spam_delete' => null, 'mass_delete' => null, 'type' => 'All', 'limit' => 20, 'offset' => 0, 'search' => '', 'status' => 'All', 'orderby' => 'date DESC'); foreach ($locals as $varname => $default) { ${$varname} = isset($this->handler_vars[$varname]) ? $this->handler_vars[$varname] : (isset($params[$varname]) ? $params[$varname] : $default); $this->theme->{$varname} = ${$varname}; } // Setting these mass_delete options prevents any other processing. Desired? if (isset($mass_spam_delete) && $status == 'spam') { // Delete all comments that have the spam status. Comments::delete_by_status('spam'); // let's optimize the table $result = DB::query('OPTIMIZE TABLE {comments}'); Session::notice(_t('Deleted all spam comments')); EventLog::log(_t('Deleted all spam comments'), 'info'); Utils::redirect(); } elseif (isset($mass_delete) && $status == 'unapproved') { // Delete all comments that are unapproved. Comments::delete_by_status('unapproved'); Session::notice(_t('Deleted all unapproved comments')); EventLog::log(_t('Deleted all unapproved comments'), 'info'); Utils::redirect(); } elseif (($do_delete || $do_spam || $do_approve || $do_unapprove) && isset($comment_ids)) { $okay = true; if (empty($nonce) || empty($timestamp) || empty($password_digest)) { $okay = false; } $wsse = Utils::WSSE($nonce, $timestamp); if ($password_digest != $wsse['digest']) { $okay = false; } if ($okay) { if ($do_delete) { $action = 'delete'; } elseif ($do_spam) { $action = 'spam'; } elseif ($do_approve) { $action = 'approve'; } elseif ($do_unapprove) { $action = 'unapprove'; } $ids = array(); foreach ($comment_ids as $id => $id_value) { if (!isset(${'$comment_ids[' . $id . ']'})) { // Skip unmoderated submitted comment_ids $ids[] = $id; } } $to_update = Comments::get(array('id' => $ids)); $modstatus = array(_t('Deleted %d comments') => 0, _t('Marked %d comments as spam') => 0, _t('Approved %d comments') => 0, _t('Unapproved %d comments') => 0, _t('Edited %d comments') => 0); Plugins::act('admin_moderate_comments', $action, $to_update, $this); switch ($action) { case 'delete': // This comment was marked for deletion $to_update = $this->comment_access_filter($to_update, 'delete'); Comments::delete_these($to_update); $modstatus[_t('Deleted %d comments')] = count($to_update); break; case 'spam': // This comment was marked as spam $to_update = $this->comment_access_filter($to_update, 'edit'); Comments::moderate_these($to_update, 'spam'); $modstatus[_t('Marked %d comments as spam')] = count($to_update); break; case 'approve': case 'approved': // Comments marked for approval $to_update = $this->comment_access_filter($to_update, 'edit'); Comments::moderate_these($to_update, 'approved'); $modstatus[_t('Approved %d comments')] = count($to_update); foreach ($to_update as $comment) { $modstatus[_t('Approved comments on these posts: %s')] = (isset($modstatus[_t('Approved comments on these posts: %s')]) ? $modstatus[_t('Approved comments on these posts: %s')] . ' · ' : '') . '<a href="' . $comment->post->permalink . '">' . $comment->post->title . '</a> '; } break; case 'unapprove': case 'unapproved': // This comment was marked for unapproval $to_update = $this->comment_access_filter($to_update, 'edit'); Comments::moderate_these($to_update, 'unapproved'); $modstatus[_t('Unapproved %d comments')] = count($to_update); break; case 'edit': $to_update = $this->comment_access_filter($to_update, 'edit'); foreach ($to_update as $comment) { // This comment was edited if ($_POST['name_' . $comment->id] != null) { $comment->name = $_POST['name_' . $comment->id]; } if ($_POST['email_' . $comment->id] != null) { $comment->email = $_POST['email_' . $comment->id]; } if ($_POST['url_' . $comment->id] != null) { $comment->url = $_POST['url_' . $comment->id]; } if ($_POST['content_' . $comment->id] != null) { $comment->content = $_POST['content_' . $comment->id]; } $comment->update(); } $modstatus[_t('Edited %d comments')] = count($to_update); break; } foreach ($modstatus as $key => $value) { if ($value) { Session::notice(sprintf($key, $value)); } } } Utils::redirect(); } // we load the WSSE tokens // for use in the delete button $this->theme->wsse = Utils::WSSE(); $arguments = array('type' => $type, 'status' => $status, 'limit' => $limit, 'offset' => $offset, 'orderby' => $orderby); // only get comments the user is allowed to manage if (!User::identify()->can('manage_all_comments')) { $arguments['post_author'] = User::identify()->id; } // there is no explicit 'all' type/status for comments, so we need to unset these arguments // if that's what we want. At the same time we can set up the search field $this->theme->search_args = ''; if ($type == 'All') { unset($arguments['type']); } else { $this->theme->search_args = 'type:' . Comment::type_name($type) . ' '; } if ($status == 'All') { unset($arguments['status']); } else { $this->theme->search_args .= 'status:' . Comment::status_name($status); } if ('' != $search) { $arguments = array_merge($arguments, Comments::search_to_get($search)); } $this->theme->comments = Comments::get($arguments); $monthcts = Comments::get(array_merge($arguments, array('month_cts' => 1))); $years = array(); foreach ($monthcts as $month) { if (isset($years[$month->year])) { $years[$month->year][] = $month; } else { $years[$month->year] = array($month); } } $this->theme->years = $years; $baseactions = array(); $statuses = Comment::list_comment_statuses(); foreach ($statuses as $statusid => $statusname) { $baseactions[$statusname] = array('url' => 'javascript:itemManage.update(\'' . $statusname . '\',__commentid__);', 'title' => _t('Change this comment\'s status to %s', array($statusname)), 'label' => Comment::status_action($statusid), 'access' => 'edit'); } /* Standard actions */ $baseactions['delete'] = array('url' => 'javascript:itemManage.update(\'delete\',__commentid__);', 'title' => _t('Delete this comment'), 'label' => _t('Delete'), 'access' => 'delete'); $baseactions['edit'] = array('url' => URL::get('edit_comment', 'id=__commentid__'), 'title' => _t('Edit this comment'), 'label' => _t('Edit'), 'access' => 'edit'); /* Allow plugins to apply actions */ $actions = Plugins::filter('comments_actions', $baseactions, $this->theme->comments); foreach ($this->theme->comments as $comment) { // filter the actions based on the user's permissions $comment_access = $comment->get_access(); $menu = FormControlDropbutton::create('comment' . $comment->id . '_commentactions'); foreach ($actions as $name => $action) { if ($name == Comment::status_name($comment->status)) { // skip current status continue; } if (!isset($action['label']) || empty($action['label'])) { // just grab something so the thing is labeled $action['label'] = _t($name); } // replace constants/placeholders $action['url'] = str_replace('__commentid__', $comment->id, $action['url']); $entry = FormControlSubmit::create($name)->set_caption($action['label'])->set_url($action['url'])->set_property('title', $action['title']); if (!isset($action['access']) || ACL::access_check($comment_access, $action['access'])) { $menu->append($entry); } } $comment->menu = Plugins::filter('comment_actions', $menu, $comment); } }
/** * Handles POST values from /manage/posts. * Used to control what content to show / manage. */ public function post_posts() { // Simply pass $_GET to the function, it's save as only values we understand will be read $this->fetch_posts($_GET); // Check which values have been passed and translate them for the faceted seach $search_values = array(); foreach ($this->locals as $varname => $default) { if (isset($_GET[$varname])) { switch ($varname) { case 'type': $search_values[] = 'type: ' . Post::type_name($_GET['type']); break; case 'status': $search_values[] = 'status: ' . Post::status_name($_GET['status']); break; case 'tag': $tags = explode(',', $_GET['tag']); foreach ($tags as $tag) { $search_values[] = 'tag: ' . $tag; } break; case 'author': $search_values[] = 'author: ' . User::get($_GET['author'])->username; break; default: $search_values[] = $varname . ': ' . $_GET[$varname]; } } } if (count($search_values) > 0) { $search_value = implode(' ', $search_values); } else { $search_value = ''; } // Create search controls and global buttons for the manage page $search = FormControlFacet::create('search'); $search->set_value($search_value)->set_property('data-facet-config', array('onsearch' => '$(".posts").manager("update", self.data("visualsearch").searchQuery.facets());', 'facetsURL' => URL::get('admin_ajax_facets', array('context' => 'facets', 'page' => 'manage', 'component' => 'facets')), 'valuesURL' => URL::get('admin_ajax_facets', array('context' => 'facets', 'page' => 'manage', 'component' => 'values')))); $navigation = FormControlStatic::create('navigation')->set_static('<a href="" id="nav_prev" class="navigation">' . _t('Previous page') . '</a>' . '<a href="" id="nav_next" class="navigation">' . _t('Next page') . '</a>'); $aggregate = FormControlAggregate::create('selected_items')->set_selector('.post_item')->label('None Selected'); $page_actions = FormControlDropbutton::create('page_actions'); $page_actions->append(FormControlSubmit::create('delete')->set_caption(_t('Delete Selected'))->set_properties(array('onclick' => 'itemManage.update(\'delete\');return false;', 'title' => _t('Delete Selected')))); Plugins::act('posts_manage_actions', $page_actions); $form = new FormUI('manage'); $form->append($search); $form->append($navigation); $form->append($aggregate); $form->append($page_actions); $this->theme->form = $form; $this->theme->admin_page = _t('Manage Posts'); $this->theme->admin_title = _t('Manage Posts'); Stack::add('admin_header_javascript', 'visualsearch'); Stack::add('admin_header_javascript', 'manage-js'); Stack::add('admin_stylesheet', 'visualsearch-css'); Stack::add('admin_stylesheet', 'visualsearch-datauri-css'); $this->display('posts'); }