Please help me and point me in the right direction.
I have a component, its main task is to display offers (hotels), I can't cope with creating an appropriate router so that the addresses look like this: www.sitename.pl/country/state/city/ID-hotel-name
My Router file: com_hotels\src\Service\Router.php
Code: Select all
<?php
namespace kb\Component\Hotels\Site\Service;
defined('_JEXEC') or die;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Categories\CategoryFactoryInterface;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Component\Router\RouterView;
use Joomla\CMS\Component\Router\RouterViewConfiguration;
use Joomla\CMS\Component\Router\Rules\MenuRules;
//use Joomla\CMS\Component\Router\Rules\NomenuRules;
use kb\Component\Hotels\Site\Service\HotelsNomenuRules as NomenuRules;
use Joomla\CMS\Component\Router\Rules\StandardRules;
use Joomla\CMS\Menu\AbstractMenu;
use Joomla\Database\DatabaseInterface;
/**
* Routing class of
*
* @since 3.3
*/
class Router extends RouterView
{
protected $noIDs = false;
/**
* The category factory
*
* @var CategoryFactoryInterface
*
* @since 4.0.0
*/
private $categoryFactory;
/**
* The db
*
* @var DatabaseInterface
*
* @since 4.0.0
*/
private $db;
/**
* Component router constructor
*
* @param SiteApplication $app The application object
* @param AbstractMenu $menu The menu object to work with
* @param CategoryFactoryInterface $categoryFactory The category object
* @param DatabaseInterface $db The database object
*/
public function __construct(SiteApplication $app, AbstractMenu $menu,
CategoryFactoryInterface $categoryFactory, DatabaseInterface $db)
{
$this->categoryFactory = $categoryFactory;
$this->db = $db;
$params = ComponentHelper::getParams('com_hotels');
$this->noIDs = (bool) $params->get('sef_ids');
$hotels = new RouterViewConfiguration('hotels');
$hotels->setKey('id');
$this->registerView($hotels);
$hotel = new RouterViewConfiguration('hotel');
$hotel->setKey('id');
$this->registerView($hotel);
$countries = new RouterViewConfiguration('countries');
$countries->setKey('id');
$this->registerView($countries);
$country = new RouterViewConfiguration('country');
$country->setKey('id');
$this->registerView($country);
$states = new RouterViewConfiguration('states');
$states->setKey('id');
$this->registerView($states);
$state = new RouterViewConfiguration('state');
$state->setKey('id');
$this->registerView($state);
$cities = new RouterViewConfiguration('cities');
$cities->setKey('id');
$this->registerView($cities);
$city = new RouterViewConfiguration('city');
$city->setKey('id');
$this->registerView($city);
parent::__construct($app, $menu);
$this->attachRule(new MenuRules($this));
$this->attachRule(new StandardRules($this));
// $this->attachRule(new NomenuRules($this));
}
}
com_hotels\src\Service\HotelsNomenuRules.php
Code: Select all
* Router this rule belongs to *
* @var RouterView
* @since 3.4
*/
protected $router;
/**
* Class constructor.
*
* @param RouterView $router Router this rule belongs to
*
* @since 3.4
*/
public function __construct(RouterView $router)
{
$this->router = $router;
}
/**
* Dummymethod to fullfill the interface requirements
*
* @param array &$query The query array to process
*
* @return void
*
* @since 3.4
* @codeCoverageIgnore
*/
public function preprocess(&$query)
{
$test = 'Test';
}
/**
* Parse a menu-less URL
*
* @param array &$segments The URL segments to parse
* @param array &$vars The vars that result from the segments
*
* @return void
*
* @since 3.4
*/
public function parse(&$segments, &$vars)
{
$vars['view'] = 'hotel';
$vars['id'] = substr($segments[0], strpos($segments[0], '-') + 1);
array_shift($segments);
array_shift($segments);
return;
}
/**
* Build a menu-less URL
*
* @param array &$query The vars that should be converted
* @param array &$segments The URL segments to create
*
* @return void
*
* @since 3.4
*/
public function build(&$query, &$segments)
{
if (!isset($query['view']) || (isset($query['view']) && $query['view'] !== 'hotel') || isset($query['format']))
{
return;
}
$segments[] = $query['view'] . '-' . $query['id'];
// the last part of the url may be missing
if (isset($query['slug'])) {
$segments[] = $query['slug'];
unset($query['slug']);
}
unset($query['view']);
unset($query['id']);
}
}
Code: Select all
<?php/**
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace kb\Component\Hotels\Site\Helper;
defined('_JEXEC') or die;
use Joomla\CMS\Categories\CategoryNode;
use Joomla\CMS\Language\Multilanguage;
/**
* Component Route Helper.
*
* @since 1.5
*/
abstract class RouteHelper
{
/**
* Get the article route.
*
* @param integer $id The route of the content item.
* @param integer $language The language code.
* @param string $layout The layout value.
*
* @return string The article route.
*
* @since 1.5
*/
public static function getHotelRoute($id, $alias, $language = 0, $layout = null)
{
// Create the link
$link = 'index.php?option=com_hotels&view=hotel&id=' . $id . '&slug=' . $alias;
if ($layout)
{
$link .= '&layout=' . $layout;
}
return $link;
}
public static function getCountryRoute($id, $slug, $language = 0, $layout = null)
{
// Create the link
$link = 'index.php?option=com_hotels&view=country&id=' . $id . '&slug=' . $slug;
if ($layout)
{
$link .= '&layout=' . $layout;
}
return $link;
}
public static function getStateRoute($id, $alias, $language = 0, $layout = null)
{
// Create the link
$link = 'index.php?option=com_hotels&view=state&id=' . $id . '&alias=' . $alias;
if ($layout)
{
$link .= '&layout=' . $layout;
}
return $link;
}
public static function getCityRoute($id, $alias, $language = 0, $layout = null)
{
// Create the link
$link = 'index.php?option=com_hotels&view=city&id=' . $id . '&alias=' . $alias;
if ($layout)
{
$link .= '&layout=' . $layout;
}
return $link;
}
/**
* Get the category route.
*
* @param integer $catid The category ID.
* @param integer $language The language code.
* @param string $layout The layout value.
*
* @return string The article route.
*
* @since 1.5
*/
public static function getHotelsRoute($language = 0, $layout = null)
{
$link = 'index.php?option=com_hotels&view=hotels';
if ($language && $language !== '*' && Multilanguage::isEnabled())
{
$link .= '&lang=' . $language;
}
if ($layout)
{
$link .= '&layout=' . $layout;
}
return $link;
}
}
Code: Select all
<a href="<?php echo Route::_(HotelsHelperRoute::getStateRoute($item->id, $item->alias)); ?>"><?php echo $item->name; ?></a>
Code: Select all
http://localhost/joomla5/austria?view=state&id=369&alias=burgenland
Code: Select all
0
Illegal offset type in isset or empty
Call Stack
# Function Location
1 () JROOT\libraries\src\Menu\AbstractMenu.php:164
2 Joomla\CMS\Menu\AbstractMenu->getItem() JROOT\libraries\src\Router\SiteRouter.php:439
3 Joomla\CMS\Router\SiteRouter->buildSefRoute() JROOT\libraries\src\Router\Router.php:407
4 Joomla\CMS\Router\Router->processBuildRules() JROOT\libraries\src\Router\Router.php:194
5 Joomla\CMS\Router\Router->build() JROOT\libraries\src\Router\Route.php:150
6 Joomla\CMS\Router\Route::link() JROOT\libraries\src\Router\Route.php:99
7 Joomla\CMS\Router\Route::_() JROOT\components\com_hotels\tmpl\country\default.php:50
8 include() JROOT\libraries\src\MVC\View\HtmlView.php:416
9 Joomla\CMS\MVC\View\HtmlView->loadTemplate() JROOT\libraries\src\MVC\View\HtmlView.php:204
10 Joomla\CMS\MVC\View\HtmlView->display() JROOT\components\com_hotels\src\View\Country\HtmlView.php:67
11 kb\Component\Hotels\Site\View\Country\HtmlView->display() JROOT\libraries\src\MVC\Controller\BaseController.php:697
12 Joomla\CMS\MVC\Controller\BaseController->display() JROOT\components\com_hotels\src\Controller\DisplayController.php:35
13 kb\Component\Hotels\Site\Controller\DisplayController->display() JROOT\libraries\src\MVC\Controller\BaseController.php:730
14 Joomla\CMS\MVC\Controller\BaseController->execute() JROOT\libraries\src\Dispatcher\ComponentDispatcher.php:143
15 Joomla\CMS\Dispatcher\ComponentDispatcher->dispatch() JROOT\libraries\src\Component\ComponentHelper.php:361
16 Joomla\CMS\Component\ComponentHelper::renderComponent() JROOT\libraries\src\Application\SiteApplication.php:218
17 Joomla\CMS\Application\SiteApplication->dispatch() JROOT\libraries\src\Application\SiteApplication.php:261
18 Joomla\CMS\Application\SiteApplication->doExecute() JROOT\libraries\src\Application\CMSApplication.php:306
19 Joomla\CMS\Application\CMSApplication->execute() JROOT\includes\app.php:58
20 require_once() JROOT\index.php:32
I followed the example of the mywalks component.
The general idea is that from the main menu, after clicking on a country, a page with a list of regions opens, after clicking on a region, a list of cities opens, and similarly, after clicking on a city, a list of hotels opens.
Am I going in the right direction or maybe this router file is not suitable for this page structure?