krzys1985b
29-12-2023, 10:24
Witam
Proszę o pomoc, nakierowanie na właściwe tory.
Mam komponent jego głównym zadaniem jest wyświetlanie ofert (hoteli), nie potrafię sobie poradzić ze stworzeniem odpowiedniego routera aby adresy wyglądały następująco: www.nazwastrony.pl/kraj/region/miasto/ID-nazwa-hotelu (http://www.nazwastrony.pl/kraj/region/miasto/ID-nazwa-hotelu)
Mój plik Router: com_hotels\src\Service\Router.php
<?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\RouterViewConfiguratio n;
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));
}
}
Do tego mam jeszcze pliki:
com_hotels\src\Service\HotelsNomenuRules.php
* 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']);
}
}
oraz com_hotels\src\Helper\RouteHelper.php
<?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;
}
}
W momencie jeśli utworzę w Menu odnośnik do kraju wyświetla mi stronę z listą przypisanych regionów z linkami do regionu które tworzy RouteHelper.php
<a href="<?php echo Route::_(HotelsHelperRoute::getStateRoute($item->id, $item->alias)); ?>"><?php echo $item->name; ?></a>
ale link wygląda następująco:
http://localhost/joomla5/austria?view=state&id=369&alias=burgenland
W momencie jak utworze podmenu burgenland czyli Austria->burgenland i po kliknięciu w menu kraju generuje mi błąd:
Illegal offset type in isset or empty
Home Page (http://localhost/joomla5/index.php)
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.p hp:46
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\HtmlV iew.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\Display Controller.php:35
13
kb\Component\Hotels\Site\Controller\DisplayControl ler->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::renderCompon ent()
JROOT\libraries\src\Application\SiteApplication.ph p:218
17
Joomla\CMS\Application\SiteApplication->dispatch()
JROOT\libraries\src\Application\SiteApplication.ph p: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
Niestety dla mnie to czarna magia i nie wiem nawet co ten błąd może oznaczać...
Wzorowałem się na komponencie mywalks (https://docs.joomla.org/J4.x:J4_Component_example_-_Mywalks).
Ogólnie zamysł jest taki ze z menu głównego po kliknięciu w kraj otwiera się strona z listą regionów, po kliknięciu w region lista miast, analogicznie po kliknięciu w miasto lista hoteli.
Czy idę w dobrym kierunku czy może ten plik routera się nie nadaje do takiej struktury strony?
Proszę o pomoc, nakierowanie na właściwe tory.
Mam komponent jego głównym zadaniem jest wyświetlanie ofert (hoteli), nie potrafię sobie poradzić ze stworzeniem odpowiedniego routera aby adresy wyglądały następująco: www.nazwastrony.pl/kraj/region/miasto/ID-nazwa-hotelu (http://www.nazwastrony.pl/kraj/region/miasto/ID-nazwa-hotelu)
Mój plik Router: com_hotels\src\Service\Router.php
<?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\RouterViewConfiguratio n;
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));
}
}
Do tego mam jeszcze pliki:
com_hotels\src\Service\HotelsNomenuRules.php
* 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']);
}
}
oraz com_hotels\src\Helper\RouteHelper.php
<?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;
}
}
W momencie jeśli utworzę w Menu odnośnik do kraju wyświetla mi stronę z listą przypisanych regionów z linkami do regionu które tworzy RouteHelper.php
<a href="<?php echo Route::_(HotelsHelperRoute::getStateRoute($item->id, $item->alias)); ?>"><?php echo $item->name; ?></a>
ale link wygląda następująco:
http://localhost/joomla5/austria?view=state&id=369&alias=burgenland
W momencie jak utworze podmenu burgenland czyli Austria->burgenland i po kliknięciu w menu kraju generuje mi błąd:
Illegal offset type in isset or empty
Home Page (http://localhost/joomla5/index.php)
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.p hp:46
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\HtmlV iew.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\Display Controller.php:35
13
kb\Component\Hotels\Site\Controller\DisplayControl ler->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::renderCompon ent()
JROOT\libraries\src\Application\SiteApplication.ph p:218
17
Joomla\CMS\Application\SiteApplication->dispatch()
JROOT\libraries\src\Application\SiteApplication.ph p: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
Niestety dla mnie to czarna magia i nie wiem nawet co ten błąd może oznaczać...
Wzorowałem się na komponencie mywalks (https://docs.joomla.org/J4.x:J4_Component_example_-_Mywalks).
Ogólnie zamysł jest taki ze z menu głównego po kliknięciu w kraj otwiera się strona z listą regionów, po kliknięciu w region lista miast, analogicznie po kliknięciu w miasto lista hoteli.
Czy idę w dobrym kierunku czy może ten plik routera się nie nadaje do takiej struktury strony?