--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for APC variable cache
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to use APC's variable cache for the cache interface
+ *
+ * New plugin interface lets us use alternative cache systems
+ * for caching. This one uses APC's variable cache.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class APCPlugin extends Plugin
+{
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheGet(&$key, &$value)
+ {
+ $value = apc_fetch($key);
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag (passed through to Memcache)
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry));
+
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $success = apc_delete($key);
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'APC',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:APC',
+ 'rawdescription' =>
+ _m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.'));
+ return true;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009, StatusNet, Inc.
- *
- * Plugin to implement cache interface for APC variable cache
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * A plugin to use APC's variable cache for the cache interface
- *
- * New plugin interface lets us use alternative cache systems
- * for caching. This one uses APC's variable cache.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class APCPlugin extends Plugin
-{
- /**
- * Get a value associated with a key
- *
- * The value should have been set previously.
- *
- * @param string &$key in; Lookup key
- * @param mixed &$value out; value associated with key
- *
- * @return boolean hook success
- */
-
- function onStartCacheGet(&$key, &$value)
- {
- $value = apc_fetch($key);
- Event::handle('EndCacheGet', array($key, &$value));
- return false;
- }
-
- /**
- * Associate a value with a key
- *
- * @param string &$key in; Key to use for lookups
- * @param mixed &$value in; Value to associate
- * @param integer &$flag in; Flag (passed through to Memcache)
- * @param integer &$expiry in; Expiry (passed through to Memcache)
- * @param boolean &$success out; Whether the set was successful
- *
- * @return boolean hook success
- */
-
- function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
- {
- $success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry));
-
- Event::handle('EndCacheSet', array($key, $value, $flag,
- $expiry));
- return false;
- }
-
- /**
- * Delete a value associated with a key
- *
- * @param string &$key in; Key to lookup
- * @param boolean &$success out; whether it worked
- *
- * @return boolean hook success
- */
-
- function onStartCacheDelete(&$key, &$success)
- {
- $success = apc_delete($key);
- Event::handle('EndCacheDelete', array($key));
- return false;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'APC',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:APC',
- 'rawdescription' =>
- _m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.'));
- return true;
- }
-}
-
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to check submitted notices with blogspam.net
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @author Brion Vibber <brion@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+define('BLOGSPAMNETPLUGIN_VERSION', '0.1');
+
+/**
+ * Plugin to check submitted notices with blogspam.net
+ *
+ * When new notices are saved, we check their text with blogspam.net (or
+ * a compatible service).
+ *
+ * Blogspam.net is supposed to catch blog comment spam, and I found that
+ * some of its tests (min/max size, bayesian match) gave a lot of false positives.
+ * So, I've turned those tests off by default. This may not get as many
+ * hits, but it's better than nothing.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class BlogspamNetPlugin extends Plugin
+{
+ var $baseUrl = 'http://test.blogspam.net:8888/';
+
+ function __construct($url=null)
+ {
+ parent::__construct();
+ if ($url) {
+ $this->baseUrl = $url;
+ }
+ }
+
+ function onStartNoticeSave($notice)
+ {
+ $args = $this->testArgs($notice);
+ common_debug("Blogspamnet args = " . print_r($args, TRUE));
+ $requestBody = xmlrpc_encode_request('testComment', array($args));
+
+ $request = new HTTPClient($this->baseUrl, HTTPClient::METHOD_POST);
+ $request->setHeader('Content-Type', 'text/xml');
+ $request->setBody($requestBody);
+ $httpResponse = $request->send();
+
+ $response = xmlrpc_decode($httpResponse->getBody());
+ if (xmlrpc_is_fault($response)) {
+ throw new ServerException("$response[faultString] ($response[faultCode])", 500);
+ } else {
+ common_debug("Blogspamnet results = " . $response);
+ if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) {
+ throw new ServerException(sprintf(_("Error from %s: %s"), $this->baseUrl, $match[2]), 500);
+ } else if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
+ throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400);
+ } else if (preg_match('/^OK$/', $response)) {
+ // don't do anything
+ } else {
+ throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500);
+ }
+ }
+ return true;
+ }
+
+ function testArgs($notice)
+ {
+ $args = array();
+ $args['comment'] = $notice->content;
+ $args['ip'] = $this->getClientIP();
+
+ if (isset($_SERVER) && array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
+ $args['agent'] = $_SERVER['HTTP_USER_AGENT'];
+ }
+
+ $profile = $notice->getProfile();
+
+ if ($profile && $profile->homepage) {
+ $args['link'] = $profile->homepage;
+ }
+
+ if ($profile && $profile->fullname) {
+ $args['name'] = $profile->fullname;
+ } else {
+ $args['name'] = $profile->nickname;
+ }
+
+ $args['site'] = common_root_url();
+ $args['version'] = $this->userAgent();
+
+ $args['options'] = "max-size=" . common_config('site','textlimit') . ",min-size=0,min-words=0,exclude=bayasian";
+
+ return $args;
+ }
+
+ function getClientIP()
+ {
+ if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+ // Note: order matters here; use proxy-forwarded stuff first
+ foreach (array('HTTP_X_FORWARDED_FOR', 'CLIENT-IP', 'REMOTE_ADDR') as $k) {
+ if (isset($_SERVER[$k])) {
+ return $_SERVER[$k];
+ }
+ }
+ }
+ return '127.0.0.1';
+ }
+
+ function userAgent()
+ {
+ return 'BlogspamNetPlugin/'.BLOGSPAMNETPLUGIN_VERSION . ' StatusNet/' . STATUSNET_VERSION;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to check submitted notices with blogspam.net
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @author Brion Vibber <brion@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-define('BLOGSPAMNETPLUGIN_VERSION', '0.1');
-
-/**
- * Plugin to check submitted notices with blogspam.net
- *
- * When new notices are saved, we check their text with blogspam.net (or
- * a compatible service).
- *
- * Blogspam.net is supposed to catch blog comment spam, and I found that
- * some of its tests (min/max size, bayesian match) gave a lot of false positives.
- * So, I've turned those tests off by default. This may not get as many
- * hits, but it's better than nothing.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class BlogspamNetPlugin extends Plugin
-{
- var $baseUrl = 'http://test.blogspam.net:8888/';
-
- function __construct($url=null)
- {
- parent::__construct();
- if ($url) {
- $this->baseUrl = $url;
- }
- }
-
- function onStartNoticeSave($notice)
- {
- $args = $this->testArgs($notice);
- common_debug("Blogspamnet args = " . print_r($args, TRUE));
- $requestBody = xmlrpc_encode_request('testComment', array($args));
-
- $request = new HTTPClient($this->baseUrl, HTTPClient::METHOD_POST);
- $request->setHeader('Content-Type', 'text/xml');
- $request->setBody($requestBody);
- $httpResponse = $request->send();
-
- $response = xmlrpc_decode($httpResponse->getBody());
- if (xmlrpc_is_fault($response)) {
- throw new ServerException("$response[faultString] ($response[faultCode])", 500);
- } else {
- common_debug("Blogspamnet results = " . $response);
- if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) {
- throw new ServerException(sprintf(_("Error from %s: %s"), $this->baseUrl, $match[2]), 500);
- } else if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
- throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400);
- } else if (preg_match('/^OK$/', $response)) {
- // don't do anything
- } else {
- throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500);
- }
- }
- return true;
- }
-
- function testArgs($notice)
- {
- $args = array();
- $args['comment'] = $notice->content;
- $args['ip'] = $this->getClientIP();
-
- if (isset($_SERVER) && array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
- $args['agent'] = $_SERVER['HTTP_USER_AGENT'];
- }
-
- $profile = $notice->getProfile();
-
- if ($profile && $profile->homepage) {
- $args['link'] = $profile->homepage;
- }
-
- if ($profile && $profile->fullname) {
- $args['name'] = $profile->fullname;
- } else {
- $args['name'] = $profile->nickname;
- }
-
- $args['site'] = common_root_url();
- $args['version'] = $this->userAgent();
-
- $args['options'] = "max-size=" . common_config('site','textlimit') . ",min-size=0,min-words=0,exclude=bayasian";
-
- return $args;
- }
-
- function getClientIP()
- {
- if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
- // Note: order matters here; use proxy-forwarded stuff first
- foreach (array('HTTP_X_FORWARDED_FOR', 'CLIENT-IP', 'REMOTE_ADDR') as $k) {
- if (isset($_SERVER[$k])) {
- return $_SERVER[$k];
- }
- }
- }
- return '127.0.0.1';
- }
-
- function userAgent()
- {
- return 'BlogspamNetPlugin/'.BLOGSPAMNETPLUGIN_VERSION . ' StatusNet/' . STATUSNET_VERSION;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Logs cache access
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Log cache access
+ *
+ * Note that since most caching plugins return false for StartCache*
+ * methods, you should add this plugin before them, i.e.
+ *
+ * addPlugin('CacheLog');
+ * addPlugin('XCache');
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class CacheLogPlugin extends Plugin
+{
+ function onStartCacheGet(&$key, &$value)
+ {
+ $this->log(LOG_INFO, "Fetching key '$key'");
+ return true;
+ }
+
+ function onEndCacheGet($key, &$value)
+ {
+ if ($value === false) {
+ $this->log(LOG_INFO, "Cache MISS for key '$key'");
+ } else {
+ $this->log(LOG_INFO, "Cache HIT for key '$key'");
+ }
+ return true;
+ }
+
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ if (empty($value)) {
+ if (is_array($value)) {
+ $this->log(LOG_INFO, "Setting empty array for key '$key'");
+ } else if (is_null($value)) {
+ $this->log(LOG_INFO, "Setting null value for key '$key'");
+ } else if (is_string($value)) {
+ $this->log(LOG_INFO, "Setting empty string for key '$key'");
+ } else if (is_integer($value)) {
+ $this->log(LOG_INFO, "Setting integer 0 for key '$key'");
+ } else {
+ $this->log(LOG_INFO, "Setting empty value '$value' for key '$key'");
+ }
+ } else {
+ $this->log(LOG_INFO, "Setting non-empty value for key '$key'");
+ }
+ return true;
+ }
+
+ function onEndCacheSet($key, $value, $flag, $expiry)
+ {
+ $this->log(LOG_INFO, "Done setting cache value for key '$key'");
+ return true;
+ }
+
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $this->log(LOG_INFO, "Deleting cache value for key '$key'");
+ return true;
+ }
+
+ function onEndCacheDelete($key)
+ {
+ $this->log(LOG_INFO, "Done deleting cache value for key '$key'");
+ return true;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'CacheLog',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:CacheLog',
+ 'description' =>
+ _m('Log reads and writes to the cache'));
+ return true;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009, StatusNet, Inc.
- *
- * Logs cache access
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * Log cache access
- *
- * Note that since most caching plugins return false for StartCache*
- * methods, you should add this plugin before them, i.e.
- *
- * addPlugin('CacheLog');
- * addPlugin('XCache');
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link http://status.net/
- */
-
-class CacheLogPlugin extends Plugin
-{
- function onStartCacheGet(&$key, &$value)
- {
- $this->log(LOG_INFO, "Fetching key '$key'");
- return true;
- }
-
- function onEndCacheGet($key, &$value)
- {
- if ($value === false) {
- $this->log(LOG_INFO, "Cache MISS for key '$key'");
- } else {
- $this->log(LOG_INFO, "Cache HIT for key '$key'");
- }
- return true;
- }
-
- function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
- {
- if (empty($value)) {
- if (is_array($value)) {
- $this->log(LOG_INFO, "Setting empty array for key '$key'");
- } else if (is_null($value)) {
- $this->log(LOG_INFO, "Setting null value for key '$key'");
- } else if (is_string($value)) {
- $this->log(LOG_INFO, "Setting empty string for key '$key'");
- } else if (is_integer($value)) {
- $this->log(LOG_INFO, "Setting integer 0 for key '$key'");
- } else {
- $this->log(LOG_INFO, "Setting empty value '$value' for key '$key'");
- }
- } else {
- $this->log(LOG_INFO, "Setting non-empty value for key '$key'");
- }
- return true;
- }
-
- function onEndCacheSet($key, $value, $flag, $expiry)
- {
- $this->log(LOG_INFO, "Done setting cache value for key '$key'");
- return true;
- }
-
- function onStartCacheDelete(&$key, &$success)
- {
- $this->log(LOG_INFO, "Deleting cache value for key '$key'");
- return true;
- }
-
- function onEndCacheDelete($key)
- {
- $this->log(LOG_INFO, "Done deleting cache value for key '$key'");
- return true;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'CacheLog',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:CacheLog',
- 'description' =>
- _m('Log reads and writes to the cache'));
- return true;
- }
-}
-
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface with disk files
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to cache data on local disk
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class DiskCachePlugin extends Plugin
+{
+ var $root = '/tmp';
+
+ function keyToFilename($key)
+ {
+ return $this->root . '/' . str_replace(':', '/', $key);
+ }
+
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheGet(&$key, &$value)
+ {
+ $filename = $this->keyToFilename($key);
+
+ if (file_exists($filename)) {
+ $data = file_get_contents($filename);
+ if ($data !== false) {
+ $value = unserialize($data);
+ }
+ }
+
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag (passed through to Memcache)
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $filename = $this->keyToFilename($key);
+ $parent = dirname($filename);
+
+ $sofar = '';
+
+ foreach (explode('/', $parent) as $part) {
+ if (empty($part)) {
+ continue;
+ }
+ $sofar .= '/' . $part;
+ if (!is_dir($sofar)) {
+ $this->debug("Creating new directory '$sofar'");
+ $success = mkdir($sofar, 0750);
+ if (!$success) {
+ $this->log(LOG_ERR, "Can't create directory '$sofar'");
+ return false;
+ }
+ }
+ }
+
+ if (is_dir($filename)) {
+ $success = false;
+ return false;
+ }
+
+ // Write to a temp file and move to destination
+
+ $tempname = tempnam(null, 'statusnetdiskcache');
+
+ $result = file_put_contents($tempname, serialize($value));
+
+ if ($result === false) {
+ $this->log(LOG_ERR, "Couldn't write '$key' to temp file '$tempname'");
+ return false;
+ }
+
+ $result = rename($tempname, $filename);
+
+ if (!$result) {
+ $this->log(LOG_ERR, "Couldn't move temp file '$tempname' to path '$filename' for key '$key'");
+ @unlink($tempname);
+ return false;
+ }
+
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $filename = $this->keyToFilename($key);
+
+ if (file_exists($filename) && !is_dir($filename)) {
+ unlink($filename);
+ }
+
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009, StatusNet, Inc.
- *
- * Plugin to implement cache interface with disk files
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * A plugin to cache data on local disk
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class DiskCachePlugin extends Plugin
-{
- var $root = '/tmp';
-
- function keyToFilename($key)
- {
- return $this->root . '/' . str_replace(':', '/', $key);
- }
-
- /**
- * Get a value associated with a key
- *
- * The value should have been set previously.
- *
- * @param string &$key in; Lookup key
- * @param mixed &$value out; value associated with key
- *
- * @return boolean hook success
- */
-
- function onStartCacheGet(&$key, &$value)
- {
- $filename = $this->keyToFilename($key);
-
- if (file_exists($filename)) {
- $data = file_get_contents($filename);
- if ($data !== false) {
- $value = unserialize($data);
- }
- }
-
- Event::handle('EndCacheGet', array($key, &$value));
- return false;
- }
-
- /**
- * Associate a value with a key
- *
- * @param string &$key in; Key to use for lookups
- * @param mixed &$value in; Value to associate
- * @param integer &$flag in; Flag (passed through to Memcache)
- * @param integer &$expiry in; Expiry (passed through to Memcache)
- * @param boolean &$success out; Whether the set was successful
- *
- * @return boolean hook success
- */
-
- function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
- {
- $filename = $this->keyToFilename($key);
- $parent = dirname($filename);
-
- $sofar = '';
-
- foreach (explode('/', $parent) as $part) {
- if (empty($part)) {
- continue;
- }
- $sofar .= '/' . $part;
- if (!is_dir($sofar)) {
- $this->debug("Creating new directory '$sofar'");
- $success = mkdir($sofar, 0750);
- if (!$success) {
- $this->log(LOG_ERR, "Can't create directory '$sofar'");
- return false;
- }
- }
- }
-
- if (is_dir($filename)) {
- $success = false;
- return false;
- }
-
- // Write to a temp file and move to destination
-
- $tempname = tempnam(null, 'statusnetdiskcache');
-
- $result = file_put_contents($tempname, serialize($value));
-
- if ($result === false) {
- $this->log(LOG_ERR, "Couldn't write '$key' to temp file '$tempname'");
- return false;
- }
-
- $result = rename($tempname, $filename);
-
- if (!$result) {
- $this->log(LOG_ERR, "Couldn't move temp file '$tempname' to path '$filename' for key '$key'");
- @unlink($tempname);
- return false;
- }
-
- Event::handle('EndCacheSet', array($key, $value, $flag,
- $expiry));
-
- return false;
- }
-
- /**
- * Delete a value associated with a key
- *
- * @param string &$key in; Key to lookup
- * @param boolean &$success out; whether it worked
- *
- * @return boolean hook success
- */
-
- function onStartCacheDelete(&$key, &$success)
- {
- $filename = $this->keyToFilename($key);
-
- if (file_exists($filename) && !is_dir($filename)) {
- unlink($filename);
- }
-
- Event::handle('EndCacheDelete', array($key));
- return false;
- }
-}
-
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to add Disqus commenting to notice pages
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ *
+ * This plugin adds Disqus commenting to your notices. Enabling this
+ * plugin will make each notice page display the Disqus widget, and
+ * notice lists will display the number of commments each notice has.
+ *
+ * To use this plugin, you need to first register your site with Disqus
+ * and get a Discus 'shortname' for it.
+ *
+ * http://disqus.com
+ *
+ * To enable the plugin, put the following in you config.php:
+ *
+ * addPlugin(
+ * 'Disqus', array(
+ * 'shortname' => 'YOURSHORTNAME',
+ * 'div_style' => 'width:675px; padding-top:10px; position:relative; float:left;'
+ * )
+ * );
+ *
+ * NOTE: the 'div_style' in an optional parameter that passes in some
+ * inline CSS when creating the Disqus widget. It's a shortcut to make
+ * the widget look OK with the default StatusNet theme. If you leave
+ * it out you'll have to edit your theme CSS files to make the widget
+ * look good. You can also control the way the widget looks by
+ * adding style rules to your theme.
+ *
+ * See: http://help.disqus.com/entries/100878-css-customization
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class DisqusPlugin extends Plugin
+{
+ function onEndShowContentBlock($action)
+ {
+ if (get_class($action) == 'ShownoticeAction') {
+
+ $attrs = array();
+ $attrs['id'] = 'disqus_thread';
+
+ if ($this->div_style) {
+ $attrs['style'] = $this->div_style;
+ }
+
+ $action->element('div', $attrs, null);
+
+ $script = <<<ENDOFSCRIPT
+var disqus_identifier = %d;
+ (function() {
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+ dsq.src = 'http://%s.disqus.com/embed.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+ })();
+ENDOFSCRIPT;
+
+ $action->inlineScript(sprintf($script, $action->notice->id, $this->shortname));
+
+ $attrs = array();
+
+ $attrs['id'] = 'disqus_thread_footer';
+
+ if ($this->div_style) {
+ $attrs['style'] = $this->div_style;
+ }
+
+ $action->elementStart('div', $attrs);
+ $action->elementStart('noscript');
+
+ $action->raw('Please enable JavaScript to view the ');
+ $noscriptUrl = 'http://disqus.com/?ref_noscript=' . $this->shortname;
+ $action->element('a', array('href' => $noscriptUrl), 'comments powered by Disqus.');
+ $action->elementEnd('noscript');
+
+ $action->elementStart('a', array('href' => 'http://disqus.com', 'class' => 'dsq-brlink'));
+ $action->raw('blog comments powered by ');
+ $action->element('span', array('class' => 'logo-disqus'), 'Disqus');
+ $action->elementEnd('a');
+ $action->elementEnd('div');
+ }
+ }
+
+ function onEndShowScripts($action)
+ {
+ // fugly
+ $script = <<<ENDOFSCRIPT
+var disqus_shortname = '%s';
+(function () {
+ var s = document.createElement('script'); s.async = true;
+ s.src = 'http://disqus.com/forums/%s/count.js';
+ (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
+}());
+ENDOFSCRIPT;
+ $action->inlineScript(sprintf($script, $this->shortname, $this->shortname));
+
+ return true;
+ }
+
+ function onStartShowNoticeItem($noticeListItem)
+ {
+ if (empty($noticeListItem->notice->is_local)) {
+ return true;
+ }
+
+ $noticeListItem->showNotice();
+ $noticeListItem->showNoticeInfo();
+
+ $noticeUrl = $noticeListItem->notice->bestUrl();
+ $noticeUrl .= '#disqus_thread';
+
+ $noticeListItem->out->element(
+ 'a', array('href' => $noticeUrl, 'class' => 'disqus_count'), 'Comments'
+ );
+
+ $noticeListItem->showNoticeOptions();
+ Event::handle('EndShowNoticeItem', array($noticeListItem));
+
+ return false;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Disqus',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Zach Copley',
+ 'homepage' => 'http://status.net/wiki/Plugin:Disqus',
+ 'rawdescription' =>
+ _m('Use <a href="http://disqus.com/">Disqus</a>'.
+ ' to add commenting to notice pages.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to add Disqus commenting to notice pages
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Zach Copley <zach@status.net>
- * @copyright 2010 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- *
- * This plugin adds Disqus commenting to your notices. Enabling this
- * plugin will make each notice page display the Disqus widget, and
- * notice lists will display the number of commments each notice has.
- *
- * To use this plugin, you need to first register your site with Disqus
- * and get a Discus 'shortname' for it.
- *
- * http://disqus.com
- *
- * To enable the plugin, put the following in you config.php:
- *
- * addPlugin(
- * 'Disqus', array(
- * 'shortname' => 'YOURSHORTNAME',
- * 'div_style' => 'width:675px; padding-top:10px; position:relative; float:left;'
- * )
- * );
- *
- * NOTE: the 'div_style' in an optional parameter that passes in some
- * inline CSS when creating the Disqus widget. It's a shortcut to make
- * the widget look OK with the default StatusNet theme. If you leave
- * it out you'll have to edit your theme CSS files to make the widget
- * look good. You can also control the way the widget looks by
- * adding style rules to your theme.
- *
- * See: http://help.disqus.com/entries/100878-css-customization
- *
- * @category Plugin
- * @package StatusNet
- * @author Zach Copley <zach@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class DisqusPlugin extends Plugin
-{
- function onEndShowContentBlock($action)
- {
- if (get_class($action) == 'ShownoticeAction') {
-
- $attrs = array();
- $attrs['id'] = 'disqus_thread';
-
- if ($this->div_style) {
- $attrs['style'] = $this->div_style;
- }
-
- $action->element('div', $attrs, null);
-
- $script = <<<ENDOFSCRIPT
-var disqus_identifier = %d;
- (function() {
- var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
- dsq.src = 'http://%s.disqus.com/embed.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
- })();
-ENDOFSCRIPT;
-
- $action->inlineScript(sprintf($script, $action->notice->id, $this->shortname));
-
- $attrs = array();
-
- $attrs['id'] = 'disqus_thread_footer';
-
- if ($this->div_style) {
- $attrs['style'] = $this->div_style;
- }
-
- $action->elementStart('div', $attrs);
- $action->elementStart('noscript');
-
- $action->raw('Please enable JavaScript to view the ');
- $noscriptUrl = 'http://disqus.com/?ref_noscript=' . $this->shortname;
- $action->element('a', array('href' => $noscriptUrl), 'comments powered by Disqus.');
- $action->elementEnd('noscript');
-
- $action->elementStart('a', array('href' => 'http://disqus.com', 'class' => 'dsq-brlink'));
- $action->raw('blog comments powered by ');
- $action->element('span', array('class' => 'logo-disqus'), 'Disqus');
- $action->elementEnd('a');
- $action->elementEnd('div');
- }
- }
-
- function onEndShowScripts($action)
- {
- // fugly
- $script = <<<ENDOFSCRIPT
-var disqus_shortname = '%s';
-(function () {
- var s = document.createElement('script'); s.async = true;
- s.src = 'http://disqus.com/forums/%s/count.js';
- (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
-}());
-ENDOFSCRIPT;
- $action->inlineScript(sprintf($script, $this->shortname, $this->shortname));
-
- return true;
- }
-
- function onStartShowNoticeItem($noticeListItem)
- {
- if (empty($noticeListItem->notice->is_local)) {
- return true;
- }
-
- $noticeListItem->showNotice();
- $noticeListItem->showNoticeInfo();
-
- $noticeUrl = $noticeListItem->notice->bestUrl();
- $noticeUrl .= '#disqus_thread';
-
- $noticeListItem->out->element(
- 'a', array('href' => $noticeUrl, 'class' => 'disqus_count'), 'Comments'
- );
-
- $noticeListItem->showNoticeOptions();
- Event::handle('EndShowNoticeItem', array($noticeListItem));
-
- return false;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Disqus',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Zach Copley',
- 'homepage' => 'http://status.net/wiki/Plugin:Disqus',
- 'rawdescription' =>
- _m('Use <a href="http://disqus.com/">Disqus</a>'.
- ' to add commenting to notice pages.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to add Echo/JS-Kit commenting to notice pages
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to use Echo (formerly JS-Kit)
+ *
+ * This plugin adds an Echo commenting widget to each notice page on
+ * your site. To get it to work, first you'll have to sign up for Echo
+ * (a for-pay service) and register your site's URL.
+ *
+ * http://aboutecho.com/
+ *
+ * Once you've done that it's pretty straight forward to turn the
+ * plugin on; just add this to your config.php:
+ *
+ * addPlugin(
+ * 'Echo',
+ * array('div_style' => 'width:675px; padding-top:10px; position:relative; float:left;')
+ * );
+ *
+ * NOTE: the 'div_style' in an optional parameter that passes in some
+ * inline CSS when creating the Echo widget. It's a shortcut to make
+ * the widget look OK with the default StatusNet theme. If you leave
+ * it out you'll have to edit your theme CSS files to make the widget
+ * look good. You can also control the way the widget looks by
+ * adding style rules to your theme.
+ *
+ * See: http://wiki.js-kit.com/Skinning-Guide#UsingCSSnbsptocustomizefontsandcolors
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class EchoPlugin extends Plugin
+{
+ // NOTE: The Echo documentation says that this script will change on
+ // a per site basis, but I think that's incorrect. It always seems to
+ // be the same.
+ public $script = 'http://cdn.js-kit.com/scripts/comments.js';
+
+ function onEndShowScripts($action)
+ {
+ if (get_class($action) == 'ShownoticeAction') {
+ $action->script($this->script);
+ }
+
+ return true;
+ }
+
+ function onEndShowContentBlock($action)
+ {
+ if (get_class($action) == 'ShownoticeAction') {
+
+ $attrs = array();
+ $attrs['class'] = 'js-kit-comments';
+ $attrs['permalink'] = $action->notice->uri;
+ $attrs['uniq'] = $action->notice->id;
+
+ // NOTE: there are some other attributes that could be useful
+ // http://wiki.js-kit.com/Echo-Behavior
+
+ if (!empty($this->div_style)) {
+ $attrs['style'] = $this->div_style;
+ }
+
+ $action->element('div', $attrs, null);
+ }
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Echo',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Zach Copley',
+ 'homepage' => 'http://status.net/wiki/Plugin:Echo',
+ 'rawdescription' =>
+ _m('Use <a href="http://aboutecho.com/">Echo</a>'.
+ ' to add commenting to notice pages.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to add Echo/JS-Kit commenting to notice pages
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Zach Copley <zach@status.net>
- * @copyright 2010 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to use Echo (formerly JS-Kit)
- *
- * This plugin adds an Echo commenting widget to each notice page on
- * your site. To get it to work, first you'll have to sign up for Echo
- * (a for-pay service) and register your site's URL.
- *
- * http://aboutecho.com/
- *
- * Once you've done that it's pretty straight forward to turn the
- * plugin on; just add this to your config.php:
- *
- * addPlugin(
- * 'Echo',
- * array('div_style' => 'width:675px; padding-top:10px; position:relative; float:left;')
- * );
- *
- * NOTE: the 'div_style' in an optional parameter that passes in some
- * inline CSS when creating the Echo widget. It's a shortcut to make
- * the widget look OK with the default StatusNet theme. If you leave
- * it out you'll have to edit your theme CSS files to make the widget
- * look good. You can also control the way the widget looks by
- * adding style rules to your theme.
- *
- * See: http://wiki.js-kit.com/Skinning-Guide#UsingCSSnbsptocustomizefontsandcolors
- *
- * @category Plugin
- * @package StatusNet
- * @author Zach Copley <zach@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class EchoPlugin extends Plugin
-{
- // NOTE: The Echo documentation says that this script will change on
- // a per site basis, but I think that's incorrect. It always seems to
- // be the same.
- public $script = 'http://cdn.js-kit.com/scripts/comments.js';
-
- function onEndShowScripts($action)
- {
- if (get_class($action) == 'ShownoticeAction') {
- $action->script($this->script);
- }
-
- return true;
- }
-
- function onEndShowContentBlock($action)
- {
- if (get_class($action) == 'ShownoticeAction') {
-
- $attrs = array();
- $attrs['class'] = 'js-kit-comments';
- $attrs['permalink'] = $action->notice->uri;
- $attrs['uniq'] = $action->notice->id;
-
- // NOTE: there are some other attributes that could be useful
- // http://wiki.js-kit.com/Echo-Behavior
-
- if (!empty($this->div_style)) {
- $attrs['style'] = $this->div_style;
- }
-
- $action->element('div', $attrs, null);
- }
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Echo',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Zach Copley',
- 'homepage' => 'http://status.net/wiki/Plugin:Echo',
- 'rawdescription' =>
- _m('Use <a href="http://aboutecho.com/">Echo</a>'.
- ' to add commenting to notice pages.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to add ICBM metadata to HTML pages and report data to GeoURL.org
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Action
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to add ICBM metadata to HTML pages and report data to GeoURL.org
+ *
+ * Adds metadata to notice and profile pages that geourl.org and others
+ * understand. Also, pings geourl.org when a new notice is saved or
+ * a profile is changed.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @seeAlso Location
+ */
+
+class GeoURLPlugin extends Plugin
+{
+ public $ping = 'http://geourl.org/ping/';
+
+ /**
+ * Add extra <meta> headers for certain pages that geourl.org understands
+ *
+ * @param Action $action page being shown
+ *
+ * @return boolean event handler flag
+ */
+
+ function onEndShowHeadElements($action)
+ {
+ $name = $action->trimmed('action');
+
+ $location = null;
+
+ if ($name == 'showstream') {
+ $profile = $action->profile;
+ if (!empty($profile) && !empty($profile->lat) && !empty($profile->lon)) {
+ $location = $profile->lat . ', ' . $profile->lon;
+ }
+ } else if ($name == 'shownotice') {
+ $notice = $action->profile;
+ if (!empty($notice) && !empty($notice->lat) && !empty($notice->lon)) {
+ $location = $notice->lat . ', ' . $notice->lon;
+ }
+ }
+
+ if (!empty($location)) {
+ $action->element('meta', array('name' => 'ICBM',
+ 'content' => $location));
+ $action->element('meta', array('name' => 'DC.title',
+ 'content' => $action->title()));
+ }
+
+ return true;
+ }
+
+ /**
+ * Report local notices to GeoURL.org when they're created
+ *
+ * @param Notice &$notice queued notice
+ *
+ * @return boolean event handler flag
+ */
+
+ function onHandleQueuedNotice(&$notice)
+ {
+ if ($notice->is_local == 1) {
+
+ $request = HTTPClient::start();
+
+ $url = common_local_url('shownotice',
+ array('notice' => $notice->id));
+
+ try {
+ $request->post($this->ping,
+ null,
+ array('p' => $url));
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_WARNING,
+ "GeoURL.org ping failed for '$url' ($this->ping)");
+ }
+ }
+
+ return true;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'GeoURL',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:GeoURL',
+ 'rawdescription' =>
+ _m('Ping <a href="http://geourl.org/">GeoURL</a> when '.
+ 'new geolocation-enhanced notices are posted.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to add ICBM metadata to HTML pages and report data to GeoURL.org
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Action
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to add ICBM metadata to HTML pages and report data to GeoURL.org
- *
- * Adds metadata to notice and profile pages that geourl.org and others
- * understand. Also, pings geourl.org when a new notice is saved or
- * a profile is changed.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @seeAlso Location
- */
-
-class GeoURLPlugin extends Plugin
-{
- public $ping = 'http://geourl.org/ping/';
-
- /**
- * Add extra <meta> headers for certain pages that geourl.org understands
- *
- * @param Action $action page being shown
- *
- * @return boolean event handler flag
- */
-
- function onEndShowHeadElements($action)
- {
- $name = $action->trimmed('action');
-
- $location = null;
-
- if ($name == 'showstream') {
- $profile = $action->profile;
- if (!empty($profile) && !empty($profile->lat) && !empty($profile->lon)) {
- $location = $profile->lat . ', ' . $profile->lon;
- }
- } else if ($name == 'shownotice') {
- $notice = $action->profile;
- if (!empty($notice) && !empty($notice->lat) && !empty($notice->lon)) {
- $location = $notice->lat . ', ' . $notice->lon;
- }
- }
-
- if (!empty($location)) {
- $action->element('meta', array('name' => 'ICBM',
- 'content' => $location));
- $action->element('meta', array('name' => 'DC.title',
- 'content' => $action->title()));
- }
-
- return true;
- }
-
- /**
- * Report local notices to GeoURL.org when they're created
- *
- * @param Notice &$notice queued notice
- *
- * @return boolean event handler flag
- */
-
- function onHandleQueuedNotice(&$notice)
- {
- if ($notice->is_local == 1) {
-
- $request = HTTPClient::start();
-
- $url = common_local_url('shownotice',
- array('notice' => $notice->id));
-
- try {
- $request->post($this->ping,
- null,
- array('p' => $url));
- } catch (HTTP_Request2_Exception $e) {
- common_log(LOG_WARNING,
- "GeoURL.org ping failed for '$url' ($this->ping)");
- }
- }
-
- return true;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'GeoURL',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:GeoURL',
- 'rawdescription' =>
- _m('Ping <a href="http://geourl.org/">GeoURL</a> when '.
- 'new geolocation-enhanced notices are posted.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to convert string locations to Geonames IDs and vice versa
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Action
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to convert string locations to Geonames IDs and vice versa
+ *
+ * This handles most of the events that Location class emits. It uses
+ * the geonames.org Web service to convert names like 'Montreal, Quebec, Canada'
+ * into IDs and lat/lon pairs.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @seeAlso Location
+ */
+
+class GeonamesPlugin extends Plugin
+{
+ const LOCATION_NS = 1;
+
+ public $host = 'ws.geonames.org';
+ public $username = null;
+ public $token = null;
+ public $expiry = 7776000; // 90-day expiry
+ public $timeout = 2; // Web service timeout in seconds.
+ public $timeoutWindow = 60; // Further lookups in this process will be disabled for N seconds after a timeout.
+ public $cachePrefix = null; // Optional shared memcache prefix override
+ // to share lookups between local instances.
+
+ protected $lastTimeout = null; // timestamp of last web service timeout
+
+ /**
+ * convert a name into a Location object
+ *
+ * @param string $name Name to convert
+ * @param string $language ISO code for anguage the name is in
+ * @param Location &$location Location object (may be null)
+ *
+ * @return boolean whether to continue (results in $location)
+ */
+
+ function onLocationFromName($name, $language, &$location)
+ {
+ $loc = $this->getCache(array('name' => $name,
+ 'language' => $language));
+
+ if ($loc !== false) {
+ $location = $loc;
+ return false;
+ }
+
+ try {
+ $geonames = $this->getGeonames('search',
+ array('maxRows' => 1,
+ 'q' => $name,
+ 'lang' => $language,
+ 'type' => 'xml'));
+ } catch (Exception $e) {
+ $this->log(LOG_WARNING, "Error for $name: " . $e->getMessage());
+ return true;
+ }
+
+ if (count($geonames) == 0) {
+ // no results
+ $this->setCache(array('name' => $name,
+ 'language' => $language),
+ null);
+ return true;
+ }
+
+ $n = $geonames[0];
+
+ $location = new Location();
+
+ $location->lat = $this->canonical($n->lat);
+ $location->lon = $this->canonical($n->lng);
+ $location->names[$language] = (string)$n->name;
+ $location->location_id = (string)$n->geonameId;
+ $location->location_ns = self::LOCATION_NS;
+
+ $this->setCache(array('name' => $name,
+ 'language' => $language),
+ $location);
+
+ // handled, don't continue processing!
+ return false;
+ }
+
+ /**
+ * convert an id into a Location object
+ *
+ * @param string $id Name to convert
+ * @param string $ns Name to convert
+ * @param string $language ISO code for language for results
+ * @param Location &$location Location object (may be null)
+ *
+ * @return boolean whether to continue (results in $location)
+ */
+
+ function onLocationFromId($id, $ns, $language, &$location)
+ {
+ if ($ns != self::LOCATION_NS) {
+ // It's not one of our IDs... keep processing
+ return true;
+ }
+
+ $loc = $this->getCache(array('id' => $id));
+
+ if ($loc !== false) {
+ $location = $loc;
+ return false;
+ }
+
+ try {
+ $geonames = $this->getGeonames('hierarchy',
+ array('geonameId' => $id,
+ 'lang' => $language));
+ } catch (Exception $e) {
+ $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage());
+ return false;
+ }
+
+ $parts = array();
+
+ foreach ($geonames as $level) {
+ if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
+ $parts[] = (string)$level->name;
+ }
+ }
+
+ $last = $geonames[count($geonames)-1];
+
+ if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
+ $parts[] = (string)$last->name;
+ }
+
+ $location = new Location();
+
+ $location->location_id = (string)$last->geonameId;
+ $location->location_ns = self::LOCATION_NS;
+ $location->lat = $this->canonical($last->lat);
+ $location->lon = $this->canonical($last->lng);
+
+ $location->names[$language] = implode(', ', array_reverse($parts));
+
+ $this->setCache(array('id' => (string)$last->geonameId),
+ $location);
+
+ // We're responsible for this namespace; nobody else
+ // can resolve it
+
+ return false;
+ }
+
+ /**
+ * convert a lat/lon pair into a Location object
+ *
+ * Given a lat/lon, we try to find a Location that's around
+ * it or nearby. We prefer populated places (cities, towns, villages).
+ *
+ * @param string $lat Latitude
+ * @param string $lon Longitude
+ * @param string $language ISO code for language for results
+ * @param Location &$location Location object (may be null)
+ *
+ * @return boolean whether to continue (results in $location)
+ */
+
+ function onLocationFromLatLon($lat, $lon, $language, &$location)
+ {
+ // Make sure they're canonical
+
+ $lat = $this->canonical($lat);
+ $lon = $this->canonical($lon);
+
+ $loc = $this->getCache(array('lat' => $lat,
+ 'lon' => $lon));
+
+ if ($loc !== false) {
+ $location = $loc;
+ return false;
+ }
+
+ try {
+ $geonames = $this->getGeonames('findNearbyPlaceName',
+ array('lat' => $lat,
+ 'lng' => $lon,
+ 'lang' => $language));
+ } catch (Exception $e) {
+ $this->log(LOG_WARNING, "Error for coords $lat, $lon: " . $e->getMessage());
+ return true;
+ }
+
+ if (count($geonames) == 0) {
+ // no results
+ $this->setCache(array('lat' => $lat,
+ 'lon' => $lon),
+ null);
+ return true;
+ }
+
+ $n = $geonames[0];
+
+ $parts = array();
+
+ $location = new Location();
+
+ $parts[] = (string)$n->name;
+
+ if (!empty($n->adminName1)) {
+ $parts[] = (string)$n->adminName1;
+ }
+
+ if (!empty($n->countryName)) {
+ $parts[] = (string)$n->countryName;
+ }
+
+ $location->location_id = (string)$n->geonameId;
+ $location->location_ns = self::LOCATION_NS;
+ $location->lat = $this->canonical($n->lat);
+ $location->lon = $this->canonical($n->lng);
+
+ $location->names[$language] = implode(', ', $parts);
+
+ $this->setCache(array('lat' => $lat,
+ 'lon' => $lon),
+ $location);
+
+ // Success! We handled it, so no further processing
+
+ return false;
+ }
+
+ /**
+ * Human-readable name for a location
+ *
+ * Given a location, we try to retrieve a human-readable name
+ * in the target language.
+ *
+ * @param Location $location Location to get the name for
+ * @param string $language ISO code for language to find name in
+ * @param string &$name Place to put the name
+ *
+ * @return boolean whether to continue
+ */
+
+ function onLocationNameLanguage($location, $language, &$name)
+ {
+ if ($location->location_ns != self::LOCATION_NS) {
+ // It's not one of our IDs... keep processing
+ return true;
+ }
+
+ $id = $location->location_id;
+
+ $n = $this->getCache(array('id' => $id,
+ 'language' => $language));
+
+ if ($n !== false) {
+ $name = $n;
+ return false;
+ }
+
+ try {
+ $geonames = $this->getGeonames('hierarchy',
+ array('geonameId' => $id,
+ 'lang' => $language));
+ } catch (Exception $e) {
+ $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage());
+ return false;
+ }
+
+ if (count($geonames) == 0) {
+ $this->setCache(array('id' => $id,
+ 'language' => $language),
+ null);
+ return false;
+ }
+
+ $parts = array();
+
+ foreach ($geonames as $level) {
+ if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
+ $parts[] = (string)$level->name;
+ }
+ }
+
+ $last = $geonames[count($geonames)-1];
+
+ if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
+ $parts[] = (string)$last->name;
+ }
+
+ if (count($parts)) {
+ $name = implode(', ', array_reverse($parts));
+ $this->setCache(array('id' => $id,
+ 'language' => $language),
+ $name);
+ }
+
+ return false;
+ }
+
+ /**
+ * Human-readable URL for a location
+ *
+ * Given a location, we try to retrieve a geonames.org URL.
+ *
+ * @param Location $location Location to get the url for
+ * @param string &$url Place to put the url
+ *
+ * @return boolean whether to continue
+ */
+
+ function onLocationUrl($location, &$url)
+ {
+ if ($location->location_ns != self::LOCATION_NS) {
+ // It's not one of our IDs... keep processing
+ return true;
+ }
+
+ $url = 'http://www.geonames.org/' . $location->location_id;
+
+ // it's been filled, so don't process further.
+ return false;
+ }
+
+ /**
+ * Machine-readable name for a location
+ *
+ * Given a location, we try to retrieve a geonames.org URL.
+ *
+ * @param Location $location Location to get the url for
+ * @param string &$url Place to put the url
+ *
+ * @return boolean whether to continue
+ */
+
+ function onLocationRdfUrl($location, &$url)
+ {
+ if ($location->location_ns != self::LOCATION_NS) {
+ // It's not one of our IDs... keep processing
+ return true;
+ }
+
+ $url = 'http://sws.geonames.org/' . $location->location_id . '/';
+
+ // it's been filled, so don't process further.
+ return false;
+ }
+
+ function getCache($attrs)
+ {
+ $c = common_memcache();
+
+ if (empty($c)) {
+ return null;
+ }
+
+ $key = $this->cacheKey($attrs);
+
+ $value = $c->get($key);
+
+ return $value;
+ }
+
+ function setCache($attrs, $loc)
+ {
+ $c = common_memcache();
+
+ if (empty($c)) {
+ return null;
+ }
+
+ $key = $this->cacheKey($attrs);
+
+ $result = $c->set($key, $loc, 0, time() + $this->expiry);
+
+ return $result;
+ }
+
+ function cacheKey($attrs)
+ {
+ $key = 'geonames:' .
+ implode(',', array_keys($attrs)) . ':'.
+ common_keyize(implode(',', array_values($attrs)));
+ if ($this->cachePrefix) {
+ return $this->cachePrefix . ':' . $key;
+ } else {
+ return common_cache_key($key);
+ }
+ }
+
+ function wsUrl($method, $params)
+ {
+ if (!empty($this->username)) {
+ $params['username'] = $this->username;
+ }
+
+ if (!empty($this->token)) {
+ $params['token'] = $this->token;
+ }
+
+ $str = http_build_query($params, null, '&');
+
+ return 'http://'.$this->host.'/'.$method.'?'.$str;
+ }
+
+ function getGeonames($method, $params)
+ {
+ if ($this->lastTimeout && (time() - $this->lastTimeout < $this->timeoutWindow)) {
+ throw new Exception("skipping due to recent web service timeout");
+ }
+
+ $client = HTTPClient::start();
+ $client->setConfig('connect_timeout', $this->timeout);
+ $client->setConfig('timeout', $this->timeout);
+
+ try {
+ $result = $client->get($this->wsUrl($method, $params));
+ } catch (Exception $e) {
+ common_log(LOG_ERR, __METHOD__ . ": " . $e->getMessage());
+ $this->lastTimeout = time();
+ throw $e;
+ }
+
+ if (!$result->isOk()) {
+ throw new Exception("HTTP error code " . $result->getStatus());
+ }
+
+ $body = $result->getBody();
+
+ if (empty($body)) {
+ throw new Exception("Empty HTTP body in response");
+ }
+
+ // This will throw an exception if the XML is mal-formed
+
+ $document = new SimpleXMLElement($body);
+
+ // No children, usually no results
+
+ $children = $document->children();
+
+ if (count($children) == 0) {
+ return array();
+ }
+
+ if (isset($document->status)) {
+ throw new Exception("Error #".$document->status['value']." ('".$document->status['message']."')");
+ }
+
+ // Array of elements, >0 elements
+
+ return $document->geoname;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Geonames',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:Geonames',
+ 'rawdescription' =>
+ _m('Uses <a href="http://geonames.org/">Geonames</a> service to get human-readable '.
+ 'names for locations based on user-provided lat/long pairs.'));
+ return true;
+ }
+
+ function canonical($coord)
+ {
+ $coord = rtrim($coord, "0");
+ $coord = rtrim($coord, ".");
+
+ return $coord;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to convert string locations to Geonames IDs and vice versa
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Action
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to convert string locations to Geonames IDs and vice versa
- *
- * This handles most of the events that Location class emits. It uses
- * the geonames.org Web service to convert names like 'Montreal, Quebec, Canada'
- * into IDs and lat/lon pairs.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @seeAlso Location
- */
-
-class GeonamesPlugin extends Plugin
-{
- const LOCATION_NS = 1;
-
- public $host = 'ws.geonames.org';
- public $username = null;
- public $token = null;
- public $expiry = 7776000; // 90-day expiry
- public $timeout = 2; // Web service timeout in seconds.
- public $timeoutWindow = 60; // Further lookups in this process will be disabled for N seconds after a timeout.
- public $cachePrefix = null; // Optional shared memcache prefix override
- // to share lookups between local instances.
-
- protected $lastTimeout = null; // timestamp of last web service timeout
-
- /**
- * convert a name into a Location object
- *
- * @param string $name Name to convert
- * @param string $language ISO code for anguage the name is in
- * @param Location &$location Location object (may be null)
- *
- * @return boolean whether to continue (results in $location)
- */
-
- function onLocationFromName($name, $language, &$location)
- {
- $loc = $this->getCache(array('name' => $name,
- 'language' => $language));
-
- if ($loc !== false) {
- $location = $loc;
- return false;
- }
-
- try {
- $geonames = $this->getGeonames('search',
- array('maxRows' => 1,
- 'q' => $name,
- 'lang' => $language,
- 'type' => 'xml'));
- } catch (Exception $e) {
- $this->log(LOG_WARNING, "Error for $name: " . $e->getMessage());
- return true;
- }
-
- if (count($geonames) == 0) {
- // no results
- $this->setCache(array('name' => $name,
- 'language' => $language),
- null);
- return true;
- }
-
- $n = $geonames[0];
-
- $location = new Location();
-
- $location->lat = $this->canonical($n->lat);
- $location->lon = $this->canonical($n->lng);
- $location->names[$language] = (string)$n->name;
- $location->location_id = (string)$n->geonameId;
- $location->location_ns = self::LOCATION_NS;
-
- $this->setCache(array('name' => $name,
- 'language' => $language),
- $location);
-
- // handled, don't continue processing!
- return false;
- }
-
- /**
- * convert an id into a Location object
- *
- * @param string $id Name to convert
- * @param string $ns Name to convert
- * @param string $language ISO code for language for results
- * @param Location &$location Location object (may be null)
- *
- * @return boolean whether to continue (results in $location)
- */
-
- function onLocationFromId($id, $ns, $language, &$location)
- {
- if ($ns != self::LOCATION_NS) {
- // It's not one of our IDs... keep processing
- return true;
- }
-
- $loc = $this->getCache(array('id' => $id));
-
- if ($loc !== false) {
- $location = $loc;
- return false;
- }
-
- try {
- $geonames = $this->getGeonames('hierarchy',
- array('geonameId' => $id,
- 'lang' => $language));
- } catch (Exception $e) {
- $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage());
- return false;
- }
-
- $parts = array();
-
- foreach ($geonames as $level) {
- if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
- $parts[] = (string)$level->name;
- }
- }
-
- $last = $geonames[count($geonames)-1];
-
- if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
- $parts[] = (string)$last->name;
- }
-
- $location = new Location();
-
- $location->location_id = (string)$last->geonameId;
- $location->location_ns = self::LOCATION_NS;
- $location->lat = $this->canonical($last->lat);
- $location->lon = $this->canonical($last->lng);
-
- $location->names[$language] = implode(', ', array_reverse($parts));
-
- $this->setCache(array('id' => (string)$last->geonameId),
- $location);
-
- // We're responsible for this namespace; nobody else
- // can resolve it
-
- return false;
- }
-
- /**
- * convert a lat/lon pair into a Location object
- *
- * Given a lat/lon, we try to find a Location that's around
- * it or nearby. We prefer populated places (cities, towns, villages).
- *
- * @param string $lat Latitude
- * @param string $lon Longitude
- * @param string $language ISO code for language for results
- * @param Location &$location Location object (may be null)
- *
- * @return boolean whether to continue (results in $location)
- */
-
- function onLocationFromLatLon($lat, $lon, $language, &$location)
- {
- // Make sure they're canonical
-
- $lat = $this->canonical($lat);
- $lon = $this->canonical($lon);
-
- $loc = $this->getCache(array('lat' => $lat,
- 'lon' => $lon));
-
- if ($loc !== false) {
- $location = $loc;
- return false;
- }
-
- try {
- $geonames = $this->getGeonames('findNearbyPlaceName',
- array('lat' => $lat,
- 'lng' => $lon,
- 'lang' => $language));
- } catch (Exception $e) {
- $this->log(LOG_WARNING, "Error for coords $lat, $lon: " . $e->getMessage());
- return true;
- }
-
- if (count($geonames) == 0) {
- // no results
- $this->setCache(array('lat' => $lat,
- 'lon' => $lon),
- null);
- return true;
- }
-
- $n = $geonames[0];
-
- $parts = array();
-
- $location = new Location();
-
- $parts[] = (string)$n->name;
-
- if (!empty($n->adminName1)) {
- $parts[] = (string)$n->adminName1;
- }
-
- if (!empty($n->countryName)) {
- $parts[] = (string)$n->countryName;
- }
-
- $location->location_id = (string)$n->geonameId;
- $location->location_ns = self::LOCATION_NS;
- $location->lat = $this->canonical($n->lat);
- $location->lon = $this->canonical($n->lng);
-
- $location->names[$language] = implode(', ', $parts);
-
- $this->setCache(array('lat' => $lat,
- 'lon' => $lon),
- $location);
-
- // Success! We handled it, so no further processing
-
- return false;
- }
-
- /**
- * Human-readable name for a location
- *
- * Given a location, we try to retrieve a human-readable name
- * in the target language.
- *
- * @param Location $location Location to get the name for
- * @param string $language ISO code for language to find name in
- * @param string &$name Place to put the name
- *
- * @return boolean whether to continue
- */
-
- function onLocationNameLanguage($location, $language, &$name)
- {
- if ($location->location_ns != self::LOCATION_NS) {
- // It's not one of our IDs... keep processing
- return true;
- }
-
- $id = $location->location_id;
-
- $n = $this->getCache(array('id' => $id,
- 'language' => $language));
-
- if ($n !== false) {
- $name = $n;
- return false;
- }
-
- try {
- $geonames = $this->getGeonames('hierarchy',
- array('geonameId' => $id,
- 'lang' => $language));
- } catch (Exception $e) {
- $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage());
- return false;
- }
-
- if (count($geonames) == 0) {
- $this->setCache(array('id' => $id,
- 'language' => $language),
- null);
- return false;
- }
-
- $parts = array();
-
- foreach ($geonames as $level) {
- if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
- $parts[] = (string)$level->name;
- }
- }
-
- $last = $geonames[count($geonames)-1];
-
- if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) {
- $parts[] = (string)$last->name;
- }
-
- if (count($parts)) {
- $name = implode(', ', array_reverse($parts));
- $this->setCache(array('id' => $id,
- 'language' => $language),
- $name);
- }
-
- return false;
- }
-
- /**
- * Human-readable URL for a location
- *
- * Given a location, we try to retrieve a geonames.org URL.
- *
- * @param Location $location Location to get the url for
- * @param string &$url Place to put the url
- *
- * @return boolean whether to continue
- */
-
- function onLocationUrl($location, &$url)
- {
- if ($location->location_ns != self::LOCATION_NS) {
- // It's not one of our IDs... keep processing
- return true;
- }
-
- $url = 'http://www.geonames.org/' . $location->location_id;
-
- // it's been filled, so don't process further.
- return false;
- }
-
- /**
- * Machine-readable name for a location
- *
- * Given a location, we try to retrieve a geonames.org URL.
- *
- * @param Location $location Location to get the url for
- * @param string &$url Place to put the url
- *
- * @return boolean whether to continue
- */
-
- function onLocationRdfUrl($location, &$url)
- {
- if ($location->location_ns != self::LOCATION_NS) {
- // It's not one of our IDs... keep processing
- return true;
- }
-
- $url = 'http://sws.geonames.org/' . $location->location_id . '/';
-
- // it's been filled, so don't process further.
- return false;
- }
-
- function getCache($attrs)
- {
- $c = common_memcache();
-
- if (empty($c)) {
- return null;
- }
-
- $key = $this->cacheKey($attrs);
-
- $value = $c->get($key);
-
- return $value;
- }
-
- function setCache($attrs, $loc)
- {
- $c = common_memcache();
-
- if (empty($c)) {
- return null;
- }
-
- $key = $this->cacheKey($attrs);
-
- $result = $c->set($key, $loc, 0, time() + $this->expiry);
-
- return $result;
- }
-
- function cacheKey($attrs)
- {
- $key = 'geonames:' .
- implode(',', array_keys($attrs)) . ':'.
- common_keyize(implode(',', array_values($attrs)));
- if ($this->cachePrefix) {
- return $this->cachePrefix . ':' . $key;
- } else {
- return common_cache_key($key);
- }
- }
-
- function wsUrl($method, $params)
- {
- if (!empty($this->username)) {
- $params['username'] = $this->username;
- }
-
- if (!empty($this->token)) {
- $params['token'] = $this->token;
- }
-
- $str = http_build_query($params, null, '&');
-
- return 'http://'.$this->host.'/'.$method.'?'.$str;
- }
-
- function getGeonames($method, $params)
- {
- if ($this->lastTimeout && (time() - $this->lastTimeout < $this->timeoutWindow)) {
- throw new Exception("skipping due to recent web service timeout");
- }
-
- $client = HTTPClient::start();
- $client->setConfig('connect_timeout', $this->timeout);
- $client->setConfig('timeout', $this->timeout);
-
- try {
- $result = $client->get($this->wsUrl($method, $params));
- } catch (Exception $e) {
- common_log(LOG_ERR, __METHOD__ . ": " . $e->getMessage());
- $this->lastTimeout = time();
- throw $e;
- }
-
- if (!$result->isOk()) {
- throw new Exception("HTTP error code " . $result->getStatus());
- }
-
- $body = $result->getBody();
-
- if (empty($body)) {
- throw new Exception("Empty HTTP body in response");
- }
-
- // This will throw an exception if the XML is mal-formed
-
- $document = new SimpleXMLElement($body);
-
- // No children, usually no results
-
- $children = $document->children();
-
- if (count($children) == 0) {
- return array();
- }
-
- if (isset($document->status)) {
- throw new Exception("Error #".$document->status['value']." ('".$document->status['message']."')");
- }
-
- // Array of elements, >0 elements
-
- return $document->geoname;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Geonames',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:Geonames',
- 'rawdescription' =>
- _m('Uses <a href="http://geonames.org/">Geonames</a> service to get human-readable '.
- 'names for locations based on user-provided lat/long pairs.'));
- return true;
- }
-
- function canonical($coord)
- {
- $coord = rtrim($coord, "0");
- $coord = rtrim($coord, ".");
-
- return $coord;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to use Google Analytics
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2008 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to use Google Analytics
+ *
+ * This plugin will spoot out the correct JavaScript spell to invoke Google Analytics on a page.
+ *
+ * Note that Google Analytics is not compatible with the Franklin Street Statement; consider using
+ * Piwik (http://www.piwik.org/) instead!
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class GoogleAnalyticsPlugin extends Plugin
+{
+ var $code = null;
+
+ function __construct($code=null)
+ {
+ $this->code = $code;
+ parent::__construct();
+ }
+
+ function onEndShowScripts($action)
+ {
+ $js1 = 'var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");'.
+ 'document.write(unescape("%3Cscript src=\'" + gaJsHost + "google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3E"));';
+ $js2 = sprintf('try{'.
+ 'var pageTracker = _gat._getTracker("%s");'.
+ 'pageTracker._trackPageview();'.
+ '} catch(err) {}',
+ $this->code);
+ $action->inlineScript($js1);
+ $action->inlineScript($js2);
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'GoogleAnalytics',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:GoogleAnalytics',
+ 'rawdescription' =>
+ _m('Use <a href="http://www.google.com/analytics/">Google Analytics</a>'.
+ ' to track Web access.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to use Google Analytics
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2008 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to use Google Analytics
- *
- * This plugin will spoot out the correct JavaScript spell to invoke Google Analytics on a page.
- *
- * Note that Google Analytics is not compatible with the Franklin Street Statement; consider using
- * Piwik (http://www.piwik.org/) instead!
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class GoogleAnalyticsPlugin extends Plugin
-{
- var $code = null;
-
- function __construct($code=null)
- {
- $this->code = $code;
- parent::__construct();
- }
-
- function onEndShowScripts($action)
- {
- $js1 = 'var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");'.
- 'document.write(unescape("%3Cscript src=\'" + gaJsHost + "google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3E"));';
- $js2 = sprintf('try{'.
- 'var pageTracker = _gat._getTracker("%s");'.
- 'pageTracker._trackPageview();'.
- '} catch(err) {}',
- $this->code);
- $action->inlineScript($js1);
- $action->inlineScript($js2);
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'GoogleAnalytics',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:GoogleAnalytics',
- 'rawdescription' =>
- _m('Use <a href="http://www.google.com/analytics/">Google Analytics</a>'.
- ' to track Web access.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to do linkbacks for notices containing links
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+require_once('Auth/Yadis/Yadis.php');
+
+define('LINKBACKPLUGIN_VERSION', '0.1');
+
+/**
+ * Plugin to do linkbacks for notices containing URLs
+ *
+ * After new notices are saved, we check their text for URLs. If there
+ * are URLs, we test each URL to see if it supports any
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class LinkbackPlugin extends Plugin
+{
+ var $notice = null;
+
+ function __construct()
+ {
+ parent::__construct();
+ }
+
+ function onHandleQueuedNotice($notice)
+ {
+ if ($notice->is_local == 1) {
+ // Try to avoid actually mucking with the
+ // notice content
+ $c = $notice->content;
+ $this->notice = $notice;
+ // Ignoring results
+ common_replace_urls_callback($c,
+ array($this, 'linkbackUrl'));
+ }
+ return true;
+ }
+
+ function linkbackUrl($url)
+ {
+ common_log(LOG_DEBUG,"Attempting linkback for " . $url);
+
+ $orig = $url;
+ $url = htmlspecialchars_decode($orig);
+ $scheme = parse_url($url, PHP_URL_SCHEME);
+ if (!in_array($scheme, array('http', 'https'))) {
+ return $orig;
+ }
+
+ // XXX: Do a HEAD first to save some time/bandwidth
+
+ $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+
+ $result = $fetcher->get($url,
+ array('User-Agent: ' . $this->userAgent(),
+ 'Accept: application/html+xml,text/html'));
+
+ if (!in_array($result->status, array('200', '206'))) {
+ return $orig;
+ }
+
+ $pb = null;
+ $tb = null;
+
+ if (array_key_exists('X-Pingback', $result->headers)) {
+ $pb = $result->headers['X-Pingback'];
+ } else if (preg_match('/<link rel="pingback" href="([^"]+)" ?\/?>/',
+ $result->body,
+ $match)) {
+ $pb = $match[1];
+ }
+
+ if (!empty($pb)) {
+ $this->pingback($result->final_url, $pb);
+ } else {
+ $tb = $this->getTrackback($result->body, $result->final_url);
+ if (!empty($tb)) {
+ $this->trackback($result->final_url, $tb);
+ }
+ }
+
+ return $orig;
+ }
+
+ function pingback($url, $endpoint)
+ {
+ $args = array($this->notice->uri, $url);
+
+ if (!extension_loaded('xmlrpc')) {
+ if (!dl('xmlrpc.so')) {
+ common_log(LOG_ERR, "Can't pingback; xmlrpc extension not available.");
+ return;
+ }
+ }
+
+ $request = HTTPClient::start();
+ try {
+ $response = $request->post($endpoint,
+ array('Content-Type: text/xml'),
+ xmlrpc_encode_request('pingback.ping', $args));
+ $response = xmlrpc_decode($response->getBody());
+ if (xmlrpc_is_fault($response)) {
+ common_log(LOG_WARNING,
+ "Pingback error for '$url' ($endpoint): ".
+ "$response[faultString] ($response[faultCode])");
+ } else {
+ common_log(LOG_INFO,
+ "Pingback success for '$url' ($endpoint): ".
+ "'$response'");
+ }
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_WARNING,
+ "Pingback request failed for '$url' ($endpoint)");
+ }
+ }
+
+ // Largely cadged from trackback_cls.php by
+ // Ran Aroussi <ran@blogish.org>, GPL2 or any later version
+ // http://phptrackback.sourceforge.net/
+
+ function getTrackback($text, $url)
+ {
+ if (preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $text, $match, PREG_SET_ORDER)) {
+ for ($i = 0; $i < count($match); $i++) {
+ if (preg_match('|dc:identifier="' . preg_quote($url) . '"|ms', $match[$i][1])) {
+ $rdf_array[] = trim($match[$i][1]);
+ }
+ }
+
+ // Loop through the RDFs array and extract trackback URIs
+
+ $tb_array = array(); // <- holds list of trackback URIs
+
+ if (!empty($rdf_array)) {
+
+ for ($i = 0; $i < count($rdf_array); $i++) {
+ if (preg_match('/trackback:ping="([^"]+)"/', $rdf_array[$i], $array)) {
+ $tb_array[] = trim($array[1]);
+ break;
+ }
+ }
+ }
+
+ // Return Trackbacks
+
+ if (empty($tb_array)) {
+ return null;
+ } else {
+ return $tb_array[0];
+ }
+ }
+
+ if (preg_match_all('/(<a[^>]*?rel=[\'"]trackback[\'"][^>]*?>)/', $text, $match)) {
+ foreach ($match[1] as $atag) {
+ if (preg_match('/href=[\'"]([^\'"]*?)[\'"]/', $atag, $url)) {
+ return $url[1];
+ }
+ }
+ }
+
+ return null;
+
+ }
+
+ function trackback($url, $endpoint)
+ {
+ $profile = $this->notice->getProfile();
+
+ $args = array('title' => sprintf(_('%1$s\'s status on %2$s'),
+ $profile->nickname,
+ common_exact_date($this->notice->created)),
+ 'excerpt' => $this->notice->content,
+ 'url' => $this->notice->uri,
+ 'blog_name' => $profile->nickname);
+
+ $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+
+ $result = $fetcher->post($endpoint,
+ http_build_query($args),
+ array('User-Agent: ' . $this->userAgent()));
+
+ if ($result->status != '200') {
+ common_log(LOG_WARNING,
+ "Trackback error for '$url' ($endpoint): ".
+ "$result->body");
+ } else {
+ common_log(LOG_INFO,
+ "Trackback success for '$url' ($endpoint): ".
+ "'$result->body'");
+ }
+ }
+
+ function userAgent()
+ {
+ return 'LinkbackPlugin/'.LINKBACKPLUGIN_VERSION .
+ ' StatusNet/' . STATUSNET_VERSION;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Linkback',
+ 'version' => LINKBACKPLUGIN_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:Linkback',
+ 'rawdescription' =>
+ _m('Notify blog authors when their posts have been linked in '.
+ 'microblog notices using '.
+ '<a href="http://www.hixie.ch/specs/pingback/pingback">Pingback</a> '.
+ 'or <a href="http://www.movabletype.org/docs/mttrackback.html">Trackback</a> protocols.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to do linkbacks for notices containing links
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-require_once('Auth/Yadis/Yadis.php');
-
-define('LINKBACKPLUGIN_VERSION', '0.1');
-
-/**
- * Plugin to do linkbacks for notices containing URLs
- *
- * After new notices are saved, we check their text for URLs. If there
- * are URLs, we test each URL to see if it supports any
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class LinkbackPlugin extends Plugin
-{
- var $notice = null;
-
- function __construct()
- {
- parent::__construct();
- }
-
- function onHandleQueuedNotice($notice)
- {
- if ($notice->is_local == 1) {
- // Try to avoid actually mucking with the
- // notice content
- $c = $notice->content;
- $this->notice = $notice;
- // Ignoring results
- common_replace_urls_callback($c,
- array($this, 'linkbackUrl'));
- }
- return true;
- }
-
- function linkbackUrl($url)
- {
- common_log(LOG_DEBUG,"Attempting linkback for " . $url);
-
- $orig = $url;
- $url = htmlspecialchars_decode($orig);
- $scheme = parse_url($url, PHP_URL_SCHEME);
- if (!in_array($scheme, array('http', 'https'))) {
- return $orig;
- }
-
- // XXX: Do a HEAD first to save some time/bandwidth
-
- $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
-
- $result = $fetcher->get($url,
- array('User-Agent: ' . $this->userAgent(),
- 'Accept: application/html+xml,text/html'));
-
- if (!in_array($result->status, array('200', '206'))) {
- return $orig;
- }
-
- $pb = null;
- $tb = null;
-
- if (array_key_exists('X-Pingback', $result->headers)) {
- $pb = $result->headers['X-Pingback'];
- } else if (preg_match('/<link rel="pingback" href="([^"]+)" ?\/?>/',
- $result->body,
- $match)) {
- $pb = $match[1];
- }
-
- if (!empty($pb)) {
- $this->pingback($result->final_url, $pb);
- } else {
- $tb = $this->getTrackback($result->body, $result->final_url);
- if (!empty($tb)) {
- $this->trackback($result->final_url, $tb);
- }
- }
-
- return $orig;
- }
-
- function pingback($url, $endpoint)
- {
- $args = array($this->notice->uri, $url);
-
- if (!extension_loaded('xmlrpc')) {
- if (!dl('xmlrpc.so')) {
- common_log(LOG_ERR, "Can't pingback; xmlrpc extension not available.");
- return;
- }
- }
-
- $request = HTTPClient::start();
- try {
- $response = $request->post($endpoint,
- array('Content-Type: text/xml'),
- xmlrpc_encode_request('pingback.ping', $args));
- $response = xmlrpc_decode($response->getBody());
- if (xmlrpc_is_fault($response)) {
- common_log(LOG_WARNING,
- "Pingback error for '$url' ($endpoint): ".
- "$response[faultString] ($response[faultCode])");
- } else {
- common_log(LOG_INFO,
- "Pingback success for '$url' ($endpoint): ".
- "'$response'");
- }
- } catch (HTTP_Request2_Exception $e) {
- common_log(LOG_WARNING,
- "Pingback request failed for '$url' ($endpoint)");
- }
- }
-
- // Largely cadged from trackback_cls.php by
- // Ran Aroussi <ran@blogish.org>, GPL2 or any later version
- // http://phptrackback.sourceforge.net/
-
- function getTrackback($text, $url)
- {
- if (preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $text, $match, PREG_SET_ORDER)) {
- for ($i = 0; $i < count($match); $i++) {
- if (preg_match('|dc:identifier="' . preg_quote($url) . '"|ms', $match[$i][1])) {
- $rdf_array[] = trim($match[$i][1]);
- }
- }
-
- // Loop through the RDFs array and extract trackback URIs
-
- $tb_array = array(); // <- holds list of trackback URIs
-
- if (!empty($rdf_array)) {
-
- for ($i = 0; $i < count($rdf_array); $i++) {
- if (preg_match('/trackback:ping="([^"]+)"/', $rdf_array[$i], $array)) {
- $tb_array[] = trim($array[1]);
- break;
- }
- }
- }
-
- // Return Trackbacks
-
- if (empty($tb_array)) {
- return null;
- } else {
- return $tb_array[0];
- }
- }
-
- if (preg_match_all('/(<a[^>]*?rel=[\'"]trackback[\'"][^>]*?>)/', $text, $match)) {
- foreach ($match[1] as $atag) {
- if (preg_match('/href=[\'"]([^\'"]*?)[\'"]/', $atag, $url)) {
- return $url[1];
- }
- }
- }
-
- return null;
-
- }
-
- function trackback($url, $endpoint)
- {
- $profile = $this->notice->getProfile();
-
- $args = array('title' => sprintf(_('%1$s\'s status on %2$s'),
- $profile->nickname,
- common_exact_date($this->notice->created)),
- 'excerpt' => $this->notice->content,
- 'url' => $this->notice->uri,
- 'blog_name' => $profile->nickname);
-
- $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
-
- $result = $fetcher->post($endpoint,
- http_build_query($args),
- array('User-Agent: ' . $this->userAgent()));
-
- if ($result->status != '200') {
- common_log(LOG_WARNING,
- "Trackback error for '$url' ($endpoint): ".
- "$result->body");
- } else {
- common_log(LOG_INFO,
- "Trackback success for '$url' ($endpoint): ".
- "'$result->body'");
- }
- }
-
- function userAgent()
- {
- return 'LinkbackPlugin/'.LINKBACKPLUGIN_VERSION .
- ' StatusNet/' . STATUSNET_VERSION;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Linkback',
- 'version' => LINKBACKPLUGIN_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:Linkback',
- 'rawdescription' =>
- _m('Notify blog authors when their posts have been linked in '.
- 'microblog notices using '.
- '<a href="http://www.hixie.ch/specs/pingback/pingback">Pingback</a> '.
- 'or <a href="http://www.movabletype.org/docs/mttrackback.html">Trackback</a> protocols.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for memcache
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to use memcache for the cache interface
+ *
+ * This used to be encoded as config-variable options in the core code;
+ * it's now broken out to a separate plugin. The same interface can be
+ * implemented by other plugins.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class MemcachePlugin extends Plugin
+{
+ static $cacheInitialized = false;
+
+ private $_conn = null;
+ public $servers = array('127.0.0.1;11211');
+
+ public $compressThreshold = 20480;
+ public $compressMinSaving = 0.2;
+
+ public $persistent = null;
+
+ public $defaultExpiry = 86400; // 24h
+
+ /**
+ * Initialize the plugin
+ *
+ * Note that onStartCacheGet() may have been called before this!
+ *
+ * @return boolean flag value
+ */
+
+ function onInitializePlugin()
+ {
+ if (self::$cacheInitialized) {
+ $this->persistent = true;
+ } else {
+ // If we're a parent command-line process we need
+ // to be able to close out the connection after
+ // forking, so disable persistence.
+ //
+ // We'll turn it back on again the second time
+ // through which will either be in a child process,
+ // or a single-process script which is switching
+ // configurations.
+ $this->persistent = (php_sapi_name() == 'cli') ? false : true;
+ }
+ $this->_ensureConn();
+ self::$cacheInitialized = true;
+ return true;
+ }
+
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheGet(&$key, &$value)
+ {
+ $this->_ensureConn();
+ $value = $this->_conn->get($key);
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag empty or Cache::COMPRESSED
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $this->_ensureConn();
+ if ($expiry === null) {
+ $expiry = $this->defaultExpiry;
+ }
+ $success = $this->_conn->set($key, $value, $this->flag(intval($flag)), $expiry);
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+ return false;
+ }
+
+ /**
+ * Atomically increment an existing numeric key value.
+ * Existing expiration time will not be changed.
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param int &$step in; Amount to increment (default 1)
+ * @param mixed &$value out; Incremented value, or false if key not set.
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheIncrement(&$key, &$step, &$value)
+ {
+ $this->_ensureConn();
+ $value = $this->_conn->increment($key, $step);
+ Event::handle('EndCacheIncrement', array($key, $step, $value));
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $this->_ensureConn();
+ $success = $this->_conn->delete($key);
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+
+ function onStartCacheReconnect(&$success)
+ {
+ if (empty($this->_conn)) {
+ // nothing to do
+ return true;
+ }
+ if ($this->persistent) {
+ common_log(LOG_ERR, "Cannot close persistent memcached connection");
+ $success = false;
+ } else {
+ common_log(LOG_INFO, "Closing memcached connection");
+ $success = $this->_conn->close();
+ $this->_conn = null;
+ }
+ return false;
+ }
+
+ /**
+ * Ensure that a connection exists
+ *
+ * Checks the instance $_conn variable and connects
+ * if it is empty.
+ *
+ * @return void
+ */
+
+ private function _ensureConn()
+ {
+ if (empty($this->_conn)) {
+ $this->_conn = new Memcache();
+
+ if (is_array($this->servers)) {
+ $servers = $this->servers;
+ } else {
+ $servers = array($this->servers);
+ }
+ foreach ($servers as $server) {
+ if (strpos($server, ';') !== false) {
+ list($host, $port) = explode(';', $server);
+ } else {
+ $host = $server;
+ $port = 11211;
+ }
+
+ $this->_conn->addServer($host, $port, $this->persistent);
+ }
+
+ // Compress items stored in the cache if they're over threshold in size
+ // (default 2KiB) and the compression would save more than min savings
+ // ratio (default 0.2).
+
+ // Allows the cache to store objects larger than 1MB (if they
+ // compress to less than 1MB), and improves cache memory efficiency.
+
+ $this->_conn->setCompressThreshold($this->compressThreshold,
+ $this->compressMinSaving);
+ }
+ }
+
+ /**
+ * Translate general flags to Memcached-specific flags
+ * @param int $flag
+ * @return int
+ */
+ protected function flag($flag)
+ {
+ $out = 0;
+ if ($flag & Cache::COMPRESSED == Cache::COMPRESSED) {
+ $out |= MEMCACHE_COMPRESSED;
+ }
+ return $out;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Memcache',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou, Craig Andrews',
+ 'homepage' => 'http://status.net/wiki/Plugin:Memcache',
+ 'rawdescription' =>
+ _m('Use <a href="http://memcached.org/">Memcached</a> to cache query results.'));
+ return true;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009, StatusNet, Inc.
- *
- * Plugin to implement cache interface for memcache
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * A plugin to use memcache for the cache interface
- *
- * This used to be encoded as config-variable options in the core code;
- * it's now broken out to a separate plugin. The same interface can be
- * implemented by other plugins.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class MemcachePlugin extends Plugin
-{
- static $cacheInitialized = false;
-
- private $_conn = null;
- public $servers = array('127.0.0.1;11211');
-
- public $compressThreshold = 20480;
- public $compressMinSaving = 0.2;
-
- public $persistent = null;
-
- public $defaultExpiry = 86400; // 24h
-
- /**
- * Initialize the plugin
- *
- * Note that onStartCacheGet() may have been called before this!
- *
- * @return boolean flag value
- */
-
- function onInitializePlugin()
- {
- if (self::$cacheInitialized) {
- $this->persistent = true;
- } else {
- // If we're a parent command-line process we need
- // to be able to close out the connection after
- // forking, so disable persistence.
- //
- // We'll turn it back on again the second time
- // through which will either be in a child process,
- // or a single-process script which is switching
- // configurations.
- $this->persistent = (php_sapi_name() == 'cli') ? false : true;
- }
- $this->_ensureConn();
- self::$cacheInitialized = true;
- return true;
- }
-
- /**
- * Get a value associated with a key
- *
- * The value should have been set previously.
- *
- * @param string &$key in; Lookup key
- * @param mixed &$value out; value associated with key
- *
- * @return boolean hook success
- */
-
- function onStartCacheGet(&$key, &$value)
- {
- $this->_ensureConn();
- $value = $this->_conn->get($key);
- Event::handle('EndCacheGet', array($key, &$value));
- return false;
- }
-
- /**
- * Associate a value with a key
- *
- * @param string &$key in; Key to use for lookups
- * @param mixed &$value in; Value to associate
- * @param integer &$flag in; Flag empty or Cache::COMPRESSED
- * @param integer &$expiry in; Expiry (passed through to Memcache)
- * @param boolean &$success out; Whether the set was successful
- *
- * @return boolean hook success
- */
-
- function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
- {
- $this->_ensureConn();
- if ($expiry === null) {
- $expiry = $this->defaultExpiry;
- }
- $success = $this->_conn->set($key, $value, $this->flag(intval($flag)), $expiry);
- Event::handle('EndCacheSet', array($key, $value, $flag,
- $expiry));
- return false;
- }
-
- /**
- * Atomically increment an existing numeric key value.
- * Existing expiration time will not be changed.
- *
- * @param string &$key in; Key to use for lookups
- * @param int &$step in; Amount to increment (default 1)
- * @param mixed &$value out; Incremented value, or false if key not set.
- *
- * @return boolean hook success
- */
- function onStartCacheIncrement(&$key, &$step, &$value)
- {
- $this->_ensureConn();
- $value = $this->_conn->increment($key, $step);
- Event::handle('EndCacheIncrement', array($key, $step, $value));
- return false;
- }
-
- /**
- * Delete a value associated with a key
- *
- * @param string &$key in; Key to lookup
- * @param boolean &$success out; whether it worked
- *
- * @return boolean hook success
- */
-
- function onStartCacheDelete(&$key, &$success)
- {
- $this->_ensureConn();
- $success = $this->_conn->delete($key);
- Event::handle('EndCacheDelete', array($key));
- return false;
- }
-
- function onStartCacheReconnect(&$success)
- {
- if (empty($this->_conn)) {
- // nothing to do
- return true;
- }
- if ($this->persistent) {
- common_log(LOG_ERR, "Cannot close persistent memcached connection");
- $success = false;
- } else {
- common_log(LOG_INFO, "Closing memcached connection");
- $success = $this->_conn->close();
- $this->_conn = null;
- }
- return false;
- }
-
- /**
- * Ensure that a connection exists
- *
- * Checks the instance $_conn variable and connects
- * if it is empty.
- *
- * @return void
- */
-
- private function _ensureConn()
- {
- if (empty($this->_conn)) {
- $this->_conn = new Memcache();
-
- if (is_array($this->servers)) {
- $servers = $this->servers;
- } else {
- $servers = array($this->servers);
- }
- foreach ($servers as $server) {
- if (strpos($server, ';') !== false) {
- list($host, $port) = explode(';', $server);
- } else {
- $host = $server;
- $port = 11211;
- }
-
- $this->_conn->addServer($host, $port, $this->persistent);
- }
-
- // Compress items stored in the cache if they're over threshold in size
- // (default 2KiB) and the compression would save more than min savings
- // ratio (default 0.2).
-
- // Allows the cache to store objects larger than 1MB (if they
- // compress to less than 1MB), and improves cache memory efficiency.
-
- $this->_conn->setCompressThreshold($this->compressThreshold,
- $this->compressMinSaving);
- }
- }
-
- /**
- * Translate general flags to Memcached-specific flags
- * @param int $flag
- * @return int
- */
- protected function flag($flag)
- {
- $out = 0;
- if ($flag & Cache::COMPRESSED == Cache::COMPRESSED) {
- $out |= MEMCACHE_COMPRESSED;
- }
- return $out;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Memcache',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou, Craig Andrews',
- 'homepage' => 'http://status.net/wiki/Plugin:Memcache',
- 'rawdescription' =>
- _m('Use <a href="http://memcached.org/">Memcached</a> to cache query results.'));
- return true;
- }
-}
-
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for memcached
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to use memcached for the cache interface
+ *
+ * This used to be encoded as config-variable options in the core code;
+ * it's now broken out to a separate plugin. The same interface can be
+ * implemented by other plugins.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @author Craig Andrews <candrews@integralblue.com>
+ * @copyright 2009 StatusNet, Inc.
+ * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class MemcachedPlugin extends Plugin
+{
+ static $cacheInitialized = false;
+
+ private $_conn = null;
+ public $servers = array('127.0.0.1;11211');
+
+ public $defaultExpiry = 86400; // 24h
+
+ /**
+ * Initialize the plugin
+ *
+ * Note that onStartCacheGet() may have been called before this!
+ *
+ * @return boolean flag value
+ */
+
+ function onInitializePlugin()
+ {
+ $this->_ensureConn();
+ self::$cacheInitialized = true;
+ return true;
+ }
+
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheGet(&$key, &$value)
+ {
+ $this->_ensureConn();
+ $value = $this->_conn->get($key);
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag empty or Cache::COMPRESSED
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $this->_ensureConn();
+ if ($expiry === null) {
+ $expiry = $this->defaultExpiry;
+ }
+ $success = $this->_conn->set($key, $value, $expiry);
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+ return false;
+ }
+
+ /**
+ * Atomically increment an existing numeric key value.
+ * Existing expiration time will not be changed.
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param int &$step in; Amount to increment (default 1)
+ * @param mixed &$value out; Incremented value, or false if key not set.
+ *
+ * @return boolean hook success
+ */
+ function onStartCacheIncrement(&$key, &$step, &$value)
+ {
+ $this->_ensureConn();
+ $value = $this->_conn->increment($key, $step);
+ Event::handle('EndCacheIncrement', array($key, $step, $value));
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $this->_ensureConn();
+ $success = $this->_conn->delete($key);
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+
+ function onStartCacheReconnect(&$success)
+ {
+ // nothing to do
+ return true;
+ }
+
+ /**
+ * Ensure that a connection exists
+ *
+ * Checks the instance $_conn variable and connects
+ * if it is empty.
+ *
+ * @return void
+ */
+
+ private function _ensureConn()
+ {
+ if (empty($this->_conn)) {
+ $this->_conn = new Memcached(common_config('site', 'nickname'));
+
+ if (!count($this->_conn->getServerList())) {
+ if (is_array($this->servers)) {
+ $servers = $this->servers;
+ } else {
+ $servers = array($this->servers);
+ }
+ foreach ($servers as $server) {
+ if (strpos($server, ';') !== false) {
+ list($host, $port) = explode(';', $server);
+ } else {
+ $host = $server;
+ $port = 11211;
+ }
+
+ $this->_conn->addServer($host, $port);
+ }
+
+ // Compress items stored in the cache.
+
+ // Allows the cache to store objects larger than 1MB (if they
+ // compress to less than 1MB), and improves cache memory efficiency.
+
+ $this->_conn->setOption(Memcached::OPT_COMPRESSION, true);
+ }
+ }
+ }
+
+ /**
+ * Translate general flags to Memcached-specific flags
+ * @param int $flag
+ * @return int
+ */
+ protected function flag($flag)
+ {
+ //no flags are presently supported
+ return $flag;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Memcached',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou, Craig Andrews',
+ 'homepage' => 'http://status.net/wiki/Plugin:Memcached',
+ 'rawdescription' =>
+ _m('Use <a href="http://memcached.org/">Memcached</a> to cache query results.'));
+ return true;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009, StatusNet, Inc.
- *
- * Plugin to implement cache interface for memcached
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @author Craig Andrews <candrews@integralblue.com>
- * @copyright 2009 StatusNet, Inc.
- * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * A plugin to use memcached for the cache interface
- *
- * This used to be encoded as config-variable options in the core code;
- * it's now broken out to a separate plugin. The same interface can be
- * implemented by other plugins.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @author Craig Andrews <candrews@integralblue.com>
- * @copyright 2009 StatusNet, Inc.
- * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class MemcachedPlugin extends Plugin
-{
- static $cacheInitialized = false;
-
- private $_conn = null;
- public $servers = array('127.0.0.1;11211');
-
- public $defaultExpiry = 86400; // 24h
-
- /**
- * Initialize the plugin
- *
- * Note that onStartCacheGet() may have been called before this!
- *
- * @return boolean flag value
- */
-
- function onInitializePlugin()
- {
- $this->_ensureConn();
- self::$cacheInitialized = true;
- return true;
- }
-
- /**
- * Get a value associated with a key
- *
- * The value should have been set previously.
- *
- * @param string &$key in; Lookup key
- * @param mixed &$value out; value associated with key
- *
- * @return boolean hook success
- */
-
- function onStartCacheGet(&$key, &$value)
- {
- $this->_ensureConn();
- $value = $this->_conn->get($key);
- Event::handle('EndCacheGet', array($key, &$value));
- return false;
- }
-
- /**
- * Associate a value with a key
- *
- * @param string &$key in; Key to use for lookups
- * @param mixed &$value in; Value to associate
- * @param integer &$flag in; Flag empty or Cache::COMPRESSED
- * @param integer &$expiry in; Expiry (passed through to Memcache)
- * @param boolean &$success out; Whether the set was successful
- *
- * @return boolean hook success
- */
-
- function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
- {
- $this->_ensureConn();
- if ($expiry === null) {
- $expiry = $this->defaultExpiry;
- }
- $success = $this->_conn->set($key, $value, $expiry);
- Event::handle('EndCacheSet', array($key, $value, $flag,
- $expiry));
- return false;
- }
-
- /**
- * Atomically increment an existing numeric key value.
- * Existing expiration time will not be changed.
- *
- * @param string &$key in; Key to use for lookups
- * @param int &$step in; Amount to increment (default 1)
- * @param mixed &$value out; Incremented value, or false if key not set.
- *
- * @return boolean hook success
- */
- function onStartCacheIncrement(&$key, &$step, &$value)
- {
- $this->_ensureConn();
- $value = $this->_conn->increment($key, $step);
- Event::handle('EndCacheIncrement', array($key, $step, $value));
- return false;
- }
-
- /**
- * Delete a value associated with a key
- *
- * @param string &$key in; Key to lookup
- * @param boolean &$success out; whether it worked
- *
- * @return boolean hook success
- */
-
- function onStartCacheDelete(&$key, &$success)
- {
- $this->_ensureConn();
- $success = $this->_conn->delete($key);
- Event::handle('EndCacheDelete', array($key));
- return false;
- }
-
- function onStartCacheReconnect(&$success)
- {
- // nothing to do
- return true;
- }
-
- /**
- * Ensure that a connection exists
- *
- * Checks the instance $_conn variable and connects
- * if it is empty.
- *
- * @return void
- */
-
- private function _ensureConn()
- {
- if (empty($this->_conn)) {
- $this->_conn = new Memcached(common_config('site', 'nickname'));
-
- if (!count($this->_conn->getServerList())) {
- if (is_array($this->servers)) {
- $servers = $this->servers;
- } else {
- $servers = array($this->servers);
- }
- foreach ($servers as $server) {
- if (strpos($server, ';') !== false) {
- list($host, $port) = explode(';', $server);
- } else {
- $host = $server;
- $port = 11211;
- }
-
- $this->_conn->addServer($host, $port);
- }
-
- // Compress items stored in the cache.
-
- // Allows the cache to store objects larger than 1MB (if they
- // compress to less than 1MB), and improves cache memory efficiency.
-
- $this->_conn->setOption(Memcached::OPT_COMPRESSION, true);
- }
- }
- }
-
- /**
- * Translate general flags to Memcached-specific flags
- * @param int $flag
- * @return int
- */
- protected function flag($flag)
- {
- //no flags are presently supported
- return $flag;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Memcached',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou, Craig Andrews',
- 'homepage' => 'http://status.net/wiki/Plugin:Memcached',
- 'rawdescription' =>
- _m('Use <a href="http://memcached.org/">Memcached</a> to cache query results.'));
- return true;
- }
-}
-
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to use Piwik Analytics
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @copyright 2008 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to use Piwik Analytics (based on the Google Analytics plugin by Evan)
+ *
+ * This plugin will spoot out the correct JavaScript spell to invoke
+ * Piwik Analytics on a page.
+ *
+ * To use this plugin add the following to your config.php
+ *
+ * addPlugin('PiwikAnalytics', array('piwikroot' => 'example.com/piwik/',
+ * 'piwikId' => 'id'));
+ *
+ * Replace 'example.com/piwik/' with the URL to your Piwik installation and
+ * make sure you don't forget the final /.
+ * Replace 'id' with the ID your statusnet installation has in your Piwik
+ * analytics setup - for example '8'.
+ *
+ */
+
+class PiwikAnalyticsPlugin extends Plugin
+{
+ /** the base of your Piwik installation */
+ public $piwikroot = null;
+ /** the Piwik Id of your statusnet installation */
+ public $piwikId = null;
+
+ /**
+ * constructor
+ *
+ * @param string $root Piwik root URL
+ * @param string $id Piwik ID of this app
+ */
+
+ function __construct($root=null, $id=null)
+ {
+ $this->piwikroot = $root;
+ $this->piwikId = $id;
+ parent::__construct();
+ }
+
+ /**
+ * Called when all scripts have been shown
+ *
+ * @param Action $action Current action
+ *
+ * @return boolean ignored
+ */
+
+ function onEndShowScripts($action)
+ {
+ $piwikCode1 = <<<ENDOFPIWIK
+var pkBaseURL = (("https:" == document.location.protocol) ? "https://{$this->piwikroot}" : "http://{$this->piwikroot}");
+document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
+ENDOFPIWIK;
+ $piwikCode2 = <<<ENDOFPIWIK
+try {
+ var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", {$this->piwikId});
+ piwikTracker.trackPageView();
+ piwikTracker.enableLinkTracking();
+} catch( err ) {}
+ENDOFPIWIK;
+
+ $action->inlineScript($piwikCode1);
+ $action->inlineScript($piwikCode2);
+ return true;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'PiwikAnalytics',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Tobias Diekershoff, Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:Piwik',
+ 'rawdescription' =>
+ _m('Use <a href="http://piwik.org/">Piwik</a> Open Source Web analytics software.'));
+ return true;
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to use Piwik Analytics
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
- * @copyright 2008 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to use Piwik Analytics (based on the Google Analytics plugin by Evan)
- *
- * This plugin will spoot out the correct JavaScript spell to invoke
- * Piwik Analytics on a page.
- *
- * To use this plugin add the following to your config.php
- *
- * addPlugin('PiwikAnalytics', array('piwikroot' => 'example.com/piwik/',
- * 'piwikId' => 'id'));
- *
- * Replace 'example.com/piwik/' with the URL to your Piwik installation and
- * make sure you don't forget the final /.
- * Replace 'id' with the ID your statusnet installation has in your Piwik
- * analytics setup - for example '8'.
- *
- */
-
-class PiwikAnalyticsPlugin extends Plugin
-{
- /** the base of your Piwik installation */
- public $piwikroot = null;
- /** the Piwik Id of your statusnet installation */
- public $piwikId = null;
-
- /**
- * constructor
- *
- * @param string $root Piwik root URL
- * @param string $id Piwik ID of this app
- */
-
- function __construct($root=null, $id=null)
- {
- $this->piwikroot = $root;
- $this->piwikId = $id;
- parent::__construct();
- }
-
- /**
- * Called when all scripts have been shown
- *
- * @param Action $action Current action
- *
- * @return boolean ignored
- */
-
- function onEndShowScripts($action)
- {
- $piwikCode1 = <<<ENDOFPIWIK
-var pkBaseURL = (("https:" == document.location.protocol) ? "https://{$this->piwikroot}" : "http://{$this->piwikroot}");
-document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
-ENDOFPIWIK;
- $piwikCode2 = <<<ENDOFPIWIK
-try {
- var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", {$this->piwikId});
- piwikTracker.trackPageView();
- piwikTracker.enableLinkTracking();
-} catch( err ) {}
-ENDOFPIWIK;
-
- $action->inlineScript($piwikCode1);
- $action->inlineScript($piwikCode2);
- return true;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'PiwikAnalytics',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Tobias Diekershoff, Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:Piwik',
- 'rawdescription' =>
- _m('Use <a href="http://piwik.org/">Piwik</a> Open Source Web analytics software.'));
- return true;
- }
-
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to create pretty Spotify URLs
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Nick Holliday <n.g.holliday@gmail.com>
+ * @copyright Nick Holliday
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+define('SPOTIFYPLUGIN_VERSION', '0.1');
+
+/**
+ * Plugin to create pretty Spotify URLs
+ *
+ * The Spotify API is called before the notice is saved to gather artist and track information.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Nick Holliday <n.g.holliday@gmail.com>
+ * @copyright Nick Holliday
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class SpotifyPlugin extends Plugin
+{
+
+ function __construct()
+ {
+ parent::__construct();
+ }
+
+ function onStartNoticeSave($notice)
+ {
+ $notice->rendered = preg_replace_callback('/spotify:[a-z]{5,6}:[a-z0-9]{22}/i',
+ "renderSpotifyURILink",
+ $notice->rendered);
+
+ $notice->rendered = preg_replace_callback('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}<\/a>/i',
+ "renderSpotifyHTTPLink",
+ $notice->rendered);
+
+ return true;
+ }
+
+ function userAgent()
+ {
+ return 'SpotifyPlugin/'.SPOTIFYPLUGIN_VERSION .
+ ' StatusNet/' . STATUSNET_VERSION;
+ }
+}
+
+function doSpotifyLookup($uri, $isArtist)
+{
+ $request = HTTPClient::start();
+ $response = $request->get('http://ws.spotify.com/lookup/1/?uri=' . $uri);
+ if ($response->isOk()) {
+ $xml = simplexml_load_string($response->getBody());
+
+ if($isArtist)
+ return $xml->name;
+ else
+ return $xml->artist->name . ' - ' . $xml->name;
+ }
+}
+
+function renderSpotifyURILink($match)
+{
+ $isArtist = false;
+ if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
+
+ $name = doSpotifyLookup($match[0], $isArtist);
+ return "<a href=\"{$match[0]}\">" . $name . "</a>";
+}
+
+function renderSpotifyHTTPLink($match)
+{
+ $match[0] = preg_replace('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\//i', 'spotify:', $match[0]);
+ $match[0] = preg_replace('/<\/a>/', '', $match[0]);
+ $match[0] = preg_replace('/\//', ':', $match[0]);
+
+ $isArtist = false;
+ if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
+
+ $name = doSpotifyLookup($match[0], $isArtist);
+ return "<a href=\"{$match[0]}\">" . $name . "</a>";
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to create pretty Spotify URLs
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Nick Holliday <n.g.holliday@gmail.com>
- * @copyright Nick Holliday
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-if (!defined('STATUSNET')) {
- exit(1);
-}
-define('SPOTIFYPLUGIN_VERSION', '0.1');
-
-/**
- * Plugin to create pretty Spotify URLs
- *
- * The Spotify API is called before the notice is saved to gather artist and track information.
- *
- * @category Plugin
- * @package StatusNet
- * @author Nick Holliday <n.g.holliday@gmail.com>
- * @copyright Nick Holliday
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class SpotifyPlugin extends Plugin
-{
-
- function __construct()
- {
- parent::__construct();
- }
-
- function onStartNoticeSave($notice)
- {
- $notice->rendered = preg_replace_callback('/spotify:[a-z]{5,6}:[a-z0-9]{22}/i',
- "renderSpotifyURILink",
- $notice->rendered);
-
- $notice->rendered = preg_replace_callback('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}<\/a>/i',
- "renderSpotifyHTTPLink",
- $notice->rendered);
-
- return true;
- }
-
- function userAgent()
- {
- return 'SpotifyPlugin/'.SPOTIFYPLUGIN_VERSION .
- ' StatusNet/' . STATUSNET_VERSION;
- }
-}
-
-function doSpotifyLookup($uri, $isArtist)
-{
- $request = HTTPClient::start();
- $response = $request->get('http://ws.spotify.com/lookup/1/?uri=' . $uri);
- if ($response->isOk()) {
- $xml = simplexml_load_string($response->getBody());
-
- if($isArtist)
- return $xml->name;
- else
- return $xml->artist->name . ' - ' . $xml->name;
- }
-}
-
-function renderSpotifyURILink($match)
-{
- $isArtist = false;
- if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
-
- $name = doSpotifyLookup($match[0], $isArtist);
- return "<a href=\"{$match[0]}\">" . $name . "</a>";
-}
-
-function renderSpotifyHTTPLink($match)
-{
- $match[0] = preg_replace('/<a href="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" title="http:\/\/open.spotify.com\/[a-z]{5,6}\/[a-z0-9]{22}" rel="external">http:\/\/open.spotify.com\//i', 'spotify:', $match[0]);
- $match[0] = preg_replace('/<\/a>/', '', $match[0]);
- $match[0] = preg_replace('/\//', ':', $match[0]);
-
- $isArtist = false;
- if(preg_match('/artist/', $match[0]) > 0) $isArtist = true;
-
- $name = doSpotifyLookup($match[0], $isArtist);
- return "<a href=\"{$match[0]}\">" . $name . "</a>";
-}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, Inc.
+ *
+ * Plugin to throttle subscriptions by a user
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Throttle
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Subscription throttle
+ *
+ * @category Throttle
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class SubscriptionThrottlePlugin extends Plugin
+{
+ public $subLimits = array(86400 => 100,
+ 3600 => 50);
+
+ public $groupLimits = array(86400 => 50,
+ 3600 => 25);
+
+ /**
+ * Filter subscriptions to see if they're coming too fast.
+ *
+ * @param User $user The user subscribing
+ * @param User $other The user being subscribed to
+ *
+ * @return boolean hook value
+ */
+
+ function onStartSubscribe($user, $other)
+ {
+ foreach ($this->subLimits as $seconds => $limit) {
+ $sub = $this->_getNthSub($user, $limit);
+
+ if (!empty($sub)) {
+ $subtime = strtotime($sub->created);
+ $now = time();
+ if ($now - $subtime < $seconds) {
+ throw new Exception(_("Too many subscriptions. Take a break and try again later."));
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Filter group joins to see if they're coming too fast.
+ *
+ * @param Group $group The group being joined
+ * @param User $user The user joining
+ *
+ * @return boolean hook value
+ */
+
+ function onStartJoinGroup($group, $user)
+ {
+ foreach ($this->groupLimits as $seconds => $limit) {
+ $mem = $this->_getNthMem($user, $limit);
+ if (!empty($mem)) {
+
+ $jointime = strtotime($mem->created);
+ $now = time();
+ if ($now - $jointime < $seconds) {
+ throw new Exception(_("Too many memberships. Take a break and try again later."));
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the Nth most recent subscription for this user
+ *
+ * @param User $user The user to get subscriptions for
+ * @param integer $n How far to count back
+ *
+ * @return Subscription a subscription or null
+ */
+
+ private function _getNthSub($user, $n)
+ {
+ $sub = new Subscription();
+
+ $sub->subscriber = $user->id;
+ $sub->orderBy('created DESC');
+ $sub->limit($n - 1, 1);
+
+ if ($sub->find(true)) {
+ return $sub;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the Nth most recent group membership for this user
+ *
+ * @param User $user The user to get memberships for
+ * @param integer $n How far to count back
+ *
+ * @return Group_member a membership or null
+ */
+
+ private function _getNthMem($user, $n)
+ {
+ $mem = new Group_member();
+
+ $mem->profile_id = $user->id;
+ $mem->orderBy('created DESC');
+ $mem->limit($n - 1, 1);
+
+ if ($mem->find(true)) {
+ return $mem;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return plugin version data for display
+ *
+ * @param array &$versions Array of version arrays
+ *
+ * @return boolean hook value
+ */
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'SubscriptionThrottle',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:SubscriptionThrottle',
+ 'rawdescription' =>
+ _m('Configurable limits for subscriptions and group memberships.'));
+ return true;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, Inc.
- *
- * Plugin to throttle subscriptions by a user
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Throttle
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2010 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * Subscription throttle
- *
- * @category Throttle
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2010 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link http://status.net/
- */
-
-class SubscriptionThrottlePlugin extends Plugin
-{
- public $subLimits = array(86400 => 100,
- 3600 => 50);
-
- public $groupLimits = array(86400 => 50,
- 3600 => 25);
-
- /**
- * Filter subscriptions to see if they're coming too fast.
- *
- * @param User $user The user subscribing
- * @param User $other The user being subscribed to
- *
- * @return boolean hook value
- */
-
- function onStartSubscribe($user, $other)
- {
- foreach ($this->subLimits as $seconds => $limit) {
- $sub = $this->_getNthSub($user, $limit);
-
- if (!empty($sub)) {
- $subtime = strtotime($sub->created);
- $now = time();
- if ($now - $subtime < $seconds) {
- throw new Exception(_("Too many subscriptions. Take a break and try again later."));
- }
- }
- }
-
- return true;
- }
-
- /**
- * Filter group joins to see if they're coming too fast.
- *
- * @param Group $group The group being joined
- * @param User $user The user joining
- *
- * @return boolean hook value
- */
-
- function onStartJoinGroup($group, $user)
- {
- foreach ($this->groupLimits as $seconds => $limit) {
- $mem = $this->_getNthMem($user, $limit);
- if (!empty($mem)) {
-
- $jointime = strtotime($mem->created);
- $now = time();
- if ($now - $jointime < $seconds) {
- throw new Exception(_("Too many memberships. Take a break and try again later."));
- }
- }
- }
-
- return true;
- }
-
- /**
- * Get the Nth most recent subscription for this user
- *
- * @param User $user The user to get subscriptions for
- * @param integer $n How far to count back
- *
- * @return Subscription a subscription or null
- */
-
- private function _getNthSub($user, $n)
- {
- $sub = new Subscription();
-
- $sub->subscriber = $user->id;
- $sub->orderBy('created DESC');
- $sub->limit($n - 1, 1);
-
- if ($sub->find(true)) {
- return $sub;
- } else {
- return null;
- }
- }
-
- /**
- * Get the Nth most recent group membership for this user
- *
- * @param User $user The user to get memberships for
- * @param integer $n How far to count back
- *
- * @return Group_member a membership or null
- */
-
- private function _getNthMem($user, $n)
- {
- $mem = new Group_member();
-
- $mem->profile_id = $user->id;
- $mem->orderBy('created DESC');
- $mem->limit($n - 1, 1);
-
- if ($mem->find(true)) {
- return $mem;
- } else {
- return null;
- }
- }
-
- /**
- * Return plugin version data for display
- *
- * @param array &$versions Array of version arrays
- *
- * @return boolean hook value
- */
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'SubscriptionThrottle',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:SubscriptionThrottle',
- 'rawdescription' =>
- _m('Configurable limits for subscriptions and group memberships.'));
- return true;
- }
-}
-
--- /dev/null
+<?php
+/**
+ * Plugin to render old skool templates
+ *
+ * Captures rendered parts from the output buffer, passes them through a template file: tpl/index.html
+ * Adds an API method at index.php/template/update which lets you overwrite the template file
+ * Requires username/password and a single POST parameter called "template"
+ * The method is disabled unless the user is #1, the first user of the system
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Brian Hendrickson <brian@megapump.com>
+ * @copyright 2009 Megapump, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://megapump.com/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+define('TEMPLATEPLUGIN_VERSION', '0.1');
+
+class TemplatePlugin extends Plugin {
+
+ var $blocks = array();
+
+ function __construct() {
+ parent::__construct();
+ }
+
+ // capture the RouterInitialized event
+ // and connect a new API method
+ // for updating the template
+ function onRouterInitialized( $m ) {
+ $m->connect( 'template/update', array(
+ 'action' => 'template',
+ ));
+ }
+
+ // <%styles%>
+ // <%scripts%>
+ // <%search%>
+ // <%feeds%>
+ // <%description%>
+ // <%head%>
+ function onStartShowHead( &$act ) {
+ $this->clear_xmlWriter($act);
+ $act->extraHead();
+ $this->blocks['head'] = $act->xw->flush();
+ $act->showStylesheets();
+ $this->blocks['styles'] = $act->xw->flush();
+ $act->showScripts();
+ $this->blocks['scripts'] = $act->xw->flush();
+ $act->showFeeds();
+ $this->blocks['feeds'] = $act->xw->flush();
+ $act->showOpenSearch();
+ $this->blocks['search'] = $act->xw->flush();
+ $act->showDescription();
+ $this->blocks['description'] = $act->xw->flush();
+ return false;
+ }
+
+ // <%bodytext%>
+ function onStartShowContentBlock( &$act ) {
+ $this->clear_xmlWriter($act);
+ return true;
+ }
+ function onEndShowContentBlock( &$act ) {
+ $this->blocks['bodytext'] = $act->xw->flush();
+ }
+
+ // <%localnav%>
+ function onStartShowLocalNavBlock( &$act ) {
+ $this->clear_xmlWriter($act);
+ return true;
+ }
+ function onEndShowLocalNavBlock( &$act ) {
+ $this->blocks['localnav'] = $act->xw->flush();
+ }
+
+ // <%export%>
+ function onStartShowExportData( &$act ) {
+ $this->clear_xmlWriter($act);
+ return true;
+ }
+ function onEndShowExportData( &$act ) {
+ $this->blocks['export'] = $act->xw->flush();
+ }
+
+ // <%subscriptions%>
+ // <%subscribers%>
+ // <%groups%>
+ // <%statistics%>
+ // <%cloud%>
+ // <%groupmembers%>
+ // <%groupstatistics%>
+ // <%groupcloud%>
+ // <%popular%>
+ // <%groupsbyposts%>
+ // <%featuredusers%>
+ // <%groupsbymembers%>
+ function onStartShowSections( &$act ) {
+ global $action;
+ $this->clear_xmlWriter($act);
+ switch ($action) {
+ case "showstream":
+ $act->showSubscriptions();
+ $this->blocks['subscriptions'] = $act->xw->flush();
+ $act->showSubscribers();
+ $this->blocks['subscribers'] = $act->xw->flush();
+ $act->showGroups();
+ $this->blocks['groups'] = $act->xw->flush();
+ $act->showStatistics();
+ $this->blocks['statistics'] = $act->xw->flush();
+ $cloud = new PersonalTagCloudSection($act, $act->user);
+ $cloud->show();
+ $this->blocks['cloud'] = $act->xw->flush();
+ break;
+ case "showgroup":
+ $act->showMembers();
+ $this->blocks['groupmembers'] = $act->xw->flush();
+ $act->showStatistics();
+ $this->blocks['groupstatistics'] = $act->xw->flush();
+ $cloud = new GroupTagCloudSection($act, $act->group);
+ $cloud->show();
+ $this->blocks['groupcloud'] = $act->xw->flush();
+ break;
+ case "public":
+ $pop = new PopularNoticeSection($act);
+ $pop->show();
+ $this->blocks['popular'] = $act->xw->flush();
+ $gbp = new GroupsByPostsSection($act);
+ $gbp->show();
+ $this->blocks['groupsbyposts'] = $act->xw->flush();
+ $feat = new FeaturedUsersSection($act);
+ $feat->show();
+ $this->blocks['featuredusers'] = $act->xw->flush();
+ break;
+ case "groups":
+ $gbp = new GroupsByPostsSection($act);
+ $gbp->show();
+ $this->blocks['groupsbyposts'] = $act->xw->flush();
+ $gbm = new GroupsByMembersSection($act);
+ $gbm->show();
+ $this->blocks['groupsbymembers'] = $act->xw->flush();
+ break;
+ }
+ return false;
+ }
+
+ // <%logo%>
+ // <%nav%>
+ // <%notice%>
+ // <%noticeform%>
+ function onStartShowHeader( &$act ) {
+ $this->clear_xmlWriter($act);
+ $act->showLogo();
+ $this->blocks['logo'] = $act->xw->flush();
+ $act->showPrimaryNav();
+ $this->blocks['nav'] = $act->xw->flush();
+ $act->showSiteNotice();
+ $this->blocks['notice'] = $act->xw->flush();
+ if (common_logged_in()) {
+ $act->showNoticeForm();
+ } else {
+ $act->showAnonymousMessage();
+ }
+ $this->blocks['noticeform'] = $act->xw->flush();
+ return false;
+ }
+
+ // <%secondarynav%>
+ // <%licenses%>
+ function onStartShowFooter( &$act ) {
+ $this->clear_xmlWriter($act);
+ $act->showSecondaryNav();
+ $this->blocks['secondarynav'] = $act->xw->flush();
+ $act->showLicenses();
+ $this->blocks['licenses'] = $act->xw->flush();
+ return false;
+ }
+
+ // capture the EndHTML event
+ // and include the template
+ function onEndEndHTML($act) {
+
+ global $action, $tags;
+
+ // set the action and title values
+ $vars = array(
+ 'action'=>$action,
+ 'title'=>$act->title(). " - ". common_config('site', 'name')
+ );
+
+ // use the PHP template
+ // unless statusnet config:
+ // $config['template']['mode'] = 'html';
+ if (!(common_config('template', 'mode') == 'html')) {
+ $tpl_file = $this->templateFolder() . '/index.php';
+ $tags = array_merge($vars,$this->blocks);
+ include $tpl_file;
+ return;
+ }
+
+ $tpl_file = $this->templateFolder() . '/index.html';
+
+ // read the static template
+ $output = file_get_contents( $tpl_file );
+
+ $tags = array();
+
+ // get a list of the <%tags%> in the template
+ $pattern='/<%([a-z]+)%>/';
+
+ if ( 1 <= preg_match_all( $pattern, $output, $found ))
+ $tags[] = $found;
+
+ // for each found tag, set its value from the rendered blocks
+ foreach( $tags[0][1] as $pos=>$tag ) {
+ if (isset($this->blocks[$tag]))
+ $vars[$tag] = $this->blocks[$tag];
+
+ // didn't find a block for the tag
+ elseif (!isset($vars[$tag]))
+ $vars[$tag] = '';
+ }
+
+ // replace the tags in the template
+ foreach( $vars as $key=>$val )
+ $output = str_replace( '<%'.$key.'%>', $val, $output );
+
+ echo $output;
+
+ return true;
+
+ }
+ function templateFolder() {
+ return 'tpl';
+ }
+
+ // catching the StartShowHTML event to halt the rendering
+ function onStartShowHTML( &$act ) {
+ $this->clear_xmlWriter($act);
+ return true;
+ }
+
+ // clear the xmlWriter
+ function clear_xmlWriter( &$act ) {
+ $act->xw->openMemory();
+ $act->xw->setIndent(true);
+ }
+
+}
+
+/**
+ * Action for updating the template remotely
+ *
+ * "template/update" -- a POST method that requires a single
+ * parameter "template", containing the new template code
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Brian Hendrickson <brian@megapump.com>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://megapump.com/
+ *
+ */
+
+class TemplateAction extends Action
+{
+
+ function prepare($args) {
+ parent::prepare($args);
+ return true;
+ }
+
+ function handle($args) {
+
+ parent::handle($args);
+
+ if (!isset($_SERVER['PHP_AUTH_USER'])) {
+
+ // not authenticated, show login form
+ header('WWW-Authenticate: Basic realm="StatusNet API"');
+
+ // cancelled the browser login form
+ $this->clientError(_('Authentication error!'), $code = 401);
+
+ } else {
+
+ $nick = $_SERVER['PHP_AUTH_USER'];
+ $pass = $_SERVER['PHP_AUTH_PW'];
+
+ // check username and password
+ $user = common_check_user($nick,$pass);
+
+ if ($user) {
+
+ // verify that user is admin
+ if (!($user->id == 1))
+ $this->clientError(_('Only User #1 can update the template.'), $code = 401);
+
+ // open the old template
+ $tpl_file = $this->templateFolder() . '/index.html';
+ $fp = fopen( $tpl_file, 'w+' );
+
+ // overwrite with the new template
+ fwrite($fp, $this->arg('template'));
+ fclose($fp);
+
+ header('HTTP/1.1 200 OK');
+ header('Content-type: text/plain');
+ print "Template Updated!";
+
+ } else {
+
+ // bad username and password
+ $this->clientError(_('Authentication error!'), $code = 401);
+
+ }
+
+ }
+ }
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'Template',
+ 'version' => TEMPLATEPLUGIN_VERSION,
+ 'author' => 'Brian Hendrickson',
+ 'homepage' => 'http://status.net/wiki/Plugin:Template',
+ 'rawdescription' =>
+ _m('Use an HTML template for Web output.'));
+ return true;
+ }
+
+}
+
+/**
+ * Function for retrieving a statusnet display section
+ *
+ * requires one parameter, the name of the section
+ * section names are listed in the comments of the TemplatePlugin class
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Brian Hendrickson <brian@megapump.com>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://megapump.com/
+ *
+ */
+
+function section($tagname) {
+ global $tags;
+ if (isset($tags[$tagname]))
+ return $tags[$tagname];
+}
+
+++ /dev/null
-<?php
-/**
- * Plugin to render old skool templates
- *
- * Captures rendered parts from the output buffer, passes them through a template file: tpl/index.html
- * Adds an API method at index.php/template/update which lets you overwrite the template file
- * Requires username/password and a single POST parameter called "template"
- * The method is disabled unless the user is #1, the first user of the system
- *
- * @category Plugin
- * @package StatusNet
- * @author Brian Hendrickson <brian@megapump.com>
- * @copyright 2009 Megapump, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://megapump.com/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-define('TEMPLATEPLUGIN_VERSION', '0.1');
-
-class TemplatePlugin extends Plugin {
-
- var $blocks = array();
-
- function __construct() {
- parent::__construct();
- }
-
- // capture the RouterInitialized event
- // and connect a new API method
- // for updating the template
- function onRouterInitialized( $m ) {
- $m->connect( 'template/update', array(
- 'action' => 'template',
- ));
- }
-
- // <%styles%>
- // <%scripts%>
- // <%search%>
- // <%feeds%>
- // <%description%>
- // <%head%>
- function onStartShowHead( &$act ) {
- $this->clear_xmlWriter($act);
- $act->extraHead();
- $this->blocks['head'] = $act->xw->flush();
- $act->showStylesheets();
- $this->blocks['styles'] = $act->xw->flush();
- $act->showScripts();
- $this->blocks['scripts'] = $act->xw->flush();
- $act->showFeeds();
- $this->blocks['feeds'] = $act->xw->flush();
- $act->showOpenSearch();
- $this->blocks['search'] = $act->xw->flush();
- $act->showDescription();
- $this->blocks['description'] = $act->xw->flush();
- return false;
- }
-
- // <%bodytext%>
- function onStartShowContentBlock( &$act ) {
- $this->clear_xmlWriter($act);
- return true;
- }
- function onEndShowContentBlock( &$act ) {
- $this->blocks['bodytext'] = $act->xw->flush();
- }
-
- // <%localnav%>
- function onStartShowLocalNavBlock( &$act ) {
- $this->clear_xmlWriter($act);
- return true;
- }
- function onEndShowLocalNavBlock( &$act ) {
- $this->blocks['localnav'] = $act->xw->flush();
- }
-
- // <%export%>
- function onStartShowExportData( &$act ) {
- $this->clear_xmlWriter($act);
- return true;
- }
- function onEndShowExportData( &$act ) {
- $this->blocks['export'] = $act->xw->flush();
- }
-
- // <%subscriptions%>
- // <%subscribers%>
- // <%groups%>
- // <%statistics%>
- // <%cloud%>
- // <%groupmembers%>
- // <%groupstatistics%>
- // <%groupcloud%>
- // <%popular%>
- // <%groupsbyposts%>
- // <%featuredusers%>
- // <%groupsbymembers%>
- function onStartShowSections( &$act ) {
- global $action;
- $this->clear_xmlWriter($act);
- switch ($action) {
- case "showstream":
- $act->showSubscriptions();
- $this->blocks['subscriptions'] = $act->xw->flush();
- $act->showSubscribers();
- $this->blocks['subscribers'] = $act->xw->flush();
- $act->showGroups();
- $this->blocks['groups'] = $act->xw->flush();
- $act->showStatistics();
- $this->blocks['statistics'] = $act->xw->flush();
- $cloud = new PersonalTagCloudSection($act, $act->user);
- $cloud->show();
- $this->blocks['cloud'] = $act->xw->flush();
- break;
- case "showgroup":
- $act->showMembers();
- $this->blocks['groupmembers'] = $act->xw->flush();
- $act->showStatistics();
- $this->blocks['groupstatistics'] = $act->xw->flush();
- $cloud = new GroupTagCloudSection($act, $act->group);
- $cloud->show();
- $this->blocks['groupcloud'] = $act->xw->flush();
- break;
- case "public":
- $pop = new PopularNoticeSection($act);
- $pop->show();
- $this->blocks['popular'] = $act->xw->flush();
- $gbp = new GroupsByPostsSection($act);
- $gbp->show();
- $this->blocks['groupsbyposts'] = $act->xw->flush();
- $feat = new FeaturedUsersSection($act);
- $feat->show();
- $this->blocks['featuredusers'] = $act->xw->flush();
- break;
- case "groups":
- $gbp = new GroupsByPostsSection($act);
- $gbp->show();
- $this->blocks['groupsbyposts'] = $act->xw->flush();
- $gbm = new GroupsByMembersSection($act);
- $gbm->show();
- $this->blocks['groupsbymembers'] = $act->xw->flush();
- break;
- }
- return false;
- }
-
- // <%logo%>
- // <%nav%>
- // <%notice%>
- // <%noticeform%>
- function onStartShowHeader( &$act ) {
- $this->clear_xmlWriter($act);
- $act->showLogo();
- $this->blocks['logo'] = $act->xw->flush();
- $act->showPrimaryNav();
- $this->blocks['nav'] = $act->xw->flush();
- $act->showSiteNotice();
- $this->blocks['notice'] = $act->xw->flush();
- if (common_logged_in()) {
- $act->showNoticeForm();
- } else {
- $act->showAnonymousMessage();
- }
- $this->blocks['noticeform'] = $act->xw->flush();
- return false;
- }
-
- // <%secondarynav%>
- // <%licenses%>
- function onStartShowFooter( &$act ) {
- $this->clear_xmlWriter($act);
- $act->showSecondaryNav();
- $this->blocks['secondarynav'] = $act->xw->flush();
- $act->showLicenses();
- $this->blocks['licenses'] = $act->xw->flush();
- return false;
- }
-
- // capture the EndHTML event
- // and include the template
- function onEndEndHTML($act) {
-
- global $action, $tags;
-
- // set the action and title values
- $vars = array(
- 'action'=>$action,
- 'title'=>$act->title(). " - ". common_config('site', 'name')
- );
-
- // use the PHP template
- // unless statusnet config:
- // $config['template']['mode'] = 'html';
- if (!(common_config('template', 'mode') == 'html')) {
- $tpl_file = $this->templateFolder() . '/index.php';
- $tags = array_merge($vars,$this->blocks);
- include $tpl_file;
- return;
- }
-
- $tpl_file = $this->templateFolder() . '/index.html';
-
- // read the static template
- $output = file_get_contents( $tpl_file );
-
- $tags = array();
-
- // get a list of the <%tags%> in the template
- $pattern='/<%([a-z]+)%>/';
-
- if ( 1 <= preg_match_all( $pattern, $output, $found ))
- $tags[] = $found;
-
- // for each found tag, set its value from the rendered blocks
- foreach( $tags[0][1] as $pos=>$tag ) {
- if (isset($this->blocks[$tag]))
- $vars[$tag] = $this->blocks[$tag];
-
- // didn't find a block for the tag
- elseif (!isset($vars[$tag]))
- $vars[$tag] = '';
- }
-
- // replace the tags in the template
- foreach( $vars as $key=>$val )
- $output = str_replace( '<%'.$key.'%>', $val, $output );
-
- echo $output;
-
- return true;
-
- }
- function templateFolder() {
- return 'tpl';
- }
-
- // catching the StartShowHTML event to halt the rendering
- function onStartShowHTML( &$act ) {
- $this->clear_xmlWriter($act);
- return true;
- }
-
- // clear the xmlWriter
- function clear_xmlWriter( &$act ) {
- $act->xw->openMemory();
- $act->xw->setIndent(true);
- }
-
-}
-
-/**
- * Action for updating the template remotely
- *
- * "template/update" -- a POST method that requires a single
- * parameter "template", containing the new template code
- *
- * @category Plugin
- * @package StatusNet
- * @author Brian Hendrickson <brian@megapump.com>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://megapump.com/
- *
- */
-
-class TemplateAction extends Action
-{
-
- function prepare($args) {
- parent::prepare($args);
- return true;
- }
-
- function handle($args) {
-
- parent::handle($args);
-
- if (!isset($_SERVER['PHP_AUTH_USER'])) {
-
- // not authenticated, show login form
- header('WWW-Authenticate: Basic realm="StatusNet API"');
-
- // cancelled the browser login form
- $this->clientError(_('Authentication error!'), $code = 401);
-
- } else {
-
- $nick = $_SERVER['PHP_AUTH_USER'];
- $pass = $_SERVER['PHP_AUTH_PW'];
-
- // check username and password
- $user = common_check_user($nick,$pass);
-
- if ($user) {
-
- // verify that user is admin
- if (!($user->id == 1))
- $this->clientError(_('Only User #1 can update the template.'), $code = 401);
-
- // open the old template
- $tpl_file = $this->templateFolder() . '/index.html';
- $fp = fopen( $tpl_file, 'w+' );
-
- // overwrite with the new template
- fwrite($fp, $this->arg('template'));
- fclose($fp);
-
- header('HTTP/1.1 200 OK');
- header('Content-type: text/plain');
- print "Template Updated!";
-
- } else {
-
- // bad username and password
- $this->clientError(_('Authentication error!'), $code = 401);
-
- }
-
- }
- }
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'Template',
- 'version' => TEMPLATEPLUGIN_VERSION,
- 'author' => 'Brian Hendrickson',
- 'homepage' => 'http://status.net/wiki/Plugin:Template',
- 'rawdescription' =>
- _m('Use an HTML template for Web output.'));
- return true;
- }
-
-}
-
-/**
- * Function for retrieving a statusnet display section
- *
- * requires one parameter, the name of the section
- * section names are listed in the comments of the TemplatePlugin class
- *
- * @category Plugin
- * @package StatusNet
- * @author Brian Hendrickson <brian@megapump.com>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://megapump.com/
- *
- */
-
-function section($tagname) {
- global $tags;
- if (isset($tags[$tagname]))
- return $tags[$tagname];
-}
-
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to limit number of users that can register (best for cloud providers)
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Action
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to limit number of users that can register (best for cloud providers)
+ *
+ * For cloud providers whose freemium model is based on how many
+ * users can register. We use it on the StatusNet Cloud.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @seeAlso Location
+ */
+
+class UserLimitPlugin extends Plugin
+{
+ public $maxUsers = null;
+
+ function onStartUserRegister(&$user, &$profile)
+ {
+ $this->_checkMaxUsers();
+ return true;
+ }
+
+ function onStartRegistrationTry($action)
+ {
+ $this->_checkMaxUsers();
+ return true;
+ }
+
+ function _checkMaxUsers()
+ {
+ if (!is_null($this->maxUsers)) {
+
+ $cls = new User();
+
+ $cnt = $cls->count();
+
+ if ($cnt >= $this->maxUsers) {
+ $msg = sprintf(_('Cannot register; maximum number of users (%d) reached.'),
+ $this->maxUsers);
+
+ throw new ClientException($msg);
+ }
+ }
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'UserLimit',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:UserLimit',
+ 'description' =>
+ _m('Limit the number of users who can register.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to limit number of users that can register (best for cloud providers)
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Action
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to limit number of users that can register (best for cloud providers)
- *
- * For cloud providers whose freemium model is based on how many
- * users can register. We use it on the StatusNet Cloud.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @seeAlso Location
- */
-
-class UserLimitPlugin extends Plugin
-{
- public $maxUsers = null;
-
- function onStartUserRegister(&$user, &$profile)
- {
- $this->_checkMaxUsers();
- return true;
- }
-
- function onStartRegistrationTry($action)
- {
- $this->_checkMaxUsers();
- return true;
- }
-
- function _checkMaxUsers()
- {
- if (!is_null($this->maxUsers)) {
-
- $cls = new User();
-
- $cnt = $cls->count();
-
- if ($cnt >= $this->maxUsers) {
- $msg = sprintf(_('Cannot register; maximum number of users (%d) reached.'),
- $this->maxUsers);
-
- throw new ClientException($msg);
- }
- }
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'UserLimit',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:UserLimit',
- 'description' =>
- _m('Limit the number of users who can register.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Plugin to show WikiHashtags content in the sidebar
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2008 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ exit(1);
+}
+
+/**
+ * Plugin to use WikiHashtags
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ *
+ * @see Event
+ */
+
+class WikiHashtagsPlugin extends Plugin
+{
+ const VERSION = '0.1';
+
+ function __construct($code=null)
+ {
+ parent::__construct();
+ }
+
+ function onStartShowSections($action)
+ {
+ $name = $action->trimmed('action');
+
+ if ($name == 'tag') {
+
+ $taginput = $action->trimmed('tag');
+ $tag = common_canonical_tag($taginput);
+
+ if (!empty($tag)) {
+
+ $url = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=render',
+ urlencode($tag));
+ $editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit',
+ urlencode($tag));
+
+ $request = HTTPClient::start();
+ $response = $request->get($url);
+ $html = $response->getBody();
+
+ $action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section'));
+
+ if ($response->isOk() && !empty($html)) {
+ $action->element('style', null,
+ "span.editsection { display: none }\n".
+ "table.toc { display: none }");
+ $action->raw($html);
+ $action->elementStart('p');
+ $action->element('a', array('href' => $editurl,
+ 'title' => sprintf(_('Edit the article for #%s on WikiHashtags'), $tag)),
+ _('Edit'));
+ $action->element('a', array('href' => 'http://www.gnu.org/copyleft/fdl.html',
+ 'title' => _('Shared under the terms of the GNU Free Documentation License'),
+ 'rel' => 'license'),
+ 'GNU FDL');
+ $action->elementEnd('p');
+ } else {
+ $action->element('a', array('href' => $editurl),
+ sprintf(_('Start the article for #%s on WikiHashtags'), $tag));
+ }
+
+ $action->elementEnd('div');
+ }
+ }
+
+ return true;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'WikiHashtags',
+ 'version' => self::VERSION,
+ 'author' => 'Evan Prodromou',
+ 'homepage' => 'http://status.net/wiki/Plugin:WikiHashtags',
+ 'rawdescription' =>
+ _m('Gets hashtag descriptions from <a href="http://hashtags.wikia.com/">WikiHashtags</a>.'));
+ return true;
+ }
+}
+++ /dev/null
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to show WikiHashtags content in the sidebar
- *
- * PHP version 5
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2008 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-/**
- * Plugin to use WikiHashtags
- *
- * @category Plugin
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- *
- * @see Event
- */
-
-class WikiHashtagsPlugin extends Plugin
-{
- const VERSION = '0.1';
-
- function __construct($code=null)
- {
- parent::__construct();
- }
-
- function onStartShowSections($action)
- {
- $name = $action->trimmed('action');
-
- if ($name == 'tag') {
-
- $taginput = $action->trimmed('tag');
- $tag = common_canonical_tag($taginput);
-
- if (!empty($tag)) {
-
- $url = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=render',
- urlencode($tag));
- $editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit',
- urlencode($tag));
-
- $request = HTTPClient::start();
- $response = $request->get($url);
- $html = $response->getBody();
-
- $action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section'));
-
- if ($response->isOk() && !empty($html)) {
- $action->element('style', null,
- "span.editsection { display: none }\n".
- "table.toc { display: none }");
- $action->raw($html);
- $action->elementStart('p');
- $action->element('a', array('href' => $editurl,
- 'title' => sprintf(_('Edit the article for #%s on WikiHashtags'), $tag)),
- _('Edit'));
- $action->element('a', array('href' => 'http://www.gnu.org/copyleft/fdl.html',
- 'title' => _('Shared under the terms of the GNU Free Documentation License'),
- 'rel' => 'license'),
- 'GNU FDL');
- $action->elementEnd('p');
- } else {
- $action->element('a', array('href' => $editurl),
- sprintf(_('Start the article for #%s on WikiHashtags'), $tag));
- }
-
- $action->elementEnd('div');
- }
- }
-
- return true;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'WikiHashtags',
- 'version' => self::VERSION,
- 'author' => 'Evan Prodromou',
- 'homepage' => 'http://status.net/wiki/Plugin:WikiHashtags',
- 'rawdescription' =>
- _m('Gets hashtag descriptions from <a href="http://hashtags.wikia.com/">WikiHashtags</a>.'));
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * Plugin to implement cache interface for XCache variable cache
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * A plugin to use XCache's variable cache for the cache interface
+ *
+ * New plugin interface lets us use alternative cache systems
+ * for caching. This one uses XCache's variable cache.
+ *
+ * @category Cache
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+class XCachePlugin extends Plugin
+{
+ /**
+ * Get a value associated with a key
+ *
+ * The value should have been set previously.
+ *
+ * @param string &$key in; Lookup key
+ * @param mixed &$value out; value associated with key
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheGet(&$key, &$value)
+ {
+ if (!xcache_isset($key)) {
+ $value = false;
+ } else {
+ $value = xcache_get($key);
+ $value = unserialize($value);
+ }
+ Event::handle('EndCacheGet', array($key, &$value));
+ return false;
+ }
+
+ /**
+ * Associate a value with a key
+ *
+ * @param string &$key in; Key to use for lookups
+ * @param mixed &$value in; Value to associate
+ * @param integer &$flag in; Flag (passed through to Memcache)
+ * @param integer &$expiry in; Expiry (passed through to Memcache)
+ * @param boolean &$success out; Whether the set was successful
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
+ {
+ $success = xcache_set($key, serialize($value));
+
+ Event::handle('EndCacheSet', array($key, $value, $flag,
+ $expiry));
+ return false;
+ }
+
+ /**
+ * Delete a value associated with a key
+ *
+ * @param string &$key in; Key to lookup
+ * @param boolean &$success out; whether it worked
+ *
+ * @return boolean hook success
+ */
+
+ function onStartCacheDelete(&$key, &$success)
+ {
+ $success = xcache_unset($key);
+ Event::handle('EndCacheDelete', array($key));
+ return false;
+ }
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'XCache',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Craig Andrews',
+ 'homepage' => 'http://status.net/wiki/Plugin:XCache',
+ 'rawdescription' =>
+ _m('Use the <a href="http://xcache.lighttpd.net/">XCache</a> variable cache to cache query results.'));
+ return true;
+ }
+}
+
+++ /dev/null
-<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2009, StatusNet, Inc.
- *
- * Plugin to implement cache interface for XCache variable cache
- *
- * PHP version 5
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- // This check helps protect against security problems;
- // your code file can't be executed directly from the web.
- exit(1);
-}
-
-/**
- * A plugin to use XCache's variable cache for the cache interface
- *
- * New plugin interface lets us use alternative cache systems
- * for caching. This one uses XCache's variable cache.
- *
- * @category Cache
- * @package StatusNet
- * @author Evan Prodromou <evan@status.net>
- * @copyright 2009 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-class XCachePlugin extends Plugin
-{
- /**
- * Get a value associated with a key
- *
- * The value should have been set previously.
- *
- * @param string &$key in; Lookup key
- * @param mixed &$value out; value associated with key
- *
- * @return boolean hook success
- */
-
- function onStartCacheGet(&$key, &$value)
- {
- if (!xcache_isset($key)) {
- $value = false;
- } else {
- $value = xcache_get($key);
- $value = unserialize($value);
- }
- Event::handle('EndCacheGet', array($key, &$value));
- return false;
- }
-
- /**
- * Associate a value with a key
- *
- * @param string &$key in; Key to use for lookups
- * @param mixed &$value in; Value to associate
- * @param integer &$flag in; Flag (passed through to Memcache)
- * @param integer &$expiry in; Expiry (passed through to Memcache)
- * @param boolean &$success out; Whether the set was successful
- *
- * @return boolean hook success
- */
-
- function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
- {
- $success = xcache_set($key, serialize($value));
-
- Event::handle('EndCacheSet', array($key, $value, $flag,
- $expiry));
- return false;
- }
-
- /**
- * Delete a value associated with a key
- *
- * @param string &$key in; Key to lookup
- * @param boolean &$success out; whether it worked
- *
- * @return boolean hook success
- */
-
- function onStartCacheDelete(&$key, &$success)
- {
- $success = xcache_unset($key);
- Event::handle('EndCacheDelete', array($key));
- return false;
- }
-
- function onPluginVersion(&$versions)
- {
- $versions[] = array('name' => 'XCache',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Craig Andrews',
- 'homepage' => 'http://status.net/wiki/Plugin:XCache',
- 'rawdescription' =>
- _m('Use the <a href="http://xcache.lighttpd.net/">XCache</a> variable cache to cache query results.'));
- return true;
- }
-}
-