- 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.
// 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);
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);
- }
}
*/
function savePreferences()
{
- $user = common_current_user();
+ $user = $this->scoped->getUser();
if (Event::handle('StartEmailSaveForm', array($this, $this->scoped))) {
$emailnotifysub = $this->boolean('emailnotifysub');
$emailmicroid = $this->boolean('emailmicroid');
$emailpost = $this->boolean('emailpost');
- assert(!is_null($user)); // should already be checked
-
$user->query('BEGIN');
$original = clone($user);
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.'));
}
return $ckeys;
}
+ public function escapedTableName()
+ {
+ return common_database_tablename($this->tableName());
+ }
+
/**
* Returns an ID, checked that it is set and reasonably valid
*
// 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);
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);
- }
}
'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/',
$pass = false;
}
- $reqs = array('gd', 'curl', 'json',
+ $reqs = array('gd', 'curl', 'intl', 'json',
'xmlwriter', 'mbstring', 'xml', 'dom', 'simplexml');
foreach ($reqs as $req) {
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.
*
*/
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;
}
/**
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;
}
/**
'|(?:(?: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
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);
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)
$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);
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;
- }
}
* @link http://status.net/
*/
-if (!defined('STATUSNET'))
-{
- exit(1);
-}
-
-require_once INSTALLDIR . '/lib/publicgroupnav.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Group directory
* @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
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');
$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();
}
/**
{
$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;
}
*
* @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;
}
}
* @link http://status.net/
*/
-if (!defined('STATUSNET'))
-{
- exit(1);
-}
-
-require_once INSTALLDIR . '/lib/publicgroupnav.php';
+if (!defined('GNUSOCIAL')) { exit(1); }
/**
* User directory
* @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
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');
$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();
}
/**
{
$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');
$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;
*
* @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';
}
// 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);
// 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);
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
$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
--- /dev/null
+#!/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";