diff --git a/actions/newmessage.php b/actions/newmessage.php index 7dce97d20b..2455f42e94 100644 --- a/actions/newmessage.php +++ b/actions/newmessage.php @@ -53,10 +53,15 @@ class NewmessageAction extends Action { $this->show_form(_('No content!')); return; } else if (mb_strlen($content) > 140) { - common_debug("Content = '$content'", __FILE__); - common_debug("mb_strlen(\$content) = " . mb_strlen($content), __FILE__); - $this->show_form(_('That\'s too long. Max message size is 140 chars.')); - return; + + $content = common_shorten_links($content); + + if (mb_strlen($content) > 140) { + common_debug("Content = '$content'", __FILE__); + common_debug("mb_strlen(\$content) = " . mb_strlen($content), __FILE__); + $this->show_form(_('That\'s too long. Max message size is 140 chars.')); + return; + } } $other = User::staticGet('id', $to); diff --git a/actions/newnotice.php b/actions/newnotice.php index 37cca982d6..8ea47b235b 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -51,10 +51,15 @@ class NewnoticeAction extends Action { $this->show_form(_('No content!')); return; } else if (mb_strlen($content) > 140) { - common_debug("Content = '$content'", __FILE__); - common_debug("mb_strlen(\$content) = " . mb_strlen($content), __FILE__); - $this->show_form(_('That\'s too long. Max notice size is 140 chars.')); - return; + + $content = common_shorten_links($content); + + if (mb_strlen($content) > 140) { + common_debug("Content = '$content'", __FILE__); + common_debug("mb_strlen(\$content) = " . mb_strlen($content), __FILE__); + $this->show_form(_('That\'s too long. Max notice size is 140 chars.')); + return; + } } $inter = new CommandInterpreter(); diff --git a/actions/postnotice.php b/actions/postnotice.php index be486a1e9d..b4a272e618 100644 --- a/actions/postnotice.php +++ b/actions/postnotice.php @@ -59,8 +59,11 @@ class PostnoticeAction extends Action { } $content = $req->get_parameter('omb_notice_content'); if (!$content || strlen($content) > 140) { - common_user_error(_('Invalid notice content'), 400); - return false; + $content = common_shorten_links($content); + if (mb_strlen($content) > 140) { + common_user_error(_('Invalid notice content'), 400); + return false; + } } $notice_uri = $req->get_parameter('omb_notice'); if (!Validate::uri($notice_uri) && diff --git a/actions/profilesettings.php b/actions/profilesettings.php index e5698011ac..2ae7360876 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -224,8 +224,8 @@ class ProfilesettingsAction extends SettingsAction { } else if ($this->nickname_exists($nickname)) { $this->show_form(_('Nickname already in use. Try another one.')); return; - } else if (!is_null($language) && strlen($language) > 50) { - $this->show_form(_('Language is too long (max 50 chars).')); + } else if (!is_null($language) && strlen($language) > 50) { + $this->show_form(_('Language is too long (max 50 chars).')); } $user = common_current_user(); diff --git a/actions/twitapidirect_messages.php b/actions/twitapidirect_messages.php index a0a09a4108..3037890ad2 100644 --- a/actions/twitapidirect_messages.php +++ b/actions/twitapidirect_messages.php @@ -113,9 +113,12 @@ class Twitapidirect_messagesAction extends TwitterapiAction { if (!$content) { $this->client_error(_('No message text!'), $code = 406, $apidata['content-type']); } else if (mb_strlen($status) > 140) { - $this->client_error(_('That\'s too long. Max message size is 140 chars.'), - $code = 406, $apidata['content-type']); - return; + $status = common_shorten_links($status); + if (mb_strlen($status) > 140) { + $this->client_error(_('That\'s too long. Max message size is 140 chars.'), + $code = 406, $apidata['content-type']); + return; + } } $other = $this->get_user($this->trimmed('user')); diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php index 539a0b1b3b..ca79feb4c6 100644 --- a/actions/twitapistatuses.php +++ b/actions/twitapistatuses.php @@ -253,13 +253,19 @@ class TwitapistatusesAction extends TwitterapiAction { return; } else if (mb_strlen($status) > 140) { + + $status = common_shorten_links($status); - // XXX: Twitter truncates anything over 140, flags the status - // as "truncated." Sending this error may screw up some clients - // that assume Twitter will truncate for them. Should we just - // truncate too? -- Zach - $this->client_error(_('That\'s too long. Max notice size is 140 chars.'), $code = 406, $apidata['content-type']); - return; + if (mb_strlen($status) > 140) { + + // XXX: Twitter truncates anything over 140, flags the status + // as "truncated." Sending this error may screw up some clients + // that assume Twitter will truncate for them. Should we just + // truncate too? -- Zach + $this->client_error(_('That\'s too long. Max notice size is 140 chars.'), $code = 406, $apidata['content-type']); + return; + + } } // Check for commands diff --git a/classes/Command.php b/classes/Command.php index 0795f86afb..c2409d140a 100644 --- a/classes/Command.php +++ b/classes/Command.php @@ -197,9 +197,14 @@ class MessageCommand extends Command { $channel->error($this->user, _('No content!')); return; } else if ($len > 140) { - $channel->error($this->user, sprintf(_('Message too long - maximum is 140 characters, you sent %d'), $len)); - return; - } else if (!$other) { + $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)) { diff --git a/classes/User.php b/classes/User.php index 916524b8e8..e3fa93395e 100644 --- a/classes/User.php +++ b/classes/User.php @@ -55,6 +55,7 @@ class User extends Memcached_DataObject public $smsemail; // varchar(255) public $uri; // varchar(255) unique_key public $autosubscribe; // tinyint(1) + public $urlshorteningservice; // varchar(50) public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP diff --git a/classes/laconica.ini b/classes/laconica.ini index 480b872d11..aa0225739e 100644 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -295,6 +295,7 @@ smsreplies = 17 smsemail = 2 uri = 2 autosubscribe = 17 +urlshorteningservice = 2 created = 142 modified = 384 diff --git a/db/laconica.sql b/db/laconica.sql index 872481ace4..d9a6dbf86a 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -65,6 +65,7 @@ create table user ( smsemail varchar(255) comment 'built from sms and carrier', uri varchar(255) unique key comment 'universally unique identifier, usually a tag URI', autosubscribe tinyint default 0 comment 'automatically subscribe to users who subscribe to us', + urlshorteningservice varchar(50) default 'metamark.net' comment 'service to use for auto-shortening URLs', created datetime not null comment 'date this record was created', modified timestamp comment 'date this record was modified', diff --git a/lib/settingsaction.php b/lib/settingsaction.php index 705ccf3eb6..9e783431f2 100644 --- a/lib/settingsaction.php +++ b/lib/settingsaction.php @@ -97,7 +97,10 @@ class SettingsAction extends Action { _('Updates by instant messenger (IM)')), 'twittersettings' => array(_('Twitter'), - _('Twitter integration options'))); + _('Twitter integration options')), + 'othersettings' => + array(_('Other'), + _('Other options'))); $action = $this->trimmed('action'); common_element_start('ul', array('id' => 'nav_views')); diff --git a/lib/util.php b/lib/util.php index a5eeab0566..edddcd2a70 100644 --- a/lib/util.php +++ b/lib/util.php @@ -747,6 +747,50 @@ function common_render_uri_thingy($matches) { return '' . $uri . '' . $trailer; } +function common_shorten_links($text) { + $r = htmlspecialchars($text); + $r = preg_replace('@https?://[^)\]>\s]+@e', "common_shorten_link('\\0')", $r); + return $r; +} + +function common_shorten_link($long_url) { + + $user = common_current_user(); + + $curlh = curl_init(); + curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait + curl_setopt($curlh, CURLOPT_USERAGENT, 'Laconica'); + curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true); + + switch($user->urlshorteningservice) { + case 'is.gd': + curl_setopt($curlh, CURLOPT_URL, 'http://is.gd/api.php?longurl='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + case 'snipr.com': + curl_setopt($curlh, CURLOPT_URL, 'http://snipr.com/site/snip?r=simple&link='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + case 'metamark.net': + curl_setopt($curlh, CURLOPT_URL, 'http://metamark.net/api/rest/simple?long_url='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + case 'tinyurl.com': + curl_setopt($curlh, CURLOPT_URL, 'http://tinyurl.com/api-create.php?url='.urlencode($long_url)); + $short_url = curl_exec($curlh); + break; + default: + $short_url = false; + } + + curl_close($curlh); + + if ($short_url) { + return $short_url; + } + return $long_url; +} + function common_xml_safe_str($str) { $xmlStr = htmlentities(iconv('UTF-8', 'UTF-8//IGNORE', $str), ENT_NOQUOTES, 'UTF-8');