2008-05-09 03:16:04 +01:00
< ? php
2008-12-21 00:39:55 +00:00
/**
2009-08-25 23:12:20 +01:00
* StatusNet , the distributed open - source microblogging tool
2008-05-20 20:14:12 +01:00
*
2009-01-13 18:41:39 +00:00
* Base class for all actions ( ~ views )
*
* PHP version 5
*
* LICENCE : This program is free software : you can redistribute it and / or modify
2008-05-14 20:26:48 +01:00
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
2008-05-20 20:14:12 +01:00
*
2008-05-14 20:26:48 +01:00
* 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 Affero General Public License for more details .
2008-05-20 20:14:12 +01:00
*
2008-05-14 20:26:48 +01:00
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
2009-01-13 18:41:39 +00:00
*
* @ category Action
2009-08-25 23:12:20 +01:00
* @ package StatusNet
2009-08-25 23:19:04 +01:00
* @ author Evan Prodromou < evan @ status . net >
* @ author Sarven Capadisli < csarven @ status . net >
2009-08-25 23:12:20 +01:00
* @ copyright 2008 StatusNet , Inc .
2009-01-13 18:41:39 +00:00
* @ license http :// www . fsf . org / licensing / licenses / agpl - 3.0 . html GNU Affero General Public License version 3.0
2009-08-25 23:16:46 +01:00
* @ link http :// status . net /
2008-05-14 20:26:48 +01:00
*/
2008-05-09 03:16:04 +01:00
2009-08-26 15:41:36 +01:00
if ( ! defined ( 'STATUSNET' ) && ! defined ( 'LACONICA' )) {
2008-12-21 00:39:55 +00:00
exit ( 1 );
}
2009-01-15 19:56:40 +00:00
require_once INSTALLDIR . '/lib/noticeform.php' ;
2009-01-14 17:01:53 +00:00
require_once INSTALLDIR . '/lib/htmloutputter.php' ;
2009-01-13 18:41:39 +00:00
/**
* Base class for all actions
*
* This is the base class for all actions in the package . An action is
* more or less a " view " in an MVC framework .
*
* Actions are responsible for extracting and validating parameters ; using
* model classes to read and write to the database ; and doing ouput .
*
* @ category Output
2009-08-25 23:12:20 +01:00
* @ package StatusNet
2009-08-25 23:19:04 +01:00
* @ author Evan Prodromou < evan @ status . net >
* @ author Sarven Capadisli < csarven @ status . net >
2009-01-13 18:41:39 +00:00
* @ license http :// www . fsf . org / licensing / licenses / agpl - 3.0 . html GNU Affero General Public License version 3.0
2009-08-25 23:16:46 +01:00
* @ link http :// status . net /
2009-01-13 18:41:39 +00:00
*
* @ see HTMLOutputter
*/
class Action extends HTMLOutputter // lawsuit
{
2008-12-21 00:39:55 +00:00
var $args ;
2009-01-15 19:21:47 +00:00
/**
* Constructor
*
* Just wraps the HTMLOutputter constructor .
*
* @ param string $output URI to output to , default = stdout
* @ param boolean $indent Whether to indent output , default true
*
* @ see XMLOutputter :: __construct
* @ see HTMLOutputter :: __construct
*/
2009-12-05 06:03:04 +00:00
function __construct ( $output = 'php://output' , $indent = null )
2008-12-21 00:39:55 +00:00
{
2009-01-15 19:21:47 +00:00
parent :: __construct ( $output , $indent );
2008-12-21 00:39:55 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* For initializing members of the class .
*
* @ param array $argarray misc . arguments
*
* @ return boolean true
*/
2008-12-21 00:39:55 +00:00
function prepare ( $argarray )
{
$this -> args =& common_copy_args ( $argarray );
2011-03-16 22:53:46 +00:00
if ( $this -> boolean ( 'ajax' )) {
StatusNet :: setAjax ( true );
}
2008-12-21 00:39:55 +00:00
return true ;
}
2009-01-22 04:22:32 +00:00
/**
* Show page , a template method .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showPage ()
{
2009-02-26 19:56:31 +00:00
if ( Event :: handle ( 'StartShowHTML' , array ( $this ))) {
$this -> startHTML ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-02-26 19:56:31 +00:00
Event :: handle ( 'EndShowHTML' , array ( $this ));
}
2009-03-20 12:59:03 +00:00
if ( Event :: handle ( 'StartShowHead' , array ( $this ))) {
2009-05-15 20:04:58 +01:00
$this -> showHead ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-03-20 12:59:03 +00:00
Event :: handle ( 'EndShowHead' , array ( $this ));
}
if ( Event :: handle ( 'StartShowBody' , array ( $this ))) {
2009-05-15 20:04:58 +01:00
$this -> showBody ();
2009-03-20 12:59:03 +00:00
Event :: handle ( 'EndShowBody' , array ( $this ));
}
if ( Event :: handle ( 'StartEndHTML' , array ( $this ))) {
2009-05-15 20:04:58 +01:00
$this -> endHTML ();
2009-03-20 12:59:03 +00:00
Event :: handle ( 'EndEndHTML' , array ( $this ));
}
2009-01-13 18:41:39 +00:00
}
2011-04-07 05:07:39 +01:00
function endHTML ()
2011-01-31 18:59:38 +00:00
{
global $_startTime ;
if ( isset ( $_startTime )) {
$endTime = microtime ( true );
$diff = round (( $endTime - $_startTime ) * 1000 );
$this -> raw ( " <!-- ${ diff } ms --> " );
}
return parent :: endHTML ();
}
2009-01-22 04:22:32 +00:00
/**
* Show head , a template method .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showHead ()
{
// XXX: attributes (profile?)
2009-01-15 19:23:28 +00:00
$this -> elementStart ( 'head' );
2009-09-24 04:23:13 +01:00
if ( Event :: handle ( 'StartShowHeadElements' , array ( $this ))) {
2010-09-02 22:10:25 +01:00
if ( Event :: handle ( 'StartShowHeadTitle' , array ( $this ))) {
$this -> showTitle ();
Event :: handle ( 'EndShowHeadTitle' , array ( $this ));
}
2009-09-24 04:23:13 +01:00
$this -> showShortcutIcon ();
$this -> showStylesheets ();
$this -> showOpenSearch ();
$this -> showFeeds ();
$this -> showDescription ();
$this -> extraHead ();
Event :: handle ( 'EndShowHeadElements' , array ( $this ));
}
2009-01-15 19:24:54 +00:00
$this -> elementEnd ( 'head' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show title , a template method .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showTitle ()
{
$this -> element ( 'title' , null ,
2010-04-10 20:12:14 +01:00
// TRANS: Page title. %1$s is the title, %2$s is the site name.
2011-04-01 16:05:42 +01:00
sprintf ( _ ( '%1$s - %2$s' ),
2009-01-13 18:41:39 +00:00
$this -> title (),
common_config ( 'site' , 'name' )));
}
2009-01-22 04:22:32 +00:00
/**
* Returns the page title
*
* SHOULD overload
*
* @ return string page title
*/
2009-01-13 18:41:39 +00:00
function title ()
{
2010-04-10 20:12:14 +01:00
// TRANS: Page title for a page without a title set.
2011-04-01 16:05:42 +01:00
return _ ( 'Untitled page' );
2009-01-13 18:41:39 +00:00
}
2009-03-16 21:42:24 +00:00
/**
* Show themed shortcut icon
*
* @ return nothing
*/
function showShortcutIcon ()
{
if ( is_readable ( INSTALLDIR . '/theme/' . common_config ( 'site' , 'theme' ) . '/favicon.ico' )) {
$this -> element ( 'link' , array ( 'rel' => 'shortcut icon' ,
2009-11-08 22:04:46 +00:00
'href' => Theme :: path ( 'favicon.ico' )));
2009-03-16 21:42:24 +00:00
} else {
2010-10-14 05:50:26 +01:00
// favicon.ico should be HTTPS if the rest of the page is
2009-03-16 21:42:24 +00:00
$this -> element ( 'link' , array ( 'rel' => 'shortcut icon' ,
2010-10-14 05:50:26 +01:00
'href' => common_path ( 'favicon.ico' , StatusNet :: isHTTPS ())));
2009-03-16 21:42:24 +00:00
}
2009-03-16 22:03:58 +00:00
if ( common_config ( 'site' , 'mobile' )) {
if ( is_readable ( INSTALLDIR . '/theme/' . common_config ( 'site' , 'theme' ) . '/apple-touch-icon.png' )) {
$this -> element ( 'link' , array ( 'rel' => 'apple-touch-icon' ,
2009-11-08 22:04:46 +00:00
'href' => Theme :: path ( 'apple-touch-icon.png' )));
2009-03-16 22:03:58 +00:00
} else {
$this -> element ( 'link' , array ( 'rel' => 'apple-touch-icon' ,
'href' => common_path ( 'apple-touch-icon.png' )));
}
}
2009-03-16 21:42:24 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show stylesheets
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showStylesheets ()
{
2009-02-13 04:33:43 +00:00
if ( Event :: handle ( 'StartShowStyles' , array ( $this ))) {
2009-07-30 21:24:04 +01:00
2009-08-26 15:33:04 +01:00
// Use old name for StatusNet for compatibility on events
if ( Event :: handle ( 'StartShowStatusNetStyles' , array ( $this )) &&
Event :: handle ( 'StartShowLaconicaStyles' , array ( $this ))) {
2010-09-02 22:11:52 +01:00
$this -> primaryCssLink ( null , 'screen, projection, tv, print' );
2009-08-25 23:12:20 +01:00
Event :: handle ( 'EndShowStatusNetStyles' , array ( $this ));
2009-02-13 04:33:43 +00:00
Event :: handle ( 'EndShowLaconicaStyles' , array ( $this ));
2009-01-13 18:41:39 +00:00
}
2009-07-30 21:24:04 +01:00
2011-03-10 16:28:08 +00:00
$this -> cssLink ( common_path ( 'js/css/smoothness/jquery-ui.css' ));
2009-02-13 04:33:43 +00:00
if ( Event :: handle ( 'StartShowUAStyles' , array ( $this ))) {
$this -> comment ( '[if IE]><link rel="stylesheet" type="text/css" ' .
2009-11-08 22:04:46 +00:00
'href="' . Theme :: path ( 'css/ie.css' , 'base' ) . '?version=' . STATUSNET_VERSION . '" /><![endif]' );
2009-02-13 04:33:43 +00:00
foreach ( array ( 6 , 7 ) as $ver ) {
2009-11-08 22:04:46 +00:00
if ( file_exists ( Theme :: file ( 'css/ie' . $ver . '.css' , 'base' ))) {
2009-02-13 04:33:43 +00:00
// Yes, IE people should be put in jail.
$this -> comment ( '[if lte IE ' . $ver . ']><link rel="stylesheet" type="text/css" ' .
2009-11-08 22:04:46 +00:00
'href="' . Theme :: path ( 'css/ie' . $ver . '.css' , 'base' ) . '?version=' . STATUSNET_VERSION . '" /><![endif]' );
2009-02-13 04:33:43 +00:00
}
}
$this -> comment ( '[if IE]><link rel="stylesheet" type="text/css" ' .
2009-11-08 22:04:46 +00:00
'href="' . Theme :: path ( 'css/ie.css' , null ) . '?version=' . STATUSNET_VERSION . '" /><![endif]' );
2009-02-13 04:33:43 +00:00
Event :: handle ( 'EndShowUAStyles' , array ( $this ));
}
2009-07-30 21:24:04 +01:00
if ( Event :: handle ( 'StartShowDesign' , array ( $this ))) {
$user = common_current_user ();
if ( empty ( $user ) || $user -> viewdesigns ) {
$design = $this -> getDesign ();
if ( ! empty ( $design )) {
$design -> showCSS ( $this );
}
}
Event :: handle ( 'EndShowDesign' , array ( $this ));
}
2009-02-13 04:33:43 +00:00
Event :: handle ( 'EndShowStyles' , array ( $this ));
2010-09-02 22:10:25 +01:00
2010-04-21 16:16:42 +01:00
if ( common_config ( 'custom_css' , 'enabled' )) {
$css = common_config ( 'custom_css' , 'css' );
if ( Event :: handle ( 'StartShowCustomCss' , array ( $this , & $css ))) {
if ( trim ( $css ) != '' ) {
$this -> style ( $css );
}
Event :: handle ( 'EndShowCustomCss' , array ( $this ));
}
}
2009-01-13 18:41:39 +00:00
}
}
2010-09-02 22:11:52 +01:00
function primaryCssLink ( $mainTheme = null , $media = null )
{
Allow theme.ini to specify external CSS URLs, such as Google Font API loaders.
Example theme.ini:
external="http://fonts.googleapis.com/css?family=Lato:100,100italic,300,300italic,400,400italic,700,700italic,900,900italic"
include=rebase
Notes:
* URLs must be quoted in the .ini file or the .ini file parser explodes!
* To do multiples, list as external[] instead of external.
* If there's an included base theme, any externals it lists will be included first.
* All externals are loaded before any local styles.
2011-03-09 18:53:12 +00:00
$theme = new Theme ( $mainTheme );
// Some themes may have external stylesheets, such as using the
// Google Font APIs to load webfonts.
foreach ( $theme -> getExternals () as $url ) {
$this -> cssLink ( $url , $mainTheme , $media );
}
2010-09-02 22:11:52 +01:00
// If the currently-selected theme has dependencies on other themes,
// we'll need to load their display.css files as well in order.
$baseThemes = $theme -> getDeps ();
foreach ( $baseThemes as $baseTheme ) {
$this -> cssLink ( 'css/display.css' , $baseTheme , $media );
}
$this -> cssLink ( 'css/display.css' , $mainTheme , $media );
}
2009-01-22 04:22:32 +00:00
/**
* Show javascript headers
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showScripts ()
{
2009-02-09 13:24:23 +00:00
if ( Event :: handle ( 'StartShowScripts' , array ( $this ))) {
if ( Event :: handle ( 'StartShowJQueryScripts' , array ( $this ))) {
2011-03-11 22:48:47 +00:00
if ( common_config ( 'site' , 'minify' )) {
$this -> script ( 'jquery.min.js' );
$this -> script ( 'jquery.form.min.js' );
2011-03-16 13:56:26 +00:00
$this -> script ( 'jquery-ui.min.js' );
2011-03-11 22:48:47 +00:00
$this -> script ( 'jquery.cookie.min.js' );
$this -> inlineScript ( 'if (typeof window.JSON !== "object") { $.getScript("' . common_path ( 'js/json2.min.js' ) . '"); }' );
$this -> script ( 'jquery.joverlay.min.js' );
} else {
$this -> script ( 'jquery.js' );
$this -> script ( 'jquery.form.js' );
2011-03-16 13:56:26 +00:00
$this -> script ( 'jquery-ui.min.js' );
2011-03-11 22:48:47 +00:00
$this -> script ( 'jquery.cookie.js' );
$this -> inlineScript ( 'if (typeof window.JSON !== "object") { $.getScript("' . common_path ( 'js/json2.js' ) . '"); }' );
$this -> script ( 'jquery.joverlay.js' );
}
2009-02-09 13:24:23 +00:00
Event :: handle ( 'EndShowJQueryScripts' , array ( $this ));
}
2009-08-26 15:33:04 +01:00
if ( Event :: handle ( 'StartShowStatusNetScripts' , array ( $this )) &&
Event :: handle ( 'StartShowLaconicaScripts' , array ( $this ))) {
2011-03-04 00:53:16 +00:00
if ( common_config ( 'site' , 'minify' )) {
$this -> script ( 'util.min.js' );
} else {
$this -> script ( 'util.js' );
$this -> script ( 'xbImportNode.js' );
$this -> script ( 'geometa.js' );
}
2010-11-02 20:05:16 +00:00
$this -> showScriptMessages ();
2009-02-16 04:45:18 +00:00
// Frame-busting code to avoid clickjacking attacks.
2010-02-19 12:13:05 +00:00
$this -> inlineScript ( 'if (window.top !== window.self) { window.top.location.href = window.self.location.href; }' );
2009-08-25 23:12:20 +01:00
Event :: handle ( 'EndShowStatusNetScripts' , array ( $this ));
2009-02-09 13:24:23 +00:00
Event :: handle ( 'EndShowLaconicaScripts' , array ( $this ));
}
Event :: handle ( 'EndShowScripts' , array ( $this ));
}
2009-01-13 18:41:39 +00:00
}
2010-11-02 20:05:16 +00:00
/**
* Exports a map of localized text strings to JavaScript code .
*
* Plugins can add to what ' s exported by hooking the StartScriptMessages or EndScriptMessages
* events and appending to the array . Try to avoid adding strings that won ' t be used , as
* they ' ll be added to HTML output .
*/
2011-01-30 17:48:09 +00:00
2010-11-02 20:05:16 +00:00
function showScriptMessages ()
{
$messages = array ();
2011-01-30 17:48:09 +00:00
2010-11-02 20:05:16 +00:00
if ( Event :: handle ( 'StartScriptMessages' , array ( $this , & $messages ))) {
// Common messages needed for timeline views etc...
// TRANS: Localized tooltip for '...' expansion button on overlong remote messages.
$messages [ 'showmore_tooltip' ] = _m ( 'TOOLTIP' , 'Show more' );
2011-02-28 23:38:54 +00:00
// TRANS: Inline reply form submit button: submits a reply comment.
2011-03-03 20:26:07 +00:00
$messages [ 'reply_submit' ] = _m ( 'BUTTON' , 'Reply' );
2011-02-28 23:38:54 +00:00
2011-03-01 00:13:16 +00:00
// TRANS: Placeholder text for inline reply form. Clicking in this box will turn it into a mini notice form.
2011-03-03 20:26:07 +00:00
$messages [ 'reply_placeholder' ] = _m ( 'Write a reply...' );
2011-03-01 00:13:16 +00:00
2010-11-02 20:05:16 +00:00
$messages = array_merge ( $messages , $this -> getScriptMessages ());
2011-01-30 17:48:09 +00:00
2010-11-17 17:19:01 +00:00
Event :: handle ( 'EndScriptMessages' , array ( $this , & $messages ));
2010-11-02 20:05:16 +00:00
}
2011-01-30 17:48:09 +00:00
2010-11-17 17:19:01 +00:00
if ( ! empty ( $messages )) {
2010-11-02 20:05:16 +00:00
$this -> inlineScript ( 'SN.messages=' . json_encode ( $messages ));
}
2011-01-30 17:48:09 +00:00
2010-11-02 20:05:16 +00:00
return $messages ;
}
/**
* If the action will need localizable text strings , export them here like so :
*
* return array ( 'pool_deepend' => _ ( 'Deep end' ),
* 'pool_shallow' => _ ( 'Shallow end' ));
*
* The exported map will be available via SN . msg () to JS code :
*
* $ ( '#pool' ) . html ( '<div class="deepend"></div><div class="shallow"></div>' );
* $ ( '#pool .deepend' ) . text ( SN . msg ( 'pool_deepend' ));
* $ ( '#pool .shallow' ) . text ( SN . msg ( 'pool_shallow' ));
*
* Exports a map of localized text strings to JavaScript code .
*
* Plugins can add to what ' s exported on any action by hooking the StartScriptMessages or
* EndScriptMessages events and appending to the array . Try to avoid adding strings that won ' t
* be used , as they ' ll be added to HTML output .
*/
function getScriptMessages ()
{
return array ();
}
2009-01-22 04:22:32 +00:00
/**
* Show OpenSearch headers
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showOpenSearch ()
{
2009-01-22 04:22:32 +00:00
$this -> element ( 'link' , array ( 'rel' => 'search' ,
'type' => 'application/opensearchdescription+xml' ,
2009-01-13 18:41:39 +00:00
'href' => common_local_url ( 'opensearch' , array ( 'type' => 'people' )),
'title' => common_config ( 'site' , 'name' ) . ' People Search' ));
2009-01-14 06:59:30 +00:00
$this -> element ( 'link' , array ( 'rel' => 'search' , 'type' => 'application/opensearchdescription+xml' ,
2009-01-13 18:41:39 +00:00
'href' => common_local_url ( 'opensearch' , array ( 'type' => 'notice' )),
'title' => common_config ( 'site' , 'name' ) . ' Notice Search' ));
}
2009-01-22 04:22:32 +00:00
/**
* Show feed headers
*
* MAY overload
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showFeeds ()
{
2009-02-11 16:37:50 +00:00
$feeds = $this -> getFeeds ();
if ( $feeds ) {
foreach ( $feeds as $feed ) {
$this -> element ( 'link' , array ( 'rel' => $feed -> rel (),
'href' => $feed -> url ,
'type' => $feed -> mimeType (),
'title' => $feed -> title ));
}
}
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show description .
*
* SHOULD overload
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showDescription ()
{
// does nothing by default
}
2009-01-22 04:22:32 +00:00
/**
* Show extra stuff in < head >.
*
* MAY overload
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function extraHead ()
{
// does nothing by default
}
2009-01-22 04:22:32 +00:00
/**
* Show body .
*
* Calls template methods
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showBody ()
{
2010-10-21 21:03:56 +01:00
$this -> elementStart ( 'body' , ( common_current_user ()) ? array ( 'id' => strtolower ( $this -> trimmed ( 'action' )),
2009-04-01 02:03:00 +01:00
'class' => 'user_in' )
2010-10-22 19:32:08 +01:00
: array ( 'id' => strtolower ( $this -> trimmed ( 'action' ))));
2009-02-02 14:14:14 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'wrap' ));
2009-02-12 22:16:48 +00:00
if ( Event :: handle ( 'StartShowHeader' , array ( $this ))) {
$this -> showHeader ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-02-12 22:16:48 +00:00
Event :: handle ( 'EndShowHeader' , array ( $this ));
}
2009-01-13 18:41:39 +00:00
$this -> showCore ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-02-12 22:16:48 +00:00
if ( Event :: handle ( 'StartShowFooter' , array ( $this ))) {
$this -> showFooter ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-02-12 22:16:48 +00:00
Event :: handle ( 'EndShowFooter' , array ( $this ));
}
2009-01-16 15:25:22 +00:00
$this -> elementEnd ( 'div' );
2009-09-24 04:23:13 +01:00
$this -> showScripts ();
2009-01-14 17:26:23 +00:00
$this -> elementEnd ( 'body' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show header of the page .
*
* Calls template methods
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showHeader ()
{
2009-01-14 08:44:23 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'header' ));
2009-01-13 18:41:39 +00:00
$this -> showLogo ();
$this -> showPrimaryNav ();
2010-01-21 15:49:49 +00:00
if ( Event :: handle ( 'StartShowSiteNotice' , array ( $this ))) {
$this -> showSiteNotice ();
Event :: handle ( 'EndShowSiteNotice' , array ( $this ));
}
2011-03-03 03:09:11 +00:00
2009-01-14 08:44:23 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show configured logo .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showLogo ()
{
2009-01-14 06:59:30 +00:00
$this -> elementStart ( 'address' , array ( 'id' => 'site_contact' ,
2009-01-17 22:30:44 +00:00
'class' => 'vcard' ));
2009-07-02 17:06:06 +01:00
if ( Event :: handle ( 'StartAddressData' , array ( $this ))) {
2010-01-26 05:21:05 +00:00
if ( common_config ( 'singleuser' , 'enabled' )) {
2010-10-20 22:34:25 +01:00
$user = User :: singleUser ();
2010-01-26 05:21:05 +00:00
$url = common_local_url ( 'showstream' ,
2010-10-20 22:34:25 +01:00
array ( 'nickname' => $user -> nickname ));
2011-01-23 17:35:35 +00:00
} else if ( common_logged_in ()) {
$cur = common_current_user ();
$url = common_local_url ( 'all' , array ( 'nickname' => $cur -> nickname ));
2010-01-26 05:21:05 +00:00
} else {
$url = common_local_url ( 'public' );
}
2011-01-23 17:35:35 +00:00
2009-07-02 17:06:06 +01:00
$this -> elementStart ( 'a' , array ( 'class' => 'url home bookmark' ,
2010-01-26 05:21:05 +00:00
'href' => $url ));
2010-10-14 19:22:49 +01:00
if ( StatusNet :: isHTTPS ()) {
$logoUrl = common_config ( 'site' , 'ssllogo' );
if ( empty ( $logoUrl )) {
// if logo is an uploaded file, try to fall back to HTTPS file URL
$httpUrl = common_config ( 'site' , 'logo' );
if ( ! empty ( $httpUrl )) {
$f = File :: staticGet ( 'url' , $httpUrl );
if ( ! empty ( $f ) && ! empty ( $f -> filename )) {
// this will handle the HTTPS case
$logoUrl = File :: url ( $f -> filename );
}
}
}
} else {
$logoUrl = common_config ( 'site' , 'logo' );
}
if ( empty ( $logoUrl ) && file_exists ( Theme :: file ( 'logo.png' ))) {
// This should handle the HTTPS case internally
$logoUrl = Theme :: path ( 'logo.png' );
}
if ( ! empty ( $logoUrl )) {
2009-07-02 17:06:06 +01:00
$this -> element ( 'img' , array ( 'class' => 'logo photo' ,
2010-10-14 19:22:49 +01:00
'src' => $logoUrl ,
2009-07-02 17:06:06 +01:00
'alt' => common_config ( 'site' , 'name' )));
}
2010-10-14 19:22:49 +01:00
2010-02-15 19:41:46 +00:00
$this -> text ( ' ' );
2009-07-02 17:06:06 +01:00
$this -> element ( 'span' , array ( 'class' => 'fn org' ), common_config ( 'site' , 'name' ));
$this -> elementEnd ( 'a' );
2011-01-23 17:35:35 +00:00
2011-02-28 19:02:38 +00:00
Event :: handle ( 'EndAddressData' , array ( $this ));
2009-01-14 06:34:22 +00:00
}
2009-01-14 06:59:30 +00:00
$this -> elementEnd ( 'address' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show primary navigation .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showPrimaryNav ()
{
2011-03-07 17:42:51 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'site_nav_global_primary' ));
2011-03-01 10:46:03 +00:00
$pn = new PrimaryNav ( $this );
$pn -> show ();
2011-03-07 17:42:51 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2009-02-04 13:49:42 +00:00
2009-01-22 04:22:32 +00:00
/**
* Show site notice .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showSiteNotice ()
{
2009-01-22 04:22:32 +00:00
// Revist. Should probably do an hAtom pattern here
2009-01-17 22:30:44 +00:00
$text = common_config ( 'site' , 'notice' );
if ( $text ) {
2011-01-14 20:36:06 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'site_notice' ,
2009-01-17 22:30:44 +00:00
'class' => 'system_notice' ));
2009-02-04 13:49:42 +00:00
$this -> raw ( $text );
2011-01-14 20:36:06 +00:00
$this -> elementEnd ( 'div' );
2009-01-17 22:30:44 +00:00
}
2009-01-13 18:41:39 +00:00
}
2009-01-17 22:30:44 +00:00
2009-01-22 04:22:32 +00:00
/**
* Show notice form .
*
* MAY overload if no notice form needed ... or direct message box ? ? ? ?
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showNoticeForm ()
{
2011-04-01 16:05:42 +01:00
// TRANS: Tab on the notice form.
$tabs = array ( 'status' => _m ( 'TAB' , 'Status' ));
2011-03-06 22:27:03 +00:00
$this -> elementStart ( 'div' , 'input_forms' );
if ( Event :: handle ( 'StartShowEntryForms' , array ( & $tabs ))) {
$this -> elementStart ( 'ul' , array ( 'class' => 'nav' ,
'id' => 'input_form_nav' ));
foreach ( $tabs as $tag => $title ) {
2011-03-07 09:57:49 +00:00
$attrs = array ( 'id' => 'input_form_nav_' . $tag ,
'class' => 'input_form_nav_tab' );
2011-03-06 22:27:03 +00:00
2011-03-11 02:01:40 +00:00
if ( $tag == 'status' ) {
// We're actually showing the placeholder form,
// but we special-case the 'Status' tab as if
// it were a small version of it.
$attrs [ 'class' ] .= ' current' ;
}
2011-03-06 22:27:03 +00:00
$this -> elementStart ( 'li' , $attrs );
$this -> element ( 'a' ,
2011-03-07 09:57:49 +00:00
array ( 'href' => 'javascript:SN.U.switchInputFormTab("' . $tag . '")' ),
2011-03-06 22:27:03 +00:00
$title );
$this -> elementEnd ( 'li' );
}
$this -> elementEnd ( 'ul' );
2011-03-11 01:31:01 +00:00
$attrs = array ( 'class' => 'input_form current' ,
'id' => 'input_form_placeholder' );
$this -> elementStart ( 'div' , $attrs );
$form = new NoticePlaceholderForm ( $this );
$form -> show ();
$this -> elementEnd ( 'div' );
2011-03-06 22:27:03 +00:00
foreach ( $tabs as $tag => $title ) {
$attrs = array ( 'class' => 'input_form' ,
'id' => 'input_form_' . $tag );
$this -> elementStart ( 'div' , $attrs );
$form = null ;
if ( Event :: handle ( 'StartMakeEntryForm' , array ( $tag , $this , & $form ))) {
if ( $tag == 'status' ) {
2011-03-28 21:24:02 +01:00
$options = $this -> noticeFormOptions ();
$form = new NoticeForm ( $this , $options );
2011-03-06 22:27:03 +00:00
}
Event :: handle ( 'EndMakeEntryForm' , array ( $tag , $this , $form ));
}
if ( ! empty ( $form )) {
$form -> show ();
}
2011-03-07 09:57:49 +00:00
$this -> elementEnd ( 'div' );
2011-03-06 22:27:03 +00:00
}
}
2011-03-07 20:06:21 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2009-02-04 13:49:42 +00:00
2011-03-28 21:24:02 +01:00
function noticeFormOptions ()
{
return array ();
}
2009-01-22 04:22:32 +00:00
/**
* Show anonymous message .
*
* SHOULD overload
*
* @ return nothing
*/
2009-01-15 22:25:26 +00:00
function showAnonymousMessage ()
{
2009-01-17 22:30:44 +00:00
// needs to be defined by the class
2009-01-15 22:25:26 +00:00
}
2009-01-17 22:30:44 +00:00
2009-01-22 04:22:32 +00:00
/**
* Show core .
*
* Shows local navigation , content block and aside .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showCore ()
{
2009-01-15 21:34:33 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'core' ));
2011-03-14 19:30:51 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'aside_primary_wrapper' ));
$this -> elementStart ( 'div' , array ( 'id' => 'content_wrapper' ));
$this -> elementStart ( 'div' , array ( 'id' => 'site_nav_local_views_wrapper' ));
2009-02-20 23:47:24 +00:00
if ( Event :: handle ( 'StartShowLocalNavBlock' , array ( $this ))) {
$this -> showLocalNavBlock ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-02-20 23:47:24 +00:00
Event :: handle ( 'EndShowLocalNavBlock' , array ( $this ));
}
2009-02-12 22:16:48 +00:00
if ( Event :: handle ( 'StartShowContentBlock' , array ( $this ))) {
$this -> showContentBlock ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-02-12 22:16:48 +00:00
Event :: handle ( 'EndShowContentBlock' , array ( $this ));
}
2009-10-01 13:27:02 +01:00
if ( Event :: handle ( 'StartShowAside' , array ( $this ))) {
$this -> showAside ();
2011-01-21 19:23:02 +00:00
$this -> flush ();
2009-10-01 13:27:02 +01:00
Event :: handle ( 'EndShowAside' , array ( $this ));
}
2009-01-19 17:04:59 +00:00
$this -> elementEnd ( 'div' );
2011-03-14 19:30:51 +00:00
$this -> elementEnd ( 'div' );
$this -> elementEnd ( 'div' );
$this -> elementEnd ( 'div' );
2009-01-19 17:04:59 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show local navigation block .
*
* @ return nothing
*/
2009-01-19 17:04:59 +00:00
function showLocalNavBlock ()
{
2011-01-14 20:53:02 +00:00
// Need to have this ID for CSS; I'm too lazy to add it to
// all menus
$this -> elementStart ( 'div' , array ( 'id' => 'site_nav_local_views' ));
2011-03-14 15:58:19 +00:00
// Cheat cheat cheat!
2009-01-13 18:41:39 +00:00
$this -> showLocalNav ();
2011-01-14 20:53:02 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2011-03-14 15:58:19 +00:00
/**
* If there ' s a logged - in user , show a bit of login context
*
* @ return nothing
*/
function showProfileBlock ()
{
if ( common_logged_in ()) {
$block = new DefaultProfileBlock ( $this );
$block -> show ();
}
}
2009-01-22 04:22:32 +00:00
/**
* Show local navigation .
*
* SHOULD overload
*
* @ return nothing
*/
2009-01-15 19:45:08 +00:00
function showLocalNav ()
2009-01-13 18:41:39 +00:00
{
2011-03-01 11:30:51 +00:00
$nav = new DefaultLocalNav ( $this );
$nav -> show ();
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
2011-03-01 20:52:46 +00:00
* Show menu for an object ( group , profile )
*
2011-03-09 20:07:26 +00:00
* This block will only show if a subclass has overridden
* the showObjectNav () method .
*
2011-03-01 20:52:46 +00:00
* @ return nothing
*/
function showObjectNavBlock ()
{
2011-03-09 20:07:26 +00:00
$rmethod = new ReflectionMethod ( $this , 'showObjectNav' );
$dclass = $rmethod -> getDeclaringClass () -> getName ();
if ( $dclass != 'Action' ) {
// Need to have this ID for CSS; I'm too lazy to add it to
// all menus
$this -> elementStart ( 'div' , array ( 'id' => 'site_nav_object' ,
'class' => 'section' ));
$this -> showObjectNav ();
$this -> elementEnd ( 'div' );
}
2011-03-01 20:52:46 +00:00
}
/**
* Show object navigation .
*
* If there are things to do with this object , show it here .
*
* @ return nothing
*/
function showObjectNav ()
{
/* Nothing here. */
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show content block .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showContentBlock ()
{
2009-01-14 17:26:23 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'content' ));
2011-03-03 03:09:11 +00:00
if ( common_logged_in ()) {
if ( Event :: handle ( 'StartShowNoticeForm' , array ( $this ))) {
$this -> showNoticeForm ();
Event :: handle ( 'EndShowNoticeForm' , array ( $this ));
}
}
2010-09-02 22:10:25 +01:00
if ( Event :: handle ( 'StartShowPageTitle' , array ( $this ))) {
$this -> showPageTitle ();
Event :: handle ( 'EndShowPageTitle' , array ( $this ));
}
2009-01-15 22:57:15 +00:00
$this -> showPageNoticeBlock ();
2009-01-15 22:17:48 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'content_inner' ));
// show the actual content (forms, lists, whatever)
2009-01-13 18:41:39 +00:00
$this -> showContent ();
2009-01-14 08:44:23 +00:00
$this -> elementEnd ( 'div' );
2009-01-15 22:17:48 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show page title .
*
* @ return nothing
*/
function showPageTitle ()
{
$this -> element ( 'h1' , null , $this -> title ());
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show page notice block .
*
2009-06-13 01:06:42 +01:00
* Only show the block if a subclassed action has overrided
* Action :: showPageNotice (), or an event handler is registered for
* the StartShowPageNotice event , in which case we assume the
* 'page_notice' definition list is desired . This is to prevent
* empty 'page_notice' definition lists from being output everywhere .
*
2009-01-22 04:22:32 +00:00
* @ return nothing
*/
2009-01-15 22:57:15 +00:00
function showPageNoticeBlock ()
{
2009-06-13 01:06:42 +01:00
$rmethod = new ReflectionMethod ( $this , 'showPageNotice' );
$dclass = $rmethod -> getDeclaringClass () -> getName ();
if ( $dclass != 'Action' || Event :: hasHandler ( 'StartShowPageNotice' )) {
2011-01-14 20:36:06 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'page_notice' ,
2009-06-13 01:06:42 +01:00
'class' => 'system_notice' ));
if ( Event :: handle ( 'StartShowPageNotice' , array ( $this ))) {
$this -> showPageNotice ();
Event :: handle ( 'EndShowPageNotice' , array ( $this ));
}
2011-01-14 20:36:06 +00:00
$this -> elementEnd ( 'div' );
2009-05-15 22:11:28 +01:00
}
2009-01-22 04:22:32 +00:00
}
2009-01-13 18:41:39 +00:00
2009-01-22 04:22:32 +00:00
/**
* Show page notice .
*
* SHOULD overload ( unless there ' s not a notice )
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showPageNotice ()
{
}
2009-01-17 22:30:44 +00:00
2009-01-22 04:22:32 +00:00
/**
* Show content .
*
* MUST overload ( unless there ' s not a notice )
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showContent ()
{
}
2009-01-22 04:22:32 +00:00
/**
* Show Aside .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showAside ()
{
2009-01-15 22:00:48 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'aside_primary' ,
'class' => 'aside' ));
2011-03-14 20:18:03 +00:00
$this -> showProfileBlock ();
2011-03-09 18:38:44 +00:00
if ( Event :: handle ( 'StartShowObjectNavBlock' , array ( $this ))) {
$this -> showObjectNavBlock ();
Event :: handle ( 'EndShowObjectNavBlock' , array ( $this ));
}
2009-02-09 21:56:38 +00:00
if ( Event :: handle ( 'StartShowSections' , array ( $this ))) {
$this -> showSections ();
Event :: handle ( 'EndShowSections' , array ( $this ));
}
2010-09-21 19:09:46 +01:00
if ( Event :: handle ( 'StartShowExportData' , array ( $this ))) {
$this -> showExportData ();
Event :: handle ( 'EndShowExportData' , array ( $this ));
}
2009-01-15 22:00:48 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show export data feeds .
*
2009-02-11 16:37:50 +00:00
* @ return void
2009-01-22 04:22:32 +00:00
*/
2009-01-13 18:41:39 +00:00
function showExportData ()
{
2009-02-11 16:37:50 +00:00
$feeds = $this -> getFeeds ();
if ( $feeds ) {
$fl = new FeedList ( $this );
$fl -> show ( $feeds );
}
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show sections .
*
* SHOULD overload
*
* @ return nothing
*/
function showSections ()
{
2009-01-13 18:41:39 +00:00
// for each section, show it
}
2009-01-22 04:22:32 +00:00
/**
* Show footer .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showFooter ()
{
2009-01-14 08:44:23 +00:00
$this -> elementStart ( 'div' , array ( 'id' => 'footer' ));
2011-02-22 00:10:07 +00:00
if ( Event :: handle ( 'StartShowInsideFooter' , array ( $this ))) {
$this -> showSecondaryNav ();
$this -> showLicenses ();
Event :: handle ( 'EndShowInsideFooter' , array ( $this ));
}
2009-01-14 08:44:23 +00:00
$this -> elementEnd ( 'div' );
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show secondary navigation .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showSecondaryNav ()
{
2011-03-01 10:46:03 +00:00
$sn = new SecondaryNav ( $this );
$sn -> show ();
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Show licenses .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showLicenses ()
{
2009-08-25 23:12:20 +01:00
$this -> showStatusNetLicense ();
2009-01-13 18:41:39 +00:00
$this -> showContentLicense ();
}
2009-01-22 04:22:32 +00:00
/**
2009-08-25 23:12:20 +01:00
* Show StatusNet license .
2009-01-22 04:22:32 +00:00
*
* @ return nothing
*/
2009-08-25 23:12:20 +01:00
function showStatusNetLicense ()
2009-01-13 18:41:39 +00:00
{
if ( common_config ( 'site' , 'broughtby' )) {
2010-04-10 20:12:14 +01:00
// TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is set.
2010-09-12 23:49:42 +01:00
// TRANS: Text between [] is a link description, text between () is the link itself.
// TRANS: Make sure there is no whitespace between "]" and "(".
// TRANS: "%%site.broughtby%%" is the value of the variable site.broughtby
2010-04-10 20:12:14 +01:00
$instr = _ ( '**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%).' );
2009-01-13 18:41:39 +00:00
} else {
2010-04-10 20:12:14 +01:00
// TRANS: First sentence of the StatusNet site license. Used if 'broughtby' is not set.
$instr = _ ( '**%%site.name%%** is a microblogging service.' );
2009-01-13 18:41:39 +00:00
}
2010-03-10 17:36:00 +00:00
$instr .= ' ' ;
2010-04-10 20:12:14 +01:00
// TRANS: Second sentence of the StatusNet site license. Mentions the StatusNet source code license.
2010-09-12 23:49:42 +01:00
// TRANS: Make sure there is no whitespace between "]" and "(".
// TRANS: Text between [] is a link description, text between () is the link itself.
// TRANS: %s is the version of StatusNet that is being used.
2009-08-25 23:42:34 +01:00
$instr .= sprintf ( _ ( 'It runs the [StatusNet](http://status.net/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).' ), STATUSNET_VERSION );
2009-01-13 18:41:39 +00:00
$output = common_markup_to_html ( $instr );
2009-01-15 20:24:54 +00:00
$this -> raw ( $output );
2009-01-13 18:41:39 +00:00
// do it
}
2009-01-22 04:22:32 +00:00
/**
* Show content license .
*
* @ return nothing
*/
2009-01-13 18:41:39 +00:00
function showContentLicense ()
{
2010-01-19 04:25:45 +00:00
if ( Event :: handle ( 'StartShowContentLicense' , array ( $this ))) {
2010-01-19 05:04:58 +00:00
switch ( common_config ( 'license' , 'type' )) {
case 'private' :
2010-04-10 20:12:14 +01:00
// TRANS: Content license displayed when license is set to 'private'.
// TRANS: %1$s is the site name.
2010-01-19 05:04:58 +00:00
$this -> element ( 'p' , null , sprintf ( _ ( 'Content and data of %1$s are private and confidential.' ),
common_config ( 'site' , 'name' )));
// fall through
case 'allrightsreserved' :
if ( common_config ( 'license' , 'owner' )) {
2010-04-10 20:12:14 +01:00
// TRANS: Content license displayed when license is set to 'allrightsreserved'.
// TRANS: %1$s is the copyright owner.
2010-01-19 05:04:58 +00:00
$this -> element ( 'p' , null , sprintf ( _ ( 'Content and data copyright by %1$s. All rights reserved.' ),
common_config ( 'license' , 'owner' )));
} else {
2010-04-10 20:12:14 +01:00
// TRANS: Content license displayed when license is set to 'allrightsreserved' and no owner is set.
2010-01-19 05:04:58 +00:00
$this -> element ( 'p' , null , _ ( 'Content and data copyright by contributors. All rights reserved.' ));
}
break ;
case 'cc' : // fall through
default :
$this -> elementStart ( 'p' );
2010-10-14 05:31:13 +01:00
$image = common_config ( 'license' , 'image' );
$sslimage = common_config ( 'license' , 'sslimage' );
if ( StatusNet :: isHTTPS ()) {
if ( ! empty ( $sslimage )) {
$url = $sslimage ;
} else if ( preg_match ( '#^http://i.creativecommons.org/#' , $image )) {
// CC support HTTPS on their images
$url = preg_replace ( '/^http/' , 'https' , $image );
} else {
// Better to show mixed content than no content
$url = $image ;
}
} else {
$url = $image ;
}
2010-01-19 05:04:58 +00:00
$this -> element ( 'img' , array ( 'id' => 'license_cc' ,
2010-10-14 05:31:13 +01:00
'src' => $url ,
2010-01-19 05:04:58 +00:00
'alt' => common_config ( 'license' , 'title' ),
'width' => '80' ,
'height' => '15' ));
2010-02-15 19:41:46 +00:00
$this -> text ( ' ' );
2010-09-12 23:49:42 +01:00
// TRANS: license message in footer.
// TRANS: %1$s is the site name, %2$s is a link to the license URL, with a licence name set in configuration.
2010-04-09 16:56:43 +01:00
$notice = _ ( 'All %1$s content and data are available under the %2$s license.' );
$link = " <a class= \" license \" rel= \" external license \" href= \" " .
htmlspecialchars ( common_config ( 'license' , 'url' )) .
" \" > " .
htmlspecialchars ( common_config ( 'license' , 'title' )) .
" </a> " ;
$this -> raw ( sprintf ( htmlspecialchars ( $notice ),
htmlspecialchars ( common_config ( 'site' , 'name' )),
$link ));
2010-01-19 05:04:58 +00:00
$this -> elementEnd ( 'p' );
break ;
}
2010-01-19 04:25:45 +00:00
Event :: handle ( 'EndShowContentLicense' , array ( $this ));
}
2009-01-13 18:41:39 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Return last modified , if applicable .
*
* MAY override
*
* @ return string last modified http header
*/
2009-01-18 18:34:54 +00:00
function lastModified ()
2008-12-21 00:39:55 +00:00
{
2009-01-22 04:22:32 +00:00
// For comparison with If-Last-Modified
// If not applicable, return null
2008-12-21 00:39:55 +00:00
return null ;
}
2009-01-22 04:22:32 +00:00
/**
* Return etag , if applicable .
*
* MAY override
*
* @ return string etag http header
*/
2008-12-21 00:39:55 +00:00
function etag ()
{
return null ;
}
2009-01-22 04:22:32 +00:00
/**
* Return true if read only .
*
* MAY override
*
2009-04-13 20:49:26 +01:00
* @ param array $args other arguments
*
2009-01-22 04:22:32 +00:00
* @ return boolean is read only action ?
*/
2009-04-13 20:54:16 +01:00
function isReadOnly ( $args )
2008-12-21 00:39:55 +00:00
{
return false ;
}
2009-01-22 04:22:32 +00:00
/**
* Returns query argument or default value if not found
*
* @ param string $key requested argument
* @ param string $def default value to return if $key is not provided
*
* @ return boolean is read only action ?
*/
2008-12-21 00:39:55 +00:00
function arg ( $key , $def = null )
{
if ( array_key_exists ( $key , $this -> args )) {
return $this -> args [ $key ];
} else {
return $def ;
}
}
2009-01-22 04:22:32 +00:00
/**
* Returns trimmed query argument or default value if not found
*
* @ param string $key requested argument
* @ param string $def default value to return if $key is not provided
*
* @ return boolean is read only action ?
*/
2008-12-21 00:39:55 +00:00
function trimmed ( $key , $def = null )
{
$arg = $this -> arg ( $key , $def );
2009-01-22 04:22:32 +00:00
return is_string ( $arg ) ? trim ( $arg ) : $arg ;
2008-12-21 00:39:55 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Handler method
*
* @ param array $argarray is ignored since it ' s now passed in in prepare ()
*
* @ return boolean is read only action ?
*/
2008-12-21 00:39:55 +00:00
function handle ( $argarray = null )
{
2009-09-23 14:33:40 +01:00
header ( 'Vary: Accept-Encoding,Cookie' );
2010-08-31 05:54:33 +01:00
2009-01-22 04:22:32 +00:00
$lm = $this -> lastModified ();
2008-12-21 00:39:55 +00:00
$etag = $this -> etag ();
2010-08-31 05:54:33 +01:00
2008-12-21 00:39:55 +00:00
if ( $etag ) {
header ( 'ETag: ' . $etag );
}
2010-08-31 05:54:33 +01:00
2008-12-21 00:39:55 +00:00
if ( $lm ) {
header ( 'Last-Modified: ' . date ( DATE_RFC1123 , $lm ));
2010-08-31 05:33:56 +01:00
if ( $this -> isCacheable ()) {
header ( 'Expires: ' . gmdate ( 'D, d M Y H:i:s' , 0 ) . ' GMT' );
header ( " Cache-Control: private, must-revalidate, max-age=0 " );
2010-09-08 20:41:39 +01:00
header ( " Pragma: " );
2010-08-31 05:54:33 +01:00
}
}
2010-09-20 21:42:58 +01:00
$checked = false ;
2010-08-31 05:54:33 +01:00
if ( $etag ) {
$if_none_match = ( array_key_exists ( 'HTTP_IF_NONE_MATCH' , $_SERVER )) ?
$_SERVER [ 'HTTP_IF_NONE_MATCH' ] : null ;
2010-09-20 21:42:58 +01:00
if ( $if_none_match ) {
// If this check fails, ignore the if-modified-since below.
$checked = true ;
if ( $this -> _hasEtag ( $etag , $if_none_match )) {
header ( 'HTTP/1.1 304 Not Modified' );
// Better way to do this?
exit ( 0 );
}
2010-08-31 05:54:33 +01:00
}
}
2010-09-20 21:42:58 +01:00
if ( ! $checked && $lm && array_key_exists ( 'HTTP_IF_MODIFIED_SINCE' , $_SERVER )) {
2010-08-31 05:54:33 +01:00
$if_modified_since = $_SERVER [ 'HTTP_IF_MODIFIED_SINCE' ];
$ims = strtotime ( $if_modified_since );
if ( $lm <= $ims ) {
header ( 'HTTP/1.1 304 Not Modified' );
// Better way to do this?
exit ( 0 );
2010-08-31 05:33:56 +01:00
}
2008-12-21 00:39:55 +00:00
}
}
2010-08-31 05:33:56 +01:00
/**
* Is this action cacheable ?
*
* If the action returns a last - modified
*
* @ param array $argarray is ignored since it ' s now passed in in prepare ()
*
* @ return boolean is read only action ?
*/
function isCacheable ()
{
return true ;
}
2009-01-22 04:22:32 +00:00
/**
* Has etag ? ( private )
*
* @ param string $etag etag http header
* @ param string $if_none_match ifNoneMatch http header
*
* @ return boolean
*/
2009-01-18 18:34:54 +00:00
function _hasEtag ( $etag , $if_none_match )
2008-12-21 00:39:55 +00:00
{
2009-02-18 23:43:26 +00:00
$etags = explode ( ',' , $if_none_match );
return in_array ( $etag , $etags ) || in_array ( '*' , $etags );
2008-12-21 00:39:55 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Boolean understands english ( yes , no , true , false )
*
2009-02-04 13:49:42 +00:00
* @ param string $key query key we ' re interested in
2009-01-22 04:22:32 +00:00
* @ param string $def default value
*
* @ return boolean interprets yes / no strings as boolean
*/
2008-12-21 00:39:55 +00:00
function boolean ( $key , $def = false )
{
$arg = strtolower ( $this -> trimmed ( $key ));
if ( is_null ( $arg )) {
return $def ;
2010-02-26 17:28:58 +00:00
} else if ( in_array ( $arg , array ( 'true' , 'yes' , '1' , 'on' ))) {
2008-12-21 00:39:55 +00:00
return true ;
} else if ( in_array ( $arg , array ( 'false' , 'no' , '0' ))) {
return false ;
} else {
return $def ;
}
}
2009-12-12 20:00:09 +00:00
/**
* Integer value of an argument
*
* @ param string $key query key we ' re interested in
* @ param string $defValue optional default value ( default null )
* @ param string $maxValue optional max value ( default null )
* @ param string $minValue optional min value ( default null )
*
* @ return integer integer value
*/
function int ( $key , $defValue = null , $maxValue = null , $minValue = null )
{
$arg = strtolower ( $this -> trimmed ( $key ));
if ( is_null ( $arg ) || ! is_integer ( $arg )) {
return $defValue ;
}
if ( ! is_null ( $maxValue )) {
$arg = min ( $arg , $maxValue );
}
if ( ! is_null ( $minValue )) {
$arg = max ( $arg , $minValue );
}
return $arg ;
}
2009-01-22 04:22:32 +00:00
/**
* Server error
*
* @ param string $msg error message to display
* @ param integer $code http error code , 500 by default
*
* @ return nothing
*/
2009-01-15 23:03:38 +00:00
function serverError ( $msg , $code = 500 )
2008-12-21 00:39:55 +00:00
{
$action = $this -> trimmed ( 'action' );
common_debug ( " Server error ' $code ' on ' $action ': $msg " , __FILE__ );
2009-02-09 12:15:52 +00:00
throw new ServerException ( $msg , $code );
2008-12-21 00:39:55 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Client error
*
* @ param string $msg error message to display
* @ param integer $code http error code , 400 by default
*
* @ return nothing
*/
2009-01-15 23:03:38 +00:00
function clientError ( $msg , $code = 400 )
2008-12-21 00:39:55 +00:00
{
$action = $this -> trimmed ( 'action' );
common_debug ( " User error ' $code ' on ' $action ': $msg " , __FILE__ );
2009-02-09 12:15:52 +00:00
throw new ClientException ( $msg , $code );
2008-12-21 00:39:55 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Returns the current URL
*
* @ return string current URL
*/
2009-01-16 19:59:16 +00:00
function selfUrl ()
2009-11-16 16:54:34 +00:00
{
list ( $action , $args ) = $this -> returnToArgs ();
return common_local_url ( $action , $args );
}
/**
* Returns arguments sufficient for re - constructing URL
*
* @ return array two elements : action , other args
*/
function returnToArgs ()
2008-12-21 00:39:55 +00:00
{
$action = $this -> trimmed ( 'action' );
2009-01-22 04:22:32 +00:00
$args = $this -> args ;
2008-12-21 00:39:55 +00:00
unset ( $args [ 'action' ]);
2009-07-01 17:58:16 +01:00
if ( common_config ( 'site' , 'fancy' )) {
unset ( $args [ 'p' ]);
}
2009-04-07 16:40:13 +01:00
if ( array_key_exists ( 'submit' , $args )) {
unset ( $args [ 'submit' ]);
}
2008-12-21 00:39:55 +00:00
foreach ( array_keys ( $_COOKIE ) as $cookie ) {
unset ( $args [ $cookie ]);
}
2009-11-16 16:54:34 +00:00
return array ( $action , $args );
2008-12-21 00:39:55 +00:00
}
2009-01-22 04:22:32 +00:00
/**
* Generate a menu item
*
* @ param string $url menu URL
* @ param string $text menu name
* @ param string $title title attribute , null by default
* @ param boolean $is_selected current menu item , false by default
* @ param string $id element id , null by default
*
* @ return nothing
*/
2009-01-15 21:19:23 +00:00
function menuItem ( $url , $text , $title = null , $is_selected = false , $id = null )
2009-01-13 18:41:39 +00:00
{
2009-01-22 04:22:32 +00:00
// Added @id to li for some control.
// XXX: We might want to move this to htmloutputter.php
2009-01-13 18:41:39 +00:00
$lattrs = array ();
if ( $is_selected ) {
$lattrs [ 'class' ] = 'current' ;
}
2009-01-17 06:33:45 +00:00
( is_null ( $id )) ? $lattrs : $lattrs [ 'id' ] = $id ;
2009-01-17 22:30:44 +00:00
2009-01-17 06:33:45 +00:00
$this -> elementStart ( 'li' , $lattrs );
2009-01-13 18:41:39 +00:00
$attrs [ 'href' ] = $url ;
if ( $title ) {
$attrs [ 'title' ] = $title ;
}
2009-01-14 06:59:30 +00:00
$this -> element ( 'a' , $attrs , $text );
$this -> elementEnd ( 'li' );
2009-01-13 18:41:39 +00:00
}
2009-01-14 04:48:05 +00:00
2009-01-22 04:22:32 +00:00
/**
* Generate pagination links
*
* @ param boolean $have_before is there something before ?
* @ param boolean $have_after is there something after ?
* @ param integer $page current page
* @ param string $action current action
* @ param array $args rest of query arguments
*
* @ return nothing
*/
2010-04-10 20:12:14 +01:00
// XXX: The messages in this pagination method only tailor to navigating
// notices. In other lists, "Previous"/"Next" type navigation is
// desirable, but not available.
2009-01-14 04:48:05 +00:00
function pagination ( $have_before , $have_after , $page , $action , $args = null )
{
2009-01-22 04:22:32 +00:00
// Does a little before-after block for next/prev page
2009-01-14 04:48:05 +00:00
if ( $have_before || $have_after ) {
2011-01-14 20:53:02 +00:00
$this -> elementStart ( 'ul' , array ( 'class' => 'nav' ,
'id' => 'pagination' ));
2009-01-14 04:48:05 +00:00
}
if ( $have_before ) {
2009-01-22 04:22:32 +00:00
$pargs = array ( 'page' => $page - 1 );
2009-01-14 08:44:23 +00:00
$this -> elementStart ( 'li' , array ( 'class' => 'nav_prev' ));
2009-03-04 13:29:21 +00:00
$this -> element ( 'a' , array ( 'href' => common_local_url ( $action , $args , $pargs ),
'rel' => 'prev' ),
2010-04-10 20:12:14 +01:00
// TRANS: Pagination message to go to a page displaying information more in the
// TRANS: present than the currently displayed information.
2009-01-14 08:44:23 +00:00
_ ( 'After' ));
2009-01-14 04:48:05 +00:00
$this -> elementEnd ( 'li' );
}
if ( $have_after ) {
2009-01-22 04:22:32 +00:00
$pargs = array ( 'page' => $page + 1 );
2009-01-14 08:44:23 +00:00
$this -> elementStart ( 'li' , array ( 'class' => 'nav_next' ));
2009-03-04 13:29:21 +00:00
$this -> element ( 'a' , array ( 'href' => common_local_url ( $action , $args , $pargs ),
'rel' => 'next' ),
2010-04-10 20:12:14 +01:00
// TRANS: Pagination message to go to a page displaying information more in the
// TRANS: past than the currently displayed information.
2009-01-14 08:44:23 +00:00
_ ( 'Before' ));
2009-01-14 04:48:05 +00:00
$this -> elementEnd ( 'li' );
}
if ( $have_before || $have_after ) {
$this -> elementEnd ( 'ul' );
}
}
2009-02-11 16:37:50 +00:00
/**
* An array of feeds for this action .
*
* Returns an array of potential feeds for this action .
*
* @ return array Feed object to show in head and links
*/
function getFeeds ()
{
return null ;
}
2009-07-30 21:24:04 +01:00
/**
* A design for this action
*
* @ return Design a design object to use
*/
function getDesign ()
{
return Design :: siteDesign ();
}
2009-11-07 23:51:57 +00:00
/**
* Check the session token .
*
* Checks that the current form has the correct session token ,
* and throw an exception if it does not .
*
* @ return void
*/
2010-04-10 20:12:14 +01:00
// XXX: Finding this type of check with the same message about 50 times.
// Possible to refactor?
2009-11-07 23:51:57 +00:00
function checkSessionToken ()
{
// CSRF protection
$token = $this -> trimmed ( 'token' );
if ( empty ( $token ) || $token != common_session_token ()) {
2010-09-12 23:49:42 +01:00
// TRANS: Client error text when there is a problem with the session token.
2009-11-07 23:51:57 +00:00
$this -> clientError ( _ ( 'There was a problem with your session token.' ));
}
}
2010-10-24 20:04:12 +01:00
/**
* Check if the current request is a POST
*
* @ return boolean true if POST ; otherwise false .
*/
function isPost ()
{
return ( $_SERVER [ 'REQUEST_METHOD' ] == 'POST' );
}
2008-05-09 03:16:04 +01:00
}