From 1d5296e596168f6ee8b18e9917e8d8aa62ac254c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 11 Feb 2009 15:39:49 -0500 Subject: change htmloutputter to use exception instead of common_user_error --- lib/htmloutputter.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php index 45e61d2fc..06603ac05 100644 --- a/lib/htmloutputter.php +++ b/lib/htmloutputter.php @@ -101,9 +101,8 @@ class HTMLOutputter extends XMLOutputter $type = common_negotiate_type($cp, $sp); if (!$type) { - common_user_error(_('This page is not available in a '. - 'media type you accept'), 406); - exit(0); + throw new ClientException(_('This page is not available in a '. + 'media type you accept'), 406); } } -- cgit v1.2.3-54-g00ecf From 5127396325a29d6c7b8f0e1e0ae3e0580ab30dda Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 11 Feb 2009 15:46:29 -0500 Subject: Move Commands stuff out of classes The classes/ subdir is primarily for the DB_DataObject classes. Stuff in there can get stomped by various generation scripts. I've moved the lurkers there -- related to command-handling -- to lib/. Since auto-loading works fine with lib/, there shouldn't be much of a visible change here. --- classes/Channel.php | 238 ----------------------- classes/Command.php | 419 ----------------------------------------- classes/CommandInterpreter.php | 198 ------------------- lib/channel.php | 238 +++++++++++++++++++++++ lib/command.php | 419 +++++++++++++++++++++++++++++++++++++++++ lib/commandinterpreter.php | 198 +++++++++++++++++++ 6 files changed, 855 insertions(+), 855 deletions(-) delete mode 100644 classes/Channel.php delete mode 100644 classes/Command.php delete mode 100644 classes/CommandInterpreter.php create mode 100644 lib/channel.php create mode 100644 lib/command.php create mode 100644 lib/commandinterpreter.php diff --git a/classes/Channel.php b/classes/Channel.php deleted file mode 100644 index fdeff21fc..000000000 --- a/classes/Channel.php +++ /dev/null @@ -1,238 +0,0 @@ -. - */ - -if (!defined('LACONICA')) { exit(1); } - -class Channel -{ - - function on($user) - { - return false; - } - - function off($user) - { - return false; - } - - function output($user, $text) - { - return false; - } - - function error($user, $text) - { - return false; - } - - function source() - { - return null; - } -} - -class XMPPChannel extends Channel -{ - - var $conn = null; - - function source() - { - return 'xmpp'; - } - - function __construct($conn) - { - $this->conn = $conn; - } - - function on($user) - { - return $this->set_notify($user, 1); - } - - function off($user) - { - return $this->set_notify($user, 0); - } - - function output($user, $text) - { - $text = '['.common_config('site', 'name') . '] ' . $text; - jabber_send_message($user->jabber, $text); - } - - function error($user, $text) - { - $text = '['.common_config('site', 'name') . '] ' . $text; - jabber_send_message($user->jabber, $text); - } - - function set_notify(&$user, $notify) - { - $orig = clone($user); - $user->jabbernotify = $notify; - $result = $user->update($orig); - if (!$result) { - $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); - common_log(LOG_ERR, - 'Could not set notify flag to ' . $notify . - ' for user ' . common_log_objstring($user) . - ': ' . $last_error->message); - return false; - } else { - common_log(LOG_INFO, - 'User ' . $user->nickname . ' set notify flag to ' . $notify); - return true; - } - } -} - -class WebChannel extends Channel -{ - var $out = null; - - function __construct($out=null) - { - $this->out = $out; - } - - function source() - { - return 'web'; - } - - function on($user) - { - return false; - } - - function off($user) - { - return false; - } - - function output($user, $text) - { - # XXX: buffer all output and send it at the end - # XXX: even better, redirect to appropriate page - # depending on what command was run - $this->out->startHTML(); - $this->out->elementStart('head'); - $this->out->element('title', null, _('Command results')); - $this->out->elementEnd('head'); - $this->out->elementStart('body'); - $this->out->element('p', array('id' => 'command_result'), $text); - $this->out->elementEnd('body'); - $this->out->endHTML(); - } - - function error($user, $text) - { - common_user_error($text); - } -} - -class AjaxWebChannel extends WebChannel -{ - function output($user, $text) - { - $this->out->startHTML('text/xml;charset=utf-8'); - $this->out->elementStart('head'); - $this->out->element('title', null, _('Command results')); - $this->out->elementEnd('head'); - $this->out->elementStart('body'); - $this->out->element('p', array('id' => 'command_result'), $text); - $this->out->elementEnd('body'); - $this->out->endHTML(); - } - - function error($user, $text) - { - $this->out->startHTML('text/xml;charset=utf-8'); - $this->out->elementStart('head'); - $this->out->element('title', null, _('Ajax Error')); - $this->out->elementEnd('head'); - $this->out->elementStart('body'); - $this->out->element('p', array('id' => 'error'), $text); - $this->out->elementEnd('body'); - $this->out->endHTML(); - } -} - -class MailChannel extends Channel -{ - - var $addr = null; - - function source() - { - return 'mail'; - } - - function __construct($addr=null) - { - $this->addr = $addr; - } - - function on($user) - { - return $this->set_notify($user, 1); - } - - function off($user) - { - return $this->set_notify($user, 0); - } - - function output($user, $text) - { - - $headers['From'] = $user->incomingemail; - $headers['To'] = $this->addr; - - $headers['Subject'] = _('Command complete'); - - return mail_send(array($this->addr), $headers, $text); - } - - function error($user, $text) - { - - $headers['From'] = $user->incomingemail; - $headers['To'] = $this->addr; - - $headers['Subject'] = _('Command failed'); - - return mail_send(array($this->addr), $headers, $text); - } - - function set_notify($user, $value) - { - $orig = clone($user); - $user->smsnotify = $value; - $result = $user->update($orig); - if (!$result) { - common_log_db_error($user, 'UPDATE', __FILE__); - return false; - } - return true; - } -} diff --git a/classes/Command.php b/classes/Command.php deleted file mode 100644 index eacbdacb3..000000000 --- a/classes/Command.php +++ /dev/null @@ -1,419 +0,0 @@ -. - */ - -if (!defined('LACONICA')) { exit(1); } - -require_once(INSTALLDIR.'/classes/Channel.php'); - -class Command -{ - - var $user = null; - - function __construct($user=null) - { - $this->user = $user; - } - - function execute($channel) - { - return false; - } -} - -class UnimplementedCommand extends Command -{ - function execute($channel) - { - $channel->error($this->user, _("Sorry, this command is not yet implemented.")); - } -} - -class TrackingCommand extends UnimplementedCommand -{ -} - -class TrackOffCommand extends UnimplementedCommand -{ -} - -class TrackCommand extends UnimplementedCommand -{ - var $word = null; - function __construct($user, $word) - { - parent::__construct($user); - $this->word = $word; - } -} - -class UntrackCommand extends UnimplementedCommand -{ - var $word = null; - function __construct($user, $word) - { - parent::__construct($user); - $this->word = $word; - } -} - -class NudgeCommand extends UnimplementedCommand -{ - var $other = null; - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } -} - -class InviteCommand extends UnimplementedCommand -{ - var $other = null; - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } -} - -class StatsCommand extends Command -{ - function execute($channel) - { - - $subs = new Subscription(); - $subs->subscriber = $this->user->id; - $subs_count = (int) $subs->count() - 1; - - $subbed = new Subscription(); - $subbed->subscribed = $this->user->id; - $subbed_count = (int) $subbed->count() - 1; - - $notices = new Notice(); - $notices->profile_id = $this->user->id; - $notice_count = (int) $notices->count(); - - $channel->output($this->user, sprintf(_("Subscriptions: %1\$s\n". - "Subscribers: %2\$s\n". - "Notices: %3\$s"), - $subs_count, - $subbed_count, - $notice_count)); - } -} - -class FavCommand extends Command -{ - - var $other = null; - - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } - - function execute($channel) - { - - $recipient = - common_relative_profile($this->user, common_canonical_nickname($this->other)); - - if (!$recipient) { - $channel->error($this->user, _('No such user.')); - return; - } - $notice = $recipient->getCurrentNotice(); - if (!$notice) { - $channel->error($this->user, _('User has no last notice')); - return; - } - - $fave = Fave::addNew($this->user, $notice); - - if (!$fave) { - $channel->error($this->user, _('Could not create favorite.')); - return; - } - - $other = User::staticGet('id', $recipient->id); - - if ($other && $other->id != $user->id) { - if ($other->email && $other->emailnotifyfav) { - mail_notify_fave($other, $this->user, $notice); - } - } - - $this->user->blowFavesCache(); - - $channel->output($this->user, _('Notice marked as fave.')); - } -} - -class WhoisCommand extends Command -{ - var $other = null; - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } - - function execute($channel) - { - $recipient = - common_relative_profile($this->user, common_canonical_nickname($this->other)); - - if (!$recipient) { - $channel->error($this->user, _('No such user.')); - return; - } - - $whois = sprintf(_("%1\$s (%2\$s)"), $recipient->nickname, - $recipient->profileurl); - if ($recipient->fullname) { - $whois .= "\n" . sprintf(_('Fullname: %s'), $recipient->fullname); - } - if ($recipient->location) { - $whois .= "\n" . sprintf(_('Location: %s'), $recipient->location); - } - if ($recipient->homepage) { - $whois .= "\n" . sprintf(_('Homepage: %s'), $recipient->homepage); - } - if ($recipient->bio) { - $whois .= "\n" . sprintf(_('About: %s'), $recipient->bio); - } - $channel->output($this->user, $whois); - } -} - -class MessageCommand extends Command -{ - var $other = null; - var $text = null; - function __construct($user, $other, $text) - { - parent::__construct($user); - $this->other = $other; - $this->text = $text; - } - - function execute($channel) - { - $other = User::staticGet('nickname', common_canonical_nickname($this->other)); - $len = mb_strlen($this->text); - if ($len == 0) { - $channel->error($this->user, _('No content!')); - return; - } else if ($len > 140) { - $content = common_shorten_links($content); - if (mb_strlen($content) > 140) { - $channel->error($this->user, sprintf(_('Message too long - maximum is 140 characters, you sent %d'), $len)); - return; - } - } - - if (!$other) { - $channel->error($this->user, _('No such user.')); - return; - } else if (!$this->user->mutuallySubscribed($other)) { - $channel->error($this->user, _('You can\'t send a message to this user.')); - return; - } else if ($this->user->id == $other->id) { - $channel->error($this->user, _('Don\'t send a message to yourself; just say it to yourself quietly instead.')); - return; - } - $message = Message::saveNew($this->user->id, $other->id, $this->text, $channel->source()); - if ($message) { - $channel->output($this->user, sprintf(_('Direct message to %s sent'), $this->other)); - } else { - $channel->error($this->user, _('Error sending direct message.')); - } - } -} - -class GetCommand extends Command -{ - - var $other = null; - - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } - - function execute($channel) - { - $target_nickname = common_canonical_nickname($this->other); - - $target = - common_relative_profile($this->user, $target_nickname); - - if (!$target) { - $channel->error($this->user, _('No such user.')); - return; - } - $notice = $target->getCurrentNotice(); - if (!$notice) { - $channel->error($this->user, _('User has no last notice')); - return; - } - $notice_content = $notice->content; - - $channel->output($this->user, $target_nickname . ": " . $notice_content); - } -} - -class SubCommand extends Command -{ - - var $other = null; - - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } - - function execute($channel) - { - - if (!$this->other) { - $channel->error($this->user, _('Specify the name of the user to subscribe to')); - return; - } - - $result = subs_subscribe_user($this->user, $this->other); - - if ($result == 'true') { - $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other)); - } else { - $channel->error($this->user, $result); - } - } -} - -class UnsubCommand extends Command -{ - - var $other = null; - - function __construct($user, $other) - { - parent::__construct($user); - $this->other = $other; - } - - function execute($channel) - { - if(!$this->other) { - $channel->error($this->user, _('Specify the name of the user to unsubscribe from')); - return; - } - - $result=subs_unsubscribe_user($this->user, $this->other); - - if ($result) { - $channel->output($this->user, sprintf(_('Unsubscribed from %s'), $this->other)); - } else { - $channel->error($this->user, $result); - } - } -} - -class OffCommand extends Command -{ - var $other = null; - function __construct($user, $other=null) - { - parent::__construct($user); - $this->other = $other; - } - function execute($channel) - { - if ($other) { - $channel->error($this->user, _("Command not yet implemented.")); - } else { - if ($channel->off($this->user)) { - $channel->output($this->user, _('Notification off.')); - } else { - $channel->error($this->user, _('Can\'t turn off notification.')); - } - } - } -} - -class OnCommand extends Command -{ - var $other = null; - function __construct($user, $other=null) - { - parent::__construct($user); - $this->other = $other; - } - - function execute($channel) - { - if ($other) { - $channel->error($this->user, _("Command not yet implemented.")); - } else { - if ($channel->on($this->user)) { - $channel->output($this->user, _('Notification on.')); - } else { - $channel->error($this->user, _('Can\'t turn on notification.')); - } - } - } -} - -class HelpCommand extends Command -{ - function execute($channel) - { - $channel->output($this->user, - _("Commands:\n". - "on - turn on notifications\n". - "off - turn off notifications\n". - "help - show this help\n". - "follow - subscribe to user\n". - "leave - unsubscribe from user\n". - "d - direct message to user\n". - "get - get last notice from user\n". - "whois - get profile info on user\n". - "fav - add user's last notice as a 'fave'\n". - "stats - get your stats\n". - "stop - same as 'off'\n". - "quit - same as 'off'\n". - "sub - same as 'follow'\n". - "unsub - same as 'leave'\n". - "last - same as 'get'\n". - "on - not yet implemented.\n". - "off - not yet implemented.\n". - "nudge - not yet implemented.\n". - "invite - not yet implemented.\n". - "track - not yet implemented.\n". - "untrack - not yet implemented.\n". - "track off - not yet implemented.\n". - "untrack all - not yet implemented.\n". - "tracks - not yet implemented.\n". - "tracking - not yet implemented.\n")); - } -} diff --git a/classes/CommandInterpreter.php b/classes/CommandInterpreter.php deleted file mode 100644 index 0679f5462..000000000 --- a/classes/CommandInterpreter.php +++ /dev/null @@ -1,198 +0,0 @@ -. - */ - -if (!defined('LACONICA')) { exit(1); } - -require_once(INSTALLDIR.'/classes/Command.php'); - -class CommandInterpreter -{ - - function handle_command($user, $text) - { - # XXX: localise - - $text = preg_replace('/\s+/', ' ', trim($text)); - list($cmd, $arg) = explode(' ', $text, 2); - - # We try to support all the same commands as Twitter, see - # http://getsatisfaction.com/twitter/topics/what_are_the_twitter_commands - # There are a few compatibility commands from earlier versions of - # Laconica - - switch(strtolower($cmd)) { - case 'help': - if ($arg) { - return null; - } - return new HelpCommand($user); - case 'on': - if ($arg) { - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new OnCommand($user, $other); - } - } else { - return new OnCommand($user); - } - case 'off': - if ($arg) { - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new OffCommand($user, $other); - } - } else { - return new OffCommand($user); - } - case 'stop': - case 'quit': - if ($arg) { - return null; - } else { - return new OffCommand($user); - } - case 'follow': - case 'sub': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new SubCommand($user, $other); - } - case 'leave': - case 'unsub': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new UnsubCommand($user, $other); - } - case 'get': - case 'last': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new GetCommand($user, $other); - } - case 'd': - case 'dm': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if (!$extra) { - return null; - } else { - return new MessageCommand($user, $other, $extra); - } - case 'whois': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new WhoisCommand($user, $other); - } - case 'fav': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new FavCommand($user, $other); - } - case 'nudge': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new NudgeCommand($user, $other); - } - case 'stats': - if ($arg) { - return null; - } - return new StatsCommand($user); - case 'invite': - if (!$arg) { - return null; - } - list($other, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else { - return new InviteCommand($user, $other); - } - case 'track': - if (!$arg) { - return null; - } - list($word, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else if ($word == 'off') { - return new TrackOffCommand($user); - } else { - return new TrackCommand($user, $word); - } - case 'untrack': - if (!$arg) { - return null; - } - list($word, $extra) = explode(' ', $arg, 2); - if ($extra) { - return null; - } else if ($word == 'all') { - return new TrackOffCommand($user); - } else { - return new UntrackCommand($user, $word); - } - case 'tracks': - case 'tracking': - if ($arg) { - return null; - } - return new TrackingCommand($user); - default: - return false; - } - } -} - diff --git a/lib/channel.php b/lib/channel.php new file mode 100644 index 000000000..fdeff21fc --- /dev/null +++ b/lib/channel.php @@ -0,0 +1,238 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +class Channel +{ + + function on($user) + { + return false; + } + + function off($user) + { + return false; + } + + function output($user, $text) + { + return false; + } + + function error($user, $text) + { + return false; + } + + function source() + { + return null; + } +} + +class XMPPChannel extends Channel +{ + + var $conn = null; + + function source() + { + return 'xmpp'; + } + + function __construct($conn) + { + $this->conn = $conn; + } + + function on($user) + { + return $this->set_notify($user, 1); + } + + function off($user) + { + return $this->set_notify($user, 0); + } + + function output($user, $text) + { + $text = '['.common_config('site', 'name') . '] ' . $text; + jabber_send_message($user->jabber, $text); + } + + function error($user, $text) + { + $text = '['.common_config('site', 'name') . '] ' . $text; + jabber_send_message($user->jabber, $text); + } + + function set_notify(&$user, $notify) + { + $orig = clone($user); + $user->jabbernotify = $notify; + $result = $user->update($orig); + if (!$result) { + $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); + common_log(LOG_ERR, + 'Could not set notify flag to ' . $notify . + ' for user ' . common_log_objstring($user) . + ': ' . $last_error->message); + return false; + } else { + common_log(LOG_INFO, + 'User ' . $user->nickname . ' set notify flag to ' . $notify); + return true; + } + } +} + +class WebChannel extends Channel +{ + var $out = null; + + function __construct($out=null) + { + $this->out = $out; + } + + function source() + { + return 'web'; + } + + function on($user) + { + return false; + } + + function off($user) + { + return false; + } + + function output($user, $text) + { + # XXX: buffer all output and send it at the end + # XXX: even better, redirect to appropriate page + # depending on what command was run + $this->out->startHTML(); + $this->out->elementStart('head'); + $this->out->element('title', null, _('Command results')); + $this->out->elementEnd('head'); + $this->out->elementStart('body'); + $this->out->element('p', array('id' => 'command_result'), $text); + $this->out->elementEnd('body'); + $this->out->endHTML(); + } + + function error($user, $text) + { + common_user_error($text); + } +} + +class AjaxWebChannel extends WebChannel +{ + function output($user, $text) + { + $this->out->startHTML('text/xml;charset=utf-8'); + $this->out->elementStart('head'); + $this->out->element('title', null, _('Command results')); + $this->out->elementEnd('head'); + $this->out->elementStart('body'); + $this->out->element('p', array('id' => 'command_result'), $text); + $this->out->elementEnd('body'); + $this->out->endHTML(); + } + + function error($user, $text) + { + $this->out->startHTML('text/xml;charset=utf-8'); + $this->out->elementStart('head'); + $this->out->element('title', null, _('Ajax Error')); + $this->out->elementEnd('head'); + $this->out->elementStart('body'); + $this->out->element('p', array('id' => 'error'), $text); + $this->out->elementEnd('body'); + $this->out->endHTML(); + } +} + +class MailChannel extends Channel +{ + + var $addr = null; + + function source() + { + return 'mail'; + } + + function __construct($addr=null) + { + $this->addr = $addr; + } + + function on($user) + { + return $this->set_notify($user, 1); + } + + function off($user) + { + return $this->set_notify($user, 0); + } + + function output($user, $text) + { + + $headers['From'] = $user->incomingemail; + $headers['To'] = $this->addr; + + $headers['Subject'] = _('Command complete'); + + return mail_send(array($this->addr), $headers, $text); + } + + function error($user, $text) + { + + $headers['From'] = $user->incomingemail; + $headers['To'] = $this->addr; + + $headers['Subject'] = _('Command failed'); + + return mail_send(array($this->addr), $headers, $text); + } + + function set_notify($user, $value) + { + $orig = clone($user); + $user->smsnotify = $value; + $result = $user->update($orig); + if (!$result) { + common_log_db_error($user, 'UPDATE', __FILE__); + return false; + } + return true; + } +} diff --git a/lib/command.php b/lib/command.php new file mode 100644 index 000000000..eacbdacb3 --- /dev/null +++ b/lib/command.php @@ -0,0 +1,419 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/classes/Channel.php'); + +class Command +{ + + var $user = null; + + function __construct($user=null) + { + $this->user = $user; + } + + function execute($channel) + { + return false; + } +} + +class UnimplementedCommand extends Command +{ + function execute($channel) + { + $channel->error($this->user, _("Sorry, this command is not yet implemented.")); + } +} + +class TrackingCommand extends UnimplementedCommand +{ +} + +class TrackOffCommand extends UnimplementedCommand +{ +} + +class TrackCommand extends UnimplementedCommand +{ + var $word = null; + function __construct($user, $word) + { + parent::__construct($user); + $this->word = $word; + } +} + +class UntrackCommand extends UnimplementedCommand +{ + var $word = null; + function __construct($user, $word) + { + parent::__construct($user); + $this->word = $word; + } +} + +class NudgeCommand extends UnimplementedCommand +{ + var $other = null; + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } +} + +class InviteCommand extends UnimplementedCommand +{ + var $other = null; + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } +} + +class StatsCommand extends Command +{ + function execute($channel) + { + + $subs = new Subscription(); + $subs->subscriber = $this->user->id; + $subs_count = (int) $subs->count() - 1; + + $subbed = new Subscription(); + $subbed->subscribed = $this->user->id; + $subbed_count = (int) $subbed->count() - 1; + + $notices = new Notice(); + $notices->profile_id = $this->user->id; + $notice_count = (int) $notices->count(); + + $channel->output($this->user, sprintf(_("Subscriptions: %1\$s\n". + "Subscribers: %2\$s\n". + "Notices: %3\$s"), + $subs_count, + $subbed_count, + $notice_count)); + } +} + +class FavCommand extends Command +{ + + var $other = null; + + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } + + function execute($channel) + { + + $recipient = + common_relative_profile($this->user, common_canonical_nickname($this->other)); + + if (!$recipient) { + $channel->error($this->user, _('No such user.')); + return; + } + $notice = $recipient->getCurrentNotice(); + if (!$notice) { + $channel->error($this->user, _('User has no last notice')); + return; + } + + $fave = Fave::addNew($this->user, $notice); + + if (!$fave) { + $channel->error($this->user, _('Could not create favorite.')); + return; + } + + $other = User::staticGet('id', $recipient->id); + + if ($other && $other->id != $user->id) { + if ($other->email && $other->emailnotifyfav) { + mail_notify_fave($other, $this->user, $notice); + } + } + + $this->user->blowFavesCache(); + + $channel->output($this->user, _('Notice marked as fave.')); + } +} + +class WhoisCommand extends Command +{ + var $other = null; + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } + + function execute($channel) + { + $recipient = + common_relative_profile($this->user, common_canonical_nickname($this->other)); + + if (!$recipient) { + $channel->error($this->user, _('No such user.')); + return; + } + + $whois = sprintf(_("%1\$s (%2\$s)"), $recipient->nickname, + $recipient->profileurl); + if ($recipient->fullname) { + $whois .= "\n" . sprintf(_('Fullname: %s'), $recipient->fullname); + } + if ($recipient->location) { + $whois .= "\n" . sprintf(_('Location: %s'), $recipient->location); + } + if ($recipient->homepage) { + $whois .= "\n" . sprintf(_('Homepage: %s'), $recipient->homepage); + } + if ($recipient->bio) { + $whois .= "\n" . sprintf(_('About: %s'), $recipient->bio); + } + $channel->output($this->user, $whois); + } +} + +class MessageCommand extends Command +{ + var $other = null; + var $text = null; + function __construct($user, $other, $text) + { + parent::__construct($user); + $this->other = $other; + $this->text = $text; + } + + function execute($channel) + { + $other = User::staticGet('nickname', common_canonical_nickname($this->other)); + $len = mb_strlen($this->text); + if ($len == 0) { + $channel->error($this->user, _('No content!')); + return; + } else if ($len > 140) { + $content = common_shorten_links($content); + if (mb_strlen($content) > 140) { + $channel->error($this->user, sprintf(_('Message too long - maximum is 140 characters, you sent %d'), $len)); + return; + } + } + + if (!$other) { + $channel->error($this->user, _('No such user.')); + return; + } else if (!$this->user->mutuallySubscribed($other)) { + $channel->error($this->user, _('You can\'t send a message to this user.')); + return; + } else if ($this->user->id == $other->id) { + $channel->error($this->user, _('Don\'t send a message to yourself; just say it to yourself quietly instead.')); + return; + } + $message = Message::saveNew($this->user->id, $other->id, $this->text, $channel->source()); + if ($message) { + $channel->output($this->user, sprintf(_('Direct message to %s sent'), $this->other)); + } else { + $channel->error($this->user, _('Error sending direct message.')); + } + } +} + +class GetCommand extends Command +{ + + var $other = null; + + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } + + function execute($channel) + { + $target_nickname = common_canonical_nickname($this->other); + + $target = + common_relative_profile($this->user, $target_nickname); + + if (!$target) { + $channel->error($this->user, _('No such user.')); + return; + } + $notice = $target->getCurrentNotice(); + if (!$notice) { + $channel->error($this->user, _('User has no last notice')); + return; + } + $notice_content = $notice->content; + + $channel->output($this->user, $target_nickname . ": " . $notice_content); + } +} + +class SubCommand extends Command +{ + + var $other = null; + + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } + + function execute($channel) + { + + if (!$this->other) { + $channel->error($this->user, _('Specify the name of the user to subscribe to')); + return; + } + + $result = subs_subscribe_user($this->user, $this->other); + + if ($result == 'true') { + $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other)); + } else { + $channel->error($this->user, $result); + } + } +} + +class UnsubCommand extends Command +{ + + var $other = null; + + function __construct($user, $other) + { + parent::__construct($user); + $this->other = $other; + } + + function execute($channel) + { + if(!$this->other) { + $channel->error($this->user, _('Specify the name of the user to unsubscribe from')); + return; + } + + $result=subs_unsubscribe_user($this->user, $this->other); + + if ($result) { + $channel->output($this->user, sprintf(_('Unsubscribed from %s'), $this->other)); + } else { + $channel->error($this->user, $result); + } + } +} + +class OffCommand extends Command +{ + var $other = null; + function __construct($user, $other=null) + { + parent::__construct($user); + $this->other = $other; + } + function execute($channel) + { + if ($other) { + $channel->error($this->user, _("Command not yet implemented.")); + } else { + if ($channel->off($this->user)) { + $channel->output($this->user, _('Notification off.')); + } else { + $channel->error($this->user, _('Can\'t turn off notification.')); + } + } + } +} + +class OnCommand extends Command +{ + var $other = null; + function __construct($user, $other=null) + { + parent::__construct($user); + $this->other = $other; + } + + function execute($channel) + { + if ($other) { + $channel->error($this->user, _("Command not yet implemented.")); + } else { + if ($channel->on($this->user)) { + $channel->output($this->user, _('Notification on.')); + } else { + $channel->error($this->user, _('Can\'t turn on notification.')); + } + } + } +} + +class HelpCommand extends Command +{ + function execute($channel) + { + $channel->output($this->user, + _("Commands:\n". + "on - turn on notifications\n". + "off - turn off notifications\n". + "help - show this help\n". + "follow - subscribe to user\n". + "leave - unsubscribe from user\n". + "d - direct message to user\n". + "get - get last notice from user\n". + "whois - get profile info on user\n". + "fav - add user's last notice as a 'fave'\n". + "stats - get your stats\n". + "stop - same as 'off'\n". + "quit - same as 'off'\n". + "sub - same as 'follow'\n". + "unsub - same as 'leave'\n". + "last - same as 'get'\n". + "on - not yet implemented.\n". + "off - not yet implemented.\n". + "nudge - not yet implemented.\n". + "invite - not yet implemented.\n". + "track - not yet implemented.\n". + "untrack - not yet implemented.\n". + "track off - not yet implemented.\n". + "untrack all - not yet implemented.\n". + "tracks - not yet implemented.\n". + "tracking - not yet implemented.\n")); + } +} diff --git a/lib/commandinterpreter.php b/lib/commandinterpreter.php new file mode 100644 index 000000000..0679f5462 --- /dev/null +++ b/lib/commandinterpreter.php @@ -0,0 +1,198 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/classes/Command.php'); + +class CommandInterpreter +{ + + function handle_command($user, $text) + { + # XXX: localise + + $text = preg_replace('/\s+/', ' ', trim($text)); + list($cmd, $arg) = explode(' ', $text, 2); + + # We try to support all the same commands as Twitter, see + # http://getsatisfaction.com/twitter/topics/what_are_the_twitter_commands + # There are a few compatibility commands from earlier versions of + # Laconica + + switch(strtolower($cmd)) { + case 'help': + if ($arg) { + return null; + } + return new HelpCommand($user); + case 'on': + if ($arg) { + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new OnCommand($user, $other); + } + } else { + return new OnCommand($user); + } + case 'off': + if ($arg) { + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new OffCommand($user, $other); + } + } else { + return new OffCommand($user); + } + case 'stop': + case 'quit': + if ($arg) { + return null; + } else { + return new OffCommand($user); + } + case 'follow': + case 'sub': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new SubCommand($user, $other); + } + case 'leave': + case 'unsub': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new UnsubCommand($user, $other); + } + case 'get': + case 'last': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new GetCommand($user, $other); + } + case 'd': + case 'dm': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if (!$extra) { + return null; + } else { + return new MessageCommand($user, $other, $extra); + } + case 'whois': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new WhoisCommand($user, $other); + } + case 'fav': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new FavCommand($user, $other); + } + case 'nudge': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new NudgeCommand($user, $other); + } + case 'stats': + if ($arg) { + return null; + } + return new StatsCommand($user); + case 'invite': + if (!$arg) { + return null; + } + list($other, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else { + return new InviteCommand($user, $other); + } + case 'track': + if (!$arg) { + return null; + } + list($word, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else if ($word == 'off') { + return new TrackOffCommand($user); + } else { + return new TrackCommand($user, $word); + } + case 'untrack': + if (!$arg) { + return null; + } + list($word, $extra) = explode(' ', $arg, 2); + if ($extra) { + return null; + } else if ($word == 'all') { + return new TrackOffCommand($user); + } else { + return new UntrackCommand($user, $word); + } + case 'tracks': + case 'tracking': + if ($arg) { + return null; + } + return new TrackingCommand($user); + default: + return false; + } + } +} + -- cgit v1.2.3-54-g00ecf From 9d07032334043625a5aa3243d911bdc1c77a7a9c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 11 Feb 2009 15:48:30 -0500 Subject: fix command classes --- lib/channel.php | 1 - lib/command.php | 74 +++++++++++++++++++++++----------------------- lib/commandinterpreter.php | 3 +- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/lib/channel.php b/lib/channel.php index fdeff21fc..f1e205546 100644 --- a/lib/channel.php +++ b/lib/channel.php @@ -21,7 +21,6 @@ if (!defined('LACONICA')) { exit(1); } class Channel { - function on($user) { return false; diff --git a/lib/command.php b/lib/command.php index eacbdacb3..507990a0b 100644 --- a/lib/command.php +++ b/lib/command.php @@ -19,18 +19,18 @@ if (!defined('LACONICA')) { exit(1); } -require_once(INSTALLDIR.'/classes/Channel.php'); +require_once(INSTALLDIR.'/lib/channel.php'); class Command { - + var $user = null; - + function __construct($user=null) { $this->user = $user; } - + function execute($channel) { return false; @@ -109,7 +109,7 @@ class StatsCommand extends Command $notices = new Notice(); $notices->profile_id = $this->user->id; $notice_count = (int) $notices->count(); - + $channel->output($this->user, sprintf(_("Subscriptions: %1\$s\n". "Subscribers: %2\$s\n". "Notices: %3\$s"), @@ -121,21 +121,21 @@ class StatsCommand extends Command class FavCommand extends Command { - + var $other = null; - + function __construct($user, $other) { parent::__construct($user); $this->other = $other; } - + function execute($channel) { - - $recipient = + + $recipient = common_relative_profile($this->user, common_canonical_nickname($this->other)); - + if (!$recipient) { $channel->error($this->user, _('No such user.')); return; @@ -145,7 +145,7 @@ class FavCommand extends Command $channel->error($this->user, _('User has no last notice')); return; } - + $fave = Fave::addNew($this->user, $notice); if (!$fave) { @@ -154,15 +154,15 @@ class FavCommand extends Command } $other = User::staticGet('id', $recipient->id); - + if ($other && $other->id != $user->id) { if ($other->email && $other->emailnotifyfav) { mail_notify_fave($other, $this->user, $notice); } } - + $this->user->blowFavesCache(); - + $channel->output($this->user, _('Notice marked as fave.')); } } @@ -175,17 +175,17 @@ class WhoisCommand extends Command parent::__construct($user); $this->other = $other; } - + function execute($channel) { - $recipient = + $recipient = common_relative_profile($this->user, common_canonical_nickname($this->other)); - + if (!$recipient) { $channel->error($this->user, _('No such user.')); return; } - + $whois = sprintf(_("%1\$s (%2\$s)"), $recipient->nickname, $recipient->profileurl); if ($recipient->fullname) { @@ -214,7 +214,7 @@ class MessageCommand extends Command $this->other = $other; $this->text = $text; } - + function execute($channel) { $other = User::staticGet('nickname', common_canonical_nickname($this->other)); @@ -229,7 +229,7 @@ class MessageCommand extends Command return; } } - + if (!$other) { $channel->error($this->user, _('No such user.')); return; @@ -251,19 +251,19 @@ class MessageCommand extends Command class GetCommand extends Command { - + var $other = null; - + function __construct($user, $other) { parent::__construct($user); $this->other = $other; } - + function execute($channel) { $target_nickname = common_canonical_nickname($this->other); - + $target = common_relative_profile($this->user, $target_nickname); @@ -277,32 +277,32 @@ class GetCommand extends Command return; } $notice_content = $notice->content; - + $channel->output($this->user, $target_nickname . ": " . $notice_content); } } class SubCommand extends Command { - + var $other = null; - + function __construct($user, $other) { parent::__construct($user); $this->other = $other; } - + function execute($channel) { - + if (!$this->other) { $channel->error($this->user, _('Specify the name of the user to subscribe to')); return; } - + $result = subs_subscribe_user($this->user, $this->other); - + if ($result == 'true') { $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other)); } else { @@ -315,7 +315,7 @@ class UnsubCommand extends Command { var $other = null; - + function __construct($user, $other) { parent::__construct($user); @@ -328,9 +328,9 @@ class UnsubCommand extends Command $channel->error($this->user, _('Specify the name of the user to unsubscribe from')); return; } - + $result=subs_unsubscribe_user($this->user, $this->other); - + if ($result) { $channel->output($this->user, sprintf(_('Unsubscribed from %s'), $this->other)); } else { @@ -369,7 +369,7 @@ class OnCommand extends Command parent::__construct($user); $this->other = $other; } - + function execute($channel) { if ($other) { @@ -406,7 +406,7 @@ class HelpCommand extends Command "unsub - same as 'leave'\n". "last - same as 'get'\n". "on - not yet implemented.\n". - "off - not yet implemented.\n". + "off - not yet implemented.\n". "nudge - not yet implemented.\n". "invite - not yet implemented.\n". "track - not yet implemented.\n". diff --git a/lib/commandinterpreter.php b/lib/commandinterpreter.php index 0679f5462..49c733c03 100644 --- a/lib/commandinterpreter.php +++ b/lib/commandinterpreter.php @@ -19,11 +19,10 @@ if (!defined('LACONICA')) { exit(1); } -require_once(INSTALLDIR.'/classes/Command.php'); +require_once INSTALLDIR.'/lib/command.php'; class CommandInterpreter { - function handle_command($user, $text) { # XXX: localise -- cgit v1.2.3-54-g00ecf From 9f035e2847e0d119ca3d70e02df6f4fa73ca64c3 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 11 Feb 2009 21:41:56 -0800 Subject: Code to handle PEAR_Errors raised by DB_DataObject that are bubbling up, but are actually expected and can safely be ignored. --- actions/emailsettings.php | 22 ++++++++++++++++++++++ actions/register.php | 23 ++++++++++++++++++++++- lib/action.php | 26 ++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/actions/emailsettings.php b/actions/emailsettings.php index b84acb214..c6c983453 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -487,4 +487,26 @@ class EmailsettingsAction extends AccountSettingsAction return $other->id != $user->id; } } + + /** + * Check old fashioned PEAR_Error msgs coming from DB_DataObject + * + * In this case email don't exist in the DB yet, so DB_DataObject + * throws an error. Overrided from Action. + * + * @param PEAR_Error + * + * @return nothing + */ + + function checkDB_DataObjectError($error) { + if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { + + // Do nothing. + + } else { + parent::checkDB_DataObjectError($error); + } + } + } diff --git a/actions/register.php b/actions/register.php index 5d7a8ce69..853bd0cf6 100644 --- a/actions/register.php +++ b/actions/register.php @@ -223,10 +223,31 @@ class RegisterAction extends Action */ function nicknameExists($nickname) - { + { $user = User::staticGet('nickname', $nickname); return ($user !== false); } + + /** + * Check old fashioned PEAR_Error msgs coming from DB_DataObject + * + * In this case nickname and email don't exist in the DB yet, + * so DB_DataObject throws an error. Overrided from Action. + * + * @param PEAR_Error + * + * @return nothing + */ + + function checkDB_DataObjectError($error) { + if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { + + // Do nothing. + + } else { + parent::checkDB_DataObjectError($error); + } + } /** * Does the given email address already exist? diff --git a/lib/action.php b/lib/action.php index bd38bf79c..e3a8ef62c 100644 --- a/lib/action.php +++ b/lib/action.php @@ -82,6 +82,17 @@ class Action extends HTMLOutputter // lawsuit */ function prepare($argarray) { + // This is for checking PEAR_Errors raised by DB_DataObject. + // Setting this to PEAR_ERROR_CALLBACK because setting + // to PEAR_ERROR_EXCEPTION does't work to allow PEAR_Errors + // to be handled as PHP5 exceptions, and PEAR_ERROR_RETURN + // does not cause DB_DataObject to actually return PEAR_Errors + // that can be checked with PEAR::isError() -- instead + // they just disappear into the ether, and can only be checked for + // after the fact. -- Zach + PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, + array($this, "checkDB_DataObjectError")); + $this->args =& common_copy_args($argarray); return true; } @@ -844,6 +855,21 @@ class Action extends HTMLOutputter // lawsuit throw new ClientException($msg, $code); } + /** + * Check old fashioned PEAR_Error msgs coming from DB_DataObject + * + * Logs the DB_DataObject error. Override to do something else. + * + * @param PEAR_Error + * + * @return nothing + */ + + function checkDB_DataObjectError($error) { + common_log(LOG_ERR, $error->getMessage()); + // XXX: throw an exception here? --Zach + } + /** * Returns the current URL * -- cgit v1.2.3-54-g00ecf From 616bdd43a921b2554d21b80af28ddb0fb6cb3c16 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 11 Feb 2009 22:08:20 -0800 Subject: Just discovered the PEAR_Error handling function in index.php. Duh. Renamed the Action functions to throw an exception like it. I still think it probably makes sense to have the callback defined in both places for finer control. --- actions/emailsettings.php | 6 +++--- actions/register.php | 6 +++--- lib/action.php | 31 ++++++++++++++++++------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/actions/emailsettings.php b/actions/emailsettings.php index c6c983453..0a86aa66d 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -489,7 +489,7 @@ class EmailsettingsAction extends AccountSettingsAction } /** - * Check old fashioned PEAR_Error msgs coming from DB_DataObject + * Handle old fashioned PEAR_Error msgs coming from DB_DataObject * * In this case email don't exist in the DB yet, so DB_DataObject * throws an error. Overrided from Action. @@ -499,13 +499,13 @@ class EmailsettingsAction extends AccountSettingsAction * @return nothing */ - function checkDB_DataObjectError($error) { + function handleError($error) { if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { // Do nothing. } else { - parent::checkDB_DataObjectError($error); + parent::handleError($error); } } diff --git a/actions/register.php b/actions/register.php index 853bd0cf6..aafb54ebb 100644 --- a/actions/register.php +++ b/actions/register.php @@ -229,7 +229,7 @@ class RegisterAction extends Action } /** - * Check old fashioned PEAR_Error msgs coming from DB_DataObject + * Handle old fashioned PEAR_Error msgs coming from DB_DataObject * * In this case nickname and email don't exist in the DB yet, * so DB_DataObject throws an error. Overrided from Action. @@ -239,13 +239,13 @@ class RegisterAction extends Action * @return nothing */ - function checkDB_DataObjectError($error) { + function handleError($error) { if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { // Do nothing. } else { - parent::checkDB_DataObjectError($error); + parent::handleError($error); } } diff --git a/lib/action.php b/lib/action.php index e3a8ef62c..926fe93fb 100644 --- a/lib/action.php +++ b/lib/action.php @@ -82,16 +82,10 @@ class Action extends HTMLOutputter // lawsuit */ function prepare($argarray) { - // This is for checking PEAR_Errors raised by DB_DataObject. - // Setting this to PEAR_ERROR_CALLBACK because setting - // to PEAR_ERROR_EXCEPTION does't work to allow PEAR_Errors - // to be handled as PHP5 exceptions, and PEAR_ERROR_RETURN - // does not cause DB_DataObject to actually return PEAR_Errors - // that can be checked with PEAR::isError() -- instead - // they just disappear into the ether, and can only be checked for - // after the fact. -- Zach + + // For PEAR_Errors comming from DB_DataObject PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, - array($this, "checkDB_DataObjectError")); + array($this, "handleError")); $this->args =& common_copy_args($argarray); return true; @@ -856,7 +850,7 @@ class Action extends HTMLOutputter // lawsuit } /** - * Check old fashioned PEAR_Error msgs coming from DB_DataObject + * Handle old fashioned PEAR_Error msgs coming from DB_DataObject * * Logs the DB_DataObject error. Override to do something else. * @@ -865,9 +859,20 @@ class Action extends HTMLOutputter // lawsuit * @return nothing */ - function checkDB_DataObjectError($error) { - common_log(LOG_ERR, $error->getMessage()); - // XXX: throw an exception here? --Zach + function handleError($error) { + + common_log(LOG_ERR, "PEAR error: " . $error->getMessage()); + $msg = sprintf(_('The database for %s isn\'t responding correctly, '. + 'so the site won\'t work properly. '. + 'The site admins probably know about the problem, '. + 'but you can contact them at %s to make sure. '. + 'Otherwise, wait a few minutes and try again.'), + common_config('site', 'name'), + common_config('site', 'email')); + + $dac = new DBErrorAction($msg, 500); + $dac->showPage(); + exit(-1); } /** -- cgit v1.2.3-54-g00ecf From a845d06c77f17a5037e30d41db939f0ed3b5936e Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 12 Feb 2009 06:49:34 -0500 Subject: ignore no-data error, since we use it all the time --- index.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/index.php b/index.php index 4db0e7555..b180e2b65 100644 --- a/index.php +++ b/index.php @@ -38,6 +38,10 @@ function getPath($req) function handleError($error) { + if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { + return; + } + common_log(LOG_ERR, "PEAR error: " . $error->getMessage()); $msg = sprintf(_('The database for %s isn\'t responding correctly, '. 'so the site won\'t work properly. '. -- cgit v1.2.3-54-g00ecf From 99773e3b5ef0fa395bccb9a9656afe7552d42594 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 12 Feb 2009 07:58:36 -0500 Subject: wrap multiline regexp in quotes so it doesn't mess up my editor's indenting --- lib/util.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/util.php b/lib/util.php index c0c980111..03e3618db 100644 --- a/lib/util.php +++ b/lib/util.php @@ -394,20 +394,20 @@ function common_render_text($text) function common_replace_urls_callback($text, $callback) { // Start off with a regex - $regex = '# - (?: - (?: - (?:https?|ftps?|mms|rtsp|gopher|news|nntp|telnet|wais|file|prospero|webcal|xmpp|irc):// - | - (?:mailto|aim|tel): - ) - [^.\s]+\.[^\s]+ - | - (?:[^.\s/:]+\.)+ - (?:museum|travel|[a-z]{2,4}) - (?:[:/][^\s]*)? - ) - #ix'; + $regex = '#'. + '(?:'. + '(?:'. + '(?:https?|ftps?|mms|rtsp|gopher|news|nntp|telnet|wais|file|prospero|webcal|xmpp|irc)://'. + '|'. + '(?:mailto|aim|tel):'. + ')'. + '[^.\s]+\.[^\s]+'. + '|'. + '(?:[^.\s/:]+\.)+'. + '(?:museum|travel|[a-z]{2,4})'. + '(?:[:/][^\s]*)?'. + ')'. + '#ix'; preg_match_all($regex, $text, $matches); // Then clean up what the regex left behind -- cgit v1.2.3-54-g00ecf From eaae4562228bcbf780329d7bbb5f35437b31ebe3 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 12 Feb 2009 08:38:43 -0500 Subject: Add XMLStringer for building XML strings We had a bunch of --- lib/util.php | 41 ++++++++++++++++++++++++++------ lib/xmlstringer.php | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 lib/xmlstringer.php diff --git a/lib/util.php b/lib/util.php index 03e3618db..a6f6a9351 100644 --- a/lib/util.php +++ b/lib/util.php @@ -475,13 +475,14 @@ function common_linkify($url) { $display = $url; $url = (!preg_match('#^([a-z]+://|(mailto|aim|tel):)#i', $url)) ? 'http://'.$url:$url; + $attrs = array('href' => $url, 'rel' => 'external'); + if ($longurl = common_longurl($url)) { $longurl = htmlentities($longurl, ENT_QUOTES, 'UTF-8'); - $title = "title=\"$longurl\""; + $attrs['title'] = $longurl; } - else $title = ''; - return "$display"; + return XMLStringer::estring('a', $attrs, $display); } function common_longurl($short_url) @@ -582,7 +583,13 @@ function common_tag_link($tag) { $canonical = common_canonical_tag($tag); $url = common_local_url('tag', array('tag' => $canonical)); - return ''; + $xs = new XMLStringer(); + $xs->elementStart('span', 'tag'); + $xs->element('a', array('href' => $url, + 'rel' => 'tag'), + $tag); + $xs->elementEnd(); + return $xs->getString(); } function common_canonical_tag($tag) @@ -600,7 +607,14 @@ function common_at_link($sender_id, $nickname) $sender = Profile::staticGet($sender_id); $recipient = common_relative_profile($sender, common_canonical_nickname($nickname)); if ($recipient) { - return ''.$nickname.''; + $xs = new XMLStringer(false); + $xs->elementStart('span', 'vcard'); + $xs->elementStart('a', array('href' => $recipient->profileurl, + 'class' => 'url')); + $xs->element('span', 'fn nickname', $nickname); + $xs->elementEnd('a'); + $xs->elementEnd('span'); + return $xs->getString(); } else { return $nickname; } @@ -611,7 +625,14 @@ function common_group_link($sender_id, $nickname) $sender = Profile::staticGet($sender_id); $group = User_group::staticGet('nickname', common_canonical_nickname($nickname)); if ($group && $sender->isMember($group)) { - return ''.$nickname.''; + $xs = new XMLStringer(); + $xs->elementStart('span', 'vcard'); + $xs->elementStart('a', array('href' => $group->permalink(), + 'class' => 'url')); + $xs->element('span', 'fn nickname', $nickname); + $xs->elementEnd('a'); + $xs->elementEnd('span'); + return $xs->getString(); } else { return $nickname; } @@ -628,7 +649,13 @@ function common_at_hash_link($sender_id, $tag) $url = common_local_url('subscriptions', array('nickname' => $user->nickname, 'tag' => $tag)); - return ''; + $xs = new XMLStringer(); + $xs->elementStart('span', 'tag'); + $xs->element('a', array('href' => $url, + 'rel' => $tag), + $tag); + $xs->elementEnd('span'); + return $xs->getString(); } else { return $tag; } diff --git a/lib/xmlstringer.php b/lib/xmlstringer.php new file mode 100644 index 000000000..951b13b67 --- /dev/null +++ b/lib/xmlstringer.php @@ -0,0 +1,68 @@ +. + * + * @category Output + * @package Laconica + * @author Evan Prodromou + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Create in-memory XML + * + * @category Output + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * @see Action + * @see HTMLOutputter + */ + +class XMLStringer extends XMLOutputter +{ + function __construct($indent=false) + { + $this->xw = new XMLWriter(); + $this->xw->openMemory(); + $this->xw->setIndent($indent); + } + + function getString() + { + return $this->xw->outputMemory(); + } + + // utility for quickly creating XML-strings + + static function estring($tag, $attrs=null, $content=null) + { + $xs = new XMLStringer(); + $xs->element($tag, $attrs, $content); + return $xs->getString(); + } +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf From ab8d27b8d1e25bd1058b904d03fedf97148f4b89 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 12 Feb 2009 09:22:45 -0500 Subject: don't over specialize URLs --- lib/util.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/util.php b/lib/util.php index a6f6a9351..37c941cdb 100644 --- a/lib/util.php +++ b/lib/util.php @@ -472,13 +472,15 @@ function common_replace_urls_callback($text, $callback) { } function common_linkify($url) { + // It comes in special'd, so we unspecial it before passing to the stringifying + // functions + $url = htmlspecialchars_decode($url); $display = $url; - $url = (!preg_match('#^([a-z]+://|(mailto|aim|tel):)#i', $url)) ? 'http://'.$url:$url; + $url = (!preg_match('#^([a-z]+://|(mailto|aim|tel):)#i', $url)) ? 'http://'.$url : $url; $attrs = array('href' => $url, 'rel' => 'external'); if ($longurl = common_longurl($url)) { - $longurl = htmlentities($longurl, ENT_QUOTES, 'UTF-8'); $attrs['title'] = $longurl; } -- cgit v1.2.3-54-g00ecf