Merge branch '0.7.x' into 0.8.x

This commit is contained in:
Evan Prodromou 2009-02-06 15:38:10 -05:00
commit 02d7167906
80 changed files with 1035 additions and 2256 deletions

38
README
View File

@ -2,8 +2,8 @@
README README
------ ------
Laconica 0.7.0 ("Rockville") Laconica 0.7.1 ("West of the Fields")
30 January 2009 6 February 2009
This is the README file for Laconica, the Open Source microblogging This is the README file for Laconica, the Open Source microblogging
platform. It includes installation instructions, descriptions of platform. It includes installation instructions, descriptions of
@ -71,8 +71,27 @@ for additional terms.
New this version New this version
================ ================
This is a major feature release, and includes some bug fixes from the This is a minor bug-fix release since version 0.7.0, released Jan 29
previous version (0.6.4, released December 14 2008.) 2009. Notable changes this version:
- Vast improvement in auto-linking to URLs.
- Link to group search from user's group page
- Improved interface in Facebook application
- Fix bad redirects in delete notice
- Updated PostgreSQL database creation script
- Show filesize in avatar/logo upload
- Vastly improved avatar/logo upload
- Allow re-authentication with OpenID
- Correctly link hashtabs inside parens and brackets
- Group and avatar image transparency works
- Better handling of commands through the Web and Ajax channels
- Fix links for profile page feeds
- Fixed destroy method in API
- Fix endpoint of Connect menu when XMPP disabled
- Show number of group members
- Enable configuration files in /etc/laconica/
Changes in version 0.7.0:
- Support for groups. Users can join groups and send themed notices - Support for groups. Users can join groups and send themed notices
to those groups. All other members of the group receive the notices. to those groups. All other members of the group receive the notices.
@ -203,9 +222,9 @@ especially if you've previously installed PHP/MySQL packages.
1. Unpack the tarball you downloaded on your Web server. Usually a 1. Unpack the tarball you downloaded on your Web server. Usually a
command like this will work: command like this will work:
tar zxf laconica-0.7.0.tar.gz tar zxf laconica-0.7.1.tar.gz
...which will make a laconica-0.7.0 subdirectory in your current ...which will make a laconica-0.7.1 subdirectory in your current
directory. (If you don't have shell access on your Web server, you directory. (If you don't have shell access on your Web server, you
may have to unpack the tarball on your local computer and FTP the may have to unpack the tarball on your local computer and FTP the
files to the server.) files to the server.)
@ -213,7 +232,7 @@ especially if you've previously installed PHP/MySQL packages.
2. Move the tarball to a directory of your choosing in your Web root 2. Move the tarball to a directory of your choosing in your Web root
directory. Usually something like this will work: directory. Usually something like this will work:
mv laconica-0.7.0 /var/www/mublog mv laconica-0.7.1 /var/www/mublog
This will make your Laconica instance available in the mublog path of This will make your Laconica instance available in the mublog path of
your server, like "http://example.net/mublog". "microblog" or your server, like "http://example.net/mublog". "microblog" or
@ -657,7 +676,7 @@ Upgrading
If you've been using Laconica 0.6, 0.5 or lower, or if you've been If you've been using Laconica 0.6, 0.5 or lower, or if you've been
tracking the "git" version of the software, you will probably want tracking the "git" version of the software, you will probably want
to upgrade and keep your existing data. There is no automated upgrade to upgrade and keep your existing data. There is no automated upgrade
procedure in Laconica 0.7.0. Try these step-by-step instructions; read procedure in Laconica 0.7.1. Try these step-by-step instructions; read
to the end first before trying them. to the end first before trying them.
0. Download Laconica and set up all the prerequisites as if you were 0. Download Laconica and set up all the prerequisites as if you were
@ -1074,7 +1093,7 @@ repository (see below), and you get a compilation error ("unexpected
T_STRING") in the browser, check to see that you don't have any T_STRING") in the browser, check to see that you don't have any
conflicts in your code. conflicts in your code.
If you upgraded to Laconica 0.7.0 without reading the "Notice inboxes" If you upgraded to Laconica 0.7.1 without reading the "Notice inboxes"
section above, and all your users' 'Personal' tabs are empty, read the section above, and all your users' 'Personal' tabs are empty, read the
"Notice inboxes" section above. "Notice inboxes" section above.
@ -1159,6 +1178,7 @@ if anyone's been overlooked in error.
* Meitar Moscovitz * Meitar Moscovitz
* Ken Sheppardson (Trac server, man-about-town) * Ken Sheppardson (Trac server, man-about-town)
* Tiago 'gouki' Faria (i18n managerx) * Tiago 'gouki' Faria (i18n managerx)
* Sean Murphy
Thanks also to the developers of our upstream library code and to the Thanks also to the developers of our upstream library code and to the
thousands of people who have tried out Identi.ca, installed Laconi.ca, thousands of people who have tried out Identi.ca, installed Laconi.ca,

View File

@ -42,6 +42,9 @@ class AllAction extends Action
if (!$this->page) { if (!$this->page) {
$this->page = 1; $this->page = 1;
} }
common_set_returnto($this->selfUrl());
return true; return true;
} }
@ -101,4 +104,15 @@ class AllAction extends Action
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'all', array('nickname' => $this->user->nickname)); $this->page, 'all', array('nickname' => $this->user->nickname));
} }
function showPageTitle()
{
$user =& common_current_user();
if ($user && ($user->id == $this->user->id)) {
$this->element('h1', NULL, _("You and friends"));
} else {
$this->element('h1', NULL, sprintf(_('%s and friends'), $this->user->nickname));
}
}
} }

View File

@ -90,9 +90,9 @@ class AvatarbynicknameAction extends Action
$url = $avatar->url; $url = $avatar->url;
} else { } else {
if ($size == 'original') { if ($size == 'original') {
$url = common_default_avatar(AVATAR_PROFILE_SIZE); $url = Avatar::defaultImage(AVATAR_PROFILE_SIZE);
} else { } else {
$url = common_default_avatar($size+0); $url = Avatar::defaultImage($size+0);
} }
} }
common_redirect($url, 302); common_redirect($url, 302);

View File

