Merge branch 'master' of evan@dev.controlyourself.ca:/var/www/trunk

This commit is contained in:
Evan Prodromou 2009-01-22 12:35:25 +01:00
commit a2a2dd88b5
39 changed files with 1419 additions and 445 deletions

View File

@ -1,5 +1,16 @@
<?php
/*
/**
* Access token class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,12 +28,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
require_once(INSTALLDIR.'/lib/omb.php');
require_once INSTALLDIR.'/lib/omb.php';
/**
* Access token class.
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class AccesstokenAction extends Action
{
/**
* Class handler.
*
* @param array $args query arguments
*
* @return boolean false if user doesn't exist
*/
function handle($args)
{
parent::handle($args);

View File

@ -1,5 +1,17 @@
<?php
/*
/**
* RSS feed for user and friends timeline action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,17 +29,34 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
require_once(INSTALLDIR.'/lib/rssaction.php');
// Formatting of RSS handled by Rss10Action
require_once INSTALLDIR.'/lib/rssaction.php';
/**
* RSS feed for user and friends timeline.
*
* Formatting of RSS handled by Rss10Action
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class AllrssAction extends Rss10Action
{
var $user = null;
/**
* Initialization.
*
* @return boolean false if user doesn't exist
*/
function init()
{
$nickname = $this->trimmed('nickname');
@ -41,11 +70,16 @@ class AllrssAction extends Rss10Action
}
}
function get_notices($limit=0)
/**
* Get notices
*
* @param integer $limit max number of notices to return
*
* @return array notices
*/
function getNotices($limit=0)
{
$user = $this->user;
$notice = $user->noticesWithFriends(0, $limit);
while ($notice->fetch()) {
@ -55,7 +89,12 @@ class AllrssAction extends Rss10Action
return $notices;
}
function get_channel()
/**
* Get channel.
*
* @return array associative array on channel information
*/
function getChannel()
{
$user = $this->user;
$c = array('url' => common_local_url('allrss',
@ -69,7 +108,12 @@ class AllrssAction extends Rss10Action
return $c;
}
function get_image()
/**
* Get image.
*
* @return string user avatar URL or null
*/
function getImage()
{
$user = $this->user;
$profile = $user->getProfile();
@ -77,6 +121,7 @@ class AllrssAction extends Rss10Action
return null;
}
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
return ($avatar) ? $avatar->url : null;
return $avatar ? $avatar->url : null;
}
}

View File

@ -1,5 +1,16 @@
<?php
/*
/**
* Retrieve user avatar by nickname action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,10 +28,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
/**
* Retrieve user avatar by nickname action class.
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class AvatarbynicknameAction extends Action
{
/**
* Class handler.
*
* @param array $args query arguments
*
* @return boolean false if nickname or user isn't found
*/
function handle($args)
{
parent::handle($args);
@ -68,3 +98,4 @@ class AvatarbynicknameAction extends Action
common_redirect($url, 302);
}
}

View File

