Own component create ROUTER file and SEF links

For Joomla! 4.x Coding related discussions, you could also use: http://groups.google.com/group/joomla-dev-general

Moderators: ooffick, General Support Moderators

Forum rules
Forum Rules
Absolute Beginner's Guide to Joomla! <-- please read before posting, this means YOU.
Forum Post Assistant - If you are serious about wanting help, you will use this tool to help you post.
Windows Defender SmartScreen Issues <-- please read this if using Windows 10.
Post Reply
krzys1985b
Joomla! Fledgling
Joomla! Fledgling
Posts: 1
Joined: Tue Dec 08, 2009 1:45 pm

Own component create ROUTER file and SEF links

Post by krzys1985b » Fri Dec 29, 2023 12:45 pm

Hello

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));
    }
}
I also have the following files:
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']);
    }
}
and com_hotels\src\Helper\RouteHelper.php

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;
    }
}
When I create a link to a country in the Menu, it displays a page with a list of assigned regions with links to the region created by RouteHelper.php

Code: Select all

<a href="<?php echo Route::_(HotelsHelperRoute::getStateRoute($item->id, $item->alias)); ?>"><?php echo $item->name; ?></a>
but the link looks like this:

Code: Select all

 http://localhost/joomla5/austria?view=state&id=369&alias=burgenland
When I create the Burgenland submenu, i.e. Austria->burgenland, and after clicking on the country menu, I get an error:

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
Unfortunately, for me it's [spam] and I don't even know what this error could mean...

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?
Last edited by toivo on Tue Jan 02, 2024 9:44 am, edited 1 time in total.
Reason: mod note: moved from 4.x Extensions

cjstrieter
Joomla! Fledgling
Joomla! Fledgling
Posts: 1
Joined: Fri Feb 09, 2024 4:57 pm

Re: Own component create ROUTER file and SEF links

Post by cjstrieter » Fri Feb 09, 2024 5:11 pm

What was the solution? I am developing a sports component and it works when I access a view/URL from a menu item but when I have <?php echo Route::_('index.php?option=com_jsports&view=teams'); ?> inside a template this message gets thrown. Any help/insight would be appreciated.


Post Reply

Return to “Joomla! 4.x Coding”