@ -34,6 +34,8 @@ if (!defined('LACONICA')) {
require_once INSTALLDIR.'/lib/accountsettingsaction.php'; require_once INSTALLDIR.'/lib/accountsettingsaction.php';
define('MAX_ORIGINAL', 480);
/** /**
* Upload an avatar * Upload an avatar
* *
@ -73,7 +75,7 @@ class AvatarsettingsAction extends AccountSettingsAction
function getInstructions() function getInstructions()
{ {
return _('You can upload your personal avatar.'); return sprintf(_('You can upload your personal avatar. The maximum file size is %s.'), ImageFile::maxFileSize());
} }
/** /**
@ -153,7 +155,7 @@ class AvatarsettingsAction extends AccountSettingsAction
$this->element('input', array('name' => 'MAX_FILE_SIZE', $this->element('input', array('name' => 'MAX_FILE_SIZE',
'type' => 'hidden', 'type' => 'hidden',
'id' => 'MAX_FILE_SIZE', 'id' => 'MAX_FILE_SIZE',
'value' => MAX_AVATAR_SIZE)); 'value' => ImageFile::maxFileSizeInt()));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
@ -198,7 +200,7 @@ class AvatarsettingsAction extends AccountSettingsAction
'class' => 'avatar_view')); 'class' => 'avatar_view'));
$this->element('h2', null, _("Original")); $this->element('h2', null, _("Original"));
$this->elementStart('div', array('id'=>'avatar_original_view')); $this->elementStart('div', array('id'=>'avatar_original_view'));
$this->element('img', array('src' => common_avatar_url($this->filedata['filename']), $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
'width' => $this->filedata['width'], 'width' => $this->filedata['width'],
'height' => $this->filedata['height'], 'height' => $this->filedata['height'],
'alt' => $user->nickname)); 'alt' => $user->nickname));
@ -210,7 +212,7 @@ class AvatarsettingsAction extends AccountSettingsAction
'class' => 'avatar_view')); 'class' => 'avatar_view'));
$this->element('h2', null, _("Preview")); $this->element('h2', null, _("Preview"));
$this->elementStart('div', array('id'=>'avatar_preview_view')); $this->elementStart('div', array('id'=>'avatar_preview_view'));
$this->element('img', array('src' => common_avatar_url($this->filedata['filename']), $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
'width' => AVATAR_PROFILE_SIZE, 'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,
'alt' => $user->nickname)); 'alt' => $user->nickname));
@ -279,14 +281,14 @@ class AvatarsettingsAction extends AccountSettingsAction
$cur = common_current_user(); $cur = common_current_user();
$filename = common_avatar_filename($cur->id, $filename = Avatar::filename($cur->id,
image_type_to_extension($imagefile->type), image_type_to_extension($imagefile->type),
null, null,
'tmp'.common_timestamp()); 'tmp'.common_timestamp());
$filepath = common_avatar_path($filename); $filepath = Avatar::path($filename);
move_uploaded_file($imagefile->filename, $filepath); move_uploaded_file($imagefile->filepath, $filepath);
$filedata = array('filename' => $filename, $filedata = array('filename' => $filename,
'filepath' => $filepath, 'filepath' => $filepath,
@ -312,15 +314,6 @@ class AvatarsettingsAction extends AccountSettingsAction
function cropAvatar() function cropAvatar()
{ {
$user = common_current_user();
$profile = $user->getProfile();
$x = $this->arg('avatar_crop_x');
$y = $this->arg('avatar_crop_y');
$w = $this->arg('avatar_crop_w');
$h = $this->arg('avatar_crop_h');
$filedata = $_SESSION['FILEDATA']; $filedata = $_SESSION['FILEDATA'];
if (!$filedata) { if (!$filedata) {
@ -328,68 +321,22 @@ class AvatarsettingsAction extends AccountSettingsAction
return; return;
} }
$filepath = common_avatar_path($filedata['filename']); // If image is not being cropped assume pos & dimentions of original
$dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
if (!file_exists($filepath)) { $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
$this->serverError(_('Lost our file.')); $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w'):$filedata['width'];
return; $dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h'):$filedata['height'];
} $size = min($dest_w, $dest_h);
$size = ($size > MAX_ORIGINAL) ? MAX_ORIGINAL:$size;
switch ($filedata['type']) {
case IMAGETYPE_GIF:
$image_src = imagecreatefromgif($filepath);
break;
case IMAGETYPE_JPEG:
$image_src = imagecreatefromjpeg($filepath);
break;
case IMAGETYPE_PNG:
$image_src = imagecreatefrompng($filepath);
break;
default:
$this->serverError(_('Unknown file type'));
return;
}
common_debug("W = $w, H = $h, X = $x, Y = $y");
$image_dest = imagecreatetruecolor($w, $h);
$background = imagecolorallocate($image_dest, 0, 0, 0);
ImageColorTransparent($image_dest, $background);
imagealphablending($image_dest, false);
imagecopyresized($image_dest, $image_src, 0, 0, $x, $y, $w, $h, $w, $h);
$cur = common_current_user();
$filename = common_avatar_filename($cur->id,
image_type_to_extension($filedata['type']),
null,
common_timestamp());
$filepath = common_avatar_path($filename);
switch ($filedata['type']) {
case IMAGETYPE_GIF:
imagegif($image_dest, $filepath);
break;
case IMAGETYPE_JPEG:
imagejpeg($image_dest, $filepath);
break;
case IMAGETYPE_PNG:
imagepng($image_dest, $filepath);
break;
default:
$this->serverError(_('Unknown file type'));
return;
}
$user = common_current_user(); $user = common_current_user();
$profile = $user->getProfile();
$profile = $cur->getProfile(); $imagefile = new ImageFile($user->id, $filedata['filepath']);
$filename = $imagefile->resize($size, $dest_x, $dest_y, $dest_w, $dest_h);
if ($profile->setOriginal($filepath)) { if ($profile->setOriginal($filename)) {
@unlink(common_avatar_path($filedata['filename'])); @unlink($filedata['filepath']);
unset($_SESSION['FILEDATA']); unset($_SESSION['FILEDATA']);
$this->mode = 'upload'; $this->mode = 'upload';
$this->showForm(_('Avatar updated.'), true); $this->showForm(_('Avatar updated.'), true);
@ -426,12 +373,14 @@ class AvatarsettingsAction extends AccountSettingsAction
{ {
parent::showScripts(); parent::showScripts();
$jcropPack = common_path('js/jcrop/jquery.Jcrop.pack.js'); if ($this->mode == 'crop') {
$jcropGo = common_path('js/jcrop/jquery.Jcrop.go.js'); $jcropPack = common_path('js/jcrop/jquery.Jcrop.pack.js');
$jcropGo = common_path('js/jcrop/jquery.Jcrop.go.js');
$this->element('script', array('type' => 'text/javascript', $this->element('script', array('type' => 'text/javascript',
'src' => $jcropPack)); 'src' => $jcropPack));
$this->element('script', array('type' => 'text/javascript', $this->element('script', array('type' => 'text/javascript',
'src' => $jcropGo)); 'src' => $jcropGo));
}
} }
} }

View File

@ -103,17 +103,18 @@ class DeletenoticeAction extends DeleteAction
function showContent() function showContent()
{ {
$this->elementStart('form', array('id' => 'notice_delete_form', $this->elementStart('form', array('id' => 'form_notice_delete',
'class' => 'form_settings',
'method' => 'post', 'method' => 'post',
'action' => common_local_url('deletenotice'))); 'action' => common_local_url('deletenotice')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Delete notice'));
$this->hidden('token', common_session_token()); $this->hidden('token', common_session_token());
$this->hidden('notice', $this->trimmed('notice')); $this->hidden('notice', $this->trimmed('notice'));
$this->elementStart('p'); $this->element('p', null, _('Are you sure you want to delete this notice?'));
$this->element('span', array('id' => 'confirmation_text'), $this->submit('form_action-yes', _('Yes'), 'submit form_action-primary', 'yes');
_('Are you sure you want to delete this notice?')); $this->submit('form_action-no', _('No'), 'submit form_action-secondary', 'no');
$this->submit('yes', _('Yes')); $this->elementEnd('fieldset');
$this->submit('no', _('No'));
$this->elementEnd('p');
$this->elementEnd('form'); $this->elementEnd('form');
} }

View File

@ -148,14 +148,11 @@ class FacebookhomeAction extends FacebookAction
function showNoticeForm() function showNoticeForm()
{ {
$post_action = "$this->app_uri/index.php"; $post_action = "$this->app_uri/index.php";
$notice_form = new FacebookNoticeForm($this, $post_action, null, $notice_form = new FacebookNoticeForm($this, $post_action, null,
$post_action, $this->user); $post_action, $this->user);
$notice_form->show(); $notice_form->show();
} }
function title() function title()
@ -169,7 +166,6 @@ class FacebookhomeAction extends FacebookAction
function showContent() function showContent()
{ {
$notice = $this->user->noticesWithFriends(($this->page-1) * $notice = $this->user->noticesWithFriends(($this->page-1) *
NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
@ -179,7 +175,6 @@ class FacebookhomeAction extends FacebookAction
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'index.php', array('nickname' => $this->user->nickname)); $this->page, 'index.php', array('nickname' => $this->user->nickname));
} }
function showNoticeList($notice) function showNoticeList($notice)

View File

@ -73,7 +73,7 @@ class FacebookinviteAction extends FacebookAction
$friend_ids = $_POST['ids']; // XXX: Hmm... is this the best way to acces the list? $friend_ids = $_POST['ids']; // XXX: Hmm... is this the best way to acces the list?
$this->elementStart("ul"); $this->elementStart('ul', array('id' => 'facebook-friends'));
foreach ($friend_ids as $friend) { foreach ($friend_ids as $friend) {
$this->elementStart('li'); $this->elementStart('li');
@ -112,11 +112,11 @@ class FacebookinviteAction extends FacebookAction
$this->element('h2', null, sprintf(_('Friends already using %s:'), $this->element('h2', null, sprintf(_('Friends already using %s:'),
common_config('site', 'name'))); common_config('site', 'name')));
$this->elementStart("ul"); $this->elementStart('ul', array('id' => 'facebook-friends'));
foreach ($exclude_ids as $friend) { foreach ($exclude_ids as $friend) {
$this->elementStart('li'); $this->elementStart('li');
$this->element('fb:profile-pic', array('uid' => $friend)); $this->element('fb:profile-pic', array('uid' => $friend, 'size' => 'square'));
$this->element('fb:name', array('uid' => $friend, $this->element('fb:name', array('uid' => $friend,
'capitalize' => 'true')); 'capitalize' => 'true'));
$this->elementEnd('li'); $this->elementEnd('li');

View File

@ -104,6 +104,9 @@ class FavoritedAction extends Action
{ {
parent::prepare($args); parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
common_set_returnto($this->selfUrl());
return true; return true;
} }

View File

@ -30,7 +30,7 @@ class FinishopenidloginAction extends Action
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
if (common_logged_in()) { if (common_is_real_login()) {
$this->clientError(_('Already logged in.')); $this->clientError(_('Already logged in.'));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') { } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$token = $this->trimmed('token'); $token = $this->trimmed('token');

View File

@ -152,7 +152,7 @@ class GrouplogoAction extends Action
function getInstructions() function getInstructions()
{ {
return _('You can upload a logo image for your group.'); return sprintf(_('You can upload a logo image for your group. The maximum file size is %s.'), ImageFile::maxFileSize());
} }
/** /**
@ -229,7 +229,7 @@ class GrouplogoAction extends Action
$this->element('input', array('name' => 'MAX_FILE_SIZE', $this->element('input', array('name' => 'MAX_FILE_SIZE',
'type' => 'hidden', 'type' => 'hidden',
'id' => 'MAX_FILE_SIZE', 'id' => 'MAX_FILE_SIZE',
'value' => MAX_AVATAR_SIZE)); 'value' => ImageFile::maxFileSizeInt()));
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
@ -263,7 +263,7 @@ class GrouplogoAction extends Action
'class' => 'avatar_view')); 'class' => 'avatar_view'));
$this->element('h2', null, _("Original")); $this->element('h2', null, _("Original"));
$this->elementStart('div', array('id'=>'avatar_original_view')); $this->elementStart('div', array('id'=>'avatar_original_view'));
$this->element('img', array('src' => common_avatar_url($this->filedata['filename']), $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
'width' => $this->filedata['width'], 'width' => $this->filedata['width'],
'height' => $this->filedata['height'], 'height' => $this->filedata['height'],
'alt' => $this->group->nickname)); 'alt' => $this->group->nickname));
@ -275,7 +275,7 @@ class GrouplogoAction extends Action
'class' => 'avatar_view')); 'class' => 'avatar_view'));
$this->element('h2', null, _("Preview")); $this->element('h2', null, _("Preview"));
$this->elementStart('div', array('id'=>'avatar_preview_view')); $this->elementStart('div', array('id'=>'avatar_preview_view'));
$this->element('img', array('src' => common_avatar_url($this->filedata['filename']), $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
'width' => AVATAR_PROFILE_SIZE, 'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,
'alt' => $this->group->nickname)); 'alt' => $this->group->nickname));
@ -343,14 +343,14 @@ class GrouplogoAction extends Action
return; return;
} }
$filename = common_avatar_filename($this->group->id, $filename = Avatar::filename($this->group->id,
image_type_to_extension($imagefile->type), image_type_to_extension($imagefile->type),
null, null,
'group-temp-'.common_timestamp()); 'group-temp-'.common_timestamp());
$filepath = common_avatar_path($filename); $filepath = Avatar::path($filename);
move_uploaded_file($imagefile->filename, $filepath); move_uploaded_file($imagefile->filepath, $filepath);
$filedata = array('filename' => $filename, $filedata = array('filename' => $filename,
'filepath' => $filepath, 'filepath' => $filepath,
@ -364,7 +364,7 @@ class GrouplogoAction extends Action
$this->mode = 'crop'; $this->mode = 'crop';
$this->showForm(_('Pick a square area of the image to be your avatar'), $this->showForm(_('Pick a square area of the image to be the logo.'),
true); true);
} }
@ -376,10 +376,6 @@ class GrouplogoAction extends Action
function cropLogo() function cropLogo()
{ {
$user = common_current_user();
$profile = $user->getProfile();
$filedata = $_SESSION['FILEDATA']; $filedata = $_SESSION['FILEDATA'];
if (!$filedata) { if (!$filedata) {
@ -387,69 +383,19 @@ class GrouplogoAction extends Action
return; return;
} }
$x = $this->arg('avatar_crop_x'); // If image is not being cropped assume pos & dimentions of original
$y = $this->arg('avatar_crop_y'); $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
$w = ($this->arg('avatar_crop_w')) ? $this->arg('avatar_crop_w') : $filedata['width']; $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
$h = ($this->arg('avatar_crop_h')) ? $this->arg('avatar_crop_h') : $filedata['height']; $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w'):$filedata['width'];
$dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h'):$filedata['height'];
$size = min($dest_w, $dest_h);
$size = ($size > MAX_ORIGINAL) ? MAX_ORIGINAL:$size;
$filepath = common_avatar_path($filedata['filename']); $imagefile = new ImageFile($this->group->id, $filedata['filepath']);
$filename = $imagefile->resize($size, $dest_x, $dest_y, $dest_w, $dest_h);
if (!file_exists($filepath)) { if ($this->group->setOriginal($filename)) {
$this->serverError(_('Lost our file.')); @unlink($filedata['filepath']);
return;
}
switch ($filedata['type']) {
case IMAGETYPE_GIF:
$image_src = imagecreatefromgif($filepath);
break;
case IMAGETYPE_JPEG:
$image_src = imagecreatefromjpeg($filepath);
break;
case IMAGETYPE_PNG:
$image_src = imagecreatefrompng($filepath);
break;
default:
$this->serverError(_('Unknown file type'));
return;
}
$size = ($w > MAX_ORIGINAL) ? MAX_ORIGINAL : $w;
$image_dest = imagecreatetruecolor($size, $size);
$background = imagecolorallocate($image_dest, 0, 0, 0);
ImageColorTransparent($image_dest, $background);
imagealphablending($image_dest, false);
imagecopyresized($image_dest, $image_src,
0, 0, $x, $y,
$size, $size, $w, $h);
$filename = common_avatar_filename($this->group->id,
image_type_to_extension($filedata['type']),
null,
'group-'.common_timestamp());
$filepath = common_avatar_path($filename);
switch ($filedata['type']) {
case IMAGETYPE_GIF:
imagegif($image_dest, $filepath);
break;
case IMAGETYPE_JPEG:
imagejpeg($image_dest, $filepath);
break;
case IMAGETYPE_PNG:
imagepng($image_dest, $filepath);
break;
default:
$this->serverError(_('Unknown file type'));
return;
}
if ($this->group->setOriginal($filename, $filedata['type'])) {
@unlink(common_avatar_path($filedata['filename']));
unset($_SESSION['FILEDATA']); unset($_SESSION['FILEDATA']);
$this->mode = 'upload'; $this->mode = 'upload';
$this->showForm(_('Logo updated.'), true); $this->showForm(_('Logo updated.'), true);

View File

@ -78,6 +78,7 @@ class LoginAction extends Action
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') { } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->checkLogin(); $this->checkLogin();
} else { } else {
common_ensure_session();
$this->showForm(); $this->showForm();
} }
} }
@ -96,7 +97,7 @@ class LoginAction extends Action
{ {
// XXX: login throttle // XXX: login throttle
// CSRF protection - token set in common_notice_form() // CSRF protection - token set in NoticeForm
$token = $this->trimmed('token'); $token = $this->trimmed('token');
if (!$token || $token != common_session_token()) { if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token. '. $this->clientError(_('There was a problem with your session token. '.
@ -106,35 +107,14 @@ class LoginAction extends Action
$nickname = common_canonical_nickname($this->trimmed('nickname')); $nickname = common_canonical_nickname($this->trimmed('nickname'));
$password = $this->arg('password'); $password = $this->arg('password');
if (common_check_user($nickname, $password)) {
// success! if (!common_check_user($nickname, $password)) {
if (!common_set_user($nickname)) {
$this->serverError(_('Error setting user.'));
return;
}
common_real_login(true);
if ($this->boolean('rememberme')) {
common_debug('Adding rememberme cookie for ' . $nickname);
common_rememberme();
}
// success!
$url = common_get_returnto();
if ($url) {
// We don't have to return to it again
common_set_returnto(null);
} else {
$url = common_local_url('all',
array('nickname' =>
$nickname));
}
common_redirect($url);
} else {
$this->showForm(_('Incorrect username or password.')); $this->showForm(_('Incorrect username or password.'));
return; return;
} }
// success! // success!
if (!common_set_user($user)) { if (!common_set_user($nickname)) {
$this->serverError(_('Error setting user.')); $this->serverError(_('Error setting user.'));
return; return;
} }
@ -142,11 +122,11 @@ class LoginAction extends Action
common_real_login(true); common_real_login(true);
if ($this->boolean('rememberme')) { if ($this->boolean('rememberme')) {
common_debug('Adding rememberme cookie for ' . $nickname);
common_rememberme($user); common_rememberme($user);
} }
// success!
$url = common_get_returnto(); $url = common_get_returnto();
if ($url) { if ($url) {
// We don't have to return to it again // We don't have to return to it again
common_set_returnto(null); common_set_returnto(null);
@ -155,6 +135,7 @@ class LoginAction extends Action
array('nickname' => array('nickname' =>
$nickname)); $nickname));
} }
common_redirect($url); common_redirect($url);
} }

View File

@ -90,7 +90,7 @@ class NewnoticeAction extends Action
$this->clientError(_('Not logged in.')); $this->clientError(_('Not logged in.'));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') { } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// CSRF protection - token set in common_notice_form() // CSRF protection
$token = $this->trimmed('token'); $token = $this->trimmed('token');
if (!$token || $token != common_session_token()) { if (!$token || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token. '. $this->clientError(_('There was a problem with your session token. '.
@ -141,9 +141,9 @@ class NewnoticeAction extends Action
if ($cmd) { if ($cmd) {
if ($this->boolean('ajax')) { if ($this->boolean('ajax')) {
$cmd->execute(new AjaxWebChannel()); $cmd->execute(new AjaxWebChannel($this));
} else { } else {
$cmd->execute(new WebChannel()); $cmd->execute(new WebChannel($this));
} }
return; return;
} }
@ -195,7 +195,7 @@ class NewnoticeAction extends Action
function ajaxErrorMsg($msg) function ajaxErrorMsg($msg)
{ {
common_start_html('text/xml;charset=utf-8', true); $this->startHTML('text/xml;charset=utf-8', true);
$this->elementStart('head'); $this->elementStart('head');
$this->element('title', null, _('Ajax Error')); $this->element('title', null, _('Ajax Error'));
$this->elementEnd('head'); $this->elementEnd('head');

View File

@ -48,6 +48,16 @@ require_once INSTALLDIR.'/lib/searchaction.php';
*/ */
class NoticesearchAction extends SearchAction class NoticesearchAction extends SearchAction
{ {
function prepare($args)
{
parent::prepare($args);
common_set_returnto($this->selfUrl());
return true;
}
/** /**
* Get instructions * Get instructions
* *
@ -154,8 +164,9 @@ class NoticesearchAction extends SearchAction
$this->elementStart('div', 'entry-title'); $this->elementStart('div', 'entry-title');
$this->elementStart('span', 'vcard author'); $this->elementStart('span', 'vcard author');
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
$this->elementStart('a', array('href' => $profile->profileurl)); $this->elementStart('a', array('href' => $profile->profileurl,
$this->element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE), 'class' => 'url'));
$this->element('img', array('src' => ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_STREAM_SIZE),
'class' => 'avatar photo', 'class' => 'avatar photo',
'width' => AVATAR_STREAM_SIZE, 'width' => AVATAR_STREAM_SIZE,
'height' => AVATAR_STREAM_SIZE, 'height' => AVATAR_STREAM_SIZE,
@ -223,15 +234,6 @@ class NoticesearchAction extends SearchAction
$this->elementEnd('a'); $this->elementEnd('a');
$this->elementEnd('dd'); $this->elementEnd('dd');
$this->elementEnd('dl'); $this->elementEnd('dl');
$this->elementStart('a',
array('href' => common_local_url('newnotice',
array('replyto' => $profile->nickname)),
'onclick' => 'doreply("'.$profile->nickname.'"); return false',
'title' => _('reply'),
'class' => 'replybutton'));
$this->hidden('posttoken', common_session_token());
$this->elementEnd('a');
$this->elementEnd('div'); $this->elementEnd('div');
$this->elementEnd('li'); $this->elementEnd('li');
} }

View File

@ -26,7 +26,7 @@ class OpenidloginAction extends Action
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
if (common_logged_in()) { if (common_is_real_login()) {
$this->clientError(_('Already logged in.')); $this->clientError(_('Already logged in.'));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') { } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$openid_url = $this->trimmed('openid_url'); $openid_url = $this->trimmed('openid_url');
@ -59,7 +59,16 @@ class OpenidloginAction extends Action
function getInstructions() function getInstructions()
{ {
return _('Login with an [OpenID](%%doc.openid%%) account.'); if (common_logged_in() && !common_is_real_login() &&
common_get_returnto()) {
// rememberme logins have to reauthenticate before
// changing any profile settings (cookie-stealing protection)
return _('For security reasons, please re-login with your ' .
'[OpenID](%%doc.openid%%) ' .
'before changing your settings.');
} else {
return _('Login with an [OpenID](%%doc.openid%%) account.');
}
} }
function showPageNotice() function showPageNotice()

View File

@ -67,7 +67,7 @@ class OpensearchAction extends Action
$short_name = _('Notice Search'); $short_name = _('Notice Search');
} }
header('Content-Type: text/html'); header('Content-Type: text/html');
common_start_xml(); $this->startXML();
$this->elementStart('OpenSearchDescription', array('xmlns' => 'http://a9.com/-/spec/opensearch/1.1/')); $this->elementStart('OpenSearchDescription', array('xmlns' => 'http://a9.com/-/spec/opensearch/1.1/'));
$short_name = common_config('site', 'name').' '.$short_name; $short_name = common_config('site', 'name').' '.$short_name;
$this->element('ShortName', null, $short_name); $this->element('ShortName', null, $short_name);
@ -81,7 +81,7 @@ class OpensearchAction extends Action
$this->element('OutputEncoding', null, 'UTF-8'); $this->element('OutputEncoding', null, 'UTF-8');
$this->element('InputEncoding', null, 'UTF-8'); $this->element('InputEncoding', null, 'UTF-8');
$this->elementEnd('OpenSearchDescription'); $this->elementEnd('OpenSearchDescription');
common_end_xml(); $this->endXML();
} }
function isReadOnly() function isReadOnly()

View File

@ -73,6 +73,9 @@ class PublicAction extends Action
{ {
parent::prepare($args); parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
common_set_returnto($this->selfUrl());
return true; return true;
} }

View File

@ -83,6 +83,8 @@ class RepliesAction extends Action
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
common_set_returnto($this->selfUrl());
return true; return true;
} }

View File

@ -112,6 +112,8 @@ class ShowfavoritesAction extends Action
$this->page = 1; $this->page = 1;
} }
common_set_returnto($this->selfUrl());
return true; return true;
} }

View File

@ -129,6 +129,8 @@ class ShowgroupAction extends Action
return false; return false;
} }
common_set_returnto($this->selfUrl());
return true; return true;
} }

View File

@ -110,6 +110,8 @@ class ShowstreamAction extends Action
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
common_set_returnto($this->selfUrl());
return true; return true;
} }
@ -140,7 +142,12 @@ class ShowstreamAction extends Action
function showPageTitle() function showPageTitle()
{ {
$this->element('h1', NULL, $this->profile->nickname._("'s profile")); $user =& common_current_user();
if ($user && ($user->id == $this->profile->id)) {
$this->element('h1', NULL, _("Your profile"));
} else {
$this->element('h1', NULL, sprintf(_('%s\'s profile'), $this->profile->nickname));
}
} }
function showPageNoticeBlock() function showPageNoticeBlock()
@ -170,26 +177,22 @@ class ShowstreamAction extends Action
function showFeeds() function showFeeds()
{ {
// Feeds
$this->element('link', array('rel' => 'alternate', $this->element('link', array('rel' => 'alternate',
'href' => common_local_url('api', 'type' => 'application/rss+xml',
array('apiaction' => 'statuses', 'href' => common_local_url('userrss',
'method' => 'entity_timeline.rss', array('nickname' => $this->user->nickname)),
'argument' => $this->user->nickname)), 'title' => sprintf(_('Notice feed for %s (RSS)'),
'type' => 'application/rss+xml', $this->user->nickname)));
'title' => sprintf(_('Notice feed for %s'), $this->user->nickname)));
$this->element('link', array('rel' => 'alternate feed', $this->element('link',
'href' => common_local_url('api', array('rel' => 'alternate',
array('apiaction' => 'statuses', 'href' => common_local_url('api',
'method' => 'entity_timeline.atom', array('apiaction' => 'statuses',
'argument' => $this->user->nickname)), 'method' => 'user_timeline.atom',
'type' => 'application/atom+xml', 'argument' => $this->user->nickname)),
'title' => sprintf(_('Notice feed for %s'), $this->user->nickname))); 'type' => 'application/atom+xml',
$this->element('link', array('rel' => 'alternate', 'title' => sprintf(_('Notice feed for %s (Atom)'),
'href' => common_local_url('userrss', array('nickname' => $this->user->nickname)));
$this->user->nickname)),
'type' => 'application/rdf+xml',
'title' => sprintf(_('Notice feed for %s'), $this->user->nickname)));
} }
function extraHead() function extraHead()
@ -239,7 +242,7 @@ class ShowstreamAction extends Action
$this->elementStart('dl', 'entity_depiction'); $this->elementStart('dl', 'entity_depiction');
$this->element('dt', null, _('Photo')); $this->element('dt', null, _('Photo'));
$this->elementStart('dd'); $this->elementStart('dd');
$this->element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE), $this->element('img', array('src' => ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_PROFILE_SIZE),
'class' => 'photo avatar', 'class' => 'photo avatar',
'width' => AVATAR_PROFILE_SIZE, 'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,
@ -312,14 +315,22 @@ class ShowstreamAction extends Action
} }
$this->elementEnd('div'); $this->elementEnd('div');
//XXX: entity_actions doesn't need to be outputted if entity is looking at their own profile
$this->elementStart('div', 'entity_actions'); $this->elementStart('div', 'entity_actions');
$this->element('h2', null, _('User actions')); $this->element('h2', null, _('User actions'));
$this->elementStart('ul'); $this->elementStart('ul');
$this->elementStart('li', array('class' => 'entity_subscribe'));
$cur = common_current_user(); $cur = common_current_user();
if ($cur && $cur->id == $this->profile->id) {
$this->elementStart('li', 'entity_edit');
$this->element('a', array('href' => common_local_url('profilesettings'),
'title' => _('Edit profile settings')),
_('Edit'));
$this->elementEnd('li');
}
if ($cur) { if ($cur) {
if ($cur->id != $this->profile->id) { if ($cur->id != $this->profile->id) {
$this->elementStart('li', 'entity_subscribe');
if ($cur->isSubscribed($this->profile)) { if ($cur->isSubscribed($this->profile)) {
$usf = new UnsubscribeForm($this, $this->profile); $usf = new UnsubscribeForm($this, $this->profile);
$usf->show(); $usf->show();
@ -327,24 +338,24 @@ class ShowstreamAction extends Action
$sf = new SubscribeForm($this, $this->profile); $sf = new SubscribeForm($this, $this->profile);
$sf->show(); $sf->show();
} }
$this->elementEnd('li');
} }
} else { } else {
$this->elementStart('li', 'entity_subscribe');
$this->showRemoteSubscribeLink(); $this->showRemoteSubscribeLink();
$this->elementEnd('li');
} }
$this->elementEnd('li');
// common_profile_new_message_nudge($cur, $this->user, $this->profile);
$user = User::staticGet('id', $this->profile->id); $user = User::staticGet('id', $this->profile->id);
if ($cur && $cur->id != $user->id && $cur->mutuallySubscribed($user)) { if ($cur && $cur->id != $user->id && $cur->mutuallySubscribed($user)) {
$this->elementStart('li', array('class' => 'entity_send-a-message')); $this->elementStart('li', 'entity_send-a-message');
$this->element('a', array('href' => common_local_url('newmessage', array('to' => $user->id)), $this->element('a', array('href' => common_local_url('newmessage', array('to' => $user->id)),
'title' => _('Send a direct message to this user')), 'title' => _('Send a direct message to this user')),
_('Message')); _('Message'));
$this->elementEnd('li'); $this->elementEnd('li');
if ($user->email && $user->emailnotifynudge) { if ($user->email && $user->emailnotifynudge) {
$this->elementStart('li', array('class' => 'entity_nudge')); $this->elementStart('li', 'entity_nudge');
$nf = new NudgeForm($this, $user); $nf = new NudgeForm($this, $user);
$nf->show(); $nf->show();
$this->elementEnd('li'); $this->elementEnd('li');
@ -353,7 +364,7 @@ class ShowstreamAction extends Action
if ($cur && $cur->id != $this->profile->id) { if ($cur && $cur->id != $this->profile->id) {
$blocked = $cur->hasBlocked($this->profile); $blocked = $cur->hasBlocked($this->profile);
$this->elementStart('li', array('class' => 'entity_block')); $this->elementStart('li', 'entity_block');
if ($blocked) { if ($blocked) {
$ubf = new UnblockForm($this, $this->profile); $ubf = new UnblockForm($this, $this->profile);
$ubf->show(); $ubf->show();

View File

@ -490,4 +490,55 @@ class SmssettingsAction extends ConnectSettingsAction
common_redirect(common_local_url('confirmaddress', common_redirect(common_local_url('confirmaddress',
array('code' => $code))); array('code' => $code)));
} }
/**
* Handle a request to remove an incoming email address
*
* @return void
*/
function removeIncoming()
{
$user = common_current_user();
if (!$user->incomingemail) {
$this->showForm(_('No incoming email address.'));
return;
}
$orig = clone($user);
$user->incomingemail = null;
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
$this->serverError(_("Couldn't update user record."));
}
$this->showForm(_('Incoming email address removed.'), true);
}
/**
* Generate a new incoming email address
*
* @return void
*
* @see Emailsettings::newIncoming
*/
function newIncoming()
{
$user = common_current_user();
$orig = clone($user);
$user->incomingemail = mail_new_incoming_address();
if (!$user->updateKeys($orig)) {
common_log_db_error($user, 'UPDATE', __FILE__);
$this->serverError(_("Couldn't update user record."));
}
$this->showForm(_('New incoming email address added.'), true);
}
} }

