Files
godot-question2answer/qa-external-example/qa-external-users.php
Emi 07ec659385 Importing project into Git
This project lived only on the server without version control. This is now the starting point for the repository.
2023-05-23 20:03:24 +02:00

637 lines
24 KiB
PHP

<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/
File: qa-external-example/qa-external-users.php
Description: Example of how to integrate with your own user database
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
*/
/*
=========================================================================
THIS FILE ALLOWS YOU TO INTEGRATE WITH AN EXISTING USER MANAGEMENT SYSTEM
=========================================================================
It is used if QA_EXTERNAL_USERS is set to true in qa-config.php.
*/
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
/**
* ==========================================================================
* YOU MUST MODIFY THIS FUNCTION *BEFORE* Q2A CREATES ITS DATABASE
* ==========================================================================
*
* You should return the appropriate MySQL column type to use for the userid,
* for smooth integration with your existing users. Allowed options are:
*
* SMALLINT, SMALLINT UNSIGNED, MEDIUMINT, MEDIUMINT UNSIGNED, INT, INT UNSIGNED,
* BIGINT, BIGINT UNSIGNED or VARCHAR(x) where x is the maximum length.
*/
function qa_get_mysql_user_column_type()
{
// Set this before anything else
return null;
/*
Example 1 - suitable if:
* You use textual user identifiers with a maximum length of 32
return 'VARCHAR(32)';
*/
/*
Example 2 - suitable if:
* You use unsigned numerical user identifiers in an INT UNSIGNED column
return 'INT UNSIGNED';
*/
}
/**
* ===========================================================================
* YOU MUST MODIFY THIS FUNCTION, BUT CAN DO SO AFTER Q2A CREATES ITS DATABASE
* ===========================================================================
*
* You should return an array containing URLs for the login, register and logout pages on
* your site. These URLs will be used as appropriate within the Q2A site.
*
* You may return absolute or relative URLs for each page. If you do not want one of the links
* to show, omit it from the array, or use null or an empty string.
*
* If you use absolute URLs, then return an array with the URLs in full (see example 1 below).
*
* If you use relative URLs, the URLs should start with $relative_url_prefix, followed by the
* relative path from the root of the Q2A site to your login page. Like in example 2 below, if
* the Q2A site is in a subdirectory, $relative_url_prefix.'../' refers to your site root.
*
* Now, about $redirect_back_to_url. Let's say a user is viewing a page on the Q2A site, and
* clicks a link to the login URL that you returned from this function. After they log in using
* the form on your main site, they want to automatically go back to the page on the Q2A site
* where they came from. This can be done with an HTTP redirect, but how does your login page
* know where to redirect the user to? The solution is $redirect_back_to_url, which is the URL
* of the page on the Q2A site where you should send the user once they've successfully logged
* in. To implement this, you can add $redirect_back_to_url as a parameter to the login URL
* that you return from this function. Your login page can then read it in from this parameter,
* and redirect the user back to the page after they've logged in. The same applies for your
* register and logout pages. Note that the URL you are given in $redirect_back_to_url is
* relative to the root of the Q2A site, so you may need to add something.
*/
function qa_get_login_links($relative_url_prefix, $redirect_back_to_url)
{
// Until you edit this function, don't show login, register or logout links
return array(
'login' => null,
'register' => null,
'logout' => null
);
/*
Example 1 - using absolute URLs, suitable if:
* Your Q2A site: http://qa.mysite.com/
* Your login page: http://www.mysite.com/login
* Your register page: http://www.mysite.com/register
* Your logout page: http://www.mysite.com/logout
return array(
'login' => 'http://www.mysite.com/login',
'register' => 'http://www.mysite.com/register',
'logout' => 'http://www.mysite.com/logout',
);
*/
/*
Example 2 - using relative URLs, suitable if:
* Your Q2A site: http://www.mysite.com/qa/
* Your login page: http://www.mysite.com/login.php
* Your register page: http://www.mysite.com/register.php
* Your logout page: http://www.mysite.com/logout.php
return array(
'login' => $relative_url_prefix.'../login.php',
'register' => $relative_url_prefix.'../register.php',
'logout' => $relative_url_prefix.'../logout.php',
);
*/
/*
Example 3 - using relative URLs, and implementing $redirect_back_to_url
In this example, your pages login.php, register.php and logout.php should read in the
parameter $_GET['redirect'], and redirect the user to the page specified by that
parameter once they have successfully logged in, registered or logged out.
return array(
'login' => $relative_url_prefix.'../login.php?redirect='.urlencode('qa/'.$redirect_back_to_url),
'register' => $relative_url_prefix.'../register.php?redirect='.urlencode('qa/'.$redirect_back_to_url),
'logout' => $relative_url_prefix.'../logout.php?redirect='.urlencode('qa/'.$redirect_back_to_url),
);
*/
}
/**
* ===========================================================================
* YOU MUST MODIFY THIS FUNCTION, BUT CAN DO SO AFTER Q2A CREATES ITS DATABASE
* ===========================================================================
*
* qa_get_logged_in_user()
*
* You should check (using $_COOKIE, $_SESSION or whatever is appropriate) whether a user is
* currently logged in. If not, return null. If so, return an array with the following elements:
*
* - userid: a user id appropriate for your response to qa_get_mysql_user_column_type()
* - publicusername: a user description you are willing to show publicly, e.g. the username
* - email: the logged in user's email address
* - passsalt: (optional) password salt specific to this user, used for form security codes
* - level: one of the QA_USER_LEVEL_* values below to denote the user's privileges:
*
* QA_USER_LEVEL_BASIC, QA_USER_LEVEL_EDITOR, QA_USER_LEVEL_ADMIN, QA_USER_LEVEL_SUPER
*
* To indicate that the user is blocked you can also add an element 'blocked' with the value true.
* Blocked users are not allowed to perform any write actions such as voting or posting.
*
* The result of this function will be passed to your other function qa_get_logged_in_user_html()
* so you may add any other elements to the returned array if they will be useful to you.
*
* Call qa_db_connection() to get the connection to the Q2A database. If your database is shared with
* Q2A, you can also use the various qa_db_* functions to run queries.
*
* In order to access the admin interface of your Q2A site, ensure that the array element 'level'
* contains QA_USER_LEVEL_ADMIN or QA_USER_LEVEL_SUPER when you are logged in.
*/
function qa_get_logged_in_user()
{
// Until you edit this function, nobody is ever logged in
return null;
/*
Example 1 - suitable if:
* You store the login state and user in a PHP session
* You use textual user identifiers that also serve as public usernames
* Your database is shared with the Q2A site
* Your database has a users table that contains emails
* The administrator has the user identifier 'admin'
session_start();
if (isset($_SESSION['is_logged_in'])) {
$userid = $_SESSION['logged_in_userid'];
$result = qa_db_read_one_assoc(qa_db_query_sub(
'SELECT email FROM users WHERE id=$',
$userid
));
if (is_array($result)) {
return array(
'userid' => $userid,
'publicusername' => $userid,
'email' => $result['email'],
'level' => ($userid == 'admin') ? QA_USER_LEVEL_ADMIN : QA_USER_LEVEL_BASIC
);
}
}
return null;
*/
/*
Example 2 - suitable if:
* You store a session ID inside a cookie
* You use numerical user identifiers
* Your database is shared with the Q2A site
* Your database has a sessions table that maps session IDs to users
* Your database has a users table that contains usernames, emails and a flag for admin privileges
if (isset($_COOKIE['sessionid'])) {
$result = qa_db_read_one_assoc(qa_db_query_sub(
'SELECT userid, username, email, admin_flag FROM users WHERE userid=(SELECT userid FROM sessions WHERE sessionid=#)',
$_COOKIE['sessionid']
));
if (is_array($result)) {
return array(
'userid' => $result['userid'],
'publicusername' => $result['username'],
'email' => $result['email'],
'level' => $result['admin_flag'] ? QA_USER_LEVEL_ADMIN : QA_USER_LEVEL_BASIC
);
}
}
return null;
*/
}
/**
* ===========================================================================
* YOU MUST MODIFY THIS FUNCTION, BUT CAN DO SO AFTER Q2A CREATES ITS DATABASE
* ===========================================================================
*
* qa_get_user_email($userid)
*
* Return the email address for user $userid, or null if you don't know it.
*
* Call qa_db_connection() to get the connection to the Q2A database. If your database is shared with
* Q2A, you can also use the various qa_db_* functions to run queries.
*/
function qa_get_user_email($userid)
{
// Until you edit this function, always return null
return null;
/*
Example 1 - suitable if:
* Your database is shared with the Q2A site
* Your database has a users table that contains emails
$result = qa_db_read_one_assoc(qa_db_query_sub(
'SELECT email FROM users WHERE userid=#',
$userid
));
if (is_array($result))
return $result['email'];
return null;
*/
}
/**
* ===========================================================================
* YOU MUST MODIFY THIS FUNCTION, BUT CAN DO SO AFTER Q2A CREATES ITS DATABASE
* ===========================================================================
*
* qa_get_userids_from_public($publicusernames)
*
* You should take the array of public usernames in $publicusernames, and return an array which
* maps valid usernames to internal user ids. For each element of this array, the username should be
* in the key, with the corresponding user id in the value. If your usernames are case- or accent-
* insensitive, keys should contain the usernames as stored, not necessarily as in $publicusernames.
*
* Call qa_db_connection() to get the connection to the Q2A database. If your database is shared with
* Q2A, you can also use the various qa_db_* functions to run queries. If you access this database or
* any other, try to use a single query instead of one per user.
*/
function qa_get_userids_from_public($publicusernames)
{
// Until you edit this function, always return null
return null;
/*
Example 1 - suitable if:
* You use textual user identifiers that are also shown publicly
$publictouserid = array();
foreach ($publicusernames as $publicusername)
$publictouserid[$publicusername] = $publicusername;
return $publictouserid;
*/
/*
Example 2 - suitable if:
* You use numerical user identifiers
* Your database is shared with the Q2A site
* Your database has a users table that contains usernames
$publictouserid = array();
if (count($publicusernames)) {
$escapedusernames = array();
foreach ($publicusernames as $publicusername)
$escapedusernames[] = "'" . qa_db_escape_string($publicusername) . "'";
$results = qa_db_read_all_assoc(qa_db_query_raw(
'SELECT username, userid FROM users WHERE username IN (' . implode(',', $escapedusernames) . ')'
));
foreach ($results as $result)
$publictouserid[$result['username']] = $result['userid'];
}
return $publictouserid;
*/
}
/**
* ===========================================================================
* YOU MUST MODIFY THIS FUNCTION, BUT CAN DO SO AFTER Q2A CREATES ITS DATABASE
* ===========================================================================
*
* qa_get_public_from_userids($userids)
*
* This is exactly like qa_get_userids_from_public(), but works in the other direction.
*
* You should take the array of user identifiers in $userids, and return an array which maps valid
* userids to public usernames. For each element of this array, the userid you were given should
* be in the key, with the corresponding username in the value.
*
* Call qa_db_connection() to get the connection to the Q2A database. If your database is shared with
* Q2A, you can also use the various qa_db_* functions to run queries. If you access this database or
* any other, try to use a single query instead of one per user.
*/
function qa_get_public_from_userids($userids)
{
// Until you edit this function, always return null
return null;
/*
Example 1 - suitable if:
* You use textual user identifiers that are also shown publicly
$useridtopublic = array();
foreach ($userids as $userid)
$useridtopublic[$userid] = $userid;
return $useridtopublic;
*/
/*
Example 2 - suitable if:
* You use numerical user identifiers
* Your database is shared with the Q2A site
* Your database has a users table that contains usernames
$useridtopublic = array();
if (count($userids)) {
$escapeduserids = array();
foreach ($userids as $userid)
$escapeduserids[] = "'" . qa_db_escape_string($userid) . "'";
$results = qa_db_read_all_assoc(qa_db_query_raw(
'SELECT username, userid FROM users WHERE userid IN (' . implode(',', $escapeduserids) . ')'
));
foreach ($results as $result)
$useridtopublic[$result['userid']] = $result['username'];
}
return $useridtopublic;
*/
}
/**
* ==========================================================================
* YOU MAY MODIFY THIS FUNCTION, BUT THE DEFAULT BELOW WILL WORK OK
* ==========================================================================
*
* qa_get_logged_in_user_html($logged_in_user, $relative_url_prefix)
*
* You should return HTML code which identifies the logged in user, to be displayed next to the
* logout link on the Q2A pages. This HTML will only be shown to the logged in user themselves.
* Note: the username MUST be escaped with htmlspecialchars() for general output, or urlencode()
* for link URLs.
*
* $logged_in_user is the array that you returned from qa_get_logged_in_user(). Hopefully this
* contains enough information to generate the HTML without another database query, but if not,
* call qa_db_connection() to get the connection to the Q2A database.
*
* $relative_url_prefix is a relative URL to the root of the Q2A site, which may be useful if
* you want to include a link that uses relative URLs. If the Q2A site is in a subdirectory of
* your site, $relative_url_prefix.'../' refers to your site root (see example 1).
*
* If you don't know what to display for a user, you can leave the default below. This will
* show the public username, linked to the Q2A profile page for the user.
*/
function qa_get_logged_in_user_html($logged_in_user, $relative_url_prefix)
{
// By default, show the public username linked to the Q2A profile page for the user
$publicusername = $logged_in_user['publicusername'];
return '<a href="' . qa_path_html('user/' . $publicusername) . '" class="qa-user-link">' . htmlspecialchars($publicusername) . '</a>';
/*
Example 1 - suitable if:
* Your Q2A site: http://www.mysite.com/qa/
* Your user pages: http://www.mysite.com/user/[username]
$publicusername = $logged_in_user['publicusername'];
return '<a href="' . htmlspecialchars($relative_url_prefix . '../user/' . urlencode($publicusername)) .
'" class="qa-user-link">' . htmlspecialchars($publicusername) . '</a>';
*/
/*
Example 2 - suitable if:
* Your Q2A site: http://qa.mysite.com/
* Your user pages: http://www.mysite.com/[username]/
* 16x16 user photos: http://www.mysite.com/[username]/photo-small.jpg
$publicusername = $logged_in_user['publicusername'];
return '<a href="http://www.mysite.com/' . htmlspecialchars(urlencode($publicusername)) . '/" class="qa-user-link">' .
'<img src="http://www.mysite.com/' . htmlspecialchars(urlencode($publicusername)) . '/photo-small.jpg" ' .
'style="width:16px; height:16px; border:none; margin-right:4px;">' . htmlspecialchars($publicusername) . '</a>';
*/
}
/**
* ==========================================================================
* YOU MAY MODIFY THIS FUNCTION, BUT THE DEFAULT BELOW WILL WORK OK
* ==========================================================================
*
* qa_get_users_html($userids, $should_include_link, $relative_url_prefix)
*
* You should return an array of HTML to display for each user in $userids. For each element of
* this array, the userid should be in the key, with the corresponding HTML in the value.
* Note: the username MUST be escaped with htmlspecialchars() for general output, or urlencode()
* for link URLs.
*
* Call qa_db_connection() to get the connection to the Q2A database. If your database is shared with
* Q2A, you can also use the various qa_db_* functions to run queries. If you access this database or
* any other, try to use a single query instead of one per user.
*
* If $should_include_link is true, the HTML may include links to user profile pages.
* If $should_include_link is false, links should not be included in the HTML.
*
* $relative_url_prefix is a relative URL to the root of the Q2A site, which may be useful if
* you want to include links that uses relative URLs. If the Q2A site is in a subdirectory of
* your site, $relative_url_prefix.'../' refers to your site root (see example 1).
*
* If you don't know what to display for a user, you can leave the default below. This will
* show the public username, linked to the Q2A profile page for each user.
*/
function qa_get_users_html($userids, $should_include_link, $relative_url_prefix)
{
// By default, show the public username linked to the Q2A profile page for each user
$useridtopublic = qa_get_public_from_userids($userids);
$usershtml = array();
foreach ($userids as $userid) {
$publicusername = $useridtopublic[$userid];
$usershtml[$userid] = htmlspecialchars($publicusername);
if ($should_include_link)
$usershtml[$userid] = '<a href="' . qa_path_html('user/' . $publicusername) . '" class="qa-user-link">' . $usershtml[$userid] . '</a>';
}
return $usershtml;
/*
Example 1 - suitable if:
* Your Q2A site: http://www.mysite.com/qa/
* Your user pages: http://www.mysite.com/user/[username]
$useridtopublic = qa_get_public_from_userids($userids);
foreach ($userids as $userid) {
$publicusername = $useridtopublic[$userid];
$usershtml[$userid] = htmlspecialchars($publicusername);
if ($should_include_link) {
$usershtml[$userid] = '<a href="' . htmlspecialchars($relative_url_prefix . '../user/' . urlencode($publicusername)) .
'" class="qa-user-link">' . $usershtml[$userid] . '</a>';
}
}
return $usershtml;
*/
/*
Example 2 - suitable if:
* Your Q2A site: http://qa.mysite.com/
* Your user pages: http://www.mysite.com/[username]/
* User photos (16x16): http://www.mysite.com/[username]/photo-small.jpg
$useridtopublic = qa_get_public_from_userids($userids);
foreach ($userids as $userid) {
$publicusername = $useridtopublic[$userid];
$usershtml[$userid] = '<img src="http://www.mysite.com/' . htmlspecialchars(urlencode($publicusername)) . '/photo-small.jpg" ' .
'style="width:16px; height:16px; border:0; margin-right:4px;">' . htmlspecialchars($publicusername);
if ($should_include_link) {
$usershtml[$userid] = '<a href="http://www.mysite.com/' . htmlspecialchars(urlencode($publicusername)) .
'/" class="qa-user-link">' . $usershtml[$userid] . '</a>';
}
}
return $usershtml;
*/
}
/**
* ==========================================================================
* YOU MAY MODIFY THIS FUNCTION, BUT THE DEFAULT BELOW WILL WORK OK
* ==========================================================================
*
* qa_avatar_html_from_userid($userid, $size, $padding)
*
* You should return some HTML for displaying the avatar of $userid on the page.
* If you do not wish to show an avatar for this user, return null.
*
* $size contains the maximum width and height of the avatar to be displayed, in pixels.
*
* If $padding is true, the HTML you return should render to a square of $size x $size pixels,
* even if the avatar is not square. This can be achieved using CSS padding - see function
* qa_get_avatar_blob_html(...) in qa-app-format.php for an example. If $padding is false,
* the HTML can render to anything which would fit inside a square of $size x $size pixels.
*
* Note that this function may be called many times to render an individual page, so it is not
* a good idea to perform a database query each time it is called. Instead, you can use the fact
* that before qa_avatar_html_from_userid(...) is called, qa_get_users_html(...) will have been
* called with all the relevant users in the array $userids. So you can pull out the information
* you need in qa_get_users_html(...) and cache it in a global variable, for use in this function.
*/
function qa_avatar_html_from_userid($userid, $size, $padding)
{
// Show no avatars by default
return null;
/*
Example 1 - suitable if:
* All your avatars are square
* Your Q2A site: http://www.mysite.com/qa/
* Your avatar images: http://www.mysite.com/avatar/[userid]-[size]x[size].jpg
$htmlsize = (int)$size;
return '<img src="http://www.mysite.com/avatar/' . htmlspecialchars($userid) . '-' . $htmlsize . 'x' . $htmlsize . '.jpg" ' .
'width="' . $htmlsize . '" height="' . $htmlsize . '" class="qa-avatar-image" alt=""/>';
*/
}
/**
* ==========================================================================
* YOU MAY MODIFY THIS FUNCTION, BUT THE DEFAULT BELOW WILL WORK OK
* ==========================================================================
*
* qa_user_report_action($userid, $action)
*
* Informs you about an action by user $userid that modified the database, such as posting,
* voting, etc... If you wish, you may use this to log user activity or monitor for abuse.
*
* Call qa_db_connection() to get the connection to the Q2A database. If your database is shared with
* Q2A, you can also use the various qa_db_* functions to run queries.
*
* $action will be a string (such as 'q_edit') describing the action. These strings will match the
* first $event parameter passed to the process_event(...) function in event modules. In fact, you might
* be better off just using a plugin with an event module instead, since you'll get more information.
*
* FYI, you can get the IP address of the user from qa_remote_ip_address().
*/
function qa_user_report_action($userid, $action)
{
// Do nothing by default
}