]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Squashed commit of the following:
authorEvan Prodromou <evan@status.net>
Tue, 30 Nov 2010 14:57:02 +0000 (09:57 -0500)
committerEvan Prodromou <evan@status.net>
Tue, 30 Nov 2010 14:58:00 +0000 (09:58 -0500)
commit 39fdd181d95d2c39a3ea1ca330b10a99a92b961f
Author: Evan Prodromou <evan@status.net>
Date:   Mon Nov 29 10:37:49 2010 -0500

    use cache key prefix for router cache key

commit 4cb9e56941922489b83d6425c059cf770991e68f
Author: Evan Prodromou <evan@status.net>
Date:   Mon Nov 29 10:31:21 2010 -0500

    use a unique hashkey based on the software version and loaded plugins

commit 44458b48aef719543e11f83b41fded65cbcb8be9
Author: Evan Prodromou <evan@status.net>
Date:   Sat Nov 27 17:04:15 2010 -0500

    cache the NUM object

commit 809c188307a9b4ada15f3d7fa573a6034341efef
Author: Evan Prodromou <evan@status.net>
Date:   Sat Nov 27 15:44:12 2010 -0500

    accelerate routing by pivoting paths on actions

lib/router.php

index 9aaac7dfe39cb8cbc051ed264868a545b3e8fb0f..3ea93b7081ece458e640ec8c55f468144fd3f2cb 100644 (file)
@@ -33,13 +33,15 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
 
 require_once 'Net/URL/Mapper.php';
 
-class StatusNet_URL_Mapper extends Net_URL_Mapper {
+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)) {
@@ -53,10 +55,47 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper {
         $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;
+    }
 }
 
 /**
@@ -87,11 +126,48 @@ class Router
 
     function __construct()
     {
-        if (!$this->m) {
-            $this->m = $this->initialize();
+        if (empty($this->m)) {
+            $k = self::cacheKey();
+            $m = Cache::get($k);
+            if (!empty($m)) {
+                $this->m = $m;
+            } else {
+                $this->m = $this->initialize();
+                Cache::set($k, $this->m);
+            }
         }
     }
 
+    /**
+     * Create a unique hashkey for the router.
+     * 
+     * The router's url map can change based on the version of the software
+     * 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 
+     * 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.
+     * 
+     * @return string cache key string that should uniquely identify a router
+     */
+    
+    static function cacheKey()
+    {
+        $plugins     = StatusNet::getActivePlugins();
+       $names       = array();
+       
+       foreach ($plugins as $plugin) {
+           $names[] = $plugin[0];
+       }
+
+       $names = array_unique($names);
+       asort($names);
+       
+        return Cache::key('router:'.STATUSNET_VERSION.':'.implode(',', $names));
+    }
+    
     function initialize()
     {
         $m = StatusNet_URL_Mapper::getInstance();