@ -37,12 +37,13 @@ require_once INSTALLDIR.'/lib/accountsettingsaction.php';
/**
* Upload an avatar
*
* We use jQuery to crop the image after upload.
* We use jCrop plugin for jQuery to crop the image after upload.
*
* @category Settings
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Zach Copley <zach@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/
*/
@ -94,42 +95,43 @@ class AvatarsettingsAction extends AccountSettingsAction
$original = $profile->getOriginalAvatar();
$this->elementStart('form', array('enctype' => 'multipart/form-data',
'method' => 'POST',
'id' => 'avatar',
'method' => 'post',
'id' => 'form_settings_avatar',
'class' => 'form_settings',
'action' =>
common_local_url('avatarsettings')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Avatar settings'));
$this->hidden('token', common_session_token());
$this->elementStart('ul', 'form_data');
if ($original) {
$this->elementStart('div',
$this->elementStart('li',
array('id' => 'avatar_original',
'class' => 'avatar_view'));
$this->element('h3', null, _("Original:"));
$this->element('h2', null, _("Original"));
$this->elementStart('div', array('id'=>'avatar_original_view'));
$this->element('img', array('src' => $original->url,
'class' => 'avatar original',
'width' => $original->width,
'height' => $original->height,
'alt' => $user->nickname));
$this->elementEnd('div');
$this->elementEnd('div');
$this->elementEnd('li');
}
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
if ($avatar) {
$this->elementStart('div',
$this->elementStart('li',
array('id' => 'avatar_preview',
'class' => 'avatar_view'));
$this->element('h3', null, _("Preview:"));
$this->element('h2', null, _("Preview"));
$this->elementStart('div', array('id'=>'avatar_preview_view'));
$this->element('img', array('src' => $original->url,//$avatar->url,
'class' => 'avatar profile',
'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE,
'alt' => $user->nickname));
$this->elementEnd('div');
$this->elementEnd('div');
foreach (array('avatar_crop_x', 'avatar_crop_y',
'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
@ -138,21 +140,28 @@ class AvatarsettingsAction extends AccountSettingsAction
'id' => $crop_info));
}
$this->submit('crop', _('Crop'));
$this->elementEnd('li');
}
$this->elementStart('li', array ('id' => 'settings_attach'));
$this->element('input', array('name' => 'avatarfile',
'type' => 'file',
'id' => 'avatarfile'));
$this->element('input', array('name' => 'MAX_FILE_SIZE',
'type' => 'hidden',
'id' => 'MAX_FILE_SIZE',
'value' => MAX_AVATAR_SIZE));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->elementStart('p');
$this->element('input', array('name' => 'avatarfile',
'type' => 'file',
'id' => 'avatarfile'));
$this->elementEnd('p');
$this->elementStart('ul', 'form_actions');
$this->elementStart('li');
$this->submit('upload', _('Upload'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
@ -250,7 +259,7 @@ class AvatarsettingsAction extends AccountSettingsAction
{
parent::showStylesheets();
$jcropStyle =
common_path('js/jcrop/jquery.Jcrop.css?version='.LACONICA_VERSION);
common_path('theme/base/css/jquery.Jcrop.css?version='.LACONICA_VERSION);
$this->element('link', array('rel' => 'stylesheet',
'type' => 'text/css',

View File

@ -1,5 +1,16 @@
<?php
/*
/**
* Block a user action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,121 +28,135 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
/**
* Block a user action class.
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class BlockAction extends Action
{
var $profile = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return false;
}
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return;
}
$id = $this->trimmed('blockto');
if (!$id) {
$this->clientError(_('No profile specified.'));
return false;
}
$this->profile = Profile::staticGet('id', $id);
if (!$this->profile) {
$this->clientError(_('No profile with that ID.'));
return false;
}
return true;
}
/**
* Handle request
*
* Shows a page with list of favorite notices
*
* @param array $args $_REQUEST args; handled in prepare()
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('block')) {
$this->are_you_sure_form();
$this->areYouSureForm();
} else if ($this->arg('no')) {
$cur = common_current_user();
common_redirect(common_local_url('subscribers',
array('nickname' => $cur->nickname)));
common_redirect(common_local_url('subscribers', array('nickname' => $cur->nickname)));
} else if ($this->arg('yes')) {
$this->block_profile();
$this->blockProfile();
}
}
}
function are_you_sure_form()
/**
* Confirm with user.
*
* Shows a confirmation form.
*
* @return void
*/
function areYouSureForm()
{
$id = $this->profile->id;
common_show_header(_('Block user'));
$this->element('p', null,
_('Are you sure you want to block this user? '.
'Afterwards, they will be unsubscribed from you, '.
'unable to subscribe to you in the future, and '.
'you will not be notified of any @-replies from them.'));
$this->elementStart('form', array('id' => 'block-' . $id,
'method' => 'post',
'class' => 'block',
'action' => common_local_url('block')));
$this->hidden('token', common_session_token());
$this->element('input', array('id' => 'blockto-' . $id,
'name' => 'blockto',
'type' => 'hidden',
'value' => $id));
foreach ($this->args as $k => $v) {
if (substr($k, 0, 9) == 'returnto-') {
$this->hidden($k, $v);
}
}
$this->submit('no', _('No'));
$this->submit('yes', _('Yes'));
$this->elementEnd('form');
common_show_footer();
}
function block_profile()
/**
* Actually block a user.
*
* @return void
*/
function blockProfile()
{
$cur = common_current_user();
if ($cur->hasBlocked($this->profile)) {
$this->clientError(_('You have already blocked this user.'));
return;
}
$result = $cur->block($this->profile);
if (!$result) {
$this->serverError(_('Failed to save block information.'));
return;
}
# Now, gotta figure where we go back to
// Now, gotta figure where we go back to
foreach ($this->args as $k => $v) {
if ($k == 'returnto-action') {
$action = $v;
@ -148,3 +173,4 @@ class BlockAction extends Action
}
}
}

94
actions/clienterror.php Normal file
View File

@ -0,0 +1,94 @@
<?php
/**
* Client error action.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* 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.
*
* 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.
*
* 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/>.
*/
if (!defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/error.php';
/**
* Class for displaying HTTP client errors
*
* @category Action
* @package Laconica
* @author Zach Copley <zach@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class ClientErrorAction extends ErrorAction
{
function __construct($message='Error', $code=400)
{
parent::__construct($message, $code);
$this->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');
$this->default = 400;
}
// XXX: Should these error actions even be invokable via URI?
function handle($args)
{
parent::handle($args);
$this->code = $this->trimmed('code');
if (!$this->code || $code < 400 || $code > 499) {
$this->code = $this->default;
}
$this->message = $this->trimmed('message');
if (!$this->message) {
$this->message = "Client Error $this->code";
}
$this->showPage();
}
}

View File

@ -1,5 +1,17 @@
<?php
/*
/**
* Disfavor action.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,41 +29,51 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/favorform.php';
/**
* Disfavor class.
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class DisfavorAction extends Action
{
/**
* Class handler.
*
* @param array $args query arguments
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return;
}
$user = common_current_user();
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
common_redirect(common_local_url('showfavorites',
array('nickname' => $user->nickname)));
return;
}
$id = $this->trimmed('notice');
$notice = Notice::staticGet($id);
$token = $this->trimmed('token-'.$notice->id);
if (!$token || $token != common_session_token()) {
$this->clientError(_("There was a problem with your session token. Try again, please."));
return;
}
$fave = new Fave();
$fave->user_id = $this->id;
$fave->notice_id = $notice->id;
@ -59,17 +81,13 @@ class DisfavorAction extends Action
$this->clientError(_('This notice is not a favorite!'));
return;
}
$result = $fave->delete();
if (!$result) {
common_log_db_error($fave, 'DELETE', __FILE__);
$this->serverError(_('Could not delete favorite.'));
return;
}
$user->blowFavesCache();
if ($this->boolean('ajax')) {
$this->startHTML('text/xml;charset=utf-8', true);
$this->elementStart('head');
@ -86,3 +104,4 @@ class DisfavorAction extends Action
}
}
}

View File

@ -67,6 +67,25 @@ class DocAction extends Action
$this->showPage();
}
// overrrided to add entry-title class
function showPageTitle() {
$this->element('h1', array('class' => 'entry-title'), $this->title());
}
// overrided to add hentry, and content-inner classes
function showContentBlock()
{
$this->elementStart('div', array('id' => 'content', 'class' => 'hentry'));
$this->showPageTitle();
$this->showPageNoticeBlock();
$this->elementStart('div', array('id' => 'content_inner',
'class' => 'entry-content'));
// show the actual content (forms, lists, whatever)
$this->showContent();
$this->elementEnd('div');
$this->elementEnd('div');
}
/**
* Display content.
*
@ -89,4 +108,3 @@ class DocAction extends Action
return ucfirst($this->title);
}
}

View File

@ -88,7 +88,12 @@ class EditgroupAction extends Action
return false;
}
$groupid = $this->trimmed('groupid');
if ($groupid) {
$this->group = User_group::staticGet('id', $groupid);
} else {
$this->group = User_group::staticGet('nickname', $nickname);
}
if (!$this->group) {
$this->clientError(_('No such group'), 404);
@ -97,7 +102,7 @@ class EditgroupAction extends Action
$cur = common_current_user();
if (!$cur->isAdmin($group)) {
if (!$cur->isAdmin($this->group)) {
$this->clientError(_('You must be an admin to edit the group'), 403);
return false;
}
@ -155,6 +160,13 @@ class EditgroupAction extends Action
function trySave()
{
$cur = common_current_user();
if (!$cur->isAdmin($this->group)) {
$this->clientError(_('You must be an admin to edit the group'), 403);
return;
}
$nickname = common_canonical_nickname($this->trimmed('nickname'));
$fullname = $this->trimmed('fullname');
$homepage = $this->trimmed('homepage');
@ -223,3 +235,4 @@ class EditgroupAction extends Action
$group->id != $this->group->id);
}
}

View File

@ -1,4 +1,18 @@
<?php
/**
* Favor action.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
@ -17,57 +31,63 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
require_once(INSTALLDIR.'/lib/mail.php');
require_once INSTALLDIR.'/lib/mail.php';
require_once INSTALLDIR.'/lib/disfavorform.php';
/**
* Favor class.
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class FavorAction extends Action
{
/**
* Class handler.
*
* @param array $args query arguments
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return;
}
$user = common_current_user();
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
common_redirect(common_local_url('showfavorites', array('nickname' => $user->nickname)));
common_redirect(common_local_url('showfavorites',
array('nickname' => $user->nickname)));
return;
}
$id = $this->trimmed('notice');
$notice = Notice::staticGet($id);
# CSRF protection
$token = $this->trimmed('token-'.$notice->id);
if (!$token || $token != common_session_token()) {
$this->clientError(_("There was a problem with your session token. Try again, please."));
return;
}
if ($user->hasFave($notice)) {
$this->clientError(_('This notice is already a favorite!'));
return;
}
$fave = Fave::addNew($user, $notice);
if (!$fave) {
$this->serverError(_('Could not create favorite.'));
return;
}
$this->notify($fave, $notice, $user);
$this->notify($notice, $user);
$user->blowFavesCache();
if ($this->boolean('ajax')) {
$this->startHTML('text/xml;charset=utf-8', true);
$this->elementStart('head');
@ -84,16 +104,24 @@ class FavorAction extends Action
}
}
function notify($fave, $notice, $user)
/**
* Notifies a user when his notice is favorited.
*
* @param class $notice favorited notice
* @param class $user user declaring a favorite
*
* @return void
*/
function notify($notice, $user)
{
$other = User::staticGet('id', $notice->profile_id);
if ($other && $other->id != $user->id) {
if ($other->email && $other->emailnotifyfav) {
mail_notify_fave($other, $user, $notice);
}
# XXX: notify by IM
# XXX: notify by SMS
// XXX: notify by IM
// XXX: notify by SMS
}
}
}
}

View File

@ -57,12 +57,12 @@ class LeavegroupAction extends Action
parent::prepare($args);
if (!common_config('inboxes','enabled')) {
$this->serverError(_('Inboxes must be enabled for groups to work'));
$this->serverError(_('Inboxes must be enabled for groups to work.'));
return false;
}
if (!common_logged_in()) {
$this->clientError(_('You must be logged in to join a group.'));
$this->clientError(_('You must be logged in to leave a group.'));
return false;
}
@ -78,24 +78,30 @@ class LeavegroupAction extends Action
}
if (!$nickname) {
$this->clientError(_('No nickname'), 404);
$this->clientError(_('No nickname.'), 404);
return false;
}
$this->group = User_group::staticGet('nickname', $nickname);
if (!$this->group) {
$this->clientError(_('No such group'), 404);
$this->clientError(_('No such group.'), 404);
return false;
}
$cur = common_current_user();
if (!$cur->isMember($group)) {
$this->clientError(_('You are not a member of that group'), 403);
if (!$cur->isMember($this->group)) {
$this->clientError(_('You are not a member of that group.'), 403);
return false;
}
if ($cur->isAdmin($this->group)) {
$this->clientError(_('You may not leave a group while you are its administrator.'), 403);
return false;
}
return true;
}

View File

@ -202,3 +202,4 @@ class NewgroupAction extends Action
return (!is_null($group) && $group != false);
}
}

View File

@ -42,6 +42,7 @@ require_once INSTALLDIR.'/lib/mail.php';
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @author Sarven Capadisli <csarven@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
@ -93,7 +94,7 @@ class NudgeAction extends Action
$this->element('title', null, _('Nudge sent'));
$this->elementEnd('head');
$this->elementStart('body');
common_nudge_response();
$this->element('p', array('id' => 'nudge_response'), _('Nudge sent!'));
$this->elementEnd('body');
$this->elementEnd('html');
} else {

View File

@ -1,5 +1,17 @@
<?php
/*
/**
* Opensearch action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,32 +29,46 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
/**
* Opensearch action class.
*
* Formatting of RSS handled by Rss10Action
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class OpensearchAction extends Action
{
/**
* Class handler.
*
* @param array $args query arguments
*
* @return boolean false if user doesn't exist
*/
function handle($args)
{
parent::handle($args);
$type = $this->trimmed('type');
$short_name = '';
if ($type == 'people') {
$type = 'peoplesearch';
$short_name = _('People Search');
} else {
$short_name = _('Notice Search');
$type = 'noticesearch';
$short_name = _('Notice Search');
}
header('Content-Type: text/html');
common_start_xml();
$this->elementStart('OpenSearchDescription', array('xmlns' => 'http://a9.com/-/spec/opensearch/1.1/'));
$short_name = common_config('site', 'name').' '.$short_name;
$this->element('ShortName', null, $short_name);
$this->element('Contact', null, common_config('site', 'email'));
@ -54,8 +80,8 @@ class OpensearchAction extends Action
$this->element('Language', null, common_language());
$this->element('OutputEncoding', null, 'UTF-8');
$this->element('InputEncoding', null, 'UTF-8');
$this->elementEnd('OpenSearchDescription');
common_end_xml();
}
}

View File

@ -81,21 +81,35 @@ class PasswordsettingsAction extends AccountSettingsAction
{
$user = common_current_user();
$this->elementStart('form', array('method' => 'POST',
'id' => 'password',
'id' => 'form_password',
'class' => 'form_settings',
'action' =>
common_local_url('profilesettings')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Password change'));
$this->hidden('token', common_session_token());
$this->elementStart('ul', 'form_data');
// Users who logged in with OpenID won't have a pwd
if ($user->password) {
$this->elementStart('li');
$this->password('oldpassword', _('Old password'));
$this->elementEnd('li');
}
$this->elementStart('li');
$this->password('newpassword', _('New password'),
_('6 or more characters'));
$this->elementEnd('li');
$this->elementStart('li');
$this->password('confirm', _('Confirm'),
_('same as password above'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('changepass', _('Change'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}

View File

@ -36,6 +36,8 @@ if (!defined('LACONICA')) {
require_once INSTALLDIR.'/lib/rssaction.php';
/**
* RSS feed for public timeline.
*
* Formatting of RSS handled by Rss10Action
*
* @category Action

View File

@ -248,6 +248,25 @@ class RegisterAction extends Action
return ($user !== false);
}
// overrrided to add entry-title class
function showPageTitle() {
$this->element('h1', array('class' => 'entry-title'), $this->title());
}
// overrided to add hentry, and content-inner class
function showContentBlock()
{
$this->elementStart('div', array('id' => 'content', 'class' => 'hentry'));
$this->showPageTitle();
$this->showPageNoticeBlock();
$this->elementStart('div', array('id' => 'content_inner',
'class' => 'entry-content'));
// show the actual content (forms, lists, whatever)
$this->showContent();
$this->elementEnd('div');
$this->elementEnd('div');
}
/**
* Instructions or a notice for the page
*

View File

@ -1,5 +1,17 @@
<?php
/*
/**
* Request token action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
@ -17,18 +29,41 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('LACONICA')) { exit(1); }
if (!defined('LACONICA')) {
exit(1);
}
require_once(INSTALLDIR.'/lib/omb.php');
require_once INSTALLDIR.'/lib/omb.php';
/**
* Request token action class.
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Robin Millette <millette@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class RequesttokenAction extends Action
{
/**
* Is read only?
*
* @return boolean false
*/
function isReadOnly()
{
return false;
}
/**
* Class handler.
*
* @param array $args array of arguments
*
* @return void
*/
function handle($args)
{
parent::handle($args);
@ -43,3 +78,4 @@ class RequesttokenAction extends Action
}
}
}

92
actions/servererror.php Normal file
View File

@ -0,0 +1,92 @@
<?php
/**
* Server error action.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* 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.
*
* 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.
*
* 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/>.
*/
if (!defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/error.php';
/**
* Class for displaying HTTP server errors
*
* Note: The older util.php class simply printed a string, but the spec
* says that 500 errors should be treated similarly to 400 errors, and
* it's easier to give an HTML response. Maybe we can customize these
* to display some funny animal cartoons. If not, we can probably role
* these classes up into a single class.
*
* See: http://tools.ietf.org/html/rfc2616#section-10
*
* @category Action
* @package Laconica
* @author Zach Copley <zach@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class ServerErrorAction extends ErrorAction
{
function __construct($message='Error', $code=500)
{
parent::__construct($message, $code);
$this->status = array(500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported');
$this->default = 500;
}
// XXX: Should these error actions even be invokable via URI?
function handle($args)
{
parent::handle($args);
$this->code = $this->trimmed('code');
if (!$this->code || $code < 500 || $code > 599) {
$this->code = $this->default;
}
$this->message = $this->trimmed('message');
if (!$this->message) {
$this->message = "Server Error $this->code";
}
$this->showPage();
}
}

View File

@ -201,13 +201,12 @@ class ShowgroupAction extends Action
function showGroupProfile()
{
$this->elementStart('div', array('id' => 'group_profile',
'class' => 'vcard author'));
$this->elementStart('div', 'entity_profile vcard author');
$this->element('h2', null, _('Group profile'));
$this->elementStart('dl', 'group_depiction');
$this->element('dt', null, _('Photo'));
$this->elementStart('dl', 'entity_depiction');
$this->element('dt', null, _('Avatar'));
$this->elementStart('dd');
$logo = ($this->group->homepage_logo) ?
@ -221,10 +220,10 @@ class ShowgroupAction extends Action
$this->elementEnd('dd');
$this->elementEnd('dl');
$this->elementStart('dl', 'group_nickname');
$this->elementStart('dl', 'entity_nickname');
$this->element('dt', null, _('Nickname'));
$this->elementStart('dd');
$hasFN = ($this->group->fullname) ? 'nickname url uid' : 'fn nickname url uid';
$hasFN = ($this->group->fullname) ? 'nickname url uid' : 'fn org nickname url uid';
$this->element('a', array('href' => $this->group->homeUrl(),
'rel' => 'me', 'class' => $hasFN),
$this->group->nickname);
@ -232,23 +231,23 @@ class ShowgroupAction extends Action
$this->elementEnd('dl');
if ($this->group->fullname) {
$this->elementStart('dl', 'group_fn');
$this->elementStart('dl', 'entity_fn');
$this->element('dt', null, _('Full name'));
$this->elementStart('dd');
$this->element('span', 'fn', $this->group->fullname);
$this->element('span', 'fn org', $this->group->fullname);
$this->elementEnd('dd');
$this->elementEnd('dl');
}
if ($this->group->location) {
$this->elementStart('dl', 'group_location');
$this->elementStart('dl', 'entity_location');
$this->element('dt', null, _('Location'));
$this->element('dd', 'location', $this->group->location);
$this->elementEnd('dl');
}
if ($this->group->homepage) {
$this->elementStart('dl', 'group_url');
$this->elementStart('dl', 'entity_url');
$this->element('dt', null, _('URL'));
$this->elementStart('dd');
$this->element('a', array('href' => $this->group->homepage,
@ -259,7 +258,7 @@ class ShowgroupAction extends Action
}
if ($this->group->description) {
$this->elementStart('dl', 'group_note');
$this->elementStart('dl', 'entity_note');
$this->element('dt', null, _('Note'));
$this->element('dd', 'note', $this->group->description);
$this->elementEnd('dl');
@ -267,15 +266,17 @@ class ShowgroupAction extends Action
$this->elementEnd('div');
$this->elementStart('div', array('id' => 'group_actions'));
$this->elementStart('div', 'entity_actions');
$this->element('h2', null, _('Group actions'));
$this->elementStart('ul');
$this->elementStart('li', array('id' => 'group_subscribe'));
$this->elementStart('li', array('id' => 'entity_subscribe'));
$cur = common_current_user();
if ($cur) {
if ($cur->isMember($this->group)) {
if (!$cur->isAdmin($this->group)) {
$lf = new LeaveForm($this, $this->group);
$lf->show();
}
} else {
$jf = new JoinForm($this, $this->group);
$jf->show();
@ -348,7 +349,7 @@ class ShowgroupAction extends Action
return;
}
$this->elementStart('div', array('id' => 'user_subscriptions',
$this->elementStart('div', array('id' => 'entity_subscriptions',
'class' => 'section'));
$this->element('h2', null, _('Members'));

View File

@ -169,14 +169,14 @@ class ShowstreamAction extends Action
$this->element('link', array('rel' => 'alternate',
'href' => common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline.rss',
'method' => 'entity_timeline.rss',
'argument' => $this->user->nickname)),
'type' => 'application/rss+xml',
'title' => sprintf(_('Notice feed for %s'), $this->user->nickname)));
$this->element('link', array('rel' => 'alternate feed',
'href' => common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline.atom',
'method' => 'entity_timeline.atom',
'argument' => $this->user->nickname)),
'type' => 'application/atom+xml',
'title' => sprintf(_('Notice feed for %s'), $this->user->nickname)));
@ -227,11 +227,11 @@ class ShowstreamAction extends Action
function showProfile()
{
$this->elementStart('div', array('id' => 'user_profile', 'class' => 'vcard author'));
$this->elementStart('div', 'entity_profile vcard author');
$this->element('h2', null, _('User profile'));
$avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE);
$this->elementStart('dl', 'user_depiction');
$this->elementStart('dl', 'entity_depiction');
$this->element('dt', null, _('Photo'));
$this->elementStart('dd');
$this->element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE),
@ -242,7 +242,7 @@ class ShowstreamAction extends Action
$this->elementEnd('dd');
$this->elementEnd('dl');
$this->elementStart('dl', 'user_nickname');
$this->elementStart('dl', 'entity_nickname');
$this->element('dt', null, _('Nickname'));
$this->elementStart('dd');
$hasFN = ($this->profile->fullname) ? 'nickname url uid' : 'fn nickname url uid';
@ -253,7 +253,7 @@ class ShowstreamAction extends Action
$this->elementEnd('dl');
if ($this->profile->fullname) {
$this->elementStart('dl', 'user_fn');
$this->elementStart('dl', 'entity_fn');
$this->element('dt', null, _('Full name'));
$this->elementStart('dd');
$this->element('span', 'fn', $this->profile->fullname);
@ -262,14 +262,14 @@ class ShowstreamAction extends Action
}
if ($this->profile->location) {
$this->elementStart('dl', 'user_location');
$this->elementStart('dl', 'entity_location');
$this->element('dt', null, _('Location'));
$this->element('dd', 'location', $this->profile->location);
$this->elementEnd('dl');
}
if ($this->profile->homepage) {
$this->elementStart('dl', 'user_url');
$this->elementStart('dl', 'entity_url');
$this->element('dt', null, _('URL'));
$this->elementStart('dd');
$this->element('a', array('href' => $this->profile->homepage,
@ -280,7 +280,7 @@ class ShowstreamAction extends Action
}
if ($this->profile->bio) {
$this->elementStart('dl', 'user_note');
$this->elementStart('dl', 'entity_note');
$this->element('dt', null, _('Note'));
$this->element('dd', 'note', $this->profile->bio);
$this->elementEnd('dl');
@ -288,7 +288,7 @@ class ShowstreamAction extends Action
$tags = Profile_tag::getTags($this->profile->id, $this->profile->id);
if (count($tags) > 0) {
$this->elementStart('dl', 'user_tags');
$this->elementStart('dl', 'entity_tags');
$this->element('dt', null, _('Tags'));
$this->elementStart('dd');
$this->elementStart('ul', 'tags xoxo');
@ -307,10 +307,11 @@ class ShowstreamAction extends Action
}
$this->elementEnd('div');
$this->elementStart('div', array('id' => 'user_actions'));
//XXX: entity_actions doesn't need to be outputted if entity is looking at their own profile
$this->elementStart('div', 'entity_actions');
$this->element('h2', null, _('User actions'));
$this->elementStart('ul');
$this->elementStart('li', array('id' => 'user_subscribe'));
$this->elementStart('li', array('id' => 'entity_subscribe'));
$cur = common_current_user();
if ($cur) {
if ($cur->id != $this->profile->id) {
@ -331,14 +332,14 @@ class ShowstreamAction extends Action
$user = User::staticGet('id', $this->profile->id);
if ($cur && $cur->id != $user->id && $cur->mutuallySubscribed($user)) {
$this->elementStart('li', array('id' => 'user_send-a-message'));
$this->elementStart('li', array('id' => 'entity_send-a-message'));
$this->element('a', array('href' => common_local_url('newmessage', array('to' => $user->id)),
'title' => _('Send a direct message to this user')),
_('Message'));
$this->elementEnd('li');
if ($user->email && $user->emailnotifynudge) {
$this->elementStart('li', array('id' => 'user_nudge'));
$this->elementStart('li', array('id' => 'entity_nudge'));
$nf = new NudgeForm($this, $user);
$nf->show();
$this->elementEnd('li');
@ -347,7 +348,7 @@ class ShowstreamAction extends Action
if ($cur && $cur->id != $this->profile->id) {
$blocked = $cur->hasBlocked($this->profile);
$this->elementStart('li', array('id' => 'user_block'));
$this->elementStart('li', array('id' => 'entity_block'));
if ($blocked) {
$ubf = new UnblockForm($this, $this->profile);
$ubf->show();
@ -366,7 +367,7 @@ class ShowstreamAction extends Action
$url = common_local_url('remotesubscribe',
array('nickname' => $this->profile->nickname));
$this->element('a', array('href' => $url,
'id' => 'user_subscribe_remote'),
'id' => 'entity_subscribe_remote'),
_('Subscribe'));
}
@ -383,17 +384,17 @@ class ShowstreamAction extends Action
function showSections()
{
$this->showStatistics();
$this->showSubscriptions();
$this->showSubscribers();
$this->showGroups();
$this->showStatistics();
}
function showSubscriptions()
{
$profile = $this->user->getSubscriptions(0, PROFILES_PER_MINILIST + 1);
$this->elementStart('div', array('id' => 'user_subscriptions',
$this->elementStart('div', array('id' => 'entity_subscriptions',
'class' => 'section'));
$this->element('h2', null, _('Subscriptions'));
@ -410,7 +411,7 @@ class ShowstreamAction extends Action
$this->elementStart('p');
$this->element('a', array('href' => common_local_url('subscriptions',
array('nickname' => $this->profile->nickname)),
'class' => 'mores'),
'class' => 'more'),
_('All subscriptions'));
$this->elementEnd('p');
}
@ -422,7 +423,7 @@ class ShowstreamAction extends Action
{
$profile = $this->user->getSubscribers(0, PROFILES_PER_MINILIST + 1);
$this->elementStart('div', array('id' => 'user_subscribers',
$this->elementStart('div', array('id' => 'entity_subscribers',
'class' => 'section'));
$this->element('h2', null, _('Subscribers'));
@ -439,7 +440,7 @@ class ShowstreamAction extends Action
$this->elementStart('p');
$this->element('a', array('href' => common_local_url('subscribers',
array('nickname' => $this->profile->nickname)),
'class' => 'mores'),
'class' => 'more'),
_('All subscribers'));
$this->elementEnd('p');
}
@ -462,19 +463,19 @@ class ShowstreamAction extends Action
$notices->profile_id = $this->profile->id;
$notice_count = (int) $notices->count();
$this->elementStart('div', array('id' => 'user_statistics',
$this->elementStart('div', array('id' => 'entity_statistics',
'class' => 'section'));
$this->element('h2', null, _('Statistics'));
// Other stats...?
$this->elementStart('dl', 'user_member-since');
$this->elementStart('dl', 'entity_member-since');
$this->element('dt', null, _('Member since'));
$this->element('dd', null, date('j M Y',
strtotime($this->profile->created)));
$this->elementEnd('dl');
$this->elementStart('dl', 'user_subscriptions');
$this->elementStart('dl', 'entity_subscriptions');
$this->elementStart('dt');
$this->element('a', array('href' => common_local_url('subscriptions',
array('nickname' => $this->profile->nickname))),
@ -483,7 +484,7 @@ class ShowstreamAction extends Action
$this->element('dd', null, (is_int($subs_count)) ? $subs_count : '0');
$this->elementEnd('dl');
$this->elementStart('dl', 'user_subscribers');
$this->elementStart('dl', 'entity_subscribers');
$this->elementStart('dt');
$this->element('a', array('href' => common_local_url('subscribers',
array('nickname' => $this->profile->nickname))),
@ -492,7 +493,7 @@ class ShowstreamAction extends Action
$this->element('dd', 'subscribers', (is_int($subbed_count)) ? $subbed_count : '0');
$this->elementEnd('dl');
$this->elementStart('dl', 'user_notices');
$this->elementStart('dl', 'entity_notices');
$this->element('dt', null, _('Notices'));
$this->element('dd', null, (is_int($notice_count)) ? $notice_count : '0');
$this->elementEnd('dl');
@ -504,7 +505,7 @@ class ShowstreamAction extends Action
{
$groups = $this->user->getGroups(0, GROUPS_PER_MINILIST + 1);
$this->elementStart('div', array('id' => 'user_groups',
$this->elementStart('div', array('id' => 'entity_groups',
'class' => 'section'));
$this->element('h2', null, _('Groups'));
@ -521,7 +522,7 @@ class ShowstreamAction extends Action
$this->elementStart('p');
$this->element('a', array('href' => common_local_url('usergroups',
array('nickname' => $this->profile->nickname)),
'class' => 'mores'),
'class' => 'more'),
_('All groups'));
$this->elementEnd('p');
}

View File

@ -0,0 +1,46 @@
$(function(){
var x = ($('#avatar_crop_x').val()) ? $('#avatar_crop_x').val() : 0;
var y = ($('#avatar_crop_y').val()) ? $('#avatar_crop_y').val() : 0;
var w = ($('#avatar_crop_w').val()) ? $('#avatar_crop_w').val() : $("#avatar_original img").attr("width");
var h = ($('#avatar_crop_h').val()) ? $('#avatar_crop_h').val() : $("#avatar_original img").attr("height");
jQuery("#avatar_original img").Jcrop({
onChange: showPreview,
setSelect: [ x, y, w, h ],
onSelect: updateCoords,
aspectRatio: 1,
boxWidth: 480,
boxHeight: 480,
bgColor: '#000',
bgOpacity: .4
});
});
function showPreview(coords) {
var rx = 96 / coords.w;
var ry = 96 / coords.h;
var img_width = $("#avatar_original img").attr("width");
var img_height = $("#avatar_original img").attr("height");
$('#avatar_preview img').css({
width: Math.round(rx *img_width) + 'px',
height: Math.round(ry * img_height) + 'px',
marginLeft: '-' + Math.round(rx * coords.x) + 'px',
marginTop: '-' + Math.round(ry * coords.y) + 'px'
});
};
function updateCoords(c) {
$('#avatar_crop_x').val(c.x);
$('#avatar_crop_y').val(c.y);
$('#avatar_crop_w').val(c.w);
$('#avatar_crop_h').val(c.h);
};
function checkCoords() {
if (parseInt($('#avatar_crop_w').val())) return true;
alert('Please select a crop region then press submit.');
return false;
};

View File

@ -1,41 +0,0 @@
$(function(){
jQuery("#photo_original img").Jcrop({
onChange: showPreview,
setSelect: [ 0, 0, $("#photo_original img").attr("width"), $("#photo_original img").attr("height") ],
onSelect: updateCoords,
aspectRatio: 1,
boxWidth: 480,
boxHeight: 480,
bgColor: '#000',
bgOpacity: .4
});
});
function showPreview(coords) {
var rx = 96 / coords.w;
var ry = 96 / coords.h;
var img_width = $("#photo_original img").attr("width");
var img_height = $("#photo_original img").attr("height");
$('#photo_preview img').css({
width: Math.round(rx *img_width) + 'px',
height: Math.round(ry * img_height) + 'px',
marginLeft: '-' + Math.round(rx * coords.x) + 'px',
marginTop: '-' + Math.round(ry * coords.y) + 'px'
});
};
function updateCoords(c) {
$('#photo_crop_x').val(c.x);
$('#photo_crop_y').val(c.y);
$('#photo_crop_w').val(c.w);
$('#photo_crop_h').val(c.h);
};
function checkCoords() {
if (parseInt($('#photo_crop_w').val())) return true;
alert('Please select a crop region then press submit.');
return false;
};

View File

@ -108,16 +108,16 @@ $(document).ready(function(){
$("form.form_group_join").each(addAjaxHidden);
$("form.form_group_leave").each(addAjaxHidden);
$("#nudge").ajaxForm ({ dataType: 'xml',
beforeSubmit: function(xml) { $("form#nudge input[type=submit]").attr("disabled", "disabled");
$("form#nudge input[type=submit]").addClass("disabled");
$("#form_user_nudge").ajaxForm ({ dataType: 'xml',
beforeSubmit: function(xml) { $("#form_user_nudge input[type=submit]").attr("disabled", "disabled");
$("#form_user_nudge input[type=submit]").addClass("disabled");
},
success: function(xml) { $("#nudge").replaceWith(document._importNode($("#nudge_response", xml).get(0),true));
$("#nudge input[type=submit]").removeAttr("disabled");
$("#nudge input[type=submit]").removeClass("disabled");
success: function(xml) { $("#form_user_nudge").replaceWith(document._importNode($("#nudge_response", xml).get(0),true));
$("#form_user_nudge input[type=submit]").removeAttr("disabled");
$("#form_user_nudge input[type=submit]").removeClass("disabled");
}
});
$("#nudge").each(addAjaxHidden);
$("#form_user_nudge").each(addAjaxHidden);
var Subscribe = { dataType: 'xml',
beforeSubmit: function(formData, jqForm, options) { $(".form_user_subscribe input[type=submit]").attr("disabled", "disabled");

View File

@ -53,7 +53,6 @@ require_once INSTALLDIR.'/lib/htmloutputter.php';
*
* @see HTMLOutputter
*/
class Action extends HTMLOutputter // lawsuit
{
var $args;
@ -69,20 +68,30 @@ class Action extends HTMLOutputter // lawsuit
* @see XMLOutputter::__construct
* @see HTMLOutputter::__construct
*/
function __construct($output='php://output', $indent=true)
{
parent::__construct($output, $indent);
}
// For initializing members of the class
/**
* For initializing members of the class.
*
* @param array $argarray misc. arguments
*
* @return boolean true
*/
function prepare($argarray)
{
$this->args =& common_copy_args($argarray);
return true;
}
/**
* Show page, a template method.
*
* @return nothing
*/
function showPage()
{
$this->startHTML();
@ -91,6 +100,11 @@ class Action extends HTMLOutputter // lawsuit
$this->endHTML();
}
/**
* Show head, a template method.
*
* @return nothing
*/
function showHead()
{
// XXX: attributes (profile?)
@ -105,6 +119,11 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('head');
}
/**
* Show title, a template method.
*
* @return nothing
*/
function showTitle()
{
$this->element('title', null,
@ -113,13 +132,24 @@ class Action extends HTMLOutputter // lawsuit
common_config('site', 'name')));
}
// SHOULD overload
/**
* Returns the page title
*
* SHOULD overload
*
* @return string page title
*/
function title()
{
return _("Untitled page");
}
/**
* Show stylesheets
*
* @return nothing
*/
function showStylesheets()
{
$this->element('link', array('rel' => 'stylesheet',
@ -145,6 +175,11 @@ class Action extends HTMLOutputter // lawsuit
}
}
/**
* Show javascript headers
*
* @return nothing
*/
function showScripts()
{
$this->element('script', array('type' => 'text/javascript',
@ -161,38 +196,66 @@ class Action extends HTMLOutputter // lawsuit
' ');
}
/**
* Show OpenSearch headers
*
* @return nothing
*/
function showOpenSearch()
{
$this->element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml',
$this->element('link', array('rel' => 'search',
'type' => 'application/opensearchdescription+xml',
'href' => common_local_url('opensearch', array('type' => 'people')),
'title' => common_config('site', 'name').' People Search'));
$this->element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml',
'href' => common_local_url('opensearch', array('type' => 'notice')),
'title' => common_config('site', 'name').' Notice Search'));
}
// MAY overload
/**
* Show feed headers
*
* MAY overload
*
* @return nothing
*/
function showFeeds()
{
// does nothing by default
}
// SHOULD overload
/**
* Show description.
*
* SHOULD overload
*
* @return nothing
*/
function showDescription()
{
// does nothing by default
}
// MAY overload
/**
* Show extra stuff in <head>.
*
* MAY overload
*
* @return nothing
*/
function extraHead()
{
// does nothing by default
}
/**
* Show body.
*
* Calls template methods
*
* @return nothing
*/
function showBody()
{
$this->elementStart('body', array('id' => $this->trimmed('action')));
@ -204,6 +267,13 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('body');
}
/**
* Show header of the page.
*
* Calls template methods
*
* @return nothing
*/
function showHeader()
{
$this->elementStart('div', array('id' => 'header'));
@ -218,14 +288,18 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('div');
}
/**
* Show configured logo.
*
* @return nothing
*/
function showLogo()
{
$this->elementStart('address', array('id' => 'site_contact',
'class' => 'vcard'));
$this->elementStart('a', array('class' => 'url home bookmark',
'href' => common_local_url('public')));
if (common_config('site', 'logo') || file_exists(theme_file('logo.png')))
{
if (common_config('site', 'logo') || file_exists(theme_file('logo.png'))) {
$this->element('img', array('class' => 'logo photo',
'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : theme_path('logo.png'),
'alt' => common_config('site', 'name')));
@ -235,6 +309,11 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('address');
}
/**
* Show primary navigation.
*
* @return nothing
*/
function showPrimaryNav()
{
$this->elementStart('dl', array('id' => 'site_nav_global_primary'));
@ -272,9 +351,14 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dl');
}
// Revist. Should probably do an hAtom pattern here
/**
* Show site notice.
*
* @return nothing
*/
function showSiteNotice()
{
// Revist. Should probably do an hAtom pattern here
$text = common_config('site', 'notice');
if ($text) {
$this->elementStart('dl', array('id' => 'site_notice',
@ -285,19 +369,38 @@ class Action extends HTMLOutputter // lawsuit
}
}
// MAY overload if no notice form needed... or direct message box????
/**
* Show notice form.
*
* MAY overload if no notice form needed... or direct message box????
*
* @return nothing
*/
function showNoticeForm()
{
$notice_form = new NoticeForm($this);
$notice_form->show();
}
/**
* Show anonymous message.
*
* SHOULD overload
*
* @return nothing
*/
function showAnonymousMessage()
{
// needs to be defined by the class
}
/**
* Show core.
*
* Shows local navigation, content block and aside.
*
* @return nothing
*/
function showCore()
{
$this->elementStart('div', array('id' => 'core'));
@ -307,6 +410,11 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('div');
}
/**
* Show local navigation block.
*
* @return nothing
*/
function showLocalNavBlock()
{
$this->elementStart('dl', array('id' => 'site_nav_local_views'));
@ -317,13 +425,23 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dl');
}
// SHOULD overload
/**
* Show local navigation.
*
* SHOULD overload
*
* @return nothing
*/
function showLocalNav()
{
// does nothing by default
}
/**
* Show content block.
*
* @return nothing
*/
function showContentBlock()
{
$this->elementStart('div', array('id' => 'content'));
@ -336,10 +454,21 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('div');
}
function showPageTitle() {
$this->element('h1', NULL, $this->title());
/**
* Show page title.
*
* @return nothing
*/
function showPageTitle()
{
$this->element('h1', null, $this->title());
}
/**
* Show page notice block.
*
* @return nothing
*/
function showPageNoticeBlock()
{
$this->elementStart('dl', array('id' => 'page_notice',
@ -351,18 +480,33 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dl');
}
// SHOULD overload (unless there's not a notice)
/**
* Show page notice.
*
* SHOULD overload (unless there's not a notice)
*
* @return nothing
*/
function showPageNotice()
{
}
// MUST overload
/**
* Show content.
*
* MUST overload (unless there's not a notice)
*
* @return nothing
*/
function showContent()
{
}
/**
* Show Aside.
*
* @return nothing
*/
function showAside()
{
$this->elementStart('div', array('id' => 'aside_primary',
@ -372,8 +516,13 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('div');
}
// MAY overload if there are feeds
/**
* Show export data feeds.
*
* MAY overload if there are feeds
*
* @return nothing
*/
function showExportData()
{
// is there structure to this?
@ -381,12 +530,23 @@ class Action extends HTMLOutputter // lawsuit
// can we reuse list of feeds from showFeeds() ?
}
// SHOULD overload
function showSections() {
/**
* Show sections.
*
* SHOULD overload
*
* @return nothing
*/
function showSections()
{
// for each section, show it
}
/**
* Show footer.
*
* @return nothing
*/
function showFooter()
{
$this->elementStart('div', array('id' => 'footer'));
@ -395,6 +555,11 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('div');
}
/**
* Show secondary navigation.
*
* @return nothing
*/
function showSecondaryNav()
{
$this->elementStart('dl', array('id' => 'site_nav_global_secondary'));
@ -418,6 +583,11 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dl');
}
/**
* Show licenses.
*
* @return nothing
*/
function showLicenses()
{
$this->elementStart('dl', array('id' => 'licenses'));
@ -426,6 +596,11 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dl');
}
/**
* Show Laconica license.
*
* @return nothing
*/
function showLaconicaLicense()
{
$this->element('dt', array('id' => 'site_laconica_license'), _('Laconica software license'));
@ -442,6 +617,11 @@ class Action extends HTMLOutputter // lawsuit
// do it
}
/**
* Show content license.
*
* @return nothing
*/
function showContentLicense()
{
$this->element('dt', array('id' => 'site_content_license'), _('Laconica software license'));
@ -461,24 +641,52 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dd');
}
// For comparison with If-Last-Modified
// If not applicable, return null
/**
* Return last modified, if applicable.
*
* MAY override
*
* @return string last modified http header
*/
function lastModified()
{
// For comparison with If-Last-Modified
// If not applicable, return null
return null;
}
/**
* Return etag, if applicable.
*
* MAY override
*
* @return string etag http header
*/
function etag()
{
return null;
}
/**
* Return true if read only.
*
* MAY override
*
* @return boolean is read only action?
*/
function isReadOnly()
{
return false;
}
/**
* 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?
*/
function arg($key, $def=null)
{
if (array_key_exists($key, $this->args)) {
@ -488,24 +696,34 @@ class Action extends HTMLOutputter // lawsuit
}
}
/**
* 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?
*/
function trimmed($key, $def=null)
{
$arg = $this->arg($key, $def);
return (is_string($arg)) ? trim($arg) : $arg;
return is_string($arg) ? trim($arg) : $arg;
}
// Note: argarray ignored, since it's now passed in in prepare()
/**
* Handler method
*
* @param array $argarray is ignored since it's now passed in in prepare()
*
* @return boolean is read only action?
*/
function handle($argarray=null)
{
$lm = $this->lastModified();
$etag = $this->etag();
if ($etag) {
header('ETag: ' . $etag);
}
if ($lm) {
header('Last-Modified: ' . date(DATE_RFC1123, $lm));
$if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
@ -523,11 +741,27 @@ class Action extends HTMLOutputter // lawsuit
}
}
/**
* Has etag? (private)
*
* @param string $etag etag http header
* @param string $if_none_match ifNoneMatch http header
*
* @return boolean
*/
function _hasEtag($etag, $if_none_match)
{
return ($if_none_match) && in_array($etag, explode(',', $if_none_match));
}
/**
* Boolean understands english (yes, no, true, false)
*
* @param string $key query key we're interested in
* @param string $def default value
*
* @return boolean interprets yes/no strings as boolean
*/
function boolean($key, $def=false)
{
$arg = strtolower($this->trimmed($key));
@ -543,6 +777,14 @@ class Action extends HTMLOutputter // lawsuit
}
}
/**
* Server error
*
* @param string $msg error message to display
* @param integer $code http error code, 500 by default
*
* @return nothing
*/
function serverError($msg, $code=500)
{
$action = $this->trimmed('action');
@ -550,6 +792,14 @@ class Action extends HTMLOutputter // lawsuit
common_server_error($msg, $code);
}
/**
* Client error
*
* @param string $msg error message to display
* @param integer $code http error code, 400 by default
*
* @return nothing
*/
function clientError($msg, $code=400)
{
$action = $this->trimmed('action');
@ -557,6 +807,11 @@ class Action extends HTMLOutputter // lawsuit
common_user_error($msg, $code);
}
/**
* Returns the current URL
*
* @return string current URL
*/
function selfUrl()
{
$action = $this->trimmed('action');
@ -568,11 +823,21 @@ class Action extends HTMLOutputter // lawsuit
return common_local_url($action, $args);
}
// Added @id to li for some control.
// XXX: We might want to move this to htmloutputter.php
/**
* 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
*/
function menuItem($url, $text, $title=null, $is_selected=false, $id=null)
{
// Added @id to li for some control.
// XXX: We might want to move this to htmloutputter.php
$lattrs = array();
if ($is_selected) {
$lattrs['class'] = 'current';
@ -589,10 +854,20 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('li');
}
// Does a little before-after block for next/prev page
/**
* 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
*/
function pagination($have_before, $have_after, $page, $action, $args=null)
{
// Does a little before-after block for next/prev page
if ($have_before || $have_after) {
$this->elementStart('div', array('class' => 'pagination'));
$this->elementStart('dl', null);
@ -600,26 +875,22 @@ class Action extends HTMLOutputter // lawsuit
$this->elementStart('dd', null);
$this->elementStart('ul', array('class' => 'nav'));
}
if ($have_before) {
$pargs = array('page' => $page-1);
$newargs = ($args) ? array_merge($args,$pargs) : $pargs;
$newargs = $args ? array_merge($args, $pargs) : $pargs;
$this->elementStart('li', array('class' => 'nav_prev'));
$this->element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'prev'),
_('After'));
$this->elementEnd('li');
}
if ($have_after) {
$pargs = array('page' => $page+1);
$newargs = ($args) ? array_merge($args,$pargs) : $pargs;
$newargs = $args ? array_merge($args, $pargs) : $pargs;
$this->elementStart('li', array('class' => 'nav_next'));
$this->element('a', array('href' => common_local_url($action, $newargs), 'rel' => 'next'),
_('Before'));
$this->elementEnd('li');
}
if ($have_before || $have_after) {
$this->elementEnd('ul');
$this->elementEnd('dd');

View File

@ -150,6 +150,6 @@ class BlockForm extends Form
function formActions()
{
$this->out->submit('submit', _('block'), 'submit', null, _('Block this user'));
$this->out->submit('submit', _('Block'), 'submit', null, _('Block this user'));
}
}

136
lib/error.php Normal file
View File

@ -0,0 +1,136 @@
<?php
/**
* Error action.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
*
* 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.
*
* 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.
*
* 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/>.
*/
if (!defined('LACONICA')) {
exit(1);
}
/**
* Base class for displaying HTTP errors
*
* @category Action
* @package Laconica
* @author Zach Copley <zach@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class ErrorAction extends Action
{
var $code = null;
var $message = null;
var $status = null;
var $default = null;
function __construct($message, $code, $output='php://output', $indent=true)
{
parent::__construct($output, $indent);
$this->code = $code;
$this->message = $message;
// XXX: hack alert: usually we aren't going to
// call this page directly, but because it's
// an action it needs an args array anyway
$this->prepare($_REQUEST);
}
/**
* To specify additional HTTP headers for the action
*
* @return void
*/
function extraHeaders()
{
$status_string = $this->status[$this->code];
header('HTTP/1.1 '.$this->code.' '.$status_string);
}
/**
* Display content.
*
* @return nothing
*/
function showContent()
{
$this->element('div', array('class' => 'error'), $this->message);
}
/**
* Page title.
*
* @return page title
*/
function title()
{
return $this->message;
}
function isReadOnly()
{
return true;
}
function showPage()
{
parent::showPage();
// We don't want to have any more output after this
exit();
}
// Overload a bunch of stuff so the page isn't too bloated
function showBody()
{
$this->elementStart('body', array('id' => 'error'));
$this->elementStart('div', 'wrap');
$this->showHeader();
$this->showCore();
$this->showFooter();
$this->elementEnd('div');
$this->elementEnd('body');
}
function showCore()
{
$this->elementStart('div', array('id' => 'core'));
$this->showContentBlock();
$this->elementEnd('div');
}
function showHeader()
{
$this->elementStart('div', array('id' => 'header'));
$this->showLogo();
$this->elementEnd('div');
}
}

View File

@ -78,9 +78,9 @@ class GroupEditForm extends Form
function id()
{
if ($this->group) {
return 'group_edit-' . $this->group->id;
return 'form_group_edit-' . $this->group->id;
} else {
return 'group_add';
return 'form_group_add';
}
}
@ -92,7 +92,7 @@ class GroupEditForm extends Form
function formClass()
{
return 'form_group_add';
return 'form_settings';
}
/**
@ -111,6 +111,18 @@ class GroupEditForm extends Form
}
}
/**
* Name of the form
*
* @return void
*/
function formLegend()
{
$this->out->element('legend', null, _('Create a new group'));
}
/**
* Data elements of the form
*
@ -121,6 +133,7 @@ class GroupEditForm extends Form
{
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li');
$this->out->hidden('groupid', $this->group->id);
$this->out->input('nickname', _('Nickname'),
($this->out->arg('nickname')) ? $this->out->arg('nickname') : $this->group->nickname,
_('1-64 lowercase letters or numbers, no punctuation or spaces'));
@ -135,7 +148,7 @@ class GroupEditForm extends Form
_('URL of the homepage or blog of the group or topic'));
$this->out->elementEnd('li');
$this->out->elementStart('li');
$this->out->textarea('description', _('description'),
$this->out->textarea('description', _('Description'),
($this->out->arg('description')) ? $this->out->arg('description') : $this->group->description,
_('Describe the group or topic in 140 chars'));
$this->out->elementEnd('li');

View File

@ -49,7 +49,7 @@ class GroupMiniList extends GroupList
{
function show()
{
$this->out->elementStart('ul', 'groups');
$this->out->elementStart('ul', 'entities groups xoxo');
$cnt = 0;
@ -73,7 +73,7 @@ class GroupMiniList extends GroupList
$this->group->fullname :
$this->group->nickname,
'href' => $this->group->homeUrl(),
'rel' => 'contact',
'rel' => 'contact group',
'class' => 'url'));
$logo = ($this->group->stream_logo) ?
$this->group->stream_logo : User_group::defaultLogo(AVATAR_STREAM_SIZE);
@ -85,7 +85,7 @@ class GroupMiniList extends GroupList
'alt' => ($this->group->fullname) ?
$this->group->fullname :
$this->group->nickname));
$this->out->element('span', 'fn nickname', $this->group->nickname);
$this->out->element('span', 'fn org nickname', $this->group->nickname);
$this->out->elementEnd('a');
$this->out->elementEnd('li');
}

View File

@ -109,6 +109,8 @@ class HTMLOutputter extends XMLOutputter
header('Content-Type: '.$type);
$this->extraHeaders();
$this->startXML('html',
'-//W3C//DTD XHTML 1.0 Strict//EN',
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
@ -133,6 +135,16 @@ class HTMLOutputter extends XMLOutputter
$this->endXML();
}
/**
* To specify additional HTTP headers for the action
*
* @return void
*/
function extraHeaders()
{
// Needs to be overloaded
}
/**
* Output an HTML text input element
*

View File

@ -93,8 +93,7 @@ class ProfileList extends Widget
$user = common_current_user();
$this->out->elementStart('div', array('id' => 'user_profile',
'class' => 'vcard'));
$this->out->elementStart('div', 'entity_profile vcard');
$avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
$this->out->elementStart('a', array('href' => $this->profile->profileurl,
@ -113,7 +112,7 @@ class ProfileList extends Widget
$this->out->elementEnd('a');
if ($this->profile->fullname) {
$this->out->elementStart('dl', 'user_fn');
$this->out->elementStart('dl', 'entity_fn');
$this->out->element('dt', null, 'Full name');
$this->out->elementStart('dd');
$this->out->elementStart('span', 'fn');
@ -123,7 +122,7 @@ class ProfileList extends Widget
$this->out->elementEnd('dl');
}
if ($this->profile->location) {
$this->out->elementStart('dl', 'user_location');
$this->out->elementStart('dl', 'entity_location');
$this->out->element('dt', null, _('Location'));
$this->out->elementStart('dd', 'location');
$this->out->raw($this->highlight($this->profile->location));
@ -131,7 +130,7 @@ class ProfileList extends Widget
$this->out->elementEnd('dl');
}
if ($this->profile->homepage) {
$this->out->elementStart('dl', 'user_url');
$this->out->elementStart('dl', 'entity_url');
$this->out->element('dt', null, _('URL'));
$this->out->elementStart('dd');
$this->out->elementStart('a', array('href' => $this->profile->homepage,
@ -142,7 +141,7 @@ class ProfileList extends Widget
$this->out->elementEnd('dl');
}
if ($this->profile->bio) {
$this->out->elementStart('dl', 'user_note');
$this->out->elementStart('dl', 'entity_note');
$this->out->element('dt', null, _('Note'));
$this->out->elementStart('dd', 'note');
$this->out->raw($this->highlight($this->profile->bio));
@ -156,7 +155,7 @@ class ProfileList extends Widget
# Get tags
$tags = Profile_tag::getTags($this->owner->id, $this->profile->id);
$this->out->elementStart('dl', 'user_tags');
$this->out->elementStart('dl', 'entity_tags');
$this->out->elementStart('dt');
if ($user->id == $this->owner->id) {
$this->out->element('a', array('href' => common_local_url('tagother',

View File

@ -49,7 +49,7 @@ class ProfileMiniList extends ProfileList
{
function show()
{
$this->out->elementStart('ul', 'users');
$this->out->elementStart('ul', 'entities users xoxo');
$cnt = 0;
@ -73,7 +73,7 @@ class ProfileMiniList extends ProfileList
$this->profile->fullname :
$this->profile->nickname,
'href' => $this->profile->profileurl,
'rel' => 'contact',
'rel' => 'contact member',
'class' => 'url'));
$avatar = $this->profile->getAvatar(AVATAR_MINI_SIZE);
$this->out->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)),

View File

@ -1588,11 +1588,6 @@ function common_session_token()
return $_SESSION['token'];
}
function common_nudge_response()
{
common_element('p', array('id' => 'nudge_response'), _('Nudge sent!'));
}
function common_cache_key($extra)
{
return 'laconica:' . common_keyize(common_config('site', 'name')) . ':' . $extra;

View File

@ -34,8 +34,6 @@ h6 { font-size:0.9em; }
caption {
font-weight:bold;
}
.opened { display: block !important;}
.closed { display: none !important;}
legend {
font-weight:bold;
@ -56,6 +54,7 @@ border-radius:4px;
-moz-border-radius:4px;
-webkit-border-radius:4px;
}
input.submit {
font-weight:bold;
}
@ -79,9 +78,6 @@ form label {
font-weight:bold;
/*margin:0 0 11px 0;*/
}
form ul li input {
}
input.checkbox {
position:relative;
top:2px;
@ -147,7 +143,11 @@ font-weight:bold;
#form_settings_profile legend,
#form_login legend,
#form_register legend {
#form_register legend,
#form_password legend,
#form_settings_avatar legend,
#newgroup legend,
#editgroup legend {
display:none;
}
@ -187,6 +187,8 @@ border-radius:4px;
padding:0 7px;
}
/* FORM SETTINGS */
@ -443,7 +445,7 @@ margin-left:4px;
#form_notice .form_note {
position:absolute;
top:120px;
top:118px;
right:98px;
z-index:9;
}
@ -455,10 +457,11 @@ display:none;
#notice_text-count {
font-weight:bold;
line-height:1.15;
padding:1px 2px;
}
#form_notice #notice_data-attach_view {
/*position:absolute;*/
position:absolute;
top:25px;
right:30px;
margin-left:4px;
@ -502,8 +505,8 @@ float:left;
/* user_profile */
#user_profile {
/* entity_profile */
.entity_profile {
position:relative;
width:475px;
min-height:123px;
@ -511,23 +514,23 @@ float:left;
margin-bottom:17px;
margin-left:0;
}
#user_profile dt,
#user_statistics dt {
.entity_profile dt,
#entity_statistics dt {
font-weight:bold;
}
#user_profile .user_depiction {
.entity_profile .entity_depiction {
float:left;
position:absolute;
top:0;
left:0;
width:96px;
}
#user_profile .user_fn,
#user_profile .user_nickname,
#user_profile .user_location,
#user_profile .user_url,
#user_profile .user_note,
#user_profile .user_tags {
.entity_profile .entity_fn,
.entity_profile .entity_nickname,
.entity_profile .entity_location,
.entity_profile .entity_url,
.entity_profile .entity_note,
.entity_profile .entity_tags {
float:left;
clear:left;
margin-left:113px;
@ -535,84 +538,82 @@ width:322px;
margin-bottom:4px;
}
#user_profile .user_fn,
#user_profile .user_nickname {
.entity_profile .entity_fn,
.entity_profile .entity_nickname {
width:auto;
clear:none;
}
#user_profile .user_fn {
.entity_profile .entity_fn {
margin-left:11px;
margin-right:4px;
}
#user_profile .user_fn .fn {
.entity_profile .entity_fn .fn {
font-weight:bold;
font-style:normal;
}
#user_profile .nickname {
.entity_profile .nickname {
font-style:italic;
font-weight:bold;
}
#user_profile .user_fn dd:before {
.entity_profile .entity_fn dd:before {
content: "(";
font-weight:normal;
}
#user_profile .user_fn dd:after {
.entity_profile .entity_fn dd:after {
content: ")";
font-weight:normal;
}
#user_profile dt {
.entity_profile dt {
display:none;
}
#user_profile h2 {
.entity_profile h2 {
display:none;
}
/* user_profile */
/* entity_profile */
/*user_actions*/
#user_actions {
clear:left;
float:left;
position:absolute;
top:0;
right:0;
/*entity_actions*/
.entity_actions {
float:right;
}
#user_actions h2 {
.entity_actions h2 {
display:none;
}
#user_actions ul {
.entity_actions ul {
list-style-type:none;
}
#user_actions li {
.entity_actions li {
margin-bottom:4px;
}
#user_actions li:first-child {
.entity_actions li:first-child {
border-top:0;
}
#user_actions fieldset {
.entity_actions fieldset {
border:0;
padding:0;
}
#user_actions legend {
.entity_actions legend {
display:none;
}
#user_actions input.submit {
.entity_actions input.submit {
display:block;
text-align:left;
cursor:pointer;
width:100%;
}
#user_actions a {
.entity_actions a,
#entity_nudge p {
text-decoration:none;
font-weight:bold;
width:100%;
display:block;
}
@ -620,35 +621,24 @@ display:block;
.form_user_block input.submit,
.form_user_unblock input.submit,
#user_send-a-message a,
.form_user_nudge input.submit {
#entity_send-a-message a,
.form_user_nudge input.submit,
#entity_nudge p {
border:0;
padding-left:20px;
}
#user_send-a-message a {
#entity_send-a-message a,
#entity_nudge p {
padding:4px 4px 4px 23px;
}
#user_subscribe input.submit,
.form_user_subscribe input.submit {
}
#user_send-a-message form {
}
#user_send-a-message textarea {
}
.user_tags ul {
.entity_tags ul {
list-style-type:none;
}
.user_tags li {
.entity_tags li {
display:inline;
margin-right:1em;
float:left;
@ -659,41 +649,43 @@ float:left;
.aside .section {
margin-bottom:29px;
clear:both;
float:left;
width:100%;
}
.aside .section h2 {
text-transform:uppercase;
font-size:1em;
}
#user_statistics dt,
#user_statistics dd {
#entity_statistics dt,
#entity_statistics dd {
display:inline;
}
#user_statistics dt:after {
#entity_statistics dt:after {
content: ":";
}
#user_subscriptions,
#user_subscriptions-common {
float:left;
#user_subscribers,
#user_groups, {
}
#user_subscriptions ul.users {
.section ul.entities {
width:220px;
float:left;
}
#user_subscriptions .users li {
.section .entities li {
list-style-type:none;
float:left;
margin-right:7px;
margin-bottom:7px;
}
#user_subscriptions .users li .photo {
width:24px;
height:24px;
.section .entities li .photo {
margin-right:0;
margin-bottom:0;
}
#user_subscriptions .users li .fn {
.section .entities li .fn {
display:none;
}
.aside .section .more {
@ -702,29 +694,36 @@ clear:both;
.profile #user_profile {
.profile .entity_profile {
margin-bottom:0;
min-height:60px;
}
.profile .form_user_subscribe,
.profile .form_user_unsubscribe {
float:right;
}
.profile .form_user_subscribe legend,
.profile .form_user_unsubscribe legend {
display:none;
}
.profiles {
list-style-type:none;
}
.profile #user_profile .user_location {
.profile .entity_profile .entity_location {
width:auto;
clear:none;
margin-left:11px;
}
.profile #user_profile dl,
.profile #user_profile dd {
.profile .entity_profile dl,
.profile .entity_profile dd {
display:inline;
float:none;
}
.profile #user_profile .user_note,
.profile #user_profile .user_url {
.profile .entity_profile .entity_note,
.profile .entity_profile .entity_url {
margin-left:59px;
clear:none;
display:block;
@ -933,7 +932,7 @@ outline:none;
}
.notice-options .notice_reply a,
.notice-options form input.submit {
.notice-options input.submit {
display:block;
border:0;
}
@ -1016,18 +1015,18 @@ border-right:0;
/*If there is hentry on #content_inner, this doesn't need to be specific to #doc */
#doc #content_inner p {
/*If there is hentry on #content_inner, then this doesn't need to be specific to #doc or any other section */
.hentry .entry-content p {
margin-bottom:18px;
}
#doc #content_inner ol,
#doc #content_inner ul {
.hentry entry-content ol,
.hentry .entry-content ul {
list-style-position:inside;
}
#doc #content_inner li {
.hentry .entry-content li {
margin-bottom:18px;
}
#doc #content_inner li li {
.hentry .entry-content li li {
margin-left:18px;
}
@ -1049,9 +1048,9 @@ background-color:#D1D9E4;
#user_actions #user_subscribe .form_note,
#user_actions #user_subscribe .form_data,
#user_actions #user_subscribe .form_actions label {
.entity_actions #user_subscribe .form_note,
.entity_actions #user_subscribe .form_data,
.entity_actions #user_subscribe .form_actions label {
display:none;
}
#form_user-relationship .form_note,
@ -1060,7 +1059,7 @@ display:none;
display:block;
}
#user_actions #user-relationship_submit {
.entity_actions #user-relationship_submit {
margin-bottom:0;
}
#form_user-relationship .form_data li label {
@ -1160,52 +1159,65 @@ clear:both;
#photo_original,
#photo_preview {
#form_settings_avatar li {
width:auto;
}
#form_settings_avatar input {
margin-left:0;
}
#avatar_original,
#avatar_preview {
float:left;
}
#photo_preview,
#settings_photo_action-crop {
#avatar_preview {
margin-left:29px;
}
#photo_preview_view {
#avatar_preview_view {
height:96px;
width:96px;
margin-bottom:18px;
overflow:hidden;
}
#settings_attach,
#form_settings_avatar .form_actions {
clear:both;
}
#form_settings_avatar .form_actions {
margin-bottom:0;
}
.section .groups,
#groups_related ul,
#users_featured ul {
list-style-type:none;
}
.section .groups li,
#groups_related li,
#users_featured li {
margin-top:11px;
float:left;
width:100%;
}
.section .groups li:first-child,
#groups_related li:first-child,
#users_featured li:first-child {
margin-top:0;
}
.section .groups .vcard,
#groups_related .vcard,
#users_featured .vcard {
float:left;
margin-bottom:-23px;
}
.section .groups dl,
#groups_related dl,
#users_featured dl {
float:left;
margin-left:63px;
clear:left;
}
.section .groups dt,
#groups_related dt,
#users_featured dt {
display:none;
font-weight:bold;

