loggedin ) { Session::add_to_set( 'login', $_SERVER['REQUEST_URI'], 'original' ); if ( URL::get_matched_rule()->name == 'admin_ajax' && isset($_SERVER['HTTP_REFERER']) ) { header( 'Content-Type: text/javascript;charset=utf-8' ); echo '{callback: function(){location.href="'.$_SERVER['HTTP_REFERER'].'"} }'; } else { $post_raw = $_POST->get_array_copy_raw(); if ( !empty( $post_raw ) ) { Session::add_to_set( 'last_form_data', $post_raw, 'post' ); Session::error( _t('We saved the last form you posted. Log back in to continue its submission.'), 'expired_form_submission' ); } $get_raw = $_GET->get_array_copy_raw(); if ( !empty( $get_raw ) ) { Session::add_to_set( 'last_form_data', $get_raw, 'get' ); Session::error( _t('We saved the last form you posted. Log back in to continue its submission.'), 'expired_form_submission' ); } Utils::redirect( URL::get( 'user', array( 'page' => 'login' ) ) ); } exit; } $last_form_data = Session::get_set( 'last_form_data' ); // This was saved in the "if ( !$user )" above, UserHandler transferred it properly. /* At this point, Controller has not created handler_vars, so we have to modify $_POST/$_GET. */ if ( isset( $last_form_data['post'] ) ) { $_POST = $_POST->merge( $last_form_data['post'] ); $_SERVER['REQUEST_METHOD'] = 'POST'; // This will trigger the proper act_admin switches. Session::remove_error( 'expired_form_submission' ); } if ( isset( $last_form_data['get'] ) ) { $_GET = $_GET->merge( $last_form_data['get'] ); Session::remove_error( 'expired_form_submission' ); // No need to change REQUEST_METHOD since GET is the default. } $user->remember(); // Create an instance of the active public theme so that its plugin functions are implemented $this->active_theme = Themes::create(); // setup the stacks for javascript in the admin - it's a method so a plugin can call it externally self::setup_stacks(); } /** * Dispatches the request to the defined method. (ie: post_{page}) */ public function act_admin() { $page = ( isset( $this->handler_vars['page'] ) && !empty( $this->handler_vars['page'] ) ) ? $this->handler_vars['page'] : 'dashboard'; if ( isset($this->handler_vars['content_type']) ) { $type = Plugins::filter('post_type_display', Post::type_name($this->handler_vars['content_type']), 'singular'); } elseif ( $page == 'publish' && isset($this->handler_vars['id'] ) ) { $type = Plugins::filter('post_type_display', Post::type_name(Post::get(intval($this->handler_vars['id']))->content_type), 'singular'); } else { $type = ''; } //$type = ( isset( $this->handler_vars['content_type'] ) && !empty( $this->handler_vars['content_type'] ) ) ? $this->handler_vars['content_type'] : ''; $theme_dir = Plugins::filter( 'admin_theme_dir', Site::get_dir( 'admin_theme', TRUE ) ); $this->theme = Themes::create( 'admin', 'RawPHPEngine', $theme_dir ); // Add some default stylesheets Stack::add('admin_stylesheet', array(Site::get_url('admin_theme') . '/css/admin.css', 'screen'), 'admin'); // Add some default template variables $this->set_admin_template_vars( $this->theme ); $this->theme->admin_type = $type; $this->theme->admin_page = $page; $this->theme->admin_page_url = ( $page == 'dashboard' ) ? URL::get( 'admin', 'page=' ) : URL::get( 'admin', 'page=' . $page ); $this->theme->page = $page; $this->theme->admin_title = ucwords($page) . ( $type != '' ? ' ' . ucwords($type) : '' ); $this->theme->admin_title = isset( $this->theme->mainmenu[$this->theme->admin_page]['text'] ) ? $this->theme->mainmenu[$this->theme->admin_page]['text'] : ucwords($page) . ( $type != '' ? ' ' . ucwords($type) : '' ); // Access check to see if the user is allowed the requested page Utils::check_request_method( array( 'GET', 'HEAD', 'POST' ) ); if ( !$this->access_allowed( $page, $type ) ) { Session::error(_t('Access to that page has been denied by the administrator.')); $this->get_blank(); } switch( $_SERVER['REQUEST_METHOD'] ) { case 'POST': // Let plugins try to handle the page Plugins::act('admin_theme_post_' . $page, $this, $this->theme); // Handle POSTs to the admin pages $fn = 'post_' . $page; if ( method_exists( $this, $fn ) ) { $this->$fn(); } else { $classname = get_class( $this ); echo sprintf( _t( '%1$s->%2$s() does not exist.' ), $classname, $fn ); exit; } break; case 'GET': case 'HEAD': // Let plugins try to handle the page Plugins::act('admin_theme_get_' . $page, $this, $this->theme); // Handle GETs of the admin pages $fn = 'get_' . $page; if ( method_exists( $this, $fn ) ) { $this->$fn(); exit; } // If a get_ function doesn't exist, just load the template and display it if ( $this->theme->template_exists( $page ) ) { $this->display( $page ); } else { // The requested console page doesn't exist header( 'HTTP/1.0 404 Not Found' ); $this->get_blank(_t('The page you were looking for was not found.')); } break; } } /** * Handle incoming requests to /admin_ajax for admin ajax requests */ public function act_admin_ajax() { header( 'Content-Type: text/javascript;charset=utf-8' ); $context = $this->handler_vars['context']; if ( method_exists( $this, 'ajax_' . $context ) ) { $type = ( isset( $this->handler_vars['content_type'] ) && !empty( $this->handler_vars['content_type'] ) ) ? $this->handler_vars['content_type'] : ''; // Access check to see if the user is allowed the requested page if ( $this->access_allowed( 'ajax_' . $context, $type ) ) { call_user_func( array( $this, 'ajax_' . $context ), $this->handler_vars ); } } else { header( 'HTTP/1.1 403 Forbidden', true, 403 ); die(); } } /** * Handles get requests from the options admin page */ public function get_options() { $this->post_options(); } /** * Handles POST requests from the options admin page */ public function post_options() { $option_items = array(); $timezones = DateTimeZone::listIdentifiers(); $timezones = array_merge( array( ''=>'' ), array_combine( array_values( $timezones ), array_values( $timezones ) ) ); $option_items[_t('Name & Tagline')] = array( 'title' => array( 'label' => _t('Site Name'), 'type' => 'text', 'helptext' => '', ), 'tagline' => array( 'label' => _t('Site Tagline'), 'type' => 'text', 'helptext' => '', ), 'about' => array( 'label' => _t('About'), 'type' => 'textarea', 'helptext' => '', ), ); $option_items[_t('Publishing')] = array( 'pagination' => array( 'label' => _t('Items per Page'), 'type' => 'text', 'helptext' => '', ), 'atom_entries' => array( 'label' => _t('Entries to show in Atom feed'), 'type' => 'text', 'helptext' => '', ), 'comments_require_id' => array( 'label' => _t('Require Comment Author Info'), 'type' => 'checkbox', 'helptext' => '', ), ); $option_items[_t('Time & Date')] = array( /*'presets' => array( 'label' => _t('Presets'), 'type' => 'select', 'selectarray' => array( 'europe' => _t('Europe') ), 'helptext' => '', ),*/ 'timezone' => array( 'label' => _t('Time Zone'), 'type' => 'select', 'selectarray' => $timezones, 'helptext' => _t( 'Current Date Time: %s', array( HabariDateTime::date_create()->format() ) ), ), 'dateformat' => array( 'label' => _t('Date Format'), 'type' => 'text', 'helptext' => _t( 'Current Date: %s', array( HabariDateTime::date_create()->date ) ), ), 'timeformat' => array( 'label' => _t('Time Format'), 'type' => 'text', 'helptext' => _t( 'Current Time: %s', array( HabariDateTime::date_create()->time ) ), ) ); $option_items[_t('Language')] = array( 'locale' => array( 'label' => _t( 'Locale' ), 'type' => 'select', 'selectarray' => array_merge( array( '' => 'default' ), array_combine( HabariLocale::list_all(), HabariLocale::list_all() ) ), 'helptext' => _t( 'International language code' ), ), 'system_locale' => array( 'label' => _t('System Locale'), 'type' => 'text', 'helptext' => _t( 'The appropriate locale code for your server' ), ), ); $option_items[_t('Troubleshooting')] = array( 'log_backtraces' => array( 'label' => _t( 'Log Backtraces' ), 'type' => 'checkbox', 'helptext' => _t( 'Logs error backtraces to the log table\'s data column. Can drastically increase log size!' ), ), ); /*$option_items[_t('Presentation')] = array( 'encoding' => array( 'label' => _t('Encoding'), 'type' => 'select', 'selectarray' => array( 'UTF-8' => 'UTF-8' ), 'helptext' => '', ), );*/ $option_items = Plugins::filter( 'admin_option_items', $option_items ); $form = new FormUI('Admin Options'); $tab_index = 3; foreach ( $option_items as $name => $option_fields ) { $fieldset = $form->append( 'wrapper', Utils::slugify( _u($name) ), $name ); $fieldset->class = 'container settings'; $fieldset->append( 'static', $name, '

