I am using INVO example app from here:
https://github.com/phalcon/invo
I have copied all the files and set the db and base url.
It works, I can login etc.
however, I wanted to learn how to use redirects e.g.
I would like to use contact-us instead of contact without changing the name of the controller.
So, I created a file routes.php inside of the app/config folder and put this inside:
<?php
$router = new Phalcon\Mvc\Router(false);
$router->add('/contact-us', array(
'controller' => "contact",
'action' => "index"
))->setName('contact');
$router->handle();
return $router;
and I have created this in my bootstrap file index.php in the public root directory
$di = new \Phalcon\DI\FactoryDefault();
$di->set('router', function(){
require __DIR__.'/../app/config/routes.php';
return $router;
});
However, it's not working and when I try to access http://localhost/test/contact-us it works, but http://localhost/test/contact-us stopped working and I am redirected to the homepage.
If I (comment the route) do this:
/*$router->add('/contact-us', array(
'controller' => "contact",
'action' => "index"
))->setName('contact');*/
$router->handle();
return $router;
Neither http://localhost/test/contact-us nor http://localhost/test/contact-us works ;(.
If I uncomment it back. contact-us works but contact don't.
I guess it's b/c of ->setName('contact') and it's stored in the memory or in some file.
how to get it back to the original state and "unset" that?
You can create two routes and each will work:
$router->add('/contact', array(
'controller' => "contact",
'action' => "index"
));
$router->add('/contact-us', array(
'controller' => "contact",
'action' => "index"
));
Or use groups of routes.
So, if you have ContactController and don't want to access it using /contact url you should add router to the DI container. After that the pages will be available only via router and default /controller/action request format will not work.
Related
I would like to know how can i do this in phalcon. I have a web site build with phalcon. All is working great now i stumbled upon a problem, here is what i need.
When a user clicks on a post that was created by another user. It takes him to this post with pictures and all things he entered to DB. I would like that in browser the name of this view is not like www.website.com/posts/index but that it is like www.website.com/posts/Nameofthepost, and like that for each other postings on the website. So that all posts (really ads) show their name up in browser. I hope i wrote everything understandable.
Appreciate all suggestions
That has to do with routing doesn't it? I modified this from my own code, I used grouping, you don't have to. I didn't test this code.
// routes.php
$router = new \Phalcon\Mvc\Router();
$router->setDefaultModule("__YOUR_MODULE__");
$router->removeExtraSlashes(true);
... your other routes ...
// posts group
$posts = new \Phalcon\Mvc\Router\Group(array(
'module' => '__YOUR_MODULE__',
'controller' => 'posts',
'action' => 'index'
));
// All the routes start with /post
$posts->setPrefix('/post');
$posts->add('/{postName}/:params', array(
'action' => 'index',
'params' => 2
));
// Maybe this will be enough for your needs,
// the one above has a catch all params, which
// has to be manually parsed
$posts->add('/{postName}', array(
'action' => 'index',
));
$posts->add('[/]*', array(
'action' => 'index',
));
$router->mount($posts);
unset($posts);
... other routes ...
return $router;
On your controller, you can get the postName param this way:
$this->dispatcher->getParam('permaPath');
As shown in the phalcon routing documentation, you can use regex in your routing config, something like this?
$posts->add('/{postName:[-0-6_A-Za-z]+}/:params', array(
'action' => 'index',
'params' => 2
));
So, only -_, 0-9, A-Z, a-z allowed for postName. If the URL had a comma in there or something, then route doesn't match, 404 page not found.
I try to use a router with phalcon. This is how it is included in index.php right after registering the 'events manager':
$di->set('router', function(){
require __DIR__.'/../app/config/routes.php';
return $router;
});
and this is how the routes.php looks like:
<?php
$router = new Phalcon\Mvc\Router(false);
$router->add("/", array(
'controller' => 'index',
'action' => 'index'
));
$router->add("/topics", array(
'controller' => 'wurst',
'action' => 'index'
));
$router->handle();
return $router;
The website reacts as if the router was not existent. /topics and topics say this:
TopicsController handler class cannot be loaded
and I also cannot use a die("test"); function inside routes.php . nothing happens.
I also tried to activate it without a separate file, but the result was the same :(
(The sample web-application INVO was used as starting point for my site )
$router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI); will use default $_SERVER['REQUEST_URI']
If your index/index action is working when you access domain.com/index.php, check that you are using proper uri source, if using nginx or php built-in server you might have some problems with routing and $_GET['_uri'] which phalcon use for handling uris.
can find more about it on phalcon router documentation about uri sources -> http://docs.phalconphp.com/en/latest/reference/routing.html#uri-sources
now it seems to work:
Action 'route404' was not found on handler 'index'
the problem was , that I put the function to set the router in index.php within "set dispatcher function". ..did not see the closing braces.
I have a quite big project that I need to program. I used to code with CodeIgniter but since they stopped maintaining the framework, I decided to switch to another. I chose Phalcon framework. The folder structure of the application that I want to implement is next:
app/
controllers/
admin/
users/
UsersController.php
UserGroupsController.php
dashboard/
system/
another_subfolder/
AnotherSubFolderController.php
production/
settings/
SettingsController.php
dashboard/
flow/
another_subfolder/
AnotherSubFolderController.php
website1/
customers/
CustomersController.php
CompaniesController.php
another_subfolder .... /
models/
sub_folder_structure/ // The same as controllers
This is just example of the folder structure of the application. There will be quite a lot of folders and sub-folders in this project to make it manageable.
From my understanding I need to register all namespaces at the loader for each sub-folder, so that Phalcon knows where to search and load the class.
//Register an autoloader
$loader = new \Phalcon\Loader();
$loader->registerNamespaces(array(
// Main
'Controllers' =>'app/controllers/',
'Models' =>'app/models/',
// Admin Routing
'Controllers\Admin'=>'app/controllers/admin',
'Models\Admin'=>'app/models/admin',
'Controllers\Admin'=>'app/controllers/admin',
'Models\Admin'=>'app/models/admin',
'Controllers\Admin\Users'=>'app/controllers/admin/users',
'Models\Admin\Users'=>'app/models/admin/users'
))->register();
The loader will look quite big.
Then I have to set-up the router so that requests redirected to the right controller. Right now I have next:
// Setup Router
$di->set('router', function(){
$router = new \Phalcon\Mvc\Router(false);
$router->removeExtraSlashes(true);
$router->add('/', array(
'namespace' => 'Controllers',
'controller' => "login"
));
$router->add('/:controller/:action/', array(
'namespace' => 'Controllers',
'controller' => 1,
'action' =>2
));
$router->add('/admin/:controller/:action/', array(
'namespace' => 'Controllers\Admin',
'controller' => 1,
'action' =>2
));
$router->add('/admin/users/:controller/:action/', array(
'namespace' => 'Controllers\Admin\Users',
'controller' => 1,
'action' =>2
));
return $router;
});
That will be also very big if I need to manually setup router for each sub-folder and namespace.
So the questions that I have are this:
Is there any way to make a loader prettier and smaller? As it will grow bigger.
How can I setup router so that I don't need to enter all of the namespaces and combinations of subfolders? Is there any way to make it smaller? May be modify dispatcher or any other class? Or is there a way I can set a path variable in the router to the location of the controller?
I have researched Phalcon documentation but could not find the way to do that.
Any help and suggestions are very much appreciated.
Thanks
Ad. 1. You can change your namespaces to be more PSR-0 (in my opinion), so I would make:
app
controllers
Admin
Users
UsersController.php
The you can register one namespace Admin or any other. Then you need to register only the top most namespace to work (keep in mind that your UsersController must have namespace Admin\Users\UsersController; to work). Thena autoloader should have only:
$loader
->registerDirs(
array(
// It's taken from my config so path may be different
__DIR__ . '/../../app/controllers/'
// other namespaces here (like for models)
)
);
I'm using registerDirs so I only point loader to the folder in which some namespace exists.
Ad. 2.
For this you can use groups of routes so you can pass a namespace as a parameter for config array of constructor and then do the repeative task in one place. Then just create new instances with different parameters;
$router->addGroup(new MahGroup(array('namespace' => 'Mah\\Controller'));
So inside MahGroup class could be:
class MahGroup extends Phalcon\Mvc\Router\Group {
public function _construct($config = array()) {
$this->setPrefix('/' . $config['perfix']);
$router->add('/:controller/:action/', array(
'namespace' => $config['namespace'],
'controller' => 1,
'action' => 2
));
// etc...
}
}
And then configuring routes:
$router->addGroup( new MahGroup(array('prefix' => 'mah-namespace', 'namespace' => 'Mah\\Namespace' )) );
$router->addGroup( new MahGroup(array('prefix' => 'mah-other-namespace', 'namespace' => 'Mah\\Other\\Namespace' )) );
But given examples for second question are just what could be done. I usually create Group class for each namespace and then declare some routes that my app uses since I'm not using english names for routes and I need rewriting polish urls to controllers which have also some namespaces.
I wanna match an url like this http://localhost/sunnetwap/1-hot and rewrite into this
http://localhost/sunnetwap/?c=1&s=hot.
In my Bootstrap and and _initRoutes function i wrote:
$frontController = Zend_Controller_Front::getInstance();
$route = new Zend_Controller_Router_Route_Regex(
"([0-9]*)-([a-z]*)",
array(
'module' => 'default',
'controller' => 'index',
'action' => 'index'
),
array(
1 => 'c',
2 => 's'
));
$frontController->getRouter()->addRoute('home',$route);
but it doesn't work. Can you help me?
The issue is probably related to the base url of your app.
It is possible that you have deployed your app at the base url http://localhost/. In this case, your routes would need to include the sunnetwap portion.
But I'm guessing that your app is deployed to http://localhost/sunnetwap/. In that case, your route is fine, but it's likely that you either have a sunnetwap alias on localhost or that the whole app is dropped into into your <docroot>/sunnetapp and that you have moved contents of the public folder up a level with corresponding changes to .htaccess. Both of these will potentially have impact on the routing.
See this answer for some ideas on how to deploy to a sub-directory when you can't map a virtual host to your app.
It's probably late and I have missed this off by a long shot.
I am trying to create a cleaner url structure; so rather than having
/index/about
/index/news
I have
/about
/news
I came across a post on this site which used the following:
public function _initCustomRoute()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$route = new Zend_Controller_Router_Route(':action', array(
'module' => 'default',
'controller' => 'index',
'action' => 'index'
));
$router->addRoute('default', $route);
}
It rewrites the url within my navigation. So I have created the relevant action and view (tested without the custom route) but I am getting:
Not Found
The requested URL /path/to/public/index.php was not found on this server.
I assume this is a thing that apache does on a windows file system by not adding the drive letter.
I've not touched the .htaccess file.
Any ideas?
Found out why! You must use virtual hosts rather than an alias as I was using.
Full guide here: http://blog.ryantan.net/2010/03/setting-up-wamp-for-zend-framework-projects/