From 227d4b688949a70c1dd3923628a101e1f0208e15 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 14:15:41 -0800 Subject: [PATCH 1/9] Stub ModPlus plugin: will hold experimental UI improvements for mod actions --- plugins/ModPlus/ModPlusPlugin.php | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 plugins/ModPlus/ModPlusPlugin.php diff --git a/plugins/ModPlus/ModPlusPlugin.php b/plugins/ModPlus/ModPlusPlugin.php new file mode 100644 index 0000000000..485b821813 --- /dev/null +++ b/plugins/ModPlus/ModPlusPlugin.php @@ -0,0 +1,43 @@ +. + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Some UI extras for now... + * + * @package ModPlusPlugin + * @maintainer Brion Vibber + */ +class ModPlusPlugin extends Plugin +{ + function onPluginVersion(&$versions) + { + $versions[] = array('name' => 'ModPlus', + 'version' => STATUSNET_VERSION, + 'author' => 'Brion Vibber', + 'homepage' => 'http://status.net/wiki/Plugin:ModPlus', + 'rawdescription' => + _m('UI extensions for profile moderation actions.')); + + return true; + } +} From 0d0e51292d97e0b3a07cf1d12031df0b8f69823f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 15:32:57 -0800 Subject: [PATCH 2/9] some User -> Profile cleanup to help in adapting the profile page action to show stuff for remote users. Subscriptions, groups, roles, etc are all on profiles now so go ahead and use em. --- classes/Profile.php | 23 +++++++++++++++++++++++ classes/User.php | 7 ++++--- lib/profileaction.php | 10 +++++----- lib/userprofile.php | 14 ++++++-------- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/classes/Profile.php b/classes/Profile.php index 37d2c571f9..b11cffc776 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -473,6 +473,29 @@ class Profile extends Memcached_DataObject return $cnt; } + /** + * Is this profile subscribed to another profile? + * + * @param Profile $other + * @return boolean + */ + function isSubscribed($other) + { + return Subscription::exists($this, $other); + } + + /** + * Are these two profiles subscribed to each other? + * + * @param Profile $other + * @return boolean + */ + function mutuallySubscribed($other) + { + return $this->isSubscribed($other) && + $other->isSubscribed($this); + } + function hasFave($notice) { $cache = common_memcache(); diff --git a/classes/User.php b/classes/User.php index 7345dc7f94..964bc3e7f3 100644 --- a/classes/User.php +++ b/classes/User.php @@ -84,7 +84,8 @@ class User extends Memcached_DataObject function isSubscribed($other) { - return Subscription::exists($this->getProfile(), $other); + $profile = $this->getProfile(); + return $profile->isSubscribed($other); } // 'update' won't write key columns, so we have to do it ourselves. @@ -418,8 +419,8 @@ class User extends Memcached_DataObject function mutuallySubscribed($other) { - return $this->isSubscribed($other) && - $other->isSubscribed($this); + $profile = $this->getProfile(); + return $profile->mutuallySubscribed($other); } function mutuallySubscribedUsers() diff --git a/lib/profileaction.php b/lib/profileaction.php index 504b775669..4bfc4d48d9 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -101,7 +101,7 @@ class ProfileAction extends OwnerDesignAction function showSubscriptions() { - $profile = $this->user->getSubscriptions(0, PROFILES_PER_MINILIST + 1); + $profile = $this->profile->getSubscriptions(0, PROFILES_PER_MINILIST + 1); $this->elementStart('div', array('id' => 'entity_subscriptions', 'class' => 'section')); @@ -134,7 +134,7 @@ class ProfileAction extends OwnerDesignAction function showSubscribers() { - $profile = $this->user->getSubscribers(0, PROFILES_PER_MINILIST + 1); + $profile = $this->profile->getSubscribers(0, PROFILES_PER_MINILIST + 1); $this->elementStart('div', array('id' => 'entity_subscribers', 'class' => 'section')); @@ -173,7 +173,7 @@ class ProfileAction extends OwnerDesignAction $subs_count = $this->profile->subscriptionCount(); $subbed_count = $this->profile->subscriberCount(); $notice_count = $this->profile->noticeCount(); - $group_count = $this->user->getGroups()->N; + $group_count = $this->profile->getGroups()->N; $age_days = (time() - strtotime($this->profile->created)) / 86400; if ($age_days < 1) { // Rather than extrapolating out to a bajillion... @@ -241,7 +241,7 @@ class ProfileAction extends OwnerDesignAction function showGroups() { - $groups = $this->user->getGroups(0, GROUPS_PER_MINILIST + 1); + $groups = $this->profile->getGroups(0, GROUPS_PER_MINILIST + 1); $this->elementStart('div', array('id' => 'entity_groups', 'class' => 'section')); @@ -249,7 +249,7 @@ class ProfileAction extends OwnerDesignAction $this->element('h2', null, _('Groups')); if ($groups) { - $gml = new GroupMiniList($groups, $this->user, $this); + $gml = new GroupMiniList($groups, $this->profile, $this); $cnt = $gml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); diff --git a/lib/userprofile.php b/lib/userprofile.php index ca060842b6..0f48078d17 100644 --- a/lib/userprofile.php +++ b/lib/userprofile.php @@ -109,10 +109,8 @@ class UserProfile extends Widget 'alt' => $this->profile->nickname)); $this->out->elementEnd('dd'); - $user = User::staticGet('id', $this->profile->id); - $cur = common_current_user(); - if ($cur && $cur->id == $user->id) { + if ($cur && $cur->id == $this->profile->id) { $this->out->elementStart('dd'); $this->out->element('a', array('href' => common_local_url('avatarsettings')), _('Edit Avatar')); $this->out->elementEnd('dd'); @@ -278,7 +276,7 @@ class UserProfile extends Widget } $this->out->elementEnd('li'); - if ($cur->mutuallySubscribed($this->user)) { + if ($cur->mutuallySubscribed($this->profile)) { // message @@ -290,7 +288,7 @@ class UserProfile extends Widget // nudge - if ($this->user->email && $this->user->emailnotifynudge) { + if ($this->user && $this->user->email && $this->user->emailnotifynudge) { $this->out->elementStart('li', 'entity_nudge'); $nf = new NudgeForm($this->out, $this->user); $nf->show(); @@ -327,7 +325,7 @@ class UserProfile extends Widget $this->out->elementStart('ul'); if ($cur->hasRight(Right::SANDBOXUSER)) { $this->out->elementStart('li', 'entity_sandbox'); - if ($this->user->isSandboxed()) { + if ($this->profile->isSandboxed()) { $usf = new UnSandboxForm($this->out, $this->profile, $r2args); $usf->show(); } else { @@ -339,7 +337,7 @@ class UserProfile extends Widget if ($cur->hasRight(Right::SILENCEUSER)) { $this->out->elementStart('li', 'entity_silence'); - if ($this->user->isSilenced()) { + if ($this->profile->isSilenced()) { $usf = new UnSilenceForm($this->out, $this->profile, $r2args); $usf->show(); } else { @@ -387,7 +385,7 @@ class UserProfile extends Widget $r2args['action'] = $action; $this->out->elementStart('li', "entity_role_$role"); - if ($this->user->hasRole($role)) { + if ($this->profile->hasRole($role)) { $rf = new RevokeRoleForm($role, $label, $this->out, $this->profile, $r2args); $rf->show(); } else { From 0e763b49024703efc3e2bbadad83b03d3dd62790 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 15:34:12 -0800 Subject: [PATCH 3/9] Stub RemoteprofileAction to show the standard profile header stuff for offsite users -- provides a way to get at the mod & block controls for remote users. --- plugins/ModPlus/ModPlusPlugin.php | 55 ++++++++++++++++++++ plugins/ModPlus/remoteprofileaction.php | 69 +++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 plugins/ModPlus/remoteprofileaction.php diff --git a/plugins/ModPlus/ModPlusPlugin.php b/plugins/ModPlus/ModPlusPlugin.php index 485b821813..89bbdf857f 100644 --- a/plugins/ModPlus/ModPlusPlugin.php +++ b/plugins/ModPlus/ModPlusPlugin.php @@ -40,4 +40,59 @@ class ModPlusPlugin extends Plugin return true; } + + /** + * Load JS at runtime if we're logged in. + * + * @param Action $action + * @return boolean hook result + */ + function onEndShowScripts($action) + { + $user = common_current_user(); + if ($user) { + $action->script('plugins/ModPlus/modplus.js'); + } + return true; + } + + /** + * Autoloader + * + * Loads our classes if they're requested. + * + * @param string $cls Class requested + * + * @return boolean hook return + */ + function onAutoload($cls) + { + switch ($cls) + { + case 'RemoteprofileAction': + case 'RemoteProfileAction': + require_once dirname(__FILE__) . '/remoteprofileaction.php'; + return false; + default: + return true; + } + } + + /** + * Add OpenID-related paths to the router table + * + * Hook for RouterInitialized event. + * + * @param Net_URL_Mapper $m URL mapper + * + * @return boolean hook return + */ + function onStartInitializeRouter($m) + { + $m->connect('user/remote/:id', + array('action' => 'remoteprofile'), + array('id' => '[\d]+')); + + return true; + } } diff --git a/plugins/ModPlus/remoteprofileaction.php b/plugins/ModPlus/remoteprofileaction.php new file mode 100644 index 0000000000..ca82045111 --- /dev/null +++ b/plugins/ModPlus/remoteprofileaction.php @@ -0,0 +1,69 @@ +arg('id'); + $this->user = false; + $this->profile = Profile::staticGet('id', $id); + + if (!$this->profile) { + $this->serverError(_('User has no profile.')); + return false; + } + + $this->tag = $this->trimmed('tag'); + $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + common_set_returnto($this->selfUrl()); + return true; + } + + function handle($args) + { + // skip yadis thingy + $this->showPage(); + } + + function title() + { + // maybe fixed in 0.9.x + if (!empty($this->profile->fullname)) { + $base = $this->profile->fullname . ' (' . $this->profile->nickname . ') '; + } else { + $base = $this->profile->nickname; + } + } + + function showContent() + { + $this->showProfile(); + // don't show notices + } + + function getFeeds() + { + // none + } + + function extraHead() + { + // none + } + function showLocalNav() + { + // none...? + } + function showSections() + { + ProfileAction::showSections(); + // skip tag cloud + } + +} \ No newline at end of file From 6849b8f9e530deae776064d4489777a9fb4eb772 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 15:39:42 -0800 Subject: [PATCH 4/9] Workaround for display of Twitter remote users in remoteprofile (ModPlus plugin): use 73px avatar if no 96px present --- lib/userprofile.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/userprofile.php b/lib/userprofile.php index 0f48078d17..9124b7c94d 100644 --- a/lib/userprofile.php +++ b/lib/userprofile.php @@ -98,6 +98,10 @@ class UserProfile extends Widget if (Event::handle('StartProfilePageAvatar', array($this->out, $this->profile))) { $avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE); + if (!$avatar) { + // hack for remote Twitter users: no 96px, but large Twitter size is 73px + $avatar = $this->profile->getAvatar(73); + } $this->out->elementStart('dl', 'entity_depiction'); $this->out->element('dt', null, _('Photo')); From 16f1c764c0ac89f922654f9f663faaada611b8e2 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 15:40:07 -0800 Subject: [PATCH 5/9] RemoteProfileAction: redirect to the regular user profile page if given a local user. --- plugins/ModPlus/remoteprofileaction.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/ModPlus/remoteprofileaction.php b/plugins/ModPlus/remoteprofileaction.php index ca82045111..9c089ee23e 100644 --- a/plugins/ModPlus/remoteprofileaction.php +++ b/plugins/ModPlus/remoteprofileaction.php @@ -19,6 +19,14 @@ class RemoteProfileAction extends ShowstreamAction return false; } + $user = User::staticGet('id', $this->profile->id); + if ($user) { + // This is a local user -- send to their regular profile. + $url = common_local_url('showstream', array('nickname' => $user->nickname)); + common_redirect($url); + return false; + } + $this->tag = $this->trimmed('tag'); $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; common_set_returnto($this->selfUrl()); From 88c35c2ccea5edcd08708f30247dc51a7473ecce Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 15:57:57 -0800 Subject: [PATCH 6/9] visual tweaks for RemoteProfileAction --- plugins/ModPlus/remoteprofileaction.php | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/plugins/ModPlus/remoteprofileaction.php b/plugins/ModPlus/remoteprofileaction.php index 9c089ee23e..f3ddbc7c65 100644 --- a/plugins/ModPlus/remoteprofileaction.php +++ b/plugins/ModPlus/remoteprofileaction.php @@ -47,12 +47,23 @@ class RemoteProfileAction extends ShowstreamAction } else { $base = $this->profile->nickname; } + $host = parse_url($this->profile->profileurl, PHP_URL_HOST); + return sprintf(_m('%s on %s'), $base, $host); } - function showContent() + /** + * Instead of showing notices, link to the original offsite profile. + */ + function showNotices() { - $this->showProfile(); - // don't show notices + $url = $this->profile->profileurl; + $host = parse_url($url, PHP_URL_HOST); + $markdown = sprintf( + _m('This profile is registered on another site; see [the profile page on %s](%s).'), + $host, + $url); + $html = common_markup_to_html($markdown); + $this->raw($html); } function getFeeds() @@ -64,10 +75,13 @@ class RemoteProfileAction extends ShowstreamAction { // none } + function showLocalNav() { - // none...? + $nav = new PublicGroupNav($this); + $nav->show(); } + function showSections() { ProfileAction::showSections(); From 5fdcba472b8673380248ab0d5dce45967f774caa Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 16:12:16 -0800 Subject: [PATCH 7/9] RemoteProfileAction cleanup: - meta robots to prevent spidering - a little notice if silenced --- lib/userprofile.php | 7 +++++-- plugins/ModPlus/remoteprofileaction.php | 11 ++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/userprofile.php b/lib/userprofile.php index 9124b7c94d..2813f735ea 100644 --- a/lib/userprofile.php +++ b/lib/userprofile.php @@ -321,6 +321,9 @@ class UserProfile extends Widget } $this->out->elementEnd('li'); + // Some actions won't be applicable to non-local users. + $isLocal = !empty($this->user); + if ($cur->hasRight(Right::SANDBOXUSER) || $cur->hasRight(Right::SILENCEUSER) || $cur->hasRight(Right::DELETEUSER)) { @@ -351,7 +354,7 @@ class UserProfile extends Widget $this->out->elementEnd('li'); } - if ($cur->hasRight(Right::DELETEUSER)) { + if ($isLocal && $cur->hasRight(Right::DELETEUSER)) { $this->out->elementStart('li', 'entity_delete'); $df = new DeleteUserForm($this->out, $this->profile, $r2args); $df->show(); @@ -361,7 +364,7 @@ class UserProfile extends Widget $this->out->elementEnd('li'); } - if ($cur->hasRight(Right::GRANTROLE)) { + if ($isLocal && $cur->hasRight(Right::GRANTROLE)) { $this->out->elementStart('li', 'entity_role'); $this->out->element('p', null, _('User role')); $this->out->elementStart('ul'); diff --git a/plugins/ModPlus/remoteprofileaction.php b/plugins/ModPlus/remoteprofileaction.php index f3ddbc7c65..5b25da1701 100644 --- a/plugins/ModPlus/remoteprofileaction.php +++ b/plugins/ModPlus/remoteprofileaction.php @@ -64,6 +64,11 @@ class RemoteProfileAction extends ShowstreamAction $url); $html = common_markup_to_html($markdown); $this->raw($html); + + if ($this->profile->hasRole(Profile_role::SILENCED)) { + $markdown = _m('Site moderators have silenced this profile, which prevents delivery of new messages to any users on this site.'); + $this->raw(common_markup_to_html($markdown)); + } } function getFeeds() @@ -71,9 +76,13 @@ class RemoteProfileAction extends ShowstreamAction // none } + /** + * Don't do various extra stuff, and also trim some things to avoid crawlers. + */ function extraHead() { - // none + $this->element('meta', array('name' => 'robots', + 'content' => 'noindex,nofollow')); } function showLocalNav() From fdcaac365354fb7315263373bae6094eab6aa3c8 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 16:38:18 -0800 Subject: [PATCH 8/9] Tweak remote profile action: hide stats from sidebar, tweak wording on remote notice --- plugins/ModPlus/remoteprofileaction.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/ModPlus/remoteprofileaction.php b/plugins/ModPlus/remoteprofileaction.php index 5b25da1701..caa5e6fbf3 100644 --- a/plugins/ModPlus/remoteprofileaction.php +++ b/plugins/ModPlus/remoteprofileaction.php @@ -59,7 +59,8 @@ class RemoteProfileAction extends ShowstreamAction $url = $this->profile->profileurl; $host = parse_url($url, PHP_URL_HOST); $markdown = sprintf( - _m('This profile is registered on another site; see [the profile page on %s](%s).'), + _m('This remote profile is registered on another site; see [%s\'s original profile page on %s](%s).'), + $this->profile->nickname, $host, $url); $html = common_markup_to_html($markdown); @@ -97,4 +98,9 @@ class RemoteProfileAction extends ShowstreamAction // skip tag cloud } + function showStatistics() + { + // skip + } + } \ No newline at end of file From 25170f272ca853c585531894d282c7545f00bf16 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 15 Nov 2010 17:32:33 -0800 Subject: [PATCH 9/9] visual cleanup on ModPlus remote profile info popup menu --- plugins/ModPlus/ModPlusPlugin.php | 18 ++++++++++++++++++ plugins/ModPlus/modplus.css | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 plugins/ModPlus/modplus.css diff --git a/plugins/ModPlus/ModPlusPlugin.php b/plugins/ModPlus/ModPlusPlugin.php index 89bbdf857f..3e7a8c7455 100644 --- a/plugins/ModPlus/ModPlusPlugin.php +++ b/plugins/ModPlus/ModPlusPlugin.php @@ -56,6 +56,11 @@ class ModPlusPlugin extends Plugin return true; } + function onEndShowStatusNetStyles($action) { + $action->cssLink('plugins/ModPlus/modplus.css'); + return true; + } + /** * Autoloader * @@ -95,4 +100,17 @@ class ModPlusPlugin extends Plugin return true; } + + function onStartShowNoticeItem($item) + { + $profile = $item->profile; + $isRemote = !(User::staticGet('id', $profile->id)); + if ($isRemote) { + $target = common_local_url('remoteprofile', array('id' => $profile->id)); + $label = _m('Remote profile options...'); + $item->out->elementStart('div', 'remote-profile-options'); + $item->out->element('a', array('href' => $target), $label); + $item->out->elementEnd('div'); + } + } } diff --git a/plugins/ModPlus/modplus.css b/plugins/ModPlus/modplus.css new file mode 100644 index 0000000000..8d2fc8fba1 --- /dev/null +++ b/plugins/ModPlus/modplus.css @@ -0,0 +1,23 @@ +.remote-profile-options { + position: absolute; + z-index: 999; + + background: url(../../theme/base/images/icons/twotone/green/admin.gif) no-repeat 8px 8px white; + border: solid 1px #c0c0c0; + + margin-top: 56px; + + padding: 6px 16px; + padding-left: 32px; + + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + -msie-border-radius: 8px; + border-radius: 8px; + + box-shadow:3px 3px 7px rgba(194, 194, 194, 0.3); + -moz-box-shadow:3px 3px 7px rgba(194, 194, 194, 0.3); + -webkit-box-shadow:3px 3px 7px rgba(194, 194, 194, 0.3); + + display: none; +}