git.gnu.io has moved to IP address 209.51.188.249 -- please double check where you are logging in.

Commit 49bce941 authored by Craig Andrews's avatar Craig Andrews

Merge remote branch 'statusnet/0.8.x' into 0.9.x

Conflicts:
	EVENTS.txt
	actions/requesttoken.php
	classes/File.php
	install.php
	lib/action.php
	lib/noticeform.php
parents 3d30ad83 5323956e
......@@ -170,12 +170,6 @@ StartShowBody: called before showing the <body> element and children
EndShowBody: called after showing the <body> element (and </body>)
- $action: action object being shown
StartHeadChildren: called before showing the children of <head> element (after <head> tag)
- $action: action object being shown
EndHeadChildren: called after showing the children of <head> element (before </head>)
- $action: action object being shown
StartPersonalGroupNav: beginning of personal group nav menu
- $action: action object being shown
......@@ -271,3 +265,9 @@ GetValidDaemons: Just before determining which daemons to run
HandleQueuedNotice: Handle a queued notice at queue time (or immediately if no queue)
- &$notice: notice to handle
StartShowHeadElements: Right after the <head> tag
- $action: the current action
EndShowHeadElements: Right before the </head> tag; put <script>s here if you need them in <head>
- $action: the current action
......@@ -362,13 +362,13 @@ class AvatarsettingsAction extends AccountSettingsAction
$profile = $user->getProfile();
$avatar = $profile->getOriginalAvatar();
$avatar->delete();
if($avatar) $avatar->delete();
$avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
$avatar->delete();
if($avatar) $avatar->delete();
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
$avatar->delete();
if($avatar) $avatar->delete();
$avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
$avatar->delete();
if($avatar) $avatar->delete();
$this->showForm(_('Avatar deleted.'), true);
}
......
......@@ -433,13 +433,14 @@ class NewnoticeAction extends Action
$content = $this->trimmed('status_textarea');
if (!$content) {
$replyto = $this->trimmed('replyto');
$inreplyto = $this->trimmed('inreplyto');
$profile = Profile::staticGet('nickname', $replyto);
if ($profile) {
$content = '@' . $profile->nickname . ' ';
}
}
$notice_form = new NoticeForm($this, '', $content);
$notice_form = new NoticeForm($this, '', $content, null, $inreplyto);
$notice_form->show();
}
......
......@@ -378,8 +378,13 @@ class ShowstreamAction extends ProfileAction
$this->showEmptyListMessage();
}
$args = array('nickname' => $this->user->nickname);
if (!empty($this->tag))
{
$args['tag'] = $this->tag;
}
$this->pagination($this->page>1, $cnt>NOTICES_PER_PAGE, $this->page,
'showstream', array('nickname' => $this->user->nickname));
'showstream', $args);
}
function showAnonymousMessage()
......
......@@ -117,11 +117,15 @@ class User extends Memcached_DataObject
function allowed_nickname($nickname)
{
// XXX: should already be validated for size, content, etc.
static $blacklist = array('rss', 'xrds', 'doc', 'main',
'settings', 'notice', 'user',
'search', 'avatar', 'tag', 'tags',
'api', 'message', 'group', 'groups',
'local');
$blacklist = array();
//all directory and file names should be blacklisted
$d = dir(INSTALLDIR);
while (false !== ($entry = $d->read())) {
$blacklist[]=$entry;
}
$d->close();
$merged = array_merge($blacklist, common_config('nickname', 'blacklist'));
return !in_array($nickname, $merged);
}
......
......@@ -61,4 +61,5 @@ VALUES
(100113, 'T-Mobile Germany', '%s@t-mobile-sms.de', now()),
(100114, 'Vodafone Germany', '%s@vodafone-sms.de', now()),
(100115, 'E-Plus', '%s@smsmail.eplus.de', now()),
(100116, 'Cellular South', '%s@csouth1.com', now());
(100116, 'Cellular South', '%s@csouth1.com', now()),
(100117, 'ChinaMobile (139)', '%s@139.com', now());
......@@ -2,6 +2,4 @@ A bookmarklet is a small piece of javascript code used as a bookmark. This one w
Drag-and-drop the following link to your bookmarks bar or right-click it and add it to your browser favorites to keep it handy.
<MTMarkdownOptions output='raw'>
<a href="javascript:var%20d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='http://%%site.server%%/%%site.path%%/index.php?action=newnotice',l=d.location,e=encodeURIComponent,g=f+'&status_textarea=%22'+((e(s))?e(s):e(document.title))+'%22 from '+l.href;function%20a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=800,height=570')){l.href=g;}}a();void(0);">Post to %%site.name%%</a>
</MTMarkdownOptions>
<a href="javascript:var%20d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='http://%%site.server%%/%%site.path%%/index.php?action=newnotice',l=d.location,e=encodeURIComponent,g=f+'&amp;status_textarea=%22'+((e(s))?e(s):e(document.title))+'%22 from '+l.href;function%20a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=800,height=570')){l.href=g;}}a();void(0);">Post to %%site.name%%</a>
......@@ -37,10 +37,10 @@ currently-implemented commands:
* **help**: Show this help. List available Jabber/XMPP commands
* **follow &lt;nickname&gt;**: Subscribe to &lt;nickname&gt;
* **sub &lt;nickname&gt;**: Same as follow
* **leave &lt;nickname&gt;**: Subscribe to &lt;nickname&gt;
* **leave &lt;nickname&gt;**: Unsubscribe from &lt;nickname&gt;
* **unsub &lt;nickname&gt;**: Same as leave
* **d &lt;nickname&gt; &lt;text&gt;**: Send direct message to &lt;nickname&gt; with message body &lt;text&gt;
* **get &lt;nickname&gt;**: Get last notice from &lt;nickname&gt;
* **last &lt;nickname&gt;**: Same as 'get'
* **whois &lt;nickname&gt;**: Get Profile info on &lt;nickname&gt;
* **fav &lt;nickname&gt;**: Add user's last notice as a favorite
\ No newline at end of file
* **fav &lt;nickname&gt;**: Add user's last notice as a favorite
......@@ -376,7 +376,7 @@ function Auth_OpenID_detectMathLibrary($exts)
// Try to load dynamic modules.
if (!$loaded) {
foreach ($extension['modules'] as $module) {
if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
if (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode') && @dl($module . "." . PHP_SHLIB_SUFFIX)) {
$loaded = true;
break;
}
......
......@@ -349,7 +349,7 @@ function &Auth_Yadis_getXMLParser()
foreach ($extensions as $name => $params) {
if (!extension_loaded($name)) {
foreach ($params['libname'] as $libname) {
if (@dl($libname)) {
if (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode') && @dl($libname)) {
$classname = $params['classname'];
}
}
......
......@@ -327,7 +327,7 @@ class OAuthRequest {/*{{{*/
public function get_normalized_http_url() {/*{{{*/
$parts = parse_url($this->http_url);
$port = @$parts['port'];
$port = isset($parts['port']) ? $parts['port'] : null;
$scheme = $parts['scheme'];
$host = $parts['host'];
$path = @$parts['path'];
......
......@@ -746,7 +746,7 @@ class PEAR
{
if (!extension_loaded($ext)) {
// if either returns true dl() will produce a FATAL error, stop that
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1) || !function_exists('dl')) {
return false;
}
if (OS_WINDOWS) {
......
......@@ -49,7 +49,13 @@ function getPath($req)
) {
return $req['p'];
} else if (array_key_exists('PATH_INFO', $_SERVER)) {
return $_SERVER['PATH_INFO'];
$path = $_SERVER['PATH_INFO'];
$script = $_SERVER['SCRIPT_NAME'];
if (substr($path, 0, mb_strlen($script)) == $script) {
return substr($path, mb_strlen($script));
} else {
return $path;
}
} else {
return null;
}
......
......@@ -244,7 +244,7 @@ function main()
*/
function haveExternalLibrary($external_library)
{
if (isset($external_library['include']) && ! @include_once $external_library['include'] ) {
if(isset($external_library['include']) && ! haveIncludeFile($external_library['include'])){
return false;
}
if (isset($external_library['check_function']) && ! function_exists($external_library['check_function'])) {
......@@ -256,6 +256,15 @@ function haveExternalLibrary($external_library)
return true;
}
// Attempt to include a PHP file and report if it worked, while
// suppressing the annoying warning messages on failure.
function haveIncludeFile($filename) {
$old = error_reporting(error_reporting() & ~E_WARNING);
$ok = include_once($filename);
error_reporting($old);
return $ok;
}
/**
* Check if all is ready for installation
*
......@@ -328,12 +337,19 @@ function checkPrereqs()
*/
function checkExtension($name)
{
if (!extension_loaded($name)) {
if (!@dl($name.'.so')) {
return false;
}
if (extension_loaded($name)) {
return true;
} elseif (function_exists('dl') && ini_get('enable_dl') && !ini_get('safe_mode')) {
// dl will throw a fatal error if it's disabled or we're in safe mode.
// More fun, it may not even exist under some SAPIs in 5.3.0 or later...
$soname = $name . '.' . PHP_SHLIB_SUFFIX;
if (PHP_SHLIB_SUFFIX == 'dll') {
$soname = "php_" . $soname;
}
return @dl($soname);
} else {
return false;
}
return true;
}
/**
......@@ -366,19 +382,19 @@ function showLibs()
E_O_T;
foreach ($absent_libraries as $library) {
echo '<li>';
if (isset($library['url'])) {
if(isset($library['url'])){
echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
} else {
echo htmlentities($library['name']);
}
echo '<ul>';
if (isset($library['deb'])) {
if(isset($library['deb'])){
echo '<li class="deb package">deb: <a href="apt:' . urlencode($library['deb']) . '">' . htmlentities($library['deb']) . '</a></li>';
}
if (isset($library['rpm'])) {
if(isset($library['rpm'])){
echo '<li class="rpm package">rpm: ' . htmlentities($library['rpm']) . '</li>';
}
if (isset($library['pear'])) {
if(isset($library['pear'])){
echo '<li class="pear package">pear: ' . htmlentities($library['pear']) . '</li>';
}
echo '</ul>';
......@@ -390,7 +406,7 @@ E_O_T;
E_O_T;
foreach ($present_libraries as $library) {
echo '<li>';
if ($library['url']) {
if(isset($library['url'])){
echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
} else {
echo htmlentities($library['name']);
......
......@@ -120,16 +120,15 @@ class Action extends HTMLOutputter // lawsuit
{
// XXX: attributes (profile?)
$this->elementStart('head');
if (Event::handle('StartHeadChildren', array($this))) {
if (Event::handle('StartShowHeadElements', array($this))) {
$this->showTitle();
$this->showShortcutIcon();
$this->showStylesheets();
$this->showScripts();
$this->showOpenSearch();
$this->showFeeds();
$this->showDescription();
$this->extraHead();
Event::handle('EndHeadChildren', array($this));
Event::handle('EndShowHeadElements', array($this));
}
$this->elementEnd('head');
}
......@@ -355,6 +354,7 @@ class Action extends HTMLOutputter // lawsuit
Event::handle('EndShowFooter', array($this));
}
$this->elementEnd('div');
$this->showScripts();
$this->elementEnd('body');
}
......@@ -879,6 +879,7 @@ class Action extends HTMLOutputter // lawsuit
*/
function handle($argarray=null)
{
header('Vary: Accept-Encoding,Cookie');
$lm = $this->lastModified();
$etag = $this->etag();
if ($etag) {
......
......@@ -325,7 +325,6 @@ class DesignSettingsAction extends AccountSettingsAction
parent::showScripts();
$this->script('js/farbtastic/farbtastic.js');
$this->script('js/farbtastic/farbtastic.go.js');
$this->script('js/userdesign.go.js');
$this->autofocus('design_background-image_file');
......
......@@ -551,9 +551,9 @@ function mail_notify_fave($other, $user, $notice)
common_init_locale($other->language);
$subject = sprintf(_('%s added your notice as a favorite'), $bestname);
$subject = sprintf(_('%s (@%s) added your notice as a favorite'), $bestname, $user->nickname);
$body = sprintf(_("%1\$s just added your notice from %2\$s".
$body = sprintf(_("%1\$s (@%7\$s) just added your notice from %2\$s".
" as one of their favorites.\n\n" .
"The URL of your notice is:\n\n" .
"%3\$s\n\n" .
......@@ -570,7 +570,8 @@ function mail_notify_fave($other, $user, $notice)
$notice->content,
common_local_url('showfavorites',
array('nickname' => $user->nickname)),
common_config('site', 'name'));
common_config('site', 'name'),
$user->nickname);
common_init_locale();
mail_to_user($other, $subject, $body);
......@@ -607,9 +608,9 @@ function mail_notify_attn($user, $notice)
$conversationUrl = null;
}
$subject = sprintf(_('%s sent a notice to your attention'), $bestname);
$subject = sprintf(_('%s (@%s) sent a notice to your attention'), $bestname, $sender->nickname);
$body = sprintf(_("%1\$s just sent a notice to your attention (an '@-reply') on %2\$s.\n\n".
$body = sprintf(_("%1\$s (@%9\$s) just sent a notice to your attention (an '@-reply') on %2\$s.\n\n".
"The notice is here:\n\n".
"\t%3\$s\n\n" .
"It reads:\n\n".
......@@ -629,10 +630,11 @@ function mail_notify_attn($user, $notice)
$notice->content,//%4
$conversationUrl,//%5
common_local_url('newnotice',
array('replyto' => $sender->nickname)),//%6
array('replyto' => $sender->nickname, 'inreplyto' => $notice->id)),//%6
common_local_url('replies',
array('nickname' => $user->nickname)),//%7
common_local_url('emailsettings'));//%8
common_local_url('emailsettings'), //%8
$sender->nickname); //%9
common_init_locale();
mail_to_user($user, $subject, $body);
......
......@@ -69,6 +69,12 @@ class NoticeForm extends Form
var $user = null;
/**
* The notice being replied to
*/
var $inreplyto = null;
/**
* Constructor
*
......@@ -77,13 +83,13 @@ class NoticeForm extends Form
* @param string $content content to pre-fill
*/
function __construct($out=null, $action=null, $content=null, $user=null)
function __construct($out=null, $action=null, $content=null, $user=null, $inreplyto=null)
{
parent::__construct($out);
$this->action = $action;
$this->content = $content;
$this->inreplyto = $inreplyto;
if ($user) {
$this->user = $user;
} else {
......@@ -168,7 +174,7 @@ class NoticeForm extends Form
if ($this->action) {
$this->out->hidden('notice_return-to', $this->action, 'returnto');
}
$this->out->hidden('notice_in-reply-to', $this->action, 'inreplyto');
$this->out->hidden('notice_in-reply-to', $this->inreplyto, 'inreplyto');
}
/**
......
......@@ -261,7 +261,7 @@ class NoticeListItem extends Widget
$attrs = array('href' => $this->profile->profileurl,
'class' => 'url');
if (!empty($this->profile->fullname)) {
$attrs['title'] = $this->profile->fullname . ' (' . $this->profile->nickname . ') ';
$attrs['title'] = $this->profile->fullname . ' (' . $this->profile->nickname . ')';
}
$this->out->elementStart('a', $attrs);
$this->showAvatar();
......@@ -418,9 +418,17 @@ class NoticeListItem extends Widget
function showContext()
{
// XXX: also show context if there are replies to this notice
if (!empty($this->notice->conversation)
&& $this->notice->conversation != $this->notice->id) {
$hasConversation = false;
if( !empty($this->notice->conversation)
&& $this->notice->conversation != $this->notice->id){
$hasConversation = true;
}else{
$conversation = Notice::conversationStream($this->notice->id, 1, 1);
if($conversation->N > 0){
$hasConversation = true;
}
}
if ($hasConversation){
$convurl = common_local_url('conversation',
array('id' => $this->notice->conversation));
$this->out->element('a', array('href' => $convurl.'#notice-'.$this->notice->id,
......@@ -442,7 +450,7 @@ class NoticeListItem extends Widget
{
if (common_logged_in()) {
$reply_url = common_local_url('newnotice',
array('replyto' => $this->profile->nickname));
array('replyto' => $this->profile->nickname, 'inreplyto' => $this->notice->id));
$this->out->elementStart('a', array('href' => $reply_url,
'class' => 'notice_reply',
'title' => _('Reply to this notice')));
......
......@@ -172,6 +172,10 @@ class Router
$m->connect('notice/new?replyto=:replyto',
array('action' => 'newnotice'),
array('replyto' => '[A-Za-z0-9_-]+'));
$m->connect('notice/new?replyto=:replyto&inreplyto=:inreplyto',
array('action' => 'newnotice'),
array('replyto' => '[A-Za-z0-9_-]+'),
array('inreplyto' => '[0-9]+'));
$m->connect('notice/:notice/file',
array('action' => 'file'),
......
......@@ -442,9 +442,9 @@ function common_replace_urls_callback($text, $callback, $notice_id = null) {
')'.
'(?:'.
'(?:\:\d+)?'. //:port
'(?:/[\pN\pL$\[\]\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\+\'\"]*)?'. // /path
'(?:\?[\pN\pL\$\[\]\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\+\'\"\/]*)?'. // ?query string
'(?:\#[\pN\pL$\[\]\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\+\'\"\/\?\#]*)?'. // #fragment
'(?:/[\pN\pL$\[\]\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\+\'\"@]*)?'. // /path
'(?:\?[\pN\pL\$\[\]\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\+\'\"@\/]*)?'. // ?query string
'(?:\#[\pN\pL$\[\]\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\+\'\"\@/\?\#]*)?'. // #fragment
')(?<![\?\.\,\#\,])'.
')'.
'#ixu';
......@@ -552,12 +552,13 @@ function common_linkify($url) {
}
if (!empty($f)) {
if (isset($f->filename)) {
if ($f->isEnclosure()) {
$is_attachment = true;
$attachment_id = $f->id;
} else { // if it has OEmbed info, it's an attachment, too
} else {
$foe = File_oembed::staticGet('file_id', $f->id);
if (!empty($foe)) {
// if it has OEmbed info, it's an attachment, too
$is_attachment = true;
$attachment_id = $f->id;
......@@ -1393,9 +1394,6 @@ function common_shorten_url($long_url)
$short_url_service = $reflectionObj->newInstanceArgs($_shorteners[$svc]['callInfo'][1]);
$short_url = $short_url_service->shorten($long_url);
if(substr($short_url,0,7)=='http://'){
$short_url = substr($short_url,7);
}
return $short_url;
}
......
$(document).ready(function(){
$.getJSON($('address .url')[0].href+'/api/statuses/friends.json?user_id=' + current_user['id'] + '&lite=true&callback=?',
function(friends){
$('#notice_data-text').autocomplete(friends, {
$('#notice_data-text').autocomplete($('address .url')[0].href+'/plugins/Autocomplete/autocomplete.json', {
multiple: true,
multipleSeparator: " ",
minChars: 1,
formatItem: function(row, i, max){
return '@' + row.screen_name + ' (' + row.name + ')';
row = eval("(" + row + ")");
switch(row.type)
{
case 'user':
return row.nickname + ' (' + row.fullname + ')';
case 'group':
return row.nickname + ' (' + row.fullname + ')';
}
},
formatMatch: function(row, i, max){
return '@' + row.screen_name;
row = eval("(" + row + ")");
switch(row.type)
{
case 'user':
return row.nickname;
case 'group':
return row.nickname;
}
},
formatResult: function(row){
return '@' + row.screen_name;
row = eval("(" + row + ")");
switch(row.type)
{
case 'user':
return '@' + row.nickname;
case 'group':
return '!' + row.nickname;
}
}
});
}
);
$.getJSON($('address .url')[0].href+'/api/statusnet/groups/list.json?user_id=' + current_user['id'] + '&callback=?',
function(groups){
$('#notice_data-text').autocomplete(groups, {
multiple: true,
multipleSeparator: " ",
minChars: 1,
formatItem: function(row, i, max){
return '!' + row.nickname + ' (' + row.fullname + ')';
},
formatMatch: function(row, i, max){
return '!' + row.nickname;
},
formatResult: function(row){
return '!' + row.nickname;
}
});
}
);
});
......@@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
require_once(INSTALLDIR.'/plugins/Autocomplete/autocomplete.php');
class AutocompletePlugin extends Plugin
{
function __construct()
......@@ -40,13 +42,6 @@ class AutocompletePlugin extends Plugin
function onEndShowScripts($action){
if (common_logged_in()) {
$current_user = common_current_user();
$js_string = <<<EOT
<script type="text/javascript">
var current_user = { id: '$current_user->id' };
</script>
EOT;
$action->raw($js_string);
$action->script('plugins/Autocomplete/jquery-autocomplete/jquery.autocomplete.pack.js');
$action->script('plugins/Autocomplete/Autocomplete.js');
}
......@@ -59,5 +54,12 @@ EOT;
}
}
function onRouterInitialized($m)
{
if (common_logged_in()) {
$m->connect('plugins/Autocomplete/autocomplete.json', array('action'=>'autocomplete'));
}
}
}
?>
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List users for autocompletion
*
* 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 Plugin
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2008-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') && !defined('LACONICA')) {
exit(1);
}
/**
* List users for autocompletion
*
* This is the form for adding a new g
*
* @category Plugin
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class AutocompleteAction extends Action
{
private $result;
/**
* Last-modified date for page
*
* When was the content of this page last modified? Based on notice,
* profile, avatar.
*
* @return int last-modified date as unix timestamp
*/
function lastModified()
{
$max=0;
foreach($this->users as $user){
$max = max($max,strtotime($user->modified),strtotime($user->profile->modified));
}
foreach($this->groups as $group){
$max = max($max,strtotime($group->modified));
}
return $max;
}
/**
* An entity tag for this page
*
* Shows the ETag for the page, based on the notice ID and timestamps
* for the notice, profile, and avatar. It's weak, since we change
* the date text "one hour ago", etc.
*
* @return string etag
*/
function etag()
{
return '"' . implode(':', array($this->arg('action'),
crc32($this->arg('q')), //the actual string can have funny characters in we don't want showing up in the etag
$this->arg('limit'),
$this->lastModified())) . '"';
}
function prepare($args)
{
parent::prepare($args);
$this->groups=array();
$this->users=array();
$q = $this->arg('q');
$limit = $this->arg('limit');
if($limit > 200) $limit=200; //prevent DOS attacks
if(substr($q,0,1)=='@'){
//user search
$q=substr($q,1);
$user = new User();
$user->limit($limit);
$user->whereAdd('nickname like \'' . trim($user->escape($q), '\'') . '%\'');
$user->find();
while($user->fetch()) {
$profile = Profile::staticGet($user->id);
$user->profile=$profile;
$this->users[]=$user;
}
}
if(substr($q,0,1)=='!'){
//group search
$q=substr($q,1);
$group = new User_group();
$group->limit($limit);
$group->whereAdd('nickname like \'' . trim($group->escape($q), '\'') . '%\'');
$group->find();
while($group->fetch()) {
$this->groups[]=$group;
}
}
return true;
}
function handle($args)
{
parent::handle($args);
$results = array();
foreach($this->users as $user){
$results[]=array('nickname' => $user->nickname, 'fullname'=> $user->profile->fullname, 'type'=>'user');
}
foreach($this->groups as $group){
$results[]=array('nickname' => $group->nickname, 'fullname'=> $group->fullname, 'type'=>'group');
}
foreach($results as $result) {