Merge branch 'master' into 0.9.x
This commit is contained in:
commit
98a579fedf
15
EVENTS.txt
15
EVENTS.txt
|
@ -640,3 +640,18 @@ EndLog: After writing to the logs
|
||||||
- $msg
|
- $msg
|
||||||
- $filename
|
- $filename
|
||||||
|
|
||||||
|
StartBlockProfile: when we're about to block
|
||||||
|
- $user: the person doing the block
|
||||||
|
- $profile: the person getting blocked, can be remote
|
||||||
|
|
||||||
|
EndBlockProfile: when a block has succeeded
|
||||||
|
- $user: the person doing the block
|
||||||
|
- $profile: the person blocked, can be remote
|
||||||
|
|
||||||
|
StartUnblockProfile: when we're about to unblock
|
||||||
|
- $user: the person doing the unblock
|
||||||
|
- $profile: the person getting unblocked, can be remote
|
||||||
|
|
||||||
|
EndUnblockProfile: when an unblock has succeeded
|
||||||
|
- $user: the person doing the unblock
|
||||||
|
- $profile: the person unblocked, can be remote
|
||||||
|
|
|
@ -109,9 +109,16 @@ class ApiBlockCreateAction extends ApiAuthAction
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->user->hasBlocked($this->other)
|
if (!$this->user->hasBlocked($this->other)) {
|
||||||
|| $this->user->block($this->other)
|
if (Event::handle('StartBlockProfile', array($this->user, $this->other))) {
|
||||||
) {
|
$result = $this->user->block($this->other);
|
||||||
|
if ($result) {
|
||||||
|
Event::handle('EndBlockProfile', array($this->user, $this->other));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->hasBlocked($this->other)) {
|
||||||
$this->initDocument($this->format);
|
$this->initDocument($this->format);
|
||||||
$this->showProfile($this->other, $this->format);
|
$this->showProfile($this->other, $this->format);
|
||||||
$this->endDocument($this->format);
|
$this->endDocument($this->format);
|
||||||
|
|
|
@ -97,9 +97,16 @@ class ApiBlockDestroyAction extends ApiAuthAction
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->user->hasBlocked($this->other)
|
if ($this->user->hasBlocked($this->other)) {
|
||||||
|| $this->user->unblock($this->other)
|
if (Event::handle('StartUnblockProfile', array($this->user, $this->other))) {
|
||||||
) {
|
$result = $this->user->unblock($this->other);
|
||||||
|
if ($result) {
|
||||||
|
Event::handle('EndUnblockProfile', array($this->user, $this->other));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->user->hasBlocked($this->other)) {
|
||||||
$this->initDocument($this->format);
|
$this->initDocument($this->format);
|
||||||
$this->showProfile($this->other, $this->format);
|
$this->showProfile($this->other, $this->format);
|
||||||
$this->endDocument($this->format);
|
$this->endDocument($this->format);
|
||||||
|
|
|
@ -156,7 +156,12 @@ class BlockAction extends ProfileFormAction
|
||||||
{
|
{
|
||||||
$cur = common_current_user();
|
$cur = common_current_user();
|
||||||
|
|
||||||
$result = $cur->block($this->profile);
|
if (Event::handle('StartBlockProfile', array($cur, $this->profile))) {
|
||||||
|
$result = $cur->block($this->profile);
|
||||||
|
if ($result) {
|
||||||
|
Event::handle('EndBlockProfile', array($cur, $this->profile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
$this->serverError(_('Failed to save block information.'));
|
$this->serverError(_('Failed to save block information.'));
|
||||||
|
@ -164,4 +169,3 @@ class BlockAction extends ProfileFormAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,17 @@ class UnblockAction extends ProfileFormAction
|
||||||
|
|
||||||
function handlePost()
|
function handlePost()
|
||||||
{
|
{
|
||||||
$cur = common_current_user();
|
$cur = common_current_user();
|
||||||
$result = $cur->unblock($this->profile);
|
|
||||||
|
$result = false;
|
||||||
|
|
||||||
|
if (Event::handle('StartUnblockProfile', array($cur, $this->profile))) {
|
||||||
|
$result = $cur->unblock($this->profile);
|
||||||
|
if ($result) {
|
||||||
|
Event::handle('EndUnblockProfile', array($cur, $this->profile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
$this->serverError(_('Error removing the block.'));
|
$this->serverError(_('Error removing the block.'));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -625,7 +625,11 @@ class User extends Memcached_DataObject
|
||||||
|
|
||||||
// Cancel their subscription, if it exists
|
// Cancel their subscription, if it exists
|
||||||
|
|
||||||
subs_unsubscribe_to($other->getUser(),$this->getProfile());
|
$otherUser = User::staticGet('id', $other->id);
|
||||||
|
|
||||||
|
if (!empty($otherUser)) {
|
||||||
|
subs_unsubscribe_to($otherUser, $this->getProfile());
|
||||||
|
}
|
||||||
|
|
||||||
$block->query('COMMIT');
|
$block->query('COMMIT');
|
||||||
|
|
||||||
|
|
123
js/geometa.js
123
js/geometa.js
|
@ -1,4 +1,4 @@
|
||||||
// A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API
|
// A shim to implement the W3C Geolocation API Specification using Gears
|
||||||
if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) (function(){
|
if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) (function(){
|
||||||
|
|
||||||
// -- BEGIN GEARS_INIT
|
// -- BEGIN GEARS_INIT
|
||||||
|
@ -96,122 +96,9 @@ var GearsGeoLocation = (function() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
var AjaxGeoLocation = (function() {
|
// If you have Gears installed use that
|
||||||
// -- PRIVATE
|
if (window.google && google.gears) {
|
||||||
var loading = false;
|
navigator.geolocation = GearsGeoLocation();
|
||||||
var loadGoogleLoader = function() {
|
}
|
||||||
if (!hasGoogleLoader() && !loading) {
|
|
||||||
loading = true;
|
|
||||||
var s = document.createElement('script');
|
|
||||||
s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
|
|
||||||
s.type = "text/javascript";
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(s);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var queue = [];
|
|
||||||
var addLocationQueue = function(callback) {
|
|
||||||
queue.push(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
var runLocationQueue = function() {
|
|
||||||
if (hasGoogleLoader()) {
|
|
||||||
while (queue.length > 0) {
|
|
||||||
var call = queue.pop();
|
|
||||||
call();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window['_google_loader_apiLoaded'] = function() {
|
|
||||||
runLocationQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasGoogleLoader = function() {
|
|
||||||
return (window['google'] && google['loader']);
|
|
||||||
}
|
|
||||||
|
|
||||||
var checkGoogleLoader = function(callback) {
|
|
||||||
if (hasGoogleLoader()) return true;
|
|
||||||
|
|
||||||
addLocationQueue(callback);
|
|
||||||
|
|
||||||
loadGoogleLoader();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
loadGoogleLoader(); // start to load as soon as possible just in case
|
|
||||||
|
|
||||||
// -- PUBLIC
|
|
||||||
return {
|
|
||||||
shim: true,
|
|
||||||
|
|
||||||
type: "ClientLocation",
|
|
||||||
|
|
||||||
lastPosition: null,
|
|
||||||
|
|
||||||
getCurrentPosition: function(successCallback, errorCallback, options) {
|
|
||||||
var self = this;
|
|
||||||
if (!checkGoogleLoader(function() {
|
|
||||||
self.getCurrentPosition(successCallback, errorCallback, options);
|
|
||||||
})) return;
|
|
||||||
|
|
||||||
if (google.loader.ClientLocation) {
|
|
||||||
var cl = google.loader.ClientLocation;
|
|
||||||
|
|
||||||
var position = {
|
|
||||||
coords: {
|
|
||||||
latitude: cl.latitude,
|
|
||||||
longitude: cl.longitude,
|
|
||||||
altitude: null,
|
|
||||||
accuracy: 43000, // same as Gears accuracy over wifi?
|
|
||||||
altitudeAccuracy: null,
|
|
||||||
heading: null,
|
|
||||||
speed: null,
|
|
||||||
},
|
|
||||||
// extra info that is outside of the bounds of the core API
|
|
||||||
address: {
|
|
||||||
city: cl.address.city,
|
|
||||||
country: cl.address.country,
|
|
||||||
country_code: cl.address.country_code,
|
|
||||||
region: cl.address.region
|
|
||||||
},
|
|
||||||
timestamp: new Date()
|
|
||||||
};
|
|
||||||
|
|
||||||
successCallback(position);
|
|
||||||
|
|
||||||
this.lastPosition = position;
|
|
||||||
} else if (errorCallback === "function") {
|
|
||||||
errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watchPosition: function(successCallback, errorCallback, options) {
|
|
||||||
this.getCurrentPosition(successCallback, errorCallback, options);
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
var watchId = setInterval(function() {
|
|
||||||
self.getCurrentPosition(successCallback, errorCallback, options);
|
|
||||||
}, 10000);
|
|
||||||
|
|
||||||
return watchId;
|
|
||||||
},
|
|
||||||
|
|
||||||
clearWatch: function(watchId) {
|
|
||||||
clearInterval(watchId);
|
|
||||||
},
|
|
||||||
|
|
||||||
getPermission: function(siteName, imageUrl, extraMessage) {
|
|
||||||
// for now just say yes :)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// If you have Gears installed use that, else use Ajax ClientLocation
|
|
||||||
navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
203
plugins/Blacklist/BlacklistPlugin.php
Normal file
203
plugins/Blacklist/BlacklistPlugin.php
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Plugin to prevent use of nicknames or URLs on a blacklist
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2009 StatusNet Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin to prevent use of nicknames or URLs on a blacklist
|
||||||
|
*
|
||||||
|
* @category Plugin
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BlacklistPlugin extends Plugin
|
||||||
|
{
|
||||||
|
public $nicknames = array();
|
||||||
|
public $urls = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook registration to prevent blacklisted homepages or nicknames
|
||||||
|
*
|
||||||
|
* Throws an exception if there's a blacklisted homepage or nickname.
|
||||||
|
*
|
||||||
|
* @param Action $action Action being called (usually register)
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onStartRegistrationTry($action)
|
||||||
|
{
|
||||||
|
$homepage = strtolower($action->trimmed('homepage'));
|
||||||
|
|
||||||
|
if (!empty($homepage)) {
|
||||||
|
if (!$this->_checkUrl($homepage)) {
|
||||||
|
$msg = sprintf(_m("You may not register with homepage '%s'"),
|
||||||
|
$homepage);
|
||||||
|
throw new ClientException($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$nickname = strtolower($action->trimmed('nickname'));
|
||||||
|
|
||||||
|
if (!empty($nickname)) {
|
||||||
|
if (!$this->_checkNickname($nickname)) {
|
||||||
|
$msg = sprintf(_m("You may not register with nickname '%s'"),
|
||||||
|
$nickname);
|
||||||
|
throw new ClientException($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook profile update to prevent blacklisted homepages or nicknames
|
||||||
|
*
|
||||||
|
* Throws an exception if there's a blacklisted homepage or nickname.
|
||||||
|
*
|
||||||
|
* @param Action $action Action being called (usually register)
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onStartProfileSaveForm($action)
|
||||||
|
{
|
||||||
|
$homepage = strtolower($action->trimmed('homepage'));
|
||||||
|
|
||||||
|
if (!empty($homepage)) {
|
||||||
|
if (!$this->_checkUrl($homepage)) {
|
||||||
|
$msg = sprintf(_m("You may not use homepage '%s'"),
|
||||||
|
$homepage);
|
||||||
|
throw new ClientException($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$nickname = strtolower($action->trimmed('nickname'));
|
||||||
|
|
||||||
|
if (!empty($nickname)) {
|
||||||
|
if (!$this->_checkNickname($nickname)) {
|
||||||
|
$msg = sprintf(_m("You may not use nickname '%s'"),
|
||||||
|
$nickname);
|
||||||
|
throw new ClientException($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook notice save to prevent blacklisted urls
|
||||||
|
*
|
||||||
|
* Throws an exception if there's a blacklisted url in the content.
|
||||||
|
*
|
||||||
|
* @param Notice &$notice Notice being saved
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onStartNoticeSave(&$notice)
|
||||||
|
{
|
||||||
|
common_replace_urls_callback($notice->content,
|
||||||
|
array($this, 'checkNoticeUrl'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper callback for notice save
|
||||||
|
*
|
||||||
|
* Throws an exception if there's a blacklisted url in the content.
|
||||||
|
*
|
||||||
|
* @param string $url URL in the notice content
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function checkNoticeUrl($url)
|
||||||
|
{
|
||||||
|
// It comes in special'd, so we unspecial it
|
||||||
|
// before comparing against patterns
|
||||||
|
|
||||||
|
$url = htmlspecialchars_decode($url);
|
||||||
|
|
||||||
|
if (!$this->_checkUrl($url)) {
|
||||||
|
$msg = sprintf(_m("You may not use url '%s' in notices"),
|
||||||
|
$url);
|
||||||
|
throw new ClientException($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for checking URLs
|
||||||
|
*
|
||||||
|
* Checks an URL against our patterns for a match.
|
||||||
|
*
|
||||||
|
* @param string $url URL to check
|
||||||
|
*
|
||||||
|
* @return boolean true means it's OK, false means it's bad
|
||||||
|
*/
|
||||||
|
|
||||||
|
private function _checkUrl($url)
|
||||||
|
{
|
||||||
|
foreach ($this->urls as $pattern) {
|
||||||
|
if (preg_match("/$pattern/", $url)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for checking nicknames
|
||||||
|
*
|
||||||
|
* Checks a nickname against our patterns for a match.
|
||||||
|
*
|
||||||
|
* @param string $nickname nickname to check
|
||||||
|
*
|
||||||
|
* @return boolean true means it's OK, false means it's bad
|
||||||
|
*/
|
||||||
|
|
||||||
|
private function _checkNickname($nickname)
|
||||||
|
{
|
||||||
|
foreach ($this->nicknames as $pattern) {
|
||||||
|
if (preg_match("/$pattern/", $nickname)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('STATUSNET')) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,20 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
|
||||||
class UserFlagPlugin extends Plugin
|
class UserFlagPlugin extends Plugin
|
||||||
{
|
{
|
||||||
|
const REVIEWFLAGS = 'UserFlagPlugin::reviewflags';
|
||||||
|
const CLEARFLAGS = 'UserFlagPlugin::clearflags';
|
||||||
|
|
||||||
|
public $flagOnBlock = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for ensuring our tables are created
|
||||||
|
*
|
||||||
|
* Ensures that the user_flag_profile table exists
|
||||||
|
* and has the right columns.
|
||||||
|
*
|
||||||
|
* @return boolean hook return
|
||||||
|
*/
|
||||||
|
|
||||||
function onCheckSchema()
|
function onCheckSchema()
|
||||||
{
|
{
|
||||||
$schema = Schema::get();
|
$schema = Schema::get();
|
||||||
|
@ -62,37 +76,61 @@ class UserFlagPlugin extends Plugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInitializePlugin()
|
/**
|
||||||
{
|
* Add our actions to the URL router
|
||||||
// XXX: do something here?
|
*
|
||||||
return true;
|
* @param Net_URL_Mapper $m URL mapper for this hit
|
||||||
}
|
*
|
||||||
|
* @return boolean hook return
|
||||||
|
*/
|
||||||
|
|
||||||
function onRouterInitialized($m) {
|
function onRouterInitialized($m)
|
||||||
|
{
|
||||||
$m->connect('main/flag/profile', array('action' => 'flagprofile'));
|
$m->connect('main/flag/profile', array('action' => 'flagprofile'));
|
||||||
|
$m->connect('main/flag/clear', array('action' => 'clearflag'));
|
||||||
$m->connect('admin/profile/flag', array('action' => 'adminprofileflag'));
|
$m->connect('admin/profile/flag', array('action' => 'adminprofileflag'));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAutoload($cls)
|
/**
|
||||||
|
* Auto-load our classes if called
|
||||||
|
*
|
||||||
|
* @param string $cls Class to load
|
||||||
|
*
|
||||||
|
* @return boolean hook return
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onAutoload($cls)
|
||||||
{
|
{
|
||||||
switch ($cls)
|
switch ($cls)
|
||||||
{
|
{
|
||||||
case 'FlagprofileAction':
|
case 'FlagprofileAction':
|
||||||
case 'AdminprofileflagAction':
|
case 'AdminprofileflagAction':
|
||||||
require_once(INSTALLDIR.'/plugins/UserFlag/' . strtolower(mb_substr($cls, 0, -6)) . '.php');
|
case 'ClearflagAction':
|
||||||
|
include_once INSTALLDIR.'/plugins/UserFlag/' .
|
||||||
|
strtolower(mb_substr($cls, 0, -6)) . '.php';
|
||||||
return false;
|
return false;
|
||||||
case 'FlagProfileForm':
|
case 'FlagProfileForm':
|
||||||
require_once(INSTALLDIR.'/plugins/UserFlag/' . strtolower($cls . '.php'));
|
case 'ClearFlagForm':
|
||||||
|
include_once INSTALLDIR.'/plugins/UserFlag/' . strtolower($cls . '.php');
|
||||||
return false;
|
return false;
|
||||||
case 'User_flag_profile':
|
case 'User_flag_profile':
|
||||||
require_once(INSTALLDIR.'/plugins/UserFlag/'.$cls.'.php');
|
include_once INSTALLDIR.'/plugins/UserFlag/'.$cls.'.php';
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a 'flag' button to profile page
|
||||||
|
*
|
||||||
|
* @param Action &$action The action being called
|
||||||
|
* @param Profile $profile Profile being shown
|
||||||
|
*
|
||||||
|
* @return boolean hook result
|
||||||
|
*/
|
||||||
|
|
||||||
function onEndProfilePageActionsElements(&$action, $profile)
|
function onEndProfilePageActionsElements(&$action, $profile)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
@ -105,8 +143,8 @@ class UserFlagPlugin extends Plugin
|
||||||
$action->element('p', 'flagged', _('Flagged'));
|
$action->element('p', 'flagged', _('Flagged'));
|
||||||
} else {
|
} else {
|
||||||
$form = new FlagProfileForm($action, $profile,
|
$form = new FlagProfileForm($action, $profile,
|
||||||
array('action' => 'showstream',
|
array('action' => 'showstream',
|
||||||
'nickname' => $profile->nickname));
|
'nickname' => $profile->nickname));
|
||||||
$form->show();
|
$form->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +154,14 @@ class UserFlagPlugin extends Plugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a 'flag' button to profiles in a list
|
||||||
|
*
|
||||||
|
* @param ProfileListItem $item item being shown
|
||||||
|
*
|
||||||
|
* @return boolean hook result
|
||||||
|
*/
|
||||||
|
|
||||||
function onEndProfileListItemActionElements($item)
|
function onEndProfileListItemActionElements($item)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
@ -136,16 +182,78 @@ class UserFlagPlugin extends Plugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add our plugin's CSS to page output
|
||||||
|
*
|
||||||
|
* @param Action $action action being shown
|
||||||
|
*
|
||||||
|
* @return boolean hook result
|
||||||
|
*/
|
||||||
|
|
||||||
function onEndShowStatusNetStyles($action)
|
function onEndShowStatusNetStyles($action)
|
||||||
{
|
{
|
||||||
$action->cssLink(common_path('plugins/UserFlag/userflag.css'),
|
$action->cssLink(common_path('plugins/UserFlag/userflag.css'),
|
||||||
null, 'screen, projection, tv');
|
null, 'screen, projection, tv');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize any flagging buttons on the page
|
||||||
|
*
|
||||||
|
* @param Action $action action being shown
|
||||||
|
*
|
||||||
|
* @return boolean hook result
|
||||||
|
*/
|
||||||
|
|
||||||
function onEndShowScripts($action)
|
function onEndShowScripts($action)
|
||||||
{
|
{
|
||||||
$action->inlineScript('if ($(".form_entity_flag").length > 0) { SN.U.FormXHR($(".form_entity_flag")); }');
|
$action->inlineScript('if ($(".form_entity_flag").length > 0) { '.
|
||||||
|
'SN.U.FormXHR($(".form_entity_flag")); '.
|
||||||
|
'}');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a user has one of our defined rights
|
||||||
|
*
|
||||||
|
* We define extra rights; this function checks to see if a
|
||||||
|
* user has one of them.
|
||||||
|
*
|
||||||
|
* @param User $user User being checked
|
||||||
|
* @param string $right Right we're checking
|
||||||
|
* @param boolean &$result out, result of the check
|
||||||
|
*
|
||||||
|
* @return boolean hook result
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onUserRightsCheck($user, $right, &$result)
|
||||||
|
{
|
||||||
|
switch ($right) {
|
||||||
|
case self::REVIEWFLAGS:
|
||||||
|
case self::CLEARFLAGS:
|
||||||
|
$result = $user->hasRole('moderator');
|
||||||
|
return false; // done processing!
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // unchanged!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally flag profile when a block happens
|
||||||
|
*
|
||||||
|
* We optionally add a flag when a profile has been blocked
|
||||||
|
*
|
||||||
|
* @param User $user User doing the block
|
||||||
|
* @param Profile $profile Profile being blocked
|
||||||
|
*
|
||||||
|
* @return boolean hook result
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onEndBlockProfile($user, $profile)
|
||||||
|
{
|
||||||
|
if ($this->flagOnBlock) {
|
||||||
|
User_flag_profile::create($user->id, $profile->id);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
|
* Data class for profile flags
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Data
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
* Copyright (C) 2009, StatusNet, Inc.
|
* Copyright (C) 2009, StatusNet, Inc.
|
||||||
*
|
*
|
||||||
|
@ -23,6 +33,18 @@ if (!defined('STATUSNET')) {
|
||||||
|
|
||||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data class for profile flags
|
||||||
|
*
|
||||||
|
* A class representing a user flagging another profile for review.
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
class User_flag_profile extends Memcached_DataObject
|
class User_flag_profile extends Memcached_DataObject
|
||||||
{
|
{
|
||||||
###START_AUTOCODE
|
###START_AUTOCODE
|
||||||
|
@ -40,7 +62,14 @@ class User_flag_profile extends Memcached_DataObject
|
||||||
/* the code above is auto generated do not remove the tag below */
|
/* the code above is auto generated do not remove the tag below */
|
||||||
###END_AUTOCODE
|
###END_AUTOCODE
|
||||||
|
|
||||||
function table() {
|
/**
|
||||||
|
* return table definition for DB_DataObject
|
||||||
|
*
|
||||||
|
* @return array array of column definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
function table()
|
||||||
|
{
|
||||||
return array(
|
return array(
|
||||||
'profile_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
'profile_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||||
'user_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
'user_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||||
|
@ -49,15 +78,39 @@ class User_flag_profile extends Memcached_DataObject
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function keys() {
|
/**
|
||||||
|
* return key definitions for DB_DataObject
|
||||||
|
*
|
||||||
|
* @return array key definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
function keys()
|
||||||
|
{
|
||||||
return array('profile_id' => 'N', 'user_id' => 'N');
|
return array('profile_id' => 'N', 'user_id' => 'N');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single object with multiple keys
|
||||||
|
*
|
||||||
|
* @param array $kv Map of key-value pairs
|
||||||
|
*
|
||||||
|
* @return User_flag_profile found object or null
|
||||||
|
*/
|
||||||
|
|
||||||
function &pkeyGet($kv)
|
function &pkeyGet($kv)
|
||||||
{
|
{
|
||||||
return Memcached_DataObject::pkeyGet('User_flag_profile', $kv);
|
return Memcached_DataObject::pkeyGet('User_flag_profile', $kv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a flag exists for given profile and user
|
||||||
|
*
|
||||||
|
* @param integer $profile_id Profile to check for
|
||||||
|
* @param integer $user_id User to check for
|
||||||
|
*
|
||||||
|
* @return boolean true if exists, else false
|
||||||
|
*/
|
||||||
|
|
||||||
static function exists($profile_id, $user_id)
|
static function exists($profile_id, $user_id)
|
||||||
{
|
{
|
||||||
$ufp = User_flag_profile::pkeyGet(array('profile_id' => $profile_id,
|
$ufp = User_flag_profile::pkeyGet(array('profile_id' => $profile_id,
|
||||||
|
@ -65,4 +118,23 @@ class User_flag_profile extends Memcached_DataObject
|
||||||
|
|
||||||
return !empty($ufp);
|
return !empty($ufp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function create($user_id, $profile_id)
|
||||||
|
{
|
||||||
|
$ufp = new User_flag_profile();
|
||||||
|
|
||||||
|
$ufp->profile_id = $profile_id;
|
||||||
|
$ufp->user_id = $user_id;
|
||||||
|
$ufp->created = common_sql_now();
|
||||||
|
|
||||||
|
if (!$ufp->insert()) {
|
||||||
|
$msg = sprintf(_("Couldn't flag profile '%d' for review."),
|
||||||
|
$profile_id);
|
||||||
|
throw new ServerException($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ufp->free();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ if (!defined('STATUSNET')) {
|
||||||
|
|
||||||
class AdminprofileflagAction extends Action
|
class AdminprofileflagAction extends Action
|
||||||
{
|
{
|
||||||
|
var $page = null;
|
||||||
|
var $profiles = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take arguments for running
|
* Take arguments for running
|
||||||
*
|
*
|
||||||
|
@ -55,6 +58,47 @@ class AdminprofileflagAction extends Action
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$user = common_current_user();
|
||||||
|
|
||||||
|
// User must be logged in.
|
||||||
|
|
||||||
|
if (!common_logged_in()) {
|
||||||
|
$this->clientError(_('Not logged in.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = common_current_user();
|
||||||
|
|
||||||
|
// ...because they're logged in
|
||||||
|
|
||||||
|
assert(!empty($user));
|
||||||
|
|
||||||
|
// It must be a "real" login, not saved cookie login
|
||||||
|
|
||||||
|
if (!common_is_real_login()) {
|
||||||
|
// Cookie theft is too easy; we require automatic
|
||||||
|
// logins to re-authenticate before admining the site
|
||||||
|
common_set_returnto($this->selfUrl());
|
||||||
|
if (Event::handle('RedirectToLogin', array($this, $user))) {
|
||||||
|
common_redirect(common_local_url('login'), 303);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User must have the right to review flags
|
||||||
|
|
||||||
|
if (!$user->hasRight(UserFlagPlugin::REVIEWFLAGS)) {
|
||||||
|
$this->clientError(_('You cannot review profile flags.'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->page = $this->trimmed('page');
|
||||||
|
|
||||||
|
if (empty($this->page)) {
|
||||||
|
$this->page = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->profiles = $this->getProfiles();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +117,14 @@ class AdminprofileflagAction extends Action
|
||||||
$this->showPage();
|
$this->showPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
function title() {
|
/**
|
||||||
|
* Title of this page
|
||||||
|
*
|
||||||
|
* @return string Title of the page
|
||||||
|
*/
|
||||||
|
|
||||||
|
function title()
|
||||||
|
{
|
||||||
return _('Flagged profiles');
|
return _('Flagged profiles');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,13 +136,20 @@ class AdminprofileflagAction extends Action
|
||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$profile = $this->getProfiles();
|
$pl = new FlaggedProfileList($this->profiles, $this);
|
||||||
|
|
||||||
$pl = new FlaggedProfileList($profile, $this);
|
$cnt = $pl->show();
|
||||||
|
|
||||||
$pl->show();
|
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
|
||||||
|
$this->page, 'adminprofileflag');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve this action's profiles
|
||||||
|
*
|
||||||
|
* @return Profile $profile Profile query results
|
||||||
|
*/
|
||||||
|
|
||||||
function getProfiles()
|
function getProfiles()
|
||||||
{
|
{
|
||||||
$ufp = new User_flag_profile();
|
$ufp = new User_flag_profile();
|
||||||
|
@ -103,7 +161,12 @@ class AdminprofileflagAction extends Action
|
||||||
$ufp->whereAdd('cleared is NULL');
|
$ufp->whereAdd('cleared is NULL');
|
||||||
|
|
||||||
$ufp->groupBy('profile_id');
|
$ufp->groupBy('profile_id');
|
||||||
$ufp->orderBy('flag_count DESC');
|
$ufp->orderBy('flag_count DESC, profile_id DESC');
|
||||||
|
|
||||||
|
$offset = ($this->page-1) * PROFILES_PER_PAGE;
|
||||||
|
$limit = PROFILES_PER_PAGE + 1;
|
||||||
|
|
||||||
|
$ufp->limit($offset, $limit);
|
||||||
|
|
||||||
$profiles = array();
|
$profiles = array();
|
||||||
|
|
||||||
|
@ -122,7 +185,27 @@ class AdminprofileflagAction extends Action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FlaggedProfileList extends ProfileList {
|
/**
|
||||||
|
* Specialization of ProfileList to show flagging information
|
||||||
|
*
|
||||||
|
* Most of the hard part is done in FlaggedProfileListItem.
|
||||||
|
*
|
||||||
|
* @category Widget
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class FlaggedProfileList extends ProfileList
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Factory method for creating new list items
|
||||||
|
*
|
||||||
|
* @param Profile $profile Profile to create an item for
|
||||||
|
*
|
||||||
|
* @return ProfileListItem newly-created item
|
||||||
|
*/
|
||||||
|
|
||||||
function newListItem($profile)
|
function newListItem($profile)
|
||||||
{
|
{
|
||||||
|
@ -130,11 +213,29 @@ class FlaggedProfileList extends ProfileList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization of ProfileListItem to show flagging information
|
||||||
|
*
|
||||||
|
* @category Widget
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
class FlaggedProfileListItem extends ProfileListItem
|
class FlaggedProfileListItem extends ProfileListItem
|
||||||
{
|
{
|
||||||
var $user = null;
|
const MAX_FLAGGERS = 5;
|
||||||
|
|
||||||
|
var $user = null;
|
||||||
var $r2args = null;
|
var $r2args = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overload parent's action list with our own moderation-oriented buttons
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
function showActions()
|
function showActions()
|
||||||
{
|
{
|
||||||
$this->user = common_current_user();
|
$this->user = common_current_user();
|
||||||
|
@ -159,6 +260,12 @@ class FlaggedProfileListItem extends ProfileListItem
|
||||||
$this->endActions();
|
$this->endActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a button to sandbox the profile
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
function showSandboxButton()
|
function showSandboxButton()
|
||||||
{
|
{
|
||||||
if ($this->user->hasRight(Right::SANDBOXUSER)) {
|
if ($this->user->hasRight(Right::SANDBOXUSER)) {
|
||||||
|
@ -174,6 +281,12 @@ class FlaggedProfileListItem extends ProfileListItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a button to silence the profile
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
function showSilenceButton()
|
function showSilenceButton()
|
||||||
{
|
{
|
||||||
if ($this->user->hasRight(Right::SILENCEUSER)) {
|
if ($this->user->hasRight(Right::SILENCEUSER)) {
|
||||||
|
@ -189,6 +302,12 @@ class FlaggedProfileListItem extends ProfileListItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a button to delete user and profile
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
function showDeleteButton()
|
function showDeleteButton()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -200,7 +319,92 @@ class FlaggedProfileListItem extends ProfileListItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a button to clear flags
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
function showClearButton()
|
function showClearButton()
|
||||||
{
|
{
|
||||||
|
if ($this->user->hasRight(UserFlagPlugin::CLEARFLAGS)) {
|
||||||
|
$this->out->elementStart('li', 'entity_clear');
|
||||||
|
$cf = new ClearFlagForm($this->out, $this->profile, $this->r2args);
|
||||||
|
$cf->show();
|
||||||
|
$this->out->elementEnd('li');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overload parent function to add flaggers list
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function endProfile()
|
||||||
|
{
|
||||||
|
$this->showFlaggersList();
|
||||||
|
parent::endProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a list of people who've flagged this profile
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showFlaggersList()
|
||||||
|
{
|
||||||
|
$flaggers = array();
|
||||||
|
|
||||||
|
$ufp = new User_flag_profile();
|
||||||
|
|
||||||
|
$ufp->selectAdd();
|
||||||
|
$ufp->selectAdd('user_id');
|
||||||
|
$ufp->profile_id = $this->profile->id;
|
||||||
|
$ufp->orderBy('created');
|
||||||
|
|
||||||
|
if ($ufp->find()) { // XXX: this should always happen
|
||||||
|
while ($ufp->fetch()) {
|
||||||
|
$user = User::staticGet('id', $ufp->user_id);
|
||||||
|
if (!empty($user)) { // XXX: this would also be unusual
|
||||||
|
$flaggers[] = clone($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$cnt = count($flaggers);
|
||||||
|
$others = 0;
|
||||||
|
|
||||||
|
if ($cnt > self::MAX_FLAGGERS) {
|
||||||
|
$flaggers = array_slice($flaggers, 0, self::MAX_FLAGGERS);
|
||||||
|
$others = $cnt - self::MAX_FLAGGERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lnks = array();
|
||||||
|
|
||||||
|
foreach ($flaggers as $flagger) {
|
||||||
|
|
||||||
|
$url = common_local_url('showstream',
|
||||||
|
array('nickname' => $flagger->nickname));
|
||||||
|
|
||||||
|
$lnks[] = XMLStringer::estring('a', array('href' => $url,
|
||||||
|
'class' => 'flagger'),
|
||||||
|
$flagger->nickname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cnt > 0) {
|
||||||
|
$text = _('Flagged by ');
|
||||||
|
|
||||||
|
$text .= implode(', ', $lnks);
|
||||||
|
|
||||||
|
if ($others > 0) {
|
||||||
|
$text .= sprintf(_(' and %d others'), $others);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementStart('p', array('class' => 'flaggers'));
|
||||||
|
$this->out->raw($text);
|
||||||
|
$this->out->elementEnd('p');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
138
plugins/UserFlag/clearflag.php
Normal file
138
plugins/UserFlag/clearflag.php
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Clear all flags for a profile
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*
|
||||||
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 2009, StatusNet, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to clear flags for a profile
|
||||||
|
*
|
||||||
|
* @category Action
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ClearflagAction extends ProfileFormAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
if (!parent::prepare($args)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = common_current_user();
|
||||||
|
|
||||||
|
assert(!empty($user)); // checked above
|
||||||
|
assert(!empty($this->profile)); // checked above
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle request
|
||||||
|
*
|
||||||
|
* Overriding the base Action's handle() here to deal check
|
||||||
|
* for Ajax and return an HXR response if necessary
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args; handled in prepare()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
$this->handlePost();
|
||||||
|
if (!$this->boolean('ajax')) {
|
||||||
|
$this->returnToArgs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle POST
|
||||||
|
*
|
||||||
|
* Executes the actions; deletes all flags
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
$ufp = new User_flag_profile();
|
||||||
|
|
||||||
|
$result = $ufp->query('UPDATE user_flag_profile ' .
|
||||||
|
'SET cleared = now() ' .
|
||||||
|
'WHERE cleared is null ' .
|
||||||
|
'AND profile_id = ' . $this->profile->id);
|
||||||
|
|
||||||
|
if ($result == false) {
|
||||||
|
$msg = sprintf(_("Couldn't clear flags for profile '%s'."),
|
||||||
|
$this->profile->nickname);
|
||||||
|
throw new ServerException($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ufp->free();
|
||||||
|
|
||||||
|
if ($this->boolean('ajax')) {
|
||||||
|
$this->ajaxResults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return results in ajax form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function ajaxResults()
|
||||||
|
{
|
||||||
|
header('Content-Type: text/xml;charset=utf-8');
|
||||||
|
$this->xw->startDocument('1.0', 'UTF-8');
|
||||||
|
$this->elementStart('html');
|
||||||
|
$this->elementStart('head');
|
||||||
|
$this->element('title', null, _('Flags cleared'));
|
||||||
|
$this->elementEnd('head');
|
||||||
|
$this->elementStart('body');
|
||||||
|
$this->element('p', 'cleared', _('Cleared'));
|
||||||
|
$this->elementEnd('body');
|
||||||
|
$this->elementEnd('html');
|
||||||
|
}
|
||||||
|
}
|
92
plugins/UserFlag/clearflagform.php
Normal file
92
plugins/UserFlag/clearflagform.php
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Form for clearing profile flags
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category Form
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/lib/form.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form for clearing profile flags
|
||||||
|
*
|
||||||
|
* @category Form
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ClearFlagForm extends ProfileActionForm
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* class of the form
|
||||||
|
* Action this form provides
|
||||||
|
*
|
||||||
|
* @return string class of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formClass()
|
||||||
|
{
|
||||||
|
return 'form_entity_clearflag';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action this form provides
|
||||||
|
*
|
||||||
|
* @return string Name of the action, lowercased.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function target()
|
||||||
|
{
|
||||||
|
return 'clearflag';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title of the form
|
||||||
|
*
|
||||||
|
* @return string Title of the form, internationalized
|
||||||
|
*/
|
||||||
|
|
||||||
|
function title()
|
||||||
|
{
|
||||||
|
return _('Clear');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the form
|
||||||
|
*
|
||||||
|
* @return string description of the form, internationalized
|
||||||
|
*/
|
||||||
|
|
||||||
|
function description()
|
||||||
|
{
|
||||||
|
return _('Clear all flags');
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,8 +63,7 @@ class FlagprofileAction extends ProfileFormAction
|
||||||
assert(!empty($this->profile)); // checked above
|
assert(!empty($this->profile)); // checked above
|
||||||
|
|
||||||
if (User_flag_profile::exists($this->profile->id,
|
if (User_flag_profile::exists($this->profile->id,
|
||||||
$user->id))
|
$user->id)) {
|
||||||
{
|
|
||||||
$this->clientError(_('Flag already exists.'));
|
$this->clientError(_('Flag already exists.'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,6 @@ class FlagprofileAction extends ProfileFormAction
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle request
|
* Handle request
|
||||||
*
|
*
|
||||||
|
@ -107,25 +105,23 @@ class FlagprofileAction extends ProfileFormAction
|
||||||
assert(!empty($user));
|
assert(!empty($user));
|
||||||
assert(!empty($this->profile));
|
assert(!empty($this->profile));
|
||||||
|
|
||||||
$ufp = new User_flag_profile();
|
// throws an exception on error
|
||||||
|
|
||||||
$ufp->profile_id = $this->profile->id;
|
User_flag_profile::create($user->id, $this->profile->id);
|
||||||
$ufp->user_id = $user->id;
|
|
||||||
$ufp->created = common_sql_now();
|
|
||||||
|
|
||||||
if (!$ufp->insert()) {
|
|
||||||
throw new ServerException(sprintf(_("Couldn't flag profile '%s' for review."),
|
|
||||||
$this->profile->nickname));
|
|
||||||
}
|
|
||||||
|
|
||||||
$ufp->free();
|
|
||||||
|
|
||||||
if ($this->boolean('ajax')) {
|
if ($this->boolean('ajax')) {
|
||||||
$this->ajaxResults();
|
$this->ajaxResults();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ajaxResults() {
|
/**
|
||||||
|
* Return results as AJAX message
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function ajaxResults()
|
||||||
|
{
|
||||||
header('Content-Type: text/xml;charset=utf-8');
|
header('Content-Type: text/xml;charset=utf-8');
|
||||||
$this->xw->startDocument('1.0', 'UTF-8');
|
$this->xw->startDocument('1.0', 'UTF-8');
|
||||||
$this->elementStart('html');
|
$this->elementStart('html');
|
||||||
|
|
98
scripts/setconfig.php
Normal file
98
scripts/setconfig.php
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* StatusNet - a distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
|
$shortoptions = 'd';
|
||||||
|
$longoptions = array('delete');
|
||||||
|
|
||||||
|
$helptext = <<<END_OF_SETCONFIG_HELP
|
||||||
|
setconfig.php [options] [section] [setting] <value>
|
||||||
|
With three args, set the setting to the value.
|
||||||
|
With two args, just show the setting.
|
||||||
|
With -d, delete the setting.
|
||||||
|
|
||||||
|
[section] section to use (required)
|
||||||
|
[setting] setting to use (required)
|
||||||
|
<value> value to set (optional)
|
||||||
|
|
||||||
|
-d --delete delete the setting (no value)
|
||||||
|
|
||||||
|
END_OF_SETCONFIG_HELP;
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
|
|
||||||
|
if (count($args) < 2 || count($args) > 3) {
|
||||||
|
show_help();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$section = $args[0];
|
||||||
|
$setting = $args[1];
|
||||||
|
|
||||||
|
if (count($args) == 3) {
|
||||||
|
$value = $args[2];
|
||||||
|
} else {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (have_option('d', 'delete')) { // Delete
|
||||||
|
if (count($args) != 2) {
|
||||||
|
show_help();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_option('v', 'verbose')) {
|
||||||
|
print "Deleting setting $section/$setting...";
|
||||||
|
}
|
||||||
|
|
||||||
|
$setting = Config::pkeyGet(array('section' => $section,
|
||||||
|
'setting' => $setting));
|
||||||
|
|
||||||
|
if (empty($setting)) {
|
||||||
|
print "Not found.\n";
|
||||||
|
} else {
|
||||||
|
$result = $setting->delete();
|
||||||
|
if ($result) {
|
||||||
|
print "DONE.\n";
|
||||||
|
} else {
|
||||||
|
print "ERROR.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (count($args) == 2) { // show
|
||||||
|
if (have_option('v', 'verbose')) {
|
||||||
|
print "$section/$setting = ";
|
||||||
|
}
|
||||||
|
$value = common_config($section, $setting);
|
||||||
|
print "$value\n";
|
||||||
|
} else { // set
|
||||||
|
if (have_option('v', 'verbose')) {
|
||||||
|
print "Setting $section/$setting...";
|
||||||
|
}
|
||||||
|
Config::save($section, $setting, $value);
|
||||||
|
print "DONE.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
print $e->getMessage() . "\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user