/** * Handles AJAX from /admin/tags * Used to delete and rename tags */ public function ajax_tags($handler_vars) { Utils::check_request_method(array('POST')); $response = new AjaxResponse(); $wsse = Utils::WSSE($handler_vars['nonce'], $handler_vars['timestamp']); if ($handler_vars['digest'] != $wsse['digest']) { $response->message = _t('WSSE authentication failed.'); $response->out(); return; } $tag_names = array(); $this->create_theme(); $action = $this->handler_vars['action']; switch ($action) { case 'delete': foreach ($_POST as $id => $delete) { // skip POST elements which are not tag ids if (preg_match('/^tag_\\d+/', $id) && $delete) { $id = substr($id, 4); $tag = Tags::get_by_id($id); $tag_names[] = $tag->term_display; Tags::vocabulary()->delete_term($tag); } } $response->message = _n(_t('Tag %s has been deleted.', array(implode('', $tag_names))), _t('%d tags have been deleted.', array(count($tag_names))), count($tag_names)); break; case 'rename': if (!isset($this->handler_vars['master'])) { $response->message = _t('Error: New name not specified.'); $response->out(); return; } $master = $this->handler_vars['master']; $tag_names = array(); foreach ($_POST as $id => $rename) { // skip POST elements which are not tag ids if (preg_match('/^tag_\\d+/', $id) && $rename) { $id = substr($id, 4); $tag = Tags::get_by_id($id); $tag_names[] = $tag->term_display; } } Tags::vocabulary()->merge($master, $tag_names); $response->message = sprintf(_n('Tag %1$s has been renamed to %2$s.', 'Tags %1$s have been renamed to %2$s.', count($tag_names)), implode($tag_names, ', '), $master); break; } $this->theme->tags = Tags::vocabulary()->get_tree('term_display ASC'); $this->theme->max = Tags::vocabulary()->max_count(); $response->data = $this->theme->fetch('tag_collection'); $response->out(); }
public function theme_route_change_sudo() { $form = $this->get_form(); $user_id = $form->userlist->value; $user = User::get_by_id($user_id); if ($_SESSION['user_id'] == $user->id) { unset($_SESSION['sudo']); } else { $_SESSION['sudo'] = $user->id; } $ar = new AjaxResponse(200, 'Ok.'); $ar->html('#sudo_handle', $user->displayname); $ar->out(); }
/** * Verifies user credentials before creating the theme and displaying the request. */ public function __construct() { $user = User::identify(); if ( !$user->loggedin ) { Session::add_to_set( 'login', $_SERVER['REQUEST_URI'], 'original' ); if ( URL::get_matched_rule()->action == 'admin_ajax' && isset( $_SERVER['HTTP_REFERER'] ) ) { $ar = new AjaxResponse(408, _t('Your session has ended, please log in and try again.') ); $ar->out(); } 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( 'auth', 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(); // on every page load check the plugins currently loaded against the list we last checked for updates and trigger a cron if we need to Update::check_plugins(); }
/** * Handles AJAX requests from the dashboard */ public function ajax_dashboard($handler_vars) { Utils::check_request_method(array('POST')); $theme_dir = Plugins::filter('admin_theme_dir', Site::get_dir('admin_theme', true)); $this->theme = Themes::create('admin', 'RawPHPEngine', $theme_dir); switch ($handler_vars['action']) { case 'updateModules': $modules = array(); foreach ($_POST as $key => $module) { // skip POST elements which are not module names if (preg_match('/^module\\d+$/', $key)) { list($module_id, $module_name) = explode(':', $module, 2); // remove non-sortable modules from the list if ($module_id != 'nosort') { $modules[$module_id] = $module_name; } } } Modules::set_active($modules); $ar = new AjaxResponse(200, _t('Modules updated.')); break; case 'addModule': $id = Modules::add($handler_vars['module_name']); $this->fetch_dashboard_modules(); $ar = new AjaxResponse(200, _t('Added module %s.', array($handler_vars['module_name']))); $ar->html('modules', $this->theme->fetch('dashboard_modules')); break; case 'removeModule': Modules::remove($handler_vars['moduleid']); $this->fetch_dashboard_modules(); $ar = new AjaxResponse(200, _t('Removed module.')); $ar->html('modules', $this->theme->fetch('dashboard_modules')); break; } $ar->out(); }
/** * Called from the themes page to save the blocks instances into areas * * @param mixed $handler_vars * @return */ public function ajax_save_areas($handler_vars) { Utils::check_request_method(array('POST')); $scope = $_POST['scope']; $msg = ''; $response = new AjaxResponse(); if (isset($_POST['area_blocks'])) { $area_blocks = $_POST['area_blocks']; DB::query('DELETE FROM {blocks_areas} WHERE scope_id = :scope_id', array('scope_id' => $scope)); foreach ((array) $area_blocks as $area => $blocks) { $display_order = 0; // if there are no blocks for a given area, skip it if (empty($blocks)) { continue; } foreach ($blocks as $block) { $display_order++; DB::query('INSERT INTO {blocks_areas} (block_id, area, scope_id, display_order) VALUES (:block_id, :area, :scope_id, :display_order)', array('block_id' => $block, 'area' => $area, 'scope_id' => $scope, 'display_order' => $display_order)); } } // $msg = json_encode( _t( 'Saved block areas settings.' ) ); // $msg = '<script type="text/javascript"> // human_msg.display_msg(' . $msg . '); // spinner.stop(); // </script>'; $response->message = _t('Saved block areas settings.'); } $this->setup_admin_theme(''); $blocks_areas_t = DB::get_results('SELECT b.*, ba.scope_id, ba.area, ba.display_order 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()); $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->scopeid = $scope; $this->theme->areas = $this->get_areas($scope); $scopes = DB::get_results('SELECT * FROM {scopes} ORDER BY name ASC;'); $scopes = Plugins::filter('get_scopes', $scopes); $this->theme->scopes = $scopes; $this->theme->active_theme = Themes::get_active_data(true); $output = $this->theme->fetch('block_areas'); $response->html('block_areas', $output); $response->out(); }
/** * Handles AJAX requests from the manage comments page. */ public function ajax_comments() { Utils::check_request_method( array( 'GET', 'HEAD' ) ); $theme_dir = Plugins::filter( 'admin_theme_dir', Site::get_dir( 'admin_theme', true ) ); $this->theme = Themes::create( 'admin', 'RawPHPEngine', $theme_dir ); $this->theme->theme = $this->theme; $params = $_GET; $this->fetch_comments( $params ); $items = $this->theme->fetch( 'comments_items' ); $timeline = $this->theme->fetch( 'timeline_items' ); $item_ids = array(); foreach ( $this->theme->comments as $comment ) { $item_ids['p' . $comment->id] = 1; } $ar = new AjaxResponse(); $ar->data = array( 'items' => $items, 'item_ids' => $item_ids, 'timeline' => $timeline, ); $ar->out(); }
/** * Handles AJAX from /admin/tags * Used to search for, delete and rename tags */ public function ajax_tags() { Utils::check_request_method(array('POST', 'HEAD')); $this->create_theme(); $params = $_POST['query']; // Get a usable array with filter parameters from the odd syntax we received from the faceted search $fetch_params = array(); if (isset($params)) { foreach ($params as $param) { $key = key($param); // Revert translation if ($key != 'text') { $key = self::$facets[$key]; } $value = current($param); if (array_key_exists($key, $fetch_params)) { $fetch_params[$key] = Utils::single_array($fetch_params[$key]); $fetch_params[$key][] = $value; } else { $fetch_params[$key] = $value; } } } // Grab facets / params $search = array_key_exists('text', $fetch_params) ? $fetch_params['text'] : null; $min = array_key_exists('morethan', $fetch_params) ? $fetch_params['morethan'] + 1 : 0; $max = array_key_exists('lessthan', $fetch_params) ? $fetch_params['lessthan'] - 1 : null; $orderby_code = array_key_exists('orderby', $fetch_params) ? $fetch_params['orderby'] : null; $orderby = isset($orderby_code) ? explode('_', self::$facet_values['orderby'][$orderby_code]) : ['alphabetical', 'asc']; $this->theme->tags = Tags::get_by_frequency(null, null, $min, $max, $search, self::$orderby_translate[$orderby[0]], $orderby[1] == 'asc'); // Create FormUI elements (list items) from the filtered tag list $this->theme->max = Tags::vocabulary()->max_count(); $this->theme->min = Tags::vocabulary()->min_count(); $output = ''; if (count($this->theme->tags) > 0) { $listitems = $this->get_tag_listitems(); // Get HTML from FormUI foreach ($listitems as $listitem) { $output .= $listitem->get($this->theme); } } $ar = new AjaxResponse(); $ar->html('#tag_collection', $output); $ar->out(); }
/** * Handles AJAX requests from the logs page. */ public function ajax_logs() { Utils::check_request_method(array('GET', 'HEAD')); $this->create_theme(); $this->fetch_logs(); $items = $this->theme->fetch('logs_items'); $timeline = $this->theme->fetch('timeline_items'); $item_ids = array(); foreach ($this->theme->logs as $log) { $item_ids['p' . $log->id] = 1; } $ar = new AjaxResponse(); $ar->data = array('items' => $items, 'item_ids' => $item_ids, 'timeline' => $timeline); $ar->out(); }
/** * Register plugin hooks * @static */ public static function __static() { /* * These registration functions are here rather than the classes that directly provide * their data (like Tags for tag_list or Posts for post_list) because putting them in * their respective classes would require that they be autoloaded on every page load * so that these functions could register their ajax endpoints. */ // Registers an auth_ajax endpoint for tag autocompletion self::register_auth_ajax('tag_list', function () { $tags = Tags::search($_GET['q']); $results = array(); foreach ($tags as $tag) { $results[] = array('id' => $tag->term_display, 'text' => $tag->term_display); } $ar = new AjaxResponse(); $ar->data = array('results' => $results, 'more' => false, 'context' => array()); $ar->out(); }); // Registers an auth_ajax endpoint for post autocompletion self::register_auth_ajax('post_list', function () { $posts = Posts::get(array('title_search' => $_GET['q'])); $results = array(); foreach ($posts as $post) { $results[] = array('id' => $post->id, 'text' => $post->title); } $ar = new AjaxResponse(); $ar->data = array('results' => $results, 'more' => false, 'context' => array()); $ar->out(); }); }
/** * Handles AJAX requests from the dashboard */ public function ajax_dashboard($handler_vars) { Utils::check_request_method(array('POST')); $this->create_theme(); $this->get_additem_form(); $available_modules = Plugins::filter('dashboard_block_list', array()); $user_id = User::identify()->id; $dashboard_area = 'dashboard_' . $user_id; switch ($handler_vars['action']) { case 'updateModules': $modules = $_POST['moduleOrder']; $order = 0; foreach ($modules as $module) { $order++; DB::query('UPDATE {blocks_areas} SET display_order = :display_order WHERE block_id = :id AND area = :dashboardarea', array('display_order' => $order, 'id' => $module, 'dashboardarea' => $dashboard_area)); } $ar = new AjaxResponse(200, _t('Modules updated.')); break; case 'addModule': $type = $handler_vars['module_name']; $title = $available_modules[$type]; $block = new Block(array('title' => $title, 'type' => $type)); $block->insert(); $max_display_order = DB::get_value('SELECT max(display_order) FROM {blocks_areas} WHERE area = :dashboardarea and scope_id = 0;', array('dashboardarea' => $dashboard_area)); $max_display_order++; DB::query('INSERT INTO {blocks_areas} (block_id, area, scope_id, display_order) VALUES (:block_id, :dashboardarea, 0, :display_order)', array('block_id' => $block->id, 'display_order' => $max_display_order, 'dashboardarea' => $dashboard_area)); $ar = new AjaxResponse(200, _t('Added module %s.', array($title))); $ar->html('modules', $this->theme->fetch('dashboard_modules')); break; case 'removeModule': $block_id = $handler_vars['moduleid']; DB::delete('{blocks}', array('id' => $block_id)); DB::delete('{blocks_areas}', array('block_id' => $block_id)); $ar = new AjaxResponse(200, _t('Removed module.')); $ar->html('modules', $this->theme->fetch('dashboard_modules')); break; case 'configModule': $block_id = $handler_vars['moduleid']; $block = DB::get_row('SELECT * FROM {blocks} b WHERE b.id = :id', array('id' => $block_id), 'Block'); /** Block $block */ $form = $block->get_form(); $form->_ajax = true; $form->set_option('success_message', _t('Module Configuration Saved.') . '<script type="text/javascript">window.setTimeout(function(){$(".form_message").fadeOut();}, 2000);</script>'); $control_id = new FormControlHidden('moduleid', 'null:null'); $control_id->value = $block->id; $control_id->id = 'moduleid'; $form->append($control_id); $control_action = new FormControlHidden('action', 'null:null'); $control_action->value = 'configModule'; $control_action->id = 'action'; $form->append($control_action); $form->out(); $form_id = $form->name; exit; break; } $ar->out(); }
/** * Handles AJAX requests from the manage comments page. */ public function ajax_comments() { Utils::check_request_method(array('GET', 'HEAD')); $this->create_theme(); $this->theme->theme = $this->theme; $params = $_GET; $this->fetch_comments($params); $items = $this->theme->fetch('comments_items'); $timeline = $this->theme->fetch('timeline_items'); $item_ids = array(); foreach ($this->theme->comments as $comment) { $item_ids['p' . $comment->id] = 1; } $ar = new AjaxResponse(); $ar->data = array('items' => $items, 'item_ids' => $item_ids, 'timeline' => $timeline); $ar->out(); }
/** * Handles AJAX requests from the groups page. */ public function ajax_groups( $handler_vars ) { Utils::check_request_method( array( 'GET', 'HEAD' ) ); $theme_dir = Plugins::filter( 'admin_theme_dir', Site::get_dir( 'admin_theme', true ) ); $this->theme = Themes::create( 'admin', 'RawPHPEngine', $theme_dir ); $output = ''; foreach ( UserGroups::get_all() as $group ) { $this->theme->group = $group; $group = UserGroup::get_by_id( $group->id ); $users = array(); foreach ( $group->members as $id ) { $user = $id == 0 ? User::anonymous() : User::get_by_id( $id ); if ( $user->id == 0 ) { $users[] = '<strong>' . $user->displayname . '</strong>'; } else { $users[] = '<strong><a href="' . URL::get( 'admin', 'page=user&id=' . $user->id ) . '">' . $user->displayname . '</a></strong>'; } } $this->theme->users = $users; $output .= $this->theme->fetch( 'groups_item' ); } $ar = new AjaxResponse(); $ar->data = array( 'items' => $output ); $ar->out(); }
/** * Handles AJAX from /manage/posts. * Used to delete posts. */ public function ajax_update_posts($handler_vars) { Utils::check_request_method(array('POST')); $response = new AjaxResponse(); $wsse = Utils::WSSE($handler_vars['nonce'], $handler_vars['timestamp']); if ($handler_vars['digest'] != $wsse['digest']) { $response->message = _t('WSSE authentication failed.'); $response->out(); return; } $ids = array(); foreach ($_POST as $id => $delete) { // skip POST elements which are not post ids if (preg_match('/^p\\d+$/', $id) && $delete) { $ids[] = (int) substr($id, 1); } } if (count($ids) == 0) { $posts = new Posts(); } else { $posts = Posts::get(array('id' => $ids, 'nolimit' => true)); } Plugins::act('admin_update_posts', $handler_vars['action'], $posts, $this); $status_msg = _t('Unknown action "%s"', array($handler_vars['action'])); switch ($handler_vars['action']) { case 'delete': $deleted = 0; foreach ($posts as $post) { if (ACL::access_check($post->get_access(), 'delete')) { $post->delete(); $deleted++; } } if ($deleted != count($posts)) { $response->message = _t('You did not have permission to delete some posts.'); } else { $response->message = sprintf(_n('Deleted %d post', 'Deleted %d posts', count($ids)), count($ids)); } break; default: // Specific plugin-supplied action Plugins::act('admin_posts_action', $response, $handler_vars['action'], $posts); break; } $response->out(); exit; }
/** * Handle ajax requests for facets on admin pages * @param $handler_vars */ public function ajax_facets($handler_vars) { // As we grabbed the facet request in the global AdminHandler, determine which Handler should actually be used for that page // The handlers need to be instantiated so their methods can be used as hooks and this was the only way that worked switch ($handler_vars['page']) { case 'manage': $handler = new AdminPostsHandler(); break; case 'tags': $handler = new AdminTagsHandler(); break; } switch ($handler_vars['component']) { case 'facets': $result = Plugins::filter('facets', array(), $handler_vars['page']); break; case 'values': $result = Plugins::filter('facetvalues', array(), $_POST['facet'], $_POST['q'], $handler_vars['page']); break; } $ar = new AjaxResponse(); $ar->data = $result; $ar->out(); }
/** * Handles AJAX requests from the groups page. */ public function ajax_groups($handler_vars) { Utils::check_request_method(array('GET', 'HEAD')); $this->create_theme(); $output = ''; foreach (UserGroups::get_all() as $group) { $this->theme->group = $group; $group = UserGroup::get_by_id($group->id); $users = array(); foreach ($group->members as $id) { $user = $id == 0 ? User::anonymous() : User::get_by_id($id); if ($user->id == 0) { $users[] = '<strong>' . $user->displayname . '</strong>'; } else { $users[] = '<strong><a href="' . URL::get('user_profile', $user, false) . '">' . $user->displayname . '</a></strong>'; } } $this->theme->users = $users; $output .= $this->theme->fetch('groups_item'); } $ar = new AjaxResponse(); $ar->data = array('items' => $output); $ar->out(); }
/** * Handles AJAX requests to update comments, comment moderation */ public function ajax_update_comment($handler_vars) { Utils::check_request_method(array('POST')); $ar = new AjaxResponse(); // check WSSE authentication $wsse = Utils::WSSE($_POST['nonce'], $_POST['timestamp']); if ($_POST['digest'] != $wsse['digest']) { $ar->message = _t('WSSE authentication failed.'); $ar->out(); return; } $ids = $_POST['selected']; if ((!isset($ids) || empty($ids)) && $_POST['action'] == 'delete') { $ar->message = _t('No comments selected.'); $ar->out(); return; } $comments = Comments::get(array('id' => $ids, 'nolimit' => true)); Plugins::act('admin_moderate_comments', $_POST['action'], $comments, $this); $status_msg = _t('Unknown action "%s"', array($handler_vars['action'])); switch ($_POST['action']) { case 'delete_spam': Comments::delete_by_status('spam'); $status_msg = _t('Deleted all spam comments'); break; case 'delete_unapproved': Comments::delete_by_status('unapproved'); $status_msg = _t('Deleted all unapproved comments'); break; case 'delete': // Comments marked for deletion Comments::delete_these($comments); $status_msg = sprintf(_n('Deleted %d comment', 'Deleted %d comments', count($ids)), count($ids)); break; case 'spam': // Comments marked as spam Comments::moderate_these($comments, 'spam'); $status_msg = sprintf(_n('Marked %d comment as spam', 'Marked %d comments as spam', count($ids)), count($ids)); break; case 'approve': case 'approved': // Comments marked for approval Comments::moderate_these($comments, 'approved'); $status_msg = sprintf(_n('Approved %d comment', 'Approved %d comments', count($ids)), count($ids)); break; case 'unapprove': case 'unapproved': // Comments marked for unapproval Comments::moderate_these($comments, 'unapproved'); $status_msg = sprintf(_n('Unapproved %d comment', 'Unapproved %d comments', count($ids)), count($ids)); break; default: // Specific plugin-supplied action $status_msg = Plugins::filter('admin_comments_action', $status_msg, $_POST['action'], $comments); break; } $ar->message = $status_msg; $ar->out(); }