From 14f03a237e1a67a764a75cfa8e6fed34f0074a4b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 12 Sep 2011 12:13:04 -0400 Subject: [PATCH 01/24] initialize fave, sub, and membership URIs --- scripts/upgrade.php | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/scripts/upgrade.php b/scripts/upgrade.php index af89760f70..2b116733c6 100644 --- a/scripts/upgrade.php +++ b/scripts/upgrade.php @@ -43,8 +43,13 @@ function main() initConversation(); initInbox(); fixupGroupURI(); + initLocalGroup(); initNoticeReshare(); + + initFaveURI(); + initSubscriptionURI(); + initGroupMemberURI(); } function tableDefs() @@ -283,4 +288,84 @@ function initNoticeReshare() printfnq("DONE.\n"); } +function initFaveURI() +{ + printfnq("Ensuring all faves have a URI..."); + + $fave = new Fave(); + $fave->whereAdd('uri IS NULL'); + + if ($fave->find()) { + while ($fave->fetch()) { + try { + $fave->decache(); + $fave->query(sprintf('update fave '. + 'set uri = "%s" '. + 'where user_id = %d '. + 'and notice_id = %d', + Fave::newURI($fave->user_id, $fave->notice_id, $fave->modified), + $fave->user_id, + $fave->notice_id)); + } catch (Exception $e) { + common_log(LOG_ERR, "Error updated fave URI: " . $e->getMessage()); + } + } + } + + printfnq("DONE.\n"); +} + +function initSubscriptionURI() +{ + printfnq("Ensuring all subscriptions have a URI..."); + + $sub = new Subscription(); + $sub->whereAdd('uri IS NULL'); + + if ($sub->find()) { + while ($sub->fetch()) { + try { + $sub->decache(); + $sub->query(sprintf('update subscription '. + 'set uri = "%s" '. + 'where subscriber = %d '. + 'and subscribed = %d', + Subscription::newURI($sub->subscriber, $sub->subscribed, $sub->created), + $sub->subscriber, + $sub->subscribed)); + } catch (Exception $e) { + common_log(LOG_ERR, "Error updated subscription URI: " . $e->getMessage()); + } + } + } + + printfnq("DONE.\n"); +} + +function initGroupMemberURI() +{ + printfnq("Ensuring all group memberships have a URI..."); + + $mem = new Group_member(); + $mem->whereAdd('uri IS NULL'); + + if ($mem->find()) { + while ($mem->fetch()) { + try { + $mem->decache(); + $mem->query(sprintf('update group_member set uri = "%s" '. + 'where profile_id = %d ' . + 'and group_id = %d ', + Group_member::newURI($mem->profile_id, $mem->group_id, $mem->created), + $mem->profile_id, + $mem->group_id)); + } catch (Exception $e) { + common_log(LOG_ERR, "Error updated membership URI: " . $e->getMessage()); + } + } + } + + printfnq("DONE.\n"); +} + main(); From 8f78743198af265b504e41931992493771c1c811 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 12 Sep 2011 13:36:12 -0400 Subject: [PATCH 02/24] correct the URI-generation for group memberships --- classes/Group_member.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/Group_member.php b/classes/Group_member.php index 2ad6589a3c..53743e7f24 100644 --- a/classes/Group_member.php +++ b/classes/Group_member.php @@ -203,14 +203,14 @@ class Group_member extends Managed_DataObject if (!empty($this->uri)) { return $this->uri; } else { - return self::newURI($this->member_id, $this->group_id, $this->created); + return self::newURI($this->profile_id, $this->group_id, $this->created); } } - static function newURI($member_id, $group_id, $created) + static function newURI($profile_id, $group_id, $created) { return TagURI::mint('join:%d:%d:%s', - $member_id, + $profile_id, $group_id, common_date_iso8601($created)); } From b2ed258e42c622fa394f541eb4b3c56373b821dd Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 12 Sep 2011 15:24:47 -0400 Subject: [PATCH 03/24] Avoid resetting modified for Faves in upgrade script --- scripts/upgrade.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/upgrade.php b/scripts/upgrade.php index 2b116733c6..4c793ac15e 100644 --- a/scripts/upgrade.php +++ b/scripts/upgrade.php @@ -300,10 +300,12 @@ function initFaveURI() try { $fave->decache(); $fave->query(sprintf('update fave '. - 'set uri = "%s" '. + 'set uri = "%s", '. + ' modified = "%s" '. 'where user_id = %d '. 'and notice_id = %d', Fave::newURI($fave->user_id, $fave->notice_id, $fave->modified), + common_sql_date(strtotime($fave->modified)), $fave->user_id, $fave->notice_id)); } catch (Exception $e) { From 8bb4eb53936b40f9d15839499c802a070448a70c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 09:08:46 -0400 Subject: [PATCH 04/24] Remove NUM --- extlib/Net/URL/Mapper.php | 324 ----------------- extlib/Net/URL/Mapper/Exception.php | 104 ------ extlib/Net/URL/Mapper/Part.php | 142 -------- extlib/Net/URL/Mapper/Part/Dynamic.php | 81 ----- extlib/Net/URL/Mapper/Part/Fixed.php | 70 ---- extlib/Net/URL/Mapper/Part/Wildcard.php | 80 ----- extlib/Net/URL/Mapper/Path.php | 451 ------------------------ extlib/Net/URL/Mapper/Path.plex | 334 ------------------ 8 files changed, 1586 deletions(-) delete mode 100644 extlib/Net/URL/Mapper.php delete mode 100644 extlib/Net/URL/Mapper/Exception.php delete mode 100644 extlib/Net/URL/Mapper/Part.php delete mode 100644 extlib/Net/URL/Mapper/Part/Dynamic.php delete mode 100644 extlib/Net/URL/Mapper/Part/Fixed.php delete mode 100644 extlib/Net/URL/Mapper/Part/Wildcard.php delete mode 100644 extlib/Net/URL/Mapper/Path.php delete mode 100644 extlib/Net/URL/Mapper/Path.plex diff --git a/extlib/Net/URL/Mapper.php b/extlib/Net/URL/Mapper.php deleted file mode 100644 index 009c135214..0000000000 --- a/extlib/Net/URL/Mapper.php +++ /dev/null @@ -1,324 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Mapper.php 232857 2007-03-28 10:23:04Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -require_once 'Net/URL/Mapper/Path.php'; -require_once 'Net/URL/Mapper/Exception.php'; - -/** - * URL parser and mapper class - * - * This class takes an URL and a configuration and returns formatted data - * about the request according to a configuration parameter - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @version Release: @package_version@ - */ -class Net_URL_Mapper -{ - /** - * Array of Net_URL_Mapper instances - * @var array - */ - private static $instances = array(); - - /** - * Mapped paths collection - * @var array - */ - protected $paths = array(); - - /** - * Prefix used for url mapping - * @var string - */ - protected $prefix = ''; - - /** - * Optional scriptname if mod_rewrite is not available - * @var string - */ - protected $scriptname = ''; - - /** - * Mapper instance id - * @var string - */ - protected $id = '__default__'; - - /** - * Class constructor - * Constructor is private, you should use getInstance() instead. - */ - private function __construct() { } - - /** - * Returns a singleton object corresponding to the requested instance id - * @param string Requested instance name - * @return Object Net_URL_Mapper Singleton - */ - public static function getInstance($id = '__default__') - { - if (!isset(self::$instances[$id])) { - $m = new Net_URL_Mapper(); - $m->id = $id; - self::$instances[$id] = $m; - } - return self::$instances[$id]; - } - - /** - * Returns the instance id - * @return string Mapper instance id - */ - public function getId() - { - return $this->id; - } - - /** - * Parses a path and creates a connection - * @param string The path to connect - * @param array Default values for path parts - * @param array Regular expressions for path parts - * @return object Net_URL_Mapper_Path - */ - public function connect($path, $defaults = array(), $rules = array()) - { - $pathObj = new Net_URL_Mapper_Path($path, $defaults, $rules); - $this->addPath($pathObj); - return $pathObj; - } - - /** - * Set the url prefix if needed - * - * Example: using the prefix to differenciate mapper instances - * - * $fr = Net_URL_Mapper::getInstance('fr'); - * $fr->setPrefix('/fr'); - * $en = Net_URL_Mapper::getInstance('en'); - * $en->setPrefix('/en'); - * - * - * @param string URL prefix - */ - public function setPrefix($prefix) - { - $this->prefix = '/'.trim($prefix, '/'); - } - - /** - * Set the scriptname if mod_rewrite not available - * - * Example: will match and generate url like - * - index.php/view/product/1 - * - * $m = Net_URL_Mapper::getInstance(); - * $m->setScriptname('index.php'); - * - * @param string URL prefix - */ - public function setScriptname($scriptname) - { - $this->scriptname = $scriptname; - } - - /** - * Will attempt to match an url with a defined path - * - * If an url corresponds to a path, the resulting values are returned - * in an array. If none is found, null is returned. In case an url is - * matched but its content doesn't validate the path rules, an exception is - * thrown. - * - * @param string URL - * @return array|null array if match found, null otherwise - * @throws Net_URL_Mapper_InvalidException - */ - public function match($url) - { - $nurl = '/'.trim($url, '/'); - - // Remove scriptname if needed - - if (!empty($this->scriptname) && - strpos($nurl, $this->scriptname) === 0) { - $nurl = substr($nurl, strlen($this->scriptname)); - if (empty($nurl)) { - $nurl = '/'; - } - } - - // Remove prefix - - if (!empty($this->prefix)) { - if (strpos($nurl, $this->prefix) !== 0) { - return null; - } - $nurl = substr($nurl, strlen($this->prefix)); - if (empty($nurl)) { - $nurl = '/'; - } - } - - // Remove query string - - if (($pos = strpos($nurl, '?')) !== false) { - $nurl = substr($nurl, 0, $pos); - } - - $paths = array(); - $values = null; - - // Make a list of paths that conform to route format - - foreach ($this->paths as $path) { - $regex = $path->getFormat(); - if (preg_match($regex, $nurl)) { - $paths[] = $path; - } - } - - // Make sure one of the paths found is valid - - foreach ($paths as $path) { - $regex = $path->getRule(); - if (preg_match($regex, $nurl, $matches)) { - $values = $path->getDefaults(); - array_shift($matches); - $clean = array(); - foreach ($matches as $k => $v) { - $v = trim($v, '/'); - if (!is_int($k) && $v !== '') { - $values[$k] = $v; - } - } - break; - } - } - - // A path conforms but does not validate - - if (is_null($values) && !empty($paths)) { - $e = new Net_URL_Mapper_InvalidException('A path was found but is invalid.'); - $e->setPath($paths[0]); - $e->setUrl($url); - throw $e; - } - - return $values; - } - - /** - * Generate an url based on given parameters - * - * Will attempt to find a path definition that matches the given parameters and - * will generate an url based on this path. - * - * @param array Values to be used for the url generation - * @param array Key/value pairs for query string if needed - * @param string Anchor (fragment) if needed - * @return string|false String if a rule was found, false otherwise - */ - public function generate($values = array(), $qstring = array(), $anchor = '') - { - // Use root path if any - - if (empty($values) && isset($this->paths['/'])) { - return $this->scriptname.$this->prefix.$this->paths['/']->generate($values, $qstring, $anchor); - } - - foreach ($this->paths as $path) { - $set = array(); - foreach ($values as $k => $v) { - if ($path->hasKey($k, $v)) { - $set[$k] = $v; - } - } - - if (count($set) == count($values) && - count($set) <= $path->getMaxKeys()) { - - $req = $path->getRequired(); - if (count(array_intersect(array_keys($set), $req)) != count($req)) { - continue; - } - $gen = $path->generate($set, $qstring, $anchor); - return $this->scriptname.$this->prefix.$gen; - } - } - return false; - } - - /** - * Returns defined paths - * @return array Array of paths - */ - public function getPaths() - { - return $this->paths; - } - - /** - * Reset all paths - * This is probably only useful for testing - */ - public function reset() - { - $this->paths = array(); - $this->prefix = ''; - } - - /** - * Add a new path to the mapper - * @param object Net_URL_Mapper_Path object - */ - public function addPath(Net_URL_Mapper_Path $path) - { - $this->paths[$path->getPath()] = $path; - } - -} -?> \ No newline at end of file diff --git a/extlib/Net/URL/Mapper/Exception.php b/extlib/Net/URL/Mapper/Exception.php deleted file mode 100644 index 1915ad9782..0000000000 --- a/extlib/Net/URL/Mapper/Exception.php +++ /dev/null @@ -1,104 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Exception.php 232857 2007-03-28 10:23:04Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -/** - * Base class for exceptions in PEAR - */ -require_once 'PEAR/Exception.php'; - -/** - * Base class for exceptions in Net_URL_Mapper package - * - * Such a base class is required by the Exception RFC: - * http://pear.php.net/pepr/pepr-proposal-show.php?id=132 - * It will rarely be thrown directly, its specialized subclasses will be - * thrown most of the time. - * - * @category Net - * @package Net_URL_Mapper - * @version Release: @package_version@ - */ -class Net_URL_Mapper_Exception extends PEAR_Exception -{ -} - -/** - * Exception thrown when a path is invalid - * - * A path can conform to a given structure, but contain invalid parameters. - * - * $m = Net_URL_Mapper::getInstance(); - * $m->connect('hi/:name', null, array('name'=>'[a-z]+')); - * $m->match('/hi/FOXY'); // Will throw the exception - * - * - * @category Net - * @package Net_URL_Mapper - * @version Release: @package_version@ - */ -class Net_URL_Mapper_InvalidException extends Net_URL_Mapper_Exception -{ - protected $path; - protected $url; - - public function setPath($path) - { - $this->path = $path; - } - - public function getPath() - { - return $this->path; - } - - public function setUrl($url) - { - $this->url = $url; - } - - public function getUrl() - { - return $this->url; - } -} -?> \ No newline at end of file diff --git a/extlib/Net/URL/Mapper/Part.php b/extlib/Net/URL/Mapper/Part.php deleted file mode 100644 index 087c368eea..0000000000 --- a/extlib/Net/URL/Mapper/Part.php +++ /dev/null @@ -1,142 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Part.php 232857 2007-03-28 10:23:04Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -abstract class Net_URL_Mapper_Part -{ - protected $defaults; - protected $rule; - protected $public; - protected $type; - protected $required = false; - - /** - * Part name if dynamic or content, generated from path - * @var string - */ - public $content; - - const DYNAMIC = 1; - const WILDCARD = 2; - const FIXED = 3; - - public function __construct($content, $path) - { - $this->content = $content; - $this->path = $path; - } - - public function setRule($rule) - { - $this->rule = $rule; - } - - abstract public function getFormat(); - - abstract public function getRule(); - - public function addSlash($str) - { - $str = trim($str, '/'); - if (($pos = strpos($this->path, '/')) !== false) { - if ($pos == 0) { - $str = '/'.$str; - } else { - $str .= '/'; - } - } - return $str; - } - - public function addSlashRegex($str) - { - $str = trim($str, '/'); - if (($pos = strpos($this->path, '/')) !== false) { - if ($pos == 0) { - $str = '\/'.$str; - } else { - $str .= '\/'; - } - } - if (!$this->isRequired()) { - $str = '('.$str.'|)'; - } - return $str; - } - - public function setDefaults($defaults) - { - $this->defaults = (string)$defaults; - } - - public function getType() - { - return $this->type; - } - - public function accept($visitor, $method = null) - { - $args = func_get_args(); - $visitor->$method($this, $args); - } - - public function setRequired($required) - { - $this->required = $required; - } - - public function isRequired() - { - return $this->required; - } - - abstract public function generate($value = null); - - public function match($value) - { - $rule = $this->getRule(); - return preg_match('/^'.$rule.'$/', $this->addSlash($value)); - } - -} - -?> \ No newline at end of file diff --git a/extlib/Net/URL/Mapper/Part/Dynamic.php b/extlib/Net/URL/Mapper/Part/Dynamic.php deleted file mode 100644 index 914afa4211..0000000000 --- a/extlib/Net/URL/Mapper/Part/Dynamic.php +++ /dev/null @@ -1,81 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Dynamic.php 232857 2007-03-28 10:23:04Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -require_once 'Net/URL/Mapper/Part.php'; - -class Net_URL_Mapper_Part_Dynamic extends Net_URL_Mapper_Part -{ - - public function __construct($content, $path) - { - $this->type = Net_URL_Mapper_Part::DYNAMIC; - $this->setRequired(true); - parent::__construct($content, $path); - } - - public function getFormat() - { - return $this->addSlashRegex('[^\/]+'); - } - - public function getRule() - { - if (!empty($this->rule)) { - return '(?P<'.$this->content.'>'.$this->addSlashRegex($this->rule).')'; - } - return '(?P<'.$this->content.'>'.$this->addSlashRegex('[^\/]+').')'; - } - - public function generate($value = null) - { - if (is_array($value) && isset($value[$this->content])) { - $val = $value[$this->content]; - } elseif (!is_array($value) && !is_null($value)) { - $val = $value; - } else { - $val = $this->defaults; - } - return $this->addSlash(urlencode($val)); - } -} -?> \ No newline at end of file diff --git a/extlib/Net/URL/Mapper/Part/Fixed.php b/extlib/Net/URL/Mapper/Part/Fixed.php deleted file mode 100644 index 7d94973eac..0000000000 --- a/extlib/Net/URL/Mapper/Part/Fixed.php +++ /dev/null @@ -1,70 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Fixed.php 232857 2007-03-28 10:23:04Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -require_once 'Net/URL/Mapper/Part.php'; - -class Net_URL_Mapper_Part_Fixed extends Net_URL_Mapper_Part -{ - - public function __construct($content, $path) - { - $this->type = Net_URL_Mapper_Part::FIXED; - parent::__construct($content, $path); - } - - public function getFormat() - { - return $this->getRule(); - } - - public function getRule() - { - return preg_quote($this->path, '/'); - } - - public function generate($value = null) - { - return $this->path; - } -} -?> \ No newline at end of file diff --git a/extlib/Net/URL/Mapper/Part/Wildcard.php b/extlib/Net/URL/Mapper/Part/Wildcard.php deleted file mode 100644 index 84e29e1306..0000000000 --- a/extlib/Net/URL/Mapper/Part/Wildcard.php +++ /dev/null @@ -1,80 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Wildcard.php 232857 2007-03-28 10:23:04Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -require_once 'Net/URL/Mapper/Part.php'; - -class Net_URL_Mapper_Part_Wildcard extends Net_URL_Mapper_Part -{ - - public function __construct($content, $path) - { - $this->type = Net_URL_Mapper_Part::WILDCARD; - $this->setRequired(true); - parent::__construct($content, $path); - } - - public function getFormat() - { - return $this->addSlashRegex('.*');; - } - - public function getRule() - { - return '(?P<'.$this->content.'>'.$this->addSlashRegex('.*').')'; - } - - public function generate($value = null) - { - if (is_array($value) && isset($value[$this->content])) { - $val = $value[$this->content]; - } elseif (!is_array($value) && !is_null($value)) { - $val = $value; - } else { - $val = $this->defaults; - } - return $this->addSlash(str_replace( - array('%2F', '%23'), - array('/', '#'), urlencode($val))); - } -} -?> \ No newline at end of file diff --git a/extlib/Net/URL/Mapper/Path.php b/extlib/Net/URL/Mapper/Path.php deleted file mode 100644 index b459fa1fd3..0000000000 --- a/extlib/Net/URL/Mapper/Path.php +++ /dev/null @@ -1,451 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Path.php 296456 2010-03-20 00:41:08Z kguest $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -require_once 'Net/URL.php'; -require_once 'Net/URL/Mapper/Part/Dynamic.php'; -require_once 'Net/URL/Mapper/Part/Wildcard.php'; -require_once 'Net/URL/Mapper/Part/Fixed.php'; - -class Net_URL_Mapper_Path -{ - private $path = ''; - private $N = 0; - public $token; - public $value; - private $line = 1; - private $state = 1; - - - protected $alias; - protected $rules = array(); - protected $defaults = array(); - protected $parts = array(); - protected $rule; - protected $format; - protected $minKeys; - protected $maxKeys; - protected $fixed = true; - protected $required; - - public function __construct($path = '', $defaults = array(), $rules = array()) - { - $this->path = '/'.trim(Net_URL::resolvePath($path), '/'); - $this->setDefaults($defaults); - $this->setRules($rules); - - try { - $this->parsePath(); - } catch (Exception $e) { - // The path could not be parsed correctly, treat it as fixed - $this->fixed = true; - $part = self::createPart(Net_URL_Mapper_Part::FIXED, $this->path, $this->path); - $this->parts = array($part); - } - $this->getRequired(); - } - - /** - * Called when the object is serialized - * Make sure we do not store too much info when the object is serialized - * and call the regular expressions generator functions so that they will - * not need to be generated again on wakeup. - * - * @return array Name of properties to store when serialized - */ - public function __sleep() - { - $this->getFormat(); - $this->getRule(); - return array('alias', 'path', 'defaults', 'rule', 'format', - 'parts', 'minKeys', 'maxKeys', 'fixed', 'required'); - } - - public function getPath() - { - return $this->path; - } - - protected function parsePath() - { - while ($this->yylex()) { } - } - - /** - * Get the path alias - * Path aliases can be used instead of full path - * @return null|string - */ - public function getAlias() - { - return $this->alias; - } - - /** - * Set the path name - * @param string Set the path name - * @see getAlias() - */ - public function setAlias($alias) - { - $this->alias = $alias; - return $this; - } - - /** - * Get the path parts default values - * @return null|array - */ - public function getDefaults() - { - return $this->defaults; - } - - /** - * Set the path parts default values - * @param array Associative array with format partname => value - */ - public function setDefaults($defaults) - { - if (is_array($defaults)) { - $this->defaults = $defaults; - } else { - $this->defaults = array(); - } - } - - /** - * Set the path parts default values - * @param array Associative array with format partname => value - */ - public function setRules($rules) - { - if (is_array($rules)) { - $this->rules = $rules; - } else { - $this->rules = array(); - } - } - - /** - * Returns the regular expression used to match this path - * @return string PERL Regular expression - */ - public function getRule() - { - if (is_null($this->rule)) { - $this->rule = '/^'; - foreach ($this->parts as $path => $part) { - $this->rule .= $part->getRule(); - } - $this->rule .= '$/'; - } - return $this->rule; - } - - public function getFormat() - { - if (is_null($this->format)) { - $this->format = '/^'; - foreach ($this->parts as $path => $part) { - $this->format .= $part->getFormat(); - } - $this->format .= '$/'; - } - return $this->format; - } - - protected function addPart($part) - { - if (array_key_exists($part->content, $this->defaults)) { - $part->setRequired(false); - $part->setDefaults($this->defaults[$part->content]); - } - if (isset($this->rules[$part->content])) { - $part->setRule($this->rules[$part->content]); - } - $this->rule = null; - if ($part->getType() != Net_URL_Mapper_Part::FIXED) { - $this->fixed = false; - $this->parts[$part->content] = $part; - } else { - $this->parts[] = $part; - } - return $part; - } - - public static function createPart($type, $content, $path) - { - switch ($type) { - case Net_URL_Mapper_Part::DYNAMIC: - return new Net_URL_Mapper_Part_Dynamic($content, $path); - break; - case Net_URL_Mapper_Part::WILDCARD: - return new Net_URL_Mapper_Part_Wildcard($content, $path); - break; - default: - return new Net_URL_Mapper_Part_Fixed($content, $path); - } - } - - /** - * Checks whether the path contains the given part by name - * If value parameter is given, the part also checks if the - * given value conforms to the part rule. - * @param string Part name - * @param mixed The value to check against - */ - public function hasKey($partName, $value = null) - { - if (array_key_exists($partName, $this->parts)) { - if (!is_null($value) && $value !== false) { - return $this->parts[$partName]->match($value); - } else { - return true; - } - } elseif (array_key_exists($partName, $this->defaults) && - $value == $this->defaults[$partName]) { - return true; - } - return false; - } - - public function generate($values = array(), $qstring = array(), $anchor = '') - { - $path = ''; - foreach ($this->parts as $part) { - $path .= $part->generate($values); - } - $path = '/'.trim(Net_URL::resolvePath($path), '/'); - if (!empty($qstring)) { - if(strpos($path, '?') === false) { - $path .= '?'; - } else { - $path .= '&'; - } - $path .= http_build_query($qstring); - } - if (!empty($anchor)) { - $path .= '#'.ltrim($anchor, '#'); - } - return $path; - } - - public function getRequired() - { - if (!isset($this->required)) { - $req = array(); - foreach ($this->parts as $part) { - if ($part->isRequired()) { - $req[] = $part->content; - } - } - $this->required = $req; - } - return $this->required; - } - - public function getMaxKeys() - { - if (is_null($this->maxKeys)) { - $this->maxKeys = count($this->required); - $this->maxKeys += count($this->defaults); - } - return $this->maxKeys; - } - - - - - private $_yy_state = 1; - private $_yy_stack = array(); - - function yylex() - { - return $this->{'yylex' . $this->_yy_state}(); - } - - function yypushstate($state) - { - array_push($this->_yy_stack, $this->_yy_state); - $this->_yy_state = $state; - } - - function yypopstate() - { - $this->_yy_state = array_pop($this->_yy_stack); - } - - function yybegin($state) - { - $this->_yy_state = $state; - } - - - - function yylex1() - { - $tokenMap = array ( - 1 => 1, - 3 => 1, - 5 => 1, - 7 => 1, - 9 => 1, - ); - if ($this->N >= strlen($this->path)) { - return false; // end of input - } - $yy_global_pattern = "/^(\/?:\/?\\(([a-zA-Z0-9_]+)\\))|^(\/?\\*\/?\\(([a-zA-Z0-9_]+)\\))|^(\/?:([a-zA-Z0-9_]+))|^(\/?\\*([a-zA-Z0-9_]+))|^(\/?([^\/:*]+))/"; - - do { - if (preg_match($yy_global_pattern, substr($this->path, $this->N), $yymatches)) { - $yysubmatches = $yymatches; - $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns - if (!count($yymatches)) { - throw new Exception('Error: lexing failed because a rule matched' . - 'an empty string. Input "' . substr($this->path, - $this->N, 5) . '... state START'); - } - next($yymatches); // skip global match - $this->token = key($yymatches); // token number - if ($tokenMap[$this->token]) { - // extract sub-patterns for passing to lex function - $yysubmatches = array_slice($yysubmatches, $this->token + 1, - $tokenMap[$this->token]); - } else { - $yysubmatches = array(); - } - $this->value = current($yymatches); // token value - $r = $this->{'yy_r1_' . $this->token}($yysubmatches); - if ($r === null) { - $this->N += strlen($this->value); - $this->line += substr_count("\n", $this->value); - // accept this token - return true; - } elseif ($r === true) { - // we have changed state - // process this token in the new state - return $this->yylex(); - } elseif ($r === false) { - $this->N += strlen($this->value); - $this->line += substr_count("\n", $this->value); - if ($this->N >= strlen($this->path)) { - return false; // end of input - } - // skip this token - continue; - } else { $yy_yymore_patterns = array( - 1 => "^(\/?\\*\/?\\(([a-zA-Z0-9_]+)\\))|^(\/?:([a-zA-Z0-9_]+))|^(\/?\\*([a-zA-Z0-9_]+))|^(\/?([^\/:*]+))", - 3 => "^(\/?:([a-zA-Z0-9_]+))|^(\/?\\*([a-zA-Z0-9_]+))|^(\/?([^\/:*]+))", - 5 => "^(\/?\\*([a-zA-Z0-9_]+))|^(\/?([^\/:*]+))", - 7 => "^(\/?([^\/:*]+))", - 9 => "", - ); - - // yymore is needed - do { - if (!strlen($yy_yymore_patterns[$this->token])) { - throw new Exception('cannot do yymore for the last token'); - } - if (preg_match($yy_yymore_patterns[$this->token], - substr($this->path, $this->N), $yymatches)) { - $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns - next($yymatches); // skip global match - $this->token = key($yymatches); // token number - $this->value = current($yymatches); // token value - $this->line = substr_count("\n", $this->value); - } - } while ($this->{'yy_r1_' . $this->token}() !== null); - // accept - $this->N += strlen($this->value); - $this->line += substr_count("\n", $this->value); - return true; - } - } else { - throw new Exception('Unexpected input at line' . $this->line . - ': ' . $this->path[$this->N]); - } - break; - } while (true); - } // end function - - - const START = 1; - function yy_r1_1($yy_subpatterns) - { - - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::DYNAMIC, $c, $this->value); - $this->addPart($part); - } - function yy_r1_3($yy_subpatterns) - { - - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::WILDCARD, $c, $this->value); - $this->addPart($part); - } - function yy_r1_5($yy_subpatterns) - { - - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::DYNAMIC, $c, $this->value); - $this->addPart($part); - } - function yy_r1_7($yy_subpatterns) - { - - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::WILDCARD, $c, $this->value); - $this->addPart($part); - } - function yy_r1_9($yy_subpatterns) - { - - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::FIXED, $c, $this->value); - $this->addPart($part); - } - -} - -?> diff --git a/extlib/Net/URL/Mapper/Path.plex b/extlib/Net/URL/Mapper/Path.plex deleted file mode 100644 index c5ef1f88ea..0000000000 --- a/extlib/Net/URL/Mapper/Path.plex +++ /dev/null @@ -1,334 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category Net - * @package Net_URL_Mapper - * @author Bertrand Mansion - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Path.plex 283937 2009-07-12 11:37:21Z mansion $ - * @link http://pear.php.net/package/Net_URL_Mapper - */ - -require_once 'Net/URL/Mapper/Part/Dynamic.php'; -require_once 'Net/URL/Mapper/Part/Wildcard.php'; -require_once 'Net/URL/Mapper/Part/Fixed.php'; - -class Net_URL_Mapper_Path -{ - private $path = ''; - private $N = 0; - public $token; - public $value; - private $line = 1; - private $state = 1; - - - protected $alias; - protected $rules = array(); - protected $defaults = array(); - protected $parts = array(); - protected $rule; - protected $format; - protected $minKeys; - protected $maxKeys; - protected $fixed = true; - protected $required; - - public function __construct($path = '', $defaults = array(), $rules = array()) - { - $this->path = '/'.trim(Net_URL::resolvePath($path), '/'); - $this->setDefaults($defaults); - $this->setRules($rules); - - try { - $this->parsePath(); - } catch (Exception $e) { - // The path could not be parsed correctly, treat it as fixed - $this->fixed = true; - $part = self::createPart(Net_URL_Mapper_Part::FIXED, $this->path, $this->path); - $this->parts = array($part); - } - $this->getRequired(); - } - - /** - * Called when the object is serialized - * Make sure we do not store too much info when the object is serialized - * and call the regular expressions generator functions so that they will - * not need to be generated again on wakeup. - * - * @return array Name of properties to store when serialized - */ - public function __sleep() - { - $this->getFormat(); - $this->getRule(); - return array('alias', 'path', 'defaults', 'rule', 'format', - 'parts', 'minKeys', 'maxKeys', 'fixed', 'required'); - } - - public function getPath() - { - return $this->path; - } - - protected function parsePath() - { - while ($this->yylex()) { } - } - - /** - * Get the path alias - * Path aliases can be used instead of full path - * @return null|string - */ - public function getAlias() - { - return $this->alias; - } - - /** - * Set the path name - * @param string Set the path name - * @see getAlias() - */ - public function setAlias($alias) - { - $this->alias = $alias; - return $this; - } - - /** - * Get the path parts default values - * @return null|array - */ - public function getDefaults() - { - return $this->defaults; - } - - /** - * Set the path parts default values - * @param array Associative array with format partname => value - */ - public function setDefaults($defaults) - { - if (is_array($defaults)) { - $this->defaults = $defaults; - } else { - $this->defaults = array(); - } - } - - /** - * Set the path parts default values - * @param array Associative array with format partname => value - */ - public function setRules($rules) - { - if (is_array($rules)) { - $this->rules = $rules; - } else { - $this->rules = array(); - } - } - - /** - * Returns the regular expression used to match this path - * @return string PERL Regular expression - */ - public function getRule() - { - if (is_null($this->rule)) { - $this->rule = '/^'; - foreach ($this->parts as $path => $part) { - $this->rule .= $part->getRule(); - } - $this->rule .= '$/'; - } - return $this->rule; - } - - public function getFormat() - { - if (is_null($this->format)) { - $this->format = '/^'; - foreach ($this->parts as $path => $part) { - $this->format .= $part->getFormat(); - } - $this->format .= '$/'; - } - return $this->format; - } - - protected function addPart($part) - { - if (array_key_exists($part->content, $this->defaults)) { - $part->setRequired(false); - $part->setDefaults($this->defaults[$part->content]); - } - if (isset($this->rules[$part->content])) { - $part->setRule($this->rules[$part->content]); - } - $this->rule = null; - if ($part->getType() != Net_URL_Mapper_Part::FIXED) { - $this->fixed = false; - $this->parts[$part->content] = $part; - } else { - $this->parts[] = $part; - } - return $part; - } - - public static function createPart($type, $content, $path) - { - switch ($type) { - case Net_URL_Mapper_Part::DYNAMIC: - return new Net_URL_Mapper_Part_Dynamic($content, $path); - break; - case Net_URL_Mapper_Part::WILDCARD: - return new Net_URL_Mapper_Part_Wildcard($content, $path); - break; - default: - return new Net_URL_Mapper_Part_Fixed($content, $path); - } - } - - /** - * Checks whether the path contains the given part by name - * If value parameter is given, the part also checks if the - * given value conforms to the part rule. - * @param string Part name - * @param mixed The value to check against - */ - public function hasKey($partName, $value = null) - { - if (array_key_exists($partName, $this->parts)) { - if (!is_null($value) && $value !== false) { - return $this->parts[$partName]->match($value); - } else { - return true; - } - } elseif (array_key_exists($partName, $this->defaults) && - $value == $this->defaults[$partName]) { - return true; - } - return false; - } - - public function generate($values = array(), $qstring = array(), $anchor = '') - { - $path = ''; - foreach ($this->parts as $part) { - $path .= $part->generate($values); - } - $path = '/'.trim(Net_URL::resolvePath($path), '/'); - if (!empty($qstring)) { - $path .= '?'.http_build_query($qstring); - } - if (!empty($anchor)) { - $path .= '#'.ltrim($anchor, '#'); - } - return $path; - } - - public function getRequired() - { - if (!isset($this->required)) { - $req = array(); - foreach ($this->parts as $part) { - if ($part->isRequired()) { - $req[] = $part->content; - } - } - $this->required = $req; - } - return $this->required; - } - - public function getMaxKeys() - { - if (is_null($this->maxKeys)) { - $this->maxKeys = count($this->required); - $this->maxKeys += count($this->defaults); - } - return $this->maxKeys; - } - - - -/*!lex2php -%input $this->path -%counter $this->N -%token $this->token -%value $this->value -%line $this->line -static = /\/?([^\/:\*]+)/ -variable = /([a-zA-Z0-9_]+)/ -dynamic = /\/?:/ -wildcard = @/?\*@ -grouping = /\/?\(([a-zA-Z0-9_]+)\)/ -*/ -/*!lex2php -%statename START -dynamic grouping { - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::DYNAMIC, $c, $this->value); - $this->addPart($part); -} -wildcard grouping { - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::WILDCARD, $c, $this->value); - $this->addPart($part); -} -dynamic variable { - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::DYNAMIC, $c, $this->value); - $this->addPart($part); -} -wildcard variable { - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::WILDCARD, $c, $this->value); - $this->addPart($part); -} -static { - $c = $yy_subpatterns[0]; - $part = self::createPart(Net_URL_Mapper_Part::FIXED, $c, $this->value); - $this->addPart($part); -} -*/ -} - -?> \ No newline at end of file From 40924842f4fde6f832f7284a30177f72864f86f8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 12:15:56 -0400 Subject: [PATCH 05/24] new URLMapper without Net_URL_Mapper --- lib/router.php | 76 +------------- lib/urlmapper.php | 246 ++++++++++++++++++++++++++++++++++++++++++++++ lib/util.php | 6 +- 3 files changed, 253 insertions(+), 75 deletions(-) create mode 100644 lib/urlmapper.php diff --git a/lib/router.php b/lib/router.php index 180d8f791b..8fbb6eb1f4 100644 --- a/lib/router.php +++ b/lib/router.php @@ -31,73 +31,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -require_once 'Net/URL/Mapper.php'; - -class StatusNet_URL_Mapper extends Net_URL_Mapper -{ - private static $_singleton = null; - private $_actionToPath = array(); - - private function __construct() - { - } - - public static function getInstance($id = '__default__') - { - if (empty(self::$_singleton)) { - self::$_singleton = new StatusNet_URL_Mapper(); - } - return self::$_singleton; - } - - public function connect($path, $defaults = array(), $rules = array()) - { - $result = null; - if (Event::handle('StartConnectPath', array(&$path, &$defaults, &$rules, &$result))) { - $result = parent::connect($path, $defaults, $rules); - if (array_key_exists('action', $defaults)) { - $action = $defaults['action']; - } elseif (array_key_exists('action', $rules)) { - $action = $rules['action']; - } else { - $action = null; - } - $this->_mapAction($action, $result); - Event::handle('EndConnectPath', array($path, $defaults, $rules, $result)); - } - return $result; - } - - protected function _mapAction($action, $path) - { - if (!array_key_exists($action, $this->_actionToPath)) { - $this->_actionToPath[$action] = array(); - } - $this->_actionToPath[$action][] = $path; - return; - } - - public function generate($values = array(), $qstring = array(), $anchor = '') - { - if (!array_key_exists('action', $values)) { - return parent::generate($values, $qstring, $anchor); - } - - $action = $values['action']; - - if (!array_key_exists($action, $this->_actionToPath)) { - return parent::generate($values, $qstring, $anchor); - } - - $oldPaths = $this->paths; - $this->paths = $this->_actionToPath[$action]; - $result = parent::generate($values, $qstring, $anchor); - $this->paths = $oldPaths; - - return $result; - } -} - /** * URL Router * @@ -159,8 +92,8 @@ class Router * you're running and the plugins that are enabled. To avoid having bad routes * get stuck in the cache, the key includes a list of plugins and the software * version. - * - * There can still be problems with a) differences in versions of the plugins and + * + * There can still be problems with a) differences in versions of the plugins and * b) people running code between official versions, but these tend to be more * sophisticated users who can grok what's going on and clear their caches. * @@ -183,7 +116,7 @@ class Router function initialize() { - $m = StatusNet_URL_Mapper::getInstance(); + $m = new URLMapper(); if (Event::handle('StartInitializeRouter', array(&$m))) { @@ -1139,7 +1072,7 @@ class Router { try { $match = $this->m->match($path); - } catch (Net_URL_Mapper_InvalidException $e) { + } catch (Exception $e) { common_log(LOG_ERR, "Problem getting route for $path - " . $e->getMessage()); // TRANS: Client error on action trying to visit a non-existing page. @@ -1161,7 +1094,6 @@ class Router } $url = $this->m->generate($args, $params, $fragment); - // Due to a bug in the Net_URL_Mapper code, the returned URL may // contain a malformed query of the form ?p1=v1?p2=v2?p3=v3. We // repair that here rather than modifying the upstream code... diff --git a/lib/urlmapper.php b/lib/urlmapper.php new file mode 100644 index 0000000000..dffb32c814 --- /dev/null +++ b/lib/urlmapper.php @@ -0,0 +1,246 @@ +. + * + * @category Cache + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 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); +} + +/** + * URL mapper + * + * Converts a path into a set of parameters, and vice versa + * + * We used to use Net_URL_Mapper, so there's a wrapper class at Router, q.v. + * + * NUM's vagaries are the main reason we have weirdnesses here. + * + * @category URL + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class URLMapper +{ + const ACTION = 'action'; + + protected $statics = array(); + protected $variables = array(); + protected $reverse = array(); + + function connect($path, $args, $paramPatterns=null) + { + if (!array_key_exists(self::ACTION, $args)) { + throw new Exception(sprintf("Can't connect %s; path has no action.", $path)); + } + + $action = $args[self::ACTION]; + + $paramNames = $this->getParamNames($path); + + if (empty($paramNames)) { + $this->statics[$path] = $args; + if (array_key_exists($action, $this->reverse)) { + $this->reverse[$args[self::ACTION]][] = array($args, $path); + } else { + $this->reverse[$args[self::ACTION]] = array(array($args, $path)); + } + } else { + + // Eff if I understand why some go here and some go there. + // Anyways, fixup my preconceptions + + foreach ($paramNames as $name) { + if (!array_key_exists($name, $paramPatterns) && + array_key_exists($name, $args)) { + $paramPatterns[$name] = $args[$name]; + unset($args[$name]); + } + } + + $regex = $this->makeRegex($path, $paramPatterns); + + $this->variables[] = array($args, $regex, $paramNames); + + $format = $this->makeFormat($path, $paramPatterns); + + if (array_key_exists($action, $this->reverse)) { + $this->reverse[$args[self::ACTION]][] = array($args, $format, $paramNames); + } else { + $this->reverse[$args[self::ACTION]] = array(array($args, $format, $paramNames)); + } + } + } + + function match($path) + { + if (array_key_exists($path, $this->statics)) { + return $this->statics[$path]; + } + + foreach ($this->variables as $pattern) { + list($args, $regex, $paramNames) = $pattern; + if (preg_match($regex, $path, $match)) { + $results = $args; + foreach ($paramNames as $name) { + $results[$name] = $match[$name]; + } + return $results; + } + } + + throw new Exception(sprintf('No match for path "%s"', $path)); + } + + function generate($args, $qstring, $fragment) + { + if (!array_key_exists(self::ACTION, $args)) { + throw new Exception("Every path needs an action."); + } + + $action = $args[self::ACTION]; + + if (!array_key_exists($action, $this->reverse)) { + throw new Exception(sprintf('No candidate paths for action "%s"', $action)); + } + + $candidates = $this->reverse[$action]; + + foreach ($candidates as $candidate) { + if (count($candidate) == 2) { // static + list($tryArgs, $tryPath) = $candidate; + foreach ($tryArgs as $key => $value) { + if (!array_key_exists($key, $args) || $args[$key] != $value) { + // next candidate + continue 2; + } + } + // success + return $tryPath; + } else { + list($tryArgs, $format, $paramNames) = $candidate; + + foreach ($tryArgs as $key => $value) { + if (!array_key_exists($key, $args) || $args[$key] != $value) { + // next candidate + continue 2; + } + } + + // success + + $toFormat = array(); + + foreach ($paramNames as $name) { + if (!array_key_exists($name, $args)) { + // next candidate + continue 2; + } + $toFormat[] = $args[$name]; + } + + $path = vsprintf($format, $toFormat); + + if (!empty($qstring)) { + $path .= '?' . http_build_query($qstring); + } + + return $path; + } + } + + unset($args['action']); + + if (empty($args)) { + throw new Exception(sprintf('No matches for action "%s"', $action)); + } + + $argstring = ''; + + foreach ($args as $key => $value) { + $argstring .= "$key=$value "; + } + + throw new Exception(sprintf('No matches for action "%s" with arguments "%s"', $action, $argstring)); + } + + protected function getParamNames($path) + { + preg_match_all('/:(?P\w+)/', $path, $match); + return $match['name']; + } + + protected function makeRegex($path, $paramPatterns) + { + $pr = new PatternReplacer($paramPatterns); + + $regex = preg_replace_callback('/:(\w+)/', + array($pr, 'toPattern'), + $path); + + $regex = '#' . str_replace('#', '\#', $regex) . '#'; + + return $regex; + } + + protected function makeFormat($path, $paramPatterns) + { + $format = preg_replace('/(:\w+)/', '%s', $path); + + return $format; + } +} + +class PatternReplacer +{ + private $patterns; + + function __construct($patterns) + { + $this->patterns = $patterns; + } + + function toPattern($matches) + { + // trim out the : + $name = $matches[1]; + if (array_key_exists($name, $this->patterns)) { + $pattern = $this->patterns[$name]; + } else { + // ??? + $pattern = '\w+'; + } + return '(?P<'.$name.'>'.$pattern.')'; + } +} diff --git a/lib/util.php b/lib/util.php index ba705eb7fa..3658e3ceea 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1237,12 +1237,12 @@ function common_local_url($action, $args=null, $params=null, $fragment=null, $ad $ssl = common_is_sensitive($action); if (common_config('site','fancy')) { - $url = common_path(mb_substr($path, 1), $ssl, $addSession); + $url = common_path($path, $ssl, $addSession); } else { if (mb_strpos($path, '/index.php') === 0) { - $url = common_path(mb_substr($path, 1), $ssl, $addSession); + $url = common_path($path, $ssl, $addSession); } else { - $url = common_path('index.php'.$path, $ssl, $addSession); + $url = common_path('index.php/'.$path, $ssl, $addSession); } } Event::handle('EndLocalURL', array(&$action, &$params, &$fragment, &$addSession, &$url)); From fa18e6365e1222fc3698197555a27e19265241f6 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 12:18:22 -0400 Subject: [PATCH 06/24] add default groupdirectory route --- plugins/Directory/DirectoryPlugin.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/Directory/DirectoryPlugin.php b/plugins/Directory/DirectoryPlugin.php index ad7fc82049..06cfca02ef 100644 --- a/plugins/Directory/DirectoryPlugin.php +++ b/plugins/Directory/DirectoryPlugin.php @@ -132,6 +132,11 @@ class DirectoryPlugin extends Plugin array('filter' => '([0-9a-zA-Z_]{1,64}|0-9)') ); + $m->connect( + 'groups', + array('action' => 'groupdirectory') + ); + return true; } From 927eae908a1b7a26e011a1a7404fd95beb047d0e Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 12:18:46 -0400 Subject: [PATCH 07/24] Remove unused xrds stuff from profile (replace in OMB please) --- actions/showstream.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/actions/showstream.php b/actions/showstream.php index ca7af0f2ed..ee8bc18e72 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -92,9 +92,6 @@ class ShowstreamAction extends ProfileAction // For YADIS discovery, we also have a tag - header('X-XRDS-Location: '. common_local_url('xrds', array('nickname' => - $this->user->nickname))); - $this->showPage(); } @@ -171,11 +168,6 @@ class ShowstreamAction extends ProfileAction function extraHead() { - // for remote subscriptions etc. - $this->element('meta', array('http-equiv' => 'X-XRDS-Location', - 'content' => common_local_url('xrds', array('nickname' => - $this->user->nickname)))); - if ($this->profile->bio) { $this->element('meta', array('name' => 'description', 'content' => $this->profile->bio)); From 15ae1cddfebe4035947ede4a53a6d24e8505ddab Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 12:19:29 -0400 Subject: [PATCH 08/24] two useful functions for profiling --- lib/util.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/util.php b/lib/util.php index ba705eb7fa..f25bae38cc 100644 --- a/lib/util.php +++ b/lib/util.php @@ -2312,3 +2312,31 @@ function common_is_email($str) { return (strpos($str, '@') !== false); } + +function common_init_stats() +{ + global $_mem, $_ts; + + $_mem = memory_get_usage(true); + $_ts = microtime(true); +} + +function common_log_delta($comment=null) +{ + global $_mem, $_ts; + + $mold = $_mem; + $told = $_ts; + + $_mem = memory_get_usage(true); + $_ts = microtime(true); + + $mtotal = $_mem - $mold; + $ttotal = $_ts - $told; + + if (empty($comment)) { + $comment = 'Delta'; + } + + common_debug(sprintf("%s: %d %d", $comment, $mtotal, round($ttotal * 1000000))); +} From a4240db48f4c2a3b64af3265961a1776dd674865 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 12:27:20 -0400 Subject: [PATCH 09/24] Deal with default param patterns more effectively --- lib/urlmapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/urlmapper.php b/lib/urlmapper.php index dffb32c814..6367d70426 100644 --- a/lib/urlmapper.php +++ b/lib/urlmapper.php @@ -59,7 +59,7 @@ class URLMapper protected $variables = array(); protected $reverse = array(); - function connect($path, $args, $paramPatterns=null) + function connect($path, $args, $paramPatterns=array()) { if (!array_key_exists(self::ACTION, $args)) { throw new Exception(sprintf("Can't connect %s; path has no action.", $path)); From f6f147c0dbdbbcff27fc205abf8a417d5e8d2597 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 12:41:54 -0400 Subject: [PATCH 10/24] with new URLMapper, cached router takes more memory, time than re-generating --- lib/router.php | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/router.php b/lib/router.php index 8fbb6eb1f4..606b30e916 100644 --- a/lib/router.php +++ b/lib/router.php @@ -69,19 +69,7 @@ class Router function __construct() { if (empty($this->m)) { - if (!common_config('router', 'cache')) { - $this->m = $this->initialize(); - } else { - $k = self::cacheKey(); - $c = Cache::instance(); - $m = $c->get($k); - if (!empty($m)) { - $this->m = $m; - } else { - $this->m = $this->initialize(); - $c->set($k, $this->m); - } - } + $this->m = $this->initialize(); } } From 601573a8a929b22ec3c54c94f0e68a792bc83308 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 14 Sep 2011 16:13:54 -0400 Subject: [PATCH 11/24] don't forget to add qstring to static paths --- lib/urlmapper.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/urlmapper.php b/lib/urlmapper.php index 6367d70426..f16bf128ef 100644 --- a/lib/urlmapper.php +++ b/lib/urlmapper.php @@ -147,7 +147,7 @@ class URLMapper } } // success - return $tryPath; + $path = $tryPath; } else { list($tryArgs, $format, $paramNames) = $candidate; @@ -171,15 +171,18 @@ class URLMapper } $path = vsprintf($format, $toFormat); - - if (!empty($qstring)) { - $path .= '?' . http_build_query($qstring); - } - - return $path; } + + if (!empty($qstring)) { + $formatted = http_build_query($qstring); + $path .= '?' . $formatted; + } + + return $path; } + // failure; some reporting twiddles + unset($args['action']); if (empty($args)) { From 5eb6c0d73132a4fb408aca8ce88e4f75e1e79997 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 14 Sep 2011 16:25:50 -0700 Subject: [PATCH 12/24] Fix undefined variable --- lib/groupprofileblock.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/groupprofileblock.php b/lib/groupprofileblock.php index df383f0696..fc0679247b 100644 --- a/lib/groupprofileblock.php +++ b/lib/groupprofileblock.php @@ -117,7 +117,7 @@ class GroupProfileBlock extends ProfileBlock array('nickname' => $this->group->nickname)), // TRANS: Tooltip for menu item in the group navigation page. Only shown for group administrators. // TRANS: %s is the nickname of the group. - 'title' => sprintf(_m('TOOLTIP','Edit %s group properties'), $nickname)), + 'title' => sprintf(_m('TOOLTIP','Edit %s group properties'), $this->group->nickname)), // TRANS: Link text for link on user profile. _m('BUTTON','Edit')); $this->out->elementEnd('li'); @@ -126,7 +126,7 @@ class GroupProfileBlock extends ProfileBlock array('nickname' => $this->group->nickname)), // TRANS: Tooltip for menu item in the group navigation page. Only shown for group administrators. // TRANS: %s is the nickname of the group. - 'title' => sprintf(_m('TOOLTIP','Add or edit %s logo'), $nickname)), + 'title' => sprintf(_m('TOOLTIP','Add or edit %s logo'), $this->group->nickname)), // TRANS: Link text for link on user profile. _m('MENU','Logo')); $this->out->elementEnd('li'); From 7c57aab44e3fad989b85872d416d0c525dbb9de8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 15 Sep 2011 09:51:33 -0400 Subject: [PATCH 13/24] change category on urlmapper.php --- lib/urlmapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/urlmapper.php b/lib/urlmapper.php index f16bf128ef..35798cf282 100644 --- a/lib/urlmapper.php +++ b/lib/urlmapper.php @@ -20,7 +20,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @category Cache + * @category URL * @package StatusNet * @author Evan Prodromou * @copyright 2011 StatusNet, Inc. From 7c03a509474235d7f81d9d9e14a683f045882ce2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 15 Sep 2011 09:54:25 -0400 Subject: [PATCH 14/24] exact match for paths --- lib/urlmapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/urlmapper.php b/lib/urlmapper.php index 35798cf282..fcaa66a553 100644 --- a/lib/urlmapper.php +++ b/lib/urlmapper.php @@ -212,7 +212,7 @@ class URLMapper array($pr, 'toPattern'), $path); - $regex = '#' . str_replace('#', '\#', $regex) . '#'; + $regex = '#^' . str_replace('#', '\#', $regex) . '$#'; return $regex; } From 0b1d8762c6f0739052dc074152a9d7ec119c33fe Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 15 Sep 2011 11:00:27 -0400 Subject: [PATCH 15/24] include q as param, not arg for search sub menu --- plugins/SearchSub/searchsubmenu.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/plugins/SearchSub/searchsubmenu.php b/plugins/SearchSub/searchsubmenu.php index 755a3c9a5b..5973eb8b93 100644 --- a/plugins/SearchSub/searchsubmenu.php +++ b/plugins/SearchSub/searchsubmenu.php @@ -85,4 +85,23 @@ class SearchSubMenu extends MoreMenu return $items; } + + function item($actionName, $args, $label, $description, $id=null, $cls=null) + { + if (empty($id)) { + $id = $this->menuItemID($actionName, $args); + } + + // Add 'q' as a search param, not part of the url path + + $url = common_local_url($actionName, array(), $args); + + $this->out->menuItem($url, + $label, + $description, + $this->isCurrent($actionName, $args), + $id, + $cls); + } } + From 73afcad34c244f17706d686669a02abc1b709708 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 15 Sep 2011 17:05:32 -0400 Subject: [PATCH 16/24] add hooks for upgrades --- EVENTS.txt | 4 ++++ scripts/upgrade.php | 30 +++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/EVENTS.txt b/EVENTS.txt index 0a9759c246..922b79a865 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -1418,3 +1418,7 @@ StartShowInvitationSuccess: Right before showing invitations success msg EndShowInvitationSuccess: After showing invitations success msg - $action: invitation action +StartUpgrade: when starting a site upgrade + +EndUpgrade: when ending a site upgrade; good place to do your own upgrades + diff --git a/scripts/upgrade.php b/scripts/upgrade.php index 4c793ac15e..1bf444267c 100644 --- a/scripts/upgrade.php +++ b/scripts/upgrade.php @@ -33,23 +33,27 @@ require_once INSTALLDIR.'/scripts/commandline.inc'; function main() { - updateSchemaCore(); - updateSchemaPlugins(); + if (Event::handle('StartUpgrade')) { + updateSchemaCore(); + updateSchemaPlugins(); - // These replace old "fixup_*" scripts + // These replace old "fixup_*" scripts - fixupNoticeRendered(); - fixupNoticeConversation(); - initConversation(); - initInbox(); - fixupGroupURI(); + fixupNoticeRendered(); + fixupNoticeConversation(); + initConversation(); + initInbox(); + fixupGroupURI(); - initLocalGroup(); - initNoticeReshare(); + initLocalGroup(); + initNoticeReshare(); - initFaveURI(); - initSubscriptionURI(); - initGroupMemberURI(); + initFaveURI(); + initSubscriptionURI(); + initGroupMemberURI(); + + Event::handle('EndUpgrade'); + } } function tableDefs() From 6e480d2458bf4039ee0446187893203cd533dc40 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 15 Sep 2011 17:06:05 -0400 Subject: [PATCH 17/24] Upgrade 0.9.x bookmarks to 1.0.x --- plugins/Bookmark/BookmarkPlugin.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plugins/Bookmark/BookmarkPlugin.php b/plugins/Bookmark/BookmarkPlugin.php index 77b8a8483c..ff68917bcc 100644 --- a/plugins/Bookmark/BookmarkPlugin.php +++ b/plugins/Bookmark/BookmarkPlugin.php @@ -551,4 +551,25 @@ class BookmarkPlugin extends MicroAppPlugin // TRANS: Application title. return _m('TITLE','Bookmark'); } + + function onEndUpgrade() + { + // Version 0.9.x of the plugin didn't stamp notices + // with verb and object-type (for obvious reasons). Update + // those notices here. + + $notice = new Notice(); + + $notice->whereAdd('exists (select uri from bookmark where bookmark.uri = notice.uri)'); + $notice->whereAdd('((object_type is null) or (object_type = "' .ActivityObject::NOTE.'"))'); + + $notice->find(); + + while ($notice->fetch()) { + $original = clone($notice); + $notice->verb = ActivityVerb::POST; + $notice->object_type = ActivityObject::BOOKMARK; + $notice->update($original); + } + } } From 0bd26ed3f07e349129e6e72576f081f493779a78 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 15 Sep 2011 16:16:58 -0700 Subject: [PATCH 18/24] Store a list of all paths the router knows about (backward compatibility with Net_URL_Mapper) --- lib/urlmapper.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/urlmapper.php b/lib/urlmapper.php index fcaa66a553..d17493e21d 100644 --- a/lib/urlmapper.php +++ b/lib/urlmapper.php @@ -4,7 +4,7 @@ * Copyright (C) 2011, StatusNet, Inc. * * URL mapper - * + * * PHP version 5 * * This program is free software: you can redistribute it and/or modify @@ -40,7 +40,7 @@ if (!defined('STATUSNET')) { * Converts a path into a set of parameters, and vice versa * * We used to use Net_URL_Mapper, so there's a wrapper class at Router, q.v. - * + * * NUM's vagaries are the main reason we have weirdnesses here. * * @category URL @@ -58,6 +58,7 @@ class URLMapper protected $statics = array(); protected $variables = array(); protected $reverse = array(); + protected $allpaths = array(); function connect($path, $args, $paramPatterns=array()) { @@ -65,6 +66,8 @@ class URLMapper throw new Exception(sprintf("Can't connect %s; path has no action.", $path)); } + $allpaths[] = $path; + $action = $args[self::ACTION]; $paramNames = $this->getParamNames($path); @@ -119,7 +122,7 @@ class URLMapper return $results; } } - + throw new Exception(sprintf('No match for path "%s"', $path)); } @@ -173,7 +176,7 @@ class URLMapper $path = vsprintf($format, $toFormat); } - if (!empty($qstring)) { + if (!empty($qstring)) { $formatted = http_build_query($qstring); $path .= '?' . $formatted; } @@ -223,6 +226,11 @@ class URLMapper return $format; } + + public function getPaths() + { + return $this->allpaths; + } } class PatternReplacer From dcbf2f6871de7cd26815334b6977792e2b2f31df Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 15 Sep 2011 16:52:23 -0700 Subject: [PATCH 19/24] Better error handling when the email subsystem isn't working. The installer was dying trying to send a confirmation email to the initial user. --- lib/mail.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/mail.php b/lib/mail.php index 3f8a08f3ca..c93464a586 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -71,18 +71,25 @@ function mail_backend() */ function mail_send($recipients, $headers, $body) { - // XXX: use Mail_Queue... maybe - $backend = mail_backend(); - if (!isset($headers['Content-Type'])) { - $headers['Content-Type'] = 'text/plain; charset=UTF-8'; - } - assert($backend); // throws an error if it's bad - $sent = $backend->send($recipients, $headers, $body); - if (PEAR::isError($sent)) { - common_log(LOG_ERR, 'Email error: ' . $sent->getMessage()); + try { + // XXX: use Mail_Queue... maybe + $backend = mail_backend(); + + if (!isset($headers['Content-Type'])) { + $headers['Content-Type'] = 'text/plain; charset=UTF-8'; + } + + assert($backend); // throws an error if it's bad + $sent = $backend->send($recipients, $headers, $body); + return true; + } catch (PEAR_Exception $e) { + common_log( + LOG_ERR, + "Unable to send email - '{$e->getMessage()}'. " + . 'Is your mail subsystem set up correctly?' + ); return false; } - return true; } /** From ce84555a506d2986988fc3fcb0d25aace8b841c4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 16 Sep 2011 15:28:11 -0400 Subject: [PATCH 20/24] upgrade to beta4 --- README | 4 ++-- lib/framework.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index bdbf2fff90..bfb94cb9e3 100644 --- a/README +++ b/README @@ -2,8 +2,8 @@ README ------ -StatusNet 1.0.0beta3 -27 August 2011 +StatusNet 1.0.0beta4 +16 September 2011 This is the README file for StatusNet, the Open Source social networking platform. It includes installation instructions, diff --git a/lib/framework.php b/lib/framework.php index 5b8f84eea7..5c7ca6c476 100644 --- a/lib/framework.php +++ b/lib/framework.php @@ -20,7 +20,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } define('STATUSNET_BASE_VERSION', '1.0.0'); -define('STATUSNET_LIFECYCLE', 'beta3'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release' +define('STATUSNET_LIFECYCLE', 'beta4'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release' define('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE); define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility From fc3d52c120f219a1cdc57b9d2f7646c7231155f3 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 17 Sep 2011 14:37:19 -0400 Subject: [PATCH 21/24] disable routes that aren't available in single-user mode --- lib/action.php | 8 ++++++-- lib/publicgroupnav.php | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/action.php b/lib/action.php index 38685f928a..9612a82b71 100644 --- a/lib/action.php +++ b/lib/action.php @@ -324,8 +324,12 @@ class Action extends HTMLOutputter // lawsuit $this->script('xbImportNode.js'); $this->script('geometa.js'); } - $this->inlineScript('var _peopletagAC = "' . - common_local_url('peopletagautocomplete') . '";'); + // This route isn't available in single-user mode. + // Not sure why, but it causes errors here. + if (!common_config('singleuser', 'enabled')) { + $this->inlineScript('var _peopletagAC = "' . + common_local_url('peopletagautocomplete') . '";'); + } $this->showScriptMessages(); // Anti-framing code to avoid clickjacking attacks in older browsers. // This will show a blank page if the page is being framed, which is diff --git a/lib/publicgroupnav.php b/lib/publicgroupnav.php index 77243fda7a..2b9c418440 100644 --- a/lib/publicgroupnav.php +++ b/lib/publicgroupnav.php @@ -62,10 +62,12 @@ class PublicGroupNav extends Menu $this->action->elementStart('ul', array('class' => 'nav')); if (Event::handle('StartPublicGroupNav', array($this))) { - // TRANS: Menu item in search group navigation panel. - $this->out->menuItem(common_local_url('public'), _m('MENU','Public'), - // TRANS: Menu item title in search group navigation panel. - _('Public timeline'), $this->actionName == 'public', 'nav_timeline_public'); + if (!common_config('singleuser', 'enabled')) { + // TRANS: Menu item in search group navigation panel. + $this->out->menuItem(common_local_url('public'), _m('MENU','Public'), + // TRANS: Menu item title in search group navigation panel. + _('Public timeline'), $this->actionName == 'public', 'nav_timeline_public'); + } // TRANS: Menu item in search group navigation panel. $this->out->menuItem(common_local_url('groups'), _m('MENU','Groups'), @@ -84,10 +86,12 @@ class PublicGroupNav extends Menu _('Featured users'), $this->actionName == 'featured', 'nav_featured'); } - // TRANS: Menu item in search group navigation panel. - $this->out->menuItem(common_local_url('favorited'), _m('MENU','Popular'), - // TRANS: Menu item title in search group navigation panel. - _('Popular notices'), $this->actionName == 'favorited', 'nav_timeline_favorited'); + if (!common_config('singleuser', 'enabled')) { + // TRANS: Menu item in search group navigation panel. + $this->out->menuItem(common_local_url('favorited'), _m('MENU','Popular'), + // TRANS: Menu item title in search group navigation panel. + _('Popular notices'), $this->actionName == 'favorited', 'nav_timeline_favorited'); + } Event::handle('EndPublicGroupNav', array($this)); } From b80b0d6520b0488cde309d18da34604cd05b5664 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 17 Sep 2011 15:08:04 -0400 Subject: [PATCH 22/24] use correct redirect on logout of single-user site --- actions/logout.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/actions/logout.php b/actions/logout.php index 567d808cd1..4e51271d43 100644 --- a/actions/logout.php +++ b/actions/logout.php @@ -73,7 +73,13 @@ class LogoutAction extends Action } Event::handle('EndLogout', array($this)); - common_redirect(common_local_url('public'), 303); + if (common_config('singleuser', 'enabled')) { + $user = User::singleUser(); + common_redirect(common_local_url('showstream', + array('nickname' => $user->nickname))); + } else { + common_redirect(common_local_url('public'), 303); + } } } From 467b840c446c0a2760e1d6985c88b02111b9b9f2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 17 Sep 2011 15:08:38 -0400 Subject: [PATCH 23/24] move OMB-specific remote login button to OMB Plugin --- lib/accountprofileblock.php | 13 ------------- plugins/OMB/OMBPlugin.php | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/accountprofileblock.php b/lib/accountprofileblock.php index 59c2777601..4eca000c9e 100644 --- a/lib/accountprofileblock.php +++ b/lib/accountprofileblock.php @@ -138,9 +138,6 @@ class AccountProfileBlock extends ProfileBlock if (Event::handle('StartProfilePageActionsElements', array($this->out, $this->profile))) { if (empty($cur)) { // not logged in if (Event::handle('StartProfileRemoteSubscribe', array($this->out, $this->profile))) { - $this->out->elementStart('li', 'entity_subscribe'); - $this->showRemoteSubscribeLink(); - $this->out->elementEnd('li'); Event::handle('EndProfileRemoteSubscribe', array($this->out, $this->profile)); } } else { @@ -298,16 +295,6 @@ class AccountProfileBlock extends ProfileBlock $this->out->elementEnd('li'); } - function showRemoteSubscribeLink() - { - $url = common_local_url('remotesubscribe', - array('nickname' => $this->profile->nickname)); - $this->out->element('a', array('href' => $url, - 'class' => 'entity_remote_subscribe'), - // TRANS: Link text for link that will subscribe to a remote profile. - _m('BUTTON','Subscribe')); - } - function show() { $this->out->elementStart('div', 'profile_block account_profile_block section'); diff --git a/plugins/OMB/OMBPlugin.php b/plugins/OMB/OMBPlugin.php index c532c4c894..de0088cc8e 100644 --- a/plugins/OMB/OMBPlugin.php +++ b/plugins/OMB/OMBPlugin.php @@ -377,6 +377,20 @@ class OMBPlugin extends Plugin return true; } + function onStartProfileRemoteSubscribe($out, $profile) + { + $out->elementStart('li', 'entity_subscribe'); + $url = common_local_url('remotesubscribe', + array('nickname' => $this->profile->nickname)); + $out->element('a', array('href' => $url, + 'class' => 'entity_remote_subscribe'), + // TRANS: Link text for link that will subscribe to a remote profile. + _m('BUTTON','Subscribe')); + $out->elementEnd('li'); + + return false; + } + /** * Plugin version info * From 70fbdb6f94848c5c08b0b6e30905d875156b8233 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Sat, 17 Sep 2011 13:27:14 -0700 Subject: [PATCH 24/24] Change time format to work with older PHP (before 5.3) --- plugins/Event/eventform.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Event/eventform.php b/plugins/Event/eventform.php index f62571ce63..8100e5903b 100644 --- a/plugins/Event/eventform.php +++ b/plugins/Event/eventform.php @@ -124,7 +124,7 @@ class EventForm extends Form $this->li(); $times = EventTimeList::getTimes($today->format('m/d/Y 12:00') . ' am ' . $today->format('T')); - $start = EventTimeList::nearestHalfHour('@' . $today->getTimestamp()); + $start = EventTimeList::nearestHalfHour($today->format('c')); $start->setTimezone(new DateTimeZone(common_timezone())); $this->out->dropdown( @@ -160,7 +160,7 @@ class EventForm extends Form 'event-endtime', // TRANS: Field label on event form. _m('LABEL','End time'), - EventTimeList::getTimes('@' . $start->getTimestamp(), true), + EventTimeList::getTimes($start->format('c'), true), // TRANS: Field title on event form. _m('Time the event ends.'), false,