diff --git a/actions/apisearchjson.php b/actions/apisearchjson.php index 79b2666554..612dbdda5c 100644 --- a/actions/apisearchjson.php +++ b/actions/apisearchjson.php @@ -89,6 +89,12 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction $this->since_id = $this->trimmed('since_id'); $this->geocode = $this->trimmed('geocode'); + if (!empty($this->auth_user)) { + $this->auth_profile = $this->auth_user->getProfile(); + } else { + $this->auth_profile = null; + } + return true; } @@ -112,20 +118,27 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction */ function showResults() { - // TODO: Support search operators like from: and to:, boolean, etc. - - $notice = new Notice(); - - // lcase it for comparison $q = strtolower($this->query); - $search_engine = $notice->getSearchEngine('notice'); - $search_engine->set_sort_mode('chron'); - $search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true); - if (false === $search_engine->query($q)) { - $cnt = 0; + // TODO: Support search operators like from: and to:, boolean, etc. + + if (preg_match('/^#([\pL\pN_\-\.]{1,64})$/ue', $q)) { + $stream = new TagNoticeStream(substr($q, 1), $this->auth_profile); + } else if ($this->isAnURL($q)) { + $canon = File_redirection::_canonUrl($q); + $file = File::staticGet('url', $canon); + if (!empty($file)) { + $stream = new FileNoticeStream($file, $this->auth_profile); + } } else { - $cnt = $notice->find(); + $stream = new SearchNoticeStream($q, $this->auth_profile); + } + + if (empty($stream)) { + // XXX: This is hackish, but need some simple way to say "There's no results" + $notice = new ArrayWrapper(array()); + } else { + $notice = $stream->getNotices(($this->page - 1) * $this->rpp, $this->rpp + 1); } // TODO: max_id, lang, geocode @@ -137,6 +150,47 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction $this->endDocument('json'); } + function isAnURL($q) { + $regex = '#^'. + '(?:^|[\s\<\>\(\)\[\]\{\}\\\'\\\";]+)(?![\@\!\#])'. + '('. + '(?:'. + '(?:'. //Known protocols + '(?:'. + '(?:(?:https?|ftps?|mms|rtsp|gopher|news|nntp|telnet|wais|file|prospero|webcal|irc)://)'. + '|'. + '(?:(?:mailto|aim|tel|xmpp):)'. + ')'. + '(?:[\pN\pL\-\_\+\%\~]+(?::[\pN\pL\-\_\+\%\~]+)?\@)?'. //user:pass@ + '(?:'. + '(?:'. + '\[[\pN\pL\-\_\:\.]+(? $source) { - $user = User::staticGet('id', $id); - if (empty($user) || $user->hasBlocked($profile) || - ($originalProfile && $user->hasBlocked($originalProfile))) { + try { + $user = User::staticGet('id', $id); + if (empty($user) || + $user->hasBlocked($profile) || + ($originalProfile && $user->hasBlocked($originalProfile))) { + unset($ni[$id]); + } + } catch (UserNoProfileException $e) { + // User doesn't have a profile; invalid; skip them. unset($ni[$id]); } } diff --git a/lib/filenoticestream.php b/lib/filenoticestream.php index fba6183fc2..f7bca1ed68 100644 --- a/lib/filenoticestream.php +++ b/lib/filenoticestream.php @@ -42,7 +42,7 @@ class FileNoticeStream extends ScopingNoticeStream $profile = Profile::current(); } parent::__construct(new CachingNoticeStream(new RawFileNoticeStream($file), - 'file:notice-ids:'.$this->url), + 'file:notice-ids:'.$file->id), $profile); } }