Merge branch 'nightly' into file_urlhash
This commit is contained in:
commit
176bde269f
1
INSTALL
1
INSTALL
|
@ -41,6 +41,7 @@ functional setup of GNU Social:
|
|||
- php5-curl Fetching files by HTTP.
|
||||
- php5-gd Image manipulation (scaling).
|
||||
- php5-gmp For Salmon signatures (part of OStatus).
|
||||
- php5-intl Internationalization support (transliteration et al).
|
||||
- php5-json For WebFinger lookups and more.
|
||||
- php5-mysqlnd The native driver for PHP5 MariaDB connections. If you
|
||||
use MySQL, 'mysql' or 'mysqli' may work.
|
||||
|
|
|
@ -405,7 +405,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
|||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$rendered = common_purify($sourceContent);
|
||||
$content = common_strip_html($rendered);
|
||||
|
||||
$shortened = $this->auth_user->shortenLinks($content);
|
||||
|
@ -504,13 +504,4 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
|||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
function purify($content)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
return htmLawed($content, $config);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ class EmailsettingsAction extends SettingsAction
|
|||
*/
|
||||
function savePreferences()
|
||||
{
|
||||
$user = common_current_user();
|
||||
$user = $this->scoped->getUser();
|
||||
|
||||
if (Event::handle('StartEmailSaveForm', array($this, $this->scoped))) {
|
||||
$emailnotifysub = $this->boolean('emailnotifysub');
|
||||
|
@ -323,8 +323,6 @@ class EmailsettingsAction extends SettingsAction
|
|||
$emailmicroid = $this->boolean('emailmicroid');
|
||||
$emailpost = $this->boolean('emailpost');
|
||||
|
||||
assert(!is_null($user)); // should already be checked
|
||||
|
||||
$user->query('BEGIN');
|
||||
|
||||
$original = clone($user);
|
||||
|
@ -340,6 +338,7 @@ class EmailsettingsAction extends SettingsAction
|
|||
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
$user->query('ROLLBACK');
|
||||
// TRANS: Server error thrown on database error updating e-mail preferences.
|
||||
$this->serverError(_('Could not update user.'));
|
||||
}
|
||||
|
|
|
@ -299,6 +299,11 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
|||
return $ckeys;
|
||||
}
|
||||
|
||||
public function escapedTableName()
|
||||
{
|
||||
return common_database_tablename($this->tableName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ID, checked that it is set and reasonably valid
|
||||
*
|
||||
|
|
|
@ -213,7 +213,7 @@ class ActivityImporter extends QueueHandler
|
|||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$rendered = common_purify($sourceContent);
|
||||
$content = common_strip_html($rendered);
|
||||
|
||||
$shortened = $user->shortenLinks($content);
|
||||
|
@ -338,15 +338,4 @@ class ActivityImporter extends QueueHandler
|
|||
|
||||
return array($groups, $replies);
|
||||
}
|
||||
|
||||
|
||||
function purify($content)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
|
||||
return htmLawed($content, $config);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,6 +207,9 @@ $default =
|
|||
'newuser' =>
|
||||
array('default' => null,
|
||||
'welcome' => null),
|
||||
'linkify' => array(
|
||||
'bare_domains' => false, // convert domain.com to <a href="http://domain.com/" ...>domain.com</a> ?
|
||||
),
|
||||
'attachments' =>
|
||||
array('server' => null,
|
||||
'dir' => INSTALLDIR . '/file/',
|
||||
|
|
|
@ -101,7 +101,7 @@ abstract class Installer
|
|||
$pass = false;
|
||||
}
|
||||
|
||||
$reqs = array('gd', 'curl', 'json',
|
||||
$reqs = array('gd', 'curl', 'intl', 'json',
|
||||
'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
|
||||
|
||||
foreach ($reqs as $req) {
|
||||
|
|
75
lib/util.php
75
lib/util.php
|
@ -576,6 +576,25 @@ function common_canonical_email($email)
|
|||
return $email;
|
||||
}
|
||||
|
||||
function common_purify($html)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
|
||||
$html = common_remove_unicode_formatting($html);
|
||||
|
||||
return htmLawed($html, $config);
|
||||
}
|
||||
|
||||
function common_remove_unicode_formatting($text)
|
||||
{
|
||||
// Strip Unicode text formatting/direction codes
|
||||
// this is pretty dangerous for visualisation of text and can be used for mischief
|
||||
return preg_replace('/[\\x{200b}-\\x{200f}\\x{202a}-\\x{202e}]/u', '', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial notice markup rendering step: build links to !group references.
|
||||
*
|
||||
|
@ -585,9 +604,9 @@ function common_canonical_email($email)
|
|||
*/
|
||||
function common_render_content($text, Notice $notice)
|
||||
{
|
||||
$r = common_render_text($text);
|
||||
$r = common_linkify_mentions($r, $notice);
|
||||
return $r;
|
||||
$text = common_render_text($text);
|
||||
$text = common_linkify_mentions($text, $notice);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -829,14 +848,15 @@ function common_find_mentions_raw($text)
|
|||
|
||||
function common_render_text($text)
|
||||
{
|
||||
$r = nl2br(htmlspecialchars($text));
|
||||
$text = common_remove_unicode_formatting($text);
|
||||
$text = nl2br(htmlspecialchars($text));
|
||||
|
||||
$r = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $r);
|
||||
$r = common_replace_urls_callback($r, 'common_linkify');
|
||||
$r = preg_replace_callback('/(^|\"\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/u',
|
||||
function ($m) { return "{$m[1]}#".common_tag_link($m[2]); }, $r);
|
||||
$text = preg_replace('/[\x{0}-\x{8}\x{b}-\x{c}\x{e}-\x{19}]/', '', $text);
|
||||
$text = common_replace_urls_callback($text, 'common_linkify');
|
||||
$text = preg_replace_callback('/(^|\"\;|\'|\(|\[|\{|\s+)#([\pL\pN_\-\.]{1,64})/u',
|
||||
function ($m) { return "{$m[1]}#".common_tag_link($m[2]); }, $text);
|
||||
// XXX: machine tags
|
||||
return $r;
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -870,12 +890,15 @@ function common_replace_urls_callback($text, $callback, $arg = null) {
|
|||
'|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'. //IPv4
|
||||
'|(?:'. //IPv6
|
||||
'\[?(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:(?:[0-9A-Fa-f]{1,4})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::|(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(?::[0-9A-Fa-f]{1,4})))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?::[0-9A-Fa-f]{1,4}){0,1}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?::[0-9A-Fa-f]{1,4}){0,2}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?::[0-9A-Fa-f]{1,4}){0,3}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:)(?::[0-9A-Fa-f]{1,4}){0,4}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?::(?::[0-9A-Fa-f]{1,4}){0,5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))\]?(?<!:)'.
|
||||
')|(?:'. //DNS
|
||||
'(?:[\pN\pL\-\_\+\%\~]+(?:\:[\pN\pL\-\_\+\%\~]+)?\@)?'. //user:pass@
|
||||
'[\pN\pL\-\_]+(?:\.[\pN\pL\-\_]+)*\.'.
|
||||
//tld list from http://data.iana.org/TLD/tlds-alpha-by-domain.txt, also added local, loc, and onion
|
||||
'(?:AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XN--0ZWM56D|测试|XN--11B5BS3A9AJ6G|परीक्षा|XN--80AKHBYKNJ4F|испытание|XN--9T4B11YI5A|테스트|XN--DEBA0AD|טעסט|XN--G6W251D|測試|XN--HGBK6AJ7F53BBA|آزمایشی|XN--HLCJ6AYA9ESC7A|பரிட்சை|XN--JXALPDLP|δοκιμή|XN--KGBECHTV|إختبار|XN--ZCKZAH|テスト|YE|YT|YU|ZA|ZM|ZONE|ZW|local|loc|onion)'.
|
||||
')(?![\pN\pL\-\_])'.
|
||||
')'.
|
||||
(common_config('linkify', 'bare_domains')
|
||||
? '|(?:'. //DNS
|
||||
'(?:[\pN\pL\-\_\+\%\~]+(?:\:[\pN\pL\-\_\+\%\~]+)?\@)?'. //user:pass@
|
||||
'[\pN\pL\-\_]+(?:\.[\pN\pL\-\_]+)*\.'.
|
||||
//tld list from http://data.iana.org/TLD/tlds-alpha-by-domain.txt, also added local, loc, and onion
|
||||
'(?:AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XN--0ZWM56D|测试|XN--11B5BS3A9AJ6G|परीक्षा|XN--80AKHBYKNJ4F|испытание|XN--9T4B11YI5A|테스트|XN--DEBA0AD|טעסט|XN--G6W251D|測試|XN--HGBK6AJ7F53BBA|آزمایشی|XN--HLCJ6AYA9ESC7A|பரிட்சை|XN--JXALPDLP|δοκιμή|XN--KGBECHTV|إختبار|XN--ZCKZAH|テスト|YE|YT|YU|ZA|ZM|ZONE|ZW|local|loc|onion)'.
|
||||
')(?![\pN\pL\-\_])'
|
||||
: '') . // if common_config('linkify', 'bare_domains') is false, don't add anything here
|
||||
')'.
|
||||
'(?:'.
|
||||
'(?:\:\d+)?'. //:port
|
||||
|
@ -1116,6 +1139,20 @@ function common_xml_safe_str($str)
|
|||
return preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str);
|
||||
}
|
||||
|
||||
function common_slugify($str)
|
||||
{
|
||||
$str = transliterator_transliterate(
|
||||
'Any-Latin;' . // any charset to latin compatible
|
||||
'NFD;' . // decompose
|
||||
'[:Nonspacing Mark:] Remove;' . // remove nonspacing marks (accents etc.)
|
||||
'NFC;' . // composite again
|
||||
'[:Punctuation:] Remove;' . // remove punctuation (.,¿? etc.)
|
||||
'Lower();' . // turn into lowercase
|
||||
'Latin-ASCII;', // get ASCII equivalents (ð to d for example)
|
||||
$str);
|
||||
return preg_replace('/[^\pL\pN]/', '', $str);
|
||||
}
|
||||
|
||||
function common_tag_link($tag)
|
||||
{
|
||||
$canonical = common_canonical_tag($tag);
|
||||
|
@ -1139,11 +1176,9 @@ function common_tag_link($tag)
|
|||
|
||||
function common_canonical_tag($tag)
|
||||
{
|
||||
// only alphanum
|
||||
$tag = preg_replace('/[^\pL\pN]/u', '', $tag);
|
||||
$tag = mb_convert_case($tag, MB_CASE_LOWER, "UTF-8");
|
||||
$tag = substr($tag, 0, 64);
|
||||
return $tag;
|
||||
$tag = common_slugify($tag);
|
||||
$tag = substr($tag, 0, 64);
|
||||
return $tag;
|
||||
}
|
||||
|
||||
function common_valid_profile_tag($str)
|
||||
|
|
|
@ -117,10 +117,10 @@ class Blog_entry extends Managed_DataObject
|
|||
$be->id = (string) new UUID();
|
||||
$be->profile_id = $profile->id;
|
||||
$be->title = $title; // Note: not HTML-protected
|
||||
$be->content = self::purify($content);
|
||||
$be->content = common_purify($content);
|
||||
|
||||
if (array_key_exists('summary', $options)) {
|
||||
$be->summary = self::purify($options['summary']);
|
||||
$be->summary = common_purify($options['summary']);
|
||||
} else {
|
||||
// Already purified
|
||||
$be->summary = self::summarize($be->content);
|
||||
|
@ -241,18 +241,4 @@ class Blog_entry extends Managed_DataObject
|
|||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up input HTML
|
||||
*/
|
||||
static function purify($html)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
$pure = htmLawed($html, $config);
|
||||
|
||||
return $pure;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,7 @@
|
|||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET'))
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/publicgroupnav.php';
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* Group directory
|
||||
|
@ -40,10 +35,11 @@ require_once INSTALLDIR . '/lib/publicgroupnav.php';
|
|||
* @category Directory
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class GroupdirectoryAction extends Action
|
||||
class GroupdirectoryAction extends ManagedAction
|
||||
{
|
||||
/**
|
||||
* The page we're on
|
||||
|
@ -138,17 +134,8 @@ class GroupdirectoryAction extends Action
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
protected function doPreparation()
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
|
||||
$this->filter = $this->arg('filter', 'all');
|
||||
$this->reverse = $this->boolean('reverse');
|
||||
|
@ -156,23 +143,6 @@ class GroupdirectoryAction extends Action
|
|||
$this->sort = $this->arg('sort', 'nickname');
|
||||
|
||||
common_set_returnto($this->selfUrl());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request
|
||||
*
|
||||
* Shows the page
|
||||
*
|
||||
* @param array $args $_REQUEST args; handled in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,74 +273,61 @@ class GroupdirectoryAction extends Action
|
|||
{
|
||||
$group = new User_group();
|
||||
|
||||
$offset = ($this->page-1) * PROFILES_PER_PAGE;
|
||||
$limit = PROFILES_PER_PAGE + 1;
|
||||
// Disable this to get global group searches
|
||||
$group->joinAdd(array('id', 'local_group:group_id'));
|
||||
|
||||
if (isset($this->q)) {
|
||||
$order = false;
|
||||
|
||||
$order = 'user_group.created ASC';
|
||||
|
||||
if ($this->sort == 'nickname') {
|
||||
if ($this->reverse) {
|
||||
$order = 'user_group.nickname DESC';
|
||||
} else {
|
||||
$order = 'user_group.nickname ASC';
|
||||
}
|
||||
} else {
|
||||
if ($this->reverse) {
|
||||
$order = 'user_group.created DESC';
|
||||
}
|
||||
}
|
||||
|
||||
$sql = <<< GROUP_QUERY_END
|
||||
SELECT user_group.*
|
||||
FROM user_group
|
||||
JOIN local_group ON user_group.id = local_group.group_id
|
||||
ORDER BY %s
|
||||
LIMIT %d, %d
|
||||
GROUP_QUERY_END;
|
||||
|
||||
$cnt = 0;
|
||||
$group->query(sprintf($sql, $order, $limit, $offset));
|
||||
$group->find();
|
||||
if (!empty($this->q)) {
|
||||
$wheres = array('nickname', 'fullname', 'homepage', 'description', 'location');
|
||||
foreach ($wheres as $where) {
|
||||
// Double % because of sprintf
|
||||
$group->whereAdd(sprintf('LOWER(%1$s.%2$s) LIKE LOWER("%%%3$s%%")',
|
||||
$group->escapedTableName(), $where,
|
||||
$group->escape($this->q)),
|
||||
'OR');
|
||||
}
|
||||
|
||||
$order = sprintf('%1$s.%2$s %3$s',
|
||||
$group->escapedTableName(),
|
||||
$this->getSortKey('created'),
|
||||
$this->reverse ? 'DESC' : 'ASC');
|
||||
} else {
|
||||
// User is browsing via AlphaNav
|
||||
$sort = $this->getSortKey();
|
||||
|
||||
$sql = <<< GROUP_QUERY_END
|
||||
SELECT user_group.*
|
||||
FROM user_group
|
||||
JOIN local_group ON user_group.id = local_group.group_id
|
||||
GROUP_QUERY_END;
|
||||
|
||||
switch($this->filter)
|
||||
{
|
||||
switch($this->filter) {
|
||||
case 'all':
|
||||
// NOOP
|
||||
break;
|
||||
case '0-9':
|
||||
$sql .=
|
||||
' AND LEFT(user_group.nickname, 1) BETWEEN \'0\' AND \'9\'';
|
||||
$group->whereAdd(sprintf('LEFT(%1$s.%2$s, 1) BETWEEN %3$s AND %4$s',
|
||||
$group->escapedTableName(),
|
||||
'nickname',
|
||||
$group->_quote("0"),
|
||||
$group->_quote("9")));
|
||||
break;
|
||||
default:
|
||||
$sql .= sprintf(
|
||||
' AND LEFT(LOWER(user_group.nickname), 1) = \'%s\'',
|
||||
$this->filter
|
||||
);
|
||||
$group->whereAdd(sprintf('LEFT(LOWER(%1$s.%2$s), 1) = %3$s',
|
||||
$group->escapedTableName(),
|
||||
'nickname',
|
||||
$group->_quote($this->filter)));
|
||||
}
|
||||
|
||||
$sql .= sprintf(
|
||||
' ORDER BY user_group.%s %s, user_group.nickname ASC LIMIT %d, %d',
|
||||
$sort,
|
||||
$this->reverse ? 'DESC' : 'ASC',
|
||||
$offset,
|
||||
$limit
|
||||
);
|
||||
|
||||
$group->query($sql);
|
||||
$order = sprintf('%1$s.%2$s %3$s, %1$s.%4$s ASC',
|
||||
$group->escapedTableName(),
|
||||
$this->getSortKey('nickname'),
|
||||
$this->reverse ? 'DESC' : 'ASC',
|
||||
'nickname');
|
||||
}
|
||||
|
||||
$offset = ($this->page-1) * PROFILES_PER_PAGE;
|
||||
$limit = PROFILES_PER_PAGE + 1;
|
||||
|
||||
$group->orderBy($order);
|
||||
$group->limit($offset, $limit);
|
||||
|
||||
$group->find();
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
|
@ -379,17 +336,14 @@ GROUP_QUERY_END;
|
|||
*
|
||||
* @return string a column name for sorting
|
||||
*/
|
||||
function getSortKey()
|
||||
function getSortKey($def='created')
|
||||
{
|
||||
switch ($this->sort) {
|
||||
case 'nickname':
|
||||
return $this->sort;
|
||||
break;
|
||||
case 'created':
|
||||
return $this->sort;
|
||||
break;
|
||||
default:
|
||||
return 'nickname';
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,7 @@
|
|||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET'))
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/publicgroupnav.php';
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* User directory
|
||||
|
@ -43,7 +38,7 @@ require_once INSTALLDIR . '/lib/publicgroupnav.php';
|
|||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class UserdirectoryAction extends Action
|
||||
class UserdirectoryAction extends ManagedAction
|
||||
{
|
||||
/**
|
||||
* The page we're on
|
||||
|
@ -137,17 +132,8 @@ class UserdirectoryAction extends Action
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*/
|
||||
function prepare($args)
|
||||
protected function doPreparation()
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
|
||||
$this->filter = $this->arg('filter', 'all');
|
||||
$this->reverse = $this->boolean('reverse');
|
||||
|
@ -155,23 +141,6 @@ class UserdirectoryAction extends Action
|
|||
$this->sort = $this->arg('sort', 'nickname');
|
||||
|
||||
common_set_returnto($this->selfUrl());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request
|
||||
*
|
||||
* Shows the page
|
||||
*
|
||||
* @param array $args $_REQUEST args; handled in prepare()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -291,10 +260,13 @@ class UserdirectoryAction extends Action
|
|||
{
|
||||
$profile = new Profile();
|
||||
|
||||
// Comment this out or disable to get global profile searches
|
||||
$profile->joinAdd(array('id', 'user:id'));
|
||||
|
||||
$offset = ($this->page - 1) * PROFILES_PER_PAGE;
|
||||
$limit = PROFILES_PER_PAGE + 1;
|
||||
|
||||
if (isset($this->q)) {
|
||||
if (!empty($this->q)) {
|
||||
// User is searching via query
|
||||
$search_engine = $profile->getSearchEngine('profile');
|
||||
|
||||
|
@ -319,34 +291,34 @@ class UserdirectoryAction extends Action
|
|||
$profile->find();
|
||||
} else {
|
||||
// User is browsing via AlphaNav
|
||||
$sort = $this->getSortKey();
|
||||
$sql = 'SELECT profile.* FROM profile, user WHERE profile.id = user.id';
|
||||
|
||||
switch($this->filter)
|
||||
{
|
||||
switch ($this->filter) {
|
||||
case 'all':
|
||||
// NOOP
|
||||
break;
|
||||
case '0-9':
|
||||
$sql .=
|
||||
' AND LEFT(profile.nickname, 1) BETWEEN \'0\' AND \'9\'';
|
||||
$profile->whereAdd(sprintf('LEFT(%1$s.%2$s, 1) BETWEEN %3$s AND %4$s',
|
||||
$profile->escapedTableName(),
|
||||
'nickname',
|
||||
$profile->_quote("0"),
|
||||
$profile->_quote("9")));
|
||||
break;
|
||||
default:
|
||||
$sql .= sprintf(
|
||||
' AND LEFT(LOWER(profile.nickname), 1) = \'%s\'',
|
||||
$this->filter
|
||||
);
|
||||
$profile->whereAdd(sprintf('LEFT(LOWER(%1$s.%2$s), 1) = %3$s',
|
||||
$profile->escapedTableName(),
|
||||
'nickname',
|
||||
$profile->_quote($this->filter)));
|
||||
}
|
||||
|
||||
$sql .= sprintf(
|
||||
' ORDER BY profile.%s %s, profile.nickname ASC LIMIT %d, %d',
|
||||
$sort,
|
||||
$this->reverse ? 'DESC' : 'ASC',
|
||||
$offset,
|
||||
$limit
|
||||
);
|
||||
$order = sprintf('%1$s.%2$s %3$s, %1$s.%4$s ASC',
|
||||
$profile->escapedTableName(),
|
||||
$this->getSortKey('nickname'),
|
||||
$this->reverse ? 'DESC' : 'ASC',
|
||||
'nickname');
|
||||
$profile->orderBy($order);
|
||||
$profile->limit($offset, $limit);
|
||||
|
||||
$profile->query($sql);
|
||||
$profile->find();
|
||||
}
|
||||
|
||||
return $profile;
|
||||
|
@ -357,15 +329,12 @@ class UserdirectoryAction extends Action
|
|||
*
|
||||
* @return string a column name for sorting
|
||||
*/
|
||||
function getSortKey()
|
||||
function getSortKey($def='nickname')
|
||||
{
|
||||
switch ($this->sort) {
|
||||
case 'nickname':
|
||||
return $this->sort;
|
||||
break;
|
||||
case 'created':
|
||||
return $this->sort;
|
||||
break;
|
||||
default:
|
||||
return 'nickname';
|
||||
}
|
||||
|
|
|
@ -621,7 +621,7 @@ class Ostatus_profile extends Managed_DataObject
|
|||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$rendered = common_purify($sourceContent);
|
||||
$content = common_strip_html($rendered);
|
||||
|
||||
$shortened = common_shorten_links($content);
|
||||
|
@ -788,7 +788,7 @@ class Ostatus_profile extends Managed_DataObject
|
|||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$rendered = common_purify($sourceContent);
|
||||
$content = common_strip_html($rendered);
|
||||
|
||||
$shortened = common_shorten_links($content);
|
||||
|
@ -914,17 +914,6 @@ class Ostatus_profile extends Managed_DataObject
|
|||
return $saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up HTML
|
||||
*/
|
||||
protected function purify($html)
|
||||
{
|
||||
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||
$config = array('safe' => 1,
|
||||
'deny_attribute' => 'id,style,on*');
|
||||
return htmLawed($html, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a list of recipient ID URIs to just those for local delivery.
|
||||
* @param Profile local profile of sender
|
||||
|
|
|
@ -249,7 +249,7 @@ class SalmonAction extends Action
|
|||
$orig = clone($oprofile);
|
||||
$oprofile->uri = $e->object_uri;
|
||||
common_debug('URIFIX Updating Ostatus_profile URI for '.$aliased_uri.' to '.$oprofile->uri);
|
||||
$oprofile->updateWithKeys($orig);
|
||||
$oprofile->updateWithKeys($orig, 'uri'); // 'uri' is the primary key column
|
||||
unset($orig);
|
||||
$this->oprofile = $oprofile;
|
||||
break; // don't iterate through aliases anymore
|
||||
|
|
59
scripts/clean_profiles.php
Executable file
59
scripts/clean_profiles.php
Executable file
|
@ -0,0 +1,59 @@
|
|||
#!/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 = 'y';
|
||||
$longoptions = array('yes');
|
||||
|
||||
$helptext = <<<END_OF_HELP
|
||||
clean_profiles.php [options]
|
||||
Deletes all profile table entries where the profile does not occur in the
|
||||
notice table, is not a group and is not a local user. Very MySQL specific I think.
|
||||
|
||||
WARNING: This has not been tested thoroughly. Maybe we've missed a table to compare somewhere.
|
||||
|
||||
-y --yes do not wait for confirmation
|
||||
|
||||
END_OF_HELP;
|
||||
|
||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||
|
||||
if (!have_option('y', 'yes')) {
|
||||
print "About to delete profiles that we think are useless to save. Are you sure? [y/N] ";
|
||||
$response = fgets(STDIN);
|
||||
if (strtolower(trim($response)) != 'y') {
|
||||
print "Aborting.\n";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
print "Deleting";
|
||||
$profile = new Profile();
|
||||
$profile->query('SELECT * FROM profile WHERE ' .
|
||||
'NOT (SELECT COUNT(*) FROM notice WHERE profile_id=profile.id) ' .
|
||||
'AND NOT (SELECT COUNT(*) FROM user WHERE user.id=profile.id) ' .
|
||||
'AND NOT (SELECT COUNT(*) FROM user_group WHERE user_group.profile_id=profile.id) ' .
|
||||
'AND NOT (SELECT COUNT(*) FROM subscription WHERE subscriber=profile.id OR subscribed=profile.id) ');
|
||||
while ($profile->fetch()) {
|
||||
echo ' '.$profile->getID().':'.$profile->getNickname();
|
||||
$profile->delete();
|
||||
}
|
||||
print "\nDONE.\n";
|
Loading…
Reference in New Issue
Block a user