From 3a44885b7ffcdcbb1b5cc8e972a3f89dd02b4c74 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 22 May 2009 20:50:08 -0400 Subject: reformat designsettings.php --- actions/designsettings.php | 84 ++++++++-------------------------------------- 1 file changed, 14 insertions(+), 70 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 315e5a199..8d8e5bad8 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -33,8 +33,6 @@ if (!defined('LACONICA')) { require_once INSTALLDIR.'/lib/accountsettingsaction.php'; - - class DesignsettingsAction extends AccountSettingsAction { /** @@ -82,8 +80,8 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('legend', null, _('Change background image')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->element('label', array('for' => 'design_ background-image_file'), - _('Upload file')); + $this->element('label', array('for' => 'design_ background-image_file'), + _('Upload file')); $this->element('input', array('name' => 'design_background-image_file', 'type' => 'file', 'id' => 'design_background-image_file')); @@ -101,11 +99,11 @@ class DesignsettingsAction extends AccountSettingsAction $this->elementStart('ul', 'form_data'); //This is a JSON object in the DB field. Here for testing. Remove later. - $userSwatch = '{"body":{"background-color":"#F0F2F5"}, - "#content":{"background-color":"#FFFFFF"}, - "#aside_primary":{"background-color":"#CEE1E9"}, - "html body":{"color":"#000000"}, - "a":{"color":"#002E6E"}}'; + $userSwatch = '{"body":{"background-color":"#F0F2F5"},'. + '"#content":{"background-color":"#FFFFFF"},'. + '"#aside_primary":{"background-color":"#CEE1E9"},'. + '"html body":{"color":"#000000"},'. + '"a":{"color":"#002E6E"}}'; //Default theme swatch -- Where should this be stored? $defaultSwatch = array('body' => array('background-color' => '#F0F2F5'), @@ -147,14 +145,13 @@ class DesignsettingsAction extends AccountSettingsAction 'title' => _('Reset back to default'))); $this->submit('save', _('Save'), 'submit form_action-secondary', 'save', _('Save design')); -/*TODO: Check submitted form values: -json_encode(form values) -if submitted Swatch == DefaultSwatch, don't store in DB. -else store in BD -*/ + /*TODO: Check submitted form values: + json_encode(form values) + if submitted Swatch == DefaultSwatch, don't store in DB. + else store in BD + */ $this->elementEnd('fieldset'); $this->elementEnd('form'); - } /** @@ -168,63 +165,10 @@ else store in BD function handlePost() { - /* - // CSRF protection - - $token = $this->trimmed('token'); - if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. '. - 'Try again, please.')); - return; - } - - $user = common_current_user(); - assert(!is_null($user)); // should already be checked - - // FIXME: scrub input - - $newpassword = $this->arg('newpassword'); - $confirm = $this->arg('confirm'); - - # Some validation - - if (strlen($newpassword) < 6) { - $this->showForm(_('Password must be 6 or more characters.')); - return; - } else if (0 != strcmp($newpassword, $confirm)) { - $this->showForm(_('Passwords don\'t match.')); - return; - } - - if ($user->password) { - $oldpassword = $this->arg('oldpassword'); - - if (!common_check_user($user->nickname, $oldpassword)) { - $this->showForm(_('Incorrect old password')); - return; - } - } - - $original = clone($user); - - $user->password = common_munge_password($newpassword, $user->id); - - $val = $user->validate(); - if ($val !== true) { - $this->showForm(_('Error saving user; invalid.')); - return; - } - - if (!$user->update($original)) { - $this->serverError(_('Can\'t save new password.')); - return; - } - - $this->showForm(_('Password saved.'), true); - */ + // TODO: implement this + return; } - /** * Add the Farbtastic stylesheet * -- cgit v1.2.3-54-g00ecf From 9c2f04afc6e70032da5aeb0441e6e0a9b0ffe253 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 23 May 2009 23:35:04 -0400 Subject: make some of the actions show the user's design --- actions/replies.php | 3 +-- actions/showfavorites.php | 5 +---- actions/usergroups.php | 3 +-- lib/galleryaction.php | 3 +-- lib/profileaction.php | 3 +-- 5 files changed, 5 insertions(+), 12 deletions(-) (limited to 'actions') diff --git a/actions/replies.php b/actions/replies.php index dfb520d64..5d84f6428 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -45,9 +45,8 @@ require_once INSTALLDIR.'/lib/feedlist.php'; * @link http://laconi.ca/ */ -class RepliesAction extends Action +class RepliesAction extends OwnerDesignAction { - var $user = null; var $page = null; /** diff --git a/actions/showfavorites.php b/actions/showfavorites.php index eed62a2ab..839f083dd 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -45,10 +45,8 @@ require_once INSTALLDIR.'/lib/feedlist.php'; * @link http://laconi.ca/ */ -class ShowfavoritesAction extends Action +class ShowfavoritesAction extends OwnerDesignAction { - /** User we're getting the faves of */ - var $user = null; /** Page of the faves we're on */ var $page = null; @@ -161,7 +159,6 @@ class ShowfavoritesAction extends Action $this->page, 'showfavorites', array('nickname' => $this->user->nickname)); } - /** * show the personal group nav * diff --git a/actions/usergroups.php b/actions/usergroups.php index e3088dcbd..7ead6e6e4 100644 --- a/actions/usergroups.php +++ b/actions/usergroups.php @@ -46,9 +46,8 @@ require_once INSTALLDIR.'/lib/grouplist.php'; * @link http://laconi.ca/ */ -class UsergroupsAction extends Action +class UsergroupsAction extends OwnerDesignAction { - var $user = null; var $page = null; var $profile = null; diff --git a/lib/galleryaction.php b/lib/galleryaction.php index 8fa11a756..498c82851 100644 --- a/lib/galleryaction.php +++ b/lib/galleryaction.php @@ -27,10 +27,9 @@ require_once INSTALLDIR.'/lib/profilelist.php'; define('AVATARS_PER_PAGE', 80); -class GalleryAction extends Action +class GalleryAction extends OwnerDesignAction { var $profile = null; - var $user = null; var $page = null; var $tag = null; diff --git a/lib/profileaction.php b/lib/profileaction.php index a3437ff4d..a14d3846e 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -47,9 +47,8 @@ require_once INSTALLDIR.'/lib/groupminilist.php'; * @link http://laconi.ca/ */ -class ProfileAction extends Action +class ProfileAction extends OwnerDesignAction { - var $user = null; var $page = null; var $profile = null; var $tag = null; -- cgit v1.2.3-54-g00ecf From 6335c9cf59b384da24506c4a3f799315fbbc4b09 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 23 May 2009 23:42:19 -0400 Subject: make invite use the current user's design --- actions/invite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actions') diff --git a/actions/invite.php b/actions/invite.php index 7e52cdbcc..c793f5824 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -19,7 +19,7 @@ if (!defined('LACONICA')) { exit(1); } -class InviteAction extends Action +class InviteAction extends CurrentUserDesignAction { var $mode = null; var $error = null; -- cgit v1.2.3-54-g00ecf From b3628b78448266fda2368f1317e70d1cca45ac17 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 27 May 2009 14:49:20 -0400 Subject: start using design object --- actions/designsettings.php | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 8d8e5bad8..da8894042 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -98,28 +98,18 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('legend', null, _('Change colours')); $this->elementStart('ul', 'form_data'); - //This is a JSON object in the DB field. Here for testing. Remove later. - $userSwatch = '{"body":{"background-color":"#F0F2F5"},'. - '"#content":{"background-color":"#FFFFFF"},'. - '"#aside_primary":{"background-color":"#CEE1E9"},'. - '"html body":{"color":"#000000"},'. - '"a":{"color":"#002E6E"}}'; - - //Default theme swatch -- Where should this be stored? - $defaultSwatch = array('body' => array('background-color' => '#F0F2F5'), - '#content' => array('background-color' => '#FFFFFF'), - '#aside_primary' => array('background-color' => '#CEE1E9'), - 'html body' => array('color' => '#000000'), - 'a' => array('color' => '#002E6E')); - - $userSwatch = ($userSwatch) ? json_decode($userSwatch, true) : $defaultSwatch; - - $s = 0; + $design = $user->getDesign(); + + if (empty($design)) { + $design = $this->defaultDesign(); + } + $labelSwatch = array('Background', 'Content', 'Sidebar', 'Text', 'Links'); + foreach($userSwatch as $propertyvalue => $value) { $foo = array_values($value); $this->elementStart('li'); @@ -150,6 +140,7 @@ class DesignsettingsAction extends AccountSettingsAction if submitted Swatch == DefaultSwatch, don't store in DB. else store in BD */ + $this->elementEnd('fieldset'); $this->elementEnd('form'); } -- cgit v1.2.3-54-g00ecf From 946d016df2a5e0af5e1b4b983b30c113dd02b4ea Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Sun, 14 Jun 2009 02:03:50 -0700 Subject: Reworked output for design settings page --- actions/designsettings.php | 164 +++++++++++++++++++++++++++++++++++---------- lib/common.php | 7 ++ 2 files changed, 136 insertions(+), 35 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 66476e677..8595cbc4c 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -22,6 +22,7 @@ * @category Settings * @package Laconica * @author Sarven Capadisli + * @author Zach Copley * @copyright 2008-2009 Control Yourself, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://laconi.ca/ @@ -104,42 +105,73 @@ class DesignsettingsAction extends AccountSettingsAction $design = $this->defaultDesign(); } - $labelSwatch = array('Background', - 'Content', - 'Sidebar', - 'Text', - 'Links'); - - foreach($userSwatch as $propertyvalue => $value) { - $foo = array_values($value); - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-'.$s), _($labelSwatch[$s])); - $this->element('input', array('name' => 'swatch-'.$s, //prefer swatch[$s] ? - 'type' => 'text', - 'id' => 'swatch-'.$s, - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => $foo[0])); - $this->elementEnd('li'); - $s++; - } + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-5'), _('Background')); + $this->element('input', array('name' => 'design_background', + 'type' => 'text', + 'id' => 'swatch-5', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => $design->backgroundcolor)); + $this->elementEnd('li'); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-1'), _('Content')); + $this->element('input', array('name' => 'design_content', + 'type' => 'text', + 'id' => 'swatch-1', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => $design->contentcolor)); + $this->elementEnd('li'); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-2'), _('Sidebar')); + $this->element('input', array('name' => 'design_sidebar', + 'type' => 'text', + 'id' => 'swatch-2', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => $design->sidebarcolor)); + $this->elementEnd('li'); - $this->elementEnd('ul'); - $this->elementEnd('fieldset'); + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-3'), _('Text')); + $this->element('input', array('name' => 'design_text', + 'type' => 'text', + 'id' => 'swatch-3', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => $design->textcolor)); + $this->elementEnd('li'); - $this->element('input', array('id' => 'settings_design_reset', - 'type' => 'reset', - 'value' => 'Reset', - 'class' => 'submit form_action-primary', - 'title' => _('Reset back to default'))); - $this->submit('save', _('Save'), 'submit form_action-secondary', 'save', _('Save design')); + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-4'), _('Links')); + $this->element('input', array('name' => 'design_links', + 'type' => 'text', + 'id' => 'swatch-4', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => $design->linkcolor)); - /*TODO: Check submitted form values: - json_encode(form values) - if submitted Swatch == DefaultSwatch, don't store in DB. - else store in BD - */ + $this->elementEnd('li'); + + $this->elementEnd('ul'); + $this->elementEnd('fieldset'); + + $this->element('input', array('id' => 'settings_design_reset', + 'type' => 'reset', + 'value' => 'Reset', + 'class' => 'submit form_action-primary', + 'title' => _('Reset back to default'))); + + $this->submit('save', _('Save'), 'submit form_action-secondary', + 'save', _('Save design')); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -156,8 +188,21 @@ class DesignsettingsAction extends AccountSettingsAction function handlePost() { - // TODO: implement this - return; + // CSRF protection + $token = $this->trimmed('token'); + if (!$token || $token != common_session_token()) { + $this->showForm(_('There was a problem with your session token. '. + 'Try again, please.')); + return; + } + + if ($this->arg('save')) { + $this->saveDesign(); + } else if ($this->arg('reset')) { + $this->resetDesign(); + } else { + $this->showForm(_('Unexpected form submission.')); + } } /** @@ -196,4 +241,53 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('script', array('type' => 'text/javascript', 'src' => $farbtasticGo)); } + + /** + * Get a default user design + * + * @return Design design + */ + + function defaultDesign() + { + $defaults = common_config('site', 'design'); + + $design = new Design(); + $design->backgroundcolor = $defaults['backgroundcolor']; + $design->contentcolor = $defaults['contentcolor']; + $design->sidebarcolor = $defaults['sidebarcolor']; + $design->textcolor = $defaults['textcolor']; + $design->linkcolor = $defaults['linkcolor']; + $design->backgroundimage = $defaults['backgroundimage']; + + return $design; + } + + /** + * Save the user's design settings + * + * @return void + */ + + function saveDesign() + { + $user = common_current_user(); + + + + $this->showForm(_('Design preferences saved.'), true); + } + + /** + * Reset design settings to previous saved value if any, or + * the defaults + * + * @return void + */ + + function resetDesign() + { + $this->showForm(_('Design preferences reset.'), true); + } + } diff --git a/lib/common.php b/lib/common.php index 5aafdfe0e..a55fb264e 100644 --- a/lib/common.php +++ b/lib/common.php @@ -72,6 +72,13 @@ $config = 'server' => $_server, 'theme' => 'default', 'skin' => 'default', + 'design' => + array('backgroundcolor' => '#F0F2F5', + 'contentcolor' => '#FFFFFF', + 'sidebarcolor' => '#CEE1E9', + 'textcolor' => '#000000', + 'linkcolor' => '#002E6E', + 'backgroundimage' => null), 'path' => $_path, 'logfile' => null, 'logo' => null, -- cgit v1.2.3-54-g00ecf From c2dae24701a22cd2362ebe1a96828cd7945c6b5a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 14:52:26 -0700 Subject: Break profilelist into a recipe Expanded the ProfileList class so it worked more like a recipe. This helps to get rid of a lot of special cases and simplifies the code. It also makes it possible to do things like group block. --- actions/groupmembers.php | 14 +++- actions/showgroup.php | 2 +- actions/subscribers.php | 32 ++++++--- actions/subscriptions.php | 34 ++++++++-- lib/peoplesearchresults.php | 15 +++-- lib/profileaction.php | 4 +- lib/profilelist.php | 154 +++++++++++++++++++++++++------------------- lib/profileminilist.php | 23 ++----- 8 files changed, 172 insertions(+), 106 deletions(-) (limited to 'actions') diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 21e5ebbaa..53fee3129 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -127,7 +127,7 @@ class GroupmembersAction extends Action $members = $this->group->getMembers($offset, $limit); if ($members) { - $member_list = new ProfileList($members, null, $this); + $member_list = new GroupMemberList($members, $this->group, $this); $cnt = $member_list->show(); } @@ -138,3 +138,15 @@ class GroupmembersAction extends Action array('nickname' => $this->group->nickname)); } } + +class GroupMemberList extends ProfileList { + + var $group = null; + + function __construct($profile, $group=null, $action=null) + { + parent::__construct($profile, $action); + + $this->group = $group; + } +} diff --git a/actions/showgroup.php b/actions/showgroup.php index 29b6fa1e6..3ce45adc6 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -344,7 +344,7 @@ class ShowgroupAction extends Action $this->element('h2', null, _('Members')); - $pml = new ProfileMiniList($member, null, $this); + $pml = new ProfileMiniList($member, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); diff --git a/actions/subscribers.php b/actions/subscribers.php index 4482de9a7..66ac00fb1 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -130,18 +130,34 @@ class SubscribersAction extends GalleryAction } } -class SubscribersList extends ProfileList +class SubscribersList extends SubscriptionList { - function showBlockForm() + function newListItem($profile) { - $bf = new BlockForm($this->out, $this->profile, - array('action' => 'subscribers', - 'nickname' => $this->owner->nickname)); - $bf->show(); + return new SubscribersListItem($profile, $this->owner, $this->action); } +} - function isReadOnly($args) +class SubscribersListItem extends SubscriptionListItem +{ + function showActions() { - return true; + $this->startActions(); + $this->showSubscribeButton(); + // Relevant code! + $this->showBlockForm(); + $this->endActions(); + } + + function showBlockForm() + { + $user = common_current_user(); + + if (!empty($user) && $this->owner->id == $user->id) { + $bf = new BlockForm($this->out, $this->profile, + array('action' => 'subscribers', + 'nickname' => $this->owner->nickname)); + $bf->show(); + } } } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index 095b18ad8..4124abea4 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -137,22 +137,46 @@ class SubscriptionsAction extends GalleryAction } } -class SubscriptionsList extends ProfileList +// XXX SubscriptionsList and SubscriptionList are dangerously close + +class SubscriptionsList extends SubscriptionList { - function showOwnerControls($profile) + function newListItem($profile) + { + return new SubscriptionsListItem($profile, $this->owner, $this->action); + } +} + +class SubscriptionsListItem extends SubscriptionListItem +{ + function showProfile() + { + $this->startProfile(); + $this->showAvatar(); + $this->showFullName(); + $this->showLocation(); + $this->showHomepage(); + $this->showBio(); + $this->showTags(); + // Relevant portion! + $this->showOwnerControls(); + $this->endProfile(); + } + + function showOwnerControls() { $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, - 'subscribed' => $profile->id)); + 'subscribed' => $this->profile->id)); if (!$sub) { return; } - $this->out->elementStart('form', array('id' => 'subedit-' . $profile->id, + $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id, 'method' => 'post', 'class' => 'form_subscription_edit', 'action' => common_local_url('subedit'))); $this->out->hidden('token', common_session_token()); - $this->out->hidden('profile', $profile->id); + $this->out->hidden('profile', $this->profile->id); $this->out->checkbox('jabber', _('Jabber'), $sub->jabber); $this->out->checkbox('sms', _('SMS'), $sub->sms); $this->out->submit('save', _('Save')); diff --git a/lib/peoplesearchresults.php b/lib/peoplesearchresults.php index d3f840852..9d9d17299 100644 --- a/lib/peoplesearchresults.php +++ b/lib/peoplesearchresults.php @@ -56,20 +56,25 @@ class PeopleSearchResults extends ProfileList function __construct($profile, $terms, $action) { - parent::__construct($profile, $terms, $action); + parent::__construct($profile, $action); + $this->terms = array_map('preg_quote', array_map('htmlspecialchars', $terms)); + $this->pattern = '/('.implode('|',$terms).')/i'; } - function highlight($text) + function newProfileItem($profile) { - return preg_replace($this->pattern, '\\1', htmlspecialchars($text)); + return new PeopleSearchResultItem($profile, $this->action); } +} - function isReadOnly($args) +class PeopleSearchResultItem extends ProfileListItem +{ + function highlight($text) { - return true; + return preg_replace($this->pattern, '\\1', htmlspecialchars($text)); } } diff --git a/lib/profileaction.php b/lib/profileaction.php index a3437ff4d..298f34b22 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -110,7 +110,7 @@ class ProfileAction extends Action $this->element('h2', null, _('Subscriptions')); if ($profile) { - $pml = new ProfileMiniList($profile, $this->user, $this); + $pml = new ProfileMiniList($profile, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); @@ -139,7 +139,7 @@ class ProfileAction extends Action $this->element('h2', null, _('Subscribers')); if ($profile) { - $pml = new ProfileMiniList($profile, $this->user, $this); + $pml = new ProfileMiniList($profile, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); diff --git a/lib/profilelist.php b/lib/profilelist.php index a4cc23555..e2faf10af 100644 --- a/lib/profilelist.php +++ b/lib/profilelist.php @@ -49,23 +49,19 @@ class ProfileList extends Widget { /** Current profile, profile query. */ var $profile = null; - /** Owner of this list */ - var $owner = null; /** Action object using us. */ var $action = null; - function __construct($profile, $owner=null, $action=null) + function __construct($profile, $action=null) { parent::__construct($action); $this->profile = $profile; - $this->owner = $owner; $this->action = $action; } function show() { - $this->out->elementStart('ul', 'profiles'); $cnt = 0; @@ -75,7 +71,8 @@ class ProfileList extends Widget if($cnt > PROFILES_PER_PAGE) { break; } - $this->showProfile(); + $pli = $this->newListItem($this->profile); + $pli->show(); } $this->out->elementEnd('ul'); @@ -83,16 +80,59 @@ class ProfileList extends Widget return $cnt; } - function showProfile() + function newListItem($profile) + { + return new ProfileListItem($this->profile, $this->action); + } +} + +class ProfileListItem extends Widget +{ + /** Current profile. */ + var $profile = null; + /** Action object using us. */ + var $action = null; + + function __construct($profile, $action) + { + parent::__construct($action); + + $this->profile = $profile; + $this->action = $action; + } + + function show() + { + $this->startItem(); + $this->showProfile(); + $this->showActions(); + $this->endItem(); + } + + function startItem() { $this->out->elementStart('li', array('class' => 'profile', 'id' => 'profile-' . $this->profile->id)); + } - $user = common_current_user(); - $is_own = !is_null($user) && isset($this->owner) && ($user->id === $this->owner->id); + function showProfile() + { + $this->startProfile(); + $this->showAvatar(); + $this->showFullName(); + $this->showLocation(); + $this->showHomepage(); + $this->showBio(); + $this->endProfile(); + } + function startProfile() + { $this->out->elementStart('div', 'entity_profile vcard'); + } + function showAvatar() + { $avatar = $this->profile->getAvatar(AVATAR_STREAM_SIZE); $this->out->elementStart('a', array('href' => $this->profile->profileurl, 'class' => 'url')); @@ -108,7 +148,10 @@ class ProfileList extends Widget $this->out->raw($this->highlight($this->profile->nickname)); $this->out->elementEnd('span'); $this->out->elementEnd('a'); + } + function showFullName() + { if (!empty($this->profile->fullname)) { $this->out->elementStart('dl', 'entity_fn'); $this->out->element('dt', null, 'Full name'); @@ -119,6 +162,10 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } + + function showLocation() + { if (!empty($this->profile->location)) { $this->out->elementStart('dl', 'entity_location'); $this->out->element('dt', null, _('Location')); @@ -127,6 +174,10 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } + + function showHomepage() + { if (!empty($this->profile->homepage)) { $this->out->elementStart('dl', 'entity_url'); $this->out->element('dt', null, _('URL')); @@ -138,6 +189,10 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } + + function showBio() + { if (!empty($this->profile->bio)) { $this->out->elementStart('dl', 'entity_note'); $this->out->element('dt', null, _('Note')); @@ -146,57 +201,33 @@ class ProfileList extends Widget $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } + } - # If we're on a list with an owner (subscriptions or subscribers)... - - if ($this->owner) { - # Get tags - $tags = Profile_tag::getTags($this->owner->id, $this->profile->id); - - $this->out->elementStart('dl', 'entity_tags'); - $this->out->elementStart('dt'); - if ($is_own) { - $this->out->element('a', array('href' => common_local_url('tagother', - array('id' => $this->profile->id))), - _('Tags')); - } else { - $this->out->text(_('Tags')); - } - $this->out->elementEnd('dt'); - $this->out->elementStart('dd'); - if ($tags) { - $this->out->elementStart('ul', 'tags xoxo'); - foreach ($tags as $tag) { - $this->out->elementStart('li'); - $this->out->element('span', 'mark_hash', '#'); - $this->out->element('a', array('rel' => 'tag', - 'href' => common_local_url($this->action->trimmed('action'), - array('nickname' => $this->owner->nickname, - 'tag' => $tag))), - $tag); - $this->out->elementEnd('li'); - } - $this->out->elementEnd('ul'); - } else { - $this->out->text(_('(none)')); - } - $this->out->elementEnd('dd'); - $this->out->elementEnd('dl'); - } - - if ($is_own) { - $this->showOwnerControls($this->profile); - } - + function endProfile() + { $this->out->elementEnd('div'); + } - $this->out->elementStart('div', 'entity_actions'); + function showActions() + { + $this->startActions(); + $this->showSubscribeButton(); + $this->endActions(); + } + function startActions() + { + $this->out->elementStart('div', 'entity_actions'); $this->out->elementStart('ul'); + } + function showSubscribeButton() + { // Is this a logged-in user, looking at someone else's // profile? + $user = common_current_user(); + if (!empty($user) && $this->profile->id != $user->id) { $this->out->elementStart('li', 'entity_subscribe'); if ($user->isSubscribed($this->profile)) { @@ -207,33 +238,22 @@ class ProfileList extends Widget $sf->show(); } $this->out->elementEnd('li'); - $this->out->elementStart('li', 'entity_block'); - if ($user->id == $this->owner->id) { - $this->showBlockForm(); - } - $this->out->elementEnd('li'); } + } + function endActions() + { $this->out->elementEnd('ul'); - $this->out->elementEnd('div'); - - $this->out->elementEnd('li'); } - /* Override this in subclasses. */ - - function showOwnerControls($profile) + function endItem() { - return; + $this->out->elementEnd('li'); } function highlight($text) { return htmlspecialchars($text); } - - function showBlockForm() - { - } } diff --git a/lib/profileminilist.php b/lib/profileminilist.php index 57496d0e9..f11cae8a5 100644 --- a/lib/profileminilist.php +++ b/lib/profileminilist.php @@ -47,26 +47,15 @@ define('PROFILES_PER_MINILIST', 27); class ProfileMiniList extends ProfileList { - function show() + function newListItem($profile) { - $this->out->elementStart('ul', 'entities users xoxo'); - - $cnt = 0; - - while ($this->profile->fetch()) { - $cnt++; - if($cnt > PROFILES_PER_MINILIST) { - break; - } - $this->showProfile(); - } - - $this->out->elementEnd('ul'); - - return $cnt; + return new ProfileMiniListItem($profile, $this->action); } +} - function showProfile() +class ProfileMiniListItem extends ProfileListItem +{ + function show() { $this->out->elementStart('li', 'vcard'); $this->out->elementStart('a', array('title' => $this->profile->getBestName(), -- cgit v1.2.3-54-g00ecf From b6dee88e5d0a0ed58391ccb8868f4afbf631342a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 15:08:00 -0700 Subject: add UI for blocking a user from a group --- actions/groupmembers.php | 170 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 2 deletions(-) (limited to 'actions') diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 53fee3129..079dad9e9 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -139,14 +139,180 @@ class GroupmembersAction extends Action } } -class GroupMemberList extends ProfileList { +class GroupMemberList extends ProfileList +{ + var $group = null; + + function __construct($profile, $group, $action) + { + parent::__construct($profile, $action); + + $this->group = $group; + } + + function newListItem($profile) + { + return new GroupMemberListItem($profile, $this->group, $this->action); + } +} +class GroupMemberListItem extends ProfileListItem +{ var $group = null; - function __construct($profile, $group=null, $action=null) + function __construct($profile, $group, $action) { parent::__construct($profile, $action); $this->group = $group; } + + function showActions() + { + $this->startActions(); + $this->showSubscribeButton(); + $this->showGroupBlockForm(); + $this->endActions(); + } + + function showGroupBlockForm() + { + $user = common_current_user(); + + if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) { + $bf = new GroupBlockForm($this->out, $this->profile, + array('action' => 'groupmembers', + 'nickname' => $this->group->nickname)); + $bf->show(); + } + + } +} + +/** + * Form for blocking a user from a group + * + * @category Form + * @package Laconica + * @author Evan Prodromou + * @author Sarven Capadisli + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see BlockForm + */ + +class GroupBlockForm extends Form +{ + /** + * Profile of user to block + */ + + var $profile = null; + + /** + * Group to block the user from + */ + + var $group = null; + + /** + * Return-to args + */ + + var $args = null; + + /** + * Constructor + * + * @param HTMLOutputter $out output channel + * @param Profile $profile profile of user to block + * @param User_group $group group to block user from + * @param array $args return-to args + */ + + function __construct($out=null, $profile=null, $group=null, $args=null) + { + parent::__construct($out); + + $this->profile = $profile; + $this->group = $group; + $this->args = $args; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + + function id() + { + // This should be unique for the page. + return 'block-' . $this->profile->id; + } + + /** + * class of the form + * + * @return string class of the form + */ + + function formClass() + { + return 'form_group_block'; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + + function action() + { + return common_local_url('groupblock'); + } + + /** + * Legend of the Form + * + * @return void + */ + function formLegend() + { + $this->out->element('legend', null, _('Block user from group')); + } + + /** + * Data elements of the form + * + * @return void + */ + + function formData() + { + $this->out->hidden('blockto-' . $this->profile->id, + $this->profile->id, + 'blockto'); + $this->out->hidden('blockgroup-' . $this->group->id, + $this->group->id, + 'blockgroup'); + if ($this->args) { + foreach ($this->args as $k => $v) { + $this->out->hidden('returnto-' . $k, $v); + } + } + } + + /** + * Action elements + * + * @return void + */ + + function formActions() + { + $this->out->submit('submit', _('Block'), 'submit', null, _('Block this user')); + } } -- cgit v1.2.3-54-g00ecf From d3a0c524cce9be65b8e45280168cf3584a60f81c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 15:40:42 -0700 Subject: Make group block work --- actions/groupblock.php | 215 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 actions/groupblock.php (limited to 'actions') diff --git a/actions/groupblock.php b/actions/groupblock.php new file mode 100644 index 000000000..93662da79 --- /dev/null +++ b/actions/groupblock.php @@ -0,0 +1,215 @@ + + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://laconi.ca/ + * + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Block a user from a group + * + * @category Action + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://laconi.ca/ + */ + +class GroupblockAction extends Action +{ + var $profile = null; + var $group = null; + + /** + * Take arguments for running + * + * @param array $args $_REQUEST args + * + * @return boolean success flag + */ + + function prepare($args) + { + parent::prepare($args); + if (!common_logged_in()) { + $this->clientError(_('Not logged in.')); + return false; + } + $token = $this->trimmed('token'); + if (empty($token) || $token != common_session_token()) { + $this->clientError(_('There was a problem with your session token. Try again, please.')); + return; + } + $id = $this->trimmed('blockto'); + if (empty($id)) { + $this->clientError(_('No profile specified.')); + return false; + } + $this->profile = Profile::staticGet('id', $id); + if (empty($this->profile)) { + $this->clientError(_('No profile with that ID.')); + return false; + } + $group_id = $this->trimmed('blockgroup'); + if (empty($group_id)) { + $this->clientError(_('No group specified.')); + return false; + } + $this->group = User_group::staticGet('id', $group_id); + if (empty($this->group)) { + $this->clientError(_('No such group.')); + return false; + } + $user = common_current_user(); + if (!$user->isAdmin($this->group)) { + $this->clientError(_('Only an admin can block group members.'), 401); + return false; + } + if (Group_block::isBlocked($this->group, $this->profile)) { + $this->clientError(_('User is already blocked from group.')); + return false; + } + // XXX: could have proactive blocks, but we don't have UI for it. + if (!$this->profile->isMember($this->group)) { + $this->clientError(_('User is not a member of group.')); + return false; + } + return true; + } + + /** + * Handle request + * + * Shows a page with list of favorite notices + * + * @param array $args $_REQUEST args; handled in prepare() + * + * @return void + */ + function handle($args) + { + parent::handle($args); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + if ($this->arg('no')) { + common_redirect(common_local_url('groupmembers', + array('nickname' => $this->group->nickname)), + 303); + } elseif ($this->arg('yes')) { + $this->blockProfile(); + } elseif ($this->arg('blockto')) { + $this->showPage(); + } + } + } + + function showContent() { + $this->areYouSureForm(); + } + + function title() { + return _('Block user from group'); + } + + function showNoticeForm() { + // nop + } + + /** + * Confirm with user. + * + * Shows a confirmation form. + * + * @return void + */ + + function areYouSureForm() + { + $id = $this->profile->id; + $this->element('p', null, + sprintf(_('Are you sure you want to block user "%s" from the group "%s"? '. + 'They will be removed from the group, unable to post, and '. + 'unable to subscribe to the group in the future.'), + $this->profile->getBestName(), + $this->group->getBestName())); + $this->elementStart('form', array('id' => 'block-' . $id, + 'method' => 'post', + 'class' => 'block', + 'action' => common_local_url('groupblock'))); + $this->hidden('token', common_session_token()); + $this->hidden('blockto-' . $this->profile->id, + $this->profile->id, + 'blockto'); + $this->hidden('blockgroup-' . $this->group->id, + $this->group->id, + 'blockgroup'); + foreach ($this->args as $k => $v) { + if (substr($k, 0, 9) == 'returnto-') { + $this->hidden($k, $v); + } + } + $this->submit('no', _('No')); + $this->submit('yes', _('Yes')); + $this->elementEnd('form'); + } + + /** + * Actually block a user. + * + * @return void + */ + + function blockProfile() + { + $block = Group_block::blockProfile($this->group, $this->profile, + common_current_user()); + + if (empty($block)) { + $this->serverError(_("Database error blocking user from group.")); + return false; + } + + // Now, gotta figure where we go back to + foreach ($this->args as $k => $v) { + if ($k == 'returnto-action') { + $action = $v; + } elseif (substr($k, 0, 9) == 'returnto-') { + $args[substr($k, 9)] = $v; + } + } + + if ($action) { + common_redirect(common_local_url($action, $args), 303); + } else { + common_redirect(common_local_url('groupmembers', + array('nickname' => $this->group->nickname)), + 303); + } + } +} + -- cgit v1.2.3-54-g00ecf From 1c87532912b63effc047da2913e55a6551d8f629 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 15:47:39 -0700 Subject: The rest of the things necessary to make group block work Link to the group block form. Hide join button if the current user is blocked. --- actions/groupmembers.php | 2 +- actions/joingroup.php | 5 ++++ actions/showgroup.php | 2 +- classes/Group_block.php | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- classes/User_group.php | 5 ++++ lib/grouplist.php | 2 +- lib/router.php | 8 ++--- 7 files changed, 91 insertions(+), 9 deletions(-) (limited to 'actions') diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 079dad9e9..150b60a54 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -180,7 +180,7 @@ class GroupMemberListItem extends ProfileListItem $user = common_current_user(); if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) { - $bf = new GroupBlockForm($this->out, $this->profile, + $bf = new GroupBlockForm($this->out, $this->profile, $this->group, array('action' => 'groupmembers', 'nickname' => $this->group->nickname)); $bf->show(); diff --git a/actions/joingroup.php b/actions/joingroup.php index a5d82ddc7..0e4f96eaf 100644 --- a/actions/joingroup.php +++ b/actions/joingroup.php @@ -96,6 +96,11 @@ class JoingroupAction extends Action return false; } + if (Group_block::isBlocked($this->group, $cur->getProfile())) { + $this->clientError(_('You have been blocked from that group by the admin.'), 403); + return false; + } + return true; } diff --git a/actions/showgroup.php b/actions/showgroup.php index 3ce45adc6..537f09278 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -283,7 +283,7 @@ class ShowgroupAction extends Action if ($cur->isMember($this->group)) { $lf = new LeaveForm($this, $this->group); $lf->show(); - } else { + } else if (!Group_block::isBlocked($this->group, $cur->getProfile())) { $jf = new JoinForm($this, $this->group); $jf->show(); } diff --git a/classes/Group_block.php b/classes/Group_block.php index 437046a9c..d945fd57a 100644 --- a/classes/Group_block.php +++ b/classes/Group_block.php @@ -1,10 +1,29 @@ . */ -require_once 'classes/Memcached_DataObject'; -class Group_block extends Memcached_DataObject +if (!defined('LACONICA')) { exit(1); } + +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class Group_block extends Memcached_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -20,4 +39,57 @@ class Group_block extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + + function &pkeyGet($kv) + { + return Memcached_DataObject::pkeyGet('Group_block', $kv); + } + + static function isBlocked($group, $profile) + { + $block = Group_block::pkeyGet(array('group_id' => $group->id, + 'blocked' => $profile->id)); + return !empty($block); + } + + static function blockProfile($group, $profile, $blocker) + { + // Insert the block + + $block = new Group_block(); + + $block->query('BEGIN'); + + $block->group_id = $group->id; + $block->blocked = $profile->id; + $block->blocker = $blocker->id; + + $result = $block->insert(); + + if (!$result) { + common_log_db_error($block, 'INSERT', __FILE__); + return null; + } + + // Delete membership if any + + $member = new Group_member(); + + $member->group_id = $group->id; + $member->profile_id = $profile->id; + + if ($member->find(true)) { + $result = $member->delete(); + if (!$result) { + common_log_db_error($member, 'DELETE', __FILE__); + return null; + } + } + + // Commit, since both have been done + + $block->query('COMMIT'); + + return $block; + } } diff --git a/classes/User_group.php b/classes/User_group.php index a135015ba..1be34b60b 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -137,4 +137,9 @@ class User_group extends Memcached_DataObject common_debug(common_log_objstring($this)); return $this->update($orig); } + + function getBestName() + { + return ($this->fullname) ? $this->fullname : $this->nickname; + } } diff --git a/lib/grouplist.php b/lib/grouplist.php index 1b8547499..1ded5160b 100644 --- a/lib/grouplist.php +++ b/lib/grouplist.php @@ -166,7 +166,7 @@ class GroupList extends Widget if ($user->isMember($this->group)) { $lf = new LeaveForm($this->out, $this->group); $lf->show(); - } else { + } else if (!Group_block::isBlocked($this->group, $user->getProfile())) { $jf = new JoinForm($this->out, $this->group); $jf->show(); } diff --git a/lib/router.php b/lib/router.php index 456d1793e..469d9a171 100644 --- a/lib/router.php +++ b/lib/router.php @@ -101,7 +101,7 @@ class Router $main = array('login', 'logout', 'register', 'subscribe', 'unsubscribe', 'confirmaddress', 'recoverpassword', 'invite', 'favor', 'disfavor', 'sup', - 'block', 'subedit'); + 'block', 'subedit', 'groupblock'); foreach ($main as $a) { $m->connect('main/'.$a, array('action' => $a)); @@ -164,10 +164,10 @@ class Router array('action' => 'newnotice'), array('replyto' => '[A-Za-z0-9_-]+')); - $m->connect('notice/:notice/file', - array('action' => 'file'), + $m->connect('notice/:notice/file', + array('action' => 'file'), array('notice' => '[0-9]+')); - + $m->connect('notice/:notice', array('action' => 'shownotice'), array('notice' => '[0-9]+')); -- cgit v1.2.3-54-g00ecf From 203a5aba67c3bd9e2848d90b1778240b387aeda3 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 15:54:22 -0700 Subject: Some UI improvements for blocking and unblocking Add unblock to the router table, so unblocking will work at all. Block form and unblock form return to subscribers list, not subscriptions list, by default. showstream action sends its parameters to block and unblock forms to better return to the right page. --- actions/block.php | 2 +- actions/showstream.php | 8 ++++++-- actions/unblock.php | 2 +- lib/router.php | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) (limited to 'actions') diff --git a/actions/block.php b/actions/block.php index 34f991dc6..0efee5932 100644 --- a/actions/block.php +++ b/actions/block.php @@ -180,7 +180,7 @@ class BlockAction extends Action if ($action) { common_redirect(common_local_url($action, $args), 303); } else { - common_redirect(common_local_url('subscriptions', + common_redirect(common_local_url('subscribers', array('nickname' => $cur->nickname)), 303); } diff --git a/actions/showstream.php b/actions/showstream.php index c1a2c337a..641228bc7 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -308,10 +308,14 @@ class ShowstreamAction extends ProfileAction $blocked = $cur->hasBlocked($this->profile); $this->elementStart('li', 'entity_block'); if ($blocked) { - $ubf = new UnblockForm($this, $this->profile); + $ubf = new UnblockForm($this, $this->profile, + array('action' => 'showstream', + 'nickname' => $this->profile->nickname)); $ubf->show(); } else { - $bf = new BlockForm($this, $this->profile); + $bf = new BlockForm($this, $this->profile, + array('action' => 'showstream', + 'nickname' => $this->profile->nickname)); $bf->show(); } $this->elementEnd('li'); diff --git a/actions/unblock.php b/actions/unblock.php index 8573b2a87..6e671c9dd 100644 --- a/actions/unblock.php +++ b/actions/unblock.php @@ -118,7 +118,7 @@ class UnblockAction extends Action if ($action) { common_redirect(common_local_url($action, $args), 303); } else { - common_redirect(common_local_url('subscriptions', + common_redirect(common_local_url('subscribers', array('nickname' => $cur->nickname)), 303); } diff --git a/lib/router.php b/lib/router.php index 12590b790..748966567 100644 --- a/lib/router.php +++ b/lib/router.php @@ -101,7 +101,7 @@ class Router $main = array('login', 'logout', 'register', 'subscribe', 'unsubscribe', 'confirmaddress', 'recoverpassword', 'invite', 'favor', 'disfavor', 'sup', - 'block', 'subedit'); + 'block', 'unblock', 'subedit'); foreach ($main as $a) { $m->connect('main/'.$a, array('action' => $a)); -- cgit v1.2.3-54-g00ecf From f8da15bf41b07a46b1fbe5323e2b8136d42c5b31 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 16:17:44 -0700 Subject: Allow users to be unblocked from a group List users who are blocked from joining a group. Add a form to let them be unblocked. Add an action that removes the block. Includes changes to group and groupblock classes. --- actions/blockedfromgroup.php | 313 +++++++++++++++++++++++++++++++++++++++++++ actions/groupunblock.php | 149 ++++++++++++++++++++ classes/Group_block.php | 20 +++ classes/User_group.php | 23 ++++ lib/groupnav.php | 6 + lib/router.php | 7 +- 6 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 actions/blockedfromgroup.php create mode 100644 actions/groupunblock.php (limited to 'actions') diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php new file mode 100644 index 000000000..1b7b31784 --- /dev/null +++ b/actions/blockedfromgroup.php @@ -0,0 +1,313 @@ +. + * + * @category Group + * @package Laconica + * @author Evan Prodromou + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * List of profiles blocked from this group + * + * @category Group + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class BlockedfromgroupAction extends Action +{ + var $page = null; + + function isReadOnly($args) + { + return true; + } + + function prepare($args) + { + parent::prepare($args); + $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + + $nickname_arg = $this->arg('nickname'); + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + $args = array('nickname' => $nickname); + if ($this->page != 1) { + $args['page'] = $this->page; + } + common_redirect(common_local_url('blockedfromgroup', $args), 301); + return false; + } + + if (!$nickname) { + $this->clientError(_('No nickname'), 404); + return false; + } + + $this->group = User_group::staticGet('nickname', $nickname); + + if (!$this->group) { + $this->clientError(_('No such group'), 404); + return false; + } + + return true; + } + + function title() + { + if ($this->page == 1) { + return sprintf(_('%s blocked profiles'), + $this->group->nickname); + } else { + return sprintf(_('%s blocked profiles, page %d'), + $this->group->nickname, + $this->page); + } + } + + function handle($args) + { + parent::handle($args); + $this->showPage(); + } + + function showPageNotice() + { + $this->element('p', 'instructions', + _('A list of the users blocked from joining this group.')); + } + + function showLocalNav() + { + $nav = new GroupNav($this, $this->group); + $nav->show(); + } + + function showContent() + { + $offset = ($this->page-1) * PROFILES_PER_PAGE; + $limit = PROFILES_PER_PAGE + 1; + + $cnt = 0; + + $blocked = $this->group->getBlocked($offset, $limit); + + if ($blocked) { + $blocked_list = new GroupBlockList($blocked, $this->group, $this); + $cnt = $blocked_list->show(); + } + + $blocked->free(); + + $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE, + $this->page, 'blockedfromgroup', + array('nickname' => $this->group->nickname)); + } +} + +class GroupBlockList extends ProfileList +{ + var $group = null; + + function __construct($profile, $group, $action) + { + parent::__construct($profile, $action); + + $this->group = $group; + } + + function newListItem($profile) + { + return new GroupBlockListItem($profile, $this->group, $this->action); + } +} + +class GroupBlockListItem extends ProfileListItem +{ + var $group = null; + + function __construct($profile, $group, $action) + { + parent::__construct($profile, $action); + + $this->group = $group; + } + + function showActions() + { + $this->startActions(); + $this->showGroupUnblockForm(); + $this->endActions(); + } + + function showGroupUnblockForm() + { + $user = common_current_user(); + + if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) { + $bf = new GroupUnblockForm($this->out, $this->profile, $this->group, + array('action' => 'blockedfromgroup', + 'nickname' => $this->group->nickname)); + $bf->show(); + } + } +} + +/** + * Form for unblocking a user from a group + * + * @category Form + * @package Laconica + * @author Evan Prodromou + * @author Sarven Capadisli + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see UnblockForm + */ + +class GroupUnblockForm extends Form +{ + /** + * Profile of user to block + */ + + var $profile = null; + + /** + * Group to block the user from + */ + + var $group = null; + + /** + * Return-to args + */ + + var $args = null; + + /** + * Constructor + * + * @param HTMLOutputter $out output channel + * @param Profile $profile profile of user to block + * @param User_group $group group to block user from + * @param array $args return-to args + */ + + function __construct($out=null, $profile=null, $group=null, $args=null) + { + parent::__construct($out); + + $this->profile = $profile; + $this->group = $group; + $this->args = $args; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + + function id() + { + // This should be unique for the page. + return 'unblock-' . $this->profile->id; + } + + /** + * class of the form + * + * @return string class of the form + */ + + function formClass() + { + return 'form_group_unblock'; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + + function action() + { + return common_local_url('groupunblock'); + } + + /** + * Legend of the Form + * + * @return void + */ + function formLegend() + { + $this->out->element('legend', null, _('Unblock user from group')); + } + + /** + * Data elements of the form + * + * @return void + */ + + function formData() + { + $this->out->hidden('unblockto-' . $this->profile->id, + $this->profile->id, + 'unblockto'); + $this->out->hidden('unblockgroup-' . $this->group->id, + $this->group->id, + 'unblockgroup'); + if ($this->args) { + foreach ($this->args as $k => $v) { + $this->out->hidden('returnto-' . $k, $v); + } + } + } + + /** + * Action elements + * + * @return void + */ + + function formActions() + { + $this->out->submit('submit', _('Unblock'), 'submit', null, _('Unblock this user')); + } +} diff --git a/actions/groupunblock.php b/actions/groupunblock.php new file mode 100644 index 000000000..a0bcb01f9 --- /dev/null +++ b/actions/groupunblock.php @@ -0,0 +1,149 @@ + + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://laconi.ca/ + * + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Unlock a user from a group + * + * @category Action + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://laconi.ca/ + */ + +class GroupunblockAction extends Action +{ + var $profile = null; + var $group = null; + + /** + * Take arguments for running + * + * @param array $args $_REQUEST args + * + * @return boolean success flag + */ + + function prepare($args) + { + parent::prepare($args); + if (!common_logged_in()) { + $this->clientError(_('Not logged in.')); + return false; + } + $token = $this->trimmed('token'); + if (empty($token) || $token != common_session_token()) { + $this->clientError(_('There was a problem with your session token. Try again, please.')); + return; + } + $id = $this->trimmed('unblockto'); + if (empty($id)) { + $this->clientError(_('No profile specified.')); + return false; + } + $this->profile = Profile::staticGet('id', $id); + if (empty($this->profile)) { + $this->clientError(_('No profile with that ID.')); + return false; + } + $group_id = $this->trimmed('unblockgroup'); + if (empty($group_id)) { + $this->clientError(_('No group specified.')); + return false; + } + $this->group = User_group::staticGet('id', $group_id); + if (empty($this->group)) { + $this->clientError(_('No such group.')); + return false; + } + $user = common_current_user(); + if (!$user->isAdmin($this->group)) { + $this->clientError(_('Only an admin can unblock group members.'), 401); + return false; + } + if (!Group_block::isBlocked($this->group, $this->profile)) { + $this->clientError(_('User is not blocked from group.')); + return false; + } + return true; + } + + /** + * Handle request + * + * @param array $args $_REQUEST args; handled in prepare() + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $this->unblockProfile(); + } + } + + /** + * Unblock a user. + * + * @return void + */ + + function unblockProfile() + { + $result = Group_block::unblockProfile($this->group, $this->profile); + + if (!$result) { + $this->serverError(_('Error removing the block.')); + return; + } + + foreach ($this->args as $k => $v) { + if ($k == 'returnto-action') { + $action = $v; + } else if (substr($k, 0, 9) == 'returnto-') { + $args[substr($k, 9)] = $v; + } + } + + if ($action) { + common_redirect(common_local_url($action, $args), 303); + } else { + common_redirect(common_local_url('blockedfromgroup', + array('nickname' => $this->group->nickname)), + 303); + } + } +} + diff --git a/classes/Group_block.php b/classes/Group_block.php index d945fd57a..4c583d8e2 100644 --- a/classes/Group_block.php +++ b/classes/Group_block.php @@ -92,4 +92,24 @@ class Group_block extends Memcached_DataObject return $block; } + + static function unblockProfile($group, $profile) + { + $block = Group_block::pkeyGet(array('group_id' => $group->id, + 'blocked' => $profile->id)); + + if (empty($block)) { + return null; + } + + $result = $block->delete(); + + if (!$result) { + common_log_db_error($block, 'DELETE', __FILE__); + return null; + } + + return true; + } + } diff --git a/classes/User_group.php b/classes/User_group.php index 1be34b60b..9f9977755 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -125,6 +125,29 @@ class User_group extends Memcached_DataObject return $members; } + function getBlocked($offset=0, $limit=null) + { + $qry = + 'SELECT profile.* ' . + 'FROM profile JOIN group_block '. + 'ON profile.id = group_block.blocked ' . + 'WHERE group_block.group_id = %d ' . + 'ORDER BY group_block.modified DESC '; + + if ($limit != null) { + if (common_config('db','type') == 'pgsql') { + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; + } else { + $qry .= ' LIMIT ' . $offset . ', ' . $limit; + } + } + + $blocked = new Profile(); + + $blocked->query(sprintf($qry, $this->id)); + return $blocked; + } + function setOriginal($filename) { $imagefile = new ImageFile($this->id, Avatar::path($filename)); diff --git a/lib/groupnav.php b/lib/groupnav.php index 90bdc1014..194247982 100644 --- a/lib/groupnav.php +++ b/lib/groupnav.php @@ -95,6 +95,12 @@ class GroupNav extends Widget $cur = common_current_user(); if ($cur && $cur->isAdmin($this->group)) { + $this->out->menuItem(common_local_url('blockedfromgroup', array('nickname' => + $nickname)), + _('Blocked'), + sprintf(_('%s blocked users'), $nickname), + $action_name == 'blockedfromgroup', + 'nav_group_blocked'); $this->out->menuItem(common_local_url('editgroup', array('nickname' => $nickname)), _('Admin'), diff --git a/lib/router.php b/lib/router.php index 3d870e565..e10871bc0 100644 --- a/lib/router.php +++ b/lib/router.php @@ -101,7 +101,8 @@ class Router $main = array('login', 'logout', 'register', 'subscribe', 'unsubscribe', 'confirmaddress', 'recoverpassword', 'invite', 'favor', 'disfavor', 'sup', - 'block', 'unblock', 'subedit', 'groupblock'); + 'block', 'unblock', 'subedit', + 'groupblock', 'groupunblock'); foreach ($main as $a) { $m->connect('main/'.$a, array('action' => $a)); @@ -228,6 +229,10 @@ class Router array('nickname' => '[a-zA-Z0-9]+')); } + $m->connect('group/:nickname/blocked', + array('action' => 'blockedfromgroup'), + array('nickname' => '[a-zA-Z0-9]+')); + $m->connect('group/:id/id', array('action' => 'groupbyid'), array('id' => '[0-9]+')); -- cgit v1.2.3-54-g00ecf From 2f3c4f8812d389df40cf62b8967cf3e359ad5663 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 22:16:24 -0700 Subject: add correct li for css magic for block stuff --- actions/blockedfromgroup.php | 2 ++ actions/groupmembers.php | 2 ++ 2 files changed, 4 insertions(+) (limited to 'actions') diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php index 1b7b31784..541ebcfd9 100644 --- a/actions/blockedfromgroup.php +++ b/actions/blockedfromgroup.php @@ -176,10 +176,12 @@ class GroupBlockListItem extends ProfileListItem $user = common_current_user(); if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) { + $this->out->elementStart('li', 'entity_block'); $bf = new GroupUnblockForm($this->out, $this->profile, $this->group, array('action' => 'blockedfromgroup', 'nickname' => $this->group->nickname)); $bf->show(); + $this->out->elementEnd('li'); } } } diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 150b60a54..65790b7ca 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -180,10 +180,12 @@ class GroupMemberListItem extends ProfileListItem $user = common_current_user(); if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) { + $this->out->elementStart('li', 'entity_block'); $bf = new GroupBlockForm($this->out, $this->profile, $this->group, array('action' => 'groupmembers', 'nickname' => $this->group->nickname)); $bf->show(); + $this->out->elementEnd('li'); } } -- cgit v1.2.3-54-g00ecf From ecbd7718d57fc427d2aeac885d8be0321b3cf1fe Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 23:37:24 -0700 Subject: Code for adding and saving group aliases Added code to add and save group aliases. Like tags, aliases are free-texted in to the group admin page. configurable max number of aliases, default is three. --- README | 8 ++++++- actions/editgroup.php | 59 ++++++++++++++++++++++++++++++++++++++++++++++--- actions/newgroup.php | 51 +++++++++++++++++++++++++++++++++++++++++- classes/User_group.php | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/common.php | 2 ++ lib/groupeditform.php | 11 ++++++++- 6 files changed, 185 insertions(+), 6 deletions(-) (limited to 'actions') diff --git a/README b/README index 2099f94d6..8fb4a941c 100644 --- a/README +++ b/README @@ -1196,7 +1196,6 @@ reporturl: URL to post statistics to. Defaults to Laconica developers' set 'run' to 'never' than to set this value to something nonsensical. - attachments ----------- @@ -1226,6 +1225,13 @@ user_quota: total size in bytes a user can store on this server. Each user monthly_quota: total size permitted in the current month. This is the total size in bytes that a user can upload each month. +group +----- + +Options for group functionality. + +maxaliases: maximum number of aliases a group can have. Default 3. Set + to 0 or less to prevent aliases in a group. Troubleshooting =============== diff --git a/actions/editgroup.php b/actions/editgroup.php index 39dad0465..29a7bce43 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -171,6 +171,7 @@ class EditgroupAction extends Action $homepage = $this->trimmed('homepage'); $description = $this->trimmed('description'); $location = $this->trimmed('location'); + $aliasstring = $this->trimmed('aliases'); if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, @@ -201,6 +202,39 @@ class EditgroupAction extends Action return; } + if (!empty($aliasstring)) { + $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring))); + } else { + $aliases = array(); + } + + if (count($aliases) > common_config('group', 'maxaliases')) { + $this->showForm(sprintf(_('Too many aliases! Maximum %d.'), + common_config('group', 'maxaliases'))); + return; + } + + foreach ($aliases as $alias) { + if (!Validate::string($alias, array('min_length' => 1, + 'max_length' => 64, + 'format' => NICKNAME_FMT))) { + $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias)); + return; + } + if ($this->nicknameExists($alias)) { + $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'), + $alias)); + return; + } + // XXX assumes alphanum nicknames + if (strcmp($alias, $nickname) == 0) { + $this->showForm(_('Alias can\'t be the same as nickname.')); + return; + } + } + + $this->group->query('BEGIN'); + $orig = clone($this->group); $this->group->nickname = $nickname; @@ -217,6 +251,14 @@ class EditgroupAction extends Action $this->serverError(_('Could not update group.')); } + $result = $this->group->setAliases($aliases); + + if (!$result) { + $this->serverError(_('Could not create aliases.')); + } + + $this->group->query('COMMIT'); + if ($this->group->nickname != $orig->nickname) { common_redirect(common_local_url('editgroup', array('nickname' => $nickname)), @@ -229,9 +271,20 @@ class EditgroupAction extends Action function nicknameExists($nickname) { $group = User_group::staticGet('nickname', $nickname); - return (!is_null($group) && - $group != false && - $group->id != $this->group->id); + + if (!empty($group) && + $group->id != $this->group->id) { + return true; + } + + $alias = Group_alias::staticGet('alias', $nickname); + + if (!empty($alias) && + $alias->group_id != $this->group->id) { + return true; + } + + return false; } } diff --git a/actions/newgroup.php b/actions/newgroup.php index 67cd6b2f1..0289e77c2 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -123,6 +123,7 @@ class NewgroupAction extends Action $homepage = $this->trimmed('homepage'); $description = $this->trimmed('description'); $location = $this->trimmed('location'); + $aliasstring = $this->trimmed('aliases'); if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, @@ -153,6 +154,37 @@ class NewgroupAction extends Action return; } + if (!empty($aliasstring)) { + $aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring))); + } else { + $aliases = array(); + } + + if (count($aliases) > common_config('group', 'maxaliases')) { + $this->showForm(sprintf(_('Too many aliases! Maximum %d.'), + common_config('group', 'maxaliases'))); + return; + } + + foreach ($aliases as $alias) { + if (!Validate::string($alias, array('min_length' => 1, + 'max_length' => 64, + 'format' => NICKNAME_FMT))) { + $this->showForm(sprintf(_('Invalid alias: "%s"'), $alias)); + return; + } + if ($this->nicknameExists($alias)) { + $this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'), + $alias)); + return; + } + // XXX assumes alphanum nicknames + if (strcmp($alias, $nickname) == 0) { + $this->showForm(_('Alias can\'t be the same as nickname.')); + return; + } + } + $cur = common_current_user(); // Checked in prepare() above @@ -177,6 +209,12 @@ class NewgroupAction extends Action $this->serverError(_('Could not create group.')); } + $result = $group->setAliases($aliases); + + if (!$result) { + $this->serverError(_('Could not create aliases.')); + } + $member = new Group_member(); $member->group_id = $group->id; @@ -199,7 +237,18 @@ class NewgroupAction extends Action function nicknameExists($nickname) { $group = User_group::staticGet('nickname', $nickname); - return (!is_null($group) && $group != false); + + if (!empty($group)) { + return true; + } + + $alias = Group_alias::staticGet('alias', $nickname); + + if (!empty($alias)) { + return true; + } + + return false; } } diff --git a/classes/User_group.php b/classes/User_group.php index 9f9977755..0fcfee8c6 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -165,4 +165,64 @@ class User_group extends Memcached_DataObject { return ($this->fullname) ? $this->fullname : $this->nickname; } + + function getAliases() + { + $aliases = array(); + + // XXX: cache this + + $alias = new Group_alias(); + + $alias->group_id = $this->id; + + if ($alias->find()) { + while ($alias->fetch()) { + $aliases[] = $alias->alias; + } + } + + $alias->free(); + + return $aliases; + } + + function setAliases($newaliases) { + + $newaliases = array_unique($newaliases); + + $oldaliases = $this->getAliases(); + + # Delete stuff that's old that not in new + + $to_delete = array_diff($oldaliases, $newaliases); + + # Insert stuff that's in new and not in old + + $to_insert = array_diff($newaliases, $oldaliases); + + $alias = new Group_alias(); + + $alias->group_id = $this->id; + + foreach ($to_delete as $delalias) { + $alias->alias = $delalias; + $result = $alias->delete(); + if (!$result) { + common_log_db_error($alias, 'DELETE', __FILE__); + return false; + } + } + + foreach ($to_insert as $insalias) { + $alias->alias = $insalias; + $result = $alias->insert(); + if (!$result) { + common_log_db_error($alias, 'INSERT', __FILE__); + return false; + } + } + + return true; + } } diff --git a/lib/common.php b/lib/common.php index 6bf4ad21f..b4e87445e 100644 --- a/lib/common.php +++ b/lib/common.php @@ -198,6 +198,8 @@ $config = 'user_quota' => 50000000, 'monthly_quota' => 15000000, ), + 'group' => + array('maxaliases' => 3), ); $config['db'] = &PEAR::getStaticProperty('DB_DataObject','options'); diff --git a/lib/groupeditform.php b/lib/groupeditform.php index ca674f3c8..7e8d6eea3 100644 --- a/lib/groupeditform.php +++ b/lib/groupeditform.php @@ -111,7 +111,6 @@ class GroupEditForm extends Form } } - /** * Name of the form * @@ -157,6 +156,16 @@ class GroupEditForm extends Form ($this->out->arg('location')) ? $this->out->arg('location') : $this->group->location, _('Location for the group, if any, like "City, State (or Region), Country"')); $this->out->elementEnd('li'); + if (common_config('group', 'maxaliases') > 0) { + $aliases = (empty($this->group)) ? array() : $this->group->getAliases(); + $this->out->elementStart('li'); + $this->out->input('aliases', _('Aliases'), + ($this->out->arg('aliases')) ? $this->out->arg('aliases') : + (!empty($aliases)) ? implode(' ', $aliases) : '', + sprintf(_('Extra nicknames for the group, comma- or space- separated, max %d'), + common_config('group', 'maxaliases')));; + $this->out->elementEnd('li'); + } $this->out->elementEnd('ul'); } -- cgit v1.2.3-54-g00ecf From dda4493af72870d61774c8389dbbab13c2dfbbc7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 14 Jun 2009 23:51:38 -0700 Subject: show aliases when showing a group --- actions/showgroup.php | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'actions') diff --git a/actions/showgroup.php b/actions/showgroup.php index 537f09278..357f579d8 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -272,6 +272,17 @@ class ShowgroupAction extends Action $this->elementEnd('dl'); } + if (common_config('group', 'maxaliases') > 0) { + $aliases = $this->group->getAliases(); + + if (!empty($aliases)) { + $this->elementStart('dl', 'entity_aliases'); + $this->element('dt', null, _('Aliases')); + $this->element('dd', 'aliases', implode(' ', $aliases)); + $this->elementEnd('dl'); + } + } + $this->elementEnd('div'); $this->elementStart('div', 'entity_actions'); -- cgit v1.2.3-54-g00ecf From 2b8a767770119165ab9c9ce62ea3512c2fb3b049 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 15 Jun 2009 00:59:15 -0700 Subject: make admins of groups --- actions/groupmembers.php | 143 +++++++++++++++++++++++++++++++++++++++++++++++ lib/router.php | 4 ++ 2 files changed, 147 insertions(+) (limited to 'actions') diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 65790b7ca..abfad3f0d 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -171,10 +171,26 @@ class GroupMemberListItem extends ProfileListItem { $this->startActions(); $this->showSubscribeButton(); + $this->showMakeAdminForm(); $this->showGroupBlockForm(); $this->endActions(); } + function showMakeAdminForm() + { + $user = common_current_user(); + + if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group) && + !$this->profile->isAdmin($this->group)) { + $this->out->elementStart('li', 'entity_make_admin'); + $maf = new MakeAdminForm($this->out, $this->profile, $this->group, + array('action' => 'groupmembers', + 'nickname' => $this->group->nickname)); + $maf->show(); + $this->out->elementEnd('li'); + } + + } function showGroupBlockForm() { $user = common_current_user(); @@ -318,3 +334,130 @@ class GroupBlockForm extends Form $this->out->submit('submit', _('Block'), 'submit', null, _('Block this user')); } } + +/** + * Form for making a user an admin for a group + * + * @category Form + * @package Laconica + * @author Evan Prodromou + * @author Sarven Capadisli + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class MakeAdminForm extends Form +{ + /** + * Profile of user to block + */ + + var $profile = null; + + /** + * Group to block the user from + */ + + var $group = null; + + /** + * Return-to args + */ + + var $args = null; + + /** + * Constructor + * + * @param HTMLOutputter $out output channel + * @param Profile $profile profile of user to block + * @param User_group $group group to block user from + * @param array $args return-to args + */ + + function __construct($out=null, $profile=null, $group=null, $args=null) + { + parent::__construct($out); + + $this->profile = $profile; + $this->group = $group; + $this->args = $args; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + + function id() + { + // This should be unique for the page. + return 'makeadmin-' . $this->profile->id; + } + + /** + * class of the form + * + * @return string class of the form + */ + + function formClass() + { + return 'form_make_admin'; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + + function action() + { + return common_local_url('makeadmin', array('nickname' => $this->group->nickname)); + } + + /** + * Legend of the Form + * + * @return void + */ + + function formLegend() + { + $this->out->element('legend', null, _('Make user an admin of the group')); + } + + /** + * Data elements of the form + * + * @return void + */ + + function formData() + { + $this->out->hidden('profileid-' . $this->profile->id, + $this->profile->id, + 'profileid'); + $this->out->hidden('groupid-' . $this->group->id, + $this->group->id, + 'groupid'); + if ($this->args) { + foreach ($this->args as $k => $v) { + $this->out->hidden('returnto-' . $k, $v); + } + } + } + + /** + * Action elements + * + * @return void + */ + + function formActions() + { + $this->out->submit('submit', _('Make Admin'), 'submit', null, _('Make this user an admin')); + } +} diff --git a/lib/router.php b/lib/router.php index e10871bc0..0fbaba9ed 100644 --- a/lib/router.php +++ b/lib/router.php @@ -233,6 +233,10 @@ class Router array('action' => 'blockedfromgroup'), array('nickname' => '[a-zA-Z0-9]+')); + $m->connect('group/:nickname/makeadmin', + array('action' => 'makeadmin'), + array('nickname' => '[a-zA-Z0-9]+')); + $m->connect('group/:id/id', array('action' => 'groupbyid'), array('id' => '[0-9]+')); -- cgit v1.2.3-54-g00ecf From 528ceec3fe351cfa3f5050159b2c9e37357e162a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 15 Jun 2009 05:44:36 -0700 Subject: makeadmin action --- actions/makeadmin.php | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 actions/makeadmin.php (limited to 'actions') diff --git a/actions/makeadmin.php b/actions/makeadmin.php new file mode 100644 index 000000000..899c23ae4 --- /dev/null +++ b/actions/makeadmin.php @@ -0,0 +1,166 @@ + + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://laconi.ca/ + * + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Make another user an admin of a group + * + * @category Action + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://laconi.ca/ + */ + +class MakeadminAction extends Action +{ + var $profile = null; + var $group = null; + + /** + * Take arguments for running + * + * @param array $args $_REQUEST args + * + * @return boolean success flag + */ + + function prepare($args) + { + parent::prepare($args); + if (!common_logged_in()) { + $this->clientError(_('Not logged in.')); + return false; + } + $token = $this->trimmed('token'); + if (empty($token) || $token != common_session_token()) { + $this->clientError(_('There was a problem with your session token. Try again, please.')); + return; + } + $id = $this->trimmed('profileid'); + if (empty($id)) { + $this->clientError(_('No profile specified.')); + return false; + } + $this->profile = Profile::staticGet('id', $id); + if (empty($this->profile)) { + $this->clientError(_('No profile with that ID.')); + return false; + } + $group_id = $this->trimmed('groupid'); + if (empty($group_id)) { + $this->clientError(_('No group specified.')); + return false; + } + $this->group = User_group::staticGet('id', $group_id); + if (empty($this->group)) { + $this->clientError(_('No such group.')); + return false; + } + $user = common_current_user(); + if (!$user->isAdmin($this->group)) { + $this->clientError(_('Only an admin can make another user an admin.'), 401); + return false; + } + if ($this->profile->isAdmin($this->group)) { + $this->clientError(sprintf(_('%s is already an admin for group "%s".'), + $this->profile->getBestName(), + $this->group->getBestName()), + 401); + return false; + } + return true; + } + + /** + * Handle request + * + * @param array $args $_REQUEST args; handled in prepare() + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $this->makeAdmin(); + } + } + + /** + * Make user an admin + * + * @return void + */ + + function makeAdmin() + { + $member = Group_member::pkeyGet(array('group_id' => $this->group->id, + 'profile_id' => $this->profile->id)); + + if (empty($member)) { + $this->serverError(_('Can\'t get membership record for %s in group %s'), + $this->profile->getBestName(), + $this->group->getBestName()); + } + + $orig = clone($member); + + $member->is_admin = 1; + + $result = $member->update($orig); + + if (!$result) { + common_log_db_error($member, 'UPDATE', __FILE__); + $this->serverError(_('Can\'t make %s an admin for group %s'), + $this->profile->getBestName(), + $this->group->getBestName()); + } + + foreach ($this->args as $k => $v) { + if ($k == 'returnto-action') { + $action = $v; + } else if (substr($k, 0, 9) == 'returnto-') { + $args[substr($k, 9)] = $v; + } + } + + if ($action) { + common_redirect(common_local_url($action, $args), 303); + } else { + common_redirect(common_local_url('groupmembers', + array('nickname' => $this->group->nickname)), + 303); + } + } +} -- cgit v1.2.3-54-g00ecf From 807d84d448fb453de777d7a1ef938150bb03de3e Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 15 Jun 2009 12:57:08 -0700 Subject: Small fix to correct the order of defined color prefs --- actions/designsettings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 8595cbc4c..dba983fdf 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -106,10 +106,10 @@ class DesignsettingsAction extends AccountSettingsAction } $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-5'), _('Background')); + $this->element('label', array('for' => 'swatch-0'), _('Background')); $this->element('input', array('name' => 'design_background', 'type' => 'text', - 'id' => 'swatch-5', + 'id' => 'swatch-0', 'class' => 'swatch', 'maxlength' => '7', 'size' => '7', -- cgit v1.2.3-54-g00ecf From 12cd87cd7b7c207b6f9c30996f0fabb019d6fd76 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 15 Jun 2009 22:50:14 +0000 Subject: Missing call to getProfile() caused verify_credentials to fail. --- actions/twitapiusers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actions') diff --git a/actions/twitapiusers.php b/actions/twitapiusers.php index 13a8746cd..21a56a9a5 100644 --- a/actions/twitapiusers.php +++ b/actions/twitapiusers.php @@ -58,7 +58,7 @@ class TwitapiusersAction extends TwitterapiAction return; } - $twitter_user = $this->twitter_user_array($profile, true); + $twitter_user = $this->twitter_user_array($user->getProfile(), true); if ($apidata['content-type'] == 'xml') { $this->init_document('xml'); -- cgit v1.2.3-54-g00ecf From fbed704f3b6a8237e815be9586eb753cc78d20c3 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 15 Jun 2009 16:22:08 -0700 Subject: don't show create-a-group link if not logged in --- actions/groups.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'actions') diff --git a/actions/groups.php b/actions/groups.php index 26b52a5fc..b49d80f37 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -100,11 +100,13 @@ class GroupsAction extends Action function showContent() { - $this->elementStart('p', array('id' => 'new_group')); - $this->element('a', array('href' => common_local_url('newgroup'), - 'class' => 'more'), - _('Create a new group')); - $this->elementEnd('p'); + if (common_logged_in()) { + $this->elementStart('p', array('id' => 'new_group')); + $this->element('a', array('href' => common_local_url('newgroup'), + 'class' => 'more'), + _('Create a new group')); + $this->elementEnd('p'); + } $offset = ($this->page-1) * GROUPS_PER_PAGE; $limit = GROUPS_PER_PAGE + 1; -- cgit v1.2.3-54-g00ecf From 20d93508776398627f5aff64b83bd20a362cb45d Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 15 Jun 2009 20:21:33 -0700 Subject: User design setting save now --- actions/designsettings.php | 256 ++++++++++++++++++++++++++++++++------------- lib/webcolor.php | 191 +++++++++++++++++++++++++++++++++ 2 files changed, 373 insertions(+), 74 deletions(-) create mode 100644 lib/webcolor.php (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index dba983fdf..0f7c27194 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -32,7 +32,8 @@ if (!defined('LACONICA')) { exit(1); } -require_once INSTALLDIR.'/lib/accountsettingsaction.php'; +require_once INSTALLDIR . '/lib/accountsettingsaction.php'; +require_once INSTALLDIR . '/lib/WebColor.php'; class DesignsettingsAction extends AccountSettingsAction { @@ -81,7 +82,7 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('legend', null, _('Change background image')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->element('label', array('for' => 'design_background-image_file'), + $this->element('label', array('for' => 'design_background-image_file'), _('Upload file')); $this->element('input', array('name' => 'design_background-image_file', 'type' => 'file', @@ -105,61 +106,79 @@ class DesignsettingsAction extends AccountSettingsAction $design = $this->defaultDesign(); } - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-0'), _('Background')); - $this->element('input', array('name' => 'design_background', - 'type' => 'text', - 'id' => 'swatch-0', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => $design->backgroundcolor)); - $this->elementEnd('li'); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-1'), _('Content')); - $this->element('input', array('name' => 'design_content', - 'type' => 'text', - 'id' => 'swatch-1', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => $design->contentcolor)); - $this->elementEnd('li'); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-2'), _('Sidebar')); - $this->element('input', array('name' => 'design_sidebar', - 'type' => 'text', - 'id' => 'swatch-2', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => $design->sidebarcolor)); - $this->elementEnd('li'); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-3'), _('Text')); - $this->element('input', array('name' => 'design_text', - 'type' => 'text', - 'id' => 'swatch-3', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => $design->textcolor)); - $this->elementEnd('li'); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-4'), _('Links')); - $this->element('input', array('name' => 'design_links', - 'type' => 'text', - 'id' => 'swatch-4', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => $design->linkcolor)); - - $this->elementEnd('li'); + try { + + $bgcolor = new WebColor($design->backgroundcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-0'), _('Background')); + $this->element('input', array('name' => 'design_background', + 'type' => 'text', + 'id' => 'swatch-0', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $bgcolor->hexValue())); + $this->elementEnd('li'); + + + $ccolor = new WebColor($design->contentcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-1'), _('Content')); + $this->element('input', array('name' => 'design_content', + 'type' => 'text', + 'id' => 'swatch-1', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $ccolor->hexValue())); + $this->elementEnd('li'); + + $sbcolor = new WebColor($design->sidebarcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-2'), _('Sidebar')); + $this->element('input', array('name' => 'design_sidebar', + 'type' => 'text', + 'id' => 'swatch-2', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $sbcolor->hexValue())); + $this->elementEnd('li'); + + $tcolor = new WebColor($design->textcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-3'), _('Text')); + $this->element('input', array('name' => 'design_text', + 'type' => 'text', + 'id' => 'swatch-3', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $tcolor->hexValue())); + $this->elementEnd('li'); + + $lcolor = new WebColor($design->linkcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-4'), _('Links')); + $this->element('input', array('name' => 'design_links', + 'type' => 'text', + 'id' => 'swatch-4', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $lcolor->hexValue())); + + $this->elementEnd('li'); + + } catch (WebColorException $e) { + common_log(LOG_ERR, 'Bad color values in design ID: ' . + $design->id); + } $this->elementEnd('ul'); $this->elementEnd('fieldset'); @@ -169,7 +188,7 @@ class DesignsettingsAction extends AccountSettingsAction 'value' => 'Reset', 'class' => 'submit form_action-primary', 'title' => _('Reset back to default'))); - + $this->submit('save', _('Save'), 'submit form_action-secondary', 'save', _('Save design')); @@ -241,40 +260,129 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('script', array('type' => 'text/javascript', 'src' => $farbtasticGo)); } - + /** * Get a default user design * - * @return Design design + * @return Design design */ - + function defaultDesign() { $defaults = common_config('site', 'design'); $design = new Design(); - $design->backgroundcolor = $defaults['backgroundcolor']; - $design->contentcolor = $defaults['contentcolor']; - $design->sidebarcolor = $defaults['sidebarcolor']; - $design->textcolor = $defaults['textcolor']; - $design->linkcolor = $defaults['linkcolor']; - $design->backgroundimage = $defaults['backgroundimage']; + + try { + + $color = new WebColor(); + + $color->parseColor($defaults['backgroundcolor']); + $design->backgroundcolor = $color->intValue(); + + $color->parseColor($defaults['contentcolor']); + $design->contentcolor = $color->intValue(); + + $color->parseColor($defaults['sidebarcolor']); + $design->sidebarcolor = $color->intValue(); + + $color->parseColor($defaults['textcolor']); + $design->sidebarcolor = $color->intValue(); + + $color->parseColor($defaults['linkcolor']); + $design->linkcolor = $color->intValue(); + + $design->backgroundimage = $defaults['backgroundimage']; + + } catch (WebColorException $e) { + common_log(LOG_ERR, _('Bad default color settings: ' . + $e->getMessage())); + } return $design; } /** - * Save the user's design settings + * Save or update the user's design settings * * @return void */ - + function saveDesign() { $user = common_current_user(); - - - + + try { + + $bgcolor = new WebColor($this->trimmed('design_background')); + $ccolor = new WebColor($this->trimmed('design_content')); + $sbcolor = new WebColor($this->trimmed('design_sidebar')); + $tcolor = new WebColor($this->trimmed('design_text')); + $lcolor = new WebColor($this->trimmed('design_links')); + + } catch (WebColorException $e) { + $this->showForm($e->getMessage()); + return; + } + + $design = User::getDesign(); + + if (!isset($design)) { + + $original = clone($design); + + $original->backgroundcolor = $bgcolor->intValue(); + $original->contentcolor = $ccolor->intValue(); + $original->sidebarcolor = $sbcolor->intValue(); + $original->textcolor = $tcolor->intValue(); + $original->linkcolor = $lcolor->intValue(); + + $result = $design->update($original); + + if ($result === false) { + common_log_db_error($design, 'UPDATE', __FILE__); + $this->showForm(_('Couldn\'t update your design.')); + return; + } + + // update design + } else { + + $user->query('BEGIN'); + + // save new design + $design = new Design(); + + $design->backgroundcolor = $bgcolor->intValue(); + $design->contentcolor = $ccolor->intValue(); + $design->sidebarcolor = $sbcolor->intValue(); + $design->textcolor = $tcolor->intValue(); + $design->linkcolor = $lcolor->intValue(); + $design->backgroundimage = $defaults['backgroundimage']; + + $id = $design->insert(); + + if (empty($id)) { + common_log_db_error($id, 'INSERT', __FILE__); + $this->showForm(_('Unable to save your design settings!')); + return; + } + + $original = clone($user); + $user->design_id = $id; + $result = $user->update($original); + + if (empty($result)) { + common_log_db_error($original, 'UPDATE', __FILE__); + $this->showForm(_('Unable to save your design settings!')); + $user->query('ROLLBACK'); + return; + } + + $user->query('COMMIT'); + + } + $this->showForm(_('Design preferences saved.'), true); } @@ -282,9 +390,9 @@ class DesignsettingsAction extends AccountSettingsAction * Reset design settings to previous saved value if any, or * the defaults * - * @return void + * @return void */ - + function resetDesign() { $this->showForm(_('Design preferences reset.'), true); diff --git a/lib/webcolor.php b/lib/webcolor.php new file mode 100644 index 000000000..65713d26e --- /dev/null +++ b/lib/webcolor.php @@ -0,0 +1,191 @@ +. + * + * @category Personal + * @package Laconica + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +class WebColor { + + // XXX: Maybe make getters and setters for r,g,b values and tuples, + // e.g.: to support this kinda CSS representation: rgb(255,0,0) + // http://www.w3.org/TR/CSS21/syndata.html#color-units + + var $red = 0; + var $green = 0; + var $blue = 0; + + /** + * Constructor + * + * @return nothing + */ + + function __construct($color = null) + { + if (isset($color)) { + $this->parseColor($color); + } + } + + /** + * Parses input to and tries to determine whether the color + * is being specified via an integer or hex tuple and sets + * the RGB instance variables accordingly. + * + * XXX: Maybe support (r,g,b) style, and array? + * + * @param mixed $color + * + * @return nothing + */ + + function parseColor($color) { + + if (is_numeric($color)) { + $this->setIntColor($color); + } else { + + // XXX named colors + + // XXX: probably should do even more validation + + if (preg_match('/(#([0-9A-Fa-f]{3,6})\b)/u', $color) > 0) { + $this->setHexColor($color); + } else { + $errmsg = _('%s is not a valid color!'); + throw new WebColorException(sprintf($errmsg, $color)); + } + } + } + + /** + * @param string $name + * + * @return nothing + */ + + function setNamedColor($name) + { + // XXX Implement this + } + + + /** + * Sets the RGB color values from a a hex tuple + * + * @param string $hexcolor + * + * @return nothing + */ + + function setHexColor($hexcolor) { + + if ($hexcolor[0] == '#') { + $hexcolor = substr($hexcolor, 1); + } + + if (strlen($hexcolor) == 6) { + list($r, $g, $b) = array($hexcolor[0].$hexcolor[1], + $hexcolor[2].$hexcolor[3], + $hexcolor[4].$hexcolor[5]); + } elseif (strlen($hexcolor) == 3) { + list($r, $g, $b) = array($hexcolor[0].$hexcolor[0], + $hexcolor[1].$hexcolor[1], + $hexcolor[2].$hexcolor[2]); + } else { + return false; + } + + $this->red = hexdec($r); + $this->green = hexdec($g); + $this->blue = hexdec($b); + + } + + /** + * Sets the RGB color values from a 24-bit integer + * + * @param int $intcolor + * + * @return nothing + */ + + function setIntColor($intcolor) + { + // We could do 32 bit and have an alpha channel because + // Sarven wants one real bad, but nah. + + $this->red = $intcolor >> 16; + $this->green = $intcolor >> 8 & 0xFF; + $this->blue = $intcolor & 0xFF; + + } + + /** + * Returns a hex tuple of the RGB color useful for output in HTML + * + * @return string + */ + + function hexValue() { + + $hexcolor = (strlen(dechex($this->red)) < 2 ? '0' : '' ) . + dechex($this->red); + $hexcolor .= (strlen(dechex($this->green)) < 2 ? '0' : '') . + dechex($this->green); + $hexcolor .= (strlen(dechex($this->blue)) < 2 ? '0' : '') . + dechex($this->blue); + + return $hexcolor; + + } + + /** + * Returns a 24-bit packed integer representation of the RGB color + * for convenient storage in the DB + * + * XXX: probably could just use hexdec() instead + * + * @return int + */ + + function intValue() + { + $intcolor = 256 * 256 * $this->red + 256 * $this->green + $this->blue; + return $intcolor; + } + +} + +class WebColorException extends Exception +{ +} + +?> \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 94fec28610a62fcf6d33c6ec1f451dadb5ca9b18 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 15 Jun 2009 20:29:30 -0700 Subject: User design setting save --- actions/designsettings.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 0f7c27194..dedf19db8 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -111,10 +111,10 @@ class DesignsettingsAction extends AccountSettingsAction $bgcolor = new WebColor($design->backgroundcolor); $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-0'), _('Background')); + $this->element('label', array('for' => 'swatch-1'), _('Background')); $this->element('input', array('name' => 'design_background', 'type' => 'text', - 'id' => 'swatch-0', + 'id' => 'swatch-1', 'class' => 'swatch', 'maxlength' => '7', 'size' => '7', @@ -125,10 +125,10 @@ class DesignsettingsAction extends AccountSettingsAction $ccolor = new WebColor($design->contentcolor); $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-1'), _('Content')); + $this->element('label', array('for' => 'swatch-2'), _('Content')); $this->element('input', array('name' => 'design_content', 'type' => 'text', - 'id' => 'swatch-1', + 'id' => 'swatch-2', 'class' => 'swatch', 'maxlength' => '7', 'size' => '7', @@ -138,10 +138,10 @@ class DesignsettingsAction extends AccountSettingsAction $sbcolor = new WebColor($design->sidebarcolor); $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-2'), _('Sidebar')); + $this->element('label', array('for' => 'swatch-3'), _('Sidebar')); $this->element('input', array('name' => 'design_sidebar', 'type' => 'text', - 'id' => 'swatch-2', + 'id' => 'swatch-3', 'class' => 'swatch', 'maxlength' => '7', 'size' => '7', @@ -151,10 +151,10 @@ class DesignsettingsAction extends AccountSettingsAction $tcolor = new WebColor($design->textcolor); $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-3'), _('Text')); + $this->element('label', array('for' => 'swatch-4'), _('Text')); $this->element('input', array('name' => 'design_text', 'type' => 'text', - 'id' => 'swatch-3', + 'id' => 'swatch-4', 'class' => 'swatch', 'maxlength' => '7', 'size' => '7', @@ -164,10 +164,10 @@ class DesignsettingsAction extends AccountSettingsAction $lcolor = new WebColor($design->linkcolor); $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-4'), _('Links')); + $this->element('label', array('for' => 'swatch-5'), _('Links')); $this->element('input', array('name' => 'design_links', 'type' => 'text', - 'id' => 'swatch-4', + 'id' => 'swatch-5', 'class' => 'swatch', 'maxlength' => '7', 'size' => '7', -- cgit v1.2.3-54-g00ecf From 2c7f0534ca26b9c9461d920bb23765b282e6fdbc Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 16 Jun 2009 04:03:08 +0000 Subject: Typo/lowercased WebColor to webcolor in required_once --- actions/designsettings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index dedf19db8..b7f9cda98 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -33,7 +33,7 @@ if (!defined('LACONICA')) { } require_once INSTALLDIR . '/lib/accountsettingsaction.php'; -require_once INSTALLDIR . '/lib/WebColor.php'; +require_once INSTALLDIR . '/lib/webcolor.php'; class DesignsettingsAction extends AccountSettingsAction { -- cgit v1.2.3-54-g00ecf From 6d5d0b3472038b0a2cbe86c7df5f062853164dec Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 16 Jun 2009 00:56:32 -0700 Subject: Update wasn't ever getting called --- actions/designsettings.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index b7f9cda98..c5aa8c1d3 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -325,17 +325,17 @@ class DesignsettingsAction extends AccountSettingsAction return; } - $design = User::getDesign(); + $design = $user->getDesign(); - if (!isset($design)) { + if (!empty($design)) { $original = clone($design); - $original->backgroundcolor = $bgcolor->intValue(); - $original->contentcolor = $ccolor->intValue(); - $original->sidebarcolor = $sbcolor->intValue(); - $original->textcolor = $tcolor->intValue(); - $original->linkcolor = $lcolor->intValue(); + $design->backgroundcolor = $bgcolor->intValue(); + $design->contentcolor = $ccolor->intValue(); + $design->sidebarcolor = $sbcolor->intValue(); + $design->textcolor = $tcolor->intValue(); + $design->linkcolor = $lcolor->intValue(); $result = $design->update($original); -- cgit v1.2.3-54-g00ecf From 54697e52989c8d7dc9e1295679e6c0ef676642e0 Mon Sep 17 00:00:00 2001 From: Robin Millette Date: Tue, 16 Jun 2009 19:38:27 -0400 Subject: Removed more dead code. --- actions/attachment.php | 42 ------------------------------------------ actions/attachment_ajax.php | 41 ----------------------------------------- 2 files changed, 83 deletions(-) (limited to 'actions') diff --git a/actions/attachment.php b/actions/attachment.php index 16ee723d9..e4dc0e054 100644 --- a/actions/attachment.php +++ b/actions/attachment.php @@ -98,48 +98,6 @@ class AttachmentAction extends Action return $a->title(); } - /** - * Last-modified date for page - * - * When was the content of this page last modified? Based on notice, - * profile, avatar. - * - * @return int last-modified date as unix timestamp - */ -/* - function lastModified() - { - return max(strtotime($this->notice->created), - strtotime($this->profile->modified), - ($this->avatar) ? strtotime($this->avatar->modified) : 0); - } -*/ - - /** - * An entity tag for this page - * - * Shows the ETag for the page, based on the notice ID and timestamps - * for the notice, profile, and avatar. It's weak, since we change - * the date text "one hour ago", etc. - * - * @return string etag - */ -/* - function etag() - { - $avtime = ($this->avatar) ? - strtotime($this->avatar->modified) : 0; - - return 'W/"' . implode(':', array($this->arg('action'), - common_language(), - $this->notice->id, - strtotime($this->notice->created), - strtotime($this->profile->modified), - $avtime)) . '"'; - } -*/ - - /** * Handle input * diff --git a/actions/attachment_ajax.php b/actions/attachment_ajax.php index 3d83393c5..5d6773010 100644 --- a/actions/attachment_ajax.php +++ b/actions/attachment_ajax.php @@ -74,46 +74,5 @@ class Attachment_ajaxAction extends AttachmentAction } $this->elementEnd('div'); } - - /** - * Last-modified date for page - * - * When was the content of this page last modified? Based on notice, - * profile, avatar. - * - * @return int last-modified date as unix timestamp - */ -/* - function lastModified() - { - return max(strtotime($this->notice->created), - strtotime($this->profile->modified), - ($this->avatar) ? strtotime($this->avatar->modified) : 0); - } -*/ - - /** - * An entity tag for this page - * - * Shows the ETag for the page, based on the notice ID and timestamps - * for the notice, profile, and avatar. It's weak, since we change - * the date text "one hour ago", etc. - * - * @return string etag - */ -/* - function etag() - { - $avtime = ($this->avatar) ? - strtotime($this->avatar->modified) : 0; - - return 'W/"' . implode(':', array($this->arg('action'), - common_language(), - $this->notice->id, - strtotime($this->notice->created), - strtotime($this->profile->modified), - $avtime)) . '"'; - } -*/ } -- cgit v1.2.3-54-g00ecf From bc1f877f6e84929b7f2722f57858cfad8508fea5 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 16 Jun 2009 19:17:37 -0700 Subject: Design settings now save and displays backgrounds --- actions/designsettings.php | 69 +++++++++++++++++++++++++++++++++++++++++----- classes/Design.php | 63 +++++++++++++++++++++++++++++++++++++----- lib/common.php | 4 +++ 3 files changed, 122 insertions(+), 14 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index c5aa8c1d3..aa6915b98 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -56,7 +56,8 @@ class DesignsettingsAction extends AccountSettingsAction function getInstructions() { - return _('Customize the way your profile looks with a background image and a colour palette of your choice.'); + return _('Customize the way your profile looks ' . + 'with a background image and a colour palette of your choice.'); } /** @@ -71,14 +72,16 @@ class DesignsettingsAction extends AccountSettingsAction { $user = common_current_user(); $this->elementStart('form', array('method' => 'post', + 'enctype' => 'multipart/form-data', 'id' => 'form_settings_design', 'class' => 'form_settings', 'action' => - common_local_url('designsettings'))); + common_local_url('designsettings'))); $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); - $this->elementStart('fieldset', array('id' => 'settings_design_background-image')); + $this->elementStart('fieldset', array('id' => + 'settings_design_background-image')); $this->element('legend', null, _('Change background image')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); @@ -87,7 +90,8 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('input', array('name' => 'design_background-image_file', 'type' => 'file', 'id' => 'design_background-image_file')); - $this->element('p', 'form_guide', _('You can upload your personal background image. The maximum file size is 2Mb.')); + $this->element('p', 'form_guide', _('You can upload your personal ' . + 'background image. The maximum file size is 2Mb.')); $this->element('input', array('name' => 'MAX_FILE_SIZE', 'type' => 'hidden', 'id' => 'MAX_FILE_SIZE', @@ -207,6 +211,20 @@ class DesignsettingsAction extends AccountSettingsAction function handlePost() { + // XXX: Robin's workaround for a bug in PHP where $_POST + // and $_FILE are empty in the case that the uploaded + // file is bigger than PHP is configured to handle. + + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + if (empty($_POST) && $_SERVER['CONTENT_LENGTH']) { + + $msg = _('The server was unable to handle that much POST ' . + 'data (%s bytes) due to its current configuration.'); + + $this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); + } + } + // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { @@ -310,8 +328,6 @@ class DesignsettingsAction extends AccountSettingsAction function saveDesign() { - $user = common_current_user(); - try { $bgcolor = new WebColor($this->trimmed('design_background')); @@ -325,6 +341,7 @@ class DesignsettingsAction extends AccountSettingsAction return; } + $user = common_current_user(); $design = $user->getDesign(); if (!empty($design)) { @@ -336,6 +353,7 @@ class DesignsettingsAction extends AccountSettingsAction $design->sidebarcolor = $sbcolor->intValue(); $design->textcolor = $tcolor->intValue(); $design->linkcolor = $lcolor->intValue(); + $design->backgroundimage = $filepath; $result = $design->update($original); @@ -358,7 +376,7 @@ class DesignsettingsAction extends AccountSettingsAction $design->sidebarcolor = $sbcolor->intValue(); $design->textcolor = $tcolor->intValue(); $design->linkcolor = $lcolor->intValue(); - $design->backgroundimage = $defaults['backgroundimage']; + $design->backgroundimage = $filepath; $id = $design->insert(); @@ -383,6 +401,43 @@ class DesignsettingsAction extends AccountSettingsAction } + // Now that we have a Design ID we can add a file to the design. + // XXX: This is an additional DB hit, but figured having the image + // associated with the Design rather than the User was worth + // it. -- Zach + + if ($_FILES['design_background-image_file']['error'] == + UPLOAD_ERR_OK) { + + $filepath = null; + + try { + $imagefile = + ImageFile::fromUpload('design_background-image_file'); + } catch (Exception $e) { + $this->showForm($e->getMessage()); + return; + } + + $filename = Design::filename($design->id, + image_type_to_extension($imagefile->type), + common_timestamp()); + + $filepath = Design::path($filename); + + move_uploaded_file($imagefile->filepath, $filepath); + + $original = clone($design); + $design->backgroundimage = $filename; + $result = $design->update($original); + + if ($result === false) { + common_log_db_error($design, 'UPDATE', __FILE__); + $this->showForm(_('Couldn\'t update your design.')); + return; + } + } + $this->showForm(_('Design preferences saved.'), true); } diff --git a/classes/Design.php b/classes/Design.php index 8bb527761..f5c87b489 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -64,12 +64,61 @@ class Design extends Memcached_DataObject __FILE__); } - $out->element('style', array('type' => 'text/css'), - 'html, body { background-color: #' . $bgcolor->hexValue() . '} '."\n". - '#content, #site_nav_local_views .current a { background-color: #' . - $ccolor->hexValue() . '} '."\n". - '#aside_primary { background-color: #'. $sbcolor->hexValue() .'} '."\n". - 'html body { color: #'. $tcolor->hexValue() .'} '."\n". - 'a { color: #' . $lcolor->hexValue() . '} '."\n"); + $css = 'html, body { background-color: #' . $bgcolor->hexValue() . '} ' . "\n"; + $css .= '#content, #site_nav_local_views .current a { background-color: #'; + $css .= $ccolor->hexValue() . '} '."\n"; + $css .= '#aside_primary { background-color: #'. $sbcolor->hexValue() . '} ' . "\n"; + $css .= 'html body { color: #'. $tcolor->hexValue() . '} '. "\n"; + $css .= 'a { color: #' . $lcolor->hexValue() . '} ' . "\n"; + + if (!empty($this->backgroundimage)) { + + $css .= 'body { background-image:url(' . + Design::url($this->backgroundimage) . + '); background-repeat:no-repeat; }' . "\n"; + } + + $out->element('style', array('type' => 'text/css'), $css); + + } + + static function filename($id, $extension, $extra=null) + { + return $id . (($extra) ? ('-' . $extra) : '') . $extension; + } + + static function path($filename) + { + $dir = common_config('background', 'dir'); + + if ($dir[strlen($dir)-1] != '/') { + $dir .= '/'; + } + + return $dir . $filename; } + + static function url($filename) + { + $path = common_config('background', 'path'); + + if ($path[strlen($path)-1] != '/') { + $path .= '/'; + } + + if ($path[0] != '/') { + $path = '/'.$path; + } + + $server = common_config('background', 'server'); + + if (empty($server)) { + $server = common_config('site', 'server'); + } + + // XXX: protocol + + return 'http://'.$server.$path.$filename; + } + } diff --git a/lib/common.php b/lib/common.php index 1381d8047..0e710625c 100644 --- a/lib/common.php +++ b/lib/common.php @@ -119,6 +119,10 @@ $config = array('server' => null, 'dir' => INSTALLDIR . '/avatar/', 'path' => $_path . '/avatar/'), + 'background' => + array('server' => null, + 'dir' => INSTALLDIR . '/background/', + 'path' => $_path . '/background/'), 'public' => array('localonly' => true, 'blacklist' => array(), -- cgit v1.2.3-54-g00ecf From befbfc9c73a75bac9d7dac4a4b7a21bd515ce1b4 Mon Sep 17 00:00:00 2001 From: Robin Millette Date: Tue, 16 Jun 2009 23:10:17 -0400 Subject: Moved url handling to its proper place, from newnotice to Notice.php --- actions/newnotice.php | 19 ------------------- classes/Notice.php | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'actions') diff --git a/actions/newnotice.php b/actions/newnotice.php index 02976a2ae..72ccd8c32 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -231,7 +231,6 @@ class NewnoticeAction extends Action if (isset($mimetype)) { $this->storeFile($notice, $mimetype); } - $this->saveUrls($notice); common_broadcast_notice($notice); if ($this->boolean('ajax')) { @@ -284,24 +283,6 @@ class NewnoticeAction extends Action } } - /** save all urls in the notice to the db - * - * follow redirects and save all available file information - * (mimetype, date, size, oembed, etc.) - * - * @param class $notice Notice to pull URLs from - * - * @return void - */ - function saveUrls($notice, $uploaded = null) { - common_replace_urls_callback($notice->content, array($this, 'saveUrl'), $notice->id); - } - - function saveUrl($data) { - list($url, $notice_id) = $data; - $zzz = File::processNew($url, $notice_id); - } - /** * Show an Ajax-y error message * diff --git a/classes/Notice.php b/classes/Notice.php index 68602b1f7..770b5d78b 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -217,6 +217,7 @@ class Notice extends Memcached_DataObject $notice->addToInboxes(); $notice->saveGroups(); + $notice->saveUrls(); $notice->query('COMMIT'); @@ -231,6 +232,24 @@ class Notice extends Memcached_DataObject return $notice; } + /** save all urls in the notice to the db + * + * follow redirects and save all available file information + * (mimetype, date, size, oembed, etc.) + * + * @param class $notice Notice to pull URLs from + * + * @return void + */ + function saveUrls() { + common_replace_urls_callback($this->content, array($this, 'saveUrl'), $this->id); + } + + function saveUrl($data) { + list($url, $notice_id) = $data; + File::processNew($url, $notice_id); + } + static function checkDupes($profile_id, $content) { $profile = Profile::staticGet($profile_id); if (!$profile) { -- cgit v1.2.3-54-g00ecf From bea2fa15060e03d818db043122bf9529d2b77662 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 17 Jun 2009 04:09:30 +0000 Subject: Added form option to tile background image and to turn it on and off --- actions/designsettings.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index aa6915b98..e97d01ceb 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -97,6 +97,34 @@ class DesignsettingsAction extends AccountSettingsAction 'id' => 'MAX_FILE_SIZE', 'value' => ImageFile::maxFileSizeInt())); $this->elementEnd('li'); + + $this->elementStart('li', array('id' => 'design_background-image_onoff')); + $this->element('input', array('name' => 'design_background-image_onoff', + 'type' => 'radio', + 'id' => 'design_background-image_on', + 'class' => 'radio', + 'value' => 'true', + 'checked'=> 'checked')); + $this->element('label', array('for' => 'design_background-image_on', + 'class' => 'radio'), + _('On')); + $this->element('input', array('name' => 'design_background-image_onoff', + 'type' => 'radio', + 'id' => 'design_background-image_off', + 'class' => 'radio', + 'value' => 'false')); + $this->element('label', array('for' => 'design_background-image_off', + 'class' => 'radio'), + _('Off')); + $this->element('p', 'form_guide', _('Turn background image on or off.')); + $this->elementEnd('li'); + + $this->elementStart('li'); + $this->checkbox('design_background-image_repeat', + _('Tile background image'), + false, null, true, false); + $this->elementEnd('li'); + $this->elementEnd('ul'); $this->elementEnd('fieldset'); -- cgit v1.2.3-54-g00ecf From d1ae3176b638a8342f0d3cfb4ac071623c639575 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 16 Jun 2009 22:18:25 -0700 Subject: Enable tiling of background imgs for Designs --- actions/designsettings.php | 20 +++++++++++++------- classes/Design.php | 25 ++++++++++++++----------- lib/common.php | 3 ++- 3 files changed, 29 insertions(+), 19 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index e97d01ceb..866d8aaeb 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -71,6 +71,12 @@ class DesignsettingsAction extends AccountSettingsAction function showContent() { $user = common_current_user(); + $design = $user->getDesign(); + + if (empty($design)) { + $design = $this->defaultDesign(); + } + $this->elementStart('form', array('method' => 'post', 'enctype' => 'multipart/form-data', 'id' => 'form_settings_design', @@ -122,7 +128,7 @@ class DesignsettingsAction extends AccountSettingsAction $this->elementStart('li'); $this->checkbox('design_background-image_repeat', _('Tile background image'), - false, null, true, false); + $design->tile); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -132,12 +138,6 @@ class DesignsettingsAction extends AccountSettingsAction $this->element('legend', null, _('Change colours')); $this->elementStart('ul', 'form_data'); - $design = $user->getDesign(); - - if (empty($design)) { - $design = $this->defaultDesign(); - } - try { $bgcolor = new WebColor($design->backgroundcolor); @@ -340,6 +340,8 @@ class DesignsettingsAction extends AccountSettingsAction $design->backgroundimage = $defaults['backgroundimage']; + $deisng->tile = $defaults['tile']; + } catch (WebColorException $e) { common_log(LOG_ERR, _('Bad default color settings: ' . $e->getMessage())); @@ -369,6 +371,8 @@ class DesignsettingsAction extends AccountSettingsAction return; } + $tile = $this->boolean('design_background-image_repeat'); + $user = common_current_user(); $design = $user->getDesign(); @@ -382,6 +386,7 @@ class DesignsettingsAction extends AccountSettingsAction $design->textcolor = $tcolor->intValue(); $design->linkcolor = $lcolor->intValue(); $design->backgroundimage = $filepath; + $design->tile = $tile; $result = $design->update($original); @@ -405,6 +410,7 @@ class DesignsettingsAction extends AccountSettingsAction $design->textcolor = $tcolor->intValue(); $design->linkcolor = $lcolor->intValue(); $design->backgroundimage = $filepath; + $design->tile = $tile; $id = $design->insert(); diff --git a/classes/Design.php b/classes/Design.php index acc94d196..4ea176677 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -41,7 +41,7 @@ class Design extends Memcached_DataObject public $textcolor; // int(4) public $linkcolor; // int(4) public $backgroundimage; // varchar(255) - public $tile; // tinyint(1) + public $tile; // tinyint(1) /* Static get */ function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Design',$k,$v); } @@ -64,23 +64,26 @@ class Design extends Memcached_DataObject common_log(LOG_ERR, "Unable to create color for design $id.", __FILE__); } - + $css = 'html, body { background-color: #' . $bgcolor->hexValue() . '} ' . "\n"; $css .= '#content, #site_nav_local_views .current a { background-color: #'; $css .= $ccolor->hexValue() . '} '."\n"; $css .= '#aside_primary { background-color: #'. $sbcolor->hexValue() . '} ' . "\n"; $css .= 'html body { color: #'. $tcolor->hexValue() . '} '. "\n"; $css .= 'a { color: #' . $lcolor->hexValue() . '} ' . "\n"; - + if (!empty($this->backgroundimage)) { - - $css .= 'body { background-image:url(' . - Design::url($this->backgroundimage) . - '); background-repeat:no-repeat; }' . "\n"; + + $repeat = ($this->tile) ? 'background-repeat:repeat;' : + 'background-repeat:no-repeat;'; + + $css .= 'body { background-image:url(' . + Design::url($this->backgroundimage) . + '); ' . $repeat . ' }' . "\n"; } - + $out->element('style', array('type' => 'text/css'), $css); - + } static function filename($id, $extension, $extra=null) @@ -98,7 +101,7 @@ class Design extends Memcached_DataObject return $dir . $filename; } - + static function url($filename) { $path = common_config('background', 'path'); @@ -121,5 +124,5 @@ class Design extends Memcached_DataObject return 'http://'.$server.$path.$filename; } - + } diff --git a/lib/common.php b/lib/common.php index 0e710625c..629fee25b 100644 --- a/lib/common.php +++ b/lib/common.php @@ -78,7 +78,8 @@ $config = 'sidebarcolor' => '#CEE1E9', 'textcolor' => '#000000', 'linkcolor' => '#002E6E', - 'backgroundimage' => null), + 'backgroundimage' => null, + 'tile' => true), 'path' => $_path, 'logfile' => null, 'logo' => null, -- cgit v1.2.3-54-g00ecf From a0618b0e33e20700b243d696f2bf139f1167ec93 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 16 Jun 2009 22:57:28 -0700 Subject: Show a background img in settings form --- actions/designsettings.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 866d8aaeb..a97235e67 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -105,6 +105,12 @@ class DesignsettingsAction extends AccountSettingsAction $this->elementEnd('li'); $this->elementStart('li', array('id' => 'design_background-image_onoff')); + + if (!empty($design->backgroundimage)) { + $this->element('img', array('src' => + Design::url($design->backgroundimage))); + } + $this->element('input', array('name' => 'design_background-image_onoff', 'type' => 'radio', 'id' => 'design_background-image_on', -- cgit v1.2.3-54-g00ecf From 7148ea86dff5754fcf0c28023cff52137843f2d9 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 17 Jun 2009 06:23:57 +0000 Subject: Dynamically tile background image and turn background image on or off in user design --- actions/designsettings.php | 4 +- js/farbtastic/farbtastic.go.js | 87 ----------- js/farbtastic/farbtastic.js | 329 ----------------------------------------- js/userdesign.go.js | 99 +++++++++++++ 4 files changed, 101 insertions(+), 418 deletions(-) delete mode 100644 js/farbtastic/farbtastic.go.js delete mode 100644 js/farbtastic/farbtastic.js create mode 100644 js/userdesign.go.js (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index a97235e67..fbec3fc67 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -305,12 +305,12 @@ class DesignsettingsAction extends AccountSettingsAction parent::showScripts(); $farbtasticPack = common_path('js/farbtastic/farbtastic.js'); - $farbtasticGo = common_path('js/farbtastic/farbtastic.go.js'); + $userDesignGo = common_path('js/userdesign.go.js'); $this->element('script', array('type' => 'text/javascript', 'src' => $farbtasticPack)); $this->element('script', array('type' => 'text/javascript', - 'src' => $farbtasticGo)); + 'src' => $userDesignGo)); } /** diff --git a/js/farbtastic/farbtastic.go.js b/js/farbtastic/farbtastic.go.js deleted file mode 100644 index 9bf740825..000000000 --- a/js/farbtastic/farbtastic.go.js +++ /dev/null @@ -1,87 +0,0 @@ -/** Init for Farbtastic library and page setup - * - * @package Laconica - * @author Sarven Capadisli - * @copyright 2009 Control Yourself, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ - */ -$(document).ready(function() { - function UpdateColors(S) { - C = $(S).val(); - switch (parseInt(S.id.slice(-1))) { - case 1: default: - $('html, body').css({'background-color':C}); - break; - case 2: - $('#content, #site_nav_local_views .current a').css({'background-color':C}); - break; - case 3: - $('#aside_primary').css({'background-color':C}); - break; - case 4: - $('html body').css({'color':C}); - break; - case 5: - $('a').css({'color':C}); - break; - } - } - - function UpdateFarbtastic(e) { - f.linked = e; - f.setColor(e.value); - } - - function UpdateSwatch(e) { - $(e).css({"background-color": e.value, - "color": f.hsl[2] > 0.5 ? "#000": "#fff"}); - } - - function SynchColors(e) { - var S = f.linked; - var C = f.color; - - if (S && S.value && S.value != C) { - S.value = C; - UpdateSwatch(S); - UpdateColors(S); - } - } - - function Init() { - $('#settings_design_color').append('
'); - $('#color-picker').hide(); - - f = $.farbtastic('#color-picker', SynchColors); - swatches = $('#settings_design_color .swatch'); - - swatches - .each(SynchColors) - .blur(function() { - tv = $(this).val(); - $(this).val(tv.toUpperCase()); - (tv.length == 4) ? ((tv[0] == '#') ? $(this).val('#'+tv[1]+tv[1]+tv[2]+tv[2]+tv[3]+tv[3]) : '') : ''; - }) - .focus(function() { - $('#color-picker').show(); - UpdateFarbtastic(this); - }) - .change(function() { - UpdateFarbtastic(this); - UpdateSwatch(this); - UpdateColors(this); - }).change(); - } - - var f, swatches; - Init(); - $('#form_settings_design').bind('reset', function(){ - setTimeout(function(){ - swatches.each(function(){UpdateColors(this);}); - $('#color-picker').remove(); - swatches.unbind(); - Init(); - },10); - }); -}); diff --git a/js/farbtastic/farbtastic.js b/js/farbtastic/farbtastic.js deleted file mode 100644 index 24a377803..000000000 --- a/js/farbtastic/farbtastic.js +++ /dev/null @@ -1,329 +0,0 @@ -// $Id: farbtastic.js,v 1.2 2007/01/08 22:53:01 unconed Exp $ -// Farbtastic 1.2 - -jQuery.fn.farbtastic = function (callback) { - $.farbtastic(this, callback); - return this; -}; - -jQuery.farbtastic = function (container, callback) { - var container = $(container).get(0); - return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback)); -} - -jQuery._farbtastic = function (container, callback) { - // Store farbtastic object - var fb = this; - - // Insert markup - $(container).html('
'); - var e = $('.farbtastic', container); - fb.wheel = $('.wheel', container).get(0); - // Dimensions - fb.radius = 84; - fb.square = 100; - fb.width = 194; - - // Fix background PNGs in IE6 - if (navigator.appVersion.match(/MSIE [0-6]\./)) { - $('*', e).each(function () { - if (this.currentStyle.backgroundImage != 'none') { - var image = this.currentStyle.backgroundImage; - image = this.currentStyle.backgroundImage.substring(5, image.length - 2); - $(this).css({ - 'backgroundImage': 'none', - 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" - }); - } - }); - } - - /** - * Link to the given element(s) or callback. - */ - fb.linkTo = function (callback) { - // Unbind previous nodes - if (typeof fb.callback == 'object') { - $(fb.callback).unbind('keyup', fb.updateValue); - } - - // Reset color - fb.color = null; - - // Bind callback or elements - if (typeof callback == 'function') { - fb.callback = callback; - } - else if (typeof callback == 'object' || typeof callback == 'string') { - fb.callback = $(callback); - fb.callback.bind('keyup', fb.updateValue); - if (fb.callback.get(0).value) { - fb.setColor(fb.callback.get(0).value); - } - } - return this; - } - fb.updateValue = function (event) { - if (this.value && this.value != fb.color) { - fb.setColor(this.value); - } - } - - /** - * Change color with HTML syntax #123456 - */ - fb.setColor = function (color) { - var unpack = fb.unpack(color); - if (fb.color != color && unpack) { - fb.color = color; - fb.rgb = unpack; - fb.hsl = fb.RGBToHSL(fb.rgb); - fb.updateDisplay(); - } - return this; - } - - /** - * Change color with HSL triplet [0..1, 0..1, 0..1] - */ - fb.setHSL = function (hsl) { - fb.hsl = hsl; - fb.rgb = fb.HSLToRGB(hsl); - fb.color = fb.pack(fb.rgb); - fb.updateDisplay(); - return this; - } - - ///////////////////////////////////////////////////// - - /** - * Retrieve the coordinates of the given event relative to the center - * of the widget. - */ - fb.widgetCoords = function (event) { - var x, y; - var el = event.target || event.srcElement; - var reference = fb.wheel; - - if (typeof event.offsetX != 'undefined') { - // Use offset coordinates and find common offsetParent - var pos = { x: event.offsetX, y: event.offsetY }; - - // Send the coordinates upwards through the offsetParent chain. - var e = el; - while (e) { - e.mouseX = pos.x; - e.mouseY = pos.y; - pos.x += e.offsetLeft; - pos.y += e.offsetTop; - e = e.offsetParent; - } - - // Look for the coordinates starting from the wheel widget. - var e = reference; - var offset = { x: 0, y: 0 } - while (e) { - if (typeof e.mouseX != 'undefined') { - x = e.mouseX - offset.x; - y = e.mouseY - offset.y; - break; - } - offset.x += e.offsetLeft; - offset.y += e.offsetTop; - e = e.offsetParent; - } - - // Reset stored coordinates - e = el; - while (e) { - e.mouseX = undefined; - e.mouseY = undefined; - e = e.offsetParent; - } - } - else { - // Use absolute coordinates - var pos = fb.absolutePosition(reference); - x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x; - y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y; - } - // Subtract distance to middle - return { x: x - fb.width / 2, y: y - fb.width / 2 }; - } - - /** - * Mousedown handler - */ - fb.mousedown = function (event) { - // Capture mouse - if (!document.dragging) { - $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup); - document.dragging = true; - } - - // Check which area is being dragged - var pos = fb.widgetCoords(event); - fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square; - - // Process - fb.mousemove(event); - return false; - } - - /** - * Mousemove handler - */ - fb.mousemove = function (event) { - // Get coordinates relative to color picker center - var pos = fb.widgetCoords(event); - - // Set new HSL parameters - if (fb.circleDrag) { - var hue = Math.atan2(pos.x, -pos.y) / 6.28; - if (hue < 0) hue += 1; - fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]); - } - else { - var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5)); - var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5)); - fb.setHSL([fb.hsl[0], sat, lum]); - } - return false; - } - - /** - * Mouseup handler - */ - fb.mouseup = function () { - // Uncapture mouse - $(document).unbind('mousemove', fb.mousemove); - $(document).unbind('mouseup', fb.mouseup); - document.dragging = false; - } - - /** - * Update the markers and styles - */ - fb.updateDisplay = function () { - // Markers - var angle = fb.hsl[0] * 6.28; - $('.h-marker', e).css({ - left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px', - top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px' - }); - - $('.sl-marker', e).css({ - left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px', - top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px' - }); - - // Saturation/Luminance gradient - $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5]))); - - // Linked elements or callback - if (typeof fb.callback == 'object') { - // Set background/foreground color - $(fb.callback).css({ - backgroundColor: fb.color, - color: fb.hsl[2] > 0.5 ? '#000' : '#fff' - }); - - // Change linked value - $(fb.callback).each(function() { - if (this.value && this.value != fb.color) { - this.value = fb.color; - } - }); - } - else if (typeof fb.callback == 'function') { - fb.callback.call(fb, fb.color); - } - } - - /** - * Get absolute position of element - */ - fb.absolutePosition = function (el) { - var r = { x: el.offsetLeft, y: el.offsetTop }; - // Resolve relative to offsetParent - if (el.offsetParent) { - var tmp = fb.absolutePosition(el.offsetParent); - r.x += tmp.x; - r.y += tmp.y; - } - return r; - }; - - /* Various color utility functions */ - fb.pack = function (rgb) { - var r = Math.round(rgb[0] * 255); - var g = Math.round(rgb[1] * 255); - var b = Math.round(rgb[2] * 255); - return '#' + (r < 16 ? '0' : '') + r.toString(16) + - (g < 16 ? '0' : '') + g.toString(16) + - (b < 16 ? '0' : '') + b.toString(16); - } - - fb.unpack = function (color) { - if (color.length == 7) { - return [parseInt('0x' + color.substring(1, 3)) / 255, - parseInt('0x' + color.substring(3, 5)) / 255, - parseInt('0x' + color.substring(5, 7)) / 255]; - } - else if (color.length == 4) { - return [parseInt('0x' + color.substring(1, 2)) / 15, - parseInt('0x' + color.substring(2, 3)) / 15, - parseInt('0x' + color.substring(3, 4)) / 15]; - } - } - - fb.HSLToRGB = function (hsl) { - var m1, m2, r, g, b; - var h = hsl[0], s = hsl[1], l = hsl[2]; - m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s; - m1 = l * 2 - m2; - return [this.hueToRGB(m1, m2, h+0.33333), - this.hueToRGB(m1, m2, h), - this.hueToRGB(m1, m2, h-0.33333)]; - } - - fb.hueToRGB = function (m1, m2, h) { - h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); - if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; - if (h * 2 < 1) return m2; - if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; - return m1; - } - - fb.RGBToHSL = function (rgb) { - var min, max, delta, h, s, l; - var r = rgb[0], g = rgb[1], b = rgb[2]; - min = Math.min(r, Math.min(g, b)); - max = Math.max(r, Math.max(g, b)); - delta = max - min; - l = (min + max) / 2; - s = 0; - if (l > 0 && l < 1) { - s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); - } - h = 0; - if (delta > 0) { - if (max == r && max != g) h += (g - b) / delta; - if (max == g && max != b) h += (2 + (b - r) / delta); - if (max == b && max != r) h += (4 + (r - g) / delta); - h /= 6; - } - return [h, s, l]; - } - - // Install mousedown handler (the others are set on the document on-demand) - $('*', e).mousedown(fb.mousedown); - - // Init color - fb.setColor('#000000'); - - // Set linked elements/callback - if (callback) { - fb.linkTo(callback); - } -} \ No newline at end of file diff --git a/js/userdesign.go.js b/js/userdesign.go.js new file mode 100644 index 000000000..b54b492cc --- /dev/null +++ b/js/userdesign.go.js @@ -0,0 +1,99 @@ +/** Init for Farbtastic library and page setup + * + * @package Laconica + * @author Sarven Capadisli + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ +$(document).ready(function() { + function UpdateColors(S) { + C = $(S).val(); + switch (parseInt(S.id.slice(-1))) { + case 1: default: + $('html, body').css({'background-color':C}); + break; + case 2: + $('#content, #site_nav_local_views .current a').css({'background-color':C}); + break; + case 3: + $('#aside_primary').css({'background-color':C}); + break; + case 4: + $('html body').css({'color':C}); + break; + case 5: + $('a').css({'color':C}); + break; + } + } + + function UpdateFarbtastic(e) { + f.linked = e; + f.setColor(e.value); + } + + function UpdateSwatch(e) { + $(e).css({"background-color": e.value, + "color": f.hsl[2] > 0.5 ? "#000": "#fff"}); + } + + function SynchColors(e) { + var S = f.linked; + var C = f.color; + + if (S && S.value && S.value != C) { + S.value = C; + UpdateSwatch(S); + UpdateColors(S); + } + } + + function InitFarbtastic() { + $('#settings_design_color').append('
'); + $('#color-picker').hide(); + + f = $.farbtastic('#color-picker', SynchColors); + swatches = $('#settings_design_color .swatch'); + + swatches + .each(SynchColors) + .blur(function() { + tv = $(this).val(); + $(this).val(tv.toUpperCase()); + (tv.length == 4) ? ((tv[0] == '#') ? $(this).val('#'+tv[1]+tv[1]+tv[2]+tv[2]+tv[3]+tv[3]) : '') : ''; + }) + .focus(function() { + $('#color-picker').show(); + UpdateFarbtastic(this); + }) + .change(function() { + UpdateFarbtastic(this); + UpdateSwatch(this); + UpdateColors(this); + }).change(); + } + + var f, swatches; + InitFarbtastic(); + $('#form_settings_design').bind('reset', function(){ + setTimeout(function(){ + swatches.each(function(){UpdateColors(this);}); + $('#color-picker').remove(); + swatches.unbind(); + InitFarbtastic(); + },10); + }); + + $('#design_background-image_off').focus(function() { + $('body').css({'background-image':'none'}); + }); + $('#design_background-image_on').focus(function() { + var bis = $('#design_background-image_onoff img')[0].src; + $('body').css({'background-image':'url('+bis+')'}); + }); + + $('#design_background-image_repeat').click(function() { + ($(this)[0].checked) ? $('body').css({'background-repeat':'repeat'}) : $('body').css({'background-repeat':'no-repeat'}); + }); +}); \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 4c640aace978a2a57b6d2d4658febde3f9826efa Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 17 Jun 2009 08:14:01 +0000 Subject: Updated markup yes/no form actions to be consistent with the rest of the site --- actions/block.php | 17 ++++++++++------- actions/groupblock.php | 17 ++++++++++------- theme/base/css/display.css | 3 ++- 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'actions') diff --git a/actions/block.php b/actions/block.php index 0efee5932..441016d4e 100644 --- a/actions/block.php +++ b/actions/block.php @@ -125,16 +125,18 @@ class BlockAction extends Action function areYouSureForm() { $id = $this->profile->id; + $this->elementStart('form', array('id' => 'block-' . $id, + 'method' => 'post', + 'class' => 'form_settings form_entity_block', + 'action' => common_local_url('block'))); + $this->elementStart('fieldset'); + $this->hidden('token', common_session_token()); + $this->element('legend', _('Block user')); $this->element('p', null, _('Are you sure you want to block this user? '. 'Afterwards, they will be unsubscribed from you, '. 'unable to subscribe to you in the future, and '. 'you will not be notified of any @-replies from them.')); - $this->elementStart('form', array('id' => 'block-' . $id, - 'method' => 'post', - 'class' => 'block', - 'action' => common_local_url('block'))); - $this->hidden('token', common_session_token()); $this->element('input', array('id' => 'blockto-' . $id, 'name' => 'blockto', 'type' => 'hidden', @@ -144,8 +146,9 @@ class BlockAction extends Action $this->hidden($k, $v); } } - $this->submit('no', _('No')); - $this->submit('yes', _('Yes')); + $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group")); + $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group')); + $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/actions/groupblock.php b/actions/groupblock.php index 93662da79..28685b1d5 100644 --- a/actions/groupblock.php +++ b/actions/groupblock.php @@ -151,17 +151,19 @@ class GroupblockAction extends Action function areYouSureForm() { $id = $this->profile->id; + $this->elementStart('form', array('id' => 'block-' . $id, + 'method' => 'post', + 'class' => 'form_settings form_entity_block', + 'action' => common_local_url('groupblock'))); + $this->elementStart('fieldset'); + $this->hidden('token', common_session_token()); + $this->element('legend', null, _('Block user')); $this->element('p', null, sprintf(_('Are you sure you want to block user "%s" from the group "%s"? '. 'They will be removed from the group, unable to post, and '. 'unable to subscribe to the group in the future.'), $this->profile->getBestName(), $this->group->getBestName())); - $this->elementStart('form', array('id' => 'block-' . $id, - 'method' => 'post', - 'class' => 'block', - 'action' => common_local_url('groupblock'))); - $this->hidden('token', common_session_token()); $this->hidden('blockto-' . $this->profile->id, $this->profile->id, 'blockto'); @@ -173,8 +175,9 @@ class GroupblockAction extends Action $this->hidden($k, $v); } } - $this->submit('no', _('No')); - $this->submit('yes', _('Yes')); + $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group")); + $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group')); + $this->elementEnd('fieldset'); $this->elementEnd('form'); } diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 49907058e..403a9c37f 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -154,7 +154,8 @@ font-weight:bold; #form_invite legend, #form_notice_delete legend, #form_password_recover legend, -#form_password_change legend { +#form_password_change legend, +.form_entity_block legend { display:none; } -- cgit v1.2.3-54-g00ecf From 76cbeff33c9659cacbb57943056aabcb1517ca5c Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 17 Jun 2009 02:35:51 -0700 Subject: Update background image settings to use bitflags --- actions/designsettings.php | 100 +++++++++++++++++++++++++++------------------ classes/Design.php | 33 +++++++++++++-- classes/laconica.ini | 2 +- db/laconica.sql | 2 +- lib/common.php | 2 +- 5 files changed, 93 insertions(+), 46 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index fbec3fc67..3dfaddd7b 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -104,37 +104,52 @@ class DesignsettingsAction extends AccountSettingsAction 'value' => ImageFile::maxFileSizeInt())); $this->elementEnd('li'); - $this->elementStart('li', array('id' => 'design_background-image_onoff')); - if (!empty($design->backgroundimage)) { + + $this->elementStart('li', array('id' => 'design_background-image_onoff')); + $this->element('img', array('src' => Design::url($design->backgroundimage))); - } - $this->element('input', array('name' => 'design_background-image_onoff', - 'type' => 'radio', - 'id' => 'design_background-image_on', - 'class' => 'radio', - 'value' => 'true', - 'checked'=> 'checked')); - $this->element('label', array('for' => 'design_background-image_on', - 'class' => 'radio'), - _('On')); - $this->element('input', array('name' => 'design_background-image_onoff', - 'type' => 'radio', - 'id' => 'design_background-image_off', - 'class' => 'radio', - 'value' => 'false')); - $this->element('label', array('for' => 'design_background-image_off', - 'class' => 'radio'), - _('Off')); - $this->element('p', 'form_guide', _('Turn background image on or off.')); - $this->elementEnd('li'); + $attrs = array('name' => 'design_background-image_onoff', + 'type' => 'radio', + 'id' => 'design_background-image_on', + 'class' => 'radio', + 'value' => 'on'); + + if ($design->disposition & BACKGROUND_ON) { + $attrs['checked'] = 'checked'; + } + + $this->element('input', $attrs); + + $this->element('label', array('for' => 'design_background-image_on', + 'class' => 'radio'), + _('On')); + + $attrs = array('name' => 'design_background-image_onoff', + 'type' => 'radio', + 'id' => 'design_background-image_off', + 'class' => 'radio', + 'value' => 'off'); + + if ($design->disposition & BACKGROUND_OFF) { + $attrs['checked'] = 'checked'; + } + + $this->element('input', $attrs); + + $this->element('label', array('for' => 'design_background-image_off', + 'class' => 'radio'), + _('Off')); + $this->element('p', 'form_guide', _('Turn background image on or off.')); + $this->elementEnd('li'); + } $this->elementStart('li'); $this->checkbox('design_background-image_repeat', _('Tile background image'), - $design->tile); + ($design->disposition & BACKGROUND_TILE) ? true : false ); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -159,7 +174,6 @@ class DesignsettingsAction extends AccountSettingsAction 'value' => '#' . $bgcolor->hexValue())); $this->elementEnd('li'); - $ccolor = new WebColor($design->contentcolor); $this->elementStart('li'); @@ -346,7 +360,7 @@ class DesignsettingsAction extends AccountSettingsAction $design->backgroundimage = $defaults['backgroundimage']; - $deisng->tile = $defaults['tile']; + $deisng->disposition = $defaults['disposition']; } catch (WebColorException $e) { common_log(LOG_ERR, _('Bad default color settings: ' . @@ -377,7 +391,23 @@ class DesignsettingsAction extends AccountSettingsAction return; } - $tile = $this->boolean('design_background-image_repeat'); + $onoff = $this->arg('design_background-image_onoff'); + + $on = false; + $off = false; + $tile = false; + + if ($onoff == 'on') { + $on = true; + } else { + $off = true; + } + + $repeat = $this->boolean('design_background-image_repeat'); + + if ($repeat) { + $tile = true; + } $user = common_current_user(); $design = $user->getDesign(); @@ -392,7 +422,8 @@ class DesignsettingsAction extends AccountSettingsAction $design->textcolor = $tcolor->intValue(); $design->linkcolor = $lcolor->intValue(); $design->backgroundimage = $filepath; - $design->tile = $tile; + + $design->setDisposition($on, $off, $tile); $result = $design->update($original); @@ -416,7 +447,8 @@ class DesignsettingsAction extends AccountSettingsAction $design->textcolor = $tcolor->intValue(); $design->linkcolor = $lcolor->intValue(); $design->backgroundimage = $filepath; - $design->tile = $tile; + + $design->setDisposition($on, $off, $tile); $id = $design->insert(); @@ -481,16 +513,4 @@ class DesignsettingsAction extends AccountSettingsAction $this->showForm(_('Design preferences saved.'), true); } - /** - * Reset design settings to previous saved value if any, or - * the defaults - * - * @return void - */ - - function resetDesign() - { - $this->showForm(_('Design preferences reset.'), true); - } - } diff --git a/classes/Design.php b/classes/Design.php index 4ea176677..5b28bf014 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -21,6 +21,10 @@ if (!defined('LACONICA')) { exit(1); } +define('BACKGROUND_ON', 1); +define('BACKGROUND_OFF', 2); +define('BACKGROUND_TILE', 4); + /** * Table Definition for design */ @@ -41,7 +45,7 @@ class Design extends Memcached_DataObject public $textcolor; // int(4) public $linkcolor; // int(4) public $backgroundimage; // varchar(255) - public $tile; // tinyint(1) + public $disposition; // tinyint(1) default_1 /* Static get */ function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Design',$k,$v); } @@ -72,9 +76,11 @@ class Design extends Memcached_DataObject $css .= 'html body { color: #'. $tcolor->hexValue() . '} '. "\n"; $css .= 'a { color: #' . $lcolor->hexValue() . '} ' . "\n"; - if (!empty($this->backgroundimage)) { + if (!empty($this->backgroundimage) && + $this->disposition & BACKGROUND_ON) { - $repeat = ($this->tile) ? 'background-repeat:repeat;' : + $repeat = ($this->disposition & BACKGROUND_TILE) ? + 'background-repeat:repeat;' : 'background-repeat:no-repeat;'; $css .= 'body { background-image:url(' . @@ -125,4 +131,25 @@ class Design extends Memcached_DataObject return 'http://'.$server.$path.$filename; } + function setDisposition($on, $off, $tile) + { + if ($on) { + $this->disposition |= BACKGROUND_ON; + } else { + $this->disposition &= ~BACKGROUND_ON; + } + + if ($off) { + $this->disposition |= BACKGROUND_OFF; + } else { + $this->disposition &= ~BACKGROUND_OFF; + } + + if ($tile) { + $this->disposition |= BACKGROUND_TILE; + } else { + $this->disposition &= ~BACKGROUND_TILE; + } + } + } diff --git a/classes/laconica.ini b/classes/laconica.ini index 569681984..1a650aba5 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -46,7 +46,7 @@ sidebarcolor = 1 textcolor = 1 linkcolor = 1 backgroundimage = 2 -tile = 17 +disposition = 17 [design__keys] id = N diff --git a/db/laconica.sql b/db/laconica.sql index 1f302de16..b018afec8 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -496,7 +496,7 @@ create table design ( textcolor integer comment 'text color', linkcolor integer comment 'link color', backgroundimage varchar(255) comment 'background image, if any', - tile tinyint default 0 comment 'tile background image' + disposition tinyint default 1 comment 'bit 1 = hide background image, bit 2 = display background image, bit 4 = tile background image' ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; create table group_block ( diff --git a/lib/common.php b/lib/common.php index 629fee25b..bcf2e5d0c 100644 --- a/lib/common.php +++ b/lib/common.php @@ -79,7 +79,7 @@ $config = 'textcolor' => '#000000', 'linkcolor' => '#002E6E', 'backgroundimage' => null, - 'tile' => true), + 'disposition' => 1), 'path' => $_path, 'logfile' => null, 'logo' => null, -- cgit v1.2.3-54-g00ecf From 2866d00517b1ccfd7585f5fc2da1ed2fcf52bdfd Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 17 Jun 2009 02:58:35 -0700 Subject: Fix sidebar color bug default design --- actions/designsettings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index 3dfaddd7b..adc09c7b0 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -353,14 +353,14 @@ class DesignsettingsAction extends AccountSettingsAction $design->sidebarcolor = $color->intValue(); $color->parseColor($defaults['textcolor']); - $design->sidebarcolor = $color->intValue(); + $design->textcolor = $color->intValue(); $color->parseColor($defaults['linkcolor']); $design->linkcolor = $color->intValue(); $design->backgroundimage = $defaults['backgroundimage']; - $deisng->disposition = $defaults['disposition']; + $design->disposition = $defaults['disposition']; } catch (WebColorException $e) { common_log(LOG_ERR, _('Bad default color settings: ' . -- cgit v1.2.3-54-g00ecf From ac3cccefb53579b01618d5ef728e883dae752fd2 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 17 Jun 2009 03:02:43 -0700 Subject: Default to image being on, no tile after upload --- actions/designsettings.php | 1 + 1 file changed, 1 insertion(+) (limited to 'actions') diff --git a/actions/designsettings.php b/actions/designsettings.php index adc09c7b0..047059e04 100644 --- a/actions/designsettings.php +++ b/actions/designsettings.php @@ -501,6 +501,7 @@ class DesignsettingsAction extends AccountSettingsAction $original = clone($design); $design->backgroundimage = $filename; + $design->setDisposition(true, false, false); $result = $design->update($original); if ($result === false) { -- cgit v1.2.3-54-g00ecf From 2fbd141361b6ddab0e036b52fc23f2bfcdfd0075 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 17 Jun 2009 08:21:53 -0700 Subject: correct arguments for ProfileList --- actions/featured.php | 5 ++--- actions/peopletag.php | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'actions') diff --git a/actions/featured.php b/actions/featured.php index 79eba2aa6..04365687d 100644 --- a/actions/featured.php +++ b/actions/featured.php @@ -32,7 +32,7 @@ if (!defined('LACONICA')) { exit(1); } -require_once(INSTALLDIR.'/lib/profilelist.php'); +require_once INSTALLDIR.'/lib/profilelist.php'; require_once INSTALLDIR.'/lib/publicgroupnav.php'; /** @@ -107,7 +107,6 @@ class FeaturedAction extends Action $featured_nicks = common_config('nickname', 'featured'); - if (count($featured_nicks) > 0) { $quoted = array(); @@ -136,7 +135,7 @@ class FeaturedAction extends Action $cnt = $profile->find(); if ($cnt > 0) { - $featured = new ProfileList($profile, null, $this); + $featured = new ProfileList($profile, $this); $featured->show(); } diff --git a/actions/peopletag.php b/actions/peopletag.php index 5add75485..dd3c1c089 100644 --- a/actions/peopletag.php +++ b/actions/peopletag.php @@ -124,7 +124,7 @@ class PeopletagAction extends Action $profile->query(sprintf($qry, $this->tag, $lim)); - $pl = new ProfileList($profile, null, $this); + $pl = new ProfileList($profile, $this); $cnt = $pl->show(); $this->pagination($this->page > 1, -- cgit v1.2.3-54-g00ecf From 8992e8fa7a3c694cc9d424b3e50cf4d87519fa28 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 17 Jun 2009 14:34:04 -0700 Subject: Ticket 1612 - make destory (and create) favorites work via API --- actions/twitapifavorites.php | 65 +++++++++++++++++++++++++++++++++++++++----- lib/router.php | 3 +- 2 files changed, 60 insertions(+), 8 deletions(-) (limited to 'actions') diff --git a/actions/twitapifavorites.php b/actions/twitapifavorites.php index 8656adbe8..2266ba11c 100644 --- a/actions/twitapifavorites.php +++ b/actions/twitapifavorites.php @@ -34,6 +34,11 @@ class TwitapifavoritesAction extends TwitterapiAction $user = $this->get_user($apidata['api_arg'], $apidata); if (empty($user)) { + if ($apidata['content-type'] == 'xml') { + $this->show_single_xml_status($notice); + } elseif ($apidata['content-type'] == 'json') { + $this->show_single_json_status($notice); + } $this->clientError('Not Found', 404, $apidata['content-type']); return; } @@ -91,7 +96,6 @@ class TwitapifavoritesAction extends TwitterapiAction // Check for RESTfulness if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) { - // XXX: Twitter just prints the err msg, no XML / JSON. $this->clientError(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']); return; @@ -102,10 +106,9 @@ class TwitapifavoritesAction extends TwitterapiAction return; } - $user = $apidata['user']; // Always the auth user - + $user = $apidata['user']; // Always the auth user $notice_id = $apidata['api_arg']; - $notice = Notice::staticGet($notice_id); + $notice = Notice::staticGet($notice_id); if (empty($notice)) { $this->clientError(_('No status found with that ID.'), @@ -115,7 +118,7 @@ class TwitapifavoritesAction extends TwitterapiAction // XXX: Twitter lets you fave things repeatedly via api. if ($user->hasFave($notice)) { - $this->clientError(_('This notice is already a favorite!'), + $this->clientError(_('This status is already a favorite!'), 403, $apidata['content-type']); return; } @@ -123,7 +126,7 @@ class TwitapifavoritesAction extends TwitterapiAction $fave = Fave::addNew($user, $notice); if (empty($fave)) { - $this->serverError(_('Could not create favorite.')); + $this->clientError(_('Could not create favorite.')); return; } @@ -141,7 +144,55 @@ class TwitapifavoritesAction extends TwitterapiAction function destroy($args, $apidata) { parent::handle($args); - $this->serverError(_('API method under construction.'), $code=501); + + // Check for RESTfulness + if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) { + $this->clientError(_('This method requires a POST or DELETE.'), + 400, $apidata['content-type']); + return; + } + + if (!in_array($apidata['content-type'], array('xml', 'json'))) { + $this->clientError(_('API method not found!'), $code = 404); + return; + } + + $user = $apidata['user']; // Always the auth user + $notice_id = $apidata['api_arg']; + $notice = Notice::staticGet($notice_id); + + if (empty($notice)) { + $this->clientError(_('No status found with that ID.'), + 404, $apidata['content-type']); + return; + } + + $fave = new Fave(); + $fave->user_id = $this->id; + $fave->notice_id = $notice->id; + + if (!$fave->find(true)) { + $this->clientError(_('That status is not a favorite!'), + 403, $apidata['content-type']); + return; + } + + $result = $fave->delete(); + + if (!$result) { + common_log_db_error($fave, 'DELETE', __FILE__); + $this->clientError(_('Could not delete favorite.'), 404); + return; + } + + $user->blowFavesCache(); + + if ($apidata['content-type'] == 'xml') { + $this->show_single_xml_status($notice); + } elseif ($apidata['content-type'] == 'json') { + $this->show_single_json_status($notice); + } + } // XXX: these two funcs swiped from faves. diff --git a/lib/router.php b/lib/router.php index 0fbaba9ed..8b6f63618 100644 --- a/lib/router.php +++ b/lib/router.php @@ -351,7 +351,8 @@ class Router $m->connect('api/favorites/:method/:argument', array('action' => 'api', - 'apiaction' => 'favorites')); + 'apiaction' => 'favorites', + array('method' => '(create|destroy)'))); $m->connect('api/favorites/:argument', array('action' => 'api', -- cgit v1.2.3-54-g00ecf From 07f5797f2fd1a425027190d424e359a1b4c4c8be Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 17 Jun 2009 15:04:57 -0700 Subject: Make the personal tag streams actually work --- actions/showstream.php | 2 +- classes/Notice.php | 6 ++++++ classes/Profile.php | 37 +++++++++++++++++++------------------ 3 files changed, 26 insertions(+), 19 deletions(-) (limited to 'actions') diff --git a/actions/showstream.php b/actions/showstream.php index 72316b259..cd5d4bb70 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -370,7 +370,7 @@ class ShowstreamAction extends ProfileAction { $notice = empty($this->tag) ? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) - : $this->user->getTaggedNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null, $this->tag); + : $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null); $pnl = new ProfileNoticeList($notice, $this); $cnt = $pnl->show(); diff --git a/classes/Notice.php b/classes/Notice.php index 6c5558d88..50242300d 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -375,6 +375,12 @@ class Notice extends Memcached_DataObject if ($tag->find()) { while ($tag->fetch()) { $tag->blowCache($blowLast); + $ck = 'profile:notice_ids_tagged:' . $this->profile_id . ':' . $tag->tag; + + $cache->delete($ck); + if ($blowLast) { + $cache->delete($ck . ';last'); + } } } $tag->free(); diff --git a/classes/Profile.php b/classes/Profile.php index 4a459b974..2f432ae8e 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -153,18 +153,16 @@ class Profile extends Memcached_DataObject return null; } - function getTaggedNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null, $tag=null) + function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null) { - // XXX: I'm not sure this is going to be any faster. It probably isn't. $ids = Notice::stream(array($this, '_streamTaggedDirect'), - array(), - 'profile:notice_ids:' . $this->id, - $offset, $limit, $since_id, $before_id, $since, $tag); - common_debug(print_r($ids, true)); + array($tag), + 'profile:notice_ids_tagged:' . $this->id . ':' . $tag, + $offset, $limit, $since_id, $max_id, $since); return Notice::getStreamByIds($ids); } - function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null) { // XXX: I'm not sure this is going to be any faster. It probably isn't. $ids = Notice::stream(array($this, '_streamDirect'), @@ -175,18 +173,23 @@ class Profile extends Memcached_DataObject return Notice::getStreamByIds($ids); } - function _streamTaggedDirect($offset, $limit, $since_id, $before_id, $since=null, $tag=null) + function _streamTaggedDirect($tag, $offset, $limit, $since_id, $max_id, $since) { - common_debug('_streamTaggedDirect()'); + // XXX It would be nice to do this without a join + $notice = new Notice(); - $notice->profile_id = $this->id; - $query = "select id from notice join notice_tag on id=notice_id where tag='" . $notice->escape($tag) . "' and profile_id=" . $notice->escape($notice->profile_id); + + $query = + "select id from notice join notice_tag on id=notice_id where tag='". + $notice->escape($tag) . + "' and profile_id=" . $notice->escape($this->id); + if ($since_id != 0) { $query .= " and id > $since_id"; } - if ($before_id != 0) { - $query .= " and id < $before_id"; + if ($max_id != 0) { + $query .= " and id < $max_id"; } if (!is_null($since)) { @@ -198,21 +201,19 @@ class Profile extends Memcached_DataObject if (!is_null($offset)) { $query .= " limit $offset, $limit"; } + $notice->query($query); + $ids = array(); while ($notice->fetch()) { - common_debug(print_r($notice, true)); $ids[] = $notice->id; } return $ids; } - - - - function _streamDirect($offset, $limit, $since_id, $before_id, $since = null) + function _streamDirect($offset, $limit, $since_id, $max_id, $since = null) { $notice = new Notice(); -- cgit v1.2.3-54-g00ecf From 06240450ef4818a8a74748ada297d1d55d18b967 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 17 Jun 2009 18:05:12 -0700 Subject: Have user favorites page show user's design --- actions/showfavorites.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actions') diff --git a/actions/showfavorites.php b/actions/showfavorites.php index 865045337..01f38a892 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php'; * @link http://laconi.ca/ */ -class ShowfavoritesAction extends Action +class ShowfavoritesAction extends CurrentUserDesignAction { /** User we're getting the faves of */ var $user = null; -- cgit v1.2.3-54-g00ecf From ba3a484a655f93329463465d224dfc6ae6494434 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 18 Jun 2009 00:12:53 -0700 Subject: order notices in a conversation --- actions/conversation.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actions') diff --git a/actions/conversation.php b/actions/conversation.php index 20c68986c..d3fc5b6a9 100644 --- a/actions/conversation.php +++ b/actions/conversation.php @@ -217,6 +217,8 @@ class ConversationTree extends NoticeList $this->out->elementStart('ol', array('class' => 'notices')); + sort($children); + foreach ($children as $child) { $this->showNoticePlus($child); } -- cgit v1.2.3-54-g00ecf From 57274d21ba554e43c6fcd90555388a60d3de014d Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 18 Jun 2009 02:01:06 -0700 Subject: Group theming. --- actions/blockedfromgroup.php | 2 +- actions/designsettings.php | 517 ------------------------------------------ actions/editgroup.php | 6 +- actions/groupblock.php | 17 +- actions/grouplogo.php | 2 +- actions/groupmembers.php | 2 +- actions/showgroup.php | 5 +- lib/accountsettingsaction.php | 2 +- lib/designsettings.php | 402 ++++++++++++++++++++++++++++++++ lib/groupnav.php | 6 + lib/router.php | 4 +- 11 files changed, 427 insertions(+), 538 deletions(-) delete mode 100644 actions/designsettings.php create mode 100644 lib/designsettings.php (limited to 'actions') diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php index 541ebcfd9..5c1eab354 100644 --- a/actions/blockedfromgroup.php +++ b/actions/blockedfromgroup.php @@ -41,7 +41,7 @@ if (!defined('LACONICA')) { * @link http://laconi.ca/ */ -class BlockedfromgroupAction extends Action +class BlockedfromgroupAction extends GroupDesignAction { var $page = null; diff --git a/actions/designsettings.php b/actions/designsettings.php deleted file mode 100644 index 047059e04..000000000 --- a/actions/designsettings.php +++ /dev/null @@ -1,517 +0,0 @@ -. - * - * @category Settings - * @package Laconica - * @author Sarven Capadisli - * @author Zach Copley - * @copyright 2008-2009 Control Yourself, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ - */ - -if (!defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR . '/lib/accountsettingsaction.php'; -require_once INSTALLDIR . '/lib/webcolor.php'; - -class DesignsettingsAction extends AccountSettingsAction -{ - /** - * Title of the page - * - * @return string Title of the page - */ - - function title() - { - return _('Profile design'); - } - - /** - * Instructions for use - * - * @return instructions for use - */ - - function getInstructions() - { - return _('Customize the way your profile looks ' . - 'with a background image and a colour palette of your choice.'); - } - - /** - * Content area of the page - * - * Shows a form for changing the password - * - * @return void - */ - - function showContent() - { - $user = common_current_user(); - $design = $user->getDesign(); - - if (empty($design)) { - $design = $this->defaultDesign(); - } - - $this->elementStart('form', array('method' => 'post', - 'enctype' => 'multipart/form-data', - 'id' => 'form_settings_design', - 'class' => 'form_settings', - 'action' => - common_local_url('designsettings'))); - $this->elementStart('fieldset'); - $this->hidden('token', common_session_token()); - - $this->elementStart('fieldset', array('id' => - 'settings_design_background-image')); - $this->element('legend', null, _('Change background image')); - $this->elementStart('ul', 'form_data'); - $this->elementStart('li'); - $this->element('label', array('for' => 'design_background-image_file'), - _('Upload file')); - $this->element('input', array('name' => 'design_background-image_file', - 'type' => 'file', - 'id' => 'design_background-image_file')); - $this->element('p', 'form_guide', _('You can upload your personal ' . - 'background image. The maximum file size is 2Mb.')); - $this->element('input', array('name' => 'MAX_FILE_SIZE', - 'type' => 'hidden', - 'id' => 'MAX_FILE_SIZE', - 'value' => ImageFile::maxFileSizeInt())); - $this->elementEnd('li'); - - if (!empty($design->backgroundimage)) { - - $this->elementStart('li', array('id' => 'design_background-image_onoff')); - - $this->element('img', array('src' => - Design::url($design->backgroundimage))); - - $attrs = array('name' => 'design_background-image_onoff', - 'type' => 'radio', - 'id' => 'design_background-image_on', - 'class' => 'radio', - 'value' => 'on'); - - if ($design->disposition & BACKGROUND_ON) { - $attrs['checked'] = 'checked'; - } - - $this->element('input', $attrs); - - $this->element('label', array('for' => 'design_background-image_on', - 'class' => 'radio'), - _('On')); - - $attrs = array('name' => 'design_background-image_onoff', - 'type' => 'radio', - 'id' => 'design_background-image_off', - 'class' => 'radio', - 'value' => 'off'); - - if ($design->disposition & BACKGROUND_OFF) { - $attrs['checked'] = 'checked'; - } - - $this->element('input', $attrs); - - $this->element('label', array('for' => 'design_background-image_off', - 'class' => 'radio'), - _('Off')); - $this->element('p', 'form_guide', _('Turn background image on or off.')); - $this->elementEnd('li'); - } - - $this->elementStart('li'); - $this->checkbox('design_background-image_repeat', - _('Tile background image'), - ($design->disposition & BACKGROUND_TILE) ? true : false ); - $this->elementEnd('li'); - - $this->elementEnd('ul'); - $this->elementEnd('fieldset'); - - $this->elementStart('fieldset', array('id' => 'settings_design_color')); - $this->element('legend', null, _('Change colours')); - $this->elementStart('ul', 'form_data'); - - try { - - $bgcolor = new WebColor($design->backgroundcolor); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-1'), _('Background')); - $this->element('input', array('name' => 'design_background', - 'type' => 'text', - 'id' => 'swatch-1', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => '#' . $bgcolor->hexValue())); - $this->elementEnd('li'); - - $ccolor = new WebColor($design->contentcolor); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-2'), _('Content')); - $this->element('input', array('name' => 'design_content', - 'type' => 'text', - 'id' => 'swatch-2', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => '#' . $ccolor->hexValue())); - $this->elementEnd('li'); - - $sbcolor = new WebColor($design->sidebarcolor); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-3'), _('Sidebar')); - $this->element('input', array('name' => 'design_sidebar', - 'type' => 'text', - 'id' => 'swatch-3', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => '#' . $sbcolor->hexValue())); - $this->elementEnd('li'); - - $tcolor = new WebColor($design->textcolor); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-4'), _('Text')); - $this->element('input', array('name' => 'design_text', - 'type' => 'text', - 'id' => 'swatch-4', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => '#' . $tcolor->hexValue())); - $this->elementEnd('li'); - - $lcolor = new WebColor($design->linkcolor); - - $this->elementStart('li'); - $this->element('label', array('for' => 'swatch-5'), _('Links')); - $this->element('input', array('name' => 'design_links', - 'type' => 'text', - 'id' => 'swatch-5', - 'class' => 'swatch', - 'maxlength' => '7', - 'size' => '7', - 'value' => '#' . $lcolor->hexValue())); - - $this->elementEnd('li'); - - } catch (WebColorException $e) { - common_log(LOG_ERR, 'Bad color values in design ID: ' . - $design->id); - } - - $this->elementEnd('ul'); - $this->elementEnd('fieldset'); - - $this->element('input', array('id' => 'settings_design_reset', - 'type' => 'reset', - 'value' => 'Reset', - 'class' => 'submit form_action-primary', - 'title' => _('Reset back to default'))); - - $this->submit('save', _('Save'), 'submit form_action-secondary', - 'save', _('Save design')); - - $this->elementEnd('fieldset'); - $this->elementEnd('form'); - } - - /** - * Handle a post - * - * Validate input and save changes. Reload the form with a success - * or error message. - * - * @return void - */ - - function handlePost() - { - // XXX: Robin's workaround for a bug in PHP where $_POST - // and $_FILE are empty in the case that the uploaded - // file is bigger than PHP is configured to handle. - - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - if (empty($_POST) && $_SERVER['CONTENT_LENGTH']) { - - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); - - $this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); - } - } - - // CSRF protection - $token = $this->trimmed('token'); - if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. '. - 'Try again, please.')); - return; - } - - if ($this->arg('save')) { - $this->saveDesign(); - } else if ($this->arg('reset')) { - $this->resetDesign(); - } else { - $this->showForm(_('Unexpected form submission.')); - } - } - - /** - * Add the Farbtastic stylesheet - * - * @return void - */ - - function showStylesheets() - { - parent::showStylesheets(); - $farbtasticStyle = - common_path('theme/base/css/farbtastic.css?version='.LACONICA_VERSION); - - $this->element('link', array('rel' => 'stylesheet', - 'type' => 'text/css', - 'href' => $farbtasticStyle, - 'media' => 'screen, projection, tv')); - } - - /** - * Add the Farbtastic scripts - * - * @return void - */ - - function showScripts() - { - parent::showScripts(); - - $farbtasticPack = common_path('js/farbtastic/farbtastic.js'); - $userDesignGo = common_path('js/userdesign.go.js'); - - $this->element('script', array('type' => 'text/javascript', - 'src' => $farbtasticPack)); - $this->element('script', array('type' => 'text/javascript', - 'src' => $userDesignGo)); - } - - /** - * Get a default user design - * - * @return Design design - */ - - function defaultDesign() - { - $defaults = common_config('site', 'design'); - - $design = new Design(); - - try { - - $color = new WebColor(); - - $color->parseColor($defaults['backgroundcolor']); - $design->backgroundcolor = $color->intValue(); - - $color->parseColor($defaults['contentcolor']); - $design->contentcolor = $color->intValue(); - - $color->parseColor($defaults['sidebarcolor']); - $design->sidebarcolor = $color->intValue(); - - $color->parseColor($defaults['textcolor']); - $design->textcolor = $color->intValue(); - - $color->parseColor($defaults['linkcolor']); - $design->linkcolor = $color->intValue(); - - $design->backgroundimage = $defaults['backgroundimage']; - - $design->disposition = $defaults['disposition']; - - } catch (WebColorException $e) { - common_log(LOG_ERR, _('Bad default color settings: ' . - $e->getMessage())); - } - - return $design; - } - - /** - * Save or update the user's design settings - * - * @return void - */ - - function saveDesign() - { - try { - - $bgcolor = new WebColor($this->trimmed('design_background')); - $ccolor = new WebColor($this->trimmed('design_content')); - $sbcolor = new WebColor($this->trimmed('design_sidebar')); - $tcolor = new WebColor($this->trimmed('design_text')); - $lcolor = new WebColor($this->trimmed('design_links')); - - } catch (WebColorException $e) { - $this->showForm($e->getMessage()); - return; - } - - $onoff = $this->arg('design_background-image_onoff'); - - $on = false; - $off = false; - $tile = false; - - if ($onoff == 'on') { - $on = true; - } else { - $off = true; - } - - $repeat = $this->boolean('design_background-image_repeat'); - - if ($repeat) { - $tile = true; - } - - $user = common_current_user(); - $design = $user->getDesign(); - - if (!empty($design)) { - - $original = clone($design); - - $design->backgroundcolor = $bgcolor->intValue(); - $design->contentcolor = $ccolor->intValue(); - $design->sidebarcolor = $sbcolor->intValue(); - $design->textcolor = $tcolor->intValue(); - $design->linkcolor = $lcolor->intValue(); - $design->backgroundimage = $filepath; - - $design->setDisposition($on, $off, $tile); - - $result = $design->update($original); - - if ($result === false) { - common_log_db_error($design, 'UPDATE', __FILE__); - $this->showForm(_('Couldn\'t update your design.')); - return; - } - - // update design - } else { - - $user->query('BEGIN'); - - // save new design - $design = new Design(); - - $design->backgroundcolor = $bgcolor->intValue(); - $design->contentcolor = $ccolor->intValue(); - $design->sidebarcolor = $sbcolor->intValue(); - $design->textcolor = $tcolor->intValue(); - $design->linkcolor = $lcolor->intValue(); - $design->backgroundimage = $filepath; - - $design->setDisposition($on, $off, $tile); - - $id = $design->insert(); - - if (empty($id)) { - common_log_db_error($id, 'INSERT', __FILE__); - $this->showForm(_('Unable to save your design settings!')); - return; - } - - $original = clone($user); - $user->design_id = $id; - $result = $user->update($original); - - if (empty($result)) { - common_log_db_error($original, 'UPDATE', __FILE__); - $this->showForm(_('Unable to save your design settings!')); - $user->query('ROLLBACK'); - return; - } - - $user->query('COMMIT'); - - } - - // Now that we have a Design ID we can add a file to the design. - // XXX: This is an additional DB hit, but figured having the image - // associated with the Design rather than the User was worth - // it. -- Zach - - if ($_FILES['design_background-image_file']['error'] == - UPLOAD_ERR_OK) { - - $filepath = null; - - try { - $imagefile = - ImageFile::fromUpload('design_background-image_file'); - } catch (Exception $e) { - $this->showForm($e->getMessage()); - return; - } - - $filename = Design::filename($design->id, - image_type_to_extension($imagefile->type), - common_timestamp()); - - $filepath = Design::path($filename); - - move_uploaded_file($imagefile->filepath, $filepath); - - $original = clone($design); - $design->backgroundimage = $filename; - $design->setDisposition(true, false, false); - $result = $design->update($original); - - if ($result === false) { - common_log_db_error($design, 'UPDATE', __FILE__); - $this->showForm(_('Couldn\'t update your design.')); - return; - } - } - - $this->showForm(_('Design preferences saved.'), true); - } - -} diff --git a/actions/editgroup.php b/actions/editgroup.php index 29a7bce43..6aa6f8b11 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -23,6 +23,7 @@ * @package Laconica * @author Evan Prodromou * @author Sarven Capadisli + * @author Zach Copley * @copyright 2008-2009 Control Yourself, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://laconi.ca/ @@ -40,14 +41,15 @@ if (!defined('LACONICA')) { * @category Group * @package Laconica * @author Evan Prodromou + * @author Zach Copley * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://laconi.ca/ */ -class EditgroupAction extends Action +class EditgroupAction extends GroupDesignAction { + var $msg; - var $group = null; function title() { diff --git a/actions/groupblock.php b/actions/groupblock.php index 28685b1d5..93662da79 100644 --- a/actions/groupblock.php +++ b/actions/groupblock.php @@ -151,19 +151,17 @@ class GroupblockAction extends Action function areYouSureForm() { $id = $this->profile->id; - $this->elementStart('form', array('id' => 'block-' . $id, - 'method' => 'post', - 'class' => 'form_settings form_entity_block', - 'action' => common_local_url('groupblock'))); - $this->elementStart('fieldset'); - $this->hidden('token', common_session_token()); - $this->element('legend', null, _('Block user')); $this->element('p', null, sprintf(_('Are you sure you want to block user "%s" from the group "%s"? '. 'They will be removed from the group, unable to post, and '. 'unable to subscribe to the group in the future.'), $this->profile->getBestName(), $this->group->getBestName())); + $this->elementStart('form', array('id' => 'block-' . $id, + 'method' => 'post', + 'class' => 'block', + 'action' => common_local_url('groupblock'))); + $this->hidden('token', common_session_token()); $this->hidden('blockto-' . $this->profile->id, $this->profile->id, 'blockto'); @@ -175,9 +173,8 @@ class GroupblockAction extends Action $this->hidden($k, $v); } } - $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group")); - $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group')); - $this->elementEnd('fieldset'); + $this->submit('no', _('No')); + $this->submit('yes', _('Yes')); $this->elementEnd('form'); } diff --git a/actions/grouplogo.php b/actions/grouplogo.php index fe6127da2..8f6158dac 100644 --- a/actions/grouplogo.php +++ b/actions/grouplogo.php @@ -50,7 +50,7 @@ define('MAX_ORIGINAL', 480); * @link http://laconi.ca/ */ -class GrouplogoAction extends Action +class GrouplogoAction extends GroupDesignAction { var $mode = null; var $imagefile = null; diff --git a/actions/groupmembers.php b/actions/groupmembers.php index abfad3f0d..d132cdf96 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -44,7 +44,7 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php'; * @link http://laconi.ca/ */ -class GroupmembersAction extends Action +class GroupmembersAction extends GroupDesignAction { var $page = null; diff --git a/actions/showgroup.php b/actions/showgroup.php index 357f579d8..b6a0f4844 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -47,10 +47,9 @@ define('MEMBERS_PER_SECTION', 27); * @link http://laconi.ca/ */ -class ShowgroupAction extends Action +class ShowgroupAction extends GroupDesignAction { - /** group we're viewing. */ - var $group = null; + /** page we're viewing. */ var $page = null; diff --git a/lib/accountsettingsaction.php b/lib/accountsettingsaction.php index 86800d2a3..4ab50abce 100644 --- a/lib/accountsettingsaction.php +++ b/lib/accountsettingsaction.php @@ -115,7 +115,7 @@ class AccountSettingsNav extends Widget 'openidsettings' => array(_('OpenID'), _('Add or remove OpenIDs')), - 'designsettings' => + 'userdesignsettings' => array(_('Design'), _('Design your profile')), 'othersettings' => diff --git a/lib/designsettings.php b/lib/designsettings.php new file mode 100644 index 000000000..6aa6bb2f1 --- /dev/null +++ b/lib/designsettings.php @@ -0,0 +1,402 @@ +. + * + * @category Settings + * @package Laconica + * @author Sarven Capadisli + * @author Zach Copley + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/accountsettingsaction.php'; +require_once INSTALLDIR . '/lib/webcolor.php'; + +class DesignSettingsAction extends AccountSettingsAction +{ + + var $submitaction = null; + + /** + * Title of the page + * + * @return string Title of the page + */ + + function title() + { + return _('Profile design'); + } + + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() + { + return _('Customize the way your profile looks ' . + 'with a background image and a colour palette of your choice.'); + } + + function showDesignForm($design) + { + + $this->elementStart('form', array('method' => 'post', + 'enctype' => 'multipart/form-data', + 'id' => 'form_settings_design', + 'class' => 'form_settings', + 'action' => $this->submitaction)); + $this->elementStart('fieldset'); + $this->hidden('token', common_session_token()); + + $this->elementStart('fieldset', array('id' => + 'settings_design_background-image')); + $this->element('legend', null, _('Change background image')); + $this->elementStart('ul', 'form_data'); + $this->elementStart('li'); + $this->element('label', array('for' => 'design_background-image_file'), + _('Upload file')); + $this->element('input', array('name' => 'design_background-image_file', + 'type' => 'file', + 'id' => 'design_background-image_file')); + $this->element('p', 'form_guide', _('You can upload your personal ' . + 'background image. The maximum file size is 2Mb.')); + $this->element('input', array('name' => 'MAX_FILE_SIZE', + 'type' => 'hidden', + 'id' => 'MAX_FILE_SIZE', + 'value' => ImageFile::maxFileSizeInt())); + $this->elementEnd('li'); + + if (!empty($design->backgroundimage)) { + + $this->elementStart('li', array('id' => 'design_background-image_onoff')); + + $this->element('img', array('src' => + Design::url($design->backgroundimage))); + + $attrs = array('name' => 'design_background-image_onoff', + 'type' => 'radio', + 'id' => 'design_background-image_on', + 'class' => 'radio', + 'value' => 'on'); + + if ($design->disposition & BACKGROUND_ON) { + $attrs['checked'] = 'checked'; + } + + $this->element('input', $attrs); + + $this->element('label', array('for' => 'design_background-image_on', + 'class' => 'radio'), + _('On')); + + $attrs = array('name' => 'design_background-image_onoff', + 'type' => 'radio', + 'id' => 'design_background-image_off', + 'class' => 'radio', + 'value' => 'off'); + + if ($design->disposition & BACKGROUND_OFF) { + $attrs['checked'] = 'checked'; + } + + $this->element('input', $attrs); + + $this->element('label', array('for' => 'design_background-image_off', + 'class' => 'radio'), + _('Off')); + $this->element('p', 'form_guide', _('Turn background image on or off.')); + $this->elementEnd('li'); + } + + $this->elementStart('li'); + $this->checkbox('design_background-image_repeat', + _('Tile background image'), + ($design->disposition & BACKGROUND_TILE) ? true : false ); + $this->elementEnd('li'); + + $this->elementEnd('ul'); + $this->elementEnd('fieldset'); + + $this->elementStart('fieldset', array('id' => 'settings_design_color')); + $this->element('legend', null, _('Change colours')); + $this->elementStart('ul', 'form_data'); + + try { + + $bgcolor = new WebColor($design->backgroundcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-1'), _('Background')); + $this->element('input', array('name' => 'design_background', + 'type' => 'text', + 'id' => 'swatch-1', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $bgcolor->hexValue())); + $this->elementEnd('li'); + + $ccolor = new WebColor($design->contentcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-2'), _('Content')); + $this->element('input', array('name' => 'design_content', + 'type' => 'text', + 'id' => 'swatch-2', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $ccolor->hexValue())); + $this->elementEnd('li'); + + $sbcolor = new WebColor($design->sidebarcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-3'), _('Sidebar')); + $this->element('input', array('name' => 'design_sidebar', + 'type' => 'text', + 'id' => 'swatch-3', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $sbcolor->hexValue())); + $this->elementEnd('li'); + + $tcolor = new WebColor($design->textcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-4'), _('Text')); + $this->element('input', array('name' => 'design_text', + 'type' => 'text', + 'id' => 'swatch-4', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $tcolor->hexValue())); + $this->elementEnd('li'); + + $lcolor = new WebColor($design->linkcolor); + + $this->elementStart('li'); + $this->element('label', array('for' => 'swatch-5'), _('Links')); + $this->element('input', array('name' => 'design_links', + 'type' => 'text', + 'id' => 'swatch-5', + 'class' => 'swatch', + 'maxlength' => '7', + 'size' => '7', + 'value' => '#' . $lcolor->hexValue())); + + $this->elementEnd('li'); + + } catch (WebColorException $e) { + common_log(LOG_ERR, 'Bad color values in design ID: ' . + $design->id); + } + + $this->elementEnd('ul'); + $this->elementEnd('fieldset'); + + $this->element('input', array('id' => 'settings_design_reset', + 'type' => 'reset', + 'value' => 'Reset', + 'class' => 'submit form_action-primary', + 'title' => _('Reset back to default'))); + + $this->submit('save', _('Save'), 'submit form_action-secondary', + 'save', _('Save design')); + + $this->elementEnd('fieldset'); + $this->elementEnd('form'); + } + + /** + * Handle a post + * + * Validate input and save changes. Reload the form with a success + * or error message. + * + * @return void + */ + + function handlePost() + { + // XXX: Robin's workaround for a bug in PHP where $_POST + // and $_FILE are empty in the case that the uploaded + // file is bigger than PHP is configured to handle. + + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + if (empty($_POST) && $_SERVER['CONTENT_LENGTH']) { + + $msg = _('The server was unable to handle that much POST ' . + 'data (%s bytes) due to its current configuration.'); + + $this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); + } + } + + // CSRF protection + $token = $this->trimmed('token'); + if (!$token || $token != common_session_token()) { + $this->showForm(_('There was a problem with your session token. '. + 'Try again, please.')); + return; + } + + if ($this->arg('save')) { + $this->saveDesign(); + } else if ($this->arg('reset')) { + $this->resetDesign(); + } else { + $this->showForm(_('Unexpected form submission.')); + } + } + + /** + * Add the Farbtastic stylesheet + * + * @return void + */ + + function showStylesheets() + { + parent::showStylesheets(); + $farbtasticStyle = + common_path('theme/base/css/farbtastic.css?version='.LACONICA_VERSION); + + $this->element('link', array('rel' => 'stylesheet', + 'type' => 'text/css', + 'href' => $farbtasticStyle, + 'media' => 'screen, projection, tv')); + } + + /** + * Add the Farbtastic scripts + * + * @return void + */ + + function showScripts() + { + parent::showScripts(); + + $farbtasticPack = common_path('js/farbtastic/farbtastic.js'); + $userDesignGo = common_path('js/userdesign.go.js'); + + $this->element('script', array('type' => 'text/javascript', + 'src' => $farbtasticPack)); + $this->element('script', array('type' => 'text/javascript', + 'src' => $userDesignGo)); + } + + /** + * Get a default user design + * + * @return Design design + */ + + function defaultDesign() + { + $defaults = common_config('site', 'design'); + + $design = new Design(); + + try { + + $color = new WebColor(); + + $color->parseColor($defaults['backgroundcolor']); + $design->backgroundcolor = $color->intValue(); + + $color->parseColor($defaults['contentcolor']); + $design->contentcolor = $color->intValue(); + + $color->parseColor($defaults['sidebarcolor']); + $design->sidebarcolor = $color->intValue(); + + $color->parseColor($defaults['textcolor']); + $design->textcolor = $color->intValue(); + + $color->parseColor($defaults['linkcolor']); + $design->linkcolor = $color->intValue(); + + $design->backgroundimage = $defaults['backgroundimage']; + + $design->disposition = $defaults['disposition']; + + } catch (WebColorException $e) { + common_log(LOG_ERR, _('Bad default color settings: ' . + $e->getMessage())); + } + + return $design; + } + + function saveBackgroundImage($design) { + + // Now that we have a Design ID we can add a file to the design. + // XXX: This is an additional DB hit, but figured having the image + // associated with the Design rather than the User was worth + // it. -- Zach + + if ($_FILES['design_background-image_file']['error'] == + UPLOAD_ERR_OK) { + + $filepath = null; + + try { + $imagefile = + ImageFile::fromUpload('design_background-image_file'); + } catch (Exception $e) { + $this->showForm($e->getMessage()); + return; + } + + $filename = Design::filename($design->id, + image_type_to_extension($imagefile->type), + common_timestamp()); + + $filepath = Design::path($filename); + + move_uploaded_file($imagefile->filepath, $filepath); + + $original = clone($design); + $design->backgroundimage = $filename; + $design->setDisposition(true, false, false); + $result = $design->update($original); + + if ($result === false) { + common_log_db_error($design, 'UPDATE', __FILE__); + $this->showForm(_('Couldn\'t update your design.')); + return; + } + } + } + +} diff --git a/lib/groupnav.php b/lib/groupnav.php index 194247982..9e530c447 100644 --- a/lib/groupnav.php +++ b/lib/groupnav.php @@ -113,6 +113,12 @@ class GroupNav extends Widget sprintf(_('Add or edit %s logo'), $nickname), $action_name == 'grouplogo', 'nav_group_logo'); + $this->out->menuItem(common_local_url('groupdesignsettings', array('nickname' => + $nickname)), + _('Design'), + sprintf(_('Add or edit %s design'), $nickname), + $action_name == 'groupdesignsettings', + 'nav_group_design'); } $this->out->elementEnd('ul'); } diff --git a/lib/router.php b/lib/router.php index 8b6f63618..1f39c60dc 100644 --- a/lib/router.php +++ b/lib/router.php @@ -132,7 +132,7 @@ class Router // settings foreach (array('profile', 'avatar', 'password', 'openid', 'im', - 'email', 'sms', 'twitter', 'design', 'other') as $s) { + 'email', 'sms', 'twitter', 'userdesign', 'other') as $s) { $m->connect('settings/'.$s, array('action' => $s.'settings')); } @@ -223,7 +223,7 @@ class Router array('nickname' => '[a-zA-Z0-9]+')); } - foreach (array('members', 'logo', 'rss') as $n) { + foreach (array('members', 'logo', 'rss', 'designsettings') as $n) { $m->connect('group/:nickname/'.$n, array('action' => 'group'.$n), array('nickname' => '[a-zA-Z0-9]+')); -- cgit v1.2.3-54-g00ecf From 3f032bc36e2c624a895c584479c8f423e62bba73 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 18 Jun 2009 02:16:39 -0700 Subject: Left out some new user and group theming file in the previous commit --- actions/groupdesignsettings.php | 330 ++++++++++++++++++++++++++++++++++++++++ actions/userdesignsettings.php | 208 +++++++++++++++++++++++++ lib/groupdesignaction.php | 87 +++++++++++ 3 files changed, 625 insertions(+) create mode 100644 actions/groupdesignsettings.php create mode 100644 actions/userdesignsettings.php create mode 100644 lib/groupdesignaction.php (limited to 'actions') diff --git a/actions/groupdesignsettings.php b/actions/groupdesignsettings.php new file mode 100644 index 000000000..7270bc8f7 --- /dev/null +++ b/actions/groupdesignsettings.php @@ -0,0 +1,330 @@ +. + * + * @category Settings + * @package Laconica + * @author Sarven Capadisli + * @author Zach Copley + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/designsettings.php'; + +class GroupDesignSettingsAction extends DesignSettingsAction +{ + var $group = null; + + /** + * Prepare to run + */ + + function prepare($args) + { + parent::prepare($args); + + if (!common_config('inboxes','enabled')) { + $this->serverError(_('Inboxes must be enabled for groups to work')); + return false; + } + + if (!common_logged_in()) { + $this->clientError(_('You must be logged in to edit a group.')); + return false; + } + + $nickname_arg = $this->trimmed('nickname'); + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + $args = array('nickname' => $nickname); + common_redirect(common_local_url('groupdesignsettings', $args), 301); + return false; + } + + if (!$nickname) { + $this->clientError(_('No nickname'), 404); + return false; + } + + $groupid = $this->trimmed('groupid'); + + if ($groupid) { + $this->group = User_group::staticGet('id', $groupid); + } else { + $this->group = User_group::staticGet('nickname', $nickname); + } + + if (!$this->group) { + $this->clientError(_('No such group'), 404); + return false; + } + + $cur = common_current_user(); + + if (!$cur->isAdmin($this->group)) { + $this->clientError(_('You must be an admin to edit the group'), 403); + return false; + } + + $this->submitaction = common_local_url('groupdesignsettings', + array('nickname' => $this->group->nickname)); + + return true; + } + + /** + * A design for this action + * + * if the group attribute has been set, returns that group's + * design. + * + * @return Design a design object to use + */ + + function getDesign() + { + + if (empty($this->group)) { + return null; + } + + return $this->group->getDesign(); + } + + /** + * Title of the page + * + * @return string Title of the page + */ + + function title() + { + return _('Group design'); + } + + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() + { + return _('Customize the way your group looks ' . + 'with a background image and a colour palette of your choice.'); + } + + /** + * Override to show group nav stuff + * + * @return nothing + */ + + function showLocalNav() + { + $nav = new GroupNav($this, $this->group); + $nav->show(); + } + + /** + * Get the design we want to edit + * + * @return Design + */ + + function getWorkingDesign() { + + $design = null; + + if (isset($this->group)) { + $design = $this->group->getDesign(); + } + + if (empty($design)) { + $design = $this->defaultDesign(); + } + + return $design; + } + + /** + * Content area of the page + * + * Shows a form for changing the design + * + * @return void + */ + + function showContent() + { + $this->showDesignForm($this->getWorkingDesign()); + } + + /** + * Save or update the group's design settings + * + * @return void + */ + + function saveDesign() + { + try { + + $bgcolor = new WebColor($this->trimmed('design_background')); + $ccolor = new WebColor($this->trimmed('design_content')); + $sbcolor = new WebColor($this->trimmed('design_sidebar')); + $tcolor = new WebColor($this->trimmed('design_text')); + $lcolor = new WebColor($this->trimmed('design_links')); + + } catch (WebColorException $e) { + $this->showForm($e->getMessage()); + return; + } + + $onoff = $this->arg('design_background-image_onoff'); + + $on = false; + $off = false; + $tile = false; + + if ($onoff == 'on') { + $on = true; + } else { + $off = true; + } + + $repeat = $this->boolean('design_background-image_repeat'); + + if ($repeat) { + $tile = true; + } + + $design = $this->group->getDesign(); + + if (!empty($design)) { + + // update design + + $original = clone($design); + + $design->backgroundcolor = $bgcolor->intValue(); + $design->contentcolor = $ccolor->intValue(); + $design->sidebarcolor = $sbcolor->intValue(); + $design->textcolor = $tcolor->intValue(); + $design->linkcolor = $lcolor->intValue(); + $design->backgroundimage = $filepath; + + $design->setDisposition($on, $off, $tile); + + $result = $design->update($original); + + if ($result === false) { + common_log_db_error($design, 'UPDATE', __FILE__); + $this->showForm(_('Couldn\'t update your design.')); + return; + } + + } else { + + $this->group->query('BEGIN'); + + // save new design + + $design = new Design(); + + $design->backgroundcolor = $bgcolor->intValue(); + $design->contentcolor = $ccolor->intValue(); + $design->sidebarcolor = $sbcolor->intValue(); + $design->textcolor = $tcolor->intValue(); + $design->linkcolor = $lcolor->intValue(); + $design->backgroundimage = $filepath; + + $design->setDisposition($on, $off, $tile); + + $id = $design->insert(); + + if (empty($id)) { + common_log_db_error($id, 'INSERT', __FILE__); + $this->showForm(_('Unable to save your design settings!')); + return; + } + + $original = clone($this->group); + $this->group->design_id = $id; + $result = $this->group->update($original); + + if (empty($result)) { + common_log_db_error($original, 'UPDATE', __FILE__); + $this->showForm(_('Unable to save your design settings!')); + $this->group->query('ROLLBACK'); + return; + } + + $this->group->query('COMMIT'); + + } + + $this->saveBackgroundImage($design); + + $this->showForm(_('Design preferences saved.'), true); + } + + /** + * Handle input and output a page (overrided) + * + * @param array $args $_REQUEST arguments + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + if (!common_logged_in()) { + $this->clientError(_('Not logged in.')); + return; + } else if (!common_is_real_login()) { + // Cookie theft means that automatic logins can't + // change important settings or see private info, and + // _all_ our settings are important + common_set_returnto($this->selfUrl()); + $user = common_current_user(); + if ($user->hasOpenID()) { + common_redirect(common_local_url('openidlogin'), 303); + } else { + common_redirect(common_local_url('login'), 303); + } + } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $this->handlePost(); + } else { + $this->showForm(); + } + } + +} diff --git a/actions/userdesignsettings.php b/actions/userdesignsettings.php new file mode 100644 index 000000000..d6088aa9d --- /dev/null +++ b/actions/userdesignsettings.php @@ -0,0 +1,208 @@ +. + * + * @category Settings + * @package Laconica + * @author Sarven Capadisli + * @author Zach Copley + * @copyright 2008-2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/designsettings.php'; + +class UserDesignSettingsAction extends DesignSettingsAction +{ + + function prepare($args) + { + parent::prepare($args); + $this->submitaction = common_local_url('userdesignsettings'); + return true; + } + + /** + * Title of the page + * + * @return string Title of the page + */ + + function title() + { + return _('Profile design'); + } + + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() + { + return _('Customize the way your profile looks ' . + 'with a background image and a colour palette of your choice.'); + } + + /** + * Get the design we want to edit + * + * @return Design + */ + + function getWorkingDesign() { + + $user = common_current_user(); + $design = $user->getDesign(); + + if (empty($design)) { + $design = $this->defaultDesign(); + } + + return $design; + } + + /** + * Content area of the page + * + * Shows a form for changing the design + * + * @return void + */ + + function showContent() + { + $this->showDesignForm($this->getWorkingDesign()); + } + + /** + * Save or update the user's design settings + * + * @return void + */ + + function saveDesign() + { + try { + + $bgcolor = new WebColor($this->trimmed('design_background')); + $ccolor = new WebColor($this->trimmed('design_content')); + $sbcolor = new WebColor($this->trimmed('design_sidebar')); + $tcolor = new WebColor($this->trimmed('design_text')); + $lcolor = new WebColor($this->trimmed('design_links')); + + } catch (WebColorException $e) { + $this->showForm($e->getMessage()); + return; + } + + $onoff = $this->arg('design_background-image_onoff'); + + $on = false; + $off = false; + $tile = false; + + if ($onoff == 'on') { + $on = true; + } else { + $off = true; + } + + $repeat = $this->boolean('design_background-image_repeat'); + + if ($repeat) { + $tile = true; + } + + $user = common_current_user(); + $design = $user->getDesign(); + + if (!empty($design)) { + + $original = clone($design); + + $design->backgroundcolor = $bgcolor->intValue(); + $design->contentcolor = $ccolor->intValue(); + $design->sidebarcolor = $sbcolor->intValue(); + $design->textcolor = $tcolor->intValue(); + $design->linkcolor = $lcolor->intValue(); + $design->backgroundimage = $filepath; + + $design->setDisposition($on, $off, $tile); + + $result = $design->update($original); + + if ($result === false) { + common_log_db_error($design, 'UPDATE', __FILE__); + $this->showForm(_('Couldn\'t update your design.')); + return; + } + + // update design + } else { + + $user->query('BEGIN'); + + // save new design + $design = new Design(); + + $design->backgroundcolor = $bgcolor->intValue(); + $design->contentcolor = $ccolor->intValue(); + $design->sidebarcolor = $sbcolor->intValue(); + $design->textcolor = $tcolor->intValue(); + $design->linkcolor = $lcolor->intValue(); + $design->backgroundimage = $filepath; + + $design->setDisposition($on, $off, $tile); + + $id = $design->insert(); + + if (empty($id)) { + common_log_db_error($id, 'INSERT', __FILE__); + $this->showForm(_('Unable to save your design settings!')); + return; + } + + $original = clone($user); + $user->design_id = $id; + $result = $user->update($original); + + if (empty($result)) { + common_log_db_error($original, 'UPDATE', __FILE__); + $this->showForm(_('Unable to save your design settings!')); + $user->query('ROLLBACK'); + return; + } + + $user->query('COMMIT'); + + } + + $this->saveBackgroundImage($design); + + $this->showForm(_('Design preferences saved.'), true); + } +} diff --git a/lib/groupdesignaction.php b/lib/groupdesignaction.php new file mode 100644 index 000000000..bc95921f1 --- /dev/null +++ b/lib/groupdesignaction.php @@ -0,0 +1,87 @@ +. + * + * @category Action + * @package Laconica + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Base class for actions that use a group's design + * + * Pages related to groups can be themed with a design. + * This superclass returns that design. + * + * @category Action + * @package Laconica + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + */ +class GroupDesignAction extends Action { + + /** The group in question */ + var $group = null; + + /** + * Show the groups's design stylesheet + * + * @return nothing + */ + function showStylesheets() + { + parent::showStylesheets(); + + $design = $this->getDesign(); + + if (!empty($design)) { + $design->showCSS($this); + } + } + + /** + * A design for this action + * + * if the group attribute has been set, returns that group's + * design. + * + * @return Design a design object to use + */ + + function getDesign() + { + + if (empty($this->group)) { + return null; + } + + return $this->group->getDesign(); + } + +} -- cgit v1.2.3-54-g00ecf From 3f54840b51d5565fdeb7057661ff730bc0e41833 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 18 Jun 2009 11:45:48 -0700 Subject: Only show twitter msgs in your own inbox --- actions/all.php | 8 ++++++- actions/allrss.php | 8 +++++++ actions/facebookhome.php | 58 ++++++++++++++++++++++-------------------------- classes/Notice.php | 2 ++ classes/Notice_inbox.php | 13 +++++++---- classes/User.php | 29 +++++++++++++++++++++++- 6 files changed, 81 insertions(+), 37 deletions(-) (limited to 'actions') diff --git a/actions/all.php b/actions/all.php index 03179a246..80fc9d54b 100644 --- a/actions/all.php +++ b/actions/all.php @@ -98,7 +98,13 @@ class AllAction extends ProfileAction function showContent() { - $notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + $cur = common_current_user(); + + if (!empty($cur) && $cur->id == $this->user->id) { + $notice = $this->user->noticeInbox(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + } else { + $notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + } $nl = new NoticeList($notice, $this); diff --git a/actions/allrss.php b/actions/allrss.php index 45f3946a6..88a4745c9 100644 --- a/actions/allrss.php +++ b/actions/allrss.php @@ -81,6 +81,14 @@ class AllrssAction extends Rss10Action */ function getNotices($limit=0) { + $cur = common_current_user(); + + if (!empty($cur) && $cur->id == $user->id) { + $notice = $this->user->noticeInbox(0, $limit); + } else { + $notice = $this->user->noticesWithFriends(0, $limit); + } + $user = $this->user; $notice = $user->noticesWithFriends(0, $limit); $notices = array(); diff --git a/actions/facebookhome.php b/actions/facebookhome.php index 00b35ef68..f74b786d1 100644 --- a/actions/facebookhome.php +++ b/actions/facebookhome.php @@ -21,29 +21,28 @@ if (!defined('LACONICA')) { exit(1); } require_once INSTALLDIR.'/lib/facebookaction.php'; - class FacebookhomeAction extends FacebookAction { var $page = null; - + function prepare($argarray) - { + { parent::prepare($argarray); - + $this->page = $this->trimmed('page'); - + if (!$this->page) { $this->page = 1; } - + return true; } function handle($args) { - parent::handle($args); - + parent::handle($args); + // If the user has opted not to initially allow the app to have // Facebook status update permission, store that preference. Only // promt the user the first time she uses the app @@ -73,7 +72,7 @@ class FacebookhomeAction extends FacebookAction $this->updateProfileBox($notice); } - if ($this->arg('status_submit') == 'Send') { + if ($this->arg('status_submit') == 'Send') { $this->saveNewNotice(); } @@ -81,7 +80,7 @@ class FacebookhomeAction extends FacebookAction // Facebook status update permission? Then show the main page // of the app $this->showPage(); - + } else { // User hasn't authenticated yet, prompt for creds @@ -89,12 +88,12 @@ class FacebookhomeAction extends FacebookAction } } - + function login() { - + $this->showStylesheets(); - + $nickname = common_canonical_nickname($this->trimmed('nickname')); $password = $this->arg('password'); @@ -141,13 +140,12 @@ class FacebookhomeAction extends FacebookAction $this->facebook->api_client->data_setUserPreference( FACEBOOK_PROMPTED_UPDATE_PREF, 'false'); } - function showNoticeForm() { $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); $notice_form->show(); } @@ -163,9 +161,8 @@ class FacebookhomeAction extends FacebookAction function showContent() { - $notice = $this->user->noticesWithFriends(($this->page-1) * - NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); - + $notice = $this->user->noticeInbox(($this->page-1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); + $nl = new NoticeList($notice, $this); $cnt = $nl->show(); @@ -176,7 +173,7 @@ class FacebookhomeAction extends FacebookAction function showNoticeList($notice) { - + $nl = new NoticeList($notice, $this); return $nl->show(); } @@ -201,16 +198,16 @@ class FacebookhomeAction extends FacebookAction $this->elementStart('ul', array('id' => 'fb-permissions-list')); $this->elementStart('li', array('id' => 'fb-permissions-item')); - + $next = urlencode("$this->app_uri/index.php"); $api_key = common_config('facebook', 'apikey'); - + $auth_url = 'http://www.facebook.com/authorize.php?api_key=' . - $api_key . '&v=1.0&ext_perm=status_update&next=' . $next . + $api_key . '&v=1.0&ext_perm=status_update&next=' . $next . '&next_cancel=' . $next . '&submit=skip'; - + $this->elementStart('span', array('class' => 'facebook-button')); - $this->element('a', array('href' => $auth_url), + $this->element('a', array('href' => $auth_url), sprintf(_('Okay, do it!'), $this->app_name)); $this->elementEnd('span'); @@ -225,7 +222,7 @@ class FacebookhomeAction extends FacebookAction $this->elementEnd('div'); } - + /** * Generate pagination links * @@ -239,11 +236,11 @@ class FacebookhomeAction extends FacebookAction */ function pagination($have_before, $have_after, $page, $action, $args=null) { - + // Does a little before-after block for next/prev page - + // XXX: Fix so this uses common_local_url() if possible. - + if ($have_before || $have_after) { $this->elementStart('div', array('class' => 'pagination')); $this->elementStart('dl', null); @@ -254,7 +251,7 @@ class FacebookhomeAction extends FacebookAction if ($have_before) { $pargs = array('page' => $page-1); $newargs = $args ? array_merge($args, $pargs) : $pargs; - $this->elementStart('li', array('class' => 'nav_prev')); + $this->elementStart('li', array('class' => 'nav_prev')); $this->element('a', array('href' => "$action?page=$newargs[page]", 'rel' => 'prev'), _('After')); $this->elementEnd('li'); @@ -274,6 +271,5 @@ class FacebookhomeAction extends FacebookAction $this->elementEnd('div'); } } - } diff --git a/classes/Notice.php b/classes/Notice.php index e621805df..93a1a1a4d 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -406,8 +406,10 @@ class Notice extends Memcached_DataObject while ($user->fetch()) { $cache->delete(common_cache_key('notice_inbox:by_user:'.$user->id)); + $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$user->id)); if ($blowLast) { $cache->delete(common_cache_key('notice_inbox:by_user:'.$user->id.';last')); + $cache->delete(common_cache_key('notice_inbox:by_user_own:'.$user->id.';last')); } } $user->free(); diff --git a/classes/Notice_inbox.php b/classes/Notice_inbox.php index 367a35f1f..4ca2e9ae3 100644 --- a/classes/Notice_inbox.php +++ b/classes/Notice_inbox.php @@ -47,20 +47,25 @@ class Notice_inbox extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - function stream($user_id, $offset, $limit, $since_id, $max_id, $since) + function stream($user_id, $offset, $limit, $since_id, $max_id, $since, $own=false) { return Notice::stream(array('Notice_inbox', '_streamDirect'), - array($user_id), - 'notice_inbox:by_user:'.$user_id, + array($user_id, $own), + ($own) ? 'notice_inbox:by_user:'.$user_id : + 'notice_inbox:by_user_own:'.$user_id, $offset, $limit, $since_id, $max_id, $since); } - function _streamDirect($user_id, $offset, $limit, $since_id, $max_id, $since) + function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id, $since) { $inbox = new Notice_inbox(); $inbox->user_id = $user_id; + if (!$own) { + $inbox->whereAdd('source != ' . NOTICE_INBOX_SOURCE_GATEWAY); + } + if ($since_id != 0) { $inbox->whereAdd('notice_id > ' . $since_id); } diff --git a/classes/User.php b/classes/User.php index c7eede94e..e8c8c5a75 100644 --- a/classes/User.php +++ b/classes/User.php @@ -437,6 +437,33 @@ class User extends Memcached_DataObject // Complicated code, depending on whether we support inboxes yet // XXX: make this go away when inboxes become mandatory + if ($enabled === false || + ($enabled == 'transitional' && $this->inboxed == 0)) { + $qry = + 'SELECT notice.* ' . + 'FROM notice JOIN subscription ON notice.profile_id = subscription.subscribed ' . + 'WHERE subscription.subscriber = %d ' . + 'AND notice.is_local != ' . NOTICE_GATEWAY; + return Notice::getStream(sprintf($qry, $this->id), + 'user:notices_with_friends:' . $this->id, + $offset, $limit, $since_id, $before_id, + $order, $since); + } else if ($enabled === true || + ($enabled == 'transitional' && $this->inboxed == 1)) { + + $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); + + return Notice::getStreamByIds($ids); + } + } + + function noticeInbox($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) + { + $enabled = common_config('inboxes', 'enabled'); + + // Complicated code, depending on whether we support inboxes yet + // XXX: make this go away when inboxes become mandatory + if ($enabled === false || ($enabled == 'transitional' && $this->inboxed == 0)) { $qry = @@ -450,7 +477,7 @@ class User extends Memcached_DataObject } else if ($enabled === true || ($enabled == 'transitional' && $this->inboxed == 1)) { - $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since); + $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); return Notice::getStreamByIds($ids); } -- cgit v1.2.3-54-g00ecf From 793a6a1155996a7bcdc068fc891e7063934bdb19 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 20 Jun 2009 16:00:04 -0700 Subject: change Controlez-Vous to Control Yourself --- actions/accesstoken.php | 2 +- actions/all.php | 2 +- actions/allrss.php | 2 +- actions/api.php | 2 +- actions/avatarbynickname.php | 2 +- actions/block.php | 2 +- actions/disfavor.php | 2 +- actions/doc.php | 2 +- actions/facebookhome.php | 2 +- actions/facebookinvite.php | 2 +- actions/facebooklogin.php | 2 +- actions/facebookremove.php | 2 +- actions/facebooksettings.php | 2 +- actions/favor.php | 2 +- actions/favoritesrss.php | 2 +- actions/file.php | 2 +- actions/finishopenidlogin.php | 2 +- actions/finishremotesubscribe.php | 2 +- actions/foaf.php | 2 +- actions/groupblock.php | 2 +- actions/groupsearch.php | 2 +- actions/groupunblock.php | 2 +- actions/invite.php | 2 +- actions/logout.php | 2 +- actions/makeadmin.php | 2 +- actions/microsummary.php | 2 +- actions/noticesearch.php | 2 +- actions/noticesearchrss.php | 2 +- actions/nudge.php | 2 +- actions/openidlogin.php | 2 +- actions/opensearch.php | 2 +- actions/peoplesearch.php | 2 +- actions/postnotice.php | 2 +- actions/publicrss.php | 2 +- actions/publicxrds.php | 2 +- actions/recoverpassword.php | 2 +- actions/remotesubscribe.php | 2 +- actions/repliesrss.php | 2 +- actions/requesttoken.php | 2 +- actions/subedit.php | 2 +- actions/subscribe.php | 2 +- actions/sup.php | 2 +- actions/tag.php | 2 +- actions/tagother.php | 2 +- actions/tagrss.php | 2 +- actions/twitapiaccount.php | 2 +- actions/twitapiblocks.php | 2 +- actions/twitapidirect_messages.php | 2 +- actions/twitapifavorites.php | 2 +- actions/twitapifriendships.php | 2 +- actions/twitapihelp.php | 2 +- actions/twitapinotifications.php | 2 +- actions/twitapistatuses.php | 2 +- actions/twitapiusers.php | 2 +- actions/unblock.php | 2 +- actions/unsubscribe.php | 2 +- actions/updateprofile.php | 2 +- actions/userauthorization.php | 2 +- actions/userbyid.php | 2 +- actions/userrss.php | 2 +- actions/xrds.php | 2 +- classes/File.php | 2 +- classes/File_oembed.php | 2 +- classes/File_redirection.php | 2 +- classes/File_thumbnail.php | 2 +- classes/File_to_post.php | 2 +- classes/Group_block.php | 2 +- classes/Memcached_DataObject.php | 2 +- classes/Notice.php | 2 +- classes/Notice_tag.php | 2 +- classes/Profile.php | 2 +- classes/Profile_block.php | 2 +- classes/Remote_profile.php | 2 +- classes/Subscription.php | 2 +- index.php | 2 +- install.php | 2 +- lib/Shorturl_api.php | 2 +- lib/arraywrapper.php | 2 +- lib/channel.php | 2 +- lib/clienterroraction.php | 2 +- lib/command.php | 2 +- lib/commandinterpreter.php | 2 +- lib/common.php | 2 +- lib/daemon.php | 2 +- lib/dberroraction.php | 2 +- lib/error.php | 2 +- lib/facebookutil.php | 2 +- lib/galleryaction.php | 2 +- lib/oauthstore.php | 2 +- lib/omb.php | 2 +- lib/openid.php | 2 +- lib/peoplesearchresults.php | 2 +- lib/queuehandler.php | 2 +- lib/search_engines.php | 2 +- lib/searchaction.php | 2 +- lib/servererroraction.php | 2 +- lib/subs.php | 2 +- lib/twitter.php | 2 +- lib/twitterapi.php | 2 +- lib/util.php | 2 +- lib/xmppqueuehandler.php | 2 +- scripts/enjitqueuehandler.php | 2 +- scripts/facebookqueuehandler.php | 2 +- scripts/fixup_hashtags.php | 2 +- scripts/fixup_inboxes.php | 2 +- scripts/fixup_notices_rendered.php | 2 +- scripts/fixup_replies.php | 2 +- scripts/getpiddir.php | 2 +- scripts/getvaliddaemons.php | 2 +- scripts/inbox_users.php | 2 +- scripts/jabberqueuehandler.php | 2 +- scripts/maildaemon.php | 2 +- scripts/ombqueuehandler.php | 2 +- scripts/pingqueuehandler.php | 2 +- scripts/publicqueuehandler.php | 2 +- scripts/setpassword.php | 2 +- scripts/smsqueuehandler.php | 2 +- scripts/sphinx-cron.sh | 2 +- scripts/sphinx-indexer.sh | 2 +- scripts/startdaemons.sh | 2 +- scripts/stopdaemons.sh | 2 +- scripts/synctwitterfriends.php | 2 +- scripts/twitterqueuehandler.php | 2 +- scripts/twitterstatusfetcher.php | 2 +- scripts/uncache_users.php | 2 +- scripts/xmppconfirmhandler.php | 2 +- scripts/xmppdaemon.php | 2 +- 127 files changed, 127 insertions(+), 127 deletions(-) (limited to 'actions') diff --git a/actions/accesstoken.php b/actions/accesstoken.php index 46b43c702..01aa77574 100644 --- a/actions/accesstoken.php +++ b/actions/accesstoken.php @@ -12,7 +12,7 @@ * @link http://laconi.ca/ * * Laconica - a distributed open-source microblogging tool - * Copyright (C) 2008, Controlez-Vous, Inc. + * Copyright (C) 2008, Control Yourself, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/actions/all.php b/actions/all.php index 80fc9d54b..f436fabd1 100644 --- a/actions/all.php +++ b/actions/all.php @@ -1,7 +1,7 @@ Date: Sat, 20 Jun 2009 16:12:55 -0700 Subject: Update copyright dates in files modified in 2009 --- actions/accesstoken.php | 2 +- actions/all.php | 2 +- actions/allrss.php | 2 +- actions/api.php | 2 +- actions/avatarbynickname.php | 2 +- actions/block.php | 2 +- actions/disfavor.php | 2 +- actions/doc.php | 2 +- actions/facebookhome.php | 2 +- actions/facebookinvite.php | 2 +- actions/facebooklogin.php | 2 +- actions/facebookremove.php | 2 +- actions/facebooksettings.php | 2 +- actions/favor.php | 2 +- actions/favoritesrss.php | 2 +- actions/file.php | 2 +- actions/finishopenidlogin.php | 2 +- actions/finishremotesubscribe.php | 2 +- actions/foaf.php | 2 +- actions/groupblock.php | 2 +- actions/groupsearch.php | 2 +- actions/groupunblock.php | 2 +- actions/invite.php | 2 +- actions/logout.php | 2 +- actions/makeadmin.php | 2 +- actions/microsummary.php | 2 +- actions/noticesearch.php | 2 +- actions/noticesearchrss.php | 2 +- actions/nudge.php | 2 +- actions/openidlogin.php | 2 +- actions/opensearch.php | 2 +- actions/peoplesearch.php | 2 +- actions/postnotice.php | 2 +- actions/publicrss.php | 2 +- actions/publicxrds.php | 2 +- actions/recoverpassword.php | 2 +- actions/remotesubscribe.php | 2 +- actions/repliesrss.php | 2 +- actions/requesttoken.php | 2 +- actions/subedit.php | 2 +- actions/subscribe.php | 2 +- actions/sup.php | 2 +- actions/tag.php | 2 +- actions/tagother.php | 2 +- actions/tagrss.php | 2 +- actions/twitapiaccount.php | 2 +- actions/twitapiblocks.php | 2 +- actions/twitapidirect_messages.php | 2 +- actions/twitapifavorites.php | 2 +- actions/twitapifriendships.php | 2 +- actions/twitapihelp.php | 2 +- actions/twitapinotifications.php | 2 +- actions/twitapistatuses.php | 2 +- actions/twitapiusers.php | 2 +- actions/unblock.php | 2 +- actions/unsubscribe.php | 2 +- actions/updateprofile.php | 2 +- actions/userauthorization.php | 2 +- actions/userbyid.php | 2 +- actions/userrss.php | 2 +- actions/xrds.php | 2 +- classes/File.php | 2 +- classes/File_oembed.php | 2 +- classes/File_redirection.php | 2 +- classes/File_thumbnail.php | 2 +- classes/File_to_post.php | 2 +- classes/Group_block.php | 2 +- classes/Memcached_DataObject.php | 2 +- classes/Notice.php | 2 +- classes/Notice_tag.php | 2 +- classes/Profile.php | 2 +- classes/Profile_block.php | 2 +- classes/Remote_profile.php | 2 +- classes/Subscription.php | 2 +- index.php | 2 +- lib/Shorturl_api.php | 2 +- lib/arraywrapper.php | 2 +- lib/channel.php | 2 +- lib/clienterroraction.php | 2 +- lib/command.php | 2 +- lib/commandinterpreter.php | 2 +- lib/common.php | 2 +- lib/daemon.php | 2 +- lib/dberroraction.php | 2 +- lib/error.php | 2 +- lib/facebookutil.php | 2 +- lib/galleryaction.php | 2 +- lib/oauthstore.php | 2 +- lib/omb.php | 2 +- lib/openid.php | 2 +- lib/peoplesearchresults.php | 2 +- lib/queuehandler.php | 2 +- lib/search_engines.php | 2 +- lib/searchaction.php | 2 +- lib/servererroraction.php | 2 +- lib/subs.php | 2 +- lib/twitter.php | 2 +- lib/twitterapi.php | 2 +- lib/util.php | 2 +- lib/xmppqueuehandler.php | 2 +- scripts/enjitqueuehandler.php | 2 +- scripts/facebookqueuehandler.php | 2 +- scripts/fixup_hashtags.php | 2 +- scripts/fixup_inboxes.php | 2 +- scripts/fixup_notices_rendered.php | 2 +- scripts/fixup_replies.php | 2 +- scripts/getpiddir.php | 2 +- scripts/getvaliddaemons.php | 2 +- scripts/inbox_users.php | 2 +- scripts/jabberqueuehandler.php | 2 +- scripts/maildaemon.php | 2 +- scripts/ombqueuehandler.php | 2 +- scripts/pingqueuehandler.php | 2 +- scripts/publicqueuehandler.php | 2 +- scripts/setpassword.php | 2 +- scripts/smsqueuehandler.php | 2 +- scripts/sphinx-cron.sh | 2 +- scripts/sphinx-indexer.sh | 2 +- scripts/startdaemons.sh | 2 +- scripts/stopdaemons.sh | 2 +- scripts/synctwitterfriends.php | 2 +- scripts/twitterqueuehandler.php | 2 +- scripts/twitterstatusfetcher.php | 2 +- scripts/uncache_users.php | 2 +- scripts/xmppconfirmhandler.php | 2 +- scripts/xmppdaemon.php | 2 +- 126 files changed, 126 insertions(+), 126 deletions(-) (limited to 'actions') diff --git a/actions/accesstoken.php b/actions/accesstoken.php index 01aa77574..2a8cd1713 100644 --- a/actions/accesstoken.php +++ b/actions/accesstoken.php @@ -12,7 +12,7 @@ * @link http://laconi.ca/ * * Laconica - a distributed open-source microblogging tool - * Copyright (C) 2008, Control Yourself, Inc. + * Copyright (C) 2008, 2009, Control Yourself, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by diff --git a/actions/all.php b/actions/all.php index f436fabd1..f06ead2a8 100644 --- a/actions/all.php +++ b/actions/all.php @@ -1,7 +1,7 @@ Date: Mon, 22 Jun 2009 22:48:31 +0000 Subject: Attachment upload server and path now configurable --- actions/newnotice.php | 34 +++++++++++++++++++++++------- classes/File.php | 58 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 77 insertions(+), 15 deletions(-) (limited to 'actions') diff --git a/actions/newnotice.php b/actions/newnotice.php index 72ccd8c32..09652d2b3 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -257,23 +257,43 @@ class NewnoticeAction extends Action } function storeFile($notice, $mimetype) { - $filename = basename($_FILES['attach']['name']); - $destination = "file/{$notice->id}-$filename"; - if (move_uploaded_file($_FILES['attach']['tmp_name'], INSTALLDIR . "/$destination")) { + + common_debug("NewnoticeAction::storeFile()"); + + $basename = basename($_FILES['attach']['name']); + + common_debug("Basename: $basename"); + + $filename = File::filename($notice->id, $basename); + + common_debug("filename: $filename"); + + $filepath = File::path($filename); + + common_debug("filepath: $filepath"); + + if (move_uploaded_file($_FILES['attach']['tmp_name'], $filepath)) { + $file = new File; + $file->filename = $filename; + $file->url = common_local_url('file', array('notice' => $notice->id)); - $file->size = filesize(INSTALLDIR . "/$destination"); + + common_debug("file->url =". $file->url); + + $file->size = filesize($filepath); $file->date = time(); $file->mimetype = $mimetype; + if ($file_id = $file->insert()) { $file_redir = new File_redirection; - $file_redir->url = common_path($destination); + $file_redir->url = File::url($filename); $file_redir->file_id = $file_id; $file_redir->insert(); $f2p = new File_to_post; - $f2p->file_id = $file_id; - $f2p->post_id = $notice->id; + $f2p->file_id = $file_id; + $f2p->post_id = $notice->id; $f2p->insert(); } else { $this->clientError(_('There was a database error while saving your file. Please try again.')); diff --git a/classes/File.php b/classes/File.php index 47af1c550..1de136240 100644 --- a/classes/File.php +++ b/classes/File.php @@ -30,7 +30,7 @@ require_once INSTALLDIR.'/classes/File_to_post.php'; * Table Definition for file */ -class File extends Memcached_DataObject +class File extends Memcached_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -38,12 +38,12 @@ class File extends Memcached_DataObject public $__table = 'file'; // table name public $id; // int(4) primary_key not_null public $url; // varchar(255) unique_key - public $mimetype; // varchar(50) - public $size; // int(4) - public $title; // varchar(255) - public $date; // int(4) - public $protected; // int(4) - public $filename; // varchar(255) + public $mimetype; // varchar(50) + public $size; // int(4) + public $title; // varchar(255) + public $date; // int(4) + public $protected; // int(4) + public $filename; // varchar(255) public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP /* Static get */ @@ -116,7 +116,7 @@ class File extends Memcached_DataObject $x = File::staticGet($file_id); if (empty($x)) die('Impossible!'); } - + File_to_post::processNew($file_id, $notice_id); return $x; } @@ -145,5 +145,47 @@ class File extends Memcached_DataObject } return true; } + + // where should the file go? + + static function filename($notice_id, $basename) + { + return $notice_id . '-' . $basename; + } + + static function path($filename) + { + $dir = common_config('attachments', 'dir'); + + if ($dir[strlen($dir)-1] != '/') { + $dir .= '/'; + } + + return $dir . $filename; + } + + static function url($filename) + { + $path = common_config('attachments', 'path'); + + if ($path[strlen($path)-1] != '/') { + $path .= '/'; + } + + if ($path[0] != '/') { + $path = '/'.$path; + } + + $server = common_config('attachments', 'server'); + + if (empty($server)) { + $server = common_config('site', 'server'); + } + + // XXX: protocol + + return 'http://'.$server.$path.$filename; + } + } -- cgit v1.2.3-54-g00ecf From 7bcaa858af31c5c496bc5adc0c73ec333d4c1e63 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 23 Jun 2009 05:35:20 -0700 Subject: make file command configurable --- README | 4 ++++ actions/newnotice.php | 3 +++ lib/common.php | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'actions') diff --git a/README b/README index de1099600..1a57d6a80 100644 --- a/README +++ b/README @@ -1232,6 +1232,10 @@ supported: an array of mime types you accept to store and distribute, setup your server to properly reckognize the types you want to support. uploads: false to disable uploading files with notices (true by default). +filecommand: The required MIME_Type library may need to use the 'file' + command. It tries the one in the Web server's path, but if + you're having problems with uploads, try setting this to the + correct value. Note: 'file' must accept '-b' and '-i' options. For quotas, be sure you've set the upload_max_filesize and post_max_size in php.ini to be large enough to handle your upload. In httpd.conf diff --git a/actions/newnotice.php b/actions/newnotice.php index 09652d2b3..b7d9ec1dd 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -116,6 +116,9 @@ class NewnoticeAction extends Action function getUploadedFileType() { require_once 'MIME/Type.php'; + $cmd = &PEAR::getStaticProperty('MIME_Type', 'fileCmd'); + $cmd = common_config('attachments', 'filecommand'); + $filetype = MIME_Type::autoDetect($_FILES['attach']['tmp_name']); if (in_array($filetype, common_config('attachments', 'supported'))) { return $filetype; diff --git a/lib/common.php b/lib/common.php index 20f1ab35e..76eb4a978 100644 --- a/lib/common.php +++ b/lib/common.php @@ -202,7 +202,7 @@ $config = array('run' => 'web', 'frequency' => 10000, 'reporturl' => 'http://laconi.ca/stats/report'), - 'attachments' => + 'attachments' => array('server' => null, 'dir' => INSTALLDIR . '/file/', 'path' => $_path . '/file/', @@ -241,6 +241,7 @@ $config = 'user_quota' => 50000000, 'monthly_quota' => 15000000, 'uploads' => true, + 'filecommand' => '/usr/bin/file', ), 'group' => array('maxaliases' => 3), -- cgit v1.2.3-54-g00ecf From e2becdb25138350170b58ae8f0d1ecd715533cf5 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 23 Jun 2009 07:25:18 -0700 Subject: use a subclass for single notice items to show attachments --- actions/shownotice.php | 28 +++++++++++++++++++++++++++- lib/noticelist.php | 13 ------------- 2 files changed, 27 insertions(+), 14 deletions(-) (limited to 'actions') diff --git a/actions/shownotice.php b/actions/shownotice.php index b0d973a99..0d89af5ac 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -209,7 +209,7 @@ class ShownoticeAction extends Action function showContent() { $this->elementStart('ol', array('class' => 'notices xoxo')); - $nli = new NoticeListItem($this->notice, $this); + $nli = new SingleNoticeItem($this->notice, $this); $nli->show(); $this->elementEnd('ol'); } @@ -264,3 +264,29 @@ class ShownoticeAction extends Action } } } + +class SingleNoticeItem extends NoticeListItem +{ + /** + * recipe function for displaying a single notice. + * + * We overload to show attachments. + * + * @return void + */ + + function show() + { + $this->showStart(); + $this->showNotice(); + $this->showNoticeAttachments(); + $this->showNoticeInfo(); + $this->showNoticeOptions(); + $this->showEnd(); + } + + function showNoticeAttachments() { + $al = new AttachmentList($this->notice, $this->out); + $al->show(); + } +} diff --git a/lib/noticelist.php b/lib/noticelist.php index ad792441a..bd4815cd6 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -179,7 +179,6 @@ class NoticeListItem extends Widget { $this->showStart(); $this->showNotice(); - $this->showNoticeAttachments(); $this->showNoticeInfo(); $this->showNoticeOptions(); $this->showEnd(); @@ -193,18 +192,6 @@ class NoticeListItem extends Widget $this->out->elementEnd('div'); } - function showNoticeAttachments() { - if ($this->isUsedInList()) { - return; - } - $al = new AttachmentList($this->notice, $this->out); - $al->show(); - } - - function isUsedInList() { - return 'shownotice' !== $this->out->args['action']; - } - function showNoticeInfo() { $this->out->elementStart('div', 'entry-content'); -- cgit v1.2.3-54-g00ecf From a21a9f26c5f0eb034ea389659dd63ffad400de5b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 23 Jun 2009 07:29:43 -0700 Subject: append uploads to content rather than showing them double --- actions/newnotice.php | 104 +++++++++++++++++++++++++++++++++---------- classes/File.php | 67 +++++++++++++++------------- classes/File_redirection.php | 70 +++-------------------------- lib/noticelist.php | 4 -- lib/util.php | 65 +++++++++++++++++++++++++++ 5 files changed, 186 insertions(+), 124 deletions(-) (limited to 'actions') diff --git a/actions/newnotice.php b/actions/newnotice.php index b7d9ec1dd..a5f87d1be 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -224,16 +224,40 @@ class NewnoticeAction extends Action } } + if (isset($mimetype)) { + $filename = $this->saveFile($mimetype); + if (empty($filename)) { + $this->clientError(_('Couldn\'t save file.')); + } + $fileurl = File::url($filename); + $short_fileurl = common_shorten_url($fileurl); + $content_shortened .= ' ' . $short_fileurl; + if (mb_strlen($content_shortened) > 140) { + $this->deleteFile($filename); + $this->clientError(_('Max notice size is 140 chars, including attachment URL.')); + } + } + + common_debug("newnotice.php - before Notice::saveNew()"); + $notice = Notice::saveNew($user->id, $content_shortened, 'web', 1, ($replyto == 'false') ? null : $replyto); + common_debug("newnotice.php - after Notice::saveNew()"); + if (is_string($notice)) { + if (isset($filename)) { + $this->deleteFile($filename); + } $this->clientError($notice); } + common_debug("newnotice.php - after Notice::saveNew()"); + if (isset($mimetype)) { - $this->storeFile($notice, $mimetype); + $this->attachFile($notice, $filename, $mimetype, $short_fileurl); } + common_broadcast_notice($notice); if ($this->boolean('ajax')) { @@ -259,7 +283,13 @@ class NewnoticeAction extends Action } } - function storeFile($notice, $mimetype) { + function saveFile($mimetype) { + + $cur = common_current_user(); + + if (empty($cur)) { + $this->serverError(_('Somehow lost the login in saveFile')); + } common_debug("NewnoticeAction::storeFile()"); @@ -267,7 +297,7 @@ class NewnoticeAction extends Action common_debug("Basename: $basename"); - $filename = File::filename($notice->id, $basename); + $filename = File::filename($cur->getProfile(), $basename, $mimetype); common_debug("filename: $filename"); @@ -276,33 +306,59 @@ class NewnoticeAction extends Action common_debug("filepath: $filepath"); if (move_uploaded_file($_FILES['attach']['tmp_name'], $filepath)) { + return $filename; + } else { + $this->clientError(_('File could not be moved to destination directory.')); + } + } - $file = new File; - $file->filename = $filename; + function deleteFile($filename) + { + $filepath = File::path($filename); + @unlink($filepath); + } - $file->url = common_local_url('file', array('notice' => $notice->id)); + function attachFile($notice, $filename, $mimetype, $short) + { + $file = new File; + $file->filename = $filename; - common_debug("file->url =". $file->url); + $file->url = common_local_url('file', array('notice' => $notice->id)); - $file->size = filesize($filepath); - $file->date = time(); - $file->mimetype = $mimetype; + common_debug("file->url =". $file->url); - if ($file_id = $file->insert()) { - $file_redir = new File_redirection; - $file_redir->url = File::url($filename); - $file_redir->file_id = $file_id; - $file_redir->insert(); + $filepath = File::path($filename); - $f2p = new File_to_post; - $f2p->file_id = $file_id; - $f2p->post_id = $notice->id; - $f2p->insert(); - } else { - $this->clientError(_('There was a database error while saving your file. Please try again.')); - } - } else { - $this->clientError(_('File could not be moved to destination directory.')); + $file->size = filesize($filepath); + $file->date = time(); + $file->mimetype = $mimetype; + + $file_id = $file->insert(); + + if (!$file_id) { + common_log_db_error($file, "INSERT", __FILE__); + $this->clientError(_('There was a database error while saving your file. Please try again.')); + } + + $file_redir = new File_redirection; + $file_redir->url = File::url($filename); + $file_redir->file_id = $file_id; + + $result = $file_redir->insert(); + + if (!$result) { + common_log_db_error($file_redir, "INSERT", __FILE__); + $this->clientError(_('There was a database error while saving your file. Please try again.')); + } + + $f2p = new File_to_post; + $f2p->file_id = $file_id; + $f2p->post_id = $notice->id; + $f2p->insert(); + + if (!$result) { + common_log_db_error($f2p, "INSERT", __FILE__); + $this->clientError(_('There was a database error while saving your file. Please try again.')); } } diff --git a/classes/File.php b/classes/File.php index 1de136240..b98c9e665 100644 --- a/classes/File.php +++ b/classes/File.php @@ -124,8 +124,8 @@ class File extends Memcached_DataObject function isRespectsQuota($user) { if ($_FILES['attach']['size'] > common_config('attachments', 'file_quota')) { return sprintf(_('No file may be larger than %d bytes ' . - 'and the file you sent was %d bytes. Try to upload a smaller version.'), - common_config('attachments', 'file_quota'), $_FILES['attach']['size']); + 'and the file you sent was %d bytes. Try to upload a smaller version.'), + common_config('attachments', 'file_quota'), $_FILES['attach']['size']); } $query = "select sum(size) as total from file join file_to_post on file_to_post.file_id = file.id join notice on file_to_post.post_id = notice.id where profile_id = {$user->id} and file.url like '%/notice/%/file'"; @@ -148,44 +148,49 @@ class File extends Memcached_DataObject // where should the file go? - static function filename($notice_id, $basename) - { - return $notice_id . '-' . $basename; - } - - static function path($filename) - { - $dir = common_config('attachments', 'dir'); + static function filename($profile, $basename, $mimetype) + { + require_once 'MIME/Type/Extension.php'; + $mte = new MIME_Type_Extension(); + $ext = $mte->getExtension($mimetype); + $nickname = $profile->nickname; + $datestamp = strftime('%Y%m%dT%H%M%S', time()); + $random = strtolower(common_confirmation_code(32)); + return "$nickname-$datestamp-$random.$ext"; + } - if ($dir[strlen($dir)-1] != '/') { - $dir .= '/'; - } + static function path($filename) + { + $dir = common_config('attachments', 'dir'); - return $dir . $filename; - } + if ($dir[strlen($dir)-1] != '/') { + $dir .= '/'; + } - static function url($filename) - { - $path = common_config('attachments', 'path'); + return $dir . $filename; + } - if ($path[strlen($path)-1] != '/') { - $path .= '/'; - } + static function url($filename) + { + $path = common_config('attachments', 'path'); - if ($path[0] != '/') { - $path = '/'.$path; - } + if ($path[strlen($path)-1] != '/') { + $path .= '/'; + } - $server = common_config('attachments', 'server'); + if ($path[0] != '/') { + $path = '/'.$path; + } - if (empty($server)) { - $server = common_config('site', 'server'); - } + $server = common_config('attachments', 'server'); - // XXX: protocol + if (empty($server)) { + $server = common_config('site', 'server'); + } - return 'http://'.$server.$path.$filename; - } + // XXX: protocol + return 'http://'.$server.$path.$filename; + } } diff --git a/classes/File_redirection.php b/classes/File_redirection.php index edd915c1e..c173017e2 100644 --- a/classes/File_redirection.php +++ b/classes/File_redirection.php @@ -25,21 +25,20 @@ require_once INSTALLDIR.'/classes/File_oembed.php'; define('USER_AGENT', 'Laconica user agent / file probe'); - /** * Table Definition for file_redirection */ -class File_redirection extends Memcached_DataObject +class File_redirection extends Memcached_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ public $__table = 'file_redirection'; // table name public $url; // varchar(255) primary_key not_null - public $file_id; // int(4) - public $redirections; // int(4) - public $httpcode; // int(4) + public $file_id; // int(4) + public $redirections; // int(4) + public $httpcode; // int(4) public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP /* Static get */ @@ -48,8 +47,6 @@ class File_redirection extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - - function _commonCurl($url, $redirs) { $curlh = curl_init(); curl_setopt($curlh, CURLOPT_URL, $url); @@ -86,8 +83,6 @@ class File_redirection extends Memcached_DataObject return $url; } - - $curlh = File_redirection::_commonCurl($short_url, $redirs); // Don't include body in output curl_setopt($curlh, CURLOPT_NOBODY, true); @@ -143,62 +138,7 @@ class File_redirection extends Memcached_DataObject } function _userMakeShort($long_url, $user) { - if (empty($user)) { - // common current user does not find a user when called from the XMPP daemon - // therefore we'll set one here fix, so that XMPP given URLs may be shortened - $user->urlshorteningservice = 'ur1.ca'; - } - $curlh = curl_init(); - curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait - curl_setopt($curlh, CURLOPT_USERAGENT, 'Laconica'); - curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true); - - switch($user->urlshorteningservice) { - case 'ur1.ca': - require_once INSTALLDIR.'/lib/Shorturl_api.php'; - $short_url_service = new LilUrl; - $short_url = $short_url_service->shorten($long_url); - break; - - case '2tu.us': - $short_url_service = new TightUrl; - require_once INSTALLDIR.'/lib/Shorturl_api.php'; - $short_url = $short_url_service->shorten($long_url); - break; - - case 'ptiturl.com': - require_once INSTALLDIR.'/lib/Shorturl_api.php'; - $short_url_service = new PtitUrl; - $short_url = $short_url_service->shorten($long_url); - break; - - case 'bit.ly': - curl_setopt($curlh, CURLOPT_URL, 'http://bit.ly/api?method=shorten&long_url='.urlencode($long_url)); - $short_url = current(json_decode(curl_exec($curlh))->results)->hashUrl; - break; - - case 'is.gd': - curl_setopt($curlh, CURLOPT_URL, 'http://is.gd/api.php?longurl='.urlencode($long_url)); - $short_url = curl_exec($curlh); - break; - case 'snipr.com': - curl_setopt($curlh, CURLOPT_URL, 'http://snipr.com/site/snip?r=simple&link='.urlencode($long_url)); - $short_url = curl_exec($curlh); - break; - case 'metamark.net': - curl_setopt($curlh, CURLOPT_URL, 'http://metamark.net/api/rest/simple?long_url='.urlencode($long_url)); - $short_url = curl_exec($curlh); - break; - case 'tinyurl.com': - curl_setopt($curlh, CURLOPT_URL, 'http://tinyurl.com/api-create.php?url='.urlencode($long_url)); - $short_url = curl_exec($curlh); - break; - default: - $short_url = false; - } - - curl_close($curlh); - + $short_url = common_shorten_url($long_url); if ($short_url) { $short_url = (string)$short_url; // store it diff --git a/lib/noticelist.php b/lib/noticelist.php index bd4815cd6..6f05c63d6 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -336,10 +336,6 @@ class NoticeListItem extends Widget // versions (>> 0.4.x) $this->out->raw(common_render_content($this->notice->content, $this->notice)); } - $uploaded = $this->notice->getUploadedAttachment(); - if ($uploaded) { - $this->out->element('a', array('href' => $uploaded[0], 'class' => 'attachment', 'id' => 'attachment-' . $uploaded[1]), $uploaded[0]); - } $this->out->elementEnd('p'); } diff --git a/lib/util.php b/lib/util.php index 0aff893fd..1af462516 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1377,3 +1377,68 @@ function common_database_tablename($tablename) //table prefixes could be added here later return $tablename; } + +function common_shorten_url($long_url) +{ + $user = common_current_user(); + if (empty($user)) { + // common current user does not find a user when called from the XMPP daemon + // therefore we'll set one here fix, so that XMPP given URLs may be shortened + $svc = 'ur1.ca'; + } else { + $svc = $user->urlshorteningservice; + } + + $curlh = curl_init(); + curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait + curl_setopt($curlh, CURLOPT_USERAGENT, 'Laconica'); + curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true); + + switch($svc) { + case 'ur1.ca': + require_once INSTALLDIR.'/lib/Shorturl_api.php'; + $short_url_service = new LilUrl; + $short_url = $short_url_service->shorten($long_url); + break; + + case '2tu.us': + $short_url_service = new TightUrl; + require_once INSTALLDIR.'/lib/Shorturl_api.php'; + $short_url = $short_url_service->shorten($long_url); + break; + + case 'ptiturl.com': + require_once INSTALLDIR.'/lib/Shorturl_api.php'; + $short_url_service = new PtitUrl; + $short_url = $short_url_service->shorten($long_url); + break; + + case 'bit.ly': + curl_setopt($curlh, CURLOPT_URL, 'http://bit.ly/api?method=shorten&long_url='.urlencode($long_url)); + $short_url = current(json_decode(curl_exec($curlh))->results)->hashUrl; + break; + + case 'is.gd': + curl_setopt($curlh, CURLOPT_URL, 'http://is.gd/api.php?longurl='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + case 'snipr.com': + curl_setopt($curlh, CURLOPT_URL, 'http://snipr.com/site/snip?r=simple&link='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + case 'metamark.net': + curl_setopt($curlh, CURLOPT_URL, 'http://metamark.net/api/rest/simple?long_url='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + case 'tinyurl.com': + curl_setopt($curlh, CURLOPT_URL, 'http://tinyurl.com/api-create.php?url='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + default: + $short_url = false; + } + + curl_close($curlh); + + return $short_url; +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf From e261a97150684c943ebd6f994f610a2c2d0ba6b6 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 23 Jun 2009 07:48:33 -0700 Subject: remove common_debug from newnotice --- actions/newnotice.php | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'actions') diff --git a/actions/newnotice.php b/actions/newnotice.php index a5f87d1be..4a2c369f0 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -238,13 +238,9 @@ class NewnoticeAction extends Action } } - common_debug("newnotice.php - before Notice::saveNew()"); - $notice = Notice::saveNew($user->id, $content_shortened, 'web', 1, ($replyto == 'false') ? null : $replyto); - common_debug("newnotice.php - after Notice::saveNew()"); - if (is_string($notice)) { if (isset($filename)) { $this->deleteFile($filename); @@ -252,8 +248,6 @@ class NewnoticeAction extends Action $this->clientError($notice); } - common_debug("newnotice.php - after Notice::saveNew()"); - if (isset($mimetype)) { $this->attachFile($notice, $filename, $mimetype, $short_fileurl); } @@ -291,20 +285,12 @@ class NewnoticeAction extends Action $this->serverError(_('Somehow lost the login in saveFile')); } - common_debug("NewnoticeAction::storeFile()"); - $basename = basename($_FILES['attach']['name']); - common_debug("Basename: $basename"); - $filename = File::filename($cur->getProfile(), $basename, $mimetype); - common_debug("filename: $filename"); - $filepath = File::path($filename); - common_debug("filepath: $filepath"); - if (move_uploaded_file($_FILES['attach']['tmp_name'], $filepath)) { return $filename; } else { @@ -325,8 +311,6 @@ class NewnoticeAction extends Action $file->url = common_local_url('file', array('notice' => $notice->id)); - common_debug("file->url =". $file->url); - $filepath = File::path($filename); $file->size = filesize($filepath); -- cgit v1.2.3-54-g00ecf