2008-05-20 14:05:35 +01:00
< ? php
2008-05-20 20:14:12 +01:00
/*
2008-05-20 14:05:35 +01:00
* Laconica - a distributed open - source microblogging tool
* Copyright ( C ) 2008 , Controlez - Vous , Inc .
2008-05-20 20:14:12 +01:00
*
2008-05-20 14:05:35 +01:00
* This program is free software : you can redistribute it and / or modify
* 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-20 14:05:35 +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-20 14:05:35 +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 />.
*/
/* XXX: break up into separate modules (HTTP, HTML, user, files) */
# Show a server error
2008-06-06 17:04:37 +01:00
function common_server_error ( $msg , $code = 500 ) {
static $status = array ( 500 => 'Internal Server Error' ,
501 => 'Not Implemented' ,
502 => 'Bad Gateway' ,
503 => 'Service Unavailable' ,
504 => 'Gateway Timeout' ,
505 => 'HTTP Version Not Supported' );
if ( ! array_key_exists ( $code , $status )) {
$code = 500 ;
}
$status_string = $status [ $code ];
header ( 'HTTP/1.1 ' . $code . ' ' . $status_string );
2008-05-20 14:05:35 +01:00
header ( 'Content-type: text/plain' );
print $msg ;
2008-06-02 20:38:51 +01:00
print " \n " ;
2008-05-20 14:05:35 +01:00
exit ();
}
# Show a user error
2008-06-26 23:50:02 +01:00
function common_user_error ( $msg , $code = 400 ) {
2008-06-06 17:04:37 +01:00
static $status = array ( 400 => 'Bad Request' ,
401 => 'Unauthorized' ,
402 => 'Payment Required' ,
403 => 'Forbidden' ,
404 => 'Not Found' ,
405 => 'Method Not Allowed' ,
406 => 'Not Acceptable' ,
407 => 'Proxy Authentication Required' ,
408 => 'Request Timeout' ,
409 => 'Conflict' ,
410 => 'Gone' ,
411 => 'Length Required' ,
412 => 'Precondition Failed' ,
413 => 'Request Entity Too Large' ,
414 => 'Request-URI Too Long' ,
415 => 'Unsupported Media Type' ,
416 => 'Requested Range Not Satisfiable' ,
417 => 'Expectation Failed' );
if ( ! array_key_exists ( $code , $status )) {
$code = 400 ;
}
$status_string = $status [ $code ];
header ( 'HTTP/1.1 ' . $code . ' ' . $status_string );
2008-05-20 14:05:35 +01:00
common_show_header ( 'Error' );
common_element ( 'div' , array ( 'class' => 'error' ), $msg );
common_show_footer ();
}
2008-05-20 14:27:22 +01:00
$xw = null ;
2008-05-20 14:05:35 +01:00
# Start an HTML element
function common_element_start ( $tag , $attrs = NULL ) {
2008-05-20 14:27:22 +01:00
global $xw ;
$xw -> startElement ( $tag );
2008-05-20 14:05:35 +01:00
if ( is_array ( $attrs )) {
foreach ( $attrs as $name => $value ) {
2008-05-20 14:27:22 +01:00
$xw -> writeAttribute ( $name , $value );
2008-05-20 14:05:35 +01:00
}
} else if ( is_string ( $attrs )) {
2008-05-20 14:27:22 +01:00
$xw -> writeAttribute ( 'class' , $attrs );
2008-05-20 14:05:35 +01:00
}
}
function common_element_end ( $tag ) {
2008-07-09 00:32:18 +01:00
static $empty_tag = array ( 'base' , 'meta' , 'link' , 'hr' ,
'br' , 'param' , 'img' , 'area' ,
2008-07-09 23:46:30 +01:00
'input' , 'col' );
2008-05-20 14:27:22 +01:00
global $xw ;
2008-07-09 00:50:04 +01:00
# XXX: check namespace
2008-07-09 00:32:18 +01:00
if ( in_array ( $tag , $empty_tag )) {
$xw -> endElement ();
} else {
$xw -> fullEndElement ();
}
2008-05-20 14:05:35 +01:00
}
function common_element ( $tag , $attrs = NULL , $content = NULL ) {
2008-07-09 00:50:04 +01:00
common_element_start ( $tag , $attrs );
global $xw ;
2008-07-22 17:36:18 +01:00
if ( ! is_null ( $content )) {
2008-07-09 00:50:04 +01:00
$xw -> text ( $content );
}
common_element_end ( $tag );
2008-05-20 14:05:35 +01:00
}
2008-05-21 15:33:51 +01:00
function common_start_xml ( $doc = NULL , $public = NULL , $system = NULL ) {
global $xw ;
$xw = new XMLWriter ();
$xw -> openURI ( 'php://output' );
$xw -> setIndent ( true );
$xw -> startDocument ( '1.0' , 'UTF-8' );
if ( $doc ) {
$xw -> writeDTD ( $doc , $public , $system );
}
}
function common_end_xml () {
global $xw ;
$xw -> endDocument ();
$xw -> flush ();
}
2008-08-06 04:45:15 +01:00
function common_init_language () {
2008-08-17 16:30:24 +01:00
mb_internal_encoding ( 'UTF-8' );
2008-07-30 04:54:46 +01:00
$language = common_language ();
2008-07-31 03:04:33 +01:00
# So we don't have to make people install the gettext locales
putenv ( 'LANGUAGE=' . $language );
2008-08-27 01:19:27 +01:00
putenv ( 'LANG=' . $language );
2008-07-31 03:04:33 +01:00
$locale_set = setlocale ( LC_ALL , $language . " .utf8 " ,
$language . " .UTF8 " ,
$language . " .utf-8 " ,
$language . " .UTF-8 " ,
$language );
2008-08-06 13:21:19 +01:00
bindtextdomain ( " laconica " , common_config ( 'site' , 'locale_path' ));
2008-07-31 03:04:33 +01:00
bind_textdomain_codeset ( " laconica " , " UTF-8 " );
2008-07-30 04:54:46 +01:00
textdomain ( " laconica " );
2008-08-06 05:04:33 +01:00
setlocale ( LC_CTYPE , 'C' );
}
define ( 'PAGE_TYPE_PREFS' , 'text/html,application/xhtml+xml,application/xml;q=0.3,text/xml;q=0.2' );
function common_show_header ( $pagetitle , $callable = NULL , $data = NULL , $headercall = NULL ) {
2008-09-18 14:56:08 +01:00
2008-08-06 05:04:33 +01:00
global $config , $xw ;
2008-09-18 14:56:08 +01:00
common_start_html ();
2008-05-20 14:05:35 +01:00
common_element_start ( 'head' );
2008-05-20 20:14:12 +01:00
common_element ( 'title' , NULL ,
2008-05-20 14:05:35 +01:00
$pagetitle . " - " . $config [ 'site' ][ 'name' ]);
2008-05-20 18:34:27 +01:00
common_element ( 'link' , array ( 'rel' => 'stylesheet' ,
'type' => 'text/css' ,
2008-06-10 19:52:38 +01:00
'href' => theme_path ( 'display.css' ),
2008-05-20 18:34:27 +01:00
'media' => 'screen, projection, tv' ));
2008-06-10 19:52:38 +01:00
foreach ( array ( 6 , 7 ) as $ver ) {
if ( file_exists ( theme_file ( 'ie' . $ver . '.css' ))) {
# Yes, IE people should be put in jail.
$xw -> writeComment ( '[if lte IE ' . $ver . ']><link rel="stylesheet" type="text/css" ' .
2008-06-24 18:13:05 +01:00
'href="' . theme_path ( 'ie' . $ver . '.css' ) . '" /><![endif]' );
2008-06-10 19:52:38 +01:00
}
}
2008-06-20 07:56:19 +01:00
2008-06-17 05:36:50 +01:00
common_element ( 'script' , array ( 'type' => 'text/javascript' ,
2008-06-17 05:40:54 +01:00
'src' => common_path ( 'js/jquery.min.js' )),
2008-06-17 05:36:50 +01:00
' ' );
2008-09-08 22:16:10 +01:00
common_element ( 'script' , array ( 'type' => 'text/javascript' ,
'src' => common_path ( 'js/jquery.form.js' )),
' ' );
2008-06-24 18:46:13 +01:00
common_element ( 'script' , array ( 'type' => 'text/javascript' ,
'src' => common_path ( 'js/util.js' )),
' ' );
2008-07-20 02:58:23 +01:00
common_element ( 'link' , array ( 'rel' => 'search' , 'type' => 'application/opensearchdescription+xml' ,
2008-07-20 20:55:05 +01:00
'href' => common_local_url ( 'opensearch' , array ( 'type' => 'people' )),
'title' => common_config ( 'site' , 'name' ) . ' People Search' ));
common_element ( 'link' , array ( 'rel' => 'search' , 'type' => 'application/opensearchdescription+xml' ,
'href' => common_local_url ( 'opensearch' , array ( 'type' => 'notice' )),
'title' => common_config ( 'site' , 'name' ) . ' Notice Search' ));
2008-06-20 07:56:19 +01:00
2008-05-21 16:24:04 +01:00
if ( $callable ) {
if ( $data ) {
call_user_func ( $callable , $data );
} else {
call_user_func ( $callable );
}
}
2008-05-20 14:05:35 +01:00
common_element_end ( 'head' );
common_element_start ( 'body' );
2008-06-10 19:52:38 +01:00
common_element_start ( 'div' , array ( 'id' => 'wrap' ));
2008-05-20 20:14:12 +01:00
common_element_start ( 'div' , array ( 'id' => 'header' ));
2008-06-10 19:52:38 +01:00
common_nav_menu ();
2008-07-20 03:32:59 +01:00
if (( isset ( $config [ 'site' ][ 'logo' ]) && is_string ( $config [ 'site' ][ 'logo' ]) && ( strlen ( $config [ 'site' ][ 'logo' ]) > 0 ))
2008-06-18 16:30:36 +01:00
|| file_exists ( theme_file ( 'logo.png' )))
{
2008-06-13 16:46:32 +01:00
common_element_start ( 'a' , array ( 'href' => common_local_url ( 'public' )));
2008-07-20 03:32:59 +01:00
common_element ( 'img' , array ( 'src' => isset ( $config [ 'site' ][ 'logo' ]) ?
2008-06-13 16:46:32 +01:00
( $config [ 'site' ][ 'logo' ]) : theme_path ( 'logo.png' ),
'alt' => $config [ 'site' ][ 'name' ],
'id' => 'logo' ));
common_element_end ( 'a' );
2008-06-18 16:20:04 +01:00
} else {
2008-06-18 16:46:43 +01:00
common_element_start ( 'p' , array ( 'id' => 'branding' ));
common_element ( 'a' , array ( 'href' => common_local_url ( 'public' )),
$config [ 'site' ][ 'name' ]);
common_element_end ( 'p' );
2008-06-13 16:46:32 +01:00
}
2008-06-20 07:56:19 +01:00
2008-06-13 16:46:32 +01:00
common_element ( 'h1' , 'pagetitle' , $pagetitle );
2008-06-20 07:56:19 +01:00
2008-06-11 19:36:34 +01:00
if ( $headercall ) {
if ( $data ) {
call_user_func ( $headercall , $data );
} else {
call_user_func ( $headercall );
}
}
2008-05-20 18:34:27 +01:00
common_element_end ( 'div' );
2008-06-10 19:52:38 +01:00
common_element_start ( 'div' , array ( 'id' => 'content' ));
2008-05-20 14:05:35 +01:00
}
2008-09-18 14:56:08 +01:00
function common_start_html ( $type = NULL ) {
if ( ! $type ) {
$httpaccept = isset ( $_SERVER [ 'HTTP_ACCEPT' ]) ? $_SERVER [ 'HTTP_ACCEPT' ] : NULL ;
# XXX: allow content negotiation for RDF, RSS, or XRDS
$type = common_negotiate_type ( common_accept_to_prefs ( $httpaccept ),
common_accept_to_prefs ( PAGE_TYPE_PREFS ));
if ( ! $type ) {
common_user_error ( _ ( 'This page is not available in a media type you accept' ), 406 );
exit ( 0 );
}
}
header ( 'Content-Type: ' . $type );
common_start_xml ( 'html' ,
'-//W3C//DTD XHTML 1.0 Strict//EN' ,
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' );
# FIXME: correct language for interface
$language = common_language ();
common_element_start ( 'html' , array ( 'xmlns' => 'http://www.w3.org/1999/xhtml' ,
'xml:lang' => $language ,
'lang' => $language ));
}
2008-05-20 14:05:35 +01:00
function common_show_footer () {
2008-05-20 18:13:53 +01:00
global $xw , $config ;
2008-06-10 19:52:38 +01:00
common_element_end ( 'div' ); # content div
2008-05-20 14:05:35 +01:00
common_foot_menu ();
2008-06-10 20:55:02 +01:00
common_element_start ( 'div' , array ( 'id' => 'footer' ));
2008-07-02 14:15:07 +01:00
common_element_start ( 'div' , 'laconica' );
2008-07-01 18:56:11 +01:00
if ( common_config ( 'site' , 'broughtby' )) {
2008-07-08 10:45:31 +01:00
$instr = _ ( '**%%site.name%%** is a microblogging service brought to you by [%%site.broughtby%%](%%site.broughtbyurl%%). ' );
2008-07-01 18:56:11 +01:00
} else {
2008-07-08 10:45:31 +01:00
$instr = _ ( '**%%site.name%%** is a microblogging service. ' );
2008-07-01 18:56:11 +01:00
}
2008-07-14 07:05:17 +01:00
$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 );
2008-07-01 18:56:11 +01:00
$output = common_markup_to_html ( $instr );
common_raw ( $output );
2008-07-02 14:15:07 +01:00
common_element_end ( 'div' );
2008-06-10 20:55:02 +01:00
common_element ( 'img' , array ( 'id' => 'cc' ,
2008-06-10 20:51:34 +01:00
'src' => $config [ 'license' ][ 'image' ],
'alt' => $config [ 'license' ][ 'title' ]));
common_element_start ( 'p' );
2008-07-08 10:45:31 +01:00
common_text ( _ ( 'Unless otherwise specified, contents of this site are copyright by the contributors and available under the ' ));
2008-06-10 20:51:34 +01:00
common_element ( 'a' , array ( 'class' => 'license' ,
'rel' => 'license' ,
2008-07-20 03:35:10 +01:00
'href' => $config [ 'license' ][ 'url' ]),
2008-06-10 20:51:34 +01:00
$config [ 'license' ][ 'title' ]);
2008-07-08 10:45:31 +01:00
common_text ( _ ( '. Contributors should be attributed by full name or nickname.' ));
2008-06-10 20:51:34 +01:00
common_element_end ( 'p' );
2008-05-20 22:04:37 +01:00
common_element_end ( 'div' );
2008-05-20 18:34:27 +01:00
common_element_end ( 'div' );
2008-05-20 14:05:35 +01:00
common_element_end ( 'body' );
common_element_end ( 'html' );
2008-05-21 15:33:51 +01:00
common_end_xml ();
2008-05-20 14:05:35 +01:00
}
2008-05-20 18:13:53 +01:00
function common_text ( $txt ) {
global $xw ;
$xw -> text ( $txt );
}
2008-05-28 19:27:07 +01:00
function common_raw ( $xml ) {
global $xw ;
$xw -> writeRaw ( $xml );
}
2008-06-10 19:52:38 +01:00
function common_nav_menu () {
2008-05-20 14:05:35 +01:00
$user = common_current_user ();
2008-06-10 19:52:38 +01:00
common_element_start ( 'ul' , array ( 'id' => 'nav' ));
2008-06-11 02:56:09 +01:00
if ( $user ) {
common_menu_item ( common_local_url ( 'all' , array ( 'nickname' => $user -> nickname )),
2008-07-08 10:45:31 +01:00
_ ( 'Home' ));
2008-06-11 02:56:09 +01:00
}
2008-07-10 05:51:26 +01:00
common_menu_item ( common_local_url ( 'peoplesearch' ), _ ( 'Search' ));
2008-07-20 06:57:02 +01:00
common_menu_item ( common_local_url ( 'tags' ), _ ( 'Tags' ));
2008-05-20 14:05:35 +01:00
if ( $user ) {
common_menu_item ( common_local_url ( 'profilesettings' ),
2008-07-08 10:45:31 +01:00
_ ( 'Settings' ));
2008-08-25 20:32:35 +01:00
common_menu_item ( common_local_url ( 'invite' ),
_ ( 'Invite' ));
2008-05-20 14:05:35 +01:00
common_menu_item ( common_local_url ( 'logout' ),
2008-07-08 10:45:31 +01:00
_ ( 'Logout' ));
2008-05-20 14:05:35 +01:00
} else {
2008-07-08 10:45:31 +01:00
common_menu_item ( common_local_url ( 'login' ), _ ( 'Login' ));
2008-07-25 00:58:04 +01:00
if ( ! common_config ( 'site' , 'closed' )) {
common_menu_item ( common_local_url ( 'register' ), _ ( 'Register' ));
}
2008-07-08 10:45:31 +01:00
common_menu_item ( common_local_url ( 'openidlogin' ), _ ( 'OpenID' ));
2008-05-20 14:05:35 +01:00
}
common_element_end ( 'ul' );
}
function common_foot_menu () {
2008-06-10 19:57:59 +01:00
common_element_start ( 'ul' , array ( 'id' => 'nav_sub' ));
2008-07-31 03:09:33 +01:00
common_menu_item ( common_local_url ( 'doc' , array ( 'title' => 'help' )),
_ ( 'Help' ));
2008-05-20 14:05:35 +01:00
common_menu_item ( common_local_url ( 'doc' , array ( 'title' => 'about' )),
2008-07-08 10:45:31 +01:00
_ ( 'About' ));
2008-06-30 17:12:01 +01:00
common_menu_item ( common_local_url ( 'doc' , array ( 'title' => 'faq' )),
2008-07-08 10:45:31 +01:00
_ ( 'FAQ' ));
2008-05-20 14:05:35 +01:00
common_menu_item ( common_local_url ( 'doc' , array ( 'title' => 'privacy' )),
2008-07-08 10:45:31 +01:00
_ ( 'Privacy' ));
2008-05-22 18:20:06 +01:00
common_menu_item ( common_local_url ( 'doc' , array ( 'title' => 'source' )),
2008-07-08 10:45:31 +01:00
_ ( 'Source' ));
2008-07-01 18:56:11 +01:00
common_menu_item ( common_local_url ( 'doc' , array ( 'title' => 'contact' )),
2008-07-08 10:45:31 +01:00
_ ( 'Contact' ));
2008-05-20 21:30:02 +01:00
common_element_end ( 'ul' );
2008-05-20 14:05:35 +01:00
}
2008-06-11 16:56:49 +01:00
function common_menu_item ( $url , $text , $title = NULL , $is_selected = false ) {
2008-06-11 16:52:58 +01:00
$lattrs = array ();
if ( $is_selected ) {
$lattrs [ 'class' ] = 'current' ;
}
common_element_start ( 'li' , $lattrs );
2008-05-20 14:05:35 +01:00
$attrs [ 'href' ] = $url ;
if ( $title ) {
$attrs [ 'title' ] = $title ;
}
common_element ( 'a' , $attrs , $text );
common_element_end ( 'li' );
}
2008-06-12 17:52:01 +01:00
function common_input ( $id , $label , $value = NULL , $instructions = NULL ) {
2008-05-20 18:47:59 +01:00
common_element_start ( 'p' );
2008-05-20 14:05:35 +01:00
common_element ( 'label' , array ( 'for' => $id ), $label );
$attrs = array ( 'name' => $id ,
'type' => 'text' ,
2008-06-27 15:55:53 +01:00
'class' => 'input_text' ,
2008-05-20 14:05:35 +01:00
'id' => $id );
if ( $value ) {
$attrs [ 'value' ] = htmlspecialchars ( $value );
}
common_element ( 'input' , $attrs );
2008-06-12 17:52:01 +01:00
if ( $instructions ) {
common_element ( 'span' , 'input_instructions' , $instructions );
}
2008-05-20 18:51:05 +01:00
common_element_end ( 'p' );
2008-05-20 14:05:35 +01:00
}
2008-06-26 19:27:05 +01:00
function common_checkbox ( $id , $label , $checked = false , $instructions = NULL , $value = 'true' )
2008-06-24 01:15:23 +01:00
{
common_element_start ( 'p' );
$attrs = array ( 'name' => $id ,
'type' => 'checkbox' ,
2008-06-27 15:55:53 +01:00
'class' => 'checkbox' ,
2008-06-26 19:27:05 +01:00
'id' => $id );
2008-06-24 01:15:23 +01:00
if ( $value ) {
$attrs [ 'value' ] = htmlspecialchars ( $value );
}
2008-06-26 19:27:05 +01:00
if ( $checked ) {
$attrs [ 'checked' ] = 'checked' ;
}
2008-06-26 19:22:31 +01:00
common_element ( 'input' , $attrs );
# XXX: use a <label>
common_text ( ' ' );
common_element ( 'span' , 'checkbox_label' , $label );
common_text ( ' ' );
2008-06-24 01:15:23 +01:00
if ( $instructions ) {
common_element ( 'span' , 'input_instructions' , $instructions );
}
common_element_end ( 'p' );
}
2008-07-19 01:34:17 +01:00
function common_dropdown ( $id , $label , $content , $instructions = NULL , $blank_select = FALSE , $selected = NULL ) {
2008-07-20 11:00:24 +01:00
common_element_start ( 'p' );
common_element ( 'label' , array ( 'for' => $id ), $label );
common_element_start ( 'select' , array ( 'id' => $id , 'name' => $id ));
if ( $blank_select ) {
common_element ( 'option' , array ( 'value' => '' ));
}
foreach ( $content as $value => $option ) {
if ( $value == $selected ) {
common_element ( 'option' , array ( 'value' => $value , 'selected' => $value ), $option );
} else {
common_element ( 'option' , array ( 'value' => $value ), $option );
}
}
common_element_end ( 'select' );
2008-07-19 01:34:17 +01:00
if ( $instructions ) {
common_element ( 'span' , 'input_instructions' , $instructions );
}
common_element_end ( 'p' );
}
2008-05-30 18:43:10 +01:00
function common_hidden ( $id , $value ) {
common_element ( 'input' , array ( 'name' => $id ,
'type' => 'hidden' ,
'id' => $id ,
'value' => $value ));
}
2008-06-12 17:52:01 +01:00
function common_password ( $id , $label , $instructions = NULL ) {
2008-05-20 18:47:59 +01:00
common_element_start ( 'p' );
2008-05-20 14:05:35 +01:00
common_element ( 'label' , array ( 'for' => $id ), $label );
$attrs = array ( 'name' => $id ,
'type' => 'password' ,
2008-06-27 15:55:53 +01:00
'class' => 'password' ,
2008-05-20 14:05:35 +01:00
'id' => $id );
common_element ( 'input' , $attrs );
2008-06-12 17:52:01 +01:00
if ( $instructions ) {
common_element ( 'span' , 'input_instructions' , $instructions );
}
2008-05-20 18:51:05 +01:00
common_element_end ( 'p' );
2008-05-20 18:47:59 +01:00
}
2008-09-08 19:35:15 +01:00
function common_submit ( $id , $label , $cls = 'submit' ) {
2008-05-20 19:06:40 +01:00
global $xw ;
2008-05-20 18:47:59 +01:00
common_element_start ( 'p' );
common_element ( 'input' , array ( 'type' => 'submit' ,
'id' => $id ,
'name' => $id ,
2008-09-08 19:35:15 +01:00
'class' => $cls ,
2008-06-11 02:56:09 +01:00
'value' => $label ));
2008-05-20 18:51:05 +01:00
common_element_end ( 'p' );
2008-05-20 14:05:35 +01:00
}
2008-06-12 17:52:01 +01:00
function common_textarea ( $id , $label , $content = NULL , $instructions = NULL ) {
2008-05-20 22:19:45 +01:00
common_element_start ( 'p' );
common_element ( 'label' , array ( 'for' => $id ), $label );
2008-06-18 04:00:19 +01:00
common_element ( 'textarea' , array ( 'rows' => 3 ,
'cols' => 40 ,
'name' => $id ,
'id' => $id ),
2008-07-02 14:15:07 +01:00
( $content ) ? $content : '' );
2008-06-12 17:52:01 +01:00
if ( $instructions ) {
common_element ( 'span' , 'input_instructions' , $instructions );
}
2008-05-20 22:19:45 +01:00
common_element_end ( 'p' );
}
2008-07-20 15:13:25 +01:00
function common_timezone () {
if ( common_logged_in ()) {
$user = common_current_user ();
if ( $user -> timezone ) {
return $user -> timezone ;
}
}
global $config ;
return $config [ 'site' ][ 'timezone' ];
}
2008-07-19 01:34:17 +01:00
function common_language () {
$httplang = isset ( $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ]) ? $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ] : NULL ;
$language = array ();
$user_language = FALSE ;
if ( common_logged_in ()) {
$user = common_current_user ();
$user_language = $user -> language ;
}
if ( $user_language ) {
return $user_language ;
} else if ( ! empty ( $httplang )) {
$language = client_prefered_language ( $httplang );
if ( $language ) {
return $language ;
}
} else {
2008-09-16 18:27:06 +01:00
return $config [ 'site' ][ 'language' ];
2008-07-19 01:34:17 +01:00
}
}
2008-05-20 14:05:35 +01:00
# salted, hashed passwords are stored in the DB
2008-06-18 22:14:54 +01:00
function common_munge_password ( $password , $id ) {
return md5 ( $password . $id );
2008-05-20 14:05:35 +01:00
}
# check if a username exists and has matching password
function common_check_user ( $nickname , $password ) {
2008-08-25 19:52:45 +01:00
# NEVER allow blank passwords, even if they match the DB
if ( mb_strlen ( $password ) == 0 ) {
return false ;
}
2008-05-20 14:05:35 +01:00
$user = User :: staticGet ( 'nickname' , $nickname );
if ( is_null ( $user )) {
return false ;
} else {
2008-07-09 06:53:43 +01:00
if ( 0 == strcmp ( common_munge_password ( $password , $user -> id ),
$user -> password )) {
return $user ;
} else {
return false ;
}
2008-05-20 14:05:35 +01:00
}
}
# is the current user logged in?
function common_logged_in () {
return ( ! is_null ( common_current_user ()));
}
function common_have_session () {
return ( 0 != strcmp ( session_id (), '' ));
}
function common_ensure_session () {
if ( ! common_have_session ()) {
@ session_start ();
}
}
2008-07-09 06:53:43 +01:00
# Three kinds of arguments:
# 1) a user object
# 2) a nickname
# 3) NULL to clear
function common_set_user ( $user ) {
2008-07-09 07:25:02 +01:00
if ( is_null ( $user ) && common_have_session ()) {
2008-05-20 14:05:35 +01:00
unset ( $_SESSION [ 'userid' ]);
return true ;
2008-07-09 06:53:43 +01:00
} else if ( is_string ( $user )) {
$nickname = $user ;
2008-05-20 14:05:35 +01:00
$user = User :: staticGet ( 'nickname' , $nickname );
2008-07-09 06:53:43 +01:00
} else if ( ! ( $user instanceof User )) {
return false ;
}
2008-07-09 23:46:30 +01:00
2008-07-09 06:53:43 +01:00
if ( $user ) {
common_ensure_session ();
$_SESSION [ 'userid' ] = $user -> id ;
return $user ;
2008-05-20 14:05:35 +01:00
}
return false ;
}
2008-06-24 04:08:34 +01:00
function common_set_cookie ( $key , $value , $expiration = 0 ) {
2008-06-24 03:52:34 +01:00
$path = common_config ( 'site' , 'path' );
$server = common_config ( 'site' , 'server' );
if ( $path && ( $path != '/' )) {
$cookiepath = '/' . $path . '/' ;
} else {
$cookiepath = '/' ;
}
return setcookie ( $key ,
$value ,
$expiration ,
$cookiepath ,
$server );
}
define ( 'REMEMBERME' , 'rememberme' );
2008-06-24 04:24:08 +01:00
define ( 'REMEMBERME_EXPIRY' , 30 * 24 * 60 * 60 );
2008-06-24 03:52:34 +01:00
2008-07-09 06:53:43 +01:00
function common_rememberme ( $user = NULL ) {
2008-06-24 03:52:34 +01:00
if ( ! $user ) {
2008-07-09 06:53:43 +01:00
$user = common_current_user ();
if ( ! $user ) {
common_debug ( 'No current user to remember' , __FILE__ );
return false ;
}
2008-06-24 03:52:34 +01:00
}
$rm = new Remember_me ();
$rm -> code = common_good_rand ( 16 );
2008-06-24 04:17:46 +01:00
$rm -> user_id = $user -> id ;
2008-06-24 04:24:08 +01:00
$result = $rm -> insert ();
if ( ! $result ) {
2008-06-24 03:52:34 +01:00
common_log_db_error ( $rm , 'INSERT' , __FILE__ );
2008-07-09 06:19:43 +01:00
common_debug ( 'Error adding rememberme record for ' . $user -> nickname , __FILE__ );
2008-06-24 03:52:34 +01:00
return false ;
}
2008-07-08 07:42:41 +01:00
common_log ( LOG_INFO , 'adding rememberme cookie for ' . $user -> nickname );
2008-06-24 03:52:34 +01:00
common_set_cookie ( REMEMBERME ,
2008-06-24 04:32:23 +01:00
implode ( ':' , array ( $rm -> user_id , $rm -> code )),
2008-06-24 03:52:34 +01:00
time () + REMEMBERME_EXPIRY );
2008-07-05 17:21:42 +01:00
return true ;
2008-06-24 03:52:34 +01:00
}
function common_remembered_user () {
$user = NULL ;
# Try to remember
2008-07-20 06:55:58 +01:00
$packed = isset ( $_COOKIE [ REMEMBERME ]) ? $_COOKIE [ REMEMBERME ] : '' ;
2008-06-24 03:52:34 +01:00
if ( $packed ) {
list ( $id , $code ) = explode ( ':' , $packed );
if ( $id && $code ) {
$rm = Remember_me :: staticGet ( $code );
2008-06-24 05:00:58 +01:00
if ( $rm && ( $rm -> user_id == $id )) {
2008-06-24 05:02:34 +01:00
$user = User :: staticGet ( $rm -> user_id );
2008-06-24 03:52:34 +01:00
if ( $user ) {
# successful!
$result = $rm -> delete ();
if ( ! $result ) {
common_log_db_error ( $rm , 'DELETE' , __FILE__ );
$user = NULL ;
} else {
2008-07-08 07:42:41 +01:00
common_log ( LOG_INFO , 'logging in ' . $user -> nickname . ' using rememberme code ' . $rm -> code );
2008-06-24 04:28:18 +01:00
common_set_user ( $user -> nickname );
2008-06-24 03:52:34 +01:00
common_real_login ( false );
2008-06-24 04:10:57 +01:00
# We issue a new cookie, so they can log in
# automatically again after this session
2008-07-09 06:53:43 +01:00
common_rememberme ( $user );
2008-06-24 03:52:34 +01:00
}
}
}
}
}
return $user ;
}
# must be called with a valid user!
function common_forgetme () {
common_set_cookie ( REMEMBERME , '' , 0 );
}
2008-05-20 14:05:35 +01:00
# who is the current user?
function common_current_user () {
2008-07-20 06:55:58 +01:00
if ( isset ( $_REQUEST [ session_name ()]) || ( isset ( $_SESSION [ 'userid' ]) && $_SESSION [ 'userid' ])) {
2008-06-24 04:49:06 +01:00
common_ensure_session ();
2008-07-20 10:49:17 +01:00
$id = isset ( $_SESSION [ 'userid' ]) ? $_SESSION [ 'userid' ] : false ;
2008-06-24 04:49:06 +01:00
if ( $id ) {
# note: this should cache
$user = User :: staticGet ( $id );
return $user ;
}
2008-05-20 14:05:35 +01:00
}
2008-06-24 03:52:34 +01:00
# that didn't work; try to remember
$user = common_remembered_user ();
2008-07-14 06:00:37 +01:00
if ( $user ) {
2008-07-20 06:55:58 +01:00
common_debug ( " Got User " . $user -> nickname );
2008-07-14 06:00:37 +01:00
common_debug ( " Faking session on remembered user " );
$_SESSION [ 'userid' ] = $user -> id ;
}
2008-05-20 14:05:35 +01:00
return $user ;
}
2008-06-24 03:52:34 +01:00
# Logins that are 'remembered' aren't 'real' -- they're subject to
# cookie-stealing. So, we don't let them do certain things. New reg,
# OpenID, and password logins _are_ real.
function common_real_login ( $real = true ) {
common_ensure_session ();
$_SESSION [ 'real_login' ] = $real ;
}
function common_is_real_login () {
return common_logged_in () && $_SESSION [ 'real_login' ];
}
2008-05-20 14:05:35 +01:00
# get canonical version of nickname for comparison
function common_canonical_nickname ( $nickname ) {
# XXX: UTF-8 canonicalization (like combining chars)
2008-06-11 15:18:24 +01:00
return strtolower ( $nickname );
2008-05-20 14:05:35 +01:00
}
# get canonical version of email for comparison
function common_canonical_email ( $email ) {
# XXX: canonicalize UTF-8
# XXX: lcase the domain part
return $email ;
}
2008-05-29 19:12:44 +01:00
define ( 'URL_REGEX' , '^|[ \t\r\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))' );
2008-05-29 18:25:49 +01:00
function common_render_content ( $text , $notice ) {
2008-09-17 12:27:30 +01:00
$r = common_render_text ( $text );
$id = $notice -> profile_id ;
$r = preg_replace ( '/(^|\s+)@([A-Za-z0-9]{1,64})/e' , " ' \\ 1@'.common_at_link( $id , ' \\ 2') " , $r );
$r = preg_replace ( '/^T ([A-Z0-9]{1,64}) /e' , " 'T '.common_at_link( $id , ' \\ 1').' ' " , $r );
return $r ;
}
function common_render_text ( $text ) {
2008-05-29 18:08:01 +01:00
$r = htmlspecialchars ( $text );
2008-07-20 13:28:32 +01:00
$r = preg_replace ( '/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/' , '' , $r );
2008-07-15 03:20:45 +01:00
$r = preg_replace ( '@https?://[^)\]>\s]+@' , '<a href="\0" class="extlink">\0</a>' , $r );
2008-09-01 03:59:32 +01:00
$r = preg_replace ( '/(^|\s+)#([A-Za-z0-9_\-\.]{1,64})/e' , " ' \\ 1#'.common_tag_link(' \\ 2') " , $r );
2008-05-20 14:05:35 +01:00
# XXX: machine tags
2008-05-29 18:08:01 +01:00
return $r ;
}
2008-07-20 06:57:02 +01:00
function common_tag_link ( $tag ) {
2008-09-17 12:22:34 +01:00
$canonical = common_canonical_tag ( $tag );
$url = common_local_url ( 'tag' , array ( 'tag' => $canonical ));
return '<a href="' . htmlspecialchars ( $url ) . '" rel="tag" class="hashlink">' . htmlspecialchars ( $tag ) . '</a>' ;
}
function common_canonical_tag ( $tag ) {
return strtolower ( str_replace ( array ( '-' , '_' , '.' ), '' , $tag ));
2008-07-20 06:57:02 +01:00
}
2008-05-29 18:18:53 +01:00
function common_at_link ( $sender_id , $nickname ) {
2008-07-07 06:43:58 +01:00
$sender = Profile :: staticGet ( $sender_id );
2008-09-04 23:41:29 +01:00
$recipient = common_relative_profile ( $sender , common_canonical_nickname ( $nickname ));
2008-07-07 06:43:58 +01:00
if ( $recipient ) {
return '<a href="' . htmlspecialchars ( $recipient -> profileurl ) . '" class="atlink">' . $nickname . '</a>' ;
} else {
return $nickname ;
}
}
2008-07-07 07:07:33 +01:00
function common_relative_profile ( $sender , $nickname , $dt = NULL ) {
2008-05-29 18:08:01 +01:00
# Try to find profiles this profile is subscribed to that have this nickname
2008-05-29 18:18:53 +01:00
$recipient = new Profile ();
2008-07-07 06:43:58 +01:00
# XXX: use a join instead of a subquery
2008-07-20 06:55:58 +01:00
$recipient -> whereAdd ( 'EXISTS (SELECT subscribed from subscription where subscriber = ' . $sender -> id . ' and subscribed = id)' , 'AND' );
2008-05-29 18:18:53 +01:00
$recipient -> whereAdd ( 'nickname = "' . trim ( $nickname ) . '"' , 'AND' );
if ( $recipient -> find ( TRUE )) {
2008-07-07 06:43:58 +01:00
# XXX: should probably differentiate between profiles with
# the same name by date of most recent update
return $recipient ;
2008-05-29 18:08:01 +01:00
}
# Try to find profiles that listen to this profile and that have this nickname
2008-05-29 18:18:53 +01:00
$recipient = new Profile ();
2008-07-07 06:43:58 +01:00
# XXX: use a join instead of a subquery
2008-07-20 06:55:58 +01:00
$recipient -> whereAdd ( 'EXISTS (SELECT subscriber from subscription where subscribed = ' . $sender -> id . ' and subscriber = id)' , 'AND' );
2008-05-29 18:18:53 +01:00
$recipient -> whereAdd ( 'nickname = "' . trim ( $nickname ) . '"' , 'AND' );
if ( $recipient -> find ( TRUE )) {
2008-07-07 06:43:58 +01:00
# XXX: should probably differentiate between profiles with
# the same name by date of most recent update
return $recipient ;
2008-05-29 18:08:01 +01:00
}
# If this is a local user, try to find a local user with that nickname.
2008-07-07 06:43:58 +01:00
$sender = User :: staticGet ( $sender -> id );
2008-05-29 18:08:01 +01:00
if ( $sender ) {
2008-05-29 18:18:53 +01:00
$recipient_user = User :: staticGet ( 'nickname' , $nickname );
if ( $recipient_user ) {
2008-07-07 06:43:58 +01:00
return $recipient_user -> getProfile ();
2008-05-29 18:08:01 +01:00
}
}
# Otherwise, no links. @messages from local users to remote users,
# or from remote users to other remote users, are just
# outside our ability to make intelligent guesses about
2008-07-07 06:43:58 +01:00
return NULL ;
2008-05-20 14:05:35 +01:00
}
// where should the avatar go for this user?
2008-06-05 20:37:08 +01:00
function common_avatar_filename ( $id , $extension , $size = NULL , $extra = NULL ) {
2008-05-20 14:05:35 +01:00
global $config ;
if ( $size ) {
2008-06-05 20:37:08 +01:00
return $id . '-' . $size . (( $extra ) ? ( '-' . $extra ) : '' ) . $extension ;
2008-05-20 14:05:35 +01:00
} else {
2008-06-05 20:37:08 +01:00
return $id . '-original' . (( $extra ) ? ( '-' . $extra ) : '' ) . $extension ;
2008-05-20 14:05:35 +01:00
}
}
function common_avatar_path ( $filename ) {
global $config ;
2008-05-30 17:24:29 +01:00
return INSTALLDIR . '/avatar/' . $filename ;
2008-05-20 14:05:35 +01:00
}
function common_avatar_url ( $filename ) {
2008-05-30 17:24:29 +01:00
return common_path ( 'avatar/' . $filename );
2008-07-03 18:03:47 +01:00
}
function common_avatar_display_url ( $avatar ) {
$server = common_config ( 'avatar' , 'server' );
if ( $server ) {
return 'http://' . $server . '/' . $avatar -> filename ;
} else {
return $avatar -> url ;
}
2008-05-20 14:05:35 +01:00
}
2008-05-21 16:54:48 +01:00
function common_default_avatar ( $size ) {
static $sizenames = array ( AVATAR_PROFILE_SIZE => 'profile' ,
AVATAR_STREAM_SIZE => 'stream' ,
AVATAR_MINI_SIZE => 'mini' );
2008-06-11 20:02:30 +01:00
return theme_path ( 'default-avatar-' . $sizenames [ $size ] . '.png' );
2008-05-21 16:54:48 +01:00
}
2008-05-20 14:05:35 +01:00
function common_local_url ( $action , $args = NULL ) {
2008-05-30 22:25:55 +01:00
global $config ;
if ( $config [ 'site' ][ 'fancy' ]) {
return common_fancy_url ( $action , $args );
} else {
return common_simple_url ( $action , $args );
}
}
function common_fancy_url ( $action , $args = NULL ) {
switch ( strtolower ( $action )) {
2008-06-06 21:01:51 +01:00
case 'public' :
2008-07-20 04:32:36 +01:00
if ( $args && isset ( $args [ 'page' ])) {
2008-06-15 04:50:12 +01:00
return common_path ( '?page=' . $args [ 'page' ]);
} else {
return common_path ( '' );
}
2008-06-06 21:01:51 +01:00
case 'publicrss' :
return common_path ( 'rss' );
2008-06-18 19:26:47 +01:00
case 'publicxrds' :
return common_path ( 'xrds' );
2008-07-20 02:58:23 +01:00
case 'opensearch' :
2008-07-20 20:55:05 +01:00
if ( $args && $args [ 'type' ]) {
return common_path ( 'opensearch/' . $args [ 'type' ]);
} else {
return common_path ( 'opensearch/people' );
}
2008-06-06 21:01:51 +01:00
case 'doc' :
return common_path ( 'doc/' . $args [ 'title' ]);
case 'login' :
case 'logout' :
case 'subscribe' :
case 'unsubscribe' :
2008-08-25 20:34:50 +01:00
case 'invite' :
2008-06-06 21:01:51 +01:00
return common_path ( 'main/' . $action );
2008-08-27 01:19:27 +01:00
case 'register' :
if ( $args && $args [ 'code' ]) {
return common_path ( 'main/register/' . $args [ 'code' ]);
} else {
return common_path ( 'main/register' );
}
2008-07-01 17:40:58 +01:00
case 'remotesubscribe' :
if ( $args && $args [ 'nickname' ]) {
return common_path ( 'main/remote?nickname=' . $args [ 'nickname' ]);
} else {
return common_path ( 'main/remote' );
}
2008-06-18 17:07:33 +01:00
case 'openidlogin' :
return common_path ( 'main/openid' );
2008-06-06 21:01:51 +01:00
case 'profilesettings' :
return common_path ( 'settings/profile' );
2008-07-15 23:18:26 +01:00
case 'emailsettings' :
return common_path ( 'settings/email' );
2008-06-18 17:13:21 +01:00
case 'openidsettings' :
return common_path ( 'settings/openid' );
2008-07-21 09:37:58 +01:00
case 'smssettings' :
return common_path ( 'settings/sms' );
2008-08-22 04:41:57 +01:00
case 'twittersettings' :
return common_path ( 'settings/twitter' );
2008-06-06 21:01:51 +01:00
case 'newnotice' :
2008-07-09 08:28:33 +01:00
if ( $args && $args [ 'replyto' ]) {
return common_path ( 'notice/new?replyto=' . $args [ 'replyto' ]);
} else {
return common_path ( 'notice/new' );
}
2008-06-06 21:01:51 +01:00
case 'shownotice' :
return common_path ( 'notice/' . $args [ 'notice' ]);
2008-07-16 04:20:45 +01:00
case 'deletenotice' :
if ( $args && $args [ 'notice' ]) {
2008-07-26 04:42:09 +01:00
return common_path ( 'notice/delete/' . $args [ 'notice' ]);
2008-07-16 04:20:45 +01:00
} else {
2008-07-26 04:42:09 +01:00
return common_path ( 'notice/delete' );
2008-07-16 04:20:45 +01:00
}
2008-06-20 07:56:19 +01:00
case 'xrds' :
2008-06-10 13:11:32 +01:00
case 'foaf' :
2008-06-06 21:01:51 +01:00
return common_path ( $args [ 'nickname' ] . '/' . $action );
2008-06-15 04:50:12 +01:00
case 'subscriptions' :
2008-06-18 18:16:22 +01:00
case 'subscribers' :
2008-06-15 04:50:12 +01:00
case 'all' :
2008-07-07 04:23:48 +01:00
case 'replies' :
2008-09-16 20:53:46 +01:00
case 'inbox' :
case 'outbox' :
2008-07-20 03:32:59 +01:00
if ( $args && isset ( $args [ 'page' ])) {
2008-06-15 04:50:12 +01:00
return common_path ( $args [ 'nickname' ] . '/' . $action . '?page=' . $args [ 'page' ]);
} else {
return common_path ( $args [ 'nickname' ] . '/' . $action );
}
2008-06-06 21:01:51 +01:00
case 'allrss' :
return common_path ( $args [ 'nickname' ] . '/all/rss' );
2008-07-07 08:30:25 +01:00
case 'repliesrss' :
return common_path ( $args [ 'nickname' ] . '/replies/rss' );
2008-06-06 21:01:51 +01:00
case 'userrss' :
return common_path ( $args [ 'nickname' ] . '/rss' );
case 'showstream' :
2008-07-20 03:55:46 +01:00
if ( $args && isset ( $args [ 'page' ])) {
2008-06-15 04:50:12 +01:00
return common_path ( $args [ 'nickname' ] . '?page=' . $args [ 'page' ]);
} else {
return common_path ( $args [ 'nickname' ]);
}
2008-06-22 16:52:50 +01:00
case 'confirmaddress' :
return common_path ( 'main/confirmaddress/' . $args [ 'code' ]);
2008-06-20 08:17:00 +01:00
case 'userbyid' :
return common_path ( 'user/' . $args [ 'id' ]);
2008-06-24 23:03:35 +01:00
case 'recoverpassword' :
2008-06-24 23:06:26 +01:00
$path = 'main/recoverpassword' ;
if ( $args [ 'code' ]) {
$path .= '/' . $args [ 'code' ];
}
return common_path ( $path );
2008-06-26 19:49:31 +01:00
case 'imsettings' :
return common_path ( 'settings/im' );
2008-07-09 23:31:44 +01:00
case 'peoplesearch' :
2008-07-09 23:38:03 +01:00
return common_path ( 'search/people' . (( $args ) ? ( '?' . http_build_query ( $args )) : '' ));
2008-07-09 23:31:44 +01:00
case 'noticesearch' :
2008-07-09 23:38:03 +01:00
return common_path ( 'search/notice' . (( $args ) ? ( '?' . http_build_query ( $args )) : '' ));
2008-07-10 00:42:28 +01:00
case 'noticesearchrss' :
return common_path ( 'search/notice/rss' . (( $args ) ? ( '?' . http_build_query ( $args )) : '' ));
2008-07-11 07:00:45 +01:00
case 'avatarbynickname' :
return common_path ( $args [ 'nickname' ] . '/avatar/' . $args [ 'size' ]);
2008-07-20 06:57:02 +01:00
case 'tag' :
if ( isset ( $args [ 'tag' ]) && $args [ 'tag' ]) {
$path = 'tag/' . $args [ 'tag' ];
unset ( $args [ 'tag' ]);
} else {
$path = 'tags' ;
}
return common_path ( $path . (( $args ) ? ( '?' . http_build_query ( $args )) : '' ));
case 'tags' :
return common_path ( 'tags' . (( $args ) ? ( '?' . http_build_query ( $args )) : '' ));
2008-09-08 19:16:24 +01:00
case 'favor' :
return common_path ( 'main/favor' );
case 'disfavor' :
return common_path ( 'main/disfavor' );
case 'showfavorites' :
if ( $args && isset ( $args [ 'page' ])) {
return common_path ( $args [ 'nickname' ] . '/favorites?page=' . $args [ 'page' ]);
} else {
return common_path ( $args [ 'nickname' ] . '/favorites' );
}
2008-09-17 19:02:44 +01:00
case 'showmessage' :
2008-09-17 19:59:50 +01:00
return common_path ( 'message/' . $args [ 'message' ]);
2008-09-17 19:02:44 +01:00
case 'newmessage' :
return common_path ( 'message/new' . (( $args ) ? ( '?' . http_build_query ( $args )) : '' ));
2008-05-30 22:25:55 +01:00
default :
return common_simple_url ( $action , $args );
}
}
function common_simple_url ( $action , $args = NULL ) {
global $config ;
2008-05-20 14:05:35 +01:00
/* XXX: pretty URLs */
$extra = '' ;
if ( $args ) {
foreach ( $args as $key => $value ) {
$extra .= " & ${ key}=${value } " ;
}
}
2008-05-30 17:24:29 +01:00
return common_path ( " index.php?action= ${ action}${extra } " );
}
function common_path ( $relative ) {
global $config ;
2008-05-20 14:05:35 +01:00
$pathpart = ( $config [ 'site' ][ 'path' ]) ? $config [ 'site' ][ 'path' ] . " / " : '' ;
2008-05-30 17:24:29 +01:00
return " http:// " . $config [ 'site' ][ 'server' ] . '/' . $pathpart . $relative ;
2008-05-20 14:05:35 +01:00
}
function common_date_string ( $dt ) {
// XXX: do some sexy date formatting
// return date(DATE_RFC822, $dt);
2008-06-27 23:25:22 +01:00
$t = strtotime ( $dt );
$now = time ();
$diff = $now - $t ;
if ( $now < $t ) { # that shouldn't happen!
2008-06-27 23:29:30 +01:00
return common_exact_date ( $dt );
2008-06-27 23:25:22 +01:00
} else if ( $diff < 60 ) {
2008-07-08 10:45:31 +01:00
return _ ( 'a few seconds ago' );
2008-06-27 23:25:22 +01:00
} else if ( $diff < 92 ) {
2008-07-08 10:45:31 +01:00
return _ ( 'about a minute ago' );
2008-06-27 23:25:22 +01:00
} else if ( $diff < 3300 ) {
2008-07-08 10:45:31 +01:00
return sprintf ( _ ( 'about %d minutes ago' ), round ( $diff / 60 ));
2008-06-27 23:25:22 +01:00
} else if ( $diff < 5400 ) {
2008-07-08 10:45:31 +01:00
return _ ( 'about an hour ago' );
2008-06-27 23:25:22 +01:00
} else if ( $diff < 22 * 3600 ) {
2008-07-08 10:45:31 +01:00
return sprintf ( _ ( 'about %d hours ago' ), round ( $diff / 3600 ));
2008-06-27 23:25:22 +01:00
} else if ( $diff < 37 * 3600 ) {
2008-07-08 10:45:31 +01:00
return _ ( 'about a day ago' );
2008-06-27 23:25:22 +01:00
} else if ( $diff < 24 * 24 * 3600 ) {
2008-07-08 14:04:08 +01:00
return sprintf ( _ ( 'about %d days ago' ), round ( $diff / ( 24 * 3600 )));
2008-06-27 23:25:22 +01:00
} else if ( $diff < 46 * 24 * 3600 ) {
2008-07-08 10:45:31 +01:00
return _ ( 'about a month ago' );
2008-06-27 23:25:22 +01:00
} else if ( $diff < 330 * 24 * 3600 ) {
2008-07-08 10:45:31 +01:00
return sprintf ( _ ( 'about %d months ago' ), round ( $diff / ( 30 * 24 * 3600 )));
2008-06-27 23:25:22 +01:00
} else if ( $diff < 480 * 24 * 3600 ) {
2008-07-08 10:45:31 +01:00
return _ ( 'about a year ago' );
2008-06-27 23:25:22 +01:00
} else {
2008-06-27 23:29:30 +01:00
return common_exact_date ( $dt );
2008-06-27 23:25:22 +01:00
}
}
2008-06-27 23:29:30 +01:00
function common_exact_date ( $dt ) {
2008-07-25 00:46:19 +01:00
static $_utc ;
static $_siteTz ;
if ( ! $_utc ) {
$_utc = new DateTimeZone ( 'UTC' );
$_siteTz = new DateTimeZone ( common_timezone ());
}
2008-07-20 15:13:25 +01:00
$dateStr = date ( 'd F Y H:i:s' , strtotime ( $dt ));
2008-07-25 00:46:19 +01:00
$d = new DateTime ( $dateStr , $_utc );
$d -> setTimezone ( $_siteTz );
2008-07-20 15:13:25 +01:00
return $d -> format ( DATE_RFC850 );
2008-05-20 14:05:35 +01:00
}
2008-05-21 15:59:16 +01:00
function common_date_w3dtf ( $dt ) {
2008-07-20 15:13:25 +01:00
$dateStr = date ( 'd F Y H:i:s' , strtotime ( $dt ));
$d = new DateTime ( $dateStr , new DateTimeZone ( 'UTC' ));
$d -> setTimezone ( new DateTimeZone ( common_timezone ()));
return $d -> format ( DATE_W3C );
2008-05-21 15:59:16 +01:00
}
2008-07-16 23:02:23 +01:00
function common_date_rfc2822 ( $dt ) {
2008-07-20 15:13:25 +01:00
$dateStr = date ( 'd F Y H:i:s' , strtotime ( $dt ));
$d = new DateTime ( $dateStr , new DateTimeZone ( 'UTC' ));
$d -> setTimezone ( new DateTimeZone ( common_timezone ()));
return $d -> format ( 'r' );
2008-07-16 23:02:23 +01:00
}
function common_date_iso8601 ( $dt ) {
2008-07-20 15:13:25 +01:00
$dateStr = date ( 'd F Y H:i:s' , strtotime ( $dt ));
$d = new DateTime ( $dateStr , new DateTimeZone ( 'UTC' ));
$d -> setTimezone ( new DateTimeZone ( common_timezone ()));
return $d -> format ( 'c' );
2008-07-16 23:02:23 +01:00
}
2008-08-25 19:23:38 +01:00
function common_sql_now () {
return strftime ( '%Y-%m-%d %H:%M:%S' , time ());
}
2008-05-20 14:05:35 +01:00
function common_redirect ( $url , $code = 307 ) {
static $status = array ( 301 => " Moved Permanently " ,
302 => " Found " ,
303 => " See Other " ,
307 => " Temporary Redirect " );
header ( " Status: ${ code } $status[$code] " );
header ( " Location: $url " );
2008-06-20 07:56:19 +01:00
2008-06-18 21:25:00 +01:00
common_start_xml ( 'a' ,
'-//W3C//DTD XHTML 1.0 Strict//EN' ,
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' );
2008-05-20 14:05:35 +01:00
common_element ( 'a' , array ( 'href' => $url ), $url );
2008-06-18 21:25:00 +01:00
common_end_xml ();
2008-07-10 06:57:26 +01:00
exit ;
2008-05-20 14:05:35 +01:00
}
2008-06-23 04:08:37 +01:00
function common_save_replies ( $notice ) {
2008-07-16 03:58:42 +01:00
# Alternative reply format
2008-07-20 04:32:36 +01:00
$tname = false ;
2008-07-16 03:58:42 +01:00
if ( preg_match ( '/^T ([A-Z0-9]{1,64}) /' , $notice -> content , $match )) {
$tname = $match [ 1 ];
}
2008-07-07 06:43:58 +01:00
# extract all @messages
$cnt = preg_match_all ( '/(?:^|\s)@([a-z0-9]{1,64})/' , $notice -> content , $match );
2008-07-16 03:58:42 +01:00
if ( ! $cnt && ! $tname ) {
2008-07-07 06:43:58 +01:00
return true ;
}
2008-07-16 03:58:42 +01:00
# XXX: is there another way to make an array copy?
2008-07-17 17:40:42 +01:00
$names = ( $tname ) ? array_unique ( array_merge ( array ( strtolower ( $tname )), $match [ 1 ])) : array_unique ( $match [ 1 ]);
2008-07-07 06:43:58 +01:00
$sender = Profile :: staticGet ( $notice -> profile_id );
# store replied only for first @ (what user/notice what the reply directed,
# we assume first @ is it)
2008-07-16 03:58:42 +01:00
for ( $i = 0 ; $i < count ( $names ); $i ++ ) {
$nickname = $names [ $i ];
2008-07-07 06:43:58 +01:00
$recipient = common_relative_profile ( $sender , $nickname , $notice -> created );
if ( ! $recipient ) {
continue ;
}
2008-07-09 21:40:50 +01:00
if ( $i == 0 && ( $recipient -> id != $sender -> id )) { # Don't save reply to self
2008-07-07 06:43:58 +01:00
$reply_for = $recipient ;
2008-07-09 21:27:16 +01:00
$recipient_notice = $reply_for -> getCurrentNotice ();
2008-07-22 09:27:24 +01:00
if ( $recipient_notice ) {
$orig = clone ( $notice );
$notice -> reply_to = $recipient_notice -> id ;
$notice -> update ( $orig );
}
2008-07-07 06:43:58 +01:00
}
$reply = new Reply ();
$reply -> notice_id = $notice -> id ;
$reply -> profile_id = $recipient -> id ;
$id = $reply -> insert ();
if ( ! $id ) {
2008-07-07 08:44:34 +01:00
$last_error = & PEAR :: getStaticProperty ( 'DB_DataObject' , 'lastError' );
2008-07-18 20:08:35 +01:00
common_log ( LOG_ERR , 'DB error inserting reply: ' . $last_error -> message );
2008-07-10 06:04:59 +01:00
common_server_error ( sprintf ( _ ( 'DB error inserting reply: %s' ), $last_error -> message ));
2008-07-07 06:43:58 +01:00
return ;
}
}
2008-06-23 04:08:37 +01:00
}
2008-06-06 17:04:37 +01:00
function common_broadcast_notice ( $notice , $remote = false ) {
2008-08-28 20:25:09 +01:00
// Check to see if notice should go to Twitter
$flink = Foreign_link :: getForeignLink ( $notice -> profile_id , 1 ); // 1 == Twitter
if ( $flink ) {
if ( ! common_twitter_broadcast ( $notice , $flink )) {
common_debug ( 'Unable to send notice: ' . $notice -> id . ' to Twitter.' , __FILE__ );
}
}
2008-07-04 06:04:25 +01:00
if ( common_config ( 'queue' , 'enabled' )) {
# Do it later!
2008-07-04 09:32:16 +01:00
return common_enqueue_notice ( $notice );
2008-07-04 06:04:25 +01:00
} else {
2008-07-05 01:22:07 +01:00
return common_real_broadcast ( $notice , $remote );
2008-07-04 06:04:25 +01:00
}
}
2008-08-28 20:25:09 +01:00
function common_twitter_broadcast ( $notice , $flink ) {
2008-09-07 07:21:18 +01:00
global $config ;
2008-08-28 20:25:09 +01:00
$success = true ;
$fuser = $flink -> getForeignUser ();
$twitter_user = $fuser -> nickname ;
$twitter_password = $flink -> credentials ;
$uri = 'http://www.twitter.com/statuses/update.json' ;
$statustxt = $notice -> content ;
$options = array (
CURLOPT_USERPWD => " $twitter_user : $twitter_password " ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => array (
'status' => $statustxt ,
2008-09-07 07:21:18 +01:00
'source' => $config [ 'integration' ][ 'source' ]
2008-08-28 20:25:09 +01:00
),
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_FAILONERROR => true ,
CURLOPT_HEADER => false ,
CURLOPT_FOLLOWLOCATION => true ,
2008-09-07 07:21:18 +01:00
CURLOPT_USERAGENT => " Laconica " ,
2008-08-28 20:25:09 +01:00
CURLOPT_CONNECTTIMEOUT => 120 , // XXX: Scary!!!! How long should this be?
CURLOPT_TIMEOUT => 120
);
$ch = curl_init ( $uri );
curl_setopt_array ( $ch , $options );
$data = curl_exec ( $ch );
$errmsg = curl_error ( $ch );
if ( $errmsg ) {
common_debug ( " cURL error: $errmsg - trying to send notice for $twitter_user . " ,
__FILE__ );
$success = false ;
}
curl_close ( $ch );
if ( ! $data ) {
common_debug ( " No data returned by Twitter's API trying to send update for $twitter_user " ,
__FILE__ );
$success = false ;
}
// Twitter should return a status
$status = json_decode ( $data );
if ( ! $status -> id ) {
common_debug ( " Unexpected data returned by Twitter API trying to send update for $twitter_user " ,
__FILE__ );
$success = false ;
}
return $status ;
}
2008-07-04 06:04:25 +01:00
# Stick the notice on the queue
function common_enqueue_notice ( $notice ) {
2008-08-29 19:17:02 +01:00
foreach ( array ( 'jabber' , 'omb' , 'sms' , 'public' ) as $transport ) {
2008-08-27 21:54:07 +01:00
$qi = new Queue_item ();
$qi -> notice_id = $notice -> id ;
$qi -> transport = $transport ;
$qi -> created = $notice -> created ;
2008-07-08 08:04:57 +01:00
$result = $qi -> insert ();
2008-08-27 22:19:40 +01:00
if ( ! $result ) {
2008-08-27 21:54:07 +01:00
$last_error = & PEAR :: getStaticProperty ( 'DB_DataObject' , 'lastError' );
common_log ( LOG_ERR , 'DB error inserting queue item: ' . $last_error -> message );
return false ;
}
common_log ( LOG_DEBUG , 'complete queueing notice ID = ' . $notice -> id . ' for ' . $transport );
2008-07-04 07:20:56 +01:00
}
2008-08-28 01:14:14 +01:00
return $result ;
2008-07-04 06:04:25 +01:00
}
2008-07-08 10:45:31 +01:00
2008-07-16 04:20:45 +01:00
function common_dequeue_notice ( $notice ) {
2008-07-26 04:39:58 +01:00
$qi = Queue_item :: staticGet ( $notice -> id );
2008-07-16 04:20:45 +01:00
if ( $qi ) {
$result = $qi -> delete ();
if ( ! $result ) {
$last_error = & PEAR :: getStaticProperty ( 'DB_DataObject' , 'lastError' );
2008-08-08 00:42:27 +01:00
common_log ( LOG_ERR , 'DB error deleting queue item: ' . $last_error -> message );
2008-07-16 04:20:45 +01:00
return false ;
}
common_log ( LOG_DEBUG , 'complete dequeueing notice ID = ' . $notice -> id );
return $result ;
} else {
return false ;
}
}
2008-07-04 06:04:25 +01:00
function common_real_broadcast ( $notice , $remote = false ) {
2008-07-05 01:22:07 +01:00
$success = true ;
2008-06-06 17:04:37 +01:00
if ( ! $remote ) {
2008-06-06 17:22:26 +01:00
# Make sure we have the OMB stuff
require_once ( INSTALLDIR . '/lib/omb.php' );
2008-07-05 01:22:07 +01:00
$success = omb_broadcast_remote_subscribers ( $notice );
2008-07-05 01:56:02 +01:00
if ( ! $success ) {
2008-07-18 20:08:35 +01:00
common_log ( LOG_ERR , 'Error in OMB broadcast for notice ' . $notice -> id );
2008-07-05 01:56:02 +01:00
}
2008-07-05 01:22:07 +01:00
}
if ( $success ) {
require_once ( INSTALLDIR . '/lib/jabber.php' );
$success = jabber_broadcast_notice ( $notice );
2008-07-05 01:56:02 +01:00
if ( ! $success ) {
2008-07-18 20:08:35 +01:00
common_log ( LOG_ERR , 'Error in jabber broadcast for notice ' . $notice -> id );
2008-07-05 01:56:02 +01:00
}
2008-06-06 17:04:37 +01:00
}
2008-07-20 20:55:49 +01:00
if ( $success ) {
require_once ( INSTALLDIR . '/lib/mail.php' );
$success = mail_broadcast_notice_sms ( $notice );
if ( ! $success ) {
common_log ( LOG_ERR , 'Error in sms broadcast for notice ' . $notice -> id );
}
}
2008-08-29 19:17:02 +01:00
if ( $success ) {
$success = jabber_public_notice ( $notice );
if ( ! $success ) {
common_log ( LOG_ERR , 'Error in public broadcast for notice ' . $notice -> id );
}
}
2008-05-20 14:05:35 +01:00
// XXX: broadcast notices to other IM
2008-07-05 01:22:07 +01:00
return $success ;
2008-05-20 14:05:35 +01:00
}
2008-06-12 19:40:28 +01:00
function common_broadcast_profile ( $profile ) {
// XXX: optionally use a queue system like http://code.google.com/p/microapps/wiki/NQDQ
require_once ( INSTALLDIR . '/lib/omb.php' );
omb_broadcast_profile ( $profile );
// XXX: Other broadcasts...?
return true ;
}
2008-06-06 17:04:37 +01:00
2008-05-20 14:05:35 +01:00
function common_profile_url ( $nickname ) {
return common_local_url ( 'showstream' , array ( 'nickname' => $nickname ));
}
2008-06-10 19:52:38 +01:00
# Don't call if nobody's logged in
2008-06-26 22:46:54 +01:00
function common_notice_form ( $action = NULL , $content = NULL ) {
2008-06-10 19:52:38 +01:00
$user = common_current_user ();
assert ( ! is_null ( $user ));
common_element_start ( 'form' , array ( 'id' => 'status_form' ,
2008-07-02 14:15:07 +01:00
'method' => 'post' ,
2008-05-20 21:11:20 +01:00
'action' => common_local_url ( 'newnotice' )));
2008-06-10 20:36:49 +01:00
common_element_start ( 'p' );
2008-07-02 14:15:07 +01:00
common_element ( 'label' , array ( 'for' => 'status_textarea' ,
2008-06-10 19:52:38 +01:00
'id' => 'status_label' ),
2008-07-08 10:45:31 +01:00
sprintf ( _ ( 'What\'s up, %s?' ), $user -> nickname ));
2008-06-24 18:46:13 +01:00
common_element ( 'span' , array ( 'id' => 'counter' , 'class' => 'counter' ), '140' );
2008-06-18 04:00:19 +01:00
common_element ( 'textarea' , array ( 'id' => 'status_textarea' ,
2008-07-02 14:15:07 +01:00
'cols' => 60 ,
'rows' => 3 ,
2008-06-18 04:00:19 +01:00
'name' => 'status_textarea' ),
2008-07-02 14:00:29 +01:00
( $content ) ? $content : '' );
2008-06-19 17:18:14 +01:00
if ( $action ) {
common_hidden ( 'returnto' , $action );
}
2008-06-10 19:52:38 +01:00
common_element ( 'input' , array ( 'id' => 'status_submit' ,
2008-06-10 22:16:14 +01:00
'name' => 'status_submit' ,
2008-06-10 19:52:38 +01:00
'type' => 'submit' ,
2008-07-08 10:45:31 +01:00
'value' => _ ( 'Send' )));
2008-06-10 20:36:49 +01:00
common_element_end ( 'p' );
2008-05-20 21:11:20 +01:00
common_element_end ( 'form' );
2008-05-20 21:25:00 +01:00
}
2008-05-20 21:11:20 +01:00
2008-05-27 12:42:19 +01:00
# Should make up a reasonable root URL
function common_root_url () {
2008-05-30 17:24:29 +01:00
return common_path ( '' );
2008-05-27 12:42:19 +01:00
}
2008-05-27 21:07:21 +01:00
# returns $bytes bytes of random data as a hexadecimal string
# "good" here is a goal and not a guarantee
function common_good_rand ( $bytes ) {
# XXX: use random.org...?
if ( file_exists ( '/dev/urandom' )) {
return common_urandom ( $bytes );
} else { # FIXME: this is probably not good enough
return common_mtrand ( $bytes );
}
}
function common_urandom ( $bytes ) {
$h = fopen ( '/dev/urandom' , 'rb' );
# should not block
$src = fread ( $h , $bytes );
fclose ( $h );
$enc = '' ;
for ( $i = 0 ; $i < $bytes ; $i ++ ) {
$enc .= sprintf ( " %02x " , ( ord ( $src [ $i ])));
}
return $enc ;
}
function common_mtrand ( $bytes ) {
$enc = '' ;
for ( $i = 0 ; $i < $bytes ; $i ++ ) {
$enc .= sprintf ( " %02x " , mt_rand ( 0 , 255 ));
}
return $enc ;
}
2008-05-30 15:23:24 +01:00
function common_set_returnto ( $url ) {
common_ensure_session ();
$_SESSION [ 'returnto' ] = $url ;
}
function common_get_returnto () {
common_ensure_session ();
return $_SESSION [ 'returnto' ];
}
2008-05-28 15:03:21 +01:00
function common_timestamp () {
2008-05-28 15:30:30 +01:00
return date ( 'YmdHis' );
2008-05-28 15:03:21 +01:00
}
2008-06-06 17:04:37 +01:00
2008-05-30 19:22:30 +01:00
function common_ensure_syslog () {
static $initialized = false ;
if ( ! $initialized ) {
2008-06-05 03:40:35 +01:00
global $config ;
2008-06-05 03:47:17 +01:00
openlog ( $config [ 'syslog' ][ 'appname' ], 0 , LOG_USER );
2008-05-30 19:22:30 +01:00
$initialized = true ;
}
}
2008-06-05 03:40:35 +01:00
function common_log ( $priority , $msg , $filename = NULL ) {
2008-07-12 16:15:21 +01:00
$logfile = common_config ( 'site' , 'logfile' );
if ( $logfile ) {
$log = fopen ( $logfile , " a " );
if ( $log ) {
2008-07-13 05:46:08 +01:00
static $syslog_priorities = array ( 'LOG_EMERG' , 'LOG_ALERT' , 'LOG_CRIT' , 'LOG_ERR' ,
2008-07-12 16:15:21 +01:00
'LOG_WARNING' , 'LOG_NOTICE' , 'LOG_INFO' , 'LOG_DEBUG' );
$output = date ( 'Y-m-d H:i:s' ) . ' ' . $syslog_priorities [ $priority ] . ': ' . $msg . " \n " ;
fwrite ( $log , $output );
fclose ( $log );
}
} else {
common_ensure_syslog ();
syslog ( $priority , $msg );
2008-07-11 08:00:21 +01:00
}
2008-05-30 19:22:30 +01:00
}
2008-06-05 03:40:35 +01:00
function common_debug ( $msg , $filename = NULL ) {
2008-06-05 03:47:17 +01:00
if ( $filename ) {
common_log ( LOG_DEBUG , basename ( $filename ) . ' - ' . $msg );
} else {
common_log ( LOG_DEBUG , $msg );
}
2008-06-04 19:51:31 +01:00
}
2008-06-22 15:27:13 +01:00
function common_log_db_error ( & $object , $verb , $filename = NULL ) {
$objstr = common_log_objstring ( $object );
2008-06-22 15:09:41 +01:00
$last_error = & PEAR :: getStaticProperty ( 'DB_DataObject' , 'lastError' );
2008-07-07 07:19:12 +01:00
common_log ( LOG_ERR , $last_error -> message . '(' . $verb . ' on ' . $objstr . ')' , $filename );
2008-06-22 15:09:41 +01:00
}
2008-06-22 15:27:13 +01:00
function common_log_objstring ( & $object ) {
2008-06-22 15:09:41 +01:00
if ( is_null ( $object )) {
return " NULL " ;
}
$arr = $object -> toArray ();
$fields = array ();
foreach ( $arr as $k => $v ) {
$fields [] = " $k =' $v ' " ;
}
2008-06-22 15:29:06 +01:00
$objstring = $object -> tableName () . '[' . implode ( ',' , $fields ) . ']' ;
2008-06-22 15:09:41 +01:00
return $objstring ;
}
2008-06-04 19:51:31 +01:00
function common_valid_http_url ( $url ) {
return Validate :: uri ( $url , array ( 'allowed_schemes' => array ( 'http' , 'https' )));
}
2008-06-05 05:01:53 +01:00
function common_valid_tag ( $tag ) {
if ( preg_match ( '/^tag:(.*?),(\d{4}(-\d{2}(-\d{2})?)?):(.*)$/' , $tag , $matches )) {
2008-06-06 17:04:37 +01:00
return ( Validate :: email ( $matches [ 1 ]) ||
2008-06-05 05:01:53 +01:00
preg_match ( '/^([\w-\.]+)$/' , $matches [ 1 ]));
}
return false ;
}
2008-06-10 20:21:01 +01:00
# Does a little before-after block for next/prev page
2008-06-20 07:56:19 +01:00
function common_pagination ( $have_before , $have_after , $page , $action , $args = NULL ) {
2008-06-10 20:21:01 +01:00
if ( $have_before || $have_after ) {
common_element_start ( 'div' , array ( 'id' => 'pagination' ));
common_element_start ( 'ul' , array ( 'id' => 'nav_pagination' ));
}
2008-06-20 07:56:19 +01:00
2008-06-10 20:21:01 +01:00
if ( $have_before ) {
$pargs = array ( 'page' => $page - 1 );
$newargs = ( $args ) ? array_merge ( $args , $pargs ) : $pargs ;
2008-06-20 07:56:19 +01:00
2008-06-10 20:21:01 +01:00
common_element_start ( 'li' , 'before' );
common_element ( 'a' , array ( 'href' => common_local_url ( $action , $newargs )),
2008-07-08 10:45:31 +01:00
_ ( '« After' ));
2008-06-10 20:21:01 +01:00
common_element_end ( 'li' );
}
if ( $have_after ) {
$pargs = array ( 'page' => $page + 1 );
$newargs = ( $args ) ? array_merge ( $args , $pargs ) : $pargs ;
common_element_start ( 'li' , 'after' );
common_element ( 'a' , array ( 'href' => common_local_url ( $action , $newargs )),
2008-07-08 10:45:31 +01:00
_ ( 'Before »' ));
2008-06-10 20:21:01 +01:00
common_element_end ( 'li' );
}
2008-06-20 07:56:19 +01:00
2008-06-10 20:21:01 +01:00
if ( $have_before || $have_after ) {
common_element_end ( 'ul' );
common_element_end ( 'div' );
}
}
2008-06-13 15:49:13 +01:00
/* Following functions are copied from MediaWiki GlobalFunctions . php
* and written by Evan Prodromou . */
function common_accept_to_prefs ( $accept , $def = '*/*' ) {
# No arg means accept anything (per HTTP spec)
if ( ! $accept ) {
return array ( $def => 1 );
}
$prefs = array ();
$parts = explode ( ',' , $accept );
foreach ( $parts as $part ) {
# FIXME: doesn't deal with params like 'text/html; level=1'
@ list ( $value , $qpart ) = explode ( ';' , $part );
$match = array ();
if ( ! isset ( $qpart )) {
$prefs [ $value ] = 1 ;
} elseif ( preg_match ( '/q\s*=\s*(\d*\.\d+)/' , $qpart , $match )) {
$prefs [ $value ] = $match [ 1 ];
}
}
return $prefs ;
}
function common_mime_type_match ( $type , $avail ) {
if ( array_key_exists ( $type , $avail )) {
return $type ;
} else {
$parts = explode ( '/' , $type );
if ( array_key_exists ( $parts [ 0 ] . '/*' , $avail )) {
return $parts [ 0 ] . '/*' ;
} elseif ( array_key_exists ( '*/*' , $avail )) {
return '*/*' ;
} else {
return NULL ;
}
}
}
function common_negotiate_type ( $cprefs , $sprefs ) {
$combine = array ();
foreach ( array_keys ( $sprefs ) as $type ) {
$parts = explode ( '/' , $type );
if ( $parts [ 1 ] != '*' ) {
$ckey = common_mime_type_match ( $type , $cprefs );
if ( $ckey ) {
$combine [ $type ] = $sprefs [ $type ] * $cprefs [ $ckey ];
}
}
}
foreach ( array_keys ( $cprefs ) as $type ) {
$parts = explode ( '/' , $type );
if ( $parts [ 1 ] != '*' && ! array_key_exists ( $type , $sprefs )) {
$skey = common_mime_type_match ( $type , $sprefs );
if ( $skey ) {
$combine [ $type ] = $sprefs [ $skey ] * $cprefs [ $type ];
}
}
}
$bestq = 0 ;
2008-06-23 18:30:43 +01:00
$besttype = " text/html " ;
2008-06-13 15:49:13 +01:00
foreach ( array_keys ( $combine ) as $type ) {
if ( $combine [ $type ] > $bestq ) {
$besttype = $type ;
$bestq = $combine [ $type ];
}
}
return $besttype ;
}
2008-06-13 18:53:44 +01:00
function common_config ( $main , $sub ) {
global $config ;
2008-07-22 09:28:40 +01:00
return isset ( $config [ $main ][ $sub ]) ? $config [ $main ][ $sub ] : false ;
2008-06-13 18:53:44 +01:00
}
2008-06-19 15:11:07 +01:00
function common_copy_args ( $from ) {
$to = array ();
$strip = get_magic_quotes_gpc ();
foreach ( $from as $k => $v ) {
$to [ $k ] = ( $strip ) ? stripslashes ( $v ) : $v ;
}
return $to ;
2008-06-20 07:54:55 +01:00
}
2008-06-20 08:17:00 +01:00
2008-09-04 07:55:04 +01:00
// Neutralise the evil effects of magic_quotes_gpc in the current request.
// This is used before handing a request off to OAuthRequest::from_request.
function common_remove_magic_from_request () {
if ( get_magic_quotes_gpc ()) {
$_POST = array_map ( 'stripslashes' , $_POST );
$_GET = array_map ( 'stripslashes' , $_GET );
}
}
2008-06-20 08:17:00 +01:00
function common_user_uri ( & $user ) {
return common_local_url ( 'userbyid' , array ( 'id' => $user -> id ));
}
function common_notice_uri ( & $notice ) {
2008-06-24 03:52:34 +01:00
return common_local_url ( 'shownotice' ,
2008-06-20 08:17:00 +01:00
array ( 'notice' => $notice -> id ));
}
2008-06-22 17:32:41 +01:00
# 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
function common_confirmation_code ( $bits ) {
2008-06-22 17:34:58 +01:00
# 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
static $codechars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ' ;
2008-06-22 17:32:41 +01:00
$chars = ceil ( $bits / 5 );
$code = '' ;
for ( $i = 0 ; $i < $chars ; $i ++ ) {
# XXX: convert to string and back
$num = hexdec ( common_good_rand ( 1 ));
2008-06-27 23:25:22 +01:00
# XXX: randomness is too precious to throw away almost
# 40% of the bits we get!
2008-06-22 17:34:58 +01:00
$code .= $codechars [ $num % 32 ];
2008-06-22 17:32:41 +01:00
}
return $code ;
}
2008-06-30 18:03:42 +01:00
# convert markup to HTML
function common_markup_to_html ( $c ) {
$c = preg_replace ( '/%%action.(\w+)%%/e' , " common_local_url(' \\ 1') " , $c );
$c = preg_replace ( '/%%doc.(\w+)%%/e' , " common_local_url('doc', array('title'=>' \\ 1')) " , $c );
$c = preg_replace ( '/%%(\w+).(\w+)%%/e' , 'common_config(\'\\1\', \'\\2\')' , $c );
return Markdown ( $c );
}
2008-07-14 04:44:43 +01:00
function common_profile_avatar_url ( $profile , $size = AVATAR_PROFILE_SIZE ) {
$avatar = $profile -> getAvatar ( $size );
if ( $avatar ) {
return common_avatar_display_url ( $avatar );
} else {
return common_default_avatar ( $size );
}
}
2008-07-16 16:25:11 +01:00
function common_profile_uri ( $profile ) {
if ( ! $profile ) {
return NULL ;
}
$user = User :: staticGet ( $profile -> id );
if ( $user ) {
return $user -> uri ;
}
2008-07-20 06:57:02 +01:00
2008-07-16 16:25:11 +01:00
$remote = Remote_profile :: staticGet ( $profile -> id );
if ( $remote ) {
return $remote -> uri ;
}
# XXX: this is a very bad profile!
return NULL ;
2008-07-20 20:30:05 +01:00
}
function common_canonical_sms ( $sms ) {
# strip non-digits
preg_replace ( '/\D/' , '' , $sms );
return $sms ;
2008-07-29 09:06:41 +01:00
}
2008-08-29 18:40:12 +01:00
function common_error_handler ( $errno , $errstr , $errfile , $errline , $errcontext ) {
switch ( $errno ) {
case E_USER_ERROR :
2008-08-30 06:30:52 +01:00
common_log ( LOG_ERR , " [ $errno ] $errstr ( $errfile : $errline ) " );
2008-08-29 18:40:12 +01:00
exit ( 1 );
break ;
case E_USER_WARNING :
2008-08-30 06:30:52 +01:00
common_log ( LOG_WARNING , " [ $errno ] $errstr ( $errfile : $errline ) " );
2008-08-29 18:40:12 +01:00
break ;
case E_USER_NOTICE :
2008-08-30 06:30:52 +01:00
common_log ( LOG_NOTICE , " [ $errno ] $errstr ( $errfile : $errline ) " );
2008-08-29 18:40:12 +01:00
break ;
}
2008-08-30 06:30:52 +01:00
# FIXME: show error page if we're on the Web
2008-08-29 18:40:12 +01:00
/* Don't execute PHP internal error handler */
return true ;
}
function common_session_token () {
common_ensure_session ();
if ( ! array_key_exists ( 'token' , $_SESSION )) {
$_SESSION [ 'token' ] = common_good_rand ( 64 );
}
return $_SESSION [ 'token' ];
}
2008-09-15 07:56:16 +01:00
2008-09-08 19:16:24 +01:00
function common_disfavor_form ( $notice ) {
common_element_start ( 'form' , array ( 'id' => 'disfavor-' . $notice -> id ,
'method' => 'post' ,
2008-09-08 21:17:51 +01:00
'class' => 'disfavor' ,
2008-09-08 19:16:24 +01:00
'action' => common_local_url ( 'disfavor' )));
common_hidden ( 'token' , common_session_token ());
common_hidden ( 'notice' , $notice -> id );
2008-09-08 21:22:26 +01:00
common_element ( 'input' , array ( 'type' => 'submit' ,
'id' => 'disfavor-submit-' . $notice -> id ,
'name' => 'disfavor-submit-' . $notice -> id ,
'class' => 'disfavor' ,
'value' => '♥' ));
2008-09-08 19:16:24 +01:00
common_element_end ( 'form' );
}
function common_favor_form ( $notice ) {
common_element_start ( 'form' , array ( 'id' => 'favor-' . $notice -> id ,
'method' => 'post' ,
2008-09-08 21:17:51 +01:00
'class' => 'favor' ,
2008-09-08 19:25:59 +01:00
'action' => common_local_url ( 'favor' )));
2008-09-08 19:16:24 +01:00
common_hidden ( 'token' , common_session_token ());
common_hidden ( 'notice' , $notice -> id );
2008-09-08 21:22:26 +01:00
common_element ( 'input' , array ( 'type' => 'submit' ,
'id' => 'favor-submit-' . $notice -> id ,
'name' => 'favor-submit-' . $notice -> id ,
'class' => 'favor' ,
'value' => '♡' ));
2008-09-08 19:16:24 +01:00
common_element_end ( 'form' );
}
2008-09-15 07:56:16 +01:00
function common_cache_key ( $extra ) {
return 'laconica:' . common_keyize ( common_config ( 'site' , 'name' )) . ':' . $extra ;
}
function common_keyize ( $str ) {
$str = strtolower ( $str );
$str = preg_replace ( '/\s/' , '_' , $str );
return $str ;
}