View File

@ -37,6 +37,9 @@ class TagAction extends Action
} }
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
common_set_returnto($this->selfUrl());
return true; return true;
} }

View File

@ -80,7 +80,7 @@ class TagotherAction extends Action
$this->elementStart('dl', 'entity_depiction'); $this->elementStart('dl', 'entity_depiction');
$this->element('dt', null, _('Photo')); $this->element('dt', null, _('Photo'));
$this->elementStart('dd'); $this->elementStart('dd');
$this->element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_PROFILE_SIZE), $this->element('img', array('src' => ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_PROFILE_SIZE),
'class' => 'photo avatar', 'class' => 'photo avatar',
'width' => AVATAR_PROFILE_SIZE, 'width' => AVATAR_PROFILE_SIZE,
'height' => AVATAR_PROFILE_SIZE, 'height' => AVATAR_PROFILE_SIZE,

View File

@ -25,12 +25,12 @@ require_once(INSTALLDIR.'/lib/rssaction.php');
class TagrssAction extends Rss10Action class TagrssAction extends Rss10Action
{ {
var $tag;
function init() function prepare($args) {
{ parent::prepare($args);
$tag = $this->trimmed('tag'); $tag = common_canonical_tag($this->trimmed('tag'));
$this->tag = Notice_tag::staticGet('tag', $tag); $this->tag = Notice_tag::staticGet('tag', $tag);
if (!$this->tag) { if (!$this->tag) {
$this->clientError(_('No such tag.')); $this->clientError(_('No such tag.'));
return false; return false;
@ -39,7 +39,7 @@ class TagrssAction extends Rss10Action
} }
} }
function get_notices($limit=0) function getNotices($limit=0)
{ {
$tag = $this->tag; $tag = $this->tag;
@ -48,7 +48,6 @@ class TagrssAction extends Rss10Action
} }
$notice = Notice_tag::getStream($tag->tag, 0, ($limit == 0) ? NOTICES_PER_PAGE : $limit); $notice = Notice_tag::getStream($tag->tag, 0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
while ($notice->fetch()) { while ($notice->fetch()) {
$notices[] = clone($notice); $notices[] = clone($notice);
} }
@ -56,10 +55,9 @@ class TagrssAction extends Rss10Action
return $notices; return $notices;
} }
function get_channel() function getChannel()
{ {
$tag = $this->tag->tag; $tagname = $this->tag->tag;
$c = array('url' => common_local_url('tagrss', array('tag' => $tagname)), $c = array('url' => common_local_url('tagrss', array('tag' => $tagname)),
'title' => $tagname, 'title' => $tagname,
'link' => common_local_url('tagrss', array('tag' => $tagname)), 'link' => common_local_url('tagrss', array('tag' => $tagname)),

View File

@ -450,7 +450,6 @@ class TwitapistatusesAction extends TwitterapiAction
if ($user->id == $notice->profile_id) { if ($user->id == $notice->profile_id) {
$replies = new Reply; $replies = new Reply;
$replies->get('notice_id', $notice_id); $replies->get('notice_id', $notice_id);
common_dequeue_notice($notice);
$replies->delete(); $replies->delete();
$notice->delete(); $notice->delete();

View File

@ -250,8 +250,8 @@ class TwittersettingsAction extends ConnectSettingsAction
$avatar = $other->getAvatar(AVATAR_MINI_SIZE); $avatar = $other->getAvatar(AVATAR_MINI_SIZE);
$avatar_url = ($avatar) ? $avatar_url = ($avatar) ?
common_avatar_display_url($avatar) : $avatar->displayUrl() :
common_default_avatar(AVATAR_MINI_SIZE); Avatar::defaultImage(AVATAR_MINI_SIZE);
$this->element('img', array('src' => $avatar_url, $this->element('img', array('src' => $avatar_url,
'width' => AVATAR_MINI_SIZE, 'width' => AVATAR_MINI_SIZE,

View File

@ -125,6 +125,12 @@ class UsergroupsAction extends Action
_('Create a new group')); _('Create a new group'));
$this->elementEnd('p'); $this->elementEnd('p');
$this->elementStart('p', array('id' => 'group_search'));
$this->element('a', array('href' => common_local_url('groupsearch'),
'class' => 'more'),
_('Search for more groups'));
$this->elementEnd('p');
$offset = ($this->page-1) * GROUPS_PER_PAGE; $offset = ($this->page-1) * GROUPS_PER_PAGE;
$limit = GROUPS_PER_PAGE + 1; $limit = GROUPS_PER_PAGE + 1;

View File

@ -4,18 +4,18 @@
*/ */
require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class Avatar extends Memcached_DataObject class Avatar extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'avatar'; // table name public $__table = 'avatar'; // table name
public $profile_id; // int(4) primary_key not_null public $profile_id; // int(4) primary_key not_null
public $original; // tinyint(1) public $original; // tinyint(1)
public $width; // int(4) primary_key not_null public $width; // int(4) primary_key not_null
public $height; // int(4) primary_key not_null public $height; // int(4) primary_key not_null
public $mediatype; // varchar(32) not_null public $mediatype; // varchar(32) not_null
public $filename; // varchar(255) public $filename; // varchar(255)
public $url; // varchar(255) unique_key public $url; // varchar(255) unique_key
public $created; // datetime() not_null public $created; // datetime() not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
@ -33,109 +33,51 @@ class Avatar extends Memcached_DataObject
{ {
$filename = $this->filename; $filename = $this->filename;
if (parent::delete()) { if (parent::delete()) {
@unlink(common_avatar_path($filename)); @unlink(Avatar::path($filename));
} }
} }
# Create and save scaled version of this avatar function &pkeyGet($kv)
# XXX: maybe break into different methods
function scale($size)
{
$image_s = imagecreatetruecolor($size, $size);
$image_a = $this->to_image();
$square = min($this->width, $this->height);
imagecolortransparent($image_s, imagecolorallocate($image_s, 0, 0, 0));
imagealphablending($image_s, false);
imagesavealpha($image_s, true);
imagecopyresampled($image_s, $image_a, 0, 0, 0, 0,
$size, $size, $square, $square);
$ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
$filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
if ($this->mediatype == 'image/jpeg') {
imagejpeg($image_s, common_avatar_path($filename));
} else {
imagepng($image_s, common_avatar_path($filename));
}
$scaled = DB_DataObject::factory('avatar');
$scaled->profile_id = $this->profile_id;
$scaled->width = $size;
$scaled->height = $size;
$scaled->original = false;
$scaled->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
$scaled->filename = $filename;
$scaled->url = common_avatar_url($filename);
$scaled->created = DB_DataObject_Cast::dateTime(); # current time
if ($scaled->insert()) {
return $scaled;
} else {
return null;
}
}
function scale_and_crop($size, $x, $y, $w, $h)
{
$image_s = imagecreatetruecolor($size, $size);
$image_a = $this->to_image();
# Retain alpha channel info if possible for .pngs
$background = imagecolorallocate($image_s, 0, 0, 0);
ImageColorTransparent($image_s, $background);
imagealphablending($image_s, false);
imagecopyresized($image_s, $image_a, 0, 0, $x, $y, $size, $size, $w, $h);
$ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png";
$filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp());
if ($this->mediatype == 'image/jpeg') {
imagejpeg($image_s, common_avatar_path($filename));
} else {
imagepng($image_s, common_avatar_path($filename));
}
$cropped = DB_DataObject::factory('avatar');
$cropped->profile_id = $this->profile_id;
$cropped->width = $size;
$cropped->height = $size;
$cropped->original = false;
$cropped->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png';
$cropped->filename = $filename;
$cropped->url = common_avatar_url($filename);
$cropped->created = DB_DataObject_Cast::dateTime(); # current time
if ($cropped->insert()) {
return $cropped;
} else {
return NULL;
}
}
function to_image()
{
$filepath = common_avatar_path($this->filename);
if ($this->mediatype == 'image/gif') {
return imagecreatefromgif($filepath);
} else if ($this->mediatype == 'image/jpeg') {
return imagecreatefromjpeg($filepath);
} else if ($this->mediatype == 'image/png') {
return imagecreatefrompng($filepath);
} else {
return NULL;
}
}
function &pkeyGet($kv)
{ {
return Memcached_DataObject::pkeyGet('Avatar', $kv); return Memcached_DataObject::pkeyGet('Avatar', $kv);
} }
// where should the avatar go for this user?
static function filename($id, $extension, $size=null, $extra=null)
{
if ($size) {
return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
} else {
return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension;
}
}
static function path($filename)
{
return INSTALLDIR . '/avatar/' . $filename;
}
static function url($filename)
{
return common_path('avatar/'.$filename);
}
function displayUrl()
{
$server = common_config('avatar', 'server');
if ($server) {
return 'http://'.$server.'/'.$this->filename;
} else {
return $this->url;
}
}
static function defaultImage($size)
{
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',
AVATAR_MINI_SIZE => 'mini');
return theme_path('default-avatar-'.$sizenames[$size].'.png');
}
} }

View File

@ -21,7 +21,7 @@ if (!defined('LACONICA')) { exit(1); }
class Channel class Channel
{ {
function on($user) function on($user)
{ {
return false; return false;
@ -36,12 +36,12 @@ class Channel
{ {
return false; return false;
} }
function error($user, $text) function error($user, $text)
{ {
return false; return false;
} }
function source() function source()
{ {
return null; return null;
@ -52,22 +52,22 @@ class XMPPChannel extends Channel
{ {
var $conn = null; var $conn = null;
function source() function source()
{ {
return 'xmpp'; return 'xmpp';
} }
function __construct($conn) function __construct($conn)
{ {
$this->conn = $conn; $this->conn = $conn;
} }
function on($user) function on($user)
{ {
return $this->set_notify($user, 1); return $this->set_notify($user, 1);
} }
function off($user) function off($user)
{ {
return $this->set_notify($user, 0); return $this->set_notify($user, 0);
@ -78,13 +78,13 @@ class XMPPChannel extends Channel
$text = '['.common_config('site', 'name') . '] ' . $text; $text = '['.common_config('site', 'name') . '] ' . $text;
jabber_send_message($user->jabber, $text); jabber_send_message($user->jabber, $text);
} }
function error($user, $text) function error($user, $text)
{ {
$text = '['.common_config('site', 'name') . '] ' . $text; $text = '['.common_config('site', 'name') . '] ' . $text;
jabber_send_message($user->jabber, $text); jabber_send_message($user->jabber, $text);
} }
function set_notify(&$user, $notify) function set_notify(&$user, $notify)
{ {
$orig = clone($user); $orig = clone($user);
@ -105,20 +105,25 @@ class XMPPChannel extends Channel
} }
} }
class WebChannel extends Channel class WebChannel extends Channel
{ {
var $out = null;
function __construct($out=null)
{
$this->out = $out;
}
function source() function source()
{ {
return 'web'; return 'web';
} }
function on($user) function on($user)
{ {
return false; return false;
} }
function off($user) function off($user)
{ {
return false; return false;
@ -129,47 +134,49 @@ class WebChannel extends Channel
# XXX: buffer all output and send it at the end # XXX: buffer all output and send it at the end
# XXX: even better, redirect to appropriate page # XXX: even better, redirect to appropriate page
# depending on what command was run # depending on what command was run
common_show_header(_('Command results')); $this->out->startHTML();
common_element('p', null, $text); $this->out->elementStart('head');
common_show_footer(); $this->out->element('title', null, _('Command results'));
$this->out->elementEnd('head');
$this->out->elementStart('body');
$this->out->element('p', array('id' => 'command_result'), $text);
$this->out->elementEnd('body');
$this->out->endHTML();
} }
function error($user, $text) function error($user, $text)
{ {
common_user_error($text); common_user_error($text);
} }
} }
class AjaxWebChannel extends WebChannel class AjaxWebChannel extends WebChannel
{ {
function output($user, $text) function output($user, $text)
{ {
common_start_html('text/xml;charset=utf-8', true); $this->out->startHTML('text/xml;charset=utf-8');
common_element_start('head'); $this->out->elementStart('head');
common_element('title', null, _('Command results')); $this->out->element('title', null, _('Command results'));
common_element_end('head'); $this->out->elementEnd('head');
common_element_start('body'); $this->out->elementStart('body');
common_element('p', array('id' => 'command_result'), $text); $this->out->element('p', array('id' => 'command_result'), $text);
common_element_end('body'); $this->out->elementEnd('body');
common_element_end('html'); $this->out->endHTML();
} }
function error($user, $text) function error($user, $text)
{ {
common_start_html('text/xml;charset=utf-8', true); $this->out->startHTML('text/xml;charset=utf-8');
common_element_start('head'); $this->out->elementStart('head');
common_element('title', null, _('Ajax Error')); $this->out->element('title', null, _('Ajax Error'));
common_element_end('head'); $this->out->elementEnd('head');
common_element_start('body'); $this->out->elementStart('body');
common_element('p', array('id' => 'error'), $text); $this->out->element('p', array('id' => 'error'), $text);
common_element_end('body'); $this->out->elementEnd('body');
common_element_end('html'); $this->out->endHTML();
} }
} }
class MailChannel extends Channel class MailChannel extends Channel
{ {
@ -179,17 +186,17 @@ class MailChannel extends Channel
{ {
return 'mail'; return 'mail';
} }
function __construct($addr=null) function __construct($addr=null)
{ {
$this->addr = $addr; $this->addr = $addr;
} }
function on($user) function on($user)
{ {
return $this->set_notify($user, 1); return $this->set_notify($user, 1);
} }
function off($user) function off($user)
{ {
return $this->set_notify($user, 0); return $this->set_notify($user, 0);
@ -200,23 +207,23 @@ class MailChannel extends Channel
$headers['From'] = $user->incomingemail; $headers['From'] = $user->incomingemail;
$headers['To'] = $this->addr; $headers['To'] = $this->addr;
$headers['Subject'] = _('Command complete'); $headers['Subject'] = _('Command complete');
return mail_send(array($this->addr), $headers, $text); return mail_send(array($this->addr), $headers, $text);
} }
function error($user, $text) function error($user, $text)
{ {
$headers['From'] = $user->incomingemail; $headers['From'] = $user->incomingemail;
$headers['To'] = $this->addr; $headers['To'] = $this->addr;
$headers['Subject'] = _('Command failed'); $headers['Subject'] = _('Command failed');
return mail_send(array($this->addr), $headers, $text); return mail_send(array($this->addr), $headers, $text);
} }
function set_notify($user, $value) function set_notify($user, $value)
{ {
$orig = clone($user); $orig = clone($user);

View File

@ -69,50 +69,45 @@ class Profile extends Memcached_DataObject
} }
} }
function setOriginal($source) function setOriginal($filename)
{ {
$imagefile = new ImageFile($this->id, Avatar::path($filename));
$info = @getimagesize($source);
if (!$info) {
return null;
}
$filename = common_avatar_filename($this->id,
image_type_to_extension($info[2]),
null, common_timestamp());
$filepath = common_avatar_path($filename);
copy($source, $filepath);
$avatar = new Avatar(); $avatar = new Avatar();
$avatar->profile_id = $this->id; $avatar->profile_id = $this->id;
$avatar->width = $info[0]; $avatar->width = $imagefile->width;
$avatar->height = $info[1]; $avatar->height = $imagefile->height;
$avatar->mediatype = image_type_to_mime_type($info[2]); $avatar->mediatype = image_type_to_mime_type($imagefile->type);
$avatar->filename = $filename; $avatar->filename = $filename;
$avatar->original = true; $avatar->original = true;
$avatar->url = common_avatar_url($filename); $avatar->url = Avatar::url($filename);
$avatar->created = DB_DataObject_Cast::dateTime(); # current time $avatar->created = DB_DataObject_Cast::dateTime(); # current time
# XXX: start a transaction here # XXX: start a transaction here
if (!$this->delete_avatars()) { if (!$this->delete_avatars() || !$avatar->insert()) {
@unlink($filepath); @unlink(Avatar::path($filename));
return null;
}
if (!$avatar->insert()) {
@unlink($filepath);
return null; return null;
} }
foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
# We don't do a scaled one if original is our scaled size # We don't do a scaled one if original is our scaled size
if (!($avatar->width == $size && $avatar->height == $size)) { if (!($avatar->width == $size && $avatar->height == $size)) {
$s = $avatar->scale($size);
if (!$s) { $scaled_filename = $imagefile->resize($size);
//$scaled = DB_DataObject::factory('avatar');
$scaled = new Avatar();
$scaled->profile_id = $this->id;
$scaled->width = $size;
$scaled->height = $size;
$scaled->original = false;
$scaled->mediatype = image_type_to_mime_type($imagefile->type);
$scaled->filename = $scaled_filename;
$scaled->url = Avatar::url($scaled_filename);
$scaled->created = DB_DataObject_Cast::dateTime(); # current time
if (!$scaled->insert()) {
return null; return null;
} }
} }
@ -121,24 +116,6 @@ class Profile extends Memcached_DataObject
return $avatar; return $avatar;
} }
function crop_avatars($x, $y, $w, $h)
{
$avatar = $this->getOriginalAvatar();
$this->delete_avatars(false); # don't delete original
foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) {
# We don't do a scaled one if original is our scaled size
if (!($avatar->width == $size && $avatar->height == $size)) {
$s = $avatar->scale_and_crop($size, $x, $y, $w, $h);
if (!$s) {
return NULL;
}
}
}
return true;
}
function delete_avatars($original=true) function delete_avatars($original=true)
{ {
$avatar = new Avatar(); $avatar = new Avatar();
@ -217,4 +194,13 @@ class Profile extends Memcached_DataObject
} }
} }
function avatarUrl($size=AVATAR_PROFILE_SIZE)
{
$avatar = $this->getAvatar($size);
if ($avatar) {
return $avatar->displayUrl();
} else {
return Avatar::defaultImage($size);
}
}
} }

View File

@ -630,4 +630,15 @@ class User extends Memcached_DataObject
return $profile; return $profile;
} }
function hasOpenID()
{
$oid = new User_openid();
$oid->user_id = $this->id;
$cnt = $oid->find();
return ($cnt > 0);
}
} }

View File

@ -88,81 +88,16 @@ class User_group extends Memcached_DataObject
return $members; return $members;
} }
function setOriginal($filename, $type) function setOriginal($filename)
{ {
$imagefile = new ImageFile($this->id, Avatar::path($filename));
$orig = clone($this); $orig = clone($this);
$this->original_logo = common_avatar_url($filename); $this->original_logo = Avatar::url($filename);
$this->homepage_logo = common_avatar_url($this->scale($filename, $this->homepage_logo = Avatar::url($imagefile->resize(AVATAR_PROFILE_SIZE));
AVATAR_PROFILE_SIZE, $this->stream_logo = Avatar::url($imagefile->resize(AVATAR_STREAM_SIZE));
$type)); $this->mini_logo = Avatar::url($imagefile->resize(AVATAR_MINI_SIZE));
$this->stream_logo = common_avatar_url($this->scale($filename,
AVATAR_STREAM_SIZE,
$type));
$this->mini_logo = common_avatar_url($this->scale($filename,
AVATAR_MINI_SIZE,
$type));
common_debug(common_log_objstring($this)); common_debug(common_log_objstring($this));
return $this->update($orig); return $this->update($orig);
} }
function scale($filename, $size, $type)
{
$filepath = common_avatar_path($filename);
if (!file_exists($filepath)) {
$this->serverError(_('Lost our file.'));
return;
}
$info = @getimagesize($filepath);
switch ($type) {
case IMAGETYPE_GIF:
$image_src = imagecreatefromgif($filepath);
break;
case IMAGETYPE_JPEG:
$image_src = imagecreatefromjpeg($filepath);
break;
case IMAGETYPE_PNG:
$image_src = imagecreatefrompng($filepath);
break;
default:
$this->serverError(_('Unknown file type'));
return;
}
$image_dest = imagecreatetruecolor($size, $size);
$background = imagecolorallocate($image_dest, 0, 0, 0);
ImageColorTransparent($image_dest, $background);
imagealphablending($image_dest, false);
imagecopyresized($image_dest, $image_src,
0, 0, 0, 0,
$size, $size, $info[0], $info[1]);
$outname = common_avatar_filename($this->id,
image_type_to_extension($type),
$size,
common_timestamp());
$outpath = common_avatar_path($outname);
switch ($type) {
case IMAGETYPE_GIF:
imagegif($image_dest, $outpath);
break;
case IMAGETYPE_JPEG:
imagejpeg($image_dest, $outpath);
break;
case IMAGETYPE_PNG:
imagepng($image_dest, $outpath);
break;
default:
$this->serverError(_('Unknown file type'));
return;
}
return $outname;
}
} }

