How to Hide a dynamic folder in URL with yii? - php

We are creating an application where we are able to create pages inside our DB. All of our domains are going to point to this application, so we are storing our domains also in the DB. Also based on that domain we are creating new layouts and determining what pages belong to that domain. With that being said here is our issue:
We put a rule inside the urlMangaer:
'http://dev.<domain:\w+>.com'=>'site/view'
which outputs: http://dev.example.com/example/index which represents: http://dev.$domain.com/$domain/$page
Our goal is for the url to read http://dev.$domain.com/$page and still have the functionality we need.
Here is our action call: public function actionView($domain = null,$page = null, $parm = null){}
A possible solution we thought of is extending the urlManager but we don't know where to begin to do so.

what about defining new action in your siteController, or find a way using actionIndex, to get both domain and page as input and render the corresponding domain, page from DB.

I figured out the solution, it was in my controller all along.
I created a new function called getDomain:
public function getDomain(){
$domain = Domain::model()->find('domain_name=:domain_name', array(':domain_name'=>Yii::app()->request->baseUrl));
return $domain->domain_name;
}
then inside my actionView function
public function actionView($domain = null,$page = null, $parm = null){
if ($domain === null){
$domain = $this->getDomain();
} ...
Now it works with out the $domain having to be inside the URL

Related

Setting local variables cleanly in a MVC pattern in PHP

I am experimenting with using the MVC pattern to set local vars in some code ie
$action=basename(__FILE__, '.php'); // load action from filename for consistancy (index for this case)
$controller = new seoController($action . '-seo'); // register controller with page action and parameter
$controller->invoke(); // invoke controller for processing
$page_title = "<insert page title here>";
$page_desc = "<insert page desc here>";
$page_keys = "<insert page keywords here>";
Of course the controller calls the model and does all the backend stuff parsing the input, getting the data and then returning.
What I would like is a clean way to set the local $page_title etc vars from the seoModel that is instantiated in setController without using the $_SESSION or any other hacky kind of way.
Is it ok from a design POV to put methods in the controller to get the info? ie
$page_title = seoController->getPageTitle();
My controllers as of now are not being used in this type of way as all they do is connect my models to the views.
I hope I'm being clear enough with my explanation.
Is it ok from a design POV to put methods in the controller to get the info?
Yes, thats what Controller is meant for.
What I would like is a clean way to set the local $page_title etc vars from the seoModel that is instantiated in setController without using the $_SESSION or any other hacky kind of way.
To avoid using $_SESSION that seems to be a bit overkill for this particular case you can set seoController attributes, for example,
Class seoController
{
$public $page_tile = '';
public method getPageTitle()
{
$model = new seoModel();
$page_title = $model->get_page_title();
$this->page_tile = $page_title;
//you could also return the page title here, skipping that
}
}
And access them from the caller
$controller = new seoController;
$controller->getPageTitle();
$page_title = $controller->page_title;
You would normally have things like meta tags stored with the model it’s describing. So if you’re loading say, a product from a model, then that model may also return the meta tags for that product:
public function show($productId)
{
$product = $this->productModel->findById($productId);
// Meta title may be available at $product->meta_title
return new ViewModel(array(
'product' => $product,
));
}
Your controller action would then return the data needed to be displayed in a view, which could be a HTML template, JSON, XML etc.

Pass variable to default codeigniter controller

I have my codeigniter setup with a default controller. It's accessible as follows:
site.com/index.php
But it's actually:
site.com/project/index
Where index is the default function.
I would like to do the following:
site.com/project7362
But it actually wants:
site.com/project/index/project7362
Where project name is a variable that is pass into the index function. But by default it looks for project-name as a controller. Is there a way to avoid this?
Essentially what I'm hoping to accomplish is to pass a variable directly after the domain name. A user may create a project, and I want that project to be accessible at domain.com/project_id
"Essentially what I'm hoping to accomplish is to pass a variable
directly after the domain name. A user may create a project, and I
want that project to be accessible at domain.com/project_id"
so another way to do this would be to have it like.
domain.com/project/id
this will give you much more flexibility later in your routes for adding different features.
in config/routes:
$route['project/(:any)'] = 'project/view/$1';
in your project controller
function view($id) {
// clean it
$id = htmlspecialchars($id) ;
if ( ! $project = $this->members->returnProjectBy($id) {
$this->showNoResultsFor($id) ; }
else { $this->show($project) ; }
}
OR -- another way to do this would be to put your defined routes first, and then have project be last (because it requires searching on whatever is there)
$route['home'] = 'page/home';
$route['contact'] = 'contact';
// etc etc so you first define your hard coded routes, and then if its not any of those
// you do a search on whatever the value is to find a project
$route['(:any)'] = 'project/view/$1';
so then your link could be
domain.com/id

Updated: Best practices for managing static content in Zend Framework?

I have some questions concerning the Zend Framework. I am attempting to route all static pages through the default controller using the now default displayAction() method. The intention is to have the displayAction() process the request by looking at the page param, determine if the script page exists, if it does render the view otherwise throw a 404 page not found error. Additionally, a test is done to see if a method with the same name as the param exists, if so, call on that action.
Listed here is the routing configuration from the application.ini
resources.router.routes.static-pages.route = /:page
resources.router.routes.static-pages.defaults.module = default
resources.router.routes.static-pages.defaults.controller = index
resources.router.routes.static-pages.defaults.action = display
Here is the controller actions:
public function someAction() {
// do something
}
public function displayAction() {
// extract page param, e.g. 'some'
$page = $this->getRequest()->getParam('page');
// create zend styled action method, e.g. 'someAction'
$page_action = $page.'Action';
// if a method within this controller exists, call on it
if (method_exists($this, $page_action)) {
$this->$page_action();
}
// if nothing was passed in page param, set to 'home'
if (empty($page)) {
$page = 'home';
}
// if script exists, render, otherwise, throw exception.
if (file_exists($this->view->getScriptPath(null)."/".$this->getRequest()->getControllerName()."/$page.".$this->viewSuffix)) {
$this->render($page);
} else {
throw new Zend_Controller_Action_Exception('Page not found', 404);
}
}
Now, here are my questions: Is there a better way of doing this? I'm relatively new to this framework, so are there best practices which apply? Is there a better way of calling on an action from within a controller? I have done A LOT of looking around through the documentation, however, quite a bit of it seems to contradict itself.
Update 1:
After having a think and a read, I've managed to simplify the solution and include a few things which were mentioned. NOTE: I use PagesController as my default static-content controller.
Listed here is the routing configuration from the application.ini. For calls to the home page i.e. "/", I pass "home" as the action param, for all other requests, the user defined / url link param is sent in action.
resources.router.routes.home.route = "/"
resources.router.routes.home.defaults.module = "default"
resources.router.routes.home.defaults.controller = "pages"
resources.router.routes.home.defaults.action = "home"
resources.router.routes.pages.route = "/:action"
resources.router.routes.pages.defaults.module = "default"
resources.router.routes.pages.defaults.controller = "pages"
Here is the controller actions. If user define parameter exists as an action, it will be called, else it falls to the php magic function __call.
public function someAction()
{
// Do something
}
public function __call($method, $args)
{
// extract action param, e.g. "home"
$page = $title = $this->getRequest()->getParam('action');
// test if script exists
if (file_exists($this->view->getScriptPath(null) . "/"
. $this->getRequest()->getControllerName() . "/$page . " . $this->viewSuffix))
{
// pass title to layout
$this->view->assign(compact('title'));
// render script
$this->render($page);
} else {
throw new Zend_Controller_Action_Exception('Page not found', 404);
}
}
It works. So, here are my questions: Would you consider standardising on using this method to manage static content? If not, why not? How would you improve it? Also, considering this is a GET request, would it be a wise move to use Zend_Filter_input to cleanse input or is that just overkill?
Your approach seems reasonable to me. However, perhaps you should take advantage of the __call method instead, which would allow you to more easily route your actions...
Setup your route like this:
resources.router.routes.static-pages.route = /:action
resources.router.routes.static-pages.defaults.module = default
resources.router.routes.static-pages.defaults.controller = index
And your controller like so:
public function someAction() {
//going to URL /some will now go into this method
}
public function __call($name, $args) {
//all URLs which don't have a matching action method will go to this one
}
I think your on the right track however here are some other ideas.
Break up your routing per sections in your INI:
ie a blog router, a static page router a forum router etc.. (I think you are already doing this)
Use the various router classes to handle routing per section rather than sending it to a controller.
Static:
http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.static
All:
http://framework.zend.com/manual/en/zend.controller.router.html
Some links that may help:
codeutopia.net/blog/2007/11/16/routing-and-complex-urls-in-zend-framework/
www.vayanis.com/2009/03/20/intro-to-zend-framework-routing/

CakePHP: Get model instance by url string

I have a CakePHP website and navigaton links are stored in database. What i want is for some navigation entries to call custom function which will return some additional, dynamic data about the link: I want to add a count of articles for link "Vacancies". I could call a function on a model that would return total count. This link is to be rendered on every page.
So i need to get appropriate models instance, but not for the current request, but the request where url points to.
So basically i have url "/en/vacancies". I can get controller name by:
$urlInfo = Router::parse("/en/vacancies");
$controllerName = $urlInfo['controller'];
What would be the reliable way to do that?
Any other solutions for the problem are welcome.
Assuming you have the method to gather the navigation link data in a Model.
App::import('Controller', $controllerName);
$controller = new $controllerName;
$controller->loadModel('YourModel');
$yourModel = $controller->YourModel;
$yourData = $yourModel->your_method();
There are a variety of other ways to do this. But, without knowing more about where you're actually going to be calling this function I can't really provide anymore suggestions.

codeigniter routing

I am currently working on CMS for a client, and I am going to be using Codeigniter to build on top of, it is only a quick project so I am not looking for a robust solution.
To create pages, I am getting to save the page details and the pull the correct page, based on the slug matching the slug in the mysql table.
My question is however, for this to work, I have to pass this slug from the URL the controller then to the model, this means that I also have too have the controller in the URL which I do not want is it possible to remove the controller from the URL with routes?
so
/page/our-story
becomes
/our-story
Is this possible
I would recommend to do it this way.
Let's say that you have : controller "page" / Method "show"
$route['page/show/:any'] = "$1";
or method is index which I don't recommend, and if you have something like news, add the following.
$route['news/show/:any'] = "news/$1";
That's it.
Yes, certainly. I just recently built a Codeigniter driven CMS myself. The whole purpose of routes is to change how your urls look and function. It helps you break away from the controller/function/argument/argument paradigm and lets you choose how you want your url's to look like.
Create a pages controller in your controllers directory
Place a _remap function inside of it to catch all requests to the controller
If you are using the latest version of CI 2.0 from Bitbucket, then in your routes.php file you can put this at the bottom of the file: $routes['404_override'] = "pages"; and then all calls to controllers that don't exist will be sent to your controller and you then can check for the presence of URL chunks. You should also make pages your default controller value as well.
See my answer for a similar question here from a few months back for example code and working code that I use in my Codeigniter CMS.
Here's the code I used in a recent project to achieve this. I borrowed it from somewhere; can't remember where.
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
Then, my index function is where you would put your page function.

Categories