Routing in Phalcon - parameter before the end of the route - php

I'm trying to set up routing in Phalcon, following this URL structure:
www.example.com/language/register/
This is my routes.php:
use Phalcon\Mvc\Router;
$router = new Router();
$router->add(
'/[a-z]{2}/register/',
array(
'controller' => 'index',
'action' => 'register',
'lang' => 1
)
);
return $router;
And this is my IndexController:
class IndexController extends ControllerBase
{
public $lang;
public function indexAction()
{
}
public function registerAction($lang)
{
$lang = $this->dispatcher->getParam('lang');
echo "Register ($lang)"; //test
}
}
Therefore, if I was to visit www.example.com/fr/register/ it would take me to the index controller, the register action, with the lang parameter fr.
However, it is not displaying the $lang variable on the page.
I can see in the Phalcon documentation that you cannot use the /:params placeholder anywhere but at the end of the route (URL), but this is a regular expression being named within the router?

You got it right, you just forgot your brackets around [a-z]{2}
$router->add(
'/([a-z]{2})/register/', // added brackets here
array(
'controller' => 'index',
'action' => 'register',
'lang' => 1
)
);
Now you can access your lang via
$lang = $this->dispatcher->getParam('lang');

Related

Cakephp v3 Fatal Error with Custom Route class