View File

@ -50,7 +50,7 @@ create table "user" (
emailnotifyfav integer default 1 /* comment 'Notify by email of favorites' */, emailnotifyfav integer default 1 /* comment 'Notify by email of favorites' */,
emailnotifynudge integer default 1 /* comment 'Notify by email of nudges' */, emailnotifynudge integer default 1 /* comment 'Notify by email of nudges' */,
emailnotifymsg integer default 1 /* comment 'Notify by email of direct messages' */, emailnotifymsg integer default 1 /* comment 'Notify by email of direct messages' */,
emailmicroid integer default 1 /* comment 'whether to publish email microid' */, emailmicroid integer default 1 /* comment 'whether to publish email microid' */,
language varchar(50) /* comment 'preferred language' */, language varchar(50) /* comment 'preferred language' */,
timezone varchar(50) /* comment 'timezone' */, timezone varchar(50) /* comment 'timezone' */,
emailpost integer default 1 /* comment 'Post by email' */, emailpost integer default 1 /* comment 'Post by email' */,
@ -146,7 +146,6 @@ create table fave (
notice_id integer not null /* comment 'notice that is the favorite' */ references notice (id), notice_id integer not null /* comment 'notice that is the favorite' */ references notice (id),
user_id integer not null /* comment 'user who likes this notice' */ references "user" (id) , user_id integer not null /* comment 'user who likes this notice' */ references "user" (id) ,
modified timestamp not null /* comment 'date this record was modified' */, modified timestamp not null /* comment 'date this record was modified' */,
primary key (notice_id, user_id) primary key (notice_id, user_id)
); );
@ -288,6 +287,7 @@ create table foreign_link (
credentials varchar(255) /* comment 'authc credentials, typically a password' */, credentials varchar(255) /* comment 'authc credentials, typically a password' */,
noticesync int not null default 1 /* comment 'notice synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies' */, noticesync int not null default 1 /* comment 'notice synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies' */,
friendsync int not null default 2 /* comment 'friend synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming */, friendsync int not null default 2 /* comment 'friend synchronisation, bit 1 = sync outgoing, bit 2 = sync incoming */,
profilesync int not null default 1 /* comment 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming' */,
created timestamp not null /* comment 'date this record was created' */, created timestamp not null /* comment 'date this record was created' */,
modified timestamp not null /* comment 'date this record was modified' */, modified timestamp not null /* comment 'date this record was modified' */,
@ -367,6 +367,59 @@ create table profile_block (
); );
create table user_group (
id serial primary key /* comment 'unique identifier' */,
nickname varchar(64) unique /* comment 'nickname for addressing' */,
fullname varchar(255) /* comment 'display name' */,
homepage varchar(255) /* comment 'URL, cached so we dont regenerate' */,
description varchar(140) /* comment 'descriptive biography' */,
location varchar(255) /* comment 'related physical location, if any' */,
original_logo varchar(255) /* comment 'original size logo' */,
homepage_logo varchar(255) /* comment 'homepage (profile) size logo' */,
stream_logo varchar(255) /* comment 'stream-sized logo' */,
mini_logo varchar(255) /* comment 'mini logo' */,
created timestamp not null /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */
);
create index user_group_nickname_idx on user_group using btree(nickname);
create table group_member (
group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id),
profile_id integer not null /* comment 'foreign key to profile table' */ references profile (id),
is_admin integer default 0 /* comment 'is this user an admin?' */,
created timestamp not null /* comment 'date this record was created' */,
modified timestamp /* comment 'date this record was modified' */,
primary key (group_id, profile_id)
);
create table related_group (
group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id) ,
related_group_id integer not null /* comment 'foreign key to user_group' */ references user_group (id),
created timestamp not null /* comment 'date this record was created' */,
primary key (group_id, related_group_id)
);
create table group_inbox (
group_id integer not null /* comment 'group receiving the message' references user_group (id) */,
notice_id integer not null /* comment 'notice received' references notice (id) */,
created timestamp not null /* comment 'date the notice was created' */,
primary key (group_id, notice_id)
);
create index group_inbox_created_idx on group_inbox using btree(created);
/* Textsearch stuff */ /* Textsearch stuff */
create index textsearch_idx on profile using gist(textsearch); create index textsearch_idx on profile using gist(textsearch);

