I'm developing a module for the SocialEngine package and I'd like to be able to specify multiple custom routes.
Currently I'm editing the Bootstrap.php file found in the directory of my module with the following;
class Courses_Bootstrap extends Engine_Application_Bootstrap_Abstract
{
protected function _initRouter(){
$fc = Zend_Controller_Front::getInstance();
$router = $fc->getRouter();
$router->addRoute('courses', new Zend_Controller_Router_Route('courses/activity/:activity_id', array('module' => 'courses', 'controller' => 'index','action' => 'activity')));
$router->addRoute('courses', new Zend_Controller_Router_Route('courses/course/edit/:course_id', array('module' => 'courses', 'controller' => 'course','action' => 'edit')));
$router->addRoute('courses', new Zend_Controller_Router_Route('courses/course/create/:course_id', array('module' => 'courses', 'controller' => 'course','action' => 'create')));
return $router;
}
}
However it would seem that when I specify more then 1 route all routes stop passing in the custom variable (course_id or activity_id)
I'm retrieving the variable as follows;
$course_id = $this->getRequest()->getParam("course_id");
I've taken the approach from here;
http://tjgamble.com/2011/04/adding-custom-routes-to-your-socialengine-4-modules/
Many thanks,
Andy
you have to give them different names:
$router->addRoute('courses_activitiy', new Zend_Controller_Router_Route('courses/activity/:activity_id', array('module' => 'courses', 'controller' => 'index','action' => 'activity')));
$router->addRoute('courses_course', new Zend_Controller_Router_Route('courses/course/edit/:course_id', array('module' => 'courses', 'controller' => 'course','action' => 'edit')));
$router->addRoute('courses_create', new Zend_Controller_Router_Route('courses/course/create/:course_id', array('module' => 'courses', 'controller' => 'course','action' => 'create')));
Related
For Social Engine 4, which uses Zend framework.
I want to show user profiles under subdomains. so, http://domain.com/profile/username will be http://username.domain.com
How can I do this. I do already have one extension which makes http://domain.com/profile/username to http://domain.com/username Here is the code for it.
$route = array(
'user_profile' => array(
'route' => ':id/*',
'defaults' => array(
'module' => 'user',
'controller' => 'profile',
'action' => 'index'
),
'reqs' => array(
'id' => "\b.+"
)
)
);
Zend_Registry::get('Zend_Controller_Front')->getRouter()->addConfig(new Zend_Config($route));
Is it possible to change it to work for subdomains? If yes how can I do it?
Thank You in advance.
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
':id.'.$setting['siteurl'],
array(
'module' => 'user',
'controller' => 'profile',
'action' => 'index',
)
);
$plainPathRoute = new Zend_Controller_Router_Route_Static('');
$router->addRoute('user_profile', $hostnameRoute->chain($plainPathRoute));
I'm a newbie at Phalcon programming, I have admin/backend and frontend controllers
Admin will be served at '/admin/:controller/:action' and frontend will be served at '/:controller/:action'
Admin controllers (KalkuRitel\Controllers\Admin namespace) are located under
app/
controllers/
admin/
and frontend controllers (KalkuRitel\Controllers\Frontend namespace) are located under
app/
controllers/
frontend/
How do I accomplish this?
And how to serve 404 page within admin and frontend controllers with their own layout?
I would recommend to create modules
app/
modules/
admin/
...
frontend/
...
api/
...
register modules:
$application->registerModules(array(
'frontend' => array(
'className' => 'Application\Frontend\Module',
'path' => __DIR__ . '/../modules/frontend/Module.php'
),
'admin' => array(
'className' => 'Application\Admin\Module',
'path' => __DIR__ . '/../modules/admin/Module.php'
),
'api' => array(
'className' => 'Application\Api\Module',
'path' => __DIR__ . '/../modules/api/Module.php'
)
));
define properly Module.php files and than set route somewhat close to this:
use Phalcon\Mvc\Router as Router;
use Phalcon\CLI\Router as CliRouter;
/**
* Registering a router
*/
$di->setShared('router', function () use ($application, $config) {
if($application instanceof Phalcon\CLI\Console) {
return new CliRouter();
}
$router = new Router(false);
$router->setDefaultModule("frontend");
$router->setUriSource(\Phalcon\Mvc\Router::URI_SOURCE_GET_URL);
$router->removeExtraSlashes(TRUE);
foreach($application->getModules() as $key => $module) {
$prefix = $key == 'frontend' ? '' : ('/' . $key);
$router->add($prefix . '/:params', array(
'module' => $key,
'controller' => 'index',
'action' => 'index',
'params' => 1
))->setName($key);
$router->add($prefix . '/:controller/:params', array(
'module' => $key,
'controller' => 1,
'action' => 'index',
'params' => 2
));
$router->add($prefix . '/:controller/:action/:params', array(
'module' => $key,
'controller' => 1,
'action' => 2,
'params' => 3
));
}
return $router;
});
More in manual:
https://docs.phalconphp.com/pl/latest/reference/routing.html and
https://docs.phalconphp.com/pl/latest/reference/applications.html
The best way to accomplish this is to create a multiple module application.
You can learn more about multiple module application setups here:
https://docs.phalconphp.com/en/latest/reference/applications.html#multi-module
Once you have the structure for this in place you can set the routes something like this:
/*
* Dependency Injector
*/
$di = new \Phalcon\Di\FactoryDefault();
/**
* Register a router
*/
$di->setShared('router', function () {
$router = new \Phalcon\Mvc\Router();
$router->setDefaultModule('frontend');
$router->setDefaultNamespace('Multiple\Frontend\Controllers');
/*
* Frontend Routes
*/
$router->add('/:controller/:action', array(
'namespace' => 'Multiple\Frontend\Controllers',
'module' => 'frontend',
'controller' => 1,
'action' => 2
));
/*
* Backend Routes
*/
$backendRoutes = new \Phalcon\Mvc\Router\Group(array(
'namespace' => 'Multiple\Backend\Controllers',
'module' => 'backend'
));
$backendRoutes->setPrefix('/admin');
$backendRoutes->add('/:controller/:action', array(
'controller' => 1,
'action' => 3
));
$router->mount($backendRoutes);
return $router;
});
This is a quick answer and may require tweaking for your individual situation but should give you a good idea of how to accomplish your goal.
My phalcon app has worked fine with standard MVC route convention.
However, I want to handle some variable via URL, then I have a route:
$router = new \Phalcon\Mvc\Router();
$router->add("/timesheet/some/{year:[0-9]+}/{month:[0-9]{2}}/{day:[0-9]{2}}", "Timesheet::some");
$router->add("/timesheet/getreport/{type:[a-z]}/{year:[0-9]+}/{month:[0-9]{2}}/{day:[0-9]{2}}", "Timesheet::getreport");
$router->addPost("/user/auth", "User::auth");
return $router;
The first route (timesheet/some) worked fine, I can access to "year", "month" variable using $year = $this->dispatcher->getParam("year");, however the second route (timesheet/getreport) doesn't work. In this case, $year = $this->dispatcher->getParam("year"); return null.
If I changed to
$router = new \Phalcon\Mvc\Router(false);
$router->add("/:controller/:action", array(
"controller" => 1,
"action" => 2,
));
$router->add("/timesheet/some/{year:[0-9]+}/{month:[0-9]{2}}/{day:[0-9]{2}}", "Timesheet::some");
$router->addPost("/timesheet/getreport/{type:[a-z]}/{year:[0-9]+}/{month:[0-9]{2}}/{day:[0-9]{2}}", "Timesheet::getreport");
$router->addPost("/user/auth", "User::auth");
return $router;
every request will be routed to index/index. My project URL is localhost/fpas, and I already try both route /fpas/timesheet/some and /timesheet/some but it always redirect to index/index. What's wrong with it? (security/auth is commented out, so it's not result from authentication).
From my understand, the default route, $router = new \Phalcon\Mvc\Router(); only allow you to follow MVC convention, while $router = new \Phalcon\Mvc\Router(false); do but you have to specific all routes for every controller/action. Can I keep the convention for most of the action, while have specific rewrite routes for some action. How can I do that?
Thank you very much.
It works for me:
$router = new Phalcon\Mvc\Router();
$router->add("/", array(
'controller' => 'index',
'action' => 'setLanguage',
));
$router->add("/{language:[a-z]{2}}", array(
'controller' => 'index',
'action' => 'index',
'language' => 1
));
this one get's default routing just with language in the beginning
$router->add("/{language:[a-z]{2}}/:controller/:action", array(
'controller' => 2,
'action' => 3,
'language' => 1
));
with default action "index" when it's not in url
$router->add("/{language:[a-z]{2}}/:controller", array(
'controller' => 2,
'action' => 'index',
'language' => 1
));
some other routes
$router->add("/{language:[a-z]{2}}/:controller/:action/:params", array(
'controller' => 2,
'action' => 3,
'language' => 1,
'params' => 4
));
$router->add("/{language:[a-z]{2}}/question/add/{type}", array(
'language' => 1,
'controller' => 'question',
'action' => 'add',
));
I am currently setting up a ZF2 application and got stuck with the router. I looked up Zend's example for segmented routing:
$route = Segment::factory(array(
'route' => '/:controller[/:action]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'controller' => 'Application\Controller\IndexController',
'action' => 'index',
),
));
By calling http://example.com/Maps/edit Zend would automatically "navigate" to the MapController and call EditAction().
Since I use Factory for the MapController I am looking for a solution like
$route = Segment::factory(array(
'route' => '/:factory[/:action]',
'constraints' => array(
'factory' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'factory' => 'Application\Controller\Factory\DefaultControllerFactory',
'action' => 'index',
),
));
Basically I want the framework to access the factory instead of the controller without listing any single factory manually.
Thanks for any suggestions!
controller manager is ServiceManager, all service manager features applies. Register controller factory instead of declaring it as invokable
I would like to create a generic module/controller/action route in Zend Framework 2 to be used with ZF2 MVC architecture.
In ZF1 the default route was defined like /[:module][/:controller][/:action] where module would default to default, controller would default to index and action to index.
Now, ZF2 changed the way modules are intended, from simple groups of controllers and views, to real standalone applications, with explicit mapping of controller name to controller class.
Since all controller names must be unique across all modules, I was thinking to name them like modulename-controllername but I would like the URL to look like /modulename/controllername without the need to create specific routes for each module, using something like the old default route for ZF1 described above.
Yes it is very possible, but you will have to do a little work. Use the following config:
'default' => array(
'type' => 'My\Route\Matcher',
'options' => array(
'route' => '/[:module][/:controller[/:action]]',
'constraints' => array(
'module' => '[a-zA-Z][a-zA-Z0-9_-]*',
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'module' => 'default',
'controller' => 'index',
'action' => 'index',
),
),
),
Then you have to write your own My\Route\Matcher to create a Routemap object that the MVC can use. It's not hard, look at the other route matchers already in the framework and you'll get the idea.
If you use the Zend Skeleton Application you have already configured this default controller.
See here https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php
To have a general/standard routing system for a zf2 module, this is my solution for just one controller "module\controller\index" ( default controller ) :
'router' => array(
'routes' => array(
'default' => array(
'type' => 'Literal',
'options' => array(
'route' => '/', // <======== this is take the first step to our module "profil"
'defaults' => array(
'module' => 'profil',
'controller' => 'profil\Controller\Index',
'action' => 'index',
),
),
),
'profil' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[profil][/:action]', // <======== this is take the next steps of the module "profil"
'constraints' => array(
'module' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array( // force the default one
'module' => 'profil',
'controller' => 'profil\Controller\Index',
'action' => 'index',
),
),
),
),
),
then in our controller "profil\Controller\Index" we have three actions "index" "home" "signout" :
public function indexAction()
{
if ($this->identity()) {
return $this->redirect()->toRoute('profil',array('action'=>'home'));
} else {
// ......
$authResult = $authService->authenticate();
if ($authResult->isValid()) {
//......
return $this->redirect()->toRoute('profil',array('action'=>'home'));
} else {
// ......
}
} else {
$messages = $form->getMessages();
}
}
return new ViewModel();
}
}
public function homeAction()
{
if (!$this->identity()) {
return $this->redirect()->toRoute('profil',array('action'=>'signout'));
}
}
public function signoutAction()
{
if ($this->identity()) {
$authService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
$authService->clearIdentity();
}
$this->redirect()->toRoute('profil');
}
and thank you anyway :)