--=REKLAMA=--

Tworzenie dodatku systemowego do rozszerzenia JRouter

Z Joomla!WikiPL

Szablon:Incomplete Szablon:Review

Hakowanie JRouter

Router Joomla! może być wzbogacany o dodatkowe reguły przy użyciu metody attatchXRules. Można użyć do tego wtyczki, a nowe reguły będą miały zakres globalny.

Poniżej znajdują się dwa przykłady hakowania JRouter z użyciem reguł oraz wtyczek. W jednym przypadku będziemy wzbogacać wyniki zwracane przez JRouter, w drugim natomiast całkowicie je zastępować.

Wzbogacanie

JRouter zwraca tablicę zmiennych, które są następnie wykorzystywane przez API JInput by przesłonić aktualne tablice zmiennych _GET / _POST / _request. Całość jest dość prosta.

Joomla 2.5

class plgSystemMyRouterAugmentor extends JPlugin
{
	/**
	 * @return  void
	 */
	public function onAfterInitialise()
	{
		$app = JFactory::getApplication();
 
		// Get the router
		$router = $app->getRouter();
 
		// Dodawanie własnych reguł:
 
		// Tworzenie tablicy zwrotnej do wywołania metody augmentRoute  w tym obiekcie
		$augmentRouteCallback = array($this, 'augmentRoute');
 
		// Dołączanie callback'a do routera
		$router->attachBuildRule($augmentRouteCallback);
	}
 
	/**
	 * @param   JRouterSite  $router Router Joomla
	 * @param   JURI         $uri     URI do przetworzenia
	 *
	 * @return  array  tablica przetwarzanych zmiennych URI
	 */
	public function augmentRoute($router, $uri)
	{
		$vars = array();
 
		// Robienie czegoś ze zmiennymi
		$vars['augment'] = 'succeeded';
 
		/**
		 * Teraz w każdym module/komponencie w adresie URI znajdzie
		 * się ?augment=succeeded
		 */
		return $vars;
	}
}

Zastępowanie

Jeśli chcesz, całkowicie zmienne, wymaga to trochę więcej pracy. W tym przypadku trzeba wywołać metodę parsującą z piaskownicy, aby dowiedzieć się, jakie byłyby wyniki. Następnie można dodać / usunąć / zmienić te wyniki. Wreszcie, przed zwróceniem tych wyników do JRouter, trzeba oflagować JRouter, aby nie kontynuować przetwarzania wyników.

Joomla 2.5

define('ROUTER_MODE_SKIP_SEF', 2);
define('ROUTER_MODE_SKIP_RAW', -1);
 
class plgSystemMyRouterReplacor extends JPlugin
{
	/**
	 * @return  void
	 */
	public function onAfterInitialise()
	{
		$app = JFactory::getApplication();
 
		$router = $app->getRouter();
 
		$replaceRouteCallback = array($this, 'replaceRoute');
 
		$router->attachBuildRule($replaceRouteCallback);
	}
 
	/**
	 * @param   JRouterSite  &$router
	 * @param   JURI         &$uri
	 *
	 * @return  array
	 */
	public function replaceRoute($router, $uri)
	{
		$app = JFactory::getApplication('site');
		$vars = array();
 
		$siteRouter = $app->getRouter();
 
		/**
		 * aby uniknąć pułapki rekurencji, musimy się upewnić, że tylko 
		 * Router strony może nas wywołać! Mogliśmy usunąć własne 
		 * reguły myRouter ... ale to będzie działać tylko 
		 * wewnątrz naszej własnej metody! Jeśli ktoś również 
		 * robi to samo, to otrzymujemy małą rekurencję, gdzie
		 * wywołujemy parser który wywołuje nas a potem klonuje 
		 * router i wywołuje parser które wywołuje 
		 * je ponownie. Kręcimy się więc w kółko.
		 */
 
		if (spl_object_hash($router) != spl_object_hash($siteRouter))
		{
			// Wykryto rekurencję - przerywamy działanie
			return $vars;
		}
 
		/**
		 * Nadal chcemy sklonować router przekazany do nas.
		 * Od teraz reguły mogą się różnić
		 */
 
		$myRouter = clone $router;
 
		// Teraz przy użyciu metody Joomla! parsujemy URI
		$vars = $myRouter->parse($uri);
 
 
		$menuId = isset($vars['itemId']) ? $vars['itemId'] : 0;
 
		//Tutaj sprawdzamy czy wybrana pozycja menu jest tą która nas interesuje.
		//W takim wypadku ignorujemy oryginalny rout i kierujemy go na nasz komponent
		if ($menuId == 67)
		{
			$vars['option'] == 'com_my_custom_component';
		}
 
		/**
		 * zmienna $vars zawiera teraz oryginalne zmienne, jak i te
 		 * przetworzone przez nas. Nie ma potrzeby wykonywania
		 * niektórych procesów, dlatego należy odpalić odpowiedni Route, 
		 * aby nie dublować operacji. Użyjemy do tego własności z Route,
		 * które przyjmują stan JROUTER_MODE_RAW lub JROUTER_MODE_SEF. 
		 */
 
		$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 $vars;
	}
}

Dziękujemy za wkład

» Robertm,