File/program/modules/crew/crew_view.php

Description

/program/modules/crew/crew_view.php - interface to the view-part of the crew module

This file defines the interface with the crew-module for viewing content. The interface consists of this function:

    crew_view(&$output,$area_id,$node_id,$module)

This function is called from /index.php when the node to display is connected to this module.

Constants
CREW_MAX_DOCUMENT_SIZE = 65536 (line 37)
Functions
crew_screen (line 467)

construct triple-indirect edit screen in pop-up

this routine constructs the necessary HTML-code to show in the CREW editor screen. We use this dynamic construction in order to be able to simply plugin parameters and translated strings into the generated pop-up screen. Perhaps there is a better way (without using a separate javascript translation file for every language) but I haven't thought of it yet.

So here's the deal. We use PHP to generate HTML code which includes the javascript configuration for the CREW editor. This generated HTML is written to the regular page that is generated whenever the user presses the Edit-button in the regular page in the form of a long Javascript string which is used to pop-up a new window. Overly complicated, so let me know if there is a better (cleaner) way.

void crew_screen ( $loc,  $uid,  $user,  $uri,  $shop,  $org,  $date,  $hmac,  $css,  $jscript,  $progcrew)
  • $loc
  • $uid
  • $user
  • $uri
  • $shop
  • $org
  • $date
  • $hmac
  • $css
  • $jscript
  • $progcrew
crew_view (line 54)

display the content of the workshop linked to node $node_id

  • return: TRUE on success + output via $theme, FALSE otherwise
  • todo: FixMe: we need to take parent node permissions into account as soon as we can assign crew permissions to sections. We now specificly look at permissions in table acls_modules_nodes OR at global (guru) permissions for modules in table acls. (June 2013).
  • todo: FixMe: we should rename SaveEdit and Save to Save and Done (May 2014)
  • todo: FixMe: we should somehow add a csrftoken into the mix (May 2014)
bool crew_view (object &$theme, int $area_id, int $node_id, array $module)
  • object &$theme: collects the (html) output
  • int $area_id: identifies the area where $node_id lives
  • int $node_id: the node to which this module is connected
  • array $module: the module record straight from the database
crew_view_dialogdef (line 207)

construct an option to select a skin and start an Edit session

this defines a dialog where the user can pick a skin from a list of existing skins and subsequently press [Edit] to actually edit the document.

  • return: dialogdefinition
array crew_view_dialogdef ()
crew_view_get_workshop_data (line 603)

retrieve the current version of the document + other workshop data

  • return: FALSE on error, array with record from db otherwise
bool|array crew_view_get_workshop_data (int $node_id)
  • int $node_id: which one are we looking at?
crew_view_save_document (line 250)

save the POST'ed version of the document to the workshop database

this saves the document after validating it. The maximum length is arbitrary but it should be enough for a 'normal' document.

  • return: TRUE on success+data saved, FALSE otherwise
bool crew_view_save_document (object &$theme, int $node_id)
  • object &$theme: collects the (html) output
  • int $node_id: key to the page/workshop we are working in
crew_view_show_edit (line 352)

show the (visually almost) empty page and load or continue with the JS popup window

this routine is responsible for showing an 'empty' page and maybe for generating a JS popup window (if $first==TRUE). The 'empty' page contains only a form with single textarea. However, this textarea is not displayed (display:none) so the casual user sees nothing (but obviously without CSS it is a different matter). This textarea is used by the CREW code to store the edited document before submitting the form. Since there are no buttons of any kind, it is completely up to the JS code to generate the necessary DOM elements that are required to successfully save the document.

If $first is TRUE, we have to setup the popup window. This is quite complicated because generate the necessary JS-code at runtime using JS. One of the reasons is that I want to set the correct translations in the popup window. There may be an easier way.

The Websocket protocol is used to talk to the Websocket server which is configured for this site. This setting can be manipulated using the Module Manager. In order to authenticate ourselves against the websocket server we use the following mechanism. There are a few important variables used in authenticating:

  • $origin: this is the website's hostname as seen by the user's browser
  • $request_uri: a string that uniquely identifies the node within the origin
  • $full_name: the full name of the current user (ie. $USER->full_name)
  • $username: the (short) name/userid of the curent user (ie. $USER->username)
  • $request_date: the current time (GMT) in the format "yyyy-mm-dd hh:mm:ss".
and also

  • $secret_key: a secret shared with the Websocket server
  • $location: the URL of the Websocket server
The authentication works as follows. The variables $origin, $request_uri, $full_name, $username and $request_date are concatenated in a $message. Then the $message and the $secret_key are used to calculate a hashed message authentication code (HMAC) according to RFC2104 (see function {@see hmac()} in waslib.php).

When connecting to the Websocket server the parameters $request_uri, $full_name, $username and $request_date are sent, together with the HMAC. The server then calculates the HMAC too and if it matches the HMAC that was sent, access is granted.

Note that the variable $origin is only used here to calculate the HMAC; it is not sent to the Websocket server like the other parameters. Instead we use the Origin as seen by the user's web browser. Obviously the two should match or else authentication fails. This way we check the browser's idea of where the web page is located. Also note that we made the current date/time part of the HMAC. That is done to prevent replay-attacks (the other variables are quasi-static between CREW editing sessions). It is up to the Websocket server to determine if the timestamp is (still) valid or not. This depends on a certain clock synchronisation between the webserver and the Websocket server.

Also note that the shared secret never leaves the webserver, only the hashed message is sent from webserver to Websocket server. However, the secret has to be the same on both ends.

  • return: TRUE on success+output generated via $theme, FALSE otherwise
bool crew_view_show_edit (object &$theme, int $module_id, [bool $first = FALSE])
  • object &$theme: collects the (html) output
  • int $module_id: identifies the crew module (need that for getting module properties)
  • bool $first: if TRUE we generate code to generate a popup
crew_view_show_view (line 149)

display the current version of the document and maybe an Edit button

this fetches a fresh version of the document from the database and displays it, with the header and the introduction (if any).

If the writer flag is TRUE, we also display the date/time/user of last update to the document plus we generate an Edit button which allows this user to actually edit the document via CREW.

Note Since CREW requires JavaScript, we use a trick: we initially hide the Edit button (and the Skin listbox) by setting the display-parameter of the surrounding DIV to none. Subsequently we set that parameter to 'block' using JavaScript. That means if JaveScript is not enabled, the user will not see the DIV and hence the button. If JS is enabled there is no problem. As an added bonus we also have a single line of text warning the user about JavaScript via a NOSCTIPT-tag. The only thing that can happen now is that the browser does not support the Websocket protocl. This is dealt with in the actual CREW code.

  • return: TRUE on success+output generated via $theme, FALSE otherwise
bool crew_view_show_view (object &$theme, bool $writer, int $node_id)
  • object &$theme: collects the (html) output
  • bool $writer: if TRUE we add an Edit button to the display
  • int $node_id: key to the page we're generating

Documentation generated on Tue, 28 Jun 2016 19:09:02 +0200 by phpDocumentor 1.4.0