Creating a System Plugin to augment JRouter

From Joomla! Documentation
(Difference between revisions)
Jump to: navigation, search
m (typo)
m (function name typo)
 
Line 51: Line 51:
 
   define('ROUTER_MODE_SKIP_RAW', -1);
 
   define('ROUTER_MODE_SKIP_RAW', -1);
 
   class plgSystemMyRouterReplacor extends JPlugin {
 
   class plgSystemMyRouterReplacor extends JPlugin {
     public function onAfterInitialize()
+
     public function onAfterInitialise()
 
     {
 
     {
 
       $app = JFactory::getApplication();
 
       $app = JFactory::getApplication();

Latest revision as of 06:28, 16 April 2013

Contents

[edit] Incomplete

Note

Please note that the content on this page is currently incomplete. Please treat it as a work in progress.

This article was last edited by Mihaibrehar (talk| contribs) 37 days ago. (Purge)


[edit] JRouter Hacking

The Joomla! Router can be modified with additional rules by using the attatchXRules methods. Ideally, this can be done from a system plugin so these rules will apply globally.

Here are 2 examples of hacking JRouter using rules and a System Plugin. One will augment the results returned by JRouter while the other will completely replace the results returned by JRouter

[edit] Augmentation

JRouter returns an array of variables which are then used through the API by JInput to override the actual _GET/_POST/_REQUEST variables. If you merely want to augment the variables being returned, then this is straightforward.

Joomla 2.5

  class plgSystemMyRouterAugmentor extends JPlugin {
    public function onAfterInitialise()
    {
     $app = JFactory::getApplication();
    // get the router
    $router = $app->getRouter();
    // add my own rules
    // create a callback array to call the augmentRoute method of this object
    $augmentCallback = array($this, 'augmentRoute');
    // attach the callback to the router
    $router->attachBuildRule($myRouterCallback);
    }
    /**
     * @param   JRouterSite &$router  The Joomla Site Router
     * @param   JURI  &$uri  The URI to parse
     *
     * @return  array  $vars The array of processed URI variables
    */
    public function augmentRoute ($router, $uri)
    {
      $vars = array();
      // do something to the vars
      $vars['augment'] = 'succeeded';
      // in this case, now to any Joomla! component/module it will look like ?augment=succeeded was in the url
      return $vars;
    }
  }

[edit] Replacement

JRouter returns an array of variables which are then used through the API by JInput to override the actual _GET/_POST/_REQUEST variables. If you want to completely replace these variables, this takes a bit more work. In this case you may need to call the parse method in a sandbox to find out what would have been the results. You can then add/delete/modify those results. Finally, before returning those results to JRouter for the site itself, you need to flag JRouter so it doesn't continue to process the results.

Joomla 2.5

  define('ROUTER_MODE_SKIP_SEF', 2);
  define('ROUTER_MODE_SKIP_RAW', -1);
  class plgSystemMyRouterReplacor extends JPlugin {
    public function onAfterInitialise()
    {
       $app = JFactory::getApplication();
      // get the router
      $router = $app->getRouter();
      // add my own rules
      // create a callback array to call the replaceRoute method of this object
      $augmentCallback = array($this, 'replaceRoute');
      // attach the callback to the router
      $router->attachBuildRule($myRouterCallback);
    }
    /**
     * @param   JRouterSite &$router  The Joomla Site Router
     * @param   JURI  &$uri  The URI to parse
     *
     * @return  array  $vars The array of processed URI variables
     */
    public function replaceRoute ($router, $uri)
    {
      global $app;
      // should we  use $app = JFactory::getApplication('site'); ?
      $vars = array();
      // get the true router
      $siteRouter= $app->getRouter()
     // to avoid a recursion trap, we need to make sure that only
     // the site router can call us!  We could have removed our own
     // rule the myRouter...but that would only work 
     // inside our own method!  If someone else is also
     // doing the same thing, we would have an ugly little
     // recursion where they call parse which calls us
     // and then we clone router and call parse which calls them
     // back, and forth and back and forth
     // friends don't let friends use recursion!
     if (spl_object_hash($router) != spl_object_hash($siteRouter)) {
       // oh no!  Abort, abort!
       return $vars;
      }
      // we still want to clone the router passed to us, not the true router
      // since the rules might be different
      $myRouter = clone $router;    
      //now use the power of Joomla! to parse this uri!
      $vars = $myRouter->parse($vars);
      //what is the menu id?  what is the airspeed velocity of an unladen swallow?
      $menuId = ? isset($vars['itemId'])  $vars['itemId'] : 0;
      // Please be smarter than this.  Load the menu and check the config.  Do something
      if ($menuId == 67) {
        // change the option to be a different component.
        $vars['option'] == 'com_my_custom_component';
      } 
      // $vars has both the merged values of what would have been calculated and our changes 
      // So force the siteRouter to skip more processing - no reason to process it twice!
      //$router->setMode(JROUTER_MODE_RAW);
      // if the router mode is RAW - integer 0, then _parseRawRoute will be called by JRouter
      //$router->setMode(JROUTER_MODE_SEF);
      // if the router mode is SEF - integer 1, then _parseSEFRoute will be called by JRouter
      // if we set it to something which is NOT SEF or RAW, nothing is done to it
      // false or null would be a logical choice, 
      //but since the comparison is == not === false, null and 0/RAW are the same
      // therefore we defined our own constants.
      // SEF/RAW is a binary condition of either a positive integer or not a positive integer[0]
      // so we extend that so SKIP_SEF becomes 2 so the if clause will fail, but anything else
      // counting on checking for if mode > 0 will work
      // and SKIP_RAW is -1, so anything counting on checking mode <=0 will work
      // if it is not 0 or 1, then we don't change it because something else
      // already triggered the skip.
      $mode = $router-getMode();
      if ($mode == JROUTER_MODE_RAW) {
        $router->setMode(ROUTER_MODE_SKIP_RAW);
      }
      if ($mode == JROUTER_MODE_SEF) {
        $router->setMode(ROUTER_MODE_SKIP_SEF);
      }   
      // return our custom variables
      return $vars;
    }
  }
Personal tools
Namespaces

Variants
Actions
Navigation
Joomla! Sites
Toolbox