]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/router.php
FacebookPlugin: Fix up FBML canvas app so it keeps working after
[quix0rs-gnu-social.git] / lib / router.php
index 00b2993734fe90a647b34f639ab603c51f256fce..e4d5e5286a0658e7b04fc82f074c6dc9e2e40318 100644 (file)
@@ -33,14 +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)) {
@@ -54,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;
+    }
 }
 
 /**
@@ -71,7 +109,6 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper {
  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link     http://status.net/
  */
-
 class Router
 {
     var $m = null;
@@ -89,11 +126,43 @@ class Router
 
     function __construct()
     {
-        if (!$this->m) {
-            $this->m = $this->initialize();
+        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);
+               }
+           }
         }
     }
 
+    /**
+     * 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()
+    {
+        return Cache::codeKey('router');
+    }
+    
     function initialize()
     {
         $m = StatusNet_URL_Mapper::getInstance();
@@ -276,7 +345,7 @@ class Router
 
             $m->connect('group/new', array('action' => 'newgroup'));
 
-            foreach (array('edit', 'join', 'leave') as $v) {
+            foreach (array('edit', 'join', 'leave', 'delete') as $v) {
                 $m->connect('group/:nickname/'.$v,
                             array('action' => $v.'group'),
                             array('nickname' => '[a-zA-Z0-9]+'));
@@ -553,11 +622,19 @@ class Router
                               'format' => '(xml|json)'));
             // blocks
 
+            $m->connect('api/blocks/create.:format',
+                        array('action' => 'ApiBlockCreate',
+                              'format' => '(xml|json)'));
+
             $m->connect('api/blocks/create/:id.:format',
                         array('action' => 'ApiBlockCreate',
                               'id' => '[a-zA-Z0-9]+',
                               'format' => '(xml|json)'));
 
+            $m->connect('api/blocks/destroy.:format',
+                        array('action' => 'ApiBlockDestroy',
+                              'format' => '(xml|json)'));
+
             $m->connect('api/blocks/destroy/:id.:format',
                         array('action' => 'ApiBlockDestroy',
                               'id' => '[a-zA-Z0-9]+',
@@ -692,7 +769,6 @@ class Router
             $m->connect('admin/snapshot', array('action' => 'snapshotadminpanel'));
             $m->connect('admin/license', array('action' => 'licenseadminpanel'));
 
-
             $m->connect('getfile/:filename',
                         array('action' => 'getfile'),
                         array('filename' => '[A-Za-z0-9._-]+'));
@@ -701,16 +777,7 @@ class Router
 
             if (common_config('singleuser', 'enabled')) {
 
-                $user = User::siteOwner();
-
-                if (!empty($user)) {
-                    $nickname = $user->nickname;
-                } else {
-                    $nickname = common_config('singleuser', 'nickname');
-                    if (empty($nickname)) {
-                        throw new ServerException(_("No single user defined for single-user mode."));
-                    }
-                }
+                $nickname = User::singleUserNickname();
 
                 foreach (array('subscriptions', 'subscribers',
                                'all', 'foaf', 'xrds',
@@ -765,9 +832,7 @@ class Router
                 $m->connect('',
                             array('action' => 'showstream',
                                   'nickname' => $nickname));
-
             } else {
-
                 $m->connect('', array('action' => 'public'));
                 $m->connect('rss', array('action' => 'publicrss'));
                 $m->connect('featuredrss', array('action' => 'featuredrss'));
@@ -848,7 +913,8 @@ class Router
         } catch (Net_URL_Mapper_InvalidException $e) {
             common_log(LOG_ERR, "Problem getting route for $path - " .
                        $e->getMessage());
-            $cac = new ClientErrorAction("Page not found.", 404);
+            // TRANS: Client error on action trying to visit a non-existing page.
+            $cac = new ClientErrorAction(_('Page not found.'), 404);
             $cac->showPage();
         }
 
@@ -875,7 +941,16 @@ class Router
         if ($qpos !== false) {
             $url = substr($url, 0, $qpos+1) .
               str_replace('?', '&', substr($url, $qpos+1));
+
+            // @fixme this is a hacky workaround for http_build_query in the
+            // lower-level code and bad configs that set the default separator
+            // to & instead of &. Encoded &s in parameters will not be
+            // affected.
+            $url = substr($url, 0, $qpos+1) .
+              str_replace('&', '&', substr($url, $qpos+1));
+
         }
+
         return $url;
     }
 }