/program/modules/confab/confab_view.php - interface to the view-part of the confab module
This file defines the interface with the confab-module for viewing content. The interface consists of this function:
This function is called from /index.php when the node to display is connected to this module.
dispatcher for braille interface
this routine decides what needs to be done (and does it). As a side effect, we check various time-out conditions.
send various headers attempting to defeat caching
this is an attempt to force the client not to reuse the data that will be sent shortly. As a bonus, we also construct a string with the corresponding http-equiv statements, to further convince the browser not to cache the page. Reference: http://www.htmlgoodies.com/beyond/reference/article.php/3472881 http://stackoverflow.com/questions/49547
While we are here, we add a few more useful headers such as Content-Type.
send all messages to the participant; update last_seen_id
this not just shows the new messages, but it shows _all_ message.
construct the main/messages screen for the braille interface
this routine checks if there are any new messages for $participant. If so, these are displayed and a basic bare bones button bar is displayed. Here the user can acknowledge the messages (by pressing [OK]), acknowledge the messages and immediately start typing a new message (by pressing [Talk]) or move to the display of all messages that were exchanged since the conversation starten (by pressing [All]).
If there are no new messages a single 'Talk' button (with an asterisk rather than the word 'Talk') is displayed. This page automatically refreshes itself, making sure that the server is regularly polled for any new messages.
show a dialog where a user can write a message or can navigate to another confab-screen
this routine sends a dialog to the user that looks a bit like this:
Message ________ to[Send] [Cancel] [All] [Users] [Quit]
In this dialog the user can enter a message, select a destination from the <listbox> (if enabled) and submit the message via [Send]. Alternatively the user can cancel this screen (and return to the main/messages screen) or navigate to one of the other screens [All] or [Users] or simply end the conversation via [Quit].
send a list of users to the participant
handle the complete procedure to join the conversation
this routine handles joining the conversation. We use the token lib, to force participants to first load an empty join dialog before entering credentials and gaining access.
the container $data holds the number of attempts to specifiy the correct passcode. If this exceeds the maximum, we leave the user with an error in an otherwise empty screen. They can try again after that, but they have to start with a fresh token.
do housekeeping and setup the opening screen with requested interface
this routine is called after the user authenticated successfully. The credentials are in $dialogdef and we are quite confident that the data was valid only moments ago and probably still is.
we now need to add the collected data to the confab_participants table. as a side effect we may have to bump the last_conversation_id ie if the current conversation has ended (after a time out), we start a new one. In that case we are the first/only participant so any name clash we may have (due to race condition) is mitigated.
output the join dialog including the form and header/introduction/footer
this routine can yield a dialog that includes fields for both the user's username and password (as used in a system login). If this is the case (indicated by the presence of the field 'login_password'), we add the paramter 'login=1' to our own URL in order to make a stop at the system login procedure (in ) before proceeding with our own join dialog (killing two birds with one stone).
validate the data entered by the user/visitor
Other than the standard validation we check the passcode and for anonymous visitors we make sure the username is unique within the conversation.
Note 1: We distinguish between Anonymous users and Registered users by adding a postfix to the nickname of the anonymous user. This postfix makes it possible to choose a name like an existing name, eg. 'hparkh' without making it impossible for the real 'hparkh' to login using her real username. As a result, there could be two participants, one named 'hparkh' and one named (say) 'hparkh*'. For the name lookup below these names are different.
Note 2: There is a possible race condition here if two participants use the same nickname at the same time. However, the database will enforce that only one of the two will 'win' and be entered into the confab_participants table. The other one will get a key violation error and, sadly, has to try again. IMHO an acceptable risk but YMMV.
construct a dialog definition for the join screen
this defines the join form. There are several flavours, depending on the confab configuration and the fact that the user is (already) logged in or not.
The basic join screen looks a bit like this:
Nickname: __________ Passcode: __________ Interface:[OK]
If a user is currently logged in, we can already enter the username. If above that the confab is of type registered users only, we make the name readonly, since the user is not allowed to join anonymously. (She must present the passcode though).
If the user is not logged in, we cannot already pre-load the username. If above that the confab is of type registered users only, we add the username and password fields from the system login so we can login and join in a single go. The reason to take this approach is that we don't want to bother the user with two screens: one with username/password and another with username passcode. IF the user provides the correct password AND passcode, we're in business. If she misses one of the two, we either 'hang' in the system login, OR in a loop for requesting a passcode from an already logged in user.
The difference between the dialogs can be detected from the existence of either the 'username' OR the 'login_username' entry in $dialogdef. Alternatively, the input field 'login_password' is only added if a username/password authentication is required too.
Note: The length of the nickname/username in the Confab tables is set at 64. A system username is limited to a length of 60. This allows for at most 4 characters to distinguish Anonymous and Registered participants in the participants and messages tables. Feels like a kludge. Sorry.
end the conversation for $participant (at their own request or forced)
this is the opposite of the confab_join_conversation() routine: we destroy the cookie and remove the participants record etc. The $reason gives the user feedback as to what just happened: if the system has closed down the conversation due to a time-out or when the moderator has closed the Confab altogether, the $reason explains. If no specific reason is given, we show a default message.
add non-empty message to database
Note that there is a chance that we post this message to conversation N (as recorded in our participant-record) whereas the confab has moved on to conversation N+1. Therefore we do hold on to the conversation_id in the participants record rather than the last_conversation_id in the config record. Once this message is processed, the participant will find out that the conversation has ended and that she lands on the login screen...
display the content of the confab linked to node $node_id
This routine is called whenever a visitor visits node $node_id. It depends on the joined-status what is actually sent to the browser. If the participant already joined the conversation, indicated by presenting a valid cookie, the request if further handled in the corresponding protocol dispatcher.
If not, this must be another participant attempting to join the conversation. If the Confab is not closed AND the maximum number of simultaneous participants is not yet reached, we enter the procedure to let the visitor present her credentials (passcode) etc. This is done in a separate routine . This keeps this routine short and readable.
calculate the number of currently joined participants in the current conversation
this calculates the number of participants in the current conversation in the confab. We only count those that have joined the conversation (status is CONFAB_USER_STATUS_JOINED) and not those that are already marked as leaving the conversation (status is CONFAB_USER_STATUS_LEAVING) or are otherwise not joined (status is CONFAB_USER_STATUS_NONE).
In case of error, we return the maximum number of participants. This may be the wrong answer but at least we won't be letting too many participants in.
check for stale participants and remove corresponding records
this routine keeps the database clean; any participants that were last seen more than CONFAB_MAX_CONVERSATION_LIMIT (24h) ago. As long as this routine is called periodically, say every time a participant joins a conversation we are able to weed out all the garbage, eventually.
retrieve all messages in the conversation since $last_message_id
this routine returns an array with all messages with an id that is greater than $last_message_id, ie. the messages that were added since $last_message_id was recorded. If $last_message_id = 0, _all_ messages in the conversation are retrieved.
Note that this routine also takes the 'personal messages' into account: if a message is personal, it is only added to the result if $nickname is either the sender or the receiver of the personal message. Others are not allowed to see these personal messages.
The result is always an array (could be empty) and it is always keyed by confab_message_id.
check for idle participants and timed out participants
we update all participants for which the status is active but that posted a message longer than timeout_idle ago. If there are any participants with a changes status, we flag that to all participants by setting the show_list flag. That means that the next time a participant returns a fresh userlist has to be sent to the browser (if applicable).
This routine also flags users that have passed the conversation timeout value, i.e. that have not touched home for a long time. Those participants are more or less kicked out, eventually freeing space for other participants.
dispatcher for visual interface
this routine decides what needs to be done (and does it). As a side effect, we check various time-out conditions.
Note that this routine handles both asynchronous requests (indicated by having 'button_send' or 'button_update' set in $_POST) which take plave behind the scenes or requests that involve a complete HTML-page (e.g. after the user presses [Refresh]).
The way to quit the conversation is to kindly ask the client to submit a Quit-request rather than simply showing the quit-screen: the latter would probable confuse the asynchronous handler in the client.
construct the main screen for the Visual interfae
this sets up the initial page that will be controlled via Javascript lateron (including resizing).
We generate the page based on the information that is currently available, i.e. the current list of (all) messages, the current list of (all) participants and an up to date listbox (if applicable).
This same routine is called whenever the user presses the Refresh-button, This is a way to refrek both lists if somehow something went wrong underway.
send an update to the client in resonse to an XMLHttpRequest
Note that we cannot process TAB ('\t') and LF ('\n') in JavaScript because these delimiters are used in our protocol. We have to get rid of those.
This routine conditionally sends updates to the client. The following messages are defined:
Send a message "M" | datim | nickfrom | nickto | message
Send a complete userlist "U" | n | m | nick1 | name1 | id1 | active1 ... | nickn | namen | idn | activen
Nicely ask the client to quit the conversation: "Q"
Indicate end of file: "Z"
The client is supposed not to process any lines following the "Z" command (which is always sent). That allows us to add a minimal escape to the main page via URL, for clients that have trouble with XMLHttpRequest functionality. Even though it doesn't work the client is able to get to a more readable page...
Documentation generated on Tue, 28 Jun 2016 19:08:43 +0200 by phpDocumentor 1.4.0