View File

@ -19,10 +19,12 @@
var max = 140; var max = 140;
var noticeBox = document.getElementById('notice_data-text'); var noticeBox = document.getElementById('notice_data-text');
noticeBox.addEventListener('keyup', keypress); if (noticeBox) {
noticeBox.addEventListener('keydown', keypress); noticeBox.addEventListener('keyup', keypress);
noticeBox.addEventListener('keypress', keypress); noticeBox.addEventListener('keydown', keypress);
noticeBox.addEventListener('change', keypress); noticeBox.addEventListener('keypress', keypress);
noticeBox.addEventListener('change', keypress);
}
// Do our the countdown // Do our the countdown
function keypress(evt) { function keypress(evt) {

View File

@ -73,7 +73,6 @@ class Action extends HTMLOutputter // lawsuit
parent::__construct($output, $indent); parent::__construct($output, $indent);
} }
/** /**
* For initializing members of the class. * For initializing members of the class.
* *
@ -162,15 +161,15 @@ class Action extends HTMLOutputter // lawsuit
'media' => 'screen, projection, tv')); 'media' => 'screen, projection, tv'));
$this->comment('[if IE]><link rel="stylesheet" type="text/css" '. $this->comment('[if IE]><link rel="stylesheet" type="text/css" '.
'href="'.theme_path('css/ie.css', 'base').'?version='.LACONICA_VERSION.'" /><![endif]'); 'href="'.theme_path('css/ie.css', 'base').'?version='.LACONICA_VERSION.'" /><![endif]');
$this->comment('[if IE]><link rel="stylesheet" type="text/css" '.
'href="'.theme_path('css/ie.css', null).'?version='.LACONICA_VERSION.'" /><![endif]');
foreach (array(6,7) as $ver) { foreach (array(6,7) as $ver) {
if (file_exists(theme_file('ie'.$ver.'.css'))) { if (file_exists(theme_file('css/ie'.$ver.'.css', 'base'))) {
// Yes, IE people should be put in jail. // Yes, IE people should be put in jail.
$this->comment('[if lte IE '.$ver.']><link rel="stylesheet" type="text/css" '. $this->comment('[if lte IE '.$ver.']><link rel="stylesheet" type="text/css" '.
'href="'.theme_path('css/ie'.$ver.'.css', 'base').'?version='.LACONICA_VERSION.'" /><![endif]'); 'href="'.theme_path('css/ie'.$ver.'.css', 'base').'?version='.LACONICA_VERSION.'" /><![endif]');
} }
} }
$this->comment('[if IE]><link rel="stylesheet" type="text/css" '.
'href="'.theme_path('css/ie.css', null).'?version='.LACONICA_VERSION.'" /><![endif]');
} }
/** /**
@ -246,7 +245,6 @@ class Action extends HTMLOutputter // lawsuit
// does nothing by default // does nothing by default
} }
/** /**
* Show body. * Show body.
* *
@ -257,7 +255,7 @@ class Action extends HTMLOutputter // lawsuit
function showBody() function showBody()
{ {
$this->elementStart('body', array('id' => $this->trimmed('action'))); $this->elementStart('body', array('id' => $this->trimmed('action')));
$this->elementStart('div', 'wrap'); $this->elementStart('div', array('id' => 'wrap'));
$this->showHeader(); $this->showHeader();
$this->showCore(); $this->showCore();
$this->showFooter(); $this->showFooter();
@ -354,7 +352,7 @@ class Action extends HTMLOutputter // lawsuit
$this->elementEnd('dd'); $this->elementEnd('dd');
$this->elementEnd('dl'); $this->elementEnd('dl');
} }
/** /**
* Show site notice. * Show site notice.
* *
@ -368,7 +366,9 @@ class Action extends HTMLOutputter // lawsuit
$this->elementStart('dl', array('id' => 'site_notice', $this->elementStart('dl', array('id' => 'site_notice',
'class' => 'system_notice')); 'class' => 'system_notice'));
$this->element('dt', null, _('Site notice')); $this->element('dt', null, _('Site notice'));
$this->element('dd', null, $text); $this->elementStart('dd', null);
$this->raw($text);
$this->elementEnd('dd');
$this->elementEnd('dl'); $this->elementEnd('dl');
} }
} }
@ -385,7 +385,7 @@ class Action extends HTMLOutputter // lawsuit
$notice_form = new NoticeForm($this); $notice_form = new NoticeForm($this);
$notice_form->show(); $notice_form->show();
} }
/** /**
* Show anonymous message. * Show anonymous message.
* *
@ -761,7 +761,7 @@ class Action extends HTMLOutputter // lawsuit
/** /**
* Boolean understands english (yes, no, true, false) * Boolean understands english (yes, no, true, false)
* *
* @param string $key query key we're interested in * @param string $key query key we're interested in
* @param string $def default value * @param string $def default value
* *
* @return boolean interprets yes/no strings as boolean * @return boolean interprets yes/no strings as boolean

View File

@ -19,12 +19,11 @@
if (!defined('LACONICA')) { exit(1); } if (!defined('LACONICA')) { exit(1); }
define('LACONICA_VERSION', '0.7.0'); define('LACONICA_VERSION', '0.7.1');
define('AVATAR_PROFILE_SIZE', 96); define('AVATAR_PROFILE_SIZE', 96);
define('AVATAR_STREAM_SIZE', 48); define('AVATAR_STREAM_SIZE', 48);
define('AVATAR_MINI_SIZE', 24); define('AVATAR_MINI_SIZE', 24);
define('MAX_AVATAR_SIZE', 256 * 1024);
define('NOTICES_PER_PAGE', 20); define('NOTICES_PER_PAGE', 20);
define('PROFILES_PER_PAGE', 20); define('PROFILES_PER_PAGE', 20);

View File

@ -111,7 +111,7 @@ class ErrorAction extends Action
function showBody() function showBody()
{ {
$this->elementStart('body', array('id' => 'error')); $this->elementStart('body', array('id' => 'error'));
$this->elementStart('div', 'wrap'); $this->elementStart('div', array('id' => 'wrap'));
$this->showHeader(); $this->showHeader();
$this->showCore(); $this->showCore();
$this->showFooter(); $this->showFooter();

View File

@ -129,7 +129,7 @@ class FacebookAction extends Action
* Start an Facebook ready HTML document * Start an Facebook ready HTML document
* *
* For Facebook we don't want to actually output any headers, * For Facebook we don't want to actually output any headers,
* DTD info, etc. * DTD info, etc. Just Stylesheet and JavaScript links.
* *
* If $type isn't specified, will attempt to do content negotiation. * If $type isn't specified, will attempt to do content negotiation.
* *
@ -140,6 +140,9 @@ class FacebookAction extends Action
function startHTML($type=null) function startHTML($type=null)
{ {
$this->showStylesheets();
$this->showScripts();
$this->elementStart('div', array('class' => 'facebook-page')); $this->elementStart('div', array('class' => 'facebook-page'));
} }
@ -168,7 +171,7 @@ class FacebookAction extends Action
function showBody() function showBody()
{ {
$this->elementStart('div', 'wrap'); $this->elementStart('div', array('id' => 'wrap'));
$this->showHeader(); $this->showHeader();
$this->showCore(); $this->showCore();
$this->showFooter(); $this->showFooter();
@ -181,8 +184,6 @@ class FacebookAction extends Action
function showHead($error, $success) function showHead($error, $success)
{ {
$this->showStylesheets();
$this->showScripts();
if ($error) { if ($error) {
$this->element("h1", null, $error); $this->element("h1", null, $error);
@ -204,7 +205,6 @@ class FacebookAction extends Action
// Make this into a widget later // Make this into a widget later
function showLocalNav() function showLocalNav()
{ {
$this->elementStart('ul', array('class' => 'nav')); $this->elementStart('ul', array('class' => 'nav'));
$this->elementStart('li', array('class' => $this->elementStart('li', array('class' =>
@ -229,18 +229,7 @@ class FacebookAction extends Action
$this->elementEnd('li'); $this->elementEnd('li');
$this->elementEnd('ul'); $this->elementEnd('ul');
} }
/**
* Show primary navigation.
*
* @return nothing
*/
function showPrimaryNav()
{
// we don't want to show anything for this
}
/** /**
* Show header of the page. * Show header of the page.
@ -254,7 +243,6 @@ class FacebookAction extends Action
$this->elementStart('div', array('id' => 'header')); $this->elementStart('div', array('id' => 'header'));
$this->showLogo(); $this->showLogo();
$this->showNoticeForm(); $this->showNoticeForm();
$this->showPrimaryNav();
$this->elementEnd('div'); $this->elementEnd('div');
} }
@ -282,7 +270,6 @@ class FacebookAction extends Action
$loginmsg_part1 = _('To use the %s Facebook Application you need to login ' . $loginmsg_part1 = _('To use the %s Facebook Application you need to login ' .
'with your username and password. Don\'t have a username yet? '); 'with your username and password. Don\'t have a username yet? ');
$loginmsg_part2 = _(' a new account.'); $loginmsg_part2 = _(' a new account.');
$this->elementStart('dd'); $this->elementStart('dd');
@ -291,18 +278,18 @@ class FacebookAction extends Action
$this->element('a', $this->element('a',
array('href' => common_local_url('register')), _('Register')); array('href' => common_local_url('register')), _('Register'));
$this->text($loginmsg_part2); $this->text($loginmsg_part2);
$this->elementEnd('p');
$this->elementEnd('dd'); $this->elementEnd('dd');
$this->elementEnd('dl'); $this->elementEnd('dl');
$this->elementEnd('div'); $this->elementEnd('div');
} }
function showLoginForm($msg = null) function showLoginForm($msg = null)
{ {
$this->elementStart('div', array('class' => 'content')); $this->elementStart('div', array('id' => 'content'));
$this->element('h1', null, _('Login')); $this->element('h1', null, _('Login'));
if ($msg) { if ($msg) {
@ -330,6 +317,7 @@ class FacebookAction extends Action
$this->elementEnd('ul'); $this->elementEnd('ul');
$this->submit('submit', _('Login')); $this->submit('submit', _('Login'));
$this->elementEnd('fieldset');
$this->elementEnd('form'); $this->elementEnd('form');
$this->elementStart('p'); $this->elementStart('p');
@ -338,6 +326,7 @@ class FacebookAction extends Action
$this->elementEnd('p'); $this->elementEnd('p');
$this->elementEnd('div'); $this->elementEnd('div');
$this->elementEnd('div');
} }
@ -347,42 +336,70 @@ class FacebookAction extends Action
// Need to include inline CSS for styling the Profile box // Need to include inline CSS for styling the Profile box
$app_props = $this->facebook->api_client->Admin_getAppProperties(array('icon_url'));
$icon_url = $app_props['icon_url'];
$style = '<style> $style = '<style>
.entry-title *,
.entry-content * {
font-size:14px;
font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
}
.entry-title a,
.entry-content a {
color:#002E6E;
}
.entry-title .vcard .photo { .entry-title .vcard .photo {
float:left; float:left;
display:inline; display:inline;
margin-right:11px;
margin-bottom:11px
} }
.entry-title .vcard .nickname { .entry-title {
margin-left:5px; margin-bottom:11px;
} }
.entry-title p.entry-content { .entry-title p.entry-content {
display:inline; display:inline;
margin-left:5px; margin-left:5px;
} }
div.entry-content {
clear:both;
}
div.entry-content dl, div.entry-content dl,
div.entry-content dt, div.entry-content dt,
div.entry-content dd { div.entry-content dd {
display:inline; display:inline;
text-transform:lowercase;
} }
div.entry-content dt, div.entry-content dd,
div.entry-content dd { div.entry-content .device dt {
display:inline; margin-left:0;
margin-left:5px; margin-right:5px;
} }
div.entry-content dl.timestamp dt { div.entry-content dl.timestamp dt,
div.entry-content dl.response dt {
display:none; display:none;
} }
div.entry-content dd a { div.entry-content dd a {
display:inline-block; display:inline-block;
} }
#facebook_laconica_app {
text-indent:-9999px;
height:16px;
width:16px;
display:block;
background:url('.$icon_url.') no-repeat 0 0;
float:right;
}
</style>'; </style>';
$this->xw->openMemory(); $this->xw->openMemory();
$item = new FacebookNoticeListItem($notice, $this); $item = new FacebookProfileBoxNotice($notice, $this);
$item->show(); $item->show();
$fbml = "<fb:wide>$style " . $this->xw->outputMemory(false) . "</fb:wide>"; $fbml = "<fb:wide>$style " . $this->xw->outputMemory(false) . "</fb:wide>";
@ -465,8 +482,6 @@ class FacebookAction extends Action
$content_shortened = common_shorten_links($content); $content_shortened = common_shorten_links($content);
if (mb_strlen($content_shortened) > 140) { if (mb_strlen($content_shortened) > 140) {
common_debug("Content = '$content_shortened'", __FILE__);
common_debug("mb_strlen(\$content) = " . mb_strlen($content_shortened), __FILE__);
$this->showPage(_('That\'s too long. Max notice size is 140 chars.')); $this->showPage(_('That\'s too long. Max notice size is 140 chars.'));
return; return;
} }
@ -539,6 +554,18 @@ class FacebookNoticeForm extends NoticeForm
class FacebookNoticeList extends NoticeList class FacebookNoticeList extends NoticeList
{ {
/**
* constructor
*
* @param Notice $notice stream of notices from DB_DataObject
*/
function __construct($notice, $out=null)
{
parent::__construct($notice, $out);
}
/** /**
* show the list of notices * show the list of notices
* *
@ -593,6 +620,20 @@ class FacebookNoticeList extends NoticeList
class FacebookNoticeListItem extends NoticeListItem class FacebookNoticeListItem extends NoticeListItem
{ {
/**
* constructor
*
* Also initializes the profile attribute.
*
* @param Notice $notice The notice we'll display
*/
function __construct($notice, $out=null)
{
parent::__construct($notice, $out);
}
/** /**
* recipe function for displaying a single notice in the Facebook App. * recipe function for displaying a single notice in the Facebook App.
* *
@ -645,3 +686,65 @@ class FacebookNoticeListItem extends NoticeListItem
} }
} }
class FacebookProfileBoxNotice extends FacebookNoticeListItem
{
/**
* constructor
*
* Also initializes the profile attribute.
*
* @param Notice $notice The notice we'll display
*/
function __construct($notice, $out=null)
{
parent::__construct($notice, $out);
}
/**
* Recipe function for displaying a single notice in the
* Facebook App's Profile
*
* @return void
*/
function show()
{
$this->out->elementStart('div', 'entry-title');
$this->showAuthor();
$this->showContent();
$this->out->elementEnd('div');
$this->out->elementStart('div', 'entry-content');
$this->showNoticeLink();
$this->showNoticeSource();
$this->showReplyTo();
$this->out->elementEnd('div');
$this->showAppLink();
}
function showAppLink()
{
$this->facebook = getFacebook();
$app_props = $this->facebook->api_client->Admin_getAppProperties(
array('canvas_name', 'application_name'));
$this->app_uri = 'http://apps.facebook.com/' . $app_props['canvas_name'];
$this->app_name = $app_props['application_name'];
$this->out->elementStart('a', array('id' => 'facebook_laconica_app',
'href' => $this->app_uri));
$this->out->text($this->app_name);
$this->out->elementEnd('a');
}
}

