From ce76d61957b22a70214d953f9580db61d09c5a66 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 05:07:14 -0700 Subject: [PATCH 01/32] marker in sessions --- lib/util.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/util.php b/lib/util.php index f6d50b1807..e5a8eaea06 100644 --- a/lib/util.php +++ b/lib/util.php @@ -139,8 +139,19 @@ function common_have_session() function common_ensure_session() { + $c = null; + if (array_key_exists(session_name, $_COOKIE)) { + $c = $_COOKIE[session_name()]; + } if (!common_have_session()) { @session_start(); + if (!isset($_SESSION['started'])) { + $_SESSION['started'] = time(); + if (!empty($c)) { + common_log(LOG_WARNING, 'Session cookie "' . $_COOKIE[session_name()] . '" ' . + ' is set but started value is null'); + } + } } } From 48d671ac39de0ebfd36858d784d3066ecbb89c10 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 05:15:59 -0700 Subject: [PATCH 02/32] session storage --- classes/Session.php | 42 ++++++++++++++++++++++++++++++++++++++++++ classes/laconica.ini | 9 +++++++++ db/laconica.sql | 11 +++++++++++ 3 files changed, 62 insertions(+) create mode 100755 classes/Session.php diff --git a/classes/Session.php b/classes/Session.php new file mode 100755 index 0000000000..9b48dabac7 --- /dev/null +++ b/classes/Session.php @@ -0,0 +1,42 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class Session extends Memcached_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'session'; // table name + public $id; // varchar(32) primary_key not_null + public $session_data; // text() + public $created; // datetime() not_null + public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP + + /* Static get */ + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Session',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE +} diff --git a/classes/laconica.ini b/classes/laconica.ini index 7e9b2b791d..766bed75de 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -380,6 +380,15 @@ replied_id = 1 notice_id = K profile_id = K +[session] +id = 130 +session_data = 34 +created = 142 +modified = 384 + +[session__keys] +id = K + [sms_carrier] id = 129 name = 2 diff --git a/db/laconica.sql b/db/laconica.sql index 3f8918de62..2c04f680a8 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -524,3 +524,14 @@ create table group_alias ( index group_alias_group_id_idx (group_id) ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; + +create table session ( + + id varchar(32) primary key comment 'session ID', + session_data text comment 'session data', + created datetime not null comment 'date this record was created', + modified timestamp comment 'date this record was modified', + + index session_modified_idx (modified) + +) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; \ No newline at end of file From 0ca22cf6e2bd80247520f7c1f83535f8de5fed0a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 05:48:22 -0700 Subject: [PATCH 03/32] a memcached_dataobject class for saving sessions --- classes/Session.php | 67 +++++++++++++++++++++++++++++++++++++++++++++ lib/util.php | 7 ++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/classes/Session.php b/classes/Session.php index 9b48dabac7..6f13c7d273 100755 --- a/classes/Session.php +++ b/classes/Session.php @@ -39,4 +39,71 @@ class Session extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + + static function open($save_path, $session_name) + { + return true; + } + + static function close() + { + return true; + } + + static function read($id) + { + $session = Session::staticGet('id', $id); + + if (empty($session)) { + return ''; + } else { + return (string)$session->session_data; + } + } + + static function write($id, $session_data) + { + $session = Session::staticGet('id', $id); + + if (empty($session)) { + $session = new Session(); + + $session->id = $id; + $session->session_data = $session_data; + $session->created = common_sql_now(); + + return $session->insert(); + } else { + $session->session_data = $session_data; + + return $session->update(); + } + } + + static function destroy($id) + { + $session = Session::staticGet('id', $id); + + if (!empty($session)) { + return $session->delete(); + } + } + + static function gc($maxlifetime) + { + $epoch = time() - $maxlifetime; + + $qry = 'DELETE FROM session ' . + 'WHERE modified < "'.$epoch.'"'; + + $session = new Session(); + + $session->query($qry); + } + + static function setSaveHandler() + { + session_set_save_handler('Session::open', 'Session::close', 'Session::read', + 'Session::write', 'Session::destroy', 'Session::gc'); + } } diff --git a/lib/util.php b/lib/util.php index e5a8eaea06..b3496a09e8 100644 --- a/lib/util.php +++ b/lib/util.php @@ -828,7 +828,12 @@ function common_date_iso8601($dt) function common_sql_now() { - return strftime('%Y-%m-%d %H:%M:%S', time()); + return common_sql_date(time()); +} + +function common_sql_date($datetime) +{ + return strftime('%Y-%m-%d %H:%M:%S', $datetime); } function common_redirect($url, $code=307) From 71dad1ff62b842578656f34a1aa33f00399309e2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 06:20:24 -0700 Subject: [PATCH 04/32] use the session class to store sessions --- README | 10 ++++++++++ index.php | 46 +++++++++++++++++++++++++++++++++------------- lib/common.php | 2 ++ lib/util.php | 3 +++ 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/README b/README index 1a57d6a80e..7f8748b3fd 100644 --- a/README +++ b/README @@ -1278,6 +1278,16 @@ type: type of search. Ignored if PostgreSQL or Sphinx are enabled. Can either systems. We'll probably add another type sometime in the future, with our own indexing system (maybe like MediaWiki's). +sessions +-------- + +Session handling. + +handle: boolean. Whether we should register our own PHP session-handling + code (using the database and memcache if enabled). Defaults to false. + Setting this to true makes some sense on large or multi-server + sites, but it probably won't hurt for smaller ones, either. + Troubleshooting =============== diff --git a/index.php b/index.php index cb6a0fe603..f9b57e9d71 100644 --- a/index.php +++ b/index.php @@ -73,6 +73,38 @@ function handleError($error) exit(-1); } +function checkMirror($action_obj) +{ + global $config; + + static $alwaysRW = array('session', 'remember_me'); + + if (common_config('db', 'mirror') && $action_obj->isReadOnly($args)) { + if (is_array(common_config('db', 'mirror'))) { + // "load balancing", ha ha + $arr = common_config('db', 'mirror'); + $k = array_rand($arr); + $mirror = $arr[$k]; + } else { + $mirror = common_config('db', 'mirror'); + } + + // We ensure that these tables always are used + // on the master DB + + $config['db']['database_rw'] = $config['db']['database']; + $config['db']['ini_rw'] = INSTALLDIR.'/classes/laconica.ini'; + + foreach ($alwaysRW as $table) { + $config['db']['table_'.$table] = 'rw'; + } + + // everyone else uses the mirror + + $config['db']['database'] = $mirror; + } +} + function main() { // quick check for fancy URL auto-detection support in installer. @@ -146,19 +178,7 @@ function main() } else { $action_obj = new $action_class(); - // XXX: find somewhere for this little block to live - - if (common_config('db', 'mirror') && $action_obj->isReadOnly($args)) { - if (is_array(common_config('db', 'mirror'))) { - // "load balancing", ha ha - $arr = common_config('db', 'mirror'); - $k = array_rand($arr); - $mirror = $arr[$k]; - } else { - $mirror = common_config('db', 'mirror'); - } - $config['db']['database'] = $mirror; - } + checkMirror($action_obj); try { if ($action_obj->prepare($args)) { diff --git a/lib/common.php b/lib/common.php index bb1a4255da..3a5913f85c 100644 --- a/lib/common.php +++ b/lib/common.php @@ -254,6 +254,8 @@ $config = 'oohembed' => array('endpoint' => 'http://oohembed.com/oohembed/'), 'search' => array('type' => 'fulltext'), + 'sessions' => + array('handle' => false), // whether to handle sessions ourselves ); $config['db'] = &PEAR::getStaticProperty('DB_DataObject','options'); diff --git a/lib/util.php b/lib/util.php index b3496a09e8..2face67770 100644 --- a/lib/util.php +++ b/lib/util.php @@ -144,6 +144,9 @@ function common_ensure_session() $c = $_COOKIE[session_name()]; } if (!common_have_session()) { + if (common_config('sessions', 'handle')) { + Session::setSaveHandler(); + } @session_start(); if (!isset($_SESSION['started'])) { $_SESSION['started'] = time(); From 5a600a02d134861933ab8d8b49245eb8b77982ec Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 06:24:06 -0700 Subject: [PATCH 05/32] fixup perms on auto-generated files --- classes/Session.php | 0 classes/laconica.ini | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 classes/Session.php mode change 100755 => 100644 classes/laconica.ini diff --git a/classes/Session.php b/classes/Session.php old mode 100755 new mode 100644 diff --git a/classes/laconica.ini b/classes/laconica.ini old mode 100755 new mode 100644 From addfcc976a202959209a9a1e806379e3732204bb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 07:02:36 -0700 Subject: [PATCH 06/32] remove debugging code from Notice.php --- classes/Notice.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index d0ee1d9250..502cc57b81 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -874,7 +874,6 @@ class Notice extends Memcached_DataObject $qry .= '('.$id.', '.$this->id.', '.$source.', "'.$this->created.'") '; $cnt++; if ($cnt >= MAX_BOXCARS) { - common_debug($qry); $inbox = new Notice_inbox(); $inbox->query($qry); $qry = $qryhdr; @@ -883,7 +882,6 @@ class Notice extends Memcached_DataObject } if ($cnt > 0) { - common_debug($qry); $inbox = new Notice_inbox(); $inbox->query($qry); } From 7af94dc12562b8114f0f823dc8438234125022da Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 07:09:21 -0700 Subject: [PATCH 07/32] some debugging code for sessions --- classes/Session.php | 24 +++++++++++++++++++++--- lib/util.php | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/classes/Session.php b/classes/Session.php index 6f13c7d273..5c48e4aa90 100644 --- a/classes/Session.php +++ b/classes/Session.php @@ -40,6 +40,11 @@ class Session extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + static function logdeb($msg) + { + common_debug("Session: " . $msg); + } + static function open($save_path, $session_name) { return true; @@ -52,6 +57,8 @@ class Session extends Memcached_DataObject static function read($id) { + self::logdeb("Fetching session '$id'"); + $session = Session::staticGet('id', $id); if (empty($session)) { @@ -63,6 +70,8 @@ class Session extends Memcached_DataObject static function write($id, $session_data) { + self::logdeb("Writing session '$id'"); + $session = Session::staticGet('id', $id); if (empty($session)) { @@ -82,6 +91,8 @@ class Session extends Memcached_DataObject static function destroy($id) { + self::logdeb("Deleting session $id"); + $session = Session::staticGet('id', $id); if (!empty($session)) { @@ -91,6 +102,8 @@ class Session extends Memcached_DataObject static function gc($maxlifetime) { + self::logdeb("garbage collection (maxlifetime = $maxlifetime)"); + $epoch = time() - $maxlifetime; $qry = 'DELETE FROM session ' . @@ -98,12 +111,17 @@ class Session extends Memcached_DataObject $session = new Session(); - $session->query($qry); + $result = $session->query($qry); + + self::logdeb("garbage collection result = $result"); } static function setSaveHandler() { - session_set_save_handler('Session::open', 'Session::close', 'Session::read', - 'Session::write', 'Session::destroy', 'Session::gc'); + self::logdeb("setting save handlers"); + $result = session_set_save_handler('Session::open', 'Session::close', 'Session::read', + 'Session::write', 'Session::destroy', 'Session::gc'); + self::logdeb("save handlers result = $result"); + return $result; } } diff --git a/lib/util.php b/lib/util.php index 2face67770..c8da8c7dd1 100644 --- a/lib/util.php +++ b/lib/util.php @@ -145,6 +145,7 @@ function common_ensure_session() } if (!common_have_session()) { if (common_config('sessions', 'handle')) { + common_log(LOG_INFO, "Using our own session handler"); Session::setSaveHandler(); } @session_start(); From 70521d55a811347fa30f37187e43b8a1fd932e21 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 07:37:58 -0700 Subject: [PATCH 08/32] log IP for API auth errors --- actions/api.php | 4 +++- lib/util.php | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/actions/api.php b/actions/api.php index 1fe5875ad6..08f5fadad9 100644 --- a/actions/api.php +++ b/actions/api.php @@ -67,7 +67,9 @@ class ApiAction extends Action $this->process_command(); } else { # basic authentication failed - common_log(LOG_WARNING, "Failed API auth attempt, nickname: $nickname."); + list($proxy, $ip) = common_client_ip(); + + common_log(LOG_WARNING, "Failed API auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip."); $this->show_basic_auth_error(); } } diff --git a/lib/util.php b/lib/util.php index c8da8c7dd1..9c1af7a0dc 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1490,4 +1490,28 @@ function common_shorten_url($long_url) curl_close($curlh); return $short_url; -} \ No newline at end of file +} + +function common_client_ip() +{ + if (!isset($_SERVER) || !array_key_exists('REQUEST_METHOD', $_SERVER)) { + return null; + } + + if ($_SERVER['HTTP_X_FORWARDED_FOR']) { + if ($_SERVER['HTTP_CLIENT_IP']) { + $proxy = $_SERVER['HTTP_CLIENT_IP']; + } else { + $proxy = $_SERVER['REMOTE_ADDR']; + } + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } else { + if ($_SERVER['HTTP_CLIENT_IP']) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + } else { + $ip = $_SERVER['REMOTE_ADDR']; + } + } + + return array($ip, $proxy); +} From fb84c35035e33eebea79f207f73ba2deea86c4d7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 07:43:58 -0700 Subject: [PATCH 09/32] don't need config in main anymore --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index f9b57e9d71..5f9a048f2c 100644 --- a/index.php +++ b/index.php @@ -111,7 +111,7 @@ function main() if (isset($_SERVER['REDIRECT_URL']) && ((dirname($_SERVER['REQUEST_URI']) . '/check-fancy') === $_SERVER['REDIRECT_URL'])) { die("Fancy URL support detection succeeded. We suggest you enable this to get fancy (pretty) URLs."); } - global $user, $action, $config; + global $user, $action; Snapshot::check(); From 871f598dcc81d7018f25590d767591722bb977f2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 27 Jun 2009 08:11:09 -0700 Subject: [PATCH 10/32] debug flag for sessions --- README | 2 ++ classes/Session.php | 4 +++- lib/common.php | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README b/README index 7f8748b3fd..c8c529ed86 100644 --- a/README +++ b/README @@ -1287,6 +1287,8 @@ handle: boolean. Whether we should register our own PHP session-handling code (using the database and memcache if enabled). Defaults to false. Setting this to true makes some sense on large or multi-server sites, but it probably won't hurt for smaller ones, either. +debug: whether to output debugging info for session storage. Can help + with weird session bugs, sometimes. Default false. Troubleshooting =============== diff --git a/classes/Session.php b/classes/Session.php index 5c48e4aa90..93fd99baa8 100644 --- a/classes/Session.php +++ b/classes/Session.php @@ -42,7 +42,9 @@ class Session extends Memcached_DataObject static function logdeb($msg) { - common_debug("Session: " . $msg); + if (common_config('sessions', 'debug')) { + common_debug("Session: " . $msg); + } } static function open($save_path, $session_name) diff --git a/lib/common.php b/lib/common.php index 3a5913f85c..e2936f0751 100644 --- a/lib/common.php +++ b/lib/common.php @@ -255,7 +255,8 @@ $config = 'search' => array('type' => 'fulltext'), 'sessions' => - array('handle' => false), // whether to handle sessions ourselves + array('handle' => false, // whether to handle sessions ourselves + 'debug' => false), // debugging output for sessions ); $config['db'] = &PEAR::getStaticProperty('DB_DataObject','options'); From d4f1637f8a20d9e4ac059930b7ba444473f5047b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 14:45:33 -0400 Subject: [PATCH 11/32] fallback for www. addresses --- classes/Status_network.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/classes/Status_network.php b/classes/Status_network.php index f8d6756b69..8726096e3c 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -132,6 +132,13 @@ class Status_network extends DB_DataObject } } else { $sn = self::memGet('hostname', strtolower($servername)); + + if (empty($sn)) { + // Try for a no-www address + if (strncasecmp($servername, 'www.', 4)) { + $sn = self::memGet('hostname', strtolower(substr($servername, 4))); + } + } } if (!empty($sn)) { From 166e4a4b58a02438825706e52d1aa3207c33505b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 14:48:19 -0400 Subject: [PATCH 12/32] bad string compare in Status_network --- classes/Status_network.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Status_network.php b/classes/Status_network.php index 8726096e3c..dbd722e88e 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -135,7 +135,7 @@ class Status_network extends DB_DataObject if (empty($sn)) { // Try for a no-www address - if (strncasecmp($servername, 'www.', 4)) { + if (0 == strncasecmp($servername, 'www.', 4)) { $sn = self::memGet('hostname', strtolower(substr($servername, 4))); } } From 495c85544a740cd0330e73d9c48ca4b84f3d8e97 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 15:21:15 -0400 Subject: [PATCH 13/32] don't canonicalize people's text into URLs --- lib/util.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/util.php b/lib/util.php index 9c1af7a0dc..469f132b8e 100644 --- a/lib/util.php +++ b/lib/util.php @@ -500,17 +500,19 @@ function common_linkify($url) { // It comes in special'd, so we unspecial it before passing to the stringifying // functions $url = htmlspecialchars_decode($url); - $display = File_redirection::_canonUrl($url); + + $canon = File_redirection::_canonUrl($url); + $longurl_data = File_redirection::where($url); if (is_array($longurl_data)) { $longurl = $longurl_data['url']; } elseif (is_string($longurl_data)) { $longurl = $longurl_data; } else { - die('impossible to linkify'); + throw new ServerException("Can't linkify url '$url'"); } - $attrs = array('href' => $longurl, 'rel' => 'external'); + $attrs = array('href' => $canon, 'rel' => 'external'); $is_attachment = false; $attachment_id = null; @@ -528,13 +530,13 @@ function common_linkify($url) { } } -// if this URL is an attachment, then we set class='attachment' and id='attahcment-ID' -// where ID is the id of the attachment for the given URL. -// -// we need a better test telling what can be shown as an attachment -// we're currently picking up oembeds only. -// I think the best option is another file_view table in the db -// and associated dbobject. + // if this URL is an attachment, then we set class='attachment' and id='attahcment-ID' + // where ID is the id of the attachment for the given URL. + // + // we need a better test telling what can be shown as an attachment + // we're currently picking up oembeds only. + // I think the best option is another file_view table in the db + // and associated dbobject. $query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'"; $file = new File; @@ -564,7 +566,7 @@ function common_linkify($url) { $attrs['id'] = "attachment-{$attachment_id}"; } - return XMLStringer::estring('a', $attrs, $display); + return XMLStringer::estring('a', $attrs, $url); } function common_shorten_links($text) From 6ca4dfa7ef42faf024599375b2ff81bfeb3d6208 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:12:23 -0400 Subject: [PATCH 14/32] Daemon can optionally not go into the background --- lib/daemon.php | 20 +++++++++++++++----- lib/queuehandler.php | 5 +++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/daemon.php b/lib/daemon.php index a0df00bdcc..72e8bc2028 100644 --- a/lib/daemon.php +++ b/lib/daemon.php @@ -23,6 +23,13 @@ if (!defined('LACONICA')) { class Daemon { + var $daemonize = true; + + function __construct($daemonize = true) + { + $this->daemonize = $daemonize; + } + function name() { return null; @@ -129,12 +136,15 @@ class Daemon common_log(LOG_INFO, $this->name() . ' already running. Exiting.'); exit(0); } - if ($this->background()) { - $this->writePidFile(); - $this->changeUser(); - $this->run(); - $this->clearPidFile(); + + if ($this->daemonize) { + $this->background(); } + + $this->writePidFile(); + $this->changeUser(); + $this->run(); + $this->clearPidFile(); } function run() diff --git a/lib/queuehandler.php b/lib/queuehandler.php index ae403c65e2..c1c4f3309a 100644 --- a/lib/queuehandler.php +++ b/lib/queuehandler.php @@ -27,11 +27,12 @@ require_once(INSTALLDIR.'/classes/Notice.php'); class QueueHandler extends Daemon { - var $_id = 'generic'; - function QueueHandler($id=null) + function __construct($id=null, $daemonize=true) { + parent::__construct($daemonize); + if ($id) { $this->set_id($id); } From 2f8c656e1df10984527fe445bd57783f5fdcafdc Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:12:45 -0400 Subject: [PATCH 15/32] command line arg handling a little more flexible --- scripts/commandline.inc | 44 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/scripts/commandline.inc b/scripts/commandline.inc index 4a7757fb98..8c5c56d5ea 100644 --- a/scripts/commandline.inc +++ b/scripts/commandline.inc @@ -115,24 +115,60 @@ require_once INSTALLDIR . '/lib/common.php'; set_error_handler('common_error_handler'); -function have_option($str) +function have_option($opt, $alt=null) { global $options; + + $matches = array($opt); + + if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { + $matches[] = '--'.$opt; + } else { + $matches[] = $opt; + } + + if (!empty($alt)) { + if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { + $matches[] = '--'.$alt; + } else { + $matches[] = $alt; + } + } + foreach ($options as $option) { - if ($option[0] == $str) { + if (in_array($option[0], $matches)) { return true; } } + return false; } -function get_option_value($str) +function get_option_value($str, $alt=null) { global $options; + + $matches = array(); + + if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { + $matches[] = '--'.$opt; + } else { + $matches[] = $opt; + } + + if (!empty($alt)) { + if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { + $matches[] = '--'.$alt; + } else { + $matches[] = $alt; + } + } + foreach ($options as $option) { - if ($option[0] == $str) { + if (in_array($option[0], $matches)) { return $option[1]; } } + return null; } \ No newline at end of file From 47e1d2adb87ae8ffa4c954d3ba62da64e986696c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:13:08 -0400 Subject: [PATCH 16/32] xmppdaemon.php can stay in foreground --- scripts/xmppdaemon.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 3eecfec29a..38d739e680 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -20,13 +20,14 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = 'i::'; -$longoptions = array('id::'); +$shortoptions = 'fi::'; +$longoptions = array('id::', 'foreground'); $helptext = <<host) ? $this->host : $this->server; $this->log(LOG_INFO, "Connecting to $connect_to on port $this->port"); @@ -323,16 +325,16 @@ if (common_config('xmpp','enabled')==false) { exit(); } -if (have_option('i')) { - $id = get_option_value('i'); -} else if (have_option('--id')) { - $id = get_option_value('--id'); +if (have_option('i', 'id')) { + $id = get_option_value('i', 'id'); } else if (count($args) > 0) { $id = $args[0]; } else { $id = null; } -$daemon = new XMPPDaemon($id); +$foreground = have_option('f', 'foreground'); + +$daemon = new XMPPDaemon($id, $foreground); $daemon->runOnce(); From c755970141810a98e08f47c52568f635167e34f1 Mon Sep 17 00:00:00 2001 From: Super-User Date: Sun, 28 Jun 2009 20:15:17 +0000 Subject: [PATCH 17/32] commandline processing handles errors better --- scripts/commandline.inc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/commandline.inc b/scripts/commandline.inc index 4a7757fb98..53b9a490bc 100644 --- a/scripts/commandline.inc +++ b/scripts/commandline.inc @@ -63,7 +63,14 @@ if (isset($longoptions)) { $parser = new Console_Getopt(); -list($options, $args) = $parser->getopt($argv, $shortoptions, $longoptions); +$result = $parser->getopt($argv, $shortoptions, $longoptions); + +if (PEAR::isError($result)) { + print $result->getMessage()."\n"; + exit(1); +} else { + list($options, $args) = $result; +} function show_help() { From b06edd1f27948aa3e34bbb0a22172fc8d87b4fe6 Mon Sep 17 00:00:00 2001 From: Super-User Date: Sun, 28 Jun 2009 20:15:45 +0000 Subject: [PATCH 18/32] more efficient fixup of conversations --- scripts/fixup_conversations.php | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/scripts/fixup_conversations.php b/scripts/fixup_conversations.php index 2cfa422e65..0be0b4bac5 100755 --- a/scripts/fixup_conversations.php +++ b/scripts/fixup_conversations.php @@ -24,22 +24,17 @@ require_once INSTALLDIR.'/scripts/commandline.inc'; common_log(LOG_INFO, 'Fixing up conversations.'); -$notice = new Notice(); -$notice->whereAdd('conversation is null'); -$notice->orderBy('id'); +$nid = new Notice(); +$nid->query('select id, reply_to from notice where conversation is null'); -$cnt = $notice->find(); +while ($nid->fetch()) { -print "Found $cnt notices.\n"; - -while ($notice->fetch()) { - - print "$notice->id =>"; - - $orig = clone($notice); - - if (empty($notice->reply_to)) { - $notice->conversation = $notice->id; + $cid = null; + + $notice = new Notice(); + + if (empty($nid->reply_to)) { + $cid = $nid->id; } else { $reply = Notice::staticGet('id', $notice->reply_to); @@ -52,6 +47,9 @@ while ($notice->fetch()) { } else { $notice->conversation = $reply->conversation; } + + unset($reply); + $reply = null; } print "$notice->conversation"; @@ -63,5 +61,10 @@ while ($notice->fetch()) { continue; } + $notice = null; + $orig = null; + unset($notice); + unset($orig); + print ".\n"; } From a4d0f22b4b2907134779d7710f967c4841f6f938 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 20:16:44 +0000 Subject: [PATCH 19/32] twitter status fetcher takes an id argument --- scripts/twitterstatusfetcher.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/twitterstatusfetcher.php b/scripts/twitterstatusfetcher.php index 5ffdda58fa..8b10bfbadd 100755 --- a/scripts/twitterstatusfetcher.php +++ b/scripts/twitterstatusfetcher.php @@ -25,9 +25,14 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); define('MAXCHILDREN', 2); define('POLL_INTERVAL', 60); // in seconds +$shortoptions = 'i::'; +$longoptions = array('id::'); + $helptext = <<_id); } /** @@ -625,6 +630,16 @@ class TwitterStatusFetcher extends Daemon declare(ticks = 1); -$fetcher = new TwitterStatusFetcher(); +if (have_option('i')) { + $id = get_option_value('i'); +} else if (have_option('--id')) { + $id = get_option_value('--id'); +} else if (count($args) > 0) { + $id = $args[0]; +} else { + $id = null; +} + +$fetcher = new TwitterStatusFetcher($id); $fetcher->runOnce(); From cfd25489235b176c33cc4104aadfe5378fffe67d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:33:08 -0400 Subject: [PATCH 20/32] got my background/foreground logic backwards --- scripts/xmppdaemon.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 38d739e680..608cc1a36c 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -335,6 +335,6 @@ if (have_option('i', 'id')) { $foreground = have_option('f', 'foreground'); -$daemon = new XMPPDaemon($id, $foreground); +$daemon = new XMPPDaemon($id, !$foreground); $daemon->runOnce(); From 9f079764aa945e9e126ffa41cece17bc8951fb78 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:38:27 -0400 Subject: [PATCH 21/32] extract log-line formatting to its own function --- lib/util.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/util.php b/lib/util.php index 469f132b8e..1ae43a0563 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1104,15 +1104,20 @@ function common_ensure_syslog() } } +function common_log_line($priority, $msg) +{ + static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR', + 'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG'); + return date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n"; +} + function common_log($priority, $msg, $filename=null) { $logfile = common_config('site', 'logfile'); if ($logfile) { $log = fopen($logfile, "a"); if ($log) { - static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR', - 'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG'); - $output = date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n"; + $output = common_log_line($priority, $msg); fwrite($log, $output); fclose($log); } From 25c721f6ffc5ecf5825b60ab7b9c021d78b50888 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:38:59 -0400 Subject: [PATCH 22/32] if not in daemon mode, xmppdaemon sends log to stdout --- scripts/xmppdaemon.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 608cc1a36c..3e46c8e260 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -309,7 +309,14 @@ class XMPPDaemon extends Daemon function log($level, $msg) { - common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg); + $text = 'XMPPDaemon('.$this->resource.'): '.$msg; + common_log($level, $text); + if (!$this->daemonize) + { + $line = common_log_line($level, $text); + echo $line; + echo "\n"; + } } function subscribed($to) From 7a0d33ab5fa29993cc7e05e41a26a26ca3ffd1e8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 16:55:19 -0400 Subject: [PATCH 23/32] reformat commandline.inc --- scripts/commandline.inc | 100 ++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/scripts/commandline.inc b/scripts/commandline.inc index 9c6787cb7a..bca09216d5 100644 --- a/scripts/commandline.inc +++ b/scripts/commandline.inc @@ -66,10 +66,10 @@ $parser = new Console_Getopt(); $result = $parser->getopt($argv, $shortoptions, $longoptions); if (PEAR::isError($result)) { - print $result->getMessage()."\n"; - exit(1); + print $result->getMessage()."\n"; + exit(1); } else { - list($options, $args) = $result; + list($options, $args) = $result; } function show_help() @@ -77,7 +77,7 @@ function show_help() global $helptext; $_default_help_text = << 1 && 0 != strncmp($opt, '--', 2)) { - $matches[] = '--'.$opt; - } else { - $matches[] = $opt; - } + if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { + $matches[] = '--'.$opt; + } else { + $matches[] = $opt; + } - if (!empty($alt)) { - if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { - $matches[] = '--'.$alt; - } else { - $matches[] = $alt; - } - } + if (!empty($alt)) { + if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { + $matches[] = '--'.$alt; + } else { + $matches[] = $alt; + } + } - foreach ($options as $option) { - if (in_array($option[0], $matches)) { - return true; - } - } + foreach ($options as $option) { + if (in_array($option[0], $matches)) { + return true; + } + } - return false; + return false; } function get_option_value($str, $alt=null) { - global $options; + global $options; - $matches = array(); + $matches = array(); - if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { - $matches[] = '--'.$opt; - } else { - $matches[] = $opt; - } + if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { + $matches[] = '--'.$opt; + } else { + $matches[] = $opt; + } - if (!empty($alt)) { - if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { - $matches[] = '--'.$alt; - } else { - $matches[] = $alt; - } - } + if (!empty($alt)) { + if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { + $matches[] = '--'.$alt; + } else { + $matches[] = $alt; + } + } - foreach ($options as $option) { - if (in_array($option[0], $matches)) { - return $option[1]; - } - } + foreach ($options as $option) { + if (in_array($option[0], $matches)) { + return $option[1]; + } + } - return null; -} \ No newline at end of file + return null; +} From 3ac6b7d120dff2d2b1c35e65559aa1613f5b02dd Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 17:02:31 -0400 Subject: [PATCH 24/32] error in get_option_value wasn't returning a value --- scripts/commandline.inc | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/scripts/commandline.inc b/scripts/commandline.inc index bca09216d5..3b6ef60987 100644 --- a/scripts/commandline.inc +++ b/scripts/commandline.inc @@ -122,10 +122,8 @@ require_once INSTALLDIR . '/lib/common.php'; set_error_handler('common_error_handler'); -function have_option($opt, $alt=null) +function _make_matches($opt, $alt) { - global $options; - $matches = array(); if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { @@ -142,6 +140,15 @@ function have_option($opt, $alt=null) } } + return $matches; +} + +function have_option($opt, $alt=null) +{ + global $options; + + $matches = _make_matches($opt, $alt); + foreach ($options as $option) { if (in_array($option[0], $matches)) { return true; @@ -151,25 +158,11 @@ function have_option($opt, $alt=null) return false; } -function get_option_value($str, $alt=null) +function get_option_value($opt, $alt=null) { global $options; - $matches = array(); - - if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { - $matches[] = '--'.$opt; - } else { - $matches[] = $opt; - } - - if (!empty($alt)) { - if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { - $matches[] = '--'.$alt; - } else { - $matches[] = $alt; - } - } + $matches = _make_matches($opt, $alt); foreach ($options as $option) { if (in_array($option[0], $matches)) { From 96814f14dbba483baa88d6e506dc7f61f0052a13 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 17:22:11 -0400 Subject: [PATCH 25/32] add a lot more logging to xmppdaemon --- scripts/xmppdaemon.php | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 3e46c8e260..231922e39e 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -75,10 +75,17 @@ class XMPPDaemon extends Daemon return false; } + $this->log(LOG_INFO, "Connected"); + $this->conn->setReconnectTimeout(600); + $this->log(LOG_INFO, "Sending initial presence."); + jabber_send_presence("Send me a message to post a notice", 'available', null, 'available', 100); + + $this->log(LOG_INFO, "Done connecting."); + return !$this->conn->isDisconnected(); } @@ -91,17 +98,23 @@ class XMPPDaemon extends Daemon { if ($this->connect()) { + $this->log(LOG_DEBUG, "Initializing stanza handlers."); + $this->conn->addEventHandler('message', 'handle_message', $this); $this->conn->addEventHandler('presence', 'handle_presence', $this); $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this); + $this->log(LOG_DEBUG, "Beginning processing loop."); + $this->conn->process(); } } function handle_reconnect(&$pl) { + $this->log(LOG_DEBUG, "Got reconnection callback."); $this->conn->processUntil('session_start'); + $this->log(LOG_DEBUG, "Sending reconnection presence."); $this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100); } @@ -113,21 +126,27 @@ class XMPPDaemon extends Daemon function handle_message(&$pl) { + $from = jabber_normalize_jid($pl['from']); + if ($pl['type'] != 'chat') { - return; - } - if (mb_strlen($pl['body']) == 0) { + $this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from."); return; } - $from = jabber_normalize_jid($pl['from']); + if (mb_strlen($pl['body']) == 0) { + $this->log(LOG_WARNING, "Ignoring message with empty body from $from."); + return; + } # Forwarded from another daemon (probably a broadcaster) for # us to handle if ($this->is_self($from)) { + $this->log(LOG_INFO, "Got forwarded notice from self ($from)."); $from = $this->get_ofrom($pl); + $this->log(LOG_INFO, "Originally sent by $from."); if (is_null($from) || $this->is_self($from)) { + $this->log(LOG_INFO, "Ignoring notice originally sent by $from."); return; } } @@ -142,6 +161,7 @@ class XMPPDaemon extends Daemon return; } if ($this->handle_command($user, $pl['body'])) { + $this->log(LOG_INFO, "Command messag by $from handled."); return; } else if ($this->is_autoreply($pl['body'])) { $this->log(LOG_INFO, 'Ignoring auto reply from ' . $from); @@ -150,12 +170,20 @@ class XMPPDaemon extends Daemon $this->log(LOG_INFO, 'Ignoring OTR from ' . $from); return; } else if ($this->is_direct($pl['body'])) { + $this->log(LOG_INFO, 'Got a direct message ' . $from); + preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to); $to = preg_replace('/^d([\ ])*/', '', $to[0][0]); $body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']); + + $this->log(LOG_INFO, 'Direct message from '. $user->nickname . ' to ' . $to); + $this->add_direct($user, $body, $to, $from); } else { + + $this->log(LOG_INFO, 'Posting a notice from ' . $user->nickname); + $this->add_notice($user, $pl); } @@ -263,6 +291,7 @@ class XMPPDaemon extends Daemon $notice = Notice::saveNew($user->id, $content_shortened, 'xmpp'); if (is_string($notice)) { $this->log(LOG_ERR, $notice); + $this->from_site($user->jabber, $notice); return; } common_broadcast_notice($notice); From 87e3c52fa80ca15e00ae0d1892999fc5be6282a1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 17:22:44 -0400 Subject: [PATCH 26/32] change name of constructor for xmppdaemon --- scripts/xmppdaemon.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 231922e39e..ca62181203 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -43,7 +43,7 @@ require_once INSTALLDIR . '/lib/daemon.php'; class XMPPDaemon extends Daemon { - function XMPPDaemon($resource=null, $daemonize=true) + function __construct($resource=null, $daemonize=true) { parent::__construct($daemonize); From 5cc58f1e01c38fbf33f3d663231b7a66cdf3310e Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 17:38:02 -0400 Subject: [PATCH 27/32] note when going background --- lib/daemon.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/daemon.php b/lib/daemon.php index 72e8bc2028..90dd773c64 100644 --- a/lib/daemon.php +++ b/lib/daemon.php @@ -138,6 +138,7 @@ class Daemon } if ($this->daemonize) { + common_log('Backgrounding daemon "'.$this->name().'"'); $this->background(); } From 6557a569e595eee75609eb6cf12e6e788061daa9 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 17:41:16 -0400 Subject: [PATCH 28/32] fix logging error --- lib/daemon.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/daemon.php b/lib/daemon.php index 90dd773c64..9d89c63e78 100644 --- a/lib/daemon.php +++ b/lib/daemon.php @@ -138,7 +138,7 @@ class Daemon } if ($this->daemonize) { - common_log('Backgrounding daemon "'.$this->name().'"'); + common_log(LOG_INFO, 'Backgrounding daemon "'.$this->name().'"'); $this->background(); } From 14575fe6fc0de65f0234c73147ca877cc4c46cb8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 19:24:14 -0400 Subject: [PATCH 29/32] better output for common error handler --- lib/util.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/util.php b/lib/util.php index 1ae43a0563..f9ff38c8ad 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1348,18 +1348,39 @@ function common_canonical_sms($sms) function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { switch ($errno) { + + case E_ERROR: + case E_COMPILE_ERROR: + case E_CORE_ERROR: case E_USER_ERROR: - common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline)"); - exit(1); + case E_PARSE: + case E_RECOVERABLE_ERROR: + common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline) [ABORT]"); + die(); break; + case E_WARNING: + case E_COMPILE_WARNING: + case E_CORE_WARNING: case E_USER_WARNING: common_log(LOG_WARNING, "[$errno] $errstr ($errfile:$errline)"); break; + case E_NOTICE: case E_USER_NOTICE: common_log(LOG_NOTICE, "[$errno] $errstr ($errfile:$errline)"); break; + + case E_STRICT: + case E_DEPRECATED: + case E_USER_DEPRECATED: + // XXX: config variable to log this stuff, too + break; + + default: + common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline) [UNKNOWN LEVEL, die()'ing]"); + die(); + break; } // FIXME: show error page if we're on the Web From ffa40a84bae9932e390cb58a4ba3a21708e61977 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 28 Jun 2009 21:03:21 -0400 Subject: [PATCH 30/32] update to latest (r76) version of XMPPHP --- extlib/XMPPHP/BOSH.php | 2 +- extlib/XMPPHP/XMLStream.php | 8 ++++---- extlib/XMPPHP/XMPP.php | 13 +++++++++++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/extlib/XMPPHP/BOSH.php b/extlib/XMPPHP/BOSH.php index b147443d79..befaf60a77 100644 --- a/extlib/XMPPHP/BOSH.php +++ b/extlib/XMPPHP/BOSH.php @@ -27,7 +27,7 @@ */ /** XMPPHP_XMLStream */ -require_once "XMPP.php"; +require_once dirname(__FILE__) . "/XMPP.php"; /** * XMPPHP Main Class diff --git a/extlib/XMPPHP/XMLStream.php b/extlib/XMPPHP/XMLStream.php index 0fcfea375e..d33411ec54 100644 --- a/extlib/XMPPHP/XMLStream.php +++ b/extlib/XMPPHP/XMLStream.php @@ -27,13 +27,13 @@ */ /** XMPPHP_Exception */ -require_once 'Exception.php'; +require_once dirname(__FILE__) . '/Exception.php'; /** XMPPHP_XMLObj */ -require_once 'XMLObj.php'; +require_once dirname(__FILE__) . '/XMLObj.php'; /** XMPPHP_Log */ -require_once 'Log.php'; +require_once dirname(__FILE__) . '/Log.php'; /** * XMPPHP XML Stream @@ -375,7 +375,7 @@ class XMPPHP_XMLStream { * integer -> process for this amount of time */ - private function __process($maximum=0) { + private function __process($maximum=5) { $remaining = $maximum; diff --git a/extlib/XMPPHP/XMPP.php b/extlib/XMPPHP/XMPP.php index 73fbd26584..429f45e565 100644 --- a/extlib/XMPPHP/XMPP.php +++ b/extlib/XMPPHP/XMPP.php @@ -27,8 +27,8 @@ */ /** XMPPHP_XMLStream */ -require_once "XMLStream.php"; -require_once "Roster.php"; +require_once dirname(__FILE__) . "/XMLStream.php"; +require_once dirname(__FILE__) . "/Roster.php"; /** * XMPPHP Main Class @@ -208,6 +208,15 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream { $this->send($out); } + /** + * Send Auth request + * + * @param string $jid + */ + public function subscribe($jid) { + $this->send(""); + #$this->send(""); + } /** * Message handler From d03b8c4276e5bd3822289a8b5c94be60cb90ef75 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 29 Jun 2009 10:22:17 -0400 Subject: [PATCH 31/32] show section with admins in sidebar of group --- actions/showgroup.php | 44 ++++++++++++++++++++++++++++++++++++++++++ classes/User_group.php | 24 +++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/actions/showgroup.php b/actions/showgroup.php index b6a0f4844e..ce11d574e9 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -331,6 +331,7 @@ class ShowgroupAction extends GroupDesignAction { $this->showMembers(); $this->showStatistics(); + $this->showAdmins(); $cloud = new GroupTagCloudSection($this, $this->group); $cloud->show(); } @@ -369,6 +370,18 @@ class ShowgroupAction extends GroupDesignAction $this->elementEnd('div'); } + /** + * Show list of admins + * + * @return void + */ + + function showAdmins() + { + $adminSection = new GroupAdminSection($this, $this->group); + $adminSection->show(); + } + /** * Show some statistics * @@ -423,3 +436,34 @@ class ShowgroupAction extends GroupDesignAction $this->elementEnd('div'); } } + +class GroupAdminSection extends ProfileSection +{ + var $group; + + function __construct($out, $group) + { + parent::__construct($out); + $this->group = $group; + } + + function getProfiles() + { + return $this->group->getAdmins(); + } + + function title() + { + return _('Admins'); + } + + function divId() + { + return 'group_admins'; + } + + function moreUrl() + { + return null; + } +} \ No newline at end of file diff --git a/classes/User_group.php b/classes/User_group.php index 9b4b01ead7..27b444705d 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -126,6 +126,30 @@ class User_group extends Memcached_DataObject return $members; } + function getAdmins($offset=0, $limit=null) + { + $qry = + 'SELECT profile.* ' . + 'FROM profile JOIN group_member '. + 'ON profile.id = group_member.profile_id ' . + 'WHERE group_member.group_id = %d ' . + 'AND group_member.is_admin = 1 ' . + 'ORDER BY group_member.modified ASC '; + + if ($limit != null) { + if (common_config('db','type') == 'pgsql') { + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; + } else { + $qry .= ' LIMIT ' . $offset . ', ' . $limit; + } + } + + $admins = new Profile(); + + $admins->query(sprintf($qry, $this->id)); + return $admins; + } + function getBlocked($offset=0, $limit=null) { $qry = From 5b8e40aaa9bdb0c07cce0cf53cd913b0c397fdc4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 29 Jun 2009 10:29:11 -0400 Subject: [PATCH 32/32] admin indicators in groups --- actions/groupmembers.php | 9 +++++++++ theme/base/css/display.css | 18 +++--------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/actions/groupmembers.php b/actions/groupmembers.php index d132cdf967..be7a9e81c7 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -167,6 +167,15 @@ class GroupMemberListItem extends ProfileListItem $this->group = $group; } + function showFullName() + { + parent::showFullName(); + if ($this->profile->isAdmin($this->group)) { + $this->out->text(' '); + $this->out->element('span', 'admin_indicator', _('Admin')); + } + } + function showActions() { $this->startActions(); diff --git a/theme/base/css/display.css b/theme/base/css/display.css index 78fcd7ecef..df4e756330 100644 --- a/theme/base/css/display.css +++ b/theme/base/css/display.css @@ -206,7 +206,6 @@ border-radius:4px; padding:0 7px; } - .form_settings input.form_action-primary { padding:0; } @@ -270,7 +269,6 @@ clear:both; margin-bottom:18px; } - #anon_notice { float:left; width:43.2%; @@ -285,7 +283,6 @@ font-size:1.1em; font-weight:bold; } - #footer { float:left; width:64%; @@ -597,7 +594,6 @@ display:none; } /* entity_profile */ - /*entity_actions*/ .entity_actions { float:right; @@ -726,7 +722,6 @@ margin-bottom:0; min-height:60px; } - .profile .form_group_join legend, .profile .form_group_leave legend, .profile .form_user_subscribe legend, @@ -761,13 +756,11 @@ display:inline; margin-right:11px; } - .profile .entity_profile .form_subscription_edit label { font-weight:normal; margin-right:11px; } - /* NOTICE */ .notice, .profile { @@ -790,7 +783,6 @@ width:95%; float:left; } - /* NOTICES */ #notices_primary { float:left; @@ -962,7 +954,6 @@ border:0; padding:0; } - .notice .attachment { position:relative; padding-left:16px; @@ -1059,7 +1050,6 @@ margin-bottom:18px; padding-left:20px; } - #filter_tags { margin-bottom:11px; float:left; @@ -1105,8 +1095,6 @@ top:3px; left:3px; } - - .pagination { float:left; clear:both; @@ -1152,7 +1140,6 @@ padding-right:30px; } /* END: NOTICE */ - .hentry .entry-content p { margin-bottom:18px; } @@ -1169,7 +1156,6 @@ margin-bottom:18px; margin-left:18px; } - /* TOP_POSTERS */ .section tbody td { padding-right:18px; @@ -1197,7 +1183,6 @@ margin-right:0; display:none; } - /* tagcloud */ .tag-cloud { list-style-type:none; @@ -1314,3 +1299,6 @@ display:none; .guide { clear:both; } +.admin_indicator { +font-style:italic; +} \ No newline at end of file