I am trying to use custom route class.
Sometimes when I redirect to urls like
www.site.com/neumaticos-bridgestone
it returns Fatal Error.
But when I refresh the page, the error is hidden
I try of implementing many custom route class
routes.php
$routes->connect('/neumaticos-:marca', ['controller' => 'Pages', 'action' => 'brand'],
['routeClass' => 'BrandRoute'])
->setPass(['marca']);
$routes->connect('/neumaticos-para-:slug', ['controller' => 'Pages', 'action' => 'vehicleVersion'],
['routeClass' => 'VehicleVersionRoute'])
->setPass(['slug']);
BrandRoute.php
namespace Cake\Routing\Route;
use Cake\Utility\Inflector;
use Cake\ORM\TableRegistry;
use Cake\ORM\Query;
class BrandRoute extends Route
{
public function parse($url, $method = '')
{
$params = parent::parse($url, $method);
if (!$params) {
return false;
}
//return false;
$brands = TableRegistry::get('ProductBrands');
$slug = strtolower($params['marca']);
$brand = $brands->find()
->where([
'ProductBrands.slug' => $slug
])
->count();
if($brand > 0){
return $params;
}else{
return false;
}
return false;
}
}
The fatal error is the next:
Error: Cake\Routing\RouteCollection::parseRequest(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Cake\Routing\Route\BrandRoute" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition
File /var/www/www.site.com/public_html/vendor/cakephp/cakephp/src/Routing/RouteCollection.php
Line: 205
$routes->connect('/:slug', ['controller' => 'Categories', 'action' =>
'view'], ['pass' => ['slug']]);
and the link will be
$this->Html->link($category->title, ['controller' => 'categories',
'action' => 'view', $category->slug]) ?>
Use controller method to split the slug text as category and id etc

CakePHP v3 unable to use custom route class more than once

I am trying to use custom route class. Everything is fine while i use only one route, but Fatal error otherwice
Cannot redeclare class Cake\Routing\Route\EventRoute in src/Routing/Route/EventRoute.php on line 24
In my routes.php
Router::scope('/', function ($routes) {
$routes->setRouteClass('EventRoute');
$routes->connect('/:event', ['controller' => 'Events', 'action' => 'view']);
$routes->connect('/:event/:action/*', ['controller' => 'Events']);
$routes->connect('/:event/:number-:name', ['controller' => 'Users', 'action' => 'view'], ['number' => '\d+', 'pass' => ['number', 'name']]);
$routes->setRouteClass('InflectedRoute');
$routes->connect('/login', ['controller' => 'Members', 'action' => 'login']);
}
In that way i want to have short URLs for all my events in DB by it's slug and convert slug into param like
http://example.com/first_event -> Events.view ['event' => 'first_event']
http://example.com/coolest_event/edit -> Events.edit
http://example.com/past_event/12-someuser -> Users.view
and keep default Cake controller/action routing if no such event found.
File EventRoute.php
<?php
namespace Cake\Routing\Route;
use Cake\ORM\TableRegistry;
class EventRoute extends Route
{
public function parse($url, $method = '')
{
$params = parent::parse($url, $method);
if (!$params) {
return false;
}
if (!empty($params['event'])) {
$events = TableRegistry::get('Events')->findBySlug($params['event'])->first();
if (empty($events)) return false;
}
return $params;
}
}
System work as expected if i use only one (any of three routes above) but i can't use all three together.
It seems that CakePHP trying to include my EventRoute.php instead of include_once?
Or I'm doing somethig wrong?

CakePHP URL [Underscore to Hyphen]

I need some help about cakephp url underscore to hyphen.
I've search already over the internet but cannot find the answer.
I followed the instruction in Cakephp(dot)org
http://book.cakephp.org/2.0/en/development/routing.html#passing-parameters-to-action
But still not working
What I wanted is to change the url
dashboard/view_profile to dashboard/view-profile
Controller : DashboardController
Action : view_profile
View : view_profile.ctp
Routes.php
Router::connect(
'dashboard/:slug',
array('controller' => 'dashboard', 'action' => 'view_profile'),
array('pass' => array('slug'))
);
Link :
<?php echo $this->Html->link('View Profile', array('controller' => 'dashboard', 'action' => 'view_profile', 'slug' => 'view-profile')); ?>
Error :
Error: The action view-profile is not defined in controller DashboardController
Error: Create DashboardController::view-profile() in file: app\Controller\DashboardController.php.
<?php
class DashboardController extends AppController {
public function view-profile() {
}
}

cakephp manage correctly permission in beforeFilter

I have a little problem isnisde my controller.
I want that a user can access only inside some pages an andmin user inside more pages.
I have a controller called UsersController
this is its beforeFilter method
public function beforeFilter () {
parent::beforeFilter(); // chiamo anche il callback beforeFilter dal parent per ottenere un'autorizzazione per l'utente loggato da tutte le viste $this->Auth->allow('index','view'); per tutti i Model
$views = array ('login','register','activate');
if ($this->Session->read('is_logged')) {
$views = array_merge ($views, array ('login','logout', 'change_password'));
if ($user_type == 'admin') {
$views = array_merge ($views, array ('add','delete','edit','create','index'));
}
}
$this->Auth->allow($views);
}
in this function guest can enter inside login, register and activate.
user logged can access inside login. logout and change_password, admin to the other pages more.
But this not works. For example a user logged can access inside the index view or add view.
Why this?
This is my beforeFilter inside appController:
public function beforeFilter () {
$this->setReleaseData();
$this->checkUserStatus();
$this->updateTimezone();
$this->setRedirect();
if($this->Session->read('is_logged')){
$auth_user = $this->Auth->user();
$this->set('user_type', $auth_user['group']);
}
}
How can I manage correctly permission to enter in pages?
Thanks
I see you are not using an Authorization Handler, thus you will have to manually deny the access to actions
$this->Auth->deny(array('index', 'add', 'edit', 'etc'));
EDIT
I would actually start by denying access to everything, in your beforeFilter (AppController)
$this->Auth->deny();
and then in the beforeFilter() of you specific controller
if ($user_type == 'admin') {
$this->Auth->allow('actionThatYouWantToGrantAccess');
}
I'd look into Auth Controller a little more. Try using Admin Routing (Turned on in App/Config/core.php) along with $this->Auth->allow() which can be set by default beforeFilter() in the AppController.php and then set with in each controller's beforeFilter as well.
/**
* #var mixed[mixed]
*/
public $components = array(
'Auth' => array(
'autoRedirect' => false,
'loginRedirect' => array(
'admin' => true,
'controller' => 'homes',
'action' => 'index',
),
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
'admin' => false,
'plugin' => false,
),
'authenticate' => array(
'Form',
),
),
'Session',
'Cookie',
);
/**
* Before Filter callback
*/
public function beforeFilter() {
// Allow public views
$this->Auth->allow('index', 'view', 'display');
}

Dynamic routing in CakePHP

I'm trying to set dynamic routes for small CMS. Is there proper way how to do it? I founded somewhere this soliution, but honestly I'm not satisfied with it. CMS have other content types so define this for every model does't seem right to me.
$productsModel = ClassRegistry::init('Product');
$products = $productsModel->find('all');
foreach($products as $product){
Router::connect('/produkty/:id/'.$product['Product']['url'], array('controller' => 'products', 'action' => 'view',$product['Product']['id']));
}
Thanks for any help!
No need to do anything complex :)
In routes.php:
Router::connect('/produkty/*', array('controller'=>'products', 'action'=>'view'));
In products_controller.php:
function view($url = null) {
$product = $this->Product->find('first', array('conditions'=>array('Product.url' => $url)));
...
}
Yop,
You don't need to define route for each entry in your model DB. Routes ARE dynamics. There are many ways to define routes but the easier is to pass args to action like they comes.
routes.php
Router::connect('/produkty/*', array('controller' => 'products', 'action' => 'view'));
products_controller.php
class ProductsController extends AppController{
public function view($id){
//do anything you want with your product id
}
}
You can also use named args
routes.php
Router::connect('/produkty/:id/*', array('controller' => 'products', 'action' => 'view'), array('id' => '[0-9]+'));
products_controller.php
class ProductsController extends AppController{
public function view(){
//named args can be find at $this->params['named']
$productId = $this->params['named']['id'];
}
}

Categories