Commit c438fbf9 by Scott

New Router system and controllers for user pages

parent 4f7605ce
...@@ -178,16 +178,18 @@ function qa_get_request_content() ...@@ -178,16 +178,18 @@ function qa_get_request_content()
$firstlower = strtolower($requestparts[0]); $firstlower = strtolower($requestparts[0]);
$routing = qa_page_routing(); $routing = qa_page_routing();
if (isset($routing[$requestlower])) { $router = new \Q2A\Http\Router(qa_routing_config());
$routeInfo = $router->match($requestlower);
if ($routeInfo !== false) {
// use new Controller system
qa_set_template($routeInfo['id']);
$ctrl = new $routeInfo['controller']();
$qa_content = call_user_func_array(array($ctrl, $routeInfo['function']), $routeInfo['params']);
} elseif (isset($routing[$requestlower])) {
qa_set_template($firstlower); qa_set_template($firstlower);
$route = $routing[$requestlower]; $qa_content = require QA_INCLUDE_DIR . $routing[$requestlower];
if (is_array($route)) {
$ctrl = new $route[0];
$qa_content = $ctrl->{$route[1]}();
}
else {
$qa_content = require QA_INCLUDE_DIR . $route;
}
} elseif (isset($routing[$firstlower . '/'])) { } elseif (isset($routing[$firstlower . '/'])) {
qa_set_template($firstlower); qa_set_template($firstlower);
...@@ -444,11 +446,27 @@ function qa_page_routing() ...@@ -444,11 +446,27 @@ function qa_page_routing()
'unanswered/' => 'pages/unanswered.php', 'unanswered/' => 'pages/unanswered.php',
'unsubscribe' => 'pages/unsubscribe.php', 'unsubscribe' => 'pages/unsubscribe.php',
'updates' => 'pages/updates.php', 'updates' => 'pages/updates.php',
'user/' => 'pages/user.php', );
'users' => ['\Q2A\Controllers\UsersController', 'top'], }
'users/blocked' => ['\Q2A\Controllers\UsersController', 'blocked'],
'users/new' => ['\Q2A\Controllers\UsersController', 'newest'], /**
'users/special' => ['\Q2A\Controllers\UsersController', 'special'], * [qa_routing_config description]
* @return [type] [description]
*/
function qa_routing_config()
{
return array(
'user' => array('get', 'user/{str}', '\Q2A\Controllers\User\UserProfile', 'profile'),
'user-self' => array('get', 'user', '\Q2A\Controllers\User\UserProfile', 'index'),
'user-wall' => array('get', 'user/{str}/wall', '\Q2A\Controllers\User\UserMessages', 'wall'),
'user-activity' => array('get', 'user/{str}/activity', '\Q2A\Controllers\User\UserPosts', 'activity'),
'user-questions' => array('get', 'user/{str}/questions', '\Q2A\Controllers\User\UserPosts', 'questions'),
'user-answers' => array('get', 'user/{str}/answers', '\Q2A\Controllers\User\UserPosts', 'answers'),
'users-top' => array('get', 'users', '\Q2A\Controllers\User\UsersList', 'top'),
'users-blocked' => array('get', 'users/blocked', '\Q2A\Controllers\User\UsersList', 'blocked'),
'users-new' => array('get', 'users/new', '\Q2A\Controllers\User\UsersList', 'newest'),
'users-special' => array('get', 'users/special', '\Q2A\Controllers\User\UsersList', 'special'),
); );
} }
......
<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
namespace Q2A\Controllers\User;
require_once QA_INCLUDE_DIR . 'db/selects.php';
require_once QA_INCLUDE_DIR . 'app/messages.php';
class UserMessages extends \Q2A\Controllers\BaseController
{
public function wall($handle)
{
if (QA_FINAL_EXTERNAL_USERS) {
// Check we're not using single-sign on integration, which doesn't allow walls
qa_fatal_error('User accounts are handled by external code');
return;
}
$userhtml = qa_html($handle);
$start = qa_get_start();
// Find the questions for this user
list($useraccount, $usermessages) = qa_db_select_with_pending(
qa_db_user_account_selectspec($handle, false),
qa_db_recent_messages_selectspec(null, null, $handle, false, qa_opt_if_loaded('page_size_wall'), $start)
);
if (!is_array($useraccount)) // check the user exists
return include QA_INCLUDE_DIR . 'qa-page-not-found.php';
// Perform pagination
$pagesize = qa_opt('page_size_wall');
$count = $useraccount['wallposts'];
$loginuserid = qa_get_logged_in_userid();
$usermessages = array_slice($usermessages, 0, $pagesize);
$usermessages = qa_wall_posts_add_rules($usermessages, $start);
// Process deleting or adding a wall post (similar but not identical code to qq-page-user-profile.php)
$errors = array();
$wallposterrorhtml = qa_wall_error_html($loginuserid, $useraccount['userid'], $useraccount['flags']);
foreach ($usermessages as $message) {
if ($message['deleteable'] && qa_clicked('m' . $message['messageid'] . '_dodelete')) {
if (!qa_check_form_security_code('wall-' . $useraccount['handle'], qa_post_text('code'))) {
$errors['page'] = qa_lang_html('misc/form_security_again');
} else {
qa_wall_delete_post($loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), $message);
qa_redirect(qa_request(), $_GET);
}
}
}
if (qa_clicked('dowallpost')) {
$inmessage = qa_post_text('message');
if (!strlen($inmessage)) {
$errors['message'] = qa_lang('profile/post_wall_empty');
} elseif (!qa_check_form_security_code('wall-' . $useraccount['handle'], qa_post_text('code'))) {
$errors['message'] = qa_lang_html('misc/form_security_again');
} elseif (!$wallposterrorhtml) {
qa_wall_add_post($loginuserid, qa_get_logged_in_handle(), qa_cookie_get(), $useraccount['userid'], $useraccount['handle'], $inmessage, '');
qa_redirect(qa_request());
}
}
// Prepare content for theme
$qa_content = qa_content_prepare();
$qa_content['title'] = qa_lang_html_sub('profile/wall_for_x', $userhtml);
$qa_content['error'] = @$errors['page'];
$qa_content['message_list'] = array(
'tags' => 'id="wallmessages"',
'form' => array(
'tags' => 'name="wallpost" method="post" action="' . qa_self_html() . '"',
'style' => 'tall',
'hidden' => array(
'qa_click' => '', // for simulating clicks in Javascript
'handle' => qa_html($useraccount['handle']),
'start' => qa_html($start),
'code' => qa_get_form_security_code('wall-' . $useraccount['handle']),
),
),
'messages' => array(),
);
if ($start == 0) { // only allow posting on first page
if ($wallposterrorhtml) {
$qa_content['message_list']['error'] = $wallposterrorhtml; // an error that means we are not allowed to post
} else {
$qa_content['message_list']['form']['fields'] = array(
'message' => array(
'tags' => 'name="message" id="message"',
'value' => qa_html(@$inmessage, false),
'rows' => 2,
'error' => qa_html(@$errors['message']),
),
);
$qa_content['message_list']['form']['buttons'] = array(
'post' => array(
'tags' => 'name="dowallpost" onclick="return qa_submit_wall_post(this, false);"',
'label' => qa_lang_html('profile/post_wall_button'),
),
);
}
}
foreach ($usermessages as $message) {
$qa_content['message_list']['messages'][] = qa_wall_post_view($message);
}
$qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next'));
// Sub menu for navigation in user pages
$ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $userid : $useraccount['userid']);
$qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'wall', $ismyuser);
return $qa_content;
}
}
<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
namespace Q2A\Controllers\User;
require_once QA_INCLUDE_DIR . 'db/users.php';
require_once QA_INCLUDE_DIR . 'db/selects.php';
require_once QA_INCLUDE_DIR . 'app/users.php';
require_once QA_INCLUDE_DIR . 'app/format.php';
class UserPosts extends \Q2A\Controllers\BaseController
{
protected $userid;
protected $userhtml;
public function activity($handle)
{
$this->userHtml($handle);
// Find the recent activity for this user
$loginuserid = qa_get_logged_in_userid();
$identifier = QA_FINAL_EXTERNAL_USERS ? $this->userid : $handle;
list($useraccount, $questions, $answerqs, $commentqs, $editqs) = qa_db_select_with_pending(
QA_FINAL_EXTERNAL_USERS ? null : qa_db_user_account_selectspec($handle, false),
qa_db_user_recent_qs_selectspec($loginuserid, $identifier, qa_opt_if_loaded('page_size_activity')),
qa_db_user_recent_a_qs_selectspec($loginuserid, $identifier),
qa_db_user_recent_c_qs_selectspec($loginuserid, $identifier),
qa_db_user_recent_edit_qs_selectspec($loginuserid, $identifier)
);
if (!QA_FINAL_EXTERNAL_USERS && !is_array($useraccount)) // check the user exists
return include QA_INCLUDE_DIR . 'qa-page-not-found.php';
// Get information on user references
$questions = qa_any_sort_and_dedupe(array_merge($questions, $answerqs, $commentqs, $editqs));
$questions = array_slice($questions, 0, qa_opt('page_size_activity'));
$usershtml = qa_userids_handles_html(qa_any_get_userids_handles($questions), false);
// Prepare content for theme
$qa_content = qa_content_prepare(true);
if (count($questions))
$qa_content['title'] = qa_lang_html_sub('profile/recent_activity_by_x', $this->userhtml);
else
$qa_content['title'] = qa_lang_html_sub('profile/no_posts_by_x', $this->userhtml);
// Recent activity by this user
$qa_content['q_list']['form'] = array(
'tags' => 'method="post" action="' . qa_self_html() . '"',
'hidden' => array(
'code' => qa_get_form_security_code('vote'),
),
);
$qa_content['q_list']['qs'] = array();
$htmldefaults = qa_post_html_defaults('Q');
$htmldefaults['whoview'] = false;
$htmldefaults['voteview'] = false;
$htmldefaults['avatarsize'] = 0;
foreach ($questions as $question) {
$qa_content['q_list']['qs'][] = qa_any_to_q_html_fields($question, $loginuserid, qa_cookie_get(),
$usershtml, null, array('voteview' => false) + qa_post_html_options($question, $htmldefaults));
}
// Sub menu for navigation in user pages
$ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $this->userid : $useraccount['userid']);
$qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'activity', $ismyuser);
return $qa_content;
}
public function questions($handle)
{
$this->userHtml($handle);
$start = qa_get_start();
// Find the questions for this user
$loginuserid = qa_get_logged_in_userid();
$identifier = QA_FINAL_EXTERNAL_USERS ? $this->userid : $handle;
list($useraccount, $userpoints, $questions) = qa_db_select_with_pending(
QA_FINAL_EXTERNAL_USERS ? null : qa_db_user_account_selectspec($handle, false),
qa_db_user_points_selectspec($identifier),
qa_db_user_recent_qs_selectspec($loginuserid, $identifier, qa_opt_if_loaded('page_size_qs'), $start)
);
if (!QA_FINAL_EXTERNAL_USERS && !is_array($useraccount)) // check the user exists
return include QA_INCLUDE_DIR . 'qa-page-not-found.php';
// Get information on user questions
$pagesize = qa_opt('page_size_qs');
$count = (int)@$userpoints['qposts'];
$questions = array_slice($questions, 0, $pagesize);
$usershtml = qa_userids_handles_html($questions, false);
// Prepare content for theme
$qa_content = qa_content_prepare(true);
if (count($questions))
$qa_content['title'] = qa_lang_html_sub('profile/questions_by_x', $this->userhtml);
else
$qa_content['title'] = qa_lang_html_sub('profile/no_questions_by_x', $this->userhtml);
// Recent questions by this user
$qa_content['q_list']['form'] = array(
'tags' => 'method="post" action="' . qa_self_html() . '"',
'hidden' => array(
'code' => qa_get_form_security_code('vote'),
),
);
$qa_content['q_list']['qs'] = array();
$htmldefaults = qa_post_html_defaults('Q');
$htmldefaults['whoview'] = false;
$htmldefaults['avatarsize'] = 0;
foreach ($questions as $question) {
$qa_content['q_list']['qs'][] = qa_post_html_fields($question, $loginuserid, qa_cookie_get(),
$usershtml, null, qa_post_html_options($question, $htmldefaults));
}
$qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next'));
// Sub menu for navigation in user pages
$ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $this->userid : $useraccount['userid']);
$qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'questions', $ismyuser);
return $qa_content;
}
public function answers($handle)
{
$this->userHtml($handle);
$start = qa_get_start();
// Find the questions for this user
$loginuserid = qa_get_logged_in_userid();
$identifier = QA_FINAL_EXTERNAL_USERS ? $this->userid : $handle;
list($useraccount, $userpoints, $questions) = qa_db_select_with_pending(
QA_FINAL_EXTERNAL_USERS ? null : qa_db_user_account_selectspec($handle, false),
qa_db_user_points_selectspec($identifier),
qa_db_user_recent_a_qs_selectspec($loginuserid, $identifier, qa_opt_if_loaded('page_size_activity'), $start)
);
if (!QA_FINAL_EXTERNAL_USERS && !is_array($useraccount)) // check the user exists
return include QA_INCLUDE_DIR . 'qa-page-not-found.php';
// Get information on user questions
$pagesize = qa_opt('page_size_activity');
$count = (int)@$userpoints['aposts'];
$questions = array_slice($questions, 0, $pagesize);
$usershtml = qa_userids_handles_html($questions, false);
// Prepare content for theme
$qa_content = qa_content_prepare(true);
if (count($questions))
$qa_content['title'] = qa_lang_html_sub('profile/answers_by_x', $this->userhtml);
else
$qa_content['title'] = qa_lang_html_sub('profile/no_answers_by_x', $this->userhtml);
// Recent questions by this user
$qa_content['q_list']['form'] = array(
'tags' => 'method="post" action="' . qa_self_html() . '"',
'hidden' => array(
'code' => qa_get_form_security_code('vote'),
),
);
$qa_content['q_list']['qs'] = array();
$htmldefaults = qa_post_html_defaults('Q');
$htmldefaults['whoview'] = false;
$htmldefaults['avatarsize'] = 0;
$htmldefaults['ovoteview'] = true;
$htmldefaults['answersview'] = false;
foreach ($questions as $question) {
$options = qa_post_html_options($question, $htmldefaults);
$options['voteview'] = qa_get_vote_view('A', false, false);
$qa_content['q_list']['qs'][] = qa_other_to_q_html_fields($question, $loginuserid, qa_cookie_get(),
$usershtml, null, $options);
}
$qa_content['page_links'] = qa_html_page_links(qa_request(), $start, $pagesize, $count, qa_opt('pages_prev_next'));
// Sub menu for navigation in user pages
$ismyuser = isset($loginuserid) && $loginuserid == (QA_FINAL_EXTERNAL_USERS ? $this->userid : $useraccount['userid']);
$qa_content['navigation']['sub'] = qa_user_sub_navigation($handle, 'answers', $ismyuser);
return $qa_content;
}
private function userHtml($handle)
{
// Get the HTML to display for the handle, and if we're using external users, determine the userid
if (QA_FINAL_EXTERNAL_USERS) {
$this->userid = qa_handle_to_userid($handle);
if (!isset($this->userid))
return include QA_INCLUDE_DIR . 'qa-page-not-found.php';
$usershtml = qa_get_users_html(array($this->userid), false, qa_path_to_root(), true);
$this->userhtml = @$usershtml[$this->userid];
} else
$this->userhtml = qa_html($handle);
}
}
...@@ -16,14 +16,14 @@ ...@@ -16,14 +16,14 @@
More about this license: http://www.question2answer.org/license.php More about this license: http://www.question2answer.org/license.php
*/ */
namespace Q2A\Controllers; namespace Q2A\Controllers\User;
require_once QA_INCLUDE_DIR . 'db/users.php'; require_once QA_INCLUDE_DIR . 'db/users.php';
require_once QA_INCLUDE_DIR . 'db/selects.php'; require_once QA_INCLUDE_DIR . 'db/selects.php';
require_once QA_INCLUDE_DIR . 'app/users.php'; require_once QA_INCLUDE_DIR . 'app/users.php';
require_once QA_INCLUDE_DIR . 'app/format.php'; require_once QA_INCLUDE_DIR . 'app/format.php';
class UsersController extends BaseController class UsersList extends \Q2A\Controllers\BaseController
{ {
/** /**
* Display top users page (ordered by points) * Display top users page (ordered by points)
......
<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
namespace Q2A\Http;
class Router
{
protected $routes;
public function __construct($routeData = array())
{
$this->routes = $routeData;
}
public function addRoute($id, $httpMethod, $routePath, $class, $func)
{
$this->routes[$id] = array($httpMethod, $routePath, $class, $func);
}
public function match($request)
{
foreach ($this->routes as $id=>$route) {
if (count($route) !== 4) {
continue;
}
list($httpMethod, $routePath, $callClass, $callFunc) = $route;
if (strtoupper($httpMethod) !== strtoupper($_SERVER['REQUEST_METHOD'])) {
continue;
}
$pathRegex = '#^' . str_replace(array('{str}', '{int}'), array('([^/]+)', '([0-9]+)'), $routePath) . '$#';
if (preg_match($pathRegex, $request, $matches)) {
return array(
'id' => $id,
'controller' => $callClass,
'function' => $callFunc,
'params' => array_slice($matches, 1)
);
}
}
return false;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment