diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/accountsettingsaction.php | 3 | ||||
-rw-r--r-- | lib/action.php | 24 | ||||
-rw-r--r-- | lib/common.php | 1 | ||||
-rw-r--r-- | lib/noticelist.php | 17 | ||||
-rw-r--r-- | lib/queuehandler.php | 91 | ||||
-rw-r--r-- | lib/router.php | 8 | ||||
-rw-r--r-- | lib/theme.php | 29 | ||||
-rw-r--r-- | lib/twitter.php | 2 | ||||
-rw-r--r-- | lib/util.php | 84 |
9 files changed, 206 insertions, 53 deletions
diff --git a/lib/accountsettingsaction.php b/lib/accountsettingsaction.php index 46090b8c1..86800d2a3 100644 --- a/lib/accountsettingsaction.php +++ b/lib/accountsettingsaction.php @@ -115,6 +115,9 @@ class AccountSettingsNav extends Widget 'openidsettings' => array(_('OpenID'), _('Add or remove OpenIDs')), + 'designsettings' => + array(_('Design'), + _('Design your profile')), 'othersettings' => array(_('Other'), _('Other options'))); diff --git a/lib/action.php b/lib/action.php index 1ba062812..0a628bfdf 100644 --- a/lib/action.php +++ b/lib/action.php @@ -194,37 +194,37 @@ class Action extends HTMLOutputter // lawsuit if (Event::handle('StartShowLaconicaStyles', array($this))) { $this->element('link', array('rel' => 'stylesheet', 'type' => 'text/css', - 'href' => theme_path('css/display.css', 'base') . '?version=' . LACONICA_VERSION, + 'href' => theme_path('base/css/display.css') . '?version=' . LACONICA_VERSION, 'media' => 'screen, projection, tv')); $this->element('link', array('rel' => 'stylesheet', 'type' => 'text/css', - 'href' => theme_path('css/display.css', null) . '?version=' . LACONICA_VERSION, + 'href' => skin_path('css/display.css') . '?version=' . LACONICA_VERSION, 'media' => 'screen, projection, tv')); if (common_config('site', 'mobile')) { $this->element('link', array('rel' => 'stylesheet', 'type' => 'text/css', - 'href' => theme_path('css/mobile.css', 'base') . '?version=' . LACONICA_VERSION, + 'href' => theme_path('base/css/mobile.css') . '?version=' . LACONICA_VERSION, // TODO: "handheld" CSS for other mobile devices 'media' => 'only screen and (max-device-width: 480px)')); // Mobile WebKit } $this->element('link', array('rel' => 'stylesheet', 'type' => 'text/css', - 'href' => theme_path('css/print.css', 'base') . '?version=' . LACONICA_VERSION, + 'href' => theme_path('base/css/print.css') . '?version=' . LACONICA_VERSION, 'media' => 'print')); Event::handle('EndShowLaconicaStyles', array($this)); } if (Event::handle('StartShowUAStyles', array($this))) { $this->comment('[if IE]><link rel="stylesheet" type="text/css" '. - 'href="'.theme_path('css/ie.css', 'base').'?version='.LACONICA_VERSION.'" /><![endif]'); + 'href="'.theme_path('base/css/ie.css').'?version='.LACONICA_VERSION.'" /><![endif]'); foreach (array(6,7) as $ver) { - if (file_exists(theme_file('css/ie'.$ver.'.css', 'base'))) { + if (file_exists(theme_file('base/css/ie'.$ver.'.css'))) { // Yes, IE people should be put in jail. $this->comment('[if lte IE '.$ver.']><link rel="stylesheet" type="text/css" '. - 'href="'.theme_path('css/ie'.$ver.'.css', 'base').'?version='.LACONICA_VERSION.'" /><![endif]'); + 'href="'.theme_path('base/css/ie'.$ver.'.css').'?version='.LACONICA_VERSION.'" /><![endif]'); } } $this->comment('[if IE]><link rel="stylesheet" type="text/css" '. - 'href="'.theme_path('css/ie.css', null).'?version='.LACONICA_VERSION.'" /><![endif]'); + 'href="'.skin_path('css/ie.css').'?version='.LACONICA_VERSION.'" /><![endif]'); Event::handle('EndShowUAStyles', array($this)); } Event::handle('EndShowStyles', array($this)); @@ -848,10 +848,12 @@ class Action extends HTMLOutputter // lawsuit } if ($lm) { header('Last-Modified: ' . date(DATE_RFC1123, $lm)); - if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { - $ims = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); + if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) { + $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $ims = strtotime($if_modified_since); if ($lm <= $ims) { - $if_none_match = $_SERVER['HTTP_IF_NONE_MATCH']; + $if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ? + $_SERVER['HTTP_IF_NONE_MATCH'] : null; if (!$if_none_match || !$etag || $this->_hasEtag($etag, $if_none_match)) { diff --git a/lib/common.php b/lib/common.php index b3882d207..dd2570e75 100644 --- a/lib/common.php +++ b/lib/common.php @@ -71,6 +71,7 @@ $config = array('name' => 'Just another Laconica microblog', 'server' => $_server, 'theme' => 'default', + 'skin' => 'default', 'path' => $_path, 'logfile' => null, 'logo' => null, diff --git a/lib/noticelist.php b/lib/noticelist.php index 4182d8808..8fccba73e 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -197,7 +197,7 @@ class NoticeListItem extends Widget $this->out->elementStart('div', 'entry-content'); $this->showNoticeLink(); $this->showNoticeSource(); - $this->showReplyTo(); + $this->showContext(); $this->out->elementEnd('div'); } @@ -421,17 +421,18 @@ class NoticeListItem extends Widget * @return void */ - function showReplyTo() + function showContext() { - if ($this->notice->reply_to) { - $replyurl = common_local_url('shownotice', - array('notice' => $this->notice->reply_to)); + // XXX: also show context if there are replies to this notice + if (!empty($this->notice->conversation) + && $this->notice->conversation != $this->notice->id) { + $convurl = common_local_url('conversation', + array('id' => $this->notice->conversation)); $this->out->elementStart('dl', 'response'); $this->out->element('dt', null, _('To')); $this->out->elementStart('dd'); - $this->out->element('a', array('href' => $replyurl, - 'rel' => 'in-reply-to'), - _('in reply to')); + $this->out->element('a', array('href' => $convurl), + _('in context')); $this->out->elementEnd('dd'); $this->out->elementEnd('dl'); } diff --git a/lib/queuehandler.php b/lib/queuehandler.php index 9ce9e32b3..f76f16e07 100644 --- a/lib/queuehandler.php +++ b/lib/queuehandler.php @@ -36,7 +36,7 @@ class QueueHandler extends Daemon $this->set_id($id); } } - + function class_name() { return ucfirst($this->transport()) . 'Handler'; @@ -46,7 +46,7 @@ class QueueHandler extends Daemon { return strtolower($this->class_name().'.'.$this->get_id()); } - + function get_id() { return $this->_id; @@ -56,16 +56,16 @@ class QueueHandler extends Daemon { $this->_id = $id; } - + function transport() { return null; } - + function start() { } - + function finish() { } @@ -74,16 +74,10 @@ class QueueHandler extends Daemon { return true; } - - function run() - { - if (!$this->start()) { - return false; - } - $this->log(LOG_INFO, 'checking for queued notices'); - $transport = $this->transport(); + + function db_dispatch() { do { - $qi = Queue_item::top($transport); + $qi = Queue_item::top($this->transport()); if ($qi) { $this->log(LOG_INFO, 'Got item enqueued '.common_exact_date($qi->created)); $notice = Notice::staticGet($qi->notice_id); @@ -113,8 +107,69 @@ class QueueHandler extends Daemon } else { $this->clear_old_claims(); $this->idle(5); - } + } } while (true); + } + + function stomp_dispatch() { + require("Stomp.php"); + $con = new Stomp(common_config('queue','stomp_server')); + if (!$con->connect()) { + $this->log(LOG_ERR, 'Failed to connect to queue server'); + return false; + } + $queue_basename = common_config('queue','queue_basename'); + // subscribe to the relevant queue (format: basename-transport) + $con->subscribe('/queue/'.$queue_basename.'-'.$this->transport()); + + do { + $frame = $con->readFrame(); + if ($frame) { + $this->log(LOG_INFO, 'Got item enqueued '.common_exact_date($frame->headers['created'])); + + // XXX: Now the queue handler receives only the ID of the + // notice, and it has to get it from the DB + // A massive improvement would be avoid DB query by transmitting + // all the notice details via queue server... + $notice = Notice::staticGet($frame->body); + + if ($notice) { + $this->log(LOG_INFO, 'broadcasting notice ID = ' . $notice->id); + $result = $this->handle_notice($notice); + if ($result) { + // if the msg has been handled positively, ack it + // and the queue server will remove it from the queue + $con->ack($frame); + $this->log(LOG_INFO, 'finished broadcasting notice ID = ' . $notice->id); + } + else { + // no ack + $this->log(LOG_WARNING, 'Failed broadcast for notice ID = ' . $notice->id); + } + $notice->free(); + unset($notice); + $notice = null; + } else { + $this->log(LOG_WARNING, 'queue item for notice that does not exist'); + } + } + } while (true); + + $con->disconnect(); + } + + function run() + { + if (!$this->start()) { + return false; + } + $this->log(LOG_INFO, 'checking for queued notices'); + if (common_config('queue','subsystem') == 'stomp') { + $this->stomp_dispatch(); + } + else { + $this->db_dispatch(); + } if (!$this->finish()) { return false; } @@ -127,7 +182,7 @@ class QueueHandler extends Daemon sleep($timeout); } } - + function clear_old_claims() { $qi = new Queue_item(); @@ -137,10 +192,10 @@ class QueueHandler extends Daemon $qi->free(); unset($qi); } - + function log($level, $msg) { common_log($level, $this->class_name() . ' ('. $this->get_id() .'): '.$msg); } } -
\ No newline at end of file + diff --git a/lib/router.php b/lib/router.php index 6fb2f9487..5e16f3419 100644 --- a/lib/router.php +++ b/lib/router.php @@ -131,7 +131,7 @@ class Router // settings foreach (array('profile', 'avatar', 'password', 'openid', 'im', - 'email', 'sms', 'twitter', 'other') as $s) { + 'email', 'sms', 'twitter', 'design', 'other') as $s) { $m->connect('settings/'.$s, array('action' => $s.'settings')); } @@ -165,6 +165,12 @@ class Router array('action' => 'deletenotice'), array('notice' => '[0-9]+')); + // conversation + + $m->connect('conversation/:id', + array('action' => 'conversation'), + array('id' => '[0-9]+')); + $m->connect('message/new', array('action' => 'newmessage')); $m->connect('message/new?to=:to', array('action' => 'newmessage'), array('to' => '[A-Za-z0-9_-]+')); $m->connect('message/:message', diff --git a/lib/theme.php b/lib/theme.php index 95030affe..bef660cbf 100644 --- a/lib/theme.php +++ b/lib/theme.php @@ -69,4 +69,31 @@ function theme_path($relative, $theme=null) } else { return common_path('theme/'.$theme.'/'.$relative); } -}
\ No newline at end of file +} + +/** + * Gets the full URL of a file in a skin dir based on its relative name + * + * @param string $relative relative path within the theme, skin directory + * @param string $theme name of the theme; defaults to current theme + * @param string $skin name of the skin; defaults to current theme + * + * @return string URL of the file + */ + +function skin_path($relative, $theme=null, $skin=null) +{ + if (!$theme) { + $theme = common_config('site', 'theme'); + } + if (!$skin) { + $skin = common_config('site', 'skin'); + } + $server = common_config('theme', 'server'); + if ($server) { + return 'http://'.$server.'/'.$theme.'/skin/'.$skin.'/'.$relative; + } else { + return common_path('theme/'.$theme.'/skin/'.$skin.'/'.$relative); + } +} + diff --git a/lib/twitter.php b/lib/twitter.php index ccc6c93ca..c1d0dc254 100644 --- a/lib/twitter.php +++ b/lib/twitter.php @@ -346,7 +346,7 @@ function save_twitter_friends($user, $twitter_id, $screen_name, $password) function is_twitter_bound($notice, $flink) { // Check to see if notice should go to Twitter - if ($flink->noticesync & FOREIGN_NOTICE_SEND) { + if (!empty($flink) && ($flink->noticesync & FOREIGN_NOTICE_SEND)) { // If it's not a Twitter-style reply, or if the user WANTS to send replies. if (!preg_match('/^@[a-zA-Z0-9_]{1,15}\b/u', $notice->content) || diff --git a/lib/util.php b/lib/util.php index 675ff51f0..888765548 100644 --- a/lib/util.php +++ b/lib/util.php @@ -874,18 +874,76 @@ function common_broadcast_notice($notice, $remote=false) function common_enqueue_notice($notice) { - foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $transport) { - $qi = new Queue_item(); - $qi->notice_id = $notice->id; - $qi->transport = $transport; - $qi->created = $notice->created; - $result = $qi->insert(); - if (!$result) { - $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); - common_log(LOG_ERR, 'DB error inserting queue item: ' . $last_error->message); - return false; + if (common_config('queue','subsystem') == 'stomp') { + // use an external message queue system via STOMP + require_once("Stomp.php"); + $con = new Stomp(common_config('queue','stomp_server')); + if (!$con->connect()) { + common_log(LOG_ERR, 'Failed to connect to queue server'); + return false; + } + $queue_basename = common_config('queue','queue_basename'); + foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $transport) { + if (!$con->send( + '/queue/'.$queue_basename.'-'.$transport, // QUEUE + $notice->id, // BODY of the message + array ( // HEADERS of the msg + 'created' => $notice->created + ))) { + common_log(LOG_ERR, 'Error sending to '.$transport.' queue'); + return false; + } + common_log(LOG_DEBUG, 'complete remote queueing notice ID = ' . $notice->id . ' for ' . $transport); + } + + //send tags as headers, so they can be used as JMS selectors + common_log(LOG_DEBUG, 'searching for tags ' . $notice->id); + $tags = array(); + $tag = new Notice_tag(); + $tag->notice_id = $notice->id; + if ($tag->find()) { + while ($tag->fetch()) { + common_log(LOG_DEBUG, 'tag found = ' . $tag->tag); + array_push($tags,$tag->tag); + } + } + $tag->free(); + + $con->send('/topic/laconica.'.$notice->profile_id, + $notice->content, + array( + 'profile_id' => $notice->profile_id, + 'created' => $notice->created, + 'tags' => implode($tags,' - ') + ) + ); + common_log(LOG_DEBUG, 'sent to personal topic ' . $notice->id); + $con->send('/topic/laconica.allusers', + $notice->content, + array( + 'profile_id' => $notice->profile_id, + 'created' => $notice->created, + 'tags' => implode($tags,' - ') + ) + ); + common_log(LOG_DEBUG, 'sent to catch-all topic ' . $notice->id); + $result = true; + } + else { + // in any other case, 'internal' + foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $transport) { + $qi = new Queue_item(); + $qi->notice_id = $notice->id; + $qi->transport = $transport; + $qi->created = $notice->created; + $result = $qi->insert(); + if (!$result) { + $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); + common_log(LOG_ERR, 'DB error inserting queue item: ' . $last_error->message); + return false; + } + common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport); } - common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport); } return $result; } @@ -1094,7 +1152,7 @@ function common_accept_to_prefs($accept, $def = '*/*') foreach($parts as $part) { // FIXME: doesn't deal with params like 'text/html; level=1' - @list($value, $qpart) = explode(';', $part); + @list($value, $qpart) = explode(';', trim($part)); $match = array(); if(!isset($qpart)) { $prefs[$value] = 1; @@ -1333,4 +1391,4 @@ function common_database_tablename($tablename) } //table prefixes could be added here later return $tablename; -}
\ No newline at end of file +} |