diff --git a/QvitterPlugin.php b/QvitterPlugin.php
index 36a1db5..742a1ff 100644
--- a/QvitterPlugin.php
+++ b/QvitterPlugin.php
@@ -153,14 +153,25 @@ class QvitterPlugin extends Plugin {
// route/reroute urls
public function onRouterInitialized($m)
{
+ $m->connect(':nickname/mutes',
+ array('action' => 'qvitter',
+ 'nickname' => Nickname::INPUT_FMT));
+ $m->connect('api/qvitter/mutes.json',
+ array('action' => 'ApiQvitterMutes'));
$m->connect('api/qvitter/sandboxed.:format',
array('action' => 'ApiQvitterSandboxed',
'format' => '(xml|json)'));
$m->connect('api/qvitter/silenced.:format',
array('action' => 'ApiQvitterSilenced',
'format' => '(xml|json)'));
+ $m->connect('api/qvitter/sandbox/create.json',
+ array('action' => 'ApiQvitterSandboxCreate'));
+ $m->connect('api/qvitter/sandbox/destroy.json',
+ array('action' => 'ApiQvitterSandboxDestroy'));
$m->connect('api/qvitter/silence/create.json',
array('action' => 'ApiQvitterSilenceCreate'));
+ $m->connect('api/qvitter/silence/destroy.json',
+ array('action' => 'ApiQvitterSilenceDestroy'));
$m->connect('services/oembed.:format',
array('action' => 'apiqvitteroembednotice',
'format' => '(xml|json)'));
@@ -1285,6 +1296,16 @@ class QvitterPlugin extends Plugin {
$notification->whereAdd(sprintf('qvitternotification.from_profile_id IN (SELECT subscribed FROM subscription WHERE subscriber = %u)', $user_id));
}
+ // the user might have opted out from notifications from profiles they have muted
+ $hide_notifications_from_muted_users = Profile_prefs::getConfigData($profile, 'qvitter', 'hide_notifications_from_muted_users');
+ if($hide_notifications_from_muted_users == '1') {
+ $muted_ids = QvitterMuted::getMutedIDs($profile->id,0,10000); // get all (hopefully not more than 10 000...)
+ if($muted_ids !== false && count($muted_ids) > 0) {
+ $ids_imploded = implode(',',$muted_ids);
+ $notification->whereAdd('qvitternotification.from_profile_id NOT IN ('.$ids_imploded.')');
+ }
+ }
+
// the user might have opted out from certain notification types
$current_profile = $user->getProfile();
$disable_notify_replies_and_mentions = Profile_prefs::getConfigData($current_profile, 'qvitter', 'disable_notify_replies_and_mentions');
diff --git a/actions/apiqvitterblocks.php b/actions/apiqvitterblocks.php
index f6d7bb2..d970605 100644
--- a/actions/apiqvitterblocks.php
+++ b/actions/apiqvitterblocks.php
@@ -96,7 +96,7 @@ class ApiQvitterBlocksAction extends ApiPrivateAuthAction
}
/**
- * Get the user's subscribers (followers) as an array of profiles
+ * Get the user's blocked profiles
*
* @return array Profiles
*/
diff --git a/actions/apiqvittermutes.php b/actions/apiqvittermutes.php
new file mode 100644
index 0000000..ec56189
--- /dev/null
+++ b/actions/apiqvittermutes.php
@@ -0,0 +1,182 @@
+ \\\\_\ ·
+ · \\) \____) ·
+ · ·
+ · ·
+ · ·
+ · Qvitter 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 three of the License or (at ·
+ · your option) any later version. ·
+ · ·
+ · Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
+ · WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see . ·
+ · ·
+ · Contact h@nnesmannerhe.im if you have any questions. ·
+ · ·
+ · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+
+class ApiQvitterMutesAction extends ApiPrivateAuthAction
+{
+ var $profiles = null;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
+ protected function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $this->format = 'json';
+
+ $this->count = (int)$this->arg('count', 100);
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * Show the profiles
+ *
+ * @return void
+ */
+ protected function handle()
+ {
+ parent::handle();
+
+ $this->target = Profile::current();
+
+ if(!$this->target instanceof Profile) {
+ $this->clientError(_('You have to be logged in to view your mutes.'), 403);
+ }
+
+ $this->profiles = $this->getProfiles();
+
+ $this->initDocument('json');
+ print json_encode($this->showProfiles());
+ $this->endDocument('json');
+ }
+
+ /**
+ * Get the user's muted profiles
+ *
+ * @return array Profiles
+ */
+ protected function getProfiles()
+ {
+ $offset = ($this->page - 1) * $this->count;
+ $limit = $this->count;
+
+ $mutes = QvitterMuted::getMutedProfiles($this->target->id, $offset, $limit);
+
+ if($mutes) {
+ return $mutes;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Is this action read only?
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean true
+ */
+ function isReadOnly($args)
+ {
+ return true;
+ }
+
+ /**
+ * When was this feed last modified?
+ *
+ * @return string datestamp of the latest profile in the stream
+ */
+ function lastModified()
+ {
+ if (!empty($this->profiles) && (count($this->profiles) > 0)) {
+ return strtotime($this->profiles[0]->modified);
+ }
+
+ return null;
+ }
+
+ /**
+ * An entity tag for this action
+ *
+ * Returns an Etag based on the action name, language, user ID, and
+ * timestamps of the first and last profiles in the subscriptions list
+ * There's also an indicator to show whether this action is being called
+ * as /api/statuses/(friends|followers) or /api/(friends|followers)/ids
+ *
+ * @return string etag
+ */
+ function etag()
+ {
+ if (!empty($this->profiles) && (count($this->profiles) > 0)) {
+
+ $last = count($this->profiles) - 1;
+
+ return '"' . implode(
+ ':',
+ array($this->arg('action'),
+ common_user_cache_hash($this->auth_user),
+ common_language(),
+ $this->target->id,
+ 'Profiles',
+ strtotime($this->profiles[0]->modified),
+ strtotime($this->profiles[$last]->modified))
+ )
+ . '"';
+ }
+
+ return null;
+ }
+
+ /**
+ * Show the profiles as Twitter-style useres and statuses
+ *
+ * @return void
+ */
+ function showProfiles()
+ {
+ $user_arrays = array();
+ if($this->profiles !== false) {
+ foreach ($this->profiles as $profile) {
+ $user_arrays[] = $this->twitterUserArray($profile, false );
+ }
+ }
+ return $user_arrays;
+ }
+}
diff --git a/actions/apiqvittersandboxcreate.php b/actions/apiqvittersandboxcreate.php
new file mode 100644
index 0000000..f713e61
--- /dev/null
+++ b/actions/apiqvittersandboxcreate.php
@@ -0,0 +1,107 @@
+ \\\\_\ ·
+ · \\) \____) ·
+ · ·
+ · ·
+ · ·
+ · Qvitter 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 three of the License or (at ·
+ · your option) any later version. ·
+ · ·
+ · Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
+ · WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see . ·
+ · ·
+ · Contact h@nnesmannerhe.im if you have any questions. ·
+ · ·
+ · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
+
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class ApiQvitterSandboxCreateAction extends ApiAuthAction
+{
+
+ protected $needPost = true;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
+ protected function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $this->format = 'json';
+
+ $this->other = $this->getTargetProfile($this->arg('id'));
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+ protected function handle()
+ {
+ parent::handle();
+
+ if (!$this->other instanceof Profile) {
+ $this->clientError(_('No such user.'), 404);
+ }
+
+ if ($this->scoped->id == $this->other->id) {
+ $this->clientError(_("You cannot sandbox yourself!"), 403);
+ }
+
+ if (!$this->scoped->hasRight(Right::SANDBOXUSER)) {
+ $this->clientError(_('You cannot sandbox users on this site.'), 403);
+ }
+ // Only administrators can sandbox other privileged users (such as others who have the right to sandbox).
+ if ($this->scoped->isPrivileged() && !$this->scoped->hasRole(Profile_role::ADMINISTRATOR)) {
+ $this->clientError(_('You cannot sandbox other privileged users.'), 403);
+ }
+
+ // only sandbox of the user isn't sandboxed
+ if (!$this->other->isSandboxed()) {
+ try {
+ $this->other->sandbox();
+ } catch (Exception $e) {
+ $this->clientError($e->getMessage(), $e->getCode());
+ }
+ }
+
+ $this->initDocument('json');
+ $this->showJsonObjects($this->twitterUserArray($this->other));
+ $this->endDocument('json');
+ }
+}
diff --git a/actions/apiqvittersandboxdestroy.php b/actions/apiqvittersandboxdestroy.php
new file mode 100644
index 0000000..1b55e23
--- /dev/null
+++ b/actions/apiqvittersandboxdestroy.php
@@ -0,0 +1,103 @@
+ \\\\_\ ·
+ · \\) \____) ·
+ · ·
+ · ·
+ · ·
+ · Qvitter 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 three of the License or (at ·
+ · your option) any later version. ·
+ · ·
+ · Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
+ · WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see . ·
+ · ·
+ · Contact h@nnesmannerhe.im if you have any questions. ·
+ · ·
+ · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
+
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class ApiQvitterSandboxDestroyAction extends ApiAuthAction
+{
+
+ protected $needPost = true;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
+ protected function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $this->format = 'json';
+
+ $this->other = $this->getTargetProfile($this->arg('id'));
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+ protected function handle()
+ {
+ parent::handle();
+
+ if (!$this->other instanceof Profile) {
+ $this->clientError(_('No such user.'), 404);
+ }
+
+ if ($this->scoped->id == $this->other->id) {
+ $this->clientError(_("You cannot unsandbox yourself!"), 403);
+ }
+
+ if (!$this->scoped->hasRight(Right::SANDBOXUSER)) {
+ $this->clientError(_('You cannot unsandbox users on this site.'), 403);
+ }
+
+ // only unsandbox if the user is sandboxed
+ if ($this->other->isSandboxed()) {
+ try {
+ $this->other->unsandbox();
+ } catch (Exception $e) {
+ $this->clientError($e->getMessage(), $e->getCode());
+ }
+ }
+
+ $this->initDocument('json');
+ $this->showJsonObjects($this->twitterUserArray($this->other));
+ $this->endDocument('json');
+ }
+}
diff --git a/actions/apiqvittersandboxed.php b/actions/apiqvittersandboxed.php
index f0d3bd1..cc87210 100644
--- a/actions/apiqvittersandboxed.php
+++ b/actions/apiqvittersandboxed.php
@@ -110,10 +110,7 @@ class ApiQvitterSandboxedAction extends ApiPrivateAuthAction
$profile = $this->getSandboxed(
($this->page - 1) * $this->count,
- $this->count,
- $this->since_id,
- $this->max_id
- );
+ $this->count);
while ($profile->fetch()) {
$profiles[] = clone($profile);
@@ -130,6 +127,7 @@ class ApiQvitterSandboxedAction extends ApiPrivateAuthAction
function getSandboxed($offset=null, $limit=null) // offset is null because DataObject wants it, 0 would mean no results
{
+
$profiles = new Profile();
$profiles->joinAdd(array('id', 'profile_role:profile_id'));
$profiles->whereAdd(sprintf('profile_role.role = \'%s\'', Profile_role::SANDBOXED));
diff --git a/actions/apiqvittersilencecreate.php b/actions/apiqvittersilencecreate.php
index 1383067..b465077 100644
--- a/actions/apiqvittersilencecreate.php
+++ b/actions/apiqvittersilencecreate.php
@@ -44,6 +44,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
class ApiQvitterSilenceCreateAction extends ApiAuthAction
{
+ protected $needPost = true;
/**
* Take arguments for running
@@ -56,6 +57,8 @@ class ApiQvitterSilenceCreateAction extends ApiAuthAction
{
parent::prepare($args);
+ $this->format = 'json';
+
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
@@ -82,6 +85,10 @@ class ApiQvitterSilenceCreateAction extends ApiAuthAction
try {
$this->other->silenceAs($this->scoped);
+ } catch (AlreadyFulfilledException $e) {
+ // don't throw client error here, just return the user array like
+ // if we successfully silenced the user. the client is only interested
+ // in making sure the user is silenced.
} catch (Exception $e) {
$this->clientError($e->getMessage(), $e->getCode());
}
diff --git a/actions/apiqvittersilenced.php b/actions/apiqvittersilenced.php
index 1f97ab3..5f29169 100644
--- a/actions/apiqvittersilenced.php
+++ b/actions/apiqvittersilenced.php
@@ -110,10 +110,7 @@ class ApiQvitterSilencedAction extends ApiPrivateAuthAction
$profile = $this->getSilenced(
($this->page - 1) * $this->count,
- $this->count,
- $this->since_id,
- $this->max_id
- );
+ $this->count);
while ($profile->fetch()) {
$profiles[] = clone($profile);
diff --git a/actions/apiqvittersilencedestroy.php b/actions/apiqvittersilencedestroy.php
new file mode 100644
index 0000000..92e206a
--- /dev/null
+++ b/actions/apiqvittersilencedestroy.php
@@ -0,0 +1,100 @@
+ \\\\_\ ·
+ · \\) \____) ·
+ · ·
+ · ·
+ · ·
+ · Qvitter 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 three of the License or (at ·
+ · your option) any later version. ·
+ · ·
+ · Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
+ · WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see . ·
+ · ·
+ · Contact h@nnesmannerhe.im if you have any questions. ·
+ · ·
+ · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
+
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class ApiQvitterSilenceDestroyAction extends ApiAuthAction
+{
+
+ protected $needPost = true;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
+ protected function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $this->format = 'json';
+
+ $this->other = $this->getTargetProfile($this->arg('id'));
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+ protected function handle()
+ {
+ parent::handle();
+
+ if (!$this->other instanceof Profile) {
+ $this->clientError(_('No such user.'), 404);
+ }
+
+ if ($this->scoped->id == $this->other->id) {
+ $this->clientError(_("You cannot unsilence yourself!"), 403);
+ }
+
+ try {
+ $this->other->unsilenceAs($this->scoped);
+ } catch (AlreadyFulfilledException $e) {
+ // don't throw client error here, just return the user array like
+ // if we successfully unsilenced the user. the client is only interested
+ // in making sure the user is unsilenced.
+ } catch (Exception $e) {
+ $this->clientError($e->getMessage(), $e->getCode());
+ }
+
+ $this->initDocument('json');
+ $this->showJsonObjects($this->twitterUserArray($this->other));
+ $this->endDocument('json');
+ }
+}
diff --git a/actions/qvitter.php b/actions/qvitter.php
index fcc1c75..79f263b 100644
--- a/actions/qvitter.php
+++ b/actions/qvitter.php
@@ -429,7 +429,19 @@ class QvitterAction extends ApiAction
?>
-
">
+ ">
-
+
-
-
-
@@ -480,6 +489,8 @@ class QvitterAction extends ApiAction
+
+