2008-05-09 11:16:04 +09:00
< ? php
2008-12-21 09:39:55 +09:00
/**
2009-01-14 03:41:39 +09:00
* Laconica , the distributed open - source microblogging tool
2008-05-21 04:14:12 +09:00
*
2009-01-14 03:41:39 +09: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-15 04:26:48 +09: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-21 04:14:12 +09:00
*
2008-05-15 04:26:48 +09: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-21 04:14:12 +09:00
*
2008-05-15 04:26:48 +09: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-14 03:41:39 +09:00
*
* @ category Action
* @ package Laconica
* @ author Evan Prodromou < evan @ controlyourself . ca >
* @ author Sarven Capadisli < csarven @ controlyourself . ca >
* @ copyright 2008 Control Yourself , Inc .
* @ license http :// www . fsf . org / licensing / licenses / agpl - 3.0 . html GNU Affero General Public License version 3.0
* @ link http :// laconi . ca /
2008-05-15 04:26:48 +09:00
*/
2008-05-09 11:16:04 +09:00
2008-12-21 09:39:55 +09:00
if ( ! defined ( 'LACONICA' )) {
exit ( 1 );
}
2009-01-16 04:56:40 +09:00
require_once INSTALLDIR . '/lib/noticeform.php' ;
2009-01-15 02:01:53 +09:00
require_once INSTALLDIR . '/lib/htmloutputter.php' ;
2009-01-14 03:41:39 +09: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
* @ package Laconica
* @ author Evan Prodromou < evan @ controlyourself . ca >
* @ author Sarven Capadisli < csarven @ controlyourself . ca >
* @ license http :// www . fsf . org / licensing / licenses / agpl - 3.0 . html GNU Affero General Public License version 3.0
* @ link http :// laconi . ca /
*
* @ see HTMLOutputter
*/
class Action extends HTMLOutputter // lawsuit
{
2008-12-21 09:39:55 +09:00
var $args ;
2009-01-16 04:21:47 +09: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
*/
function __construct ( $output = 'php://output' , $indent = true )
2008-12-21 09:39:55 +09:00
{
2009-01-16 04:21:47 +09:00
parent :: __construct ( $output , $indent );
2008-12-21 09:39:55 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* For initializing members of the class .
*
* @ param array $argarray misc . arguments
*
* @ return boolean true
*/
2008-12-21 09:39:55 +09:00
function prepare ( $argarray )
{
$this -> args =& common_copy_args ( $argarray );
return true ;
}
2009-01-22 13:22:32 +09:00
/**
* Show page , a template method .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showPage ()
{
2009-02-27 04:56:31 +09:00
if ( Event :: handle ( 'StartShowHTML' , array ( $this ))) {
$this -> startHTML ();
Event :: handle ( 'EndShowHTML' , array ( $this ));
}
2009-03-20 21:59:03 +09:00
if ( Event :: handle ( 'StartShowHead' , array ( $this ))) {
2009-01-14 03:41:39 +09:00
$this -> showHead ();
2009-03-20 21:59:03 +09:00
Event :: handle ( 'EndShowHead' , array ( $this ));
}
if ( Event :: handle ( 'StartShowBody' , array ( $this ))) {
2009-01-14 03:41:39 +09:00
$this -> showBody ();
2009-03-20 21:59:03 +09:00
Event :: handle ( 'EndShowBody' , array ( $this ));
}
if ( Event :: handle ( 'StartEndHTML' , array ( $this ))) {
2009-01-14 03:41:39 +09:00
$this -> endHTML ();
2009-03-20 21:59:03 +09:00
Event :: handle ( 'EndEndHTML' , array ( $this ));
}
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show head , a template method .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showHead ()
{
// XXX: attributes (profile?)
2009-01-16 04:23:28 +09:00
$this -> elementStart ( 'head' );
2009-01-14 03:41:39 +09:00
$this -> showTitle ();
2009-03-17 06:42:24 +09:00
$this -> showShortcutIcon ();
2009-01-14 03:41:39 +09:00
$this -> showStylesheets ();
$this -> showScripts ();
2009-02-08 22:02:51 +09:00
$this -> showRelationshipLinks ();
2009-01-14 03:41:39 +09:00
$this -> showOpenSearch ();
$this -> showFeeds ();
$this -> showDescription ();
$this -> extraHead ();
2009-01-16 04:24:54 +09:00
$this -> elementEnd ( 'head' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show title , a template method .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showTitle ()
{
$this -> element ( 'title' , null ,
sprintf ( _ ( " %s - %s " ),
$this -> title (),
common_config ( 'site' , 'name' )));
}
2009-01-22 13:22:32 +09:00
/**
* Returns the page title
*
* SHOULD overload
*
* @ return string page title
*/
2009-01-14 03:41:39 +09:00
function title ()
{
return _ ( " Untitled page " );
}
2009-03-17 06:42:24 +09: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' ,
'href' => theme_path ( 'favicon.ico' )));
} else {
$this -> element ( 'link' , array ( 'rel' => 'shortcut icon' ,
'href' => common_path ( 'favicon.ico' )));
}
2009-03-17 07:03:58 +09: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' ,
'href' => theme_path ( 'apple-touch-icon.png' )));
} else {
$this -> element ( 'link' , array ( 'rel' => 'apple-touch-icon' ,
'href' => common_path ( 'apple-touch-icon.png' )));
}
}
2009-03-17 06:42:24 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show stylesheets
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showStylesheets ()
{
2009-02-13 13:33:43 +09:00
if ( Event :: handle ( 'StartShowStyles' , array ( $this ))) {
if ( Event :: handle ( 'StartShowLaconicaStyles' , array ( $this ))) {
$this -> element ( 'link' , array ( 'rel' => 'stylesheet' ,
'type' => 'text/css' ,
'href' => theme_path ( 'css/display.css' , 'base' ) . '?version=' . LACONICA_VERSION ,
'media' => 'screen, projection, tv' ));
$this -> element ( 'link' , array ( 'rel' => 'stylesheet' ,
'type' => 'text/css' ,
'href' => theme_path ( 'css/display.css' , null ) . '?version=' . LACONICA_VERSION ,
'media' => 'screen, projection, tv' ));
2009-02-18 05:32:19 +09:00
if ( common_config ( 'site' , 'mobile' )) {
$this -> element ( 'link' , array ( 'rel' => 'stylesheet' ,
'type' => 'text/css' ,
'href' => theme_path ( 'css/mobile.css' , 'base' ) . '?version=' . LACONICA_VERSION ,
// TODO: "handheld" CSS for other mobile devices
'media' => 'only screen and (max-device-width: 480px)' )); // Mobile WebKit
}
2009-02-24 13:31:31 +09:00
$this -> element ( 'link' , array ( 'rel' => 'stylesheet' ,
'type' => 'text/css' ,
'href' => theme_path ( 'css/print.css' , 'base' ) . '?version=' . LACONICA_VERSION ,
'media' => 'print' ));
2009-02-13 13:33:43 +09:00
Event :: handle ( 'EndShowLaconicaStyles' , array ( $this ));
2009-01-14 03:41:39 +09:00
}
2009-02-13 13:33:43 +09:00
if ( Event :: handle ( 'StartShowUAStyles' , array ( $this ))) {
$this -> comment ( '[if IE]><link rel="stylesheet" type="text/css" ' .
'href="' . theme_path ( 'css/ie.css' , 'base' ) . '?version=' . LACONICA_VERSION . '" /><![endif]' );
foreach ( array ( 6 , 7 ) as $ver ) {
if ( file_exists ( theme_file ( 'css/ie' . $ver . '.css' , 'base' ))) {
// Yes, IE people should be put in jail.
$this -> comment ( '[if lte IE ' . $ver . ']><link rel="stylesheet" type="text/css" ' .
'href="' . theme_path ( 'css/ie' . $ver . '.css' , 'base' ) . '?version=' . LACONICA_VERSION . '" /><![endif]' );
}
}
$this -> comment ( '[if IE]><link rel="stylesheet" type="text/css" ' .
'href="' . theme_path ( 'css/ie.css' , null ) . '?version=' . LACONICA_VERSION . '" /><![endif]' );
Event :: handle ( 'EndShowUAStyles' , array ( $this ));
}
Event :: handle ( 'EndShowStyles' , array ( $this ));
2009-01-14 03:41:39 +09:00
}
}
2009-01-22 13:22:32 +09:00
/**
* Show javascript headers
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showScripts ()
{
2009-02-09 22:24:23 +09:00
if ( Event :: handle ( 'StartShowScripts' , array ( $this ))) {
if ( Event :: handle ( 'StartShowJQueryScripts' , array ( $this ))) {
$this -> element ( 'script' , array ( 'type' => 'text/javascript' ,
'src' => common_path ( 'js/jquery.min.js' )),
' ' );
$this -> element ( 'script' , array ( 'type' => 'text/javascript' ,
'src' => common_path ( 'js/jquery.form.js' )),
' ' );
Event :: handle ( 'EndShowJQueryScripts' , array ( $this ));
}
if ( Event :: handle ( 'StartShowLaconicaScripts' , array ( $this ))) {
$this -> element ( 'script' , array ( 'type' => 'text/javascript' ,
'src' => common_path ( 'js/xbImportNode.js' )),
' ' );
$this -> element ( 'script' , array ( 'type' => 'text/javascript' ,
'src' => common_path ( 'js/util.js?version=' . LACONICA_VERSION )),
' ' );
2009-02-16 13:45:18 +09:00
// Frame-busting code to avoid clickjacking attacks.
$this -> element ( 'script' , array ( 'type' => 'text/javascript' ),
'if (window.top !== window.self) { window.top.location.href = window.self.location.href; }' );
2009-02-09 22:24:23 +09:00
Event :: handle ( 'EndShowLaconicaScripts' , array ( $this ));
}
Event :: handle ( 'EndShowScripts' , array ( $this ));
}
2009-01-14 03:41:39 +09:00
}
2009-02-08 22:02:51 +09:00
/**
* Show document relationship links
*
* SHOULD overload
*
* @ return nothing
*/
function showRelationshipLinks ()
{
// output <link> elements with appropriate HTML4.01 link types:
// http://www.w3.org/TR/html401/types.html#type-links
}
2009-01-22 13:22:32 +09:00
/**
* Show OpenSearch headers
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showOpenSearch ()
{
2009-01-22 13:22:32 +09:00
$this -> element ( 'link' , array ( 'rel' => 'search' ,
'type' => 'application/opensearchdescription+xml' ,
2009-01-14 03:41:39 +09:00
'href' => common_local_url ( 'opensearch' , array ( 'type' => 'people' )),
'title' => common_config ( 'site' , 'name' ) . ' People Search' ));
2009-01-14 15:59:30 +09:00
$this -> element ( 'link' , array ( 'rel' => 'search' , 'type' => 'application/opensearchdescription+xml' ,
2009-01-14 03:41:39 +09:00
'href' => common_local_url ( 'opensearch' , array ( 'type' => 'notice' )),
'title' => common_config ( 'site' , 'name' ) . ' Notice Search' ));
}
2009-01-22 13:22:32 +09:00
/**
* Show feed headers
*
* MAY overload
*
* @ return nothing
*/
2009-02-12 01:37:50 +09:00
2009-01-14 03:41:39 +09:00
function showFeeds ()
{
2009-02-12 01:37:50 +09: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-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show description .
*
* SHOULD overload
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showDescription ()
{
// does nothing by default
}
2009-01-22 13:22:32 +09:00
/**
* Show extra stuff in < head >.
*
* MAY overload
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function extraHead ()
{
// does nothing by default
}
2009-01-22 13:22:32 +09:00
/**
* Show body .
*
* Calls template methods
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showBody ()
{
2009-04-01 10:03:00 +09:00
$this -> elementStart ( 'body' , ( common_current_user ()) ? array ( 'id' => $this -> trimmed ( 'action' ),
'class' => 'user_in' )
: array ( 'id' => $this -> trimmed ( 'action' )));
2009-02-02 23:14:14 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'wrap' ));
2009-02-13 07:16:48 +09:00
if ( Event :: handle ( 'StartShowHeader' , array ( $this ))) {
$this -> showHeader ();
Event :: handle ( 'EndShowHeader' , array ( $this ));
}
2009-01-14 03:41:39 +09:00
$this -> showCore ();
2009-02-13 07:16:48 +09:00
if ( Event :: handle ( 'StartShowFooter' , array ( $this ))) {
$this -> showFooter ();
Event :: handle ( 'EndShowFooter' , array ( $this ));
}
2009-01-17 00:25:22 +09:00
$this -> elementEnd ( 'div' );
2009-01-15 02:26:23 +09:00
$this -> elementEnd ( 'body' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show header of the page .
*
* Calls template methods
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showHeader ()
{
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'header' ));
2009-01-14 03:41:39 +09:00
$this -> showLogo ();
$this -> showPrimaryNav ();
$this -> showSiteNotice ();
2009-01-18 07:30:44 +09:00
if ( common_logged_in ()) {
$this -> showNoticeForm ();
} else {
$this -> showAnonymousMessage ();
}
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'div' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show configured logo .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showLogo ()
{
2009-01-14 15:59:30 +09:00
$this -> elementStart ( 'address' , array ( 'id' => 'site_contact' ,
2009-01-18 07:30:44 +09:00
'class' => 'vcard' ));
2009-01-14 15:59:30 +09:00
$this -> elementStart ( 'a' , array ( 'class' => 'url home bookmark' ,
2009-01-18 07:30:44 +09:00
'href' => common_local_url ( 'public' )));
2009-01-22 13:22:32 +09:00
if ( common_config ( 'site' , 'logo' ) || file_exists ( theme_file ( 'logo.png' ))) {
2009-01-14 15:34:22 +09:00
$this -> element ( 'img' , array ( 'class' => 'logo photo' ,
2009-01-16 11:21:58 +09:00
'src' => ( common_config ( 'site' , 'logo' )) ? common_config ( 'site' , 'logo' ) : theme_path ( 'logo.png' ),
'alt' => common_config ( 'site' , 'name' )));
2009-01-14 15:34:22 +09:00
}
2009-01-16 11:21:58 +09:00
$this -> element ( 'span' , array ( 'class' => 'fn org' ), common_config ( 'site' , 'name' ));
2009-01-14 15:59:30 +09:00
$this -> elementEnd ( 'a' );
$this -> elementEnd ( 'address' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show primary navigation .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showPrimaryNav ()
{
2009-02-09 22:02:23 +09:00
$user = common_current_user ();
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'dl' , array ( 'id' => 'site_nav_global_primary' ));
2009-01-15 02:01:53 +09:00
$this -> element ( 'dt' , null , _ ( 'Primary site navigation' ));
2009-01-18 07:30:44 +09:00
$this -> elementStart ( 'dd' );
2009-01-16 06:33:45 +09:00
$this -> elementStart ( 'ul' , array ( 'class' => 'nav' ));
2009-02-09 22:02:23 +09:00
if ( Event :: handle ( 'StartPrimaryNav' , array ( $this ))) {
if ( $user ) {
$this -> menuItem ( common_local_url ( 'all' , array ( 'nickname' => $user -> nickname )),
_ ( 'Home' ), _ ( 'Personal profile and friends timeline' ), false , 'nav_home' );
$this -> menuItem ( common_local_url ( 'profilesettings' ),
_ ( 'Account' ), _ ( 'Change your email, avatar, password, profile' ), false , 'nav_account' );
if ( common_config ( 'xmpp' , 'enabled' )) {
$this -> menuItem ( common_local_url ( 'imsettings' ),
_ ( 'Connect' ), _ ( 'Connect to IM, SMS, Twitter' ), false , 'nav_connect' );
} else {
$this -> menuItem ( common_local_url ( 'smssettings' ),
_ ( 'Connect' ), _ ( 'Connect to SMS, Twitter' ), false , 'nav_connect' );
}
2009-04-08 03:08:56 +09:00
$this -> menuItem ( common_local_url ( 'invite' ),
_ ( 'Invite' ),
sprintf ( _ ( 'Invite friends and colleagues to join you on %s' ),
common_config ( 'site' , 'name' )),
false , 'nav_invitecontact' );
2009-02-09 22:02:23 +09:00
$this -> menuItem ( common_local_url ( 'logout' ),
_ ( 'Logout' ), _ ( 'Logout from the site' ), false , 'nav_logout' );
2009-04-08 03:09:54 +09:00
}
else {
2009-02-09 22:02:23 +09:00
if ( ! common_config ( 'site' , 'closed' )) {
$this -> menuItem ( common_local_url ( 'register' ),
_ ( 'Register' ), _ ( 'Create an account' ), false , 'nav_register' );
}
$this -> menuItem ( common_local_url ( 'openidlogin' ),
_ ( 'OpenID' ), _ ( 'Login with OpenID' ), false , 'nav_openid' );
2009-04-08 03:09:54 +09:00
$this -> menuItem ( common_local_url ( 'login' ),
_ ( 'Login' ), _ ( 'Login to the site' ), false , 'nav_login' );
2009-01-14 03:41:39 +09:00
}
2009-02-09 22:02:23 +09:00
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'help' )),
_ ( 'Help' ), _ ( 'Help me!' ), false , 'nav_help' );
2009-04-08 03:09:54 +09:00
$this -> menuItem ( common_local_url ( 'peoplesearch' ),
_ ( 'Search' ), _ ( 'Search for people or text' ), false , 'nav_search' );
2009-02-09 22:02:23 +09:00
Event :: handle ( 'EndPrimaryNav' , array ( $this ));
2009-01-14 03:41:39 +09:00
}
2009-01-14 15:59:30 +09:00
$this -> elementEnd ( 'ul' );
2009-01-18 07:30:44 +09:00
$this -> elementEnd ( 'dd' );
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'dl' );
2009-01-14 03:41:39 +09:00
}
2009-02-04 22:49:42 +09:00
2009-01-22 13:22:32 +09:00
/**
* Show site notice .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showSiteNotice ()
{
2009-01-22 13:22:32 +09:00
// Revist. Should probably do an hAtom pattern here
2009-01-18 07:30:44 +09:00
$text = common_config ( 'site' , 'notice' );
if ( $text ) {
$this -> elementStart ( 'dl' , array ( 'id' => 'site_notice' ,
'class' => 'system_notice' ));
$this -> element ( 'dt' , null , _ ( 'Site notice' ));
2009-02-04 22:49:42 +09:00
$this -> elementStart ( 'dd' , null );
$this -> raw ( $text );
$this -> elementEnd ( 'dd' );
2009-01-18 07:30:44 +09:00
$this -> elementEnd ( 'dl' );
}
2009-01-14 03:41:39 +09:00
}
2009-01-18 07:30:44 +09:00
2009-01-22 13:22:32 +09:00
/**
* Show notice form .
*
* MAY overload if no notice form needed ... or direct message box ? ? ? ?
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showNoticeForm ()
{
2009-01-16 05:11:55 +09:00
$notice_form = new NoticeForm ( $this );
2009-01-15 02:01:53 +09:00
$notice_form -> show ();
2009-01-14 03:41:39 +09:00
}
2009-02-04 22:49:42 +09:00
2009-01-22 13:22:32 +09:00
/**
* Show anonymous message .
*
* SHOULD overload
*
* @ return nothing
*/
2009-01-16 07:25:26 +09:00
function showAnonymousMessage ()
{
2009-01-18 07:30:44 +09:00
// needs to be defined by the class
2009-01-16 07:25:26 +09:00
}
2009-01-18 07:30:44 +09:00
2009-01-22 13:22:32 +09:00
/**
* Show core .
*
* Shows local navigation , content block and aside .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showCore ()
{
2009-01-16 06:34:33 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'core' ));
2009-02-21 08:47:24 +09:00
if ( Event :: handle ( 'StartShowLocalNavBlock' , array ( $this ))) {
$this -> showLocalNavBlock ();
Event :: handle ( 'EndShowLocalNavBlock' , array ( $this ));
}
2009-02-13 07:16:48 +09:00
if ( Event :: handle ( 'StartShowContentBlock' , array ( $this ))) {
$this -> showContentBlock ();
Event :: handle ( 'EndShowContentBlock' , array ( $this ));
}
2009-01-20 02:04:59 +09:00
$this -> showAside ();
$this -> elementEnd ( 'div' );
}
2009-01-22 13:22:32 +09:00
/**
* Show local navigation block .
*
* @ return nothing
*/
2009-01-20 02:04:59 +09:00
function showLocalNavBlock ()
{
2009-01-16 08:44:19 +09:00
$this -> elementStart ( 'dl' , array ( 'id' => 'site_nav_local_views' ));
$this -> element ( 'dt' , null , _ ( 'Local views' ));
$this -> elementStart ( 'dd' );
2009-01-14 03:41:39 +09:00
$this -> showLocalNav ();
2009-01-16 08:44:19 +09:00
$this -> elementEnd ( 'dd' );
2009-01-20 02:09:50 +09:00
$this -> elementEnd ( 'dl' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show local navigation .
*
* SHOULD overload
*
* @ return nothing
*/
2009-01-16 04:45:08 +09:00
function showLocalNav ()
2009-01-14 03:41:39 +09:00
{
2009-01-16 04:45:08 +09:00
// does nothing by default
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show content block .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showContentBlock ()
{
2009-01-15 02:26:23 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'content' ));
2009-01-14 03:41:39 +09:00
$this -> showPageTitle ();
2009-01-16 07:57:15 +09:00
$this -> showPageNoticeBlock ();
2009-01-16 07:17:48 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'content_inner' ));
// show the actual content (forms, lists, whatever)
2009-01-14 03:41:39 +09:00
$this -> showContent ();
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'div' );
2009-01-16 07:17:48 +09:00
$this -> elementEnd ( 'div' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show page title .
*
* @ return nothing
*/
function showPageTitle ()
{
$this -> element ( 'h1' , null , $this -> title ());
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show page notice block .
*
* @ return nothing
*/
2009-01-16 07:57:15 +09:00
function showPageNoticeBlock ()
{
2009-01-18 07:30:44 +09:00
$this -> elementStart ( 'dl' , array ( 'id' => 'page_notice' ,
'class' => 'system_notice' ));
$this -> element ( 'dt' , null , _ ( 'Page notice' ));
$this -> elementStart ( 'dd' );
$this -> showPageNotice ();
$this -> elementEnd ( 'dd' );
$this -> elementEnd ( 'dl' );
2009-01-22 13:22:32 +09:00
}
2009-01-14 03:41:39 +09:00
2009-01-22 13:22:32 +09:00
/**
* Show page notice .
*
* SHOULD overload ( unless there ' s not a notice )
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showPageNotice ()
{
}
2009-01-18 07:30:44 +09:00
2009-01-22 13:22:32 +09:00
/**
* Show content .
*
* MUST overload ( unless there ' s not a notice )
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showContent ()
{
}
2009-01-22 13:22:32 +09:00
/**
* Show Aside .
*
* @ return nothing
*/
2009-02-10 06:56:38 +09:00
2009-01-14 03:41:39 +09:00
function showAside ()
{
2009-01-16 07:00:48 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'aside_primary' ,
'class' => 'aside' ));
2009-03-20 21:59:03 +09:00
if ( Event :: handle ( 'StartShowExportData' , array ( $this ))) {
2009-01-14 03:41:39 +09:00
$this -> showExportData ();
2009-03-20 21:59:03 +09:00
Event :: handle ( 'EndShowExportData' , array ( $this ));
}
2009-02-10 06:56:38 +09:00
if ( Event :: handle ( 'StartShowSections' , array ( $this ))) {
$this -> showSections ();
Event :: handle ( 'EndShowSections' , array ( $this ));
}
2009-01-16 07:00:48 +09:00
$this -> elementEnd ( 'div' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show export data feeds .
*
2009-02-12 01:37:50 +09:00
* @ return void
2009-01-22 13:22:32 +09:00
*/
2009-02-12 01:37:50 +09:00
2009-01-14 03:41:39 +09:00
function showExportData ()
{
2009-02-12 01:37:50 +09:00
$feeds = $this -> getFeeds ();
if ( $feeds ) {
$fl = new FeedList ( $this );
$fl -> show ( $feeds );
}
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show sections .
*
* SHOULD overload
*
* @ return nothing
*/
function showSections ()
{
2009-01-14 03:41:39 +09:00
// for each section, show it
}
2009-01-22 13:22:32 +09:00
/**
* Show footer .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showFooter ()
{
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'div' , array ( 'id' => 'footer' ));
2009-01-14 03:41:39 +09:00
$this -> showSecondaryNav ();
$this -> showLicenses ();
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'div' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show secondary navigation .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showSecondaryNav ()
{
2009-01-16 05:24:41 +09:00
$this -> elementStart ( 'dl' , array ( 'id' => 'site_nav_global_secondary' ));
$this -> element ( 'dt' , null , _ ( 'Secondary site navigation' ));
$this -> elementStart ( 'dd' , null );
2009-01-16 06:33:45 +09:00
$this -> elementStart ( 'ul' , array ( 'class' => 'nav' ));
2009-02-09 22:02:23 +09:00
if ( Event :: handle ( 'StartSecondaryNav' , array ( $this ))) {
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'help' )),
_ ( 'Help' ));
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'about' )),
_ ( 'About' ));
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'faq' )),
_ ( 'FAQ' ));
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'privacy' )),
_ ( 'Privacy' ));
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'source' )),
_ ( 'Source' ));
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'contact' )),
_ ( 'Contact' ));
2009-02-21 10:17:20 +09:00
$this -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'badge' )),
_ ( 'Badge' ));
2009-02-09 22:02:23 +09:00
Event :: handle ( 'EndSecondaryNav' , array ( $this ));
}
2009-01-14 15:59:30 +09:00
$this -> elementEnd ( 'ul' );
2009-01-16 05:24:41 +09:00
$this -> elementEnd ( 'dd' );
$this -> elementEnd ( 'dl' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show licenses .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showLicenses ()
{
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'dl' , array ( 'id' => 'licenses' ));
2009-01-14 03:41:39 +09:00
$this -> showLaconicaLicense ();
$this -> showContentLicense ();
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'dl' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Show Laconica license .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showLaconicaLicense ()
{
2009-01-15 02:01:53 +09:00
$this -> element ( 'dt' , array ( 'id' => 'site_laconica_license' ), _ ( 'Laconica software license' ));
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'dd' , null );
2009-01-14 03:41:39 +09:00
if ( common_config ( 'site' , 'broughtby' )) {
$instr = _ ( '**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%). ' );
} else {
$instr = _ ( '**%%site.name%%** is a microblogging service. ' );
}
$instr .= sprintf ( _ ( 'It runs the [Laconica](http://laconi.ca/) microblogging software, version %s, available under the [GNU Affero General Public License](http://www.fsf.org/licensing/licenses/agpl-3.0.html).' ), LACONICA_VERSION );
$output = common_markup_to_html ( $instr );
2009-01-16 05:24:54 +09:00
$this -> raw ( $output );
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'dd' );
2009-01-14 03:41:39 +09:00
// do it
}
2009-01-22 13:22:32 +09:00
/**
* Show content license .
*
* @ return nothing
*/
2009-01-14 03:41:39 +09:00
function showContentLicense ()
{
2009-01-15 02:01:53 +09:00
$this -> element ( 'dt' , array ( 'id' => 'site_content_license' ), _ ( 'Laconica software license' ));
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'dd' , array ( 'id' => 'site_content_license_cc' ));
2009-01-14 15:59:30 +09:00
$this -> elementStart ( 'p' );
2009-01-17 00:52:17 +09:00
$this -> element ( 'img' , array ( 'id' => 'license_cc' ,
'src' => common_config ( 'license' , 'image' ),
'alt' => common_config ( 'license' , 'title' )));
2009-01-19 04:58:28 +09:00
//TODO: This is dirty: i18n
$this -> text ( _ ( 'All ' . common_config ( 'site' , 'name' ) . ' content and data are available under the ' ));
2009-01-14 15:59:30 +09:00
$this -> element ( 'a' , array ( 'class' => 'license' ,
2009-01-14 17:44:23 +09:00
'rel' => 'external license' ,
2009-01-16 07:40:56 +09:00
'href' => common_config ( 'license' , 'url' )),
common_config ( 'license' , 'title' ));
2009-01-17 00:52:17 +09:00
$this -> text ( _ ( 'license.' ));
2009-01-14 15:59:30 +09:00
$this -> elementEnd ( 'p' );
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'dd' );
2009-01-14 03:41:39 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Return last modified , if applicable .
*
* MAY override
*
* @ return string last modified http header
*/
2009-01-19 03:34:54 +09:00
function lastModified ()
2008-12-21 09:39:55 +09:00
{
2009-01-22 13:22:32 +09:00
// For comparison with If-Last-Modified
// If not applicable, return null
2008-12-21 09:39:55 +09:00
return null ;
}
2009-01-22 13:22:32 +09:00
/**
* Return etag , if applicable .
*
* MAY override
*
* @ return string etag http header
*/
2008-12-21 09:39:55 +09:00
function etag ()
{
return null ;
}
2009-01-22 13:22:32 +09:00
/**
* Return true if read only .
*
* MAY override
*
2009-04-14 04:49:26 +09:00
* @ param array $args other arguments
*
2009-01-22 13:22:32 +09:00
* @ return boolean is read only action ?
*/
2009-04-14 04:49:26 +09:00
2009-04-14 04:54:16 +09:00
function isReadOnly ( $args )
2008-12-21 09:39:55 +09:00
{
return false ;
}
2009-01-22 13:22:32 +09: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 09:39:55 +09:00
function arg ( $key , $def = null )
{
if ( array_key_exists ( $key , $this -> args )) {
return $this -> args [ $key ];
} else {
return $def ;
}
}
2009-01-22 13:22:32 +09: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 09:39:55 +09:00
function trimmed ( $key , $def = null )
{
$arg = $this -> arg ( $key , $def );
2009-01-22 13:22:32 +09:00
return is_string ( $arg ) ? trim ( $arg ) : $arg ;
2008-12-21 09:39:55 +09:00
}
2009-01-22 13:22:32 +09: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 09:39:55 +09:00
function handle ( $argarray = null )
{
2009-01-22 13:22:32 +09:00
$lm = $this -> lastModified ();
2008-12-21 09:39:55 +09:00
$etag = $this -> etag ();
if ( $etag ) {
header ( 'ETag: ' . $etag );
}
if ( $lm ) {
header ( 'Last-Modified: ' . date ( DATE_RFC1123 , $lm ));
2009-03-07 10:19:38 +09:00
if ( isset ( $_SERVER [ 'HTTP_IF_MODIFIED_SINCE' ])) {
$ims = strtotime ( $_SERVER [ 'HTTP_IF_MODIFIED_SINCE' ]);
2008-12-21 09:39:55 +09:00
if ( $lm <= $ims ) {
2009-02-19 08:43:26 +09:00
$if_none_match = $_SERVER [ 'HTTP_IF_NONE_MATCH' ];
if ( ! $if_none_match ||
! $etag ||
$this -> _hasEtag ( $etag , $if_none_match )) {
2008-12-21 09:39:55 +09:00
header ( 'HTTP/1.1 304 Not Modified' );
// Better way to do this?
exit ( 0 );
}
}
}
}
}
2009-01-22 13:22:32 +09:00
/**
* Has etag ? ( private )
*
* @ param string $etag etag http header
* @ param string $if_none_match ifNoneMatch http header
*
* @ return boolean
*/
2009-02-19 08:43:26 +09:00
2009-01-19 03:34:54 +09:00
function _hasEtag ( $etag , $if_none_match )
2008-12-21 09:39:55 +09:00
{
2009-02-19 08:43:26 +09:00
$etags = explode ( ',' , $if_none_match );
return in_array ( $etag , $etags ) || in_array ( '*' , $etags );
2008-12-21 09:39:55 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Boolean understands english ( yes , no , true , false )
*
2009-02-04 22:49:42 +09:00
* @ param string $key query key we ' re interested in
2009-01-22 13:22:32 +09:00
* @ param string $def default value
*
* @ return boolean interprets yes / no strings as boolean
*/
2008-12-21 09:39:55 +09:00
function boolean ( $key , $def = false )
{
$arg = strtolower ( $this -> trimmed ( $key ));
if ( is_null ( $arg )) {
return $def ;
} else if ( in_array ( $arg , array ( 'true' , 'yes' , '1' ))) {
return true ;
} else if ( in_array ( $arg , array ( 'false' , 'no' , '0' ))) {
return false ;
} else {
return $def ;
}
}
2009-01-22 13:22:32 +09:00
/**
* Server error
*
* @ param string $msg error message to display
* @ param integer $code http error code , 500 by default
*
* @ return nothing
*/
2009-02-09 21:15:52 +09:00
2009-01-16 08:03:38 +09:00
function serverError ( $msg , $code = 500 )
2008-12-21 09:39:55 +09:00
{
$action = $this -> trimmed ( 'action' );
common_debug ( " Server error ' $code ' on ' $action ': $msg " , __FILE__ );
2009-02-09 21:15:52 +09:00
throw new ServerException ( $msg , $code );
2008-12-21 09:39:55 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Client error
*
* @ param string $msg error message to display
* @ param integer $code http error code , 400 by default
*
* @ return nothing
*/
2009-02-09 21:15:52 +09:00
2009-01-16 08:03:38 +09:00
function clientError ( $msg , $code = 400 )
2008-12-21 09:39:55 +09:00
{
$action = $this -> trimmed ( 'action' );
common_debug ( " User error ' $code ' on ' $action ': $msg " , __FILE__ );
2009-02-09 21:15:52 +09:00
throw new ClientException ( $msg , $code );
2008-12-21 09:39:55 +09:00
}
2009-01-22 13:22:32 +09:00
/**
* Returns the current URL
*
* @ return string current URL
*/
2009-04-08 00:40:13 +09:00
2009-01-17 04:59:16 +09:00
function selfUrl ()
2008-12-21 09:39:55 +09:00
{
$action = $this -> trimmed ( 'action' );
2009-01-22 13:22:32 +09:00
$args = $this -> args ;
2008-12-21 09:39:55 +09:00
unset ( $args [ 'action' ]);
2009-04-08 00:40:13 +09:00
if ( array_key_exists ( 'submit' , $args )) {
unset ( $args [ 'submit' ]);
}
2008-12-21 09:39:55 +09:00
foreach ( array_keys ( $_COOKIE ) as $cookie ) {
unset ( $args [ $cookie ]);
}
return common_local_url ( $action , $args );
}
2009-01-22 13:22:32 +09: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-16 06:19:23 +09:00
function menuItem ( $url , $text , $title = null , $is_selected = false , $id = null )
2009-01-14 03:41:39 +09:00
{
2009-01-22 13:22:32 +09:00
// Added @id to li for some control.
// XXX: We might want to move this to htmloutputter.php
2009-01-14 03:41:39 +09:00
$lattrs = array ();
if ( $is_selected ) {
$lattrs [ 'class' ] = 'current' ;
}
2009-01-17 15:33:45 +09:00
( is_null ( $id )) ? $lattrs : $lattrs [ 'id' ] = $id ;
2009-01-18 07:30:44 +09:00
2009-01-17 15:33:45 +09:00
$this -> elementStart ( 'li' , $lattrs );
2009-01-14 03:41:39 +09:00
$attrs [ 'href' ] = $url ;
if ( $title ) {
$attrs [ 'title' ] = $title ;
}
2009-01-14 15:59:30 +09:00
$this -> element ( 'a' , $attrs , $text );
$this -> elementEnd ( 'li' );
2009-01-14 03:41:39 +09:00
}
2009-01-14 13:48:05 +09:00
2009-01-22 13:22:32 +09: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
*/
2009-01-14 13:48:05 +09:00
function pagination ( $have_before , $have_after , $page , $action , $args = null )
{
2009-01-22 13:22:32 +09:00
// Does a little before-after block for next/prev page
2009-01-14 13:48:05 +09:00
if ( $have_before || $have_after ) {
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'div' , array ( 'class' => 'pagination' ));
$this -> elementStart ( 'dl' , null );
2009-01-15 02:01:53 +09:00
$this -> element ( 'dt' , null , _ ( 'Pagination' ));
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'dd' , null );
$this -> elementStart ( 'ul' , array ( 'class' => 'nav' ));
2009-01-14 13:48:05 +09:00
}
if ( $have_before ) {
2009-01-22 13:22:32 +09:00
$pargs = array ( 'page' => $page - 1 );
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'li' , array ( 'class' => 'nav_prev' ));
2009-03-04 22:29:21 +09:00
$this -> element ( 'a' , array ( 'href' => common_local_url ( $action , $args , $pargs ),
'rel' => 'prev' ),
2009-01-14 17:44:23 +09:00
_ ( 'After' ));
2009-01-14 13:48:05 +09:00
$this -> elementEnd ( 'li' );
}
if ( $have_after ) {
2009-01-22 13:22:32 +09:00
$pargs = array ( 'page' => $page + 1 );
2009-01-14 17:44:23 +09:00
$this -> elementStart ( 'li' , array ( 'class' => 'nav_next' ));
2009-03-04 22:29:21 +09:00
$this -> element ( 'a' , array ( 'href' => common_local_url ( $action , $args , $pargs ),
'rel' => 'next' ),
2009-01-14 17:44:23 +09:00
_ ( 'Before' ));
2009-01-14 13:48:05 +09:00
$this -> elementEnd ( 'li' );
}
if ( $have_before || $have_after ) {
$this -> elementEnd ( 'ul' );
2009-01-14 17:44:23 +09:00
$this -> elementEnd ( 'dd' );
$this -> elementEnd ( 'dl' );
2009-01-14 13:48:05 +09:00
$this -> elementEnd ( 'div' );
}
}
2009-02-12 01:37:50 +09: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-04-15 16:38:19 +09:00
2009-02-10 17:42:01 +09:00
/**
* Generate document metadata for sequential navigation
*
* @ 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
*/
function sequenceRelationships ( $have_next , $have_previous , $page , $action , $args = null )
{
// Outputs machine-readable pagination in <link> elements.
// Pattern taken from $this->pagination() method.
// "next" is equivalent to "after"
if ( $have_next ) {
$pargs = array ( 'page' => $page - 1 );
$this -> element ( 'link' , array ( 'rel' => 'next' ,
2009-04-15 16:38:19 +09:00
'href' => common_local_url ( $action , $args , $pargs ),
2009-02-10 17:42:01 +09:00
'title' => _ ( 'Next' )));
}
// "previous" is equivalent to "before"
if ( $have_previous = true ) { // FIXME
$pargs = array ( 'page' => $page + 1 );
$this -> element ( 'link' , array ( 'rel' => 'prev' ,
2009-04-15 16:38:19 +09:00
'href' => common_local_url ( $action , $args , $pargs ),
2009-02-10 17:42:01 +09:00
'title' => _ ( 'Previous' )));
}
}
2008-05-09 11:16:04 +09:00
}