View File

@ -172,7 +172,7 @@ class HTMLOutputter extends XMLOutputter
'type' => 'text', 'type' => 'text',
'id' => $id); 'id' => $id);
if ($value) { if ($value) {
$attrs['value'] = htmlspecialchars($value); $attrs['value'] = $value;
} }
$this->element('input', $attrs); $this->element('input', $attrs);
if ($instructions) { if ($instructions) {
@ -206,7 +206,7 @@ class HTMLOutputter extends XMLOutputter
'class' => 'checkbox', 'class' => 'checkbox',
'id' => $id); 'id' => $id);
if ($value) { if ($value) {
$attrs['value'] = htmlspecialchars($value); $attrs['value'] = $value;
} }
if ($checked) { if ($checked) {
$attrs['checked'] = 'checked'; $attrs['checked'] = 'checked';

View File

@ -47,18 +47,22 @@ if (!defined('LACONICA')) {
class ImageFile class ImageFile
{ {
var $filename = null; var $id;
var $barename = null; var $filepath;
var $type = null; var $barename;
var $height = null; var $type;
var $width = null; var $height;
var $width;
function __construct($filename=null, $type=null, $width=null, $height=null) function __construct($id=null, $filepath=null, $type=null, $width=null, $height=null)
{ {
$this->filename = $filename; $this->id = $id;
$this->type = $type; $this->filepath = $filepath;
$this->width = $type;
$this->height = $type; $info = @getimagesize($this->filepath);
$this->type = ($info) ? $info[2]:$type;
$this->width = ($info) ? $info[0]:$width;
$this->height = ($info) ? $info[1]:$height;
} }
static function fromUpload($param='upload') static function fromUpload($param='upload')
@ -68,7 +72,7 @@ class ImageFile
break; break;
case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE: case UPLOAD_ERR_FORM_SIZE:
throw new Exception(_('That file is too big.')); throw new Exception(sprintf(_('That file is too big. The maximum file size is %d.'), $this->maxFileSize()));
return; return;
case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_PARTIAL:
@unlink($_FILES[$param]['tmp_name']); @unlink($_FILES[$param]['tmp_name']);
@ -79,35 +83,140 @@ class ImageFile
return; return;
} }
$imagefile = new ImageFile($_FILES[$param]['tmp_name']); $info = @getimagesize($_FILES[$param]['tmp_name']);
$info = @getimagesize($imagefile->filename);
if (!$info) { if (!$info) {
@unlink($imagefile->filename); @unlink($_FILES[$param]['tmp_name']);
throw new Exception(_('Not an image or corrupt file.')); throw new Exception(_('Not an image or corrupt file.'));
return; return;
} }
$imagefile->width = $info[0]; if ($info[2] !== IMAGETYPE_GIF &&
$imagefile->height = $info[1]; $info[2] !== IMAGETYPE_JPEG &&
$info[2] !== IMAGETYPE_PNG) {
switch ($info[2]) { @unlink($_FILES[$param]['tmp_name']);
case IMAGETYPE_GIF:
case IMAGETYPE_JPEG:
case IMAGETYPE_PNG:
$imagefile->type = $info[2];
break;
default:
@unlink($imagefile->filename);
throw new Exception(_('Unsupported image file format.')); throw new Exception(_('Unsupported image file format.'));
return; return;
} }
return $imagefile; return new ImageFile(null, $_FILES[$param]['tmp_name']);
}
function resize($size, $x = 0, $y = 0, $w = null, $h = null)
{
$w = ($w === null) ? $this->width:$w;
$h = ($h === null) ? $this->height:$h;
if (!file_exists($this->filepath)) {
throw new Exception(_('Lost our file.'));
return;
}
switch ($this->type) {
case IMAGETYPE_GIF:
$image_src = imagecreatefromgif($this->filepath);
break;
case IMAGETYPE_JPEG:
$image_src = imagecreatefromjpeg($this->filepath);
break;
case IMAGETYPE_PNG:
$image_src = imagecreatefrompng($this->filepath);
break;
default:
throw new Exception(_('Unknown file type'));
return;
}
$image_dest = imagecreatetruecolor($size, $size);
if ($this->type == IMAGETYPE_GIF || $this->type == IMAGETYPE_PNG) {
$transparent_idx = imagecolortransparent($image_src);
if ($transparent_idx >= 0) {
$transparent_color = imagecolorsforindex($image_src, $transparent_idx);
$transparent_idx = imagecolorallocate($image_dest, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
imagefill($image_dest, 0, 0, $transparent_idx);
imagecolortransparent($image_dest, $transparent_idx);
} elseif ($this->type == IMAGETYPE_PNG) {
imagealphablending($image_dest, false);
$transparent = imagecolorallocatealpha($image_dest, 0, 0, 0, 127);
imagefill($image_dest, 0, 0, $transparent);
imagesavealpha($image_dest, true);
}
}
imagecopyresampled($image_dest, $image_src, 0, 0, $x, $y, $size, $size, $w, $h);
$outname = Avatar::filename($this->id,
image_type_to_extension($this->type),
$size,
common_timestamp());
$outpath = Avatar::path($outname);
switch ($this->type) {
case IMAGETYPE_GIF:
imagegif($image_dest, $outpath);
break;
case IMAGETYPE_JPEG:
imagejpeg($image_dest, $outpath);
break;
case IMAGETYPE_PNG:
imagepng($image_dest, $outpath);
break;
default:
throw new Exception(_('Unknown file type'));
return;
}
return $outname;
} }
function unlink() function unlink()
{ {
@unlink($this->filename); @unlink($this->filename);
} }
static function maxFileSize()
{
$value = ImageFile::maxFileSizeInt();
if ($value > 1024 * 1024) {
return ($value/(1024*1024)).'Mb';
} else if ($value > 1024) {
return ($value/(1024)).'kB';
} else {
return $value;
}
}
static function maxFileSizeInt()
{
return min(ImageFile::strToInt(ini_get('post_max_size')),
ImageFile::strToInt(ini_get('upload_max_filesize')),
ImageFile::strToInt(ini_get('memory_limit')));
}
static function strToInt($str)
{
$unit = substr($str, -1);
$num = substr($str, 0, -1);
switch(strtoupper($unit)){
case 'G':
$num *= 1024;
case 'M':
$num *= 1024;
case 'K':
$num *= 1024;
}
return $num;
}
} }

View File

@ -178,7 +178,7 @@ function jabber_format_entry($profile, $notice)
$entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n"; $entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n";
$entry .= "<link rel='self' type='application/rss+xml' href='" . $self_url . "'/>\n"; $entry .= "<link rel='self' type='application/rss+xml' href='" . $self_url . "'/>\n";
$entry .= "<author><name>" . $profile->nickname . "</name></author>\n"; $entry .= "<author><name>" . $profile->nickname . "</name></author>\n";
$entry .= "<icon>" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "</icon>\n"; $entry .= "<icon>" . $profile->avatarUrl(AVATAR_PROFILE_SIZE) . "</icon>\n";
$entry .= "</source>\n"; $entry .= "</source>\n";
$entry .= "<title>" . htmlspecialchars($msg) . "</title>\n"; $entry .= "<title>" . htmlspecialchars($msg) . "</title>\n";
$entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n"; $entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";

View File