' . htmlentities( $name, ENT_COMPAT, 'UTF-8' ) . '

' ); foreach ( $option_fields as $option_name => $option ) { $field = $fieldset->append( $option['type'], $option_name, $option_name, $option['label'] ); $field->template = 'optionscontrol_' . $option['type']; $field->class = 'item clear'; if ( $option['type'] == 'select' && isset( $option['selectarray'] ) ) { $field->options = $option['selectarray']; } $field->tabindex = $tab_index; $tab_index++; if ( isset( $option['helptext'] ) ) { $field->helptext = $option['helptext']; } else { $field->helptext = ''; } } } /* @todo: filter for additional options from plugins * We could either use existing config forms and simply extract * the form controls, or we could create something different */ $submit = $form->append( 'submit', 'apply', _t('Apply'), 'admincontrol_submit' ); $submit->tabindex = $tab_index; $form->on_success( array( $this, 'form_options_success' ) ); $this->theme->form = $form->get(); $this->theme->option_names = array_keys( $option_items ); $this->theme->display( 'options' ); } /** * Display a message when the site options are saved, and save those options * * @param FormUI $form The successfully submitted form */ public function form_options_success($form) { Session::notice( _t( 'Successfully updated options' ) ); $form->save(); Utils::redirect(); } /** * Handles POST requests from the dashboard. */ public function post_dashboard() { $this->get_dashboard(); } /** * Handles get requests for the dashboard * @todo update check should probably be cron'd and cached, not re-checked every load */ public function get_dashboard() { // Not sure how best to determine this yet, maybe set an option on install, maybe do this: $firstpostdate = DB::get_value('SELECT min(pubdate) FROM {posts} WHERE status = ?', array(Post::status('published'))); if ( intval( $firstpostdate ) !== 0 ) $firstpostdate = time() - $firstpostdate; $this->theme->active_time = array( 'years' => floor($firstpostdate / 31556736), 'months' => floor(($firstpostdate % 31556736) / 2629728), 'days' => round(($firstpostdate % 2629728) / 86400), ); // get the active theme, so we can check it $active_theme = Themes::get_active(); $active_theme = $active_theme->name . ':' . $active_theme->version; // if the active plugin list has changed, expire the updates cache if ( Cache::has( 'dashboard_updates' ) && ( Cache::get( 'dashboard_updates_plugins' ) != Options::get( 'active_plugins' ) ) ) { Cache::expire( 'dashboard_updates' ); } // if the theme version has changed, expire the updates cache if ( Cache::has( 'dashboard_updates' ) && ( Cache::get( 'dashboard_updates_theme' ) != $active_theme ) ) { Cache::expire( 'dashboard_updates' ); } /* * Check for updates to core and any hooked plugins * cache the output so we don't make a request every load but can still display updates */ if ( Cache::has( 'dashboard_updates' ) ) { $this->theme->updates = Cache::get( 'dashboard_updates' ); } else { $updates = Update::check(); if ( !Error::is_error( $updates ) ) { Cache::set( 'dashboard_updates', $updates ); $this->theme->updates = $updates; // cache the set of plugins we just used to check for Cache::set( 'dashboard_updates_plugins', Options::get( 'active_plugins' ) ); // cache the active theme we just used to check for Cache::set( 'dashboard_updates_theme', $active_theme ); } else { $this->theme->updates = array(); } } $this->theme->stats = array( 'author_count' => Users::get( array( 'count' => 1 ) ), 'page_count' => Posts::get( array( 'count' => 1, 'content_type' => Post::type('page'), 'status' => Post::status('published') ) ), 'entry_count' => Posts::get( array( 'count' => 1, 'content_type' => Post::type('entry'), 'status' => Post::status('published') ) ), 'comment_count' => Comments::count_total( Comment::STATUS_APPROVED, FALSE ), 'tag_count' => Tags::count_total(), 'page_draft_count' => Posts::get( array( 'count' => 1, 'content_type' => Post::type('page'), 'status' => Post::status('draft'), 'user_id' => User::identify()->id ) ), 'entry_draft_count' => Posts::get( array( 'count' => 1, 'content_type' => Post::type('entry'), 'status' => Post::status('draft'), 'user_id' => User::identify()->id ) ), 'unapproved_comment_count' => User::identify()->can( 'manage_all_comments' ) ? Comments::count_total( Comment::STATUS_UNAPPROVED, FALSE ) : Comments::count_by_author( User::identify()->id, Comment::STATUS_UNAPPROVED ), 'spam_comment_count' => User::identify()->can( 'manage_all_comments' ) ? Comments::count_total( Comment::STATUS_SPAM, FALSE ) : Comments::count_by_author( User::identify()->id, Comment::STATUS_SPAM ), 'user_entry_scheduled_count' => Posts::get( array( 'count' => 1, 'content_type' => Post::type( 'any' ), 'status' => Post::status( 'scheduled' ), 'user_id' => User::identify()->id ) ), ); $this->fetch_dashboard_modules(); // check for first run $u = User::identify(); if ( ! isset( $u->info->experience_level ) ) { $this->theme->first_run = true; $u->info->experience_level = 'user'; $u->info->commit(); } else { $this->theme->first_run = false; } $this->display( 'dashboard' ); } /** * Fetches active modules for display on the dashboard */ /* public function fetch_dashboard_modules() { if ( count( Modules::get_all() ) == 0 ) { $this->theme->modules = array(); return; } // get the active module list $modules = Modules::get_active(); if(User::identify()->can('manage_dash_modules')) { // append the 'Add Item' module $modules['nosort'] = 'Add Item'; // register the 'Add Item' filter Plugins::register( array( $this, 'filter_dash_module_add_item' ), 'filter', 'dash_module_add_item'); } foreach ( $modules as $id => $module_name ) { $slug = Utils::slugify( (string) $module_name, '_' ); $module = array( 'name' => $module_name, 'title' => $module_name, 'content' => '', 'options' => '' ); $module = Plugins::filter( 'dash_module_' .$slug, $module, $id, $this->theme ); $modules[$id] = $module; } $this->theme->modules = $modules; } */ /** * Handles POST requests from the publish page. */ public function post_publish() { $this->get_publish(); } public static function form_publish_success( FormUI $form , $thispost ) { $post_id = 0; if ( isset($thispost->id) ) { $post_id = intval($thispost->id); } Utils::debug( $post_id ); // If an id has been passed in, we're updating an existing post, otherwise we're creating one if ( 0 !== $post_id ) { $post = Post::get( array( 'id' => $post_id, 'status' => Post::status( 'any' ) ) ); $thispost->theme->admin_page = sprintf(_t('Publish %s'), Plugins::filter('post_type_display', Post::type_name($post->content_type), 'singular')); // $form = $post->get_form( 'admin' ); // Verify that the post hasn't already been updated since the form was loaded if ( $post->modified != $form->modified->value ) { Session::notice( _t( 'The post %1$s was updated since you made changes. Please review those changes before overwriting them.', array( sprintf('\'%2$s\'', $post->permalink, htmlspecialchars( $post->title ) ) ) ) ); Utils::redirect( URL::get( 'admin', 'page=publish&id=' . $post->id ) ); exit; } // Don't try to update form values that have been removed by plugins $expected = array('title', 'tags', 'content'); foreach ( $expected as $field ) { if ( isset($form->$field) ) { $post->$field = $form->$field->value; } } if ( $form->newslug->value == '' ) { Session::notice( _t( 'A post slug cannot be empty. Keeping old slug.' ) ); } elseif ( $form->newslug->value != $form->slug->value ) { $post->slug = $form->newslug->value; } // sorry, we just don't allow changing posts you don't have rights to if ( ! ACL::access_check( $post->get_access(), 'edit' ) ) { Session::error( _t( 'You don\'t have permission to edit that post' ) ); $thispost->get_blank(); } // sorry, we just don't allow changing content types to types you don't have rights to $user = User::identify(); $type = 'post_' . Post::type_name( $form->content_type->value ); if ( $form->content_type->value != $post->content_type && ( $user->cannot( $type ) || ! $user->can_any( array( 'own_posts' => 'edit', 'post_any' => 'edit', $type => 'edit' ) ) ) ) { Session::error(_t('Changing content types is not allowed')); $thispost->get_blank(); } $post->content_type = $form->content_type->value; // if not previously published and the user wants to publish now, change the pubdate to the current date/time // if the post pubdate is <= the current date/time. if ( ( $post->status != Post::status( 'published' ) ) && ( $form->status->value == Post::status( 'published' ) ) && ( HabariDateTime::date_create( $form->pubdate->value )->int <= HabariDateTime::date_create()->int ) ) { $post->pubdate = HabariDateTime::date_create(); } // else let the user change the publication date. // If previously published and the new date is in the future, the post will be unpublished and scheduled. Any other status, and the post will just get the new pubdate. // This will result in the post being scheduled for future publication if the date/time is in the future and the new status is published. else { $post->pubdate = HabariDateTime::date_create( $form->pubdate->value ); } $minor = $form->minor_edit->value && ($post->status != Post::status('draft')); $post->status = $form->status->value; } else { $post = new Post(); // $form = $post->get_form( 'admin' ); // check the user can create new posts of the set type. $user = User::identify(); $type = 'post_' . Post::type_name($form->content_type->value); if ( ACL::user_cannot( $user, $type) || ( ! ACL::user_can( $user, 'post_any', 'create' ) && ! ACL::user_can( $user, $type, 'create') ) ) { Session::error(_t('Creating that post type is denied')); $thispost->get_blank(); } // $form->set_option( 'form_action', URL::get('admin', 'page=publish' ) ); $form->on_success( array( $thispost, 'form_publish_success' ) ); if ( HabariDateTime::date_create( $form->pubdate->value )->int > $post->pubdate->int ) { $post->pubdate = HabariDateTime::date_create( $form->pubdate->value ); } $postdata = array( 'slug' => $form->newslug->value, 'user_id' => User::identify()->id, 'pubdate' => $post->pubdate, 'status' => $form->status->value, 'content_type' => $form->content_type->value, ); // Don't try to add form values that have been removed by plugins $expected = array('title', 'tags', 'content'); foreach ( $expected as $field ) { if ( isset($form->$field) ) { $postdata[$field] = $form->$field->value; } } $minor = false; $post = Post::create( $postdata ); } if ( $post->pubdate->int > HabariDateTime::date_create()->int && $post->status == Post::status( 'published' ) ) { $post->status = Post::status( 'scheduled' ); } $post->info->comments_disabled = !$form->comments_enabled->value; Plugins::act('publish_post', $post, $form); $post->update( $minor ); $permalink = ( $post->status != Post::status( 'published' ) ) ? $post->permalink . '?preview=1' : $post->permalink; Session::notice( sprintf( _t( 'The post %1$s has been saved as %2$s.' ), sprintf('\'%2$s\'', $permalink, htmlspecialchars( $post->title ) ), Post::status_name( $post->status ) ) ); if ( $post->slug != Utils::slugify( $post->title ) ) { Session::notice( sprintf( _t( 'The content address is \'%1$s\'.'), $post->slug )); } Utils::redirect( URL::get( 'admin', 'page=publish&id=' . $post->id ) ); } /** * Handles GET requests of the publish page. */ public function get_publish( $template = 'publish') { $extract = $this->handler_vars->filter_keys('id', 'content_type'); foreach ( $extract as $key => $value ) { $$key = $value; } // Utils::debug( $id ); // 0 is what's assigned to new posts if ( isset( $id ) && ( $id != 0 )) { $post = Post::get( array( 'id' => $id, 'status' => Post::status( 'any' ) ) ); if ( !$post ) { Session::error(_t('Access to that post id is denied')); $this->get_blank(); } $this->theme->post = $post; } else { $post = new Post(); $this->theme->post = $post; $post->content_type = Post::type( ( isset( $content_type ) ) ? $content_type : 'entry' ); // check the user can create new posts of the set type. $user = User::identify(); $type = 'post_' . Post::type_name( $post->content_type ); if ( ACL::user_cannot( $user, $type ) || ( ! ACL::user_can( $user, 'post_any', 'create' ) && ! ACL::user_can( $user, $type, 'create' ) ) ) { Session::error( _t( 'Access to create posts of type %s is denied', array( Post::type_name( $post->content_type ) ) ) ); $this->get_blank(); } } // Utils::debug( $this->theme ); $this->theme->admin_page = sprintf(_t('Publish %s'), Plugins::filter('post_type_display', Post::type_name($post->content_type), 'singular')); $this->theme->admin_title = sprintf(_t('Publish %s'), Plugins::filter('post_type_display', Post::type_name($post->content_type), 'singular')); // Utils::debug( $this->theme ); $statuses = Post::list_post_statuses( false ); $this->theme->statuses = $statuses; $form = $post->get_form( 'admin' ); $form->set_option( 'form_action', URL::get('admin', 'page=publish' ) ); $this->theme->form = $form; $this->theme->wsse = Utils::WSSE(); $this->display( $template ); } /** * Deletes a post from the database. */ public function post_delete_post() { $extract = $this->handler_vars->filter_keys('id', 'nonce', 'timestamp', 'digest'); foreach ( $extract as $key => $value ) { $$key = $value; } $okay = TRUE; if ( empty( $id ) || empty( $nonce ) || empty( $timestamp ) || empty( $digest ) ) { $okay = FALSE; } $wsse = Utils::WSSE( $nonce, $timestamp ); if ( $digest != $wsse['digest'] ) { $okay = FALSE; } $post = Post::get( array( 'id' => $id, 'status' => Post::status( 'any' ) ) ); if ( ! ACL::access_check( $post->get_access(), 'delete' ) ) { $okay = FALSE; } if ( !$okay ) { Utils::redirect( URL::get( 'admin', 'page=posts&type='. Post::status( 'any' ) ) ); } $post->delete(); Session::notice( sprintf( _t( 'Deleted the %1$s titled "%2$s".' ), Post::type_name( $post->content_type ), htmlspecialchars( $post->title ) ) ); Utils::redirect( URL::get( 'admin', 'page=posts&type=' . Post::status( 'any' ) ) ); } /** * Handles GET requests of a user page. */ public function get_user() { $edit_user = User::identify(); $permission = false; if ( ($this->handler_vars['user'] == '') || (User::get_by_name($this->handler_vars['user']) == $edit_user) ) { if($edit_user->can('manage_self') || $edit_user->can('manage_users')) { $permission = true; } $who = _t("You"); $possessive = _t("Your User Information"); } else { if($edit_user->can('manage_users')) { $permission = true; } $edit_user = User::get_by_name($this->handler_vars['user']); $who = $edit_user->username; $possessive = sprintf( _t("%s's User Information"), $who ); } if(!$permission) { Session::error(_t('Access to that page has been denied by the administrator.')); $this->get_blank(); return; } // Get author list $author_list = Users::get_all(); $authors[0] = _t('nobody'); foreach ( $author_list as $author ) { $authors[ $author->id ] = $author->displayname; } unset($authors[ $edit_user->id ]); // We can't reassign posts to ourself $this->theme->authors = $authors; $this->theme->edit_user = $edit_user; $this->theme->who = $who; $this->theme->possessive = $possessive; // Redirect to the users management page if we're trying to edit a non-existent user if ( !$edit_user ) { Session::error( _t( 'No such user!' ) ); Utils::redirect( URL::get( 'admin', 'page=users' ) ); } $this->theme->edit_user = $edit_user; $field_sections = array( 'user_info' => $possessive, 'change_password' => _t('Change Password'), 'regional_settings' => _t('Regional Settings'), 'dashboard' => _t( 'Dashboard' ), ); $form = new FormUI('User Options'); // Create a tracker for who we are dealing with $form->append('hidden', 'edit_user', 'edit_user'); $form->edit_user->value = $edit_user->id; // Generate sections foreach ( $field_sections as $key => $name ) { $fieldset = $form->append( 'wrapper', $key, $name ); $fieldset->class = 'container settings'; $fieldset->append( 'static', $key, '

' . htmlentities( $name, ENT_COMPAT, 'UTF-8' ) . '

' ); } // User Info $displayname = $form->user_info->append('text', 'displayname', 'null:null', _t('Display Name'), 'optionscontrol_text'); $displayname->class[] = 'important item clear'; $displayname->value = $edit_user->displayname; $username = $form->user_info->append('text', 'username', 'null:null', _t('User Name'), 'optionscontrol_text'); $username->class[] = 'item clear'; $username->value = $edit_user->username; $username->add_validator('validate_username', $edit_user->username); $email = $form->user_info->append('text', 'email', 'null:null', _t('Email'), 'optionscontrol_text'); $email->class[] = 'item clear'; $email->value = $edit_user->email; $email->add_validator('validate_email'); $imageurl = $form->user_info->append('text', 'imageurl', 'null:null', _t('Portrait URL'), 'optionscontrol_text'); $imageurl->class[] = 'item clear'; $imageurl->value = $edit_user->info->imageurl; // Change Password $password1 = $form->change_password->append('text', 'password1', 'null:null', _t('New Password'), 'optionscontrol_text'); $password1->class[] = 'item clear'; $password1->type = 'password'; $password1->value = ''; $password2 = $form->change_password->append('text', 'password2', 'null:null', _t('New Password Again'), 'optionscontrol_text'); $password2->class[] = 'item clear'; $password2->type = 'password'; $password2->value = ''; $delete = $this->handler_vars->filter_keys('delete'); // don't validate password match if action is delete if (!isset($delete['delete'])) { $password2->add_validator('validate_same', $password1, _t('Passwords must match.')); } // Regional settings $timezones = DateTimeZone::listIdentifiers(); $timezones = array_merge( array_combine( array_values( $timezones ), array_values( $timezones ) ) ); $locale_tz = $form->regional_settings->append('text', 'locale_tz', 'null:null', _t('Timezone'), 'optionscontrol_select'); $locale_tz->class[] = 'item clear'; $locale_tz->value = $edit_user->info->locale_tz; $locale_tz->options = $timezones; $locale_tz->multiple = false; $locale_date_format = $form->regional_settings->append('text', 'locale_date_format', 'null:null', _t('Date Format'), 'optionscontrol_text'); $locale_date_format->class[] = 'item clear'; $locale_date_format->value = $edit_user->info->locale_date_format; if ( isset($edit_user->info->locale_date_format) && $edit_user->info->locale_date_format != '' ) { $current = HabariDateTime::date_create()->get($edit_user->info->locale_date_format); } else { $current = HabariDateTime::date_create()->date; } $locale_date_format->helptext = _t('See php.net/date for details. Current format: %s', array('http://php.net/date', $current) ); $locale_time_format = $form->regional_settings->append('text', 'locale_time_format', 'null:null', _t('Time Format'), 'optionscontrol_text'); $locale_time_format->class[] = 'item clear'; $locale_time_format->value = $edit_user->info->locale_time_format; if ( isset($edit_user->info->locale_time_format) && $edit_user->info->locale_time_format != '' ) { $current = HabariDateTime::date_create()->get($edit_user->info->locale_time_format); } else { $current = HabariDateTime::date_create()->time; } $locale_time_format->helptext = _t('See php.net/date for details. Current format: %s', array('http://php.net/date', $current) ); $spam_count = $form->dashboard->append( 'checkbox', 'dashboard_hide_spam_count', 'null:null', _t( 'Hide Spam Count' ), 'optionscontrol_checkbox' ); $spam_count->class[] = 'item clear'; $spam_count->helptext = _t( 'Hide the number of SPAM comments on your dashboard.' ); $spam_count->value = $edit_user->info->dashboard_hide_spam_count; // Controls $controls = $form->append( 'wrapper', 'page_controls' ); $controls->class = 'container controls transparent'; $submit = $controls->append( 'submit', 'apply', _t('Apply'), 'optionscontrol_submit' ); $submit->class[] = 'pct30'; $controls->append( 'static', 'reassign', '' . _t('Reassign posts to: %s', array(Utils::html_select('reassign', $authors)) ) . '' . _t('and') . ''); $form->on_success( array( $this, 'form_user_success' ) ); // Let plugins alter this form Plugins::act('form_user', $form, $edit_user); $this->theme->form = $form->get(); $this->theme->display('user'); } /** * Handles form submission from a user's page. */ public function form_user_success($form) { $edit_user = User::get_by_id($form->edit_user->value); $current_user = User::identify(); // Let's check for deletion if ( Controller::get_var('delete') != NULL ) { if ( $current_user->id != $edit_user->id ) { // We're going to delete the user before we need it, so store the username $username = $edit_user->username; $posts = Posts::get( array( 'user_id' => $edit_user->id, 'nolimit' => true ) ); if ( ( Controller::get_var('reassign') != NULL ) && (Controller::get_var('reassign') != 0) && (Controller::get_var('reassign') != $edit_user->id)) { // we're going to re-assign all of this user's posts $newauthor = Controller::get_var('reassign'); Posts::reassign( $newauthor, $posts ); $edit_user->delete(); } else { // delete user, then delete posts $edit_user->delete(); // delete posts foreach ( $posts as $post ) { $post->delete(); } } Session::notice( sprintf( _t( '%s has been deleted' ), $username ) ); Utils::redirect(URL::get('admin', array('page' => 'users'))); } else { Session::notice( _t( 'You cannot delete yourself.') ); } } $update = false; // Change username if ( isset($form->username) && $edit_user->username != $form->username->value ) { Session::notice( _t( '%1$s has been renamed to %2$s.', array($edit_user->username, $form->username->value) ) ); $edit_user->username = $form->username->value; $update = true; } // Change email if ( isset($form->email) && $edit_user->email != $form->email->value ) { $edit_user->email = $form->email->value; $update = true; } // Change password if ( isset($form->password1) && !(Utils::crypt($form->password1->value, $edit_user->password)) && ($form->password1->value != '') ) { Session::notice( _t( 'Password changed.' ) ); $edit_user->password = Utils::crypt( $form->password1->value ); $edit_user->update(); } // Set various info fields $info_fields = array('displayname', 'imageurl', 'locale_tz', 'locale_date_format', 'locale_time_format', 'dashboard_hide_spam_count'); // let plugins easily specify other user info fields to pick $info_fields = Plugins::filter( 'adminhandler_post_user_fields', $info_fields ); foreach ( $info_fields as $info_field ) { if ( isset($form->{$info_field}) && ($edit_user->info->{$info_field} != $form->{$info_field}->value) ) { $edit_user->info->{$info_field} = $form->$info_field->value; $update = true; } } // Let plugins tell us to update $update = Plugins::filter( 'form_user_update', $update, $form, $edit_user ); if ( $update ) { $edit_user->update(); Session::notice( _t('User updated.') ); } Utils::redirect(URL::get('admin', array('page' => 'user', 'user' => $edit_user->username))); } /** * Handles POST requests from the user profile page. */ public function post_user() { $this->get_user(); } /** * Handles AJAX from /users. * Used to delete users and fetch new ones. */ public function ajax_update_users($handler_vars) { Utils::check_request_method( array( 'POST' ) ); echo json_encode( $this->update_users( $handler_vars ) ); } /** * Update an array of POSTed users. */ public function update_users($handler_vars) { if ( isset($handler_vars['delete']) ) { $currentuser = User::identify(); $wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] ); if ( isset($handler_vars['digest']) && $handler_vars['digest'] != $wsse['digest'] ) { Session::error( _t('WSSE authentication failed.') ); return Session::messages_get( true, 'array' ); } foreach ( $_POST as $id => $delete ) { // skip POST elements which are not log ids if ( preg_match( '/^p\d+/', $id ) && $delete ) { $id = substr($id, 1); $ids[] = array( 'id' => $id ); } } if ( isset( $handler_vars['checkbox_ids'] ) ) { $checkbox_ids = $handler_vars['checkbox_ids']; foreach ( $checkbox_ids as $id => $delete ) { if ( $delete ) { $ids[] = array( 'id' => $id ); } } } $count = 0; if ( ! isset($ids) ) { Session::notice( _t('No users deleted.') ); return Session::messages_get( true, 'array' ); } foreach ( $ids as $id ) { $id = $id['id']; $user = User::get_by_id( $id ); if ( $currentuser != $user ) { $assign = intval( $handler_vars['reassign'] ); if ( $user->id == $assign ) { return; } $posts = Posts::get( array( 'user_id' => $user->id, 'nolimit' => 1) ); if ( isset($posts[0]) ) { if ( 0 == $assign ) { foreach ( $posts as $post ) { $post->delete(); } } else { Posts::reassign( $assign, $posts ); } } $user->delete(); } else { $msg_status = _t('You cannot delete yourself.'); } $count++; } if ( !isset($msg_status) ) { $msg_status = sprintf( _t('Deleted %d users.'), $count ); } Session::notice( $msg_status ); } } /** * Assign values needed to display the users listing * */ private function fetch_users($params = NULL) { // prepare the WSSE tokens $this->theme->wsse = Utils::WSSE(); // Get author list $author_list = Users::get_all(); $authors[0] = _t('nobody'); foreach ( $author_list as $author ) { $authors[ $author->id ] = $author->displayname; } $this->theme->authors = $authors; } /** * Handles GET requests of the users page. */ public function get_users() { $this->fetch_users(); $this->theme->display('users'); } /** * Handles POST requests from the Users listing (ie: creating a new user) */ public function post_users() { $this->fetch_users(); $extract = $this->handler_vars->filter_keys('newuser', 'delete', 'new_pass1', 'new_pass2', 'new_email', 'new_username'); foreach ( $extract as $key => $value ) { $$key = $value; } if ( isset($newuser) ) { $action = 'newuser'; } elseif ( isset($delete) ) { $action = 'delete'; } $error = ''; if ( isset( $action ) && ( 'newuser' == $action ) ) { if ( !isset( $new_pass1 ) || !isset( $new_pass2 ) || empty( $new_pass1 ) || empty( $new_pass2 ) ) { Session::error( _t( 'Password is required.' ), 'adduser' ); } else if ( $new_pass1 !== $new_pass2 ) { Session::error( _t( 'Password mis-match.'), 'adduser' ); } if ( !isset( $new_email ) || empty( $new_email ) || ( !strstr( $new_email, '@' ) ) ) { Session::error( _t( 'Please supply a valid email address.' ), 'adduser' ); } if ( !isset( $new_username ) || empty( $new_username ) ) { Session::error( _t( 'Please supply a user name.' ), 'adduser' ); } // safety check to make sure no such username exists $user = User::get_by_name( $new_username ); if ( isset( $user->id ) ) { Session::error( _t( 'That username is already assigned.' ), 'adduser' ); } if ( !Session::has_errors( 'adduser' ) ) { $user = new User( array( 'username' => $new_username, 'email' => $new_email, 'password' => Utils::crypt( $new_pass1 ) ) ); if ( $user->insert() ) { Session::notice( sprintf( _t( "Added user '%s'" ), $new_username ) ); } else { $dberror = DB::get_last_error(); Session::error( $dberror[2], 'adduser' ); } } else { $settings = array(); if ( isset($username) ) { $settings['new_username'] = $new_username; } if ( isset( $new_email ) ) { $settings['new_email'] = $new_email; } $this->theme->assign( 'settings', $settings ); } } else if ( isset( $action ) && ( 'delete' == $action ) ) { $this->update_users($this->handler_vars); } $this->theme->display('users'); } /** * Handles plugin activation or deactivation. */ public function get_plugin_toggle() { $extract = $this->handler_vars->filter_keys('plugin_id', 'action'); foreach ( $extract as $key => $value ) { $$key = $value; } $plugins = Plugins::list_all(); foreach ( $plugins as $file ) { if ( Plugins::id_from_file($file) == $plugin_id ) { switch ( strtolower($action) ) { case 'activate': if ( Plugins::activate_plugin($file) ) { $plugins = Plugins::get_active(); Session::notice( _t( "Activated plugin '%s'", array($plugins[Plugins::id_from_file( $file )]->info->name) ), $plugins[Plugins::id_from_file($file)]->plugin_id ); } break; case 'deactivate': if ( Plugins::deactivate_plugin($file) ) { $plugins = Plugins::get_active(); Session::notice( _t( "Deactivated plugin '%s'", array($plugins[Plugins::id_from_file( $file )]->info->name) ), $plugins[Plugins::id_from_file($file)]->plugin_id ); } break; default: Plugins::act( 'adminhandler_get_plugin_toggle_action', $action, $file, $plugin_id, $plugins ); break; } } } Utils::redirect( URL::get( 'admin', 'page=plugins' ) ); } /** * A POST handler for the admin themes page that simply passes those options through. */ public function post_themes() { return $this->get_themes(); } /** * Handles GET requests for the theme listing */ public function get_themes() { $all_themes = Themes::get_all_data(); foreach ( $all_themes as $name => $theme ) { if ( isset($all_themes[$name]['info']->update) && $all_themes[$name]['info']->update != '' && isset($all_themes[$name]['info']->version) && $all_themes[$name]['info']->version != '' ) { Update::add($name, $all_themes[$name]['info']->update, $all_themes[$name]['info']->version); } } $updates = Update::check(); foreach ( $all_themes as $name => $theme ) { if ( isset($all_themes[$name]['info']->update) && isset($updates[$all_themes[$name]['info']->update]) ) { $all_themes[$name]['info']->update = $updates[$all_themes[$name]['info']->update]['latest_version']; } else { $all_themes[$name]['info']->update = ''; } } $this->theme->all_themes = $all_themes; $this->theme->active_theme = Themes::get_active_data(); $this->theme->active_theme_dir = $this->theme->active_theme['path']; // If the active theme is configurable, allow it to configure $this->theme->active_theme_name = $this->theme->active_theme['info']->name; $this->theme->configurable = Plugins::filter( 'theme_config', false, $this->active_theme); $this->theme->assign( 'configure', Controller::get_var('configure') ); $activedata = Themes::get_active_data(); $areas = array(); if ( isset($activedata['info']->areas->area) ) { foreach ( $activedata['info']->areas->area as $area ) { $areas[] = (string)$area; } } $this->theme->areas = $areas; $this->theme->blocks = Plugins::filter('block_list', array()); $this->theme->block_instances = DB::get_results('SELECT b.* FROM {blocks} b ORDER BY b.title ASC', array(), 'Block'); $blocks_areas_t = DB::get_results('SELECT b.*, ba.scope_id, ba.area FROM {blocks} b INNER JOIN {blocks_areas} ba ON ba.block_id = b.id ORDER BY ba.scope_id ASC, ba.area ASC, ba.display_order ASC', array(), 'Block'); $blocks_areas = array(); foreach ( $blocks_areas_t as $block ) { if ( !isset($blocks_areas[$block->scope_id]) ) { $blocks_areas[$block->scope_id] = array(); } $blocks_areas[$block->scope_id][$block->area][$block->display_order] = $block; } $this->theme->blocks_areas = $blocks_areas; $this->theme->scopes = DB::get_results('SELECT * FROM {scopes} ORDER BY id ASC;'); $this->theme->display( 'themes' ); } /** * Activates a theme. */ public function get_activate_theme() { $theme_name = $this->handler_vars['theme_name']; $theme_dir = $this->handler_vars['theme_dir']; if ( isset($theme_name) && isset($theme_dir) ) { Themes::activate_theme( $theme_name, $theme_dir ); } Session::notice( sprintf( _t( "Activated theme '%s'" ), $theme_name ) ); Utils::redirect( URL::get( 'admin', 'page=themes' ) ); } /** * Handles GET requests for the import page. */ public function get_import() { $importer = isset( $_POST['importer'] ) ? $_POST['importer'] : ''; $stage = isset( $_POST['stage'] ) ? $_POST['stage'] : ''; $this->theme->enctype = Plugins::filter( 'import_form_enctype', 'application/x-www-form-urlencoded', $importer, $stage ); $this->display( 'import' ); } /** * Handles the submission of the import form, importing data from a WordPress database. * This function should probably be broken into an importer class, since it is WordPress-specific. */ public function post_import() { if ( !isset( $_POST['importer'] ) ) { Utils::redirect( URL::get( 'admin', 'page=import' ) ); } $importer = isset( $_POST['importer'] ) ? $_POST['importer'] : ''; $stage = isset( $_POST['stage'] ) ? $_POST['stage'] : ''; $this->theme->enctype = Plugins::filter( 'import_form_enctype', 'application/x-www-form-urlencoded', $importer, $stage ); $this->display( 'import' ); } /** * Construct a form for a comment. * @return FormUI The comment's form. */ public function form_comment($comment, $actions) { $form = new FormUI( 'comment' ); $user = User::identify(); // Create the top description $top = $form->append('wrapper', 'buttons_1'); $top->class = 'container buttons comment overview'; $top->append('static', 'overview', $this->theme->fetch('comment.overview')); $buttons_1 = $top->append('wrapper', 'buttons_1'); $buttons_1->class = 'item buttons'; foreach ( $actions as $status => $action ) { $id = $action . '_1'; $buttons_1->append('submit', $id, _t(ucfirst($action))); $buttons_1->$id->class = 'button ' . $action; if ( Comment::status_name($comment->status) == $status ) { $buttons_1->$id->class = 'button active ' . $action; $buttons_1->$id->disabled = true; } else { $buttons_1->$id->disabled = false; } } // Content $form->append('wrapper', 'content_wrapper'); $content = $form->content_wrapper->append('textarea', 'content', 'null:null', _t('Comment'), 'admincontrol_textarea'); $content->class = 'resizable'; $content->value = $comment->content; // Create the splitter $comment_controls = $form->append('tabs', 'comment_controls'); // Create the author info $author = $comment_controls->append('fieldset', 'authorinfo', _t('Author')); $author->append('text', 'author_name', 'null:null', _t('Author Name'), 'tabcontrol_text'); $author->author_name->value = $comment->name; $author->append('text', 'author_email', 'null:null', _t('Author Email'), 'tabcontrol_text'); $author->author_email->value = $comment->email; $author->append('text', 'author_url', 'null:null', _t('Author URL'), 'tabcontrol_text'); $author->author_url->value = $comment->url; $author->append('text', 'author_ip', 'null:null', _t('IP Address:'), 'tabcontrol_text'); $author->author_ip->value = long2ip($comment->ip); // Create the advanced settings $settings = $comment_controls->append('fieldset', 'settings', _t('Settings')); $settings->append('text', 'comment_date', 'null:null', _t('Date:'), 'tabcontrol_text'); $settings->comment_date->value = $comment->date->get('Y-m-d H:i:s'); $settings->append('text', 'comment_post', 'null:null', _t('Post ID:'), 'tabcontrol_text'); $settings->comment_post->value = $comment->post->id; $statuses = Comment::list_comment_statuses( false ); $statuses = Plugins::filter( 'admin_publish_list_comment_statuses', $statuses ); $settings->append('select', 'comment_status', 'null:null', _t('Status'), $statuses, 'tabcontrol_select'); $settings->comment_status->value = $comment->status; // // Create the stats // $comment_controls->append('fieldset', 'stats_tab', _t('Stats')); // $stats = $form->stats_tab->append('wrapper', 'tags_buttons'); // $stats->class = 'container'; // // $stats->append('static', 'post_count', '

'._t('Comments on this post:').'

' . Comments::count_by_id($comment->post->id) . '


'); // $stats->append('static', 'ip_count', '

'._t('Comments from this IP:').'

' . Comments::count_by_ip($comment->ip) . '


'); // $stats->append('static', 'email_count', '

'._t('Comments by this author:').'

' . Comments::count_by_email($comment->email) . '


'); // $stats->append('static', 'url_count', '

'._t('Comments with this URL:').'

' . Comments::count_by_url($comment->url) . '


'); // Create the second set of action buttons $buttons_2 = $form->append('wrapper', 'buttons_2'); $buttons_2->class = 'container buttons comment'; foreach ( $actions as $status => $action ) { $id = $action . '_2'; $buttons_2->append('submit', $id, _t(ucfirst($action))); $buttons_2->$id->class = 'button ' . $action; if ( Comment::status_name($comment->status) == $status ) { $buttons_2->$id->class = 'button active ' . $action; $buttons_2->$id->disabled = true; } else { $buttons_2->$id->disabled = false; } } // Allow plugins to alter form Plugins::act('form_comment_edit', $form, $comment); return $form; } /** * Handles GET requests for an individual comment. */ public function get_comment($update = FALSE) { if ( isset( $this->handler_vars['id'] ) && $comment = Comment::get( $this->handler_vars['id'] ) ) { $this->theme->comment = $comment; // Convenience array to output actions twice $actions = array( 'deleted' => 'delete', 'spam' => 'spam', 'unapproved' => 'unapprove', 'approved' => 'approve', 'saved' => 'save' ); $form = $this->form_comment( $comment, $actions ); if ( $update ) { foreach ( $actions as $key => $action ) { $id_one = $action . '_1'; $id_two = $action . '_2'; if ( $form->$id_one->value != NULL || $form->$id_two->value != NULL ) { if ( $action == 'delete' ) { $comment->delete(); Utils::redirect(URL::get('admin', 'page=comments')); } if ( $action != 'save' ) { foreach ( Comment::list_comment_statuses() as $status ) { if ( $status == $key ) { $comment->status = Comment::status_name( $status ); $set_status = true; } } } } } $comment->content = $form->content; $comment->name = $form->author_name; $comment->url = $form->author_url; $comment->email = $form->author_email; $comment->ip = ip2long( $form->author_ip ); $comment->date = HabariDateTime::date_create( $form->comment_date ); $comment->post_id = $form->comment_post; if ( ! isset($set_status) ) { $comment->status = $form->comment_status->value; } $comment->update(); Plugins::act('comment_edit', $comment, $form); Utils::redirect(); } $comment->content = $form; $this->theme->form = $form; $this->display('comment'); } else { Utils::redirect(URL::get('admin', 'page=comments')); } } /** * Handles POST requests for an individual comment. */ public function post_comment() { $this->get_comment(true); } /** * Handles GET requests for the comments page. */ public function get_comments() { $this->post_comments(); } /** * Handles the submission of the comment moderation form. * @todo Separate delete from "delete until purge" */ public function post_comments() { // Get special search statuses $statuses = Comment::list_comment_statuses(); $statuses = array_combine( $statuses, array_map( create_function('$a', 'return "status:{$a}";'), $statuses ) ); // Get special search types $types = Comment::list_comment_types(); $types = array_combine( $types, array_map( create_function('$a', 'return "type:{$a}";'), $types ) ); $this->theme->special_searches = array_merge($statuses, $types); $this->fetch_comments(); $this->display( 'comments' ); } /** * 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' => '', 'PasswordDigest' => '', '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 == Comment::STATUS_SPAM ) { // Delete all comments that have the spam status. Comments::delete_by_status( Comment::STATUS_SPAM ); // let's optimize the table $result = DB::query('OPTIMIZE TABLE {comments}'); Session::notice( _t( 'Deleted all spam comments' ) ); Utils::redirect(); } elseif ( isset( $mass_delete ) && $status == Comment::STATUS_UNAPPROVED ) { // Delete all comments that are unapproved. Comments::delete_by_status( Comment::STATUS_UNAPPROVED ); Session::notice( _t( 'Deleted all unapproved comments' ) ); Utils::redirect(); } // if we're updating posts, let's do so: elseif ( ( $do_delete || $do_spam || $do_approve || $do_unapprove ) && isset( $comment_ids )) { $okay = true; if ( empty( $nonce ) || empty( $timestamp ) || empty( $PasswordDigest ) ) { $okay = false; } $wsse = Utils::WSSE( $nonce, $timestamp ); if ( $PasswordDigest != $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, Comment::STATUS_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, Comment::STATUS_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' )] . ' · ' : '') . '' . $comment->post->title . ' '; } 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, Comment::STATUS_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('admin', 'page=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 = array(); foreach ( $actions as $name => $action ) { if ( !isset( $action['access'] ) || ACL::access_check( $comment_access, $action['access'] ) ) { $menu[$name] = $action; } } // remove the current status from the dropmenu unset($menu[Comment::status_name($comment->status)]); $comment->menu = Plugins::filter('comment_actions', $menu, $comment); } } /** * A helper function for fetch_comments() * Filters a list of comments by ACL access * @param object $comments an array of Comment objects * @param string $access the access type to check for * @return a filtered array of Comment objects. */ public function comment_access_filter( $comments, $access ) { $result = array(); foreach ( $comments as $comment ) { if ( ACL::access_check( $comment->get_access(), $access ) ) { $result[] = $comment; } } return $result; } /** * A POST handler for the admin plugins page that simply passes those options through. */ public function post_plugins() { return $this->get_plugins(); } /** * Display the plugin administration page */ public function get_plugins() { $all_plugins = Plugins::list_all(); $active_plugins = Plugins::get_active(); $sort_active_plugins = array(); $sort_inactive_plugins = array(); foreach ( $all_plugins as $file ) { $plugin = array(); $plugin_id = Plugins::id_from_file( $file ); $plugin['plugin_id'] = $plugin_id; $plugin['file'] = $file; $error = ''; $providing = array(); if ( Utils::php_check_file_syntax( $file, $error ) ) { $plugin['debug'] = false; if ( array_key_exists( $plugin_id, $active_plugins ) ) { $plugin['verb'] = _t( 'Deactivate' ); $pluginobj = $active_plugins[$plugin_id]; $plugin['active'] = true; $plugin_actions = array(); $plugin_actions = Plugins::filter( 'plugin_config', $plugin_actions, $plugin_id ); $plugin['actions'] = array(); foreach ( $plugin_actions as $plugin_action => $plugin_action_caption ) { if ( is_numeric($plugin_action) ) { $plugin_action = $plugin_action_caption; } $action = array( 'caption' => $plugin_action_caption, 'action' => $plugin_action, ); $urlparams = array('page' => 'plugins', 'configure'=>$plugin_id); $action['url'] = URL::get( 'admin', $urlparams ); if ( $action['caption'] == '?' ) { if ( isset($_GET['configaction']) ) { $urlparams['configaction'] = $_GET['configaction']; } if ( $_GET['help'] != $plugin_action ) { $urlparams['help'] = $plugin_action; } $action['url'] = URL::get( 'admin', $urlparams ); $plugin['help'] = $action; } else { if ( isset($_GET['help']) ) { $urlparams['help'] = $_GET['help']; } $urlparams['configaction'] = $plugin_action; $action['url'] = URL::get( 'admin', $urlparams ); $plugin['actions'][$plugin_action] = $action; } } $plugin['actions']['deactivate'] = array( 'url' => URL::get( 'admin', 'page=plugin_toggle&plugin_id=' . $plugin['plugin_id'] . '&action=deactivate'), 'caption' => _t('Deactivate'), 'action' => 'Deactivate', ); if ( isset($plugin['info']->provides) ) { foreach ( $plugin['info']->provides->feature as $feature ) { $providing[(string) $feature] = $feature; } } } else { // instantiate this plugin // in order to get its info() $plugin['active'] = false; $plugin['verb'] = _t( 'Activate' ); $plugin['actions'] = array( 'activate' => array( 'url' => URL::get( 'admin', 'page=plugin_toggle&plugin_id=' . $plugin['plugin_id'] . '&action=activate'), 'caption' => _t('Activate'), 'action' => 'activate', ), ); } $plugin['info'] = Plugins::load_info( $file ); } else { $plugin['debug'] = true; $plugin['error'] = $error; $plugin['active'] = false; } if ( isset( $this->handler_vars['configure'] ) && ( $this->handler_vars['configure'] == $plugin['plugin_id'] ) ) { if ( i