View File

@ -3,7 +3,7 @@
#aside_primary {
padding-left:11px;
}
.notice-options form input.submit {
.notice-options input.submit {
font-size:0;
margin-top:3px;
height:16px;
@ -24,3 +24,7 @@ margin-left:-7px;
.notice div.entry-content .timestamp a {
margin-right:4px;
}
.entity_profile .entity_nickname {
padding-right:3px;
}

8
theme/base/css/ie6.css Normal file
View File

@ -0,0 +1,8 @@
/* IE6 specific styles */
.entity_profile .entity_nickname,
.entity_profile .entity_location,
.entity_profile .entity_url,
.entity_profile .entity_note,
.entity_profile .entity_tags {
margin-left:55px;
}

View File

@ -22,6 +22,7 @@ input, textarea, select {
border-color:#aaa;
}
input.submit,
#form_notice.warning #notice_text-count,
#nav_register a,
@ -42,8 +43,9 @@ a,
div.notice-options input,
.form_user_block input.submit,
.form_user_unblock input.submit,
#user_send-a-message a,
.form_user_nudge input.submit {
#entity_send-a-message a,
.form_user_nudge input.submit,
#entity_nudge p {
color:#002E6E;
}
@ -55,7 +57,7 @@ background-color:#fcfffc;
}
#aside_primary,
#user_subscribe a,
#entity_subscribe a,
#TB_window input.submit,
.form_user_subscribe input.submit {
background-color:#CEE1E9;
@ -132,26 +134,31 @@ background-image:url(../../base/images/icons/icon_vcard.gif);
}
#user_send-a-message a,
#entity_send-a-message a,
.form_user_nudge input.submit,
.form_user_block input.submit,
.form_user_unblock input.submit {
.form_user_unblock input.submit,
#entity_nudge p {
background-position: 0 40%;
background-repeat: no-repeat;
background-color:transparent;
}
.form_group_join input.submit,
.form_group_leave input.submit
.form_user_subscribe input.submit,
.form_user_unsubscribe input.submit {
background-color:#A9BF4F;
color:#fff;
}
.form_user_unsubscribe input.submit {
.form_user_unsubscribe input.submit,
.form_group_leave input.submit {
background-color:#97BFD1;
}
#user_send-a-message a {
#entity_send-a-message a {
background-image:url(../images/icons/twotone/green/quote.gif);
}
#entity_nudge p,
.form_user_nudge input.submit {
background-image:url(../images/icons/twotone/green/mail.gif);
}