@ -63,6 +63,8 @@ class MailboxAction extends PersonalAction
$this->page = 1; $this->page = 1;
} }
common_set_returnto($this->selfUrl());
return true; return true;
} }
@ -181,8 +183,8 @@ class MailboxAction extends PersonalAction
'class' => 'url')); 'class' => 'url'));
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
$this->element('img', array('src' => ($avatar) ? $this->element('img', array('src' => ($avatar) ?
common_avatar_display_url($avatar) : $avatar->displayUrl() :
common_default_avatar(AVATAR_STREAM_SIZE), Avatar::defaultImage(AVATAR_STREAM_SIZE),
'class' => 'photo avatar', 'class' => 'photo avatar',
'width' => AVATAR_STREAM_SIZE, 'width' => AVATAR_STREAM_SIZE,
'height' => AVATAR_STREAM_SIZE, 'height' => AVATAR_STREAM_SIZE,

View File

@ -203,11 +203,14 @@ class NoticeListItem extends Widget
function showNoticeOptions() function showNoticeOptions()
{ {
$this->out->elementStart('div', 'notice-options'); $user = common_current_user();
$this->showFaveForm(); if ($user) {
$this->showReplyLink(); $this->out->elementStart('div', 'notice-options');
$this->showDeleteLink(); $this->showFaveForm();
$this->out->elementEnd('div'); $this->showReplyLink();
$this->showDeleteLink();
$this->out->elementEnd('div');
}
} }
/** /**
@ -282,8 +285,8 @@ class NoticeListItem extends Widget
$avatar = $this->profile->getAvatar($avatar_size); $avatar = $this->profile->getAvatar($avatar_size);
$this->out->element('img', array('src' => ($avatar) ? $this->out->element('img', array('src' => ($avatar) ?
common_avatar_display_url($avatar) : $avatar->displayUrl() :
common_default_avatar($avatar_size), Avatar::defaultImage($avatar_size),
'class' => 'avatar photo', 'class' => 'avatar photo',
'width' => $avatar_size, 'width' => $avatar_size,
'height' => $avatar_size, 'height' => $avatar_size,

View File

@ -82,7 +82,7 @@ class NoticeSection extends Section
$profile->nickname, $profile->nickname,
'href' => $profile->profileurl, 'href' => $profile->profileurl,
'class' => 'url')); 'class' => 'url'));
$this->out->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)), $this->out->element('img', array('src' => (($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_MINI_SIZE)),
'width' => AVATAR_MINI_SIZE, 'width' => AVATAR_MINI_SIZE,
'height' => AVATAR_MINI_SIZE, 'height' => AVATAR_MINI_SIZE,
'class' => 'avatar photo', 'class' => 'avatar photo',

View File

@ -55,7 +55,6 @@ class PersonalAction extends Action
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
common_set_returnto($this->selfUrl());
} }
} }

View File

@ -31,7 +31,7 @@ if (!defined('LACONICA')) {
exit(1); exit(1);
} }
define('NOTICES_PER_SECTION', 6); define('NOTICES_PER_SECTION', 5);
/** /**
* Base class for sections showing lists of notices * Base class for sections showing lists of notices

View File

@ -97,7 +97,7 @@ class ProfileList extends Widget
$avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE); $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE);
$this->out->elementStart('a', array('href' => $this->profile->profileurl, $this->out->elementStart('a', array('href' => $this->profile->profileurl,
'class' => 'url')); 'class' => 'url'));
$this->out->element('img', array('src' => ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE), $this->out->element('img', array('src' => ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_STREAM_SIZE),
'class' => 'photo avatar', 'class' => 'photo avatar',
'width' => AVATAR_STREAM_SIZE, 'width' => AVATAR_STREAM_SIZE,
'height' => AVATAR_STREAM_SIZE, 'height' => AVATAR_STREAM_SIZE,

View File

@ -74,7 +74,7 @@ class ProfileMiniList extends ProfileList
'rel' => 'contact member', 'rel' => 'contact member',
'class' => 'url')); 'class' => 'url'));
$avatar = $this->profile->getAvatar(AVATAR_MINI_SIZE); $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)), $this->out->element('img', array('src' => (($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_MINI_SIZE)),
'width' => AVATAR_MINI_SIZE, 'width' => AVATAR_MINI_SIZE,
'height' => AVATAR_MINI_SIZE, 'height' => AVATAR_MINI_SIZE,
'class' => 'avatar photo', 'class' => 'avatar photo',

View File

@ -86,7 +86,7 @@ class ProfileSection extends Section
'rel' => 'contact member', 'rel' => 'contact member',
'class' => 'url')); 'class' => 'url'));
$avatar = $profile->getAvatar(AVATAR_MINI_SIZE); $avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
$this->out->element('img', array('src' => (($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_MINI_SIZE)), $this->out->element('img', array('src' => (($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_MINI_SIZE)),
'width' => AVATAR_MINI_SIZE, 'width' => AVATAR_MINI_SIZE,
'height' => AVATAR_MINI_SIZE, 'height' => AVATAR_MINI_SIZE,
'class' => 'avatar photo', 'class' => 'avatar photo',

View File

@ -199,7 +199,7 @@ class Rss10Action extends Action
$this->element('dc:date', null, common_date_w3dtf($notice->created)); $this->element('dc:date', null, common_date_w3dtf($notice->created));
$this->element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname); $this->element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname);
$this->element('sioc:has_creator', array('rdf:resource' => $creator_uri)); $this->element('sioc:has_creator', array('rdf:resource' => $creator_uri));
$this->element('laconica:postIcon', array('rdf:resource' => common_profile_avatar_url($profile))); $this->element('laconica:postIcon', array('rdf:resource' => $profile->avatarUrl()));
$this->element('cc:licence', array('rdf:resource' => common_config('license', 'url'))); $this->element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
$this->elementEnd('item'); $this->elementEnd('item');
$this->creators[$creator_uri] = $profile; $this->creators[$creator_uri] = $profile;
@ -216,7 +216,7 @@ class Rss10Action extends Action
$this->element('foaf:name', null, $profile->fullname); $this->element('foaf:name', null, $profile->fullname);
} }
$this->element('sioc:id', null, $id); $this->element('sioc:id', null, $id);
$avatar = common_profile_avatar_url($profile); $avatar = $profile->avatarUrl();
$this->element('sioc:avatar', array('rdf:resource' => $avatar)); $this->element('sioc:avatar', array('rdf:resource' => $avatar));
$this->elementEnd('sioc:User'); $this->elementEnd('sioc:User');
} }

View File

@ -76,7 +76,12 @@ class SettingsAction extends Action
// change important settings or see private info, and // change important settings or see private info, and
// _all_ our settings are important // _all_ our settings are important
common_set_returnto($this->selfUrl()); common_set_returnto($this->selfUrl());
common_redirect(common_local_url('login')); $user = common_current_user();
if ($user->hasOpenID()) {
common_redirect(common_local_url('openidlogin'));
} else {
common_redirect(common_local_url('login'));
}
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') { } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->handlePost(); $this->handlePost();
} else { } else {

View File

@ -43,7 +43,7 @@ class TwitterapiAction extends Action
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
$twitter_user['profile_image_url'] = ($avatar) ? common_avatar_display_url($avatar) : common_default_avatar(AVATAR_STREAM_SIZE); $twitter_user['profile_image_url'] = ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_STREAM_SIZE);
$twitter_user['protected'] = 'false'; # not supported by Laconica yet $twitter_user['protected'] = 'false'; # not supported by Laconica yet
$twitter_user['url'] = ($profile->homepage) ? $profile->homepage : null; $twitter_user['url'] = ($profile->homepage) ? $profile->homepage : null;

View File

@ -386,46 +386,99 @@ function common_render_text($text)
$r = htmlspecialchars($text); $r = htmlspecialchars($text);
$r = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $r); $r = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $r);
$r = preg_replace_callback('@(ftp|http|https|mms|rtsp|gopher|news|nntp|telnet|wais|file|prospero|webcal|xmpp|irc)://[^\]>\s]+@', 'common_render_uri_thingy', $r); $r = common_replace_urls_callback($r, 'common_linkify');
$r = preg_replace_callback('@(mailto|aim|tel):[^\]>\s]+@', 'common_render_uri_thingy', $r); // Pseudo-protocols don't require '//' after ':'. $r = preg_replace('/(^|\(|\[|\s+)#([A-Za-z0-9_\-\.]{1,64})/e', "'\\1#'.common_tag_link('\\2')", $r);
$r = preg_replace('/(^|\s+)#([A-Za-z0-9_\-\.]{1,64})/e', "'\\1#'.common_tag_link('\\2')", $r);
// XXX: machine tags // XXX: machine tags
return $r; return $r;
} }
function common_render_uri_thingy($matches) function common_replace_urls_callback($text, $callback) {
{ // Start off with a regex
$uri = $matches[0]; $regex = '#
$trailer = ''; (?:
(?:
(?:https?|ftps?|mms|rtsp|gopher|news|nntp|telnet|wais|file|prospero|webcal|xmpp|irc)://
|
(?:mailto|aim|tel):
)
[^.\s]+\.[^\s]+
|
(?:[^.\s/:]+\.)+
(?:museum|travel|[a-z]{2,4})
(?:[:/][^\s]*)?
)
#ix';
preg_match_all($regex, $text, $matches);
// Some heuristics for extracting URIs from surrounding punctuation // Then clean up what the regex left behind
// Strip from trailing text... $offset = 0;
if (preg_match('/^(.*)([,.:"\']+)$/', $uri, $matches)) { foreach($matches[0] as $url) {
$uri = $matches[1]; $url = htmlspecialchars_decode($url);
$trailer = $matches[2];
}
$pairs = array( // Make sure we didn't pick up an email address
']' => '[', // technically disallowed in URIs, but used in Java docs if (preg_match('#^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$#i', $url)) continue;
')' => '(', // far too frequent in Wikipedia and MSDN
); // Remove trailing punctuation
$final = substr($uri, -1, 1); $url = rtrim($url, '.?!,;:\'"`');
if (isset($pairs[$final])) {
$openers = substr_count($uri, $pairs[$final]); // Remove surrounding parens and the like
$closers = substr_count($uri, $final); preg_match('/[)\]>]+$/', $url, $trailing);
if ($closers > $openers) { if (isset($trailing[0])) {
// Assume the paren was opened outside the URI preg_match_all('/[(\[<]/', $url, $opened);
$uri = substr($uri, 0, -1); preg_match_all('/[)\]>]/', $url, $closed);
$trailer = $final . $trailer; $unopened = count($closed[0]) - count($opened[0]);
// Make sure not to take off more closing parens than there are at the end
$unopened = ($unopened > mb_strlen($trailing[0])) ? mb_strlen($trailing[0]):$unopened;
$url = ($unopened > 0) ? mb_substr($url, 0, $unopened * -1):$url;
} }
// Remove trailing punctuation again (in case there were some inside parens)
$url = rtrim($url, '.?!,;:\'"`');
// Make sure we didn't capture part of the next sentence
preg_match('#((?:[^.\s/]+\.)+)(museum|travel|[a-z]{2,4})#i', $url, $url_parts);
// Were the parts capitalized any?
$last_part = (mb_strtolower($url_parts[2]) !== $url_parts[2]) ? true:false;
$prev_part = (mb_strtolower($url_parts[1]) !== $url_parts[1]) ? true:false;
// If the first part wasn't cap'd but the last part was, we captured too much
if ((!$prev_part && $last_part)) {
$url = substr_replace($url, '', mb_strpos($url, '.'.$url_parts[2], 0));
}
// Capture the new TLD
preg_match('#((?:[^.\s/]+\.)+)(museum|travel|[a-z]{2,4})#i', $url, $url_parts);
$tlds = array('ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'arpa', 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'biz', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', 'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'edu', 'ee', 'eg', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'info', 'int', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', 'mn', 'mo', 'mobi', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 'ne', 'net', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', 'tz', 'ua', 'ug', 'uk', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm', 'zw');
if (!in_array($url_parts[2], $tlds)) continue;
// Call user specified func
$modified_url = $callback($url);
// Replace it!
$start = mb_strpos($text, $url, $offset);
$text = mb_substr($text, 0, $start).$modified_url.mb_substr($text, $start + mb_strlen($url), mb_strlen($text));
$offset = $start + mb_strlen($modified_url);
} }
if ($longurl = common_longurl($uri)) {
return $text;
}
function common_linkify($url) {
$display = $url;
$url = (!preg_match('#^([a-z]+://|(mailto|aim|tel):)#i', $url)) ? 'http://'.$url:$url;
if ($longurl = common_longurl($url)) {
$longurl = htmlentities($longurl, ENT_QUOTES, 'UTF-8'); $longurl = htmlentities($longurl, ENT_QUOTES, 'UTF-8');
$title = " title='$longurl'"; $title = "title=\"$longurl\"";
} }
else $title = ''; else $title = '';
return '<a href="' . $uri . '"' . $title . ' class="extlink">' . $uri . '</a>' . $trailer; return "<a href=\"$url\" $title class=\"extlink\">$display</a>";
} }
function common_longurl($short_url) function common_longurl($short_url)
@ -449,7 +502,7 @@ function common_shorten_links($text)
static $cache = array(); static $cache = array();
if (isset($cache[$text])) return $cache[$text]; if (isset($cache[$text])) return $cache[$text];
// \s = not a horizontal whitespace character (since PHP 5.2.4) // \s = not a horizontal whitespace character (since PHP 5.2.4)
return $cache[$text] = preg_replace('@https?://[^)\]>\s]+@e', "common_shorten_link('\\0')", $text); return $cache[$text] = common_replace_urls_callback($text, 'common_shorten_link');;
} }
function common_shorten_link($url, $reverse = false) function common_shorten_link($url, $reverse = false)
@ -614,48 +667,6 @@ function common_relative_profile($sender, $nickname, $dt=null)
return null; return null;
} }
// where should the avatar go for this user?
function common_avatar_filename($id, $extension, $size=null, $extra=null)
{
global $config;
if ($size) {
return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension;
} else {
return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension;
}
}
function common_avatar_path($filename)
{
global $config;
return INSTALLDIR . '/avatar/' . $filename;
}
function common_avatar_url($filename)
{
return common_path('avatar/'.$filename);
}
function common_avatar_display_url($avatar)
{
$server = common_config('avatar', 'server');
if ($server) {
return 'http://'.$server.'/'.$avatar->filename;
} else {
return $avatar->url;
}
}
function common_default_avatar($size)
{
static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile',
AVATAR_STREAM_SIZE => 'stream',
AVATAR_MINI_SIZE => 'mini');
return theme_path('default-avatar-'.$sizenames[$size].'.png');
}
function common_local_url($action, $args=null, $fragment=null) function common_local_url($action, $args=null, $fragment=null)
{ {
$url = null; $url = null;
@ -697,6 +708,8 @@ function common_fancy_url($action, $args=null)
return common_path("api/statuses/public_timeline.atom"); return common_path("api/statuses/public_timeline.atom");
case 'publicxrds': case 'publicxrds':
return common_path('xrds'); return common_path('xrds');
case 'tagrss':
return common_path('tag/' . $args['tag'] . '/rss');
case 'featuredrss': case 'featuredrss':
return common_path('featuredrss'); return common_path('featuredrss');
case 'favoritedrss': case 'favoritedrss':
@ -898,7 +911,7 @@ function common_fancy_url($action, $args=null)
case 'grouprss': case 'grouprss':
return common_path('group/'.$args['nickname'].'/rss'); return common_path('group/'.$args['nickname'].'/rss');
case 'groupmembers': case 'groupmembers':
return common_path('group/'.$args['nickname'].'/members'); return common_path('group/'.$args['nickname'].'/members' . (($args['page']) ? ('?page=' . $args['page']) : ''));
case 'grouplogo': case 'grouplogo':
return common_path('group/'.$args['nickname'].'/logo'); return common_path('group/'.$args['nickname'].'/logo');
case 'usergroups': case 'usergroups':
@ -1470,16 +1483,6 @@ function common_markup_to_html($c)
return Markdown($c); return Markdown($c);
} }
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);
}
}
function common_profile_uri($profile) function common_profile_uri($profile)
{ {
if (!$profile) { if (!$profile) {

View File

@ -74,7 +74,7 @@ class EnjitQueueHandler extends QueueHandler
$atom .= "<link href='" . $profile->profileurl . "'/>\n"; $atom .= "<link href='" . $profile->profileurl . "'/>\n";
$atom .= "<link rel='self' type='application/rss+xml' href='" . common_local_url('userrss', array('nickname' => $profile->nickname)) . "'/>\n"; $atom .= "<link rel='self' type='application/rss+xml' href='" . common_local_url('userrss', array('nickname' => $profile->nickname)) . "'/>\n";
$atom .= "<author><name>" . $profile->nickname . "</name></author>\n"; $atom .= "<author><name>" . $profile->nickname . "</name></author>\n";
$atom .= "<icon>" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "</icon>\n"; $atom .= "<icon>" . $profile->avatarUrl(AVATAR_PROFILE_SIZE) . "</icon>\n";
$atom .= "</source>\n"; $atom .= "</source>\n";
$atom .= "<title>" . htmlspecialchars($msg) . "</title>\n"; $atom .= "<title>" . htmlspecialchars($msg) . "</title>\n";
$atom .= "<summary>" . htmlspecialchars($msg) . "</summary>\n"; $atom .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";

View File

@ -20,12 +20,11 @@ font-family:sans-serif;
font-size:1em; font-size:1em;
line-height:1.65; line-height:1.65;
position:relative; position:relative;
margin:0 auto;
width:71.714em;
} }
h1,h2,h3,h4,h5,h6 { h1,h2,h3,h4,h5,h6 {
text-transform:uppercase; text-transform:uppercase;
margin-bottom:7px; margin-bottom:7px;
overflow:hidden;
} }
h1 { h1 {
font-size:1.4em; font-size:1.4em;
@ -153,7 +152,8 @@ font-weight:bold;
#form_remote_subscribe legend, #form_remote_subscribe legend,
#form_openid_login legend, #form_openid_login legend,
#form_search legend, #form_search legend,
#form_invite legend { #form_invite legend,
#form_notice_delete legend {
display:none; display:none;
} }
@ -180,6 +180,7 @@ float:left;
width:90%; width:90%;
} }
#form_login p.form_guide, #form_login p.form_guide,
#form_register #settings_rememberme p.form_guide, #form_register #settings_rememberme p.form_guide,
#form_openid_login #settings_rememberme p.form_guide, #form_openid_login #settings_rememberme p.form_guide,
@ -195,12 +196,16 @@ border-radius:4px;
padding:0 7px; padding:0 7px;
} }
.form_settings input.form_action-secondary {
margin-left:29px;
padding:0;
}
#form_search .submit { #form_search .submit {
margin-left:11px; margin-left:11px;
} }
address { address {
float:left; float:left;
margin-bottom:18px; margin-bottom:18px;
@ -240,10 +245,9 @@ display:none;
#site_notice { #site_notice {
position:absolute; position:absolute;
right:0; top:65px;
top:49px; right:18px;
float:right; width:250px;
width:300px;
} }
#page_notice { #page_notice {
clear:both; clear:both;
@ -254,6 +258,7 @@ margin-bottom:18px;
#anon_notice { #anon_notice {
float:left; float:left;
width:432px; width:432px;
width:28.052em;
padding:11px; padding:11px;
border-radius:7px; border-radius:7px;
-moz-border-radius:7px; -moz-border-radius:7px;
@ -361,9 +366,10 @@ margin-right:4px;
} }
#wrap { #wrap {
float:left;
margin:0 auto; margin:0 auto;
width:71.714em; width:71.714em;
width:1003px;
overflow:hidden;
} }
#core { #core {
@ -391,9 +397,9 @@ float:left;
} }
#aside_primary { #aside_primary {
width:284px; width:280px;
float:left; float:left;
margin-left:2px; margin-left:4px;
padding:18px; padding:18px;
border-radius:7px; border-radius:7px;
-moz-border-radius:7px; -moz-border-radius:7px;
@ -509,6 +515,7 @@ min-height:123px;
float:left; float:left;
margin-bottom:18px; margin-bottom:18px;
margin-left:0; margin-left:0;
overflow:hidden;
} }
.entity_profile dt, .entity_profile dt,
#entity_statistics dt { #entity_statistics dt {
@ -606,12 +613,14 @@ display:block;
.form_user_block input.submit, .form_user_block input.submit,
.form_user_unblock input.submit, .form_user_unblock input.submit,
.entity_send-a-message a, .entity_send-a-message a,
.entity_edit a,
.form_user_nudge input.submit, .form_user_nudge input.submit,
.entity_nudge p { .entity_nudge p {
border:0; border:0;
padding-left:20px; padding-left:20px;
} }
.entity_edit a,
.entity_send-a-message a, .entity_send-a-message a,
.entity_nudge p { .entity_nudge p {
padding:4px 4px 4px 23px; padding:4px 4px 4px 23px;
@ -749,7 +758,7 @@ border-radius:4px;
/* NOTICES */ /* NOTICES */
#notices_primary { #notices_primary {
float:left; float:left;
width:644px; width:100%;
border-radius:7px; border-radius:7px;
-moz-border-radius:7px; -moz-border-radius:7px;
-webkit-border-radius:7px; -webkit-border-radius:7px;
@ -766,6 +775,10 @@ padding-left:28px;
margin-right:11px; margin-right:11px;
} }
.fn {
overflow:hidden;
}
.notice .author .fn { .notice .author .fn {
font-weight:bold; font-weight:bold;
} }
@ -790,7 +803,7 @@ text-decoration:underline;
.notice .entry-title { .notice .entry-title {
float:left; float:left;
width:100%; width:100%;
overflow:auto; overflow:hidden;
} }
#shownotice .notice .entry-title { #shownotice .notice .entry-title {
font-size:2.2em; font-size:2.2em;
@ -934,7 +947,7 @@ padding:0;
#new_group { #new_group, #group_search {
margin-bottom:18px; margin-bottom:18px;
} }
#new_group a { #new_group a {
@ -1063,13 +1076,20 @@ margin-bottom:0;
} }
.section .notice { .section .notice {
padding-top:11px; padding-top:7px;
padding-bottom:11px; padding-bottom:7px;
border-top:0;
} }
.section .notice:first-child { .section .notice:first-child {
padding-top:0; padding-top:0;
border-top:0; }
.section .notice .author {
margin-right:0;
}
.section .notice .author .fn {
display:none;
} }
@ -1154,3 +1174,5 @@ clear:both;
#form_settings_avatar .form_actions { #form_settings_avatar .form_actions {
margin-bottom:0; margin-bottom:0;
} }

View File

@ -1,10 +1,86 @@
@import url("display.css"); @import url("display.css");
@import url("../../identica/css/display.css"); @import url("../../identica/css/display.css");
span.facebook-button { border: 2px solid #777; padding: 5px; display: block; float: left; margin-right: 20px; -moz-border-radius: 4px; border-radius:4px; -webkit-border-radius:4px; font-weight: bold; background-color:#A9BF4F; color:#fff; font-size:1.2em } * {
font-size:14px;
font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
}
#wrap {
background-color:#F0F2F5;
padding-left:18px;
padding-right:18px;
width:auto;
}
p,label,
h1,h2,h3,h4,h5,h6 {
color:#000;
}
#content {
width:95%;
}
#site_nav_local_views a {
background-color:#D0DFE7;
}
#site_nav_local_views a:hover {
background-color:#FAFBFC;
}
span.facebook-button {
border: 2px solid #aaa;
padding: 3px;
display: block;
float: left;
margin-right: 20px;
-moz-border-radius: 4px;
border-radius:4px;
-webkit-border-radius:4px;
font-weight: bold;
background-color:#A9BF4F;
color:#fff;
font-size:1.2em
}
span.facebook-button a { color:#fff } span.facebook-button a { color:#fff }
.facebook_guide {
margin-bottom:18px;
}
.facebook_guide p {
font-weight:bold;
}
input {
height:auto !important;
}
#facebook-friends {
float:left;
width:100%;
}
#facebook-friends li {
float:left;
margin-right:2%;
margin-bottom:11px;
width:18%;
height:115px;
}
#facebook-friends li a {
float:left;
}
#add_to_profile {
position:absolute;
right:18px;
top:10px;
z-index:2;
}
.notice div.entry-content dl, .notice div.entry-content dl,
.notice div.entry-content dt, .notice div.entry-content dt,
.notice div.entry-content dd { .notice div.entry-content dd {
@ -19,12 +95,6 @@ margin-bottom:18px;
list-style-type:none; list-style-type:none;
} }
.facebook_guide p {
margin-bottom:18px;
font-size:1.3em;
font-weight:bold;
}
.form_settings label { .form_settings label {
margin-right:18px; margin-right:18px;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -34,6 +34,9 @@ border-color:#aaa;
border-color:#97BFD1; border-color:#97BFD1;
} }
.form_settings input.form_action-secondary {
background:none;
}
input.submit, input.submit,
#form_notice.warning #notice_text-count, #form_notice.warning #notice_text-count,
@ -59,7 +62,8 @@ div.notice-options input,
.form_user_unblock input.submit, .form_user_unblock input.submit,
.entity_send-a-message a, .entity_send-a-message a,
.form_user_nudge input.submit, .form_user_nudge input.submit,
.entity_nudge p { .entity_nudge p,
.form_settings input.form_action-secondary {
color:#002E6E; color:#002E6E;
} }
@ -67,7 +71,6 @@ color:#002E6E;
.profile { .profile {
border-top-color:#D1D9E4; border-top-color:#D1D9E4;
} }
.section .notice,
.section .profile { .section .profile {
border-top-color:#97BFD1; border-top-color:#97BFD1;
} }
@ -92,12 +95,6 @@ color:#333;
color:#000; color:#000;
} }
#form_notice #notice_data-attach_view {
background-image:url(../images/icons/twotone/green/paper-clip.gif);
background-repeat:no-repeat;
background-position:0 45%;
background-color:transparent;
}
#nav_register a { #nav_register a {
text-decoration:none; text-decoration:none;
@ -123,8 +120,6 @@ background-color:rgba(255, 255, 255, 0.7);
} }
#page_notice .error { #page_notice .error {
background-color:#F7E8E8; background-color:#F7E8E8;
} }
@ -144,26 +139,21 @@ background-color:#A9BF4F;
} }
#export_data li a { #export_data li a {
background-repeat:no-repeat; background-repeat:no-repeat;
background-position:0 45%; background-position:0 45%;
} }
#export_data li a.rss { #export_data li a.rss {
background-image:url(../../base/images/icons/icon_rss.jpg); background-image:url(../../base/images/icons/icon_rss.png);
} }
#export_data li a.atom { #export_data li a.atom {
background-image:url(../../base/images/icons/icon_atom.jpg); background-image:url(../../base/images/icons/icon_atom.png);
} }
#export_data li a.foaf { #export_data li a.foaf {
background-image:url(../../base/images/icons/icon_foaf.gif); background-image:url(../../base/images/icons/icon_foaf.gif);
} }
#export_data li a.export_vcard {
background-image:url(../../base/images/icons/icon_vcard.gif);
}
.entity_edit a,
.entity_send-a-message a, .entity_send-a-message a,
.form_user_nudge input.submit, .form_user_nudge input.submit,
.form_user_block input.submit, .form_user_block input.submit,
@ -185,6 +175,9 @@ color:#fff;
background-color:#97BFD1; background-color:#97BFD1;
} }
.entity_edit a {
background-image:url(../images/icons/twotone/green/edit.gif);
}
.entity_send-a-message a { .entity_send-a-message a {
background-image:url(../images/icons/twotone/green/quote.gif); background-image:url(../images/icons/twotone/green/quote.gif);
} }
@ -204,30 +197,6 @@ background-image:url(../images/icons/twotone/green/shield.gif);
background-color:#fcfcfc; background-color:#fcfcfc;
} }
.notice-data a span {
background-color:transparent;
background-repeat:no-repeat;
background-position:0 45%;
}
.notice_video .notice-data a span {
background-image:url(../images/icons/twotone/green/camera.gif);
}
.notice_audio .notice-data a span {
background-image:url(../images/icons/twotone/green/music.gif);
}
.notice_image .notice-data a span {
background-image:url(../images/icons/twotone/green/search.gif);
}
.notice_event .notice-data a span {
background-image:url(../images/icons/twotone/green/calendar.gif);
}
.notice_location .notice-data a span {
background-image:url(../images/icons/twotone/green/flag.gif);
}
.notice_document .notice-data a span {
background-image:url(../images/icons/twotone/green/document.gif);
}
.notice-options .notice_reply a, .notice-options .notice_reply a,
.notice-options form input.submit { .notice-options form input.submit {
background-color:transparent; background-color:transparent;
@ -269,17 +238,21 @@ background-color:#fcfcfc;
#new_group a { #new_group a {
background:transparent url(../images/icons/twotone/green/news.gif) no-repeat 0 45%; background:transparent url(../images/icons/twotone/green/news.gif) no-repeat 0 45%;
} }
#usergroups #new_group {
float: left;
margin-right: 2em;
}
.pagination .nav_prev a, .pagination .nav_prev a,
.pagination .nav_next a { .pagination .nav_next a {
background-repeat:no-repeat; background-repeat:no-repeat;
border-color:#D1D9E4;
} }
.pagination .nav_prev a { .pagination .nav_prev a {
background-image:url(../images/icons/twotone/green/arrow-left.gif); background-image:url(../images/icons/twotone/green/arrow-left.gif);
background-position:0 45%; background-position:10% 45%;
} }
.pagination .nav_next a { .pagination .nav_next a {
background-image:url(../images/icons/twotone/green/arrow-right.gif); background-image:url(../images/icons/twotone/green/arrow-right.gif);
background-position:100% 45%; background-position:90% 45%;
} }

9
theme/default/css/ie.css Normal file
View File

@ -0,0 +1,9 @@
/* IE specific styles */
.notice-options input.submit {
color:#fff;
}
#site_nav_local_views a {
background-color:#ACCCDA;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

View File

@ -1,73 +0,0 @@
@charset "UTF-8";
/* CSS Document */
body {
text-align: center;
}
input {
height: 24px;
}
#wrap {
margin: 0 auto;
padding: 0 20px;
width: 800px;
text-align: left;
background: url(bg-header.gif) repeat-x #fbf2d7;
}
#header {
position: relative;
margin-left: 108px;
}
#nav_views {
margin: 0;
}
#nav_views li {
line-height: 19px;
}
.statistics dd {
margin-top: -15px;
clear: both;
}
#notices {
margin: 0;
}
.notice_single {
height: 48px;
}
#profile {
margin-left:0px;
}
#profile p.notice_current {
height: 96px;
}
#filter_tags {
margin-left:20px;
}
#content .subscriptions {
margin-left:30px;
width:100%;
}
#subscriptions_avatars li {
float: left;
margin: 0;
padding: 0;
}
img.avatar.original, img.avatar.profile {
clear: none;
float: left;
}
#status_textarea {
height: 46px;
}
#nav_pagination li a {
padding: 6px 15px;
line-height: 27px;
}
#nav_sub {
position: relative;
margin-left: 108px;
}
#footer {
margin-left: 108px;
}

View File

@ -1,39 +0,0 @@
@charset "UTF-8";
/* CSS Document */
input.disfavor,
input.favor {
text-indent:0;
text-align:right;
padding-left:25px;
}
#profile_actions li {
float:left;
clear:both;
}
#profile_actions #profile_nudge input.submit {
margin-left:0;
width:100px;
}
#statistics dd {
clear: both;
}
#subscriptions_avatars li {
float: left;
}
img.avatar.original, img.avatar.profile {
clear: none;
float: left;
}
#nav_pagination li a {
padding: 6px 15px;
line-height: 27px;
}
#filter_tags ul li#filter_tags_item label {
position:relative;
top:-8px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -34,6 +34,9 @@ border-color:#aaa;
border-color:#ddd; border-color:#ddd;
} }
.form_settings input.form_action-secondary {
background:none;
}
input.submit, input.submit,
#form_notice.warning #notice_text-count, #form_notice.warning #notice_text-count,
@ -59,7 +62,8 @@ div.notice-options input,
.form_user_unblock input.submit, .form_user_unblock input.submit,
.entity_send-a-message a, .entity_send-a-message a,
.form_user_nudge input.submit, .form_user_nudge input.submit,
.entity_nudge p { .entity_nudge p,
.form_settings input.form_action-secondary {
color:#002E6E; color:#002E6E;
} }
@ -67,7 +71,6 @@ color:#002E6E;
.profile { .profile {
border-top-color:#CEE1E9; border-top-color:#CEE1E9;
} }
.section .notice,
.section .profile { .section .profile {
border-top-color:#87B4C8; border-top-color:#87B4C8;
} }
@ -92,12 +95,6 @@ color:#333;
color:#000; color:#000;
} }
#form_notice #notice_data-attach_view {
background-image:url(../images/icons/twotone/green/paper-clip.gif);
background-repeat:no-repeat;
background-position:0 45%;
background-color:transparent;
}
#nav_register a { #nav_register a {
text-decoration:none; text-decoration:none;
@ -123,8 +120,6 @@ background-color:rgba(255, 255, 255, 0.7);
} }
#page_notice .error { #page_notice .error {
background-color:#F7E8E8; background-color:#F7E8E8;
} }
@ -144,26 +139,21 @@ background-color:#9BB43E;
} }
#export_data li a { #export_data li a {
background-repeat:no-repeat; background-repeat:no-repeat;
background-position:0 45%; background-position:0 45%;
} }
#export_data li a.rss { #export_data li a.rss {
background-image:url(../../base/images/icons/icon_rss.jpg); background-image:url(../../base/images/icons/icon_rss.png);
} }
#export_data li a.atom { #export_data li a.atom {
background-image:url(../../base/images/icons/icon_atom.jpg); background-image:url(../../base/images/icons/icon_atom.png);
} }
#export_data li a.foaf { #export_data li a.foaf {
background-image:url(../../base/images/icons/icon_foaf.gif); background-image:url(../../base/images/icons/icon_foaf.gif);
} }
#export_data li a.export_vcard {
background-image:url(../../base/images/icons/icon_vcard.gif);
}
.entity_edit a,
.entity_send-a-message a, .entity_send-a-message a,
.form_user_nudge input.submit, .form_user_nudge input.submit,
.form_user_block input.submit, .form_user_block input.submit,
@ -185,6 +175,9 @@ color:#fff;
background-color:#87B4C8; background-color:#87B4C8;
} }
.entity_edit a {
background-image:url(../images/icons/twotone/green/edit.gif);
}
.entity_send-a-message a { .entity_send-a-message a {
background-image:url(../images/icons/twotone/green/quote.gif); background-image:url(../images/icons/twotone/green/quote.gif);
} }
@ -204,30 +197,6 @@ background-image:url(../images/icons/twotone/green/shield.gif);
background-color:#fcfcfc; background-color:#fcfcfc;
} }
.notice-data a span {
background-color:transparent;
background-repeat:no-repeat;
background-position:0 45%;
}
.notice_video .notice-data a span {
background-image:url(../images/icons/twotone/green/camera.gif);
}
.notice_audio .notice-data a span {
background-image:url(../images/icons/twotone/green/music.gif);
}
.notice_image .notice-data a span {
background-image:url(../images/icons/twotone/green/search.gif);
}
.notice_event .notice-data a span {
background-image:url(../images/icons/twotone/green/calendar.gif);
}
.notice_location .notice-data a span {
background-image:url(../images/icons/twotone/green/flag.gif);
}
.notice_document .notice-data a span {
background-image:url(../images/icons/twotone/green/document.gif);
}
.notice-options .notice_reply a, .notice-options .notice_reply a,
.notice-options form input.submit { .notice-options form input.submit {
background-color:transparent; background-color:transparent;
@ -269,7 +238,10 @@ background-color:#fcfcfc;
#new_group a { #new_group a {
background:transparent url(../images/icons/twotone/green/news.gif) no-repeat 0 45%; background:transparent url(../images/icons/twotone/green/news.gif) no-repeat 0 45%;
} }
#usergroups #new_group {
float: left;
margin-right: 2em;
}
.pagination .nav_prev a, .pagination .nav_prev a,
.pagination .nav_next a { .pagination .nav_next a {

View File

@ -1,187 +0,0 @@
/* CSS Document */
/* Design & CSS by Marie-Claude Doyon http://www.marieclaudedoyon.com */
@import url(../default/display.css);
html {
background: url(bg-body.gif) repeat-y top center #d8e2d7;
}
body {
color: #193441;
}
a {
color: #C15D42;
}
#wrap {
background: url(bg-header.gif) repeat-x #FCFFF5;
}
#header h1.pagetitle {
color: #d8e2d7;
}
#header h2.sitename {
color: #FCFFF5;
}
#nav li a {
color: #91AA9D;
}
#nav_views li a {
color: #FCFFF5;
background-color: #91AA9D;
border-right: 1px solid #6A8787;
}
#nav_views li.current a, #nav_views li.current a:hover {
color: #3F606F;
background-color: #FCFFF5;
border-right: 1px solid #6A8787;
}
#nav_views li.current a:hover {
color: #193441;
}
#nav_views li a:hover {
color: #FCFFF5;
background-color: #3F606F;
border-right: 1px solid #6A8787;
}
#nav_sub {
border-top: 1px solid #D8E2D7;
}
.instructions p, .success, .error {
border: 1px solid #91AA9D;
color: #FCFFF5;
}
.instructions a:hover, .success a:hover, .error a:hover {
color: #FCFFF5;
}
#notices {
border-top: 1px solid #D8E2D7;
}
.notice_single {
border-bottom: 1px solid #D8E2D7;
}
.notice_single:hover {
background-color: #F3F8EA;
}
input#submit_yes, input#submit_no {
color: #FCFFF5;
background-color: #C15D42;
}
input#submit_yes:hover, input#submit_no:hover {
background-color: #904632;
}
p.time a {
color: #91AA9D;
}
#profile {
border-top: 1px solid #D8E2D7;
}
#profile h2 {
color: #91AA9D;
}
#nav_pagination li {
background-color: #91AA9D;
}
#nav_pagination li a {
background-color: #91AA9D;
color: #FCFFF5;
}
#nav_pagination li a:hover {
color: #FCFFF5;
}
#footer {
border-top: 1px solid #D8E2D7;
}
form input {
border: 1px solid #D8E2D7;
}
input#submit, input.submit {
color: #FCFFF5;
background-color: #C15D42;
}
input#submit:hover, input.submit:hover {
background-color: #904632;
}
textarea, input {
color: #193441;
}
textarea:focus, input:focus {
background-color: #f0f6eb;
}
.input_instructions {
color: #91aa9d;
}
#status_label {
color: #91AA9D;
}
#status_textarea {
color: #193441;
}
#status_submit {
background-color: #C15D42;
color: #FCFFF5;
}
#status_submit:hover {
background-color: #904632;
}
#content .subscribe .submit, #content .unsubscribe .submit, #remotesubscribe .button, #remotesubscribe {
background-color: #c15d42;
color: #fcfff5;
}
#profiles {
border-top: 1px solid #D8E2D7;
}
.profile_single {
border-bottom: 1px solid #D8E2D7;
}
.profile_single:hover {
background-color: #F3F8EA;
}
#messages {
border-top: 1px solid #D8E2D7;
}
.message_single {
border-bottom: 1px solid #D8E2D7;
}
.message_single:hover {
background-color: #F3F8EA;
}

View File

@ -1,14 +0,0 @@
@charset "UTF-8";
/* CSS Document */
@import url(../default/ie6.css);
#wrap {
background: url(bg-header.gif) repeat-x #FCFFF5;
}
input.disfavor,
input.favor {
text-indent:0px;
text-align:right;
padding-left:25px;
}

View File

@ -1,3 +0,0 @@
@charset "UTF-8";
/* CSS Document */
@import url(../default/ie7.css);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 B