Currently everything is working golden except for the fact that a user could manually put in a URL, which messes up how CI is setup for my site. For instance:
www.somesite.com/folder/
this folder in the controller should not be accessible... and needs to redirected to that folders index page, which will give them a 404 error. I've tried adding deny to all in the htaccess file, but it doesn't seem to do anything.
www.somesite.com/folder/index.html
I actually want all folders to function likes this. I do have an index.html file in the folder, but it doesn't get read. Is there a way to fix this in CI? I'm also having an issue with users being able to manually access the controller functions. I've tried to change them to private as people have suggested, but then my scripts can't access them. For instance:
www.somesite.com/controller_file/some_function
How do I block them from accessing this function?
You can create a whitelist sollution:
Open your application/config/routes.php
add the routes you want to allow.
add a catchall route .* And redirect it to a errot handler
Codeigniters trys to matches the route patterns in the order they are listed in the array so
whenever a user enters a route you did not explicitly allow it will allqays redirect him to the catchall route
user-guide on routing
EDIT:
You can create a blacklist logic by redirecting only requests matching a specific pattern, and keep the default behaviour for all others.
As far as denying access to the filesystem goes, your best bet would be to to place your Application and System folders outside of the webroot. Then edit your index.php to set the new path to each folder. My general set up looks like this:
+ Root
| - Application
| - System
| + Webroot
| | - js
| | - css
| | - index.php
| | - ...
+ - ...
As for your second question, to prevent certain functions from being accessed directly from the url you need to prepend them with an underbar.
So instead of
public function some_function() {...}
Use
public function _some_function() {...}
It can then be called in your controller with $this->_some_function();
If you have any AJAX functions, you'll need to drop the underbar from their name to make them accessible. You can stop users accessing them directly from the URL by wrapping your functions with the following conditional.
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')) {}
The above checks if the request is via AJAX.
Related
I am a Drupal dev and new to code-igniter or any such php frameworks.
Now i have to modify an existing application done on codeigniter and the structure must be as follows:
example.com/motors
example.com/motors/car-for-sale
example.com/motors/car-for-rent etc.
Before it has only one url example.com/motors and i want to create more urls as mentioned above.
In the application\views\content folder i have the following structure:
application\views\content\motors.php
application\views\content\motors
application\views\content\motors\car-for-sale.php
In the application\controller folder i have the following structure:
application\controller\motors.php
application\controller\motors\motors.php
application\controller\motors\car-for-sale.php
I want to get the url example.com/motors & example.com/motors/car-for-sale from the files resides in the motors folder.Also how can i set a default file to load when i open example.com/motors?
You can't have a (controllers) directory that matches the name of a controller class at the same level. That is, since you have a controllers/motors.php, the files under controllers/motors/* will never be reached.
Instead (and this is the answer to your second question), you should set the default_controller name and rename controllers/motors.php to controllers/motors/<default_controller>.php.
Note that the default_controller setting points to a controller name (not a file location) and is applied to all directories. That is, if you set it to 'Default', then controllers/Default.php will be used when you open http://domain.tld/ and controllers/motors/Default.php will be used if you open http://domain.tld/motors/.
Also, your controller names MUST start with a capital letter, so default.php would be incorrect and should be Default.php instead. This might be working for you on Windows right now (because of its case-insensitive file system), but as soon as you upload your site to a Linux (or other UNIX-based) host, any classes with file names that don't start with a capital letter won't work.
It looks like you're trying to build a CodeIgniter site with a completely different paradigm from what it is designed around.
The structure you are after can be set up using the routes.php file within application/config
In there, you can set routes to go to any location needed, so for you, something like:
$routes['motors/cars-for-sale'] => 'motors/cars_for_sale';
$routes['motors/cars-for-rent'] => 'motors/cars_for_rent';
Then in application/controller you'd have a Motors.php file, which starts:
class Motors extends CI_Controller{
And also has the functions cars_for_sale and cars_for_rent
The mappings in routes sets this to link together.
In order to get the views you want for any given route, in the controller function, you'd have:
$this->load->view('path/to/view/file', $array_of_data); // view path does not need the .php extension
I'd recommend having a look and possibly even a follow through of the CodeIgniter tutorial in their documentation
I have pages that are generated from a database, based on the URI. Functons as it should, however I can't set-up my routes to eliminate the controller and function from the URL.
$route['studios/(:any)'] = 'studios/location/$1';
Right now, I have the route to show the controller name and the URI variable (whatever that may be). However, I want to eliminate the controller name as well and just display the URI variable that's called as the URL. Hard to explain - hopefully someone picks up my drift...
Current URL would be: domain.com/studios/studio1
But I want to just display: domain.com/studio1
I tried $route['/(:any)'] = 'studios/location/$1';, but that's messing up my entire site.
Help?
$route['studios(/:any)*'] = 'studios/location';
This route will force everything from studios on to studios/location. You can then access any of the parameters using URI segments:
$id = $this->uri->segment(2);
If your URL was somewhere.com/studios/location/2, $id would resolve to 2
However, since you want it to just be from the root on, you will have to put your override route at the bottom of the routes file so it is assessed last:
// all other routes here. Which must be specifically
// defined if you want a catch all like the one you mentioned
$route['(:any)'] = 'studios/location';
Alternatively, if you want a high maintenance site, you can specify a collection of routes like so:
$route['(studio1|studio2|studio3)'] = 'studios/location/$1';
how is it "messing up your site"?
In any case, you should not have the / before (:any)
Just:
$route['(:any)'] = 'studios/location/$1';
EDIT:
BEFORE the $route['(:any)'], you'll need to specify routes fro all your controllers; this is pretty normal, don't know if I'd call it "high maintenance", but you'll need to decide
Being new to Cake on PHP, I am trying to work out if I have a URL, what would be the easiest way to find the controller code for it?
The URL on my local machine is something like:
http://foofoofoo.local/protected/admin/org/edit/1
I have worked out that the location of the view for this file is at this location on my machine:
/var/www/MyApp/protected/app/views/org/admin_edit.ctp
I thought what I'd do is do a search throughout the entire codebase for anything referencing admin_edit.ctp. I found two entries, and changed them to see if I had found the point where the view is called, but despite changing the file name on these entries - the app still works when I visit the URL: http://foofoofoo.local/protected/admin/org/edit/1
I just want to see where the admin_edit.ctp file is being called within the site.
URL: http://foofoofoo.local/protected/admin/org/edit/1
This means I can assume you have a added a route in your /app/Config/routes.php. Where this is pointing can not be said since we don't have access to this file.
Why can I assume you have added this to your routes? Because the posted URL is not matching the CakePHP Conventions which clearly states that controllers should be defined in plural. Since the URL will be accessing the Controller directly through the Controller, unless a route has been specified, I know that the OrgController does not exist. Why?
Try Inflector::pluralize('Org'). It will return 'Orgs' to you. And thus meaning the controller should be called OrgsController and you should be accessing this Controller via the following URL.
http://foofoofoo.local/protected/admin/orgs/edit/1
In this OrgsController there should be an action (function) called admin_edit(), because you have prepended the org with Admin, which is a prefix.
It can be possible that the /protected part, is part of the URL as well, but do not know where your main /App is located and what part of the URL is pointing to the /app/webroot/index.php file.
The Views can be found at /app/View/Orgs/*.ctp.
If you are still having trouble finding your files. Please start with the Blog tutorial written by the Cake Community. This tutorial describes all the neat built-in tricks and will get your first app running in no-time. Please read that first!
If you are still having trouble, feel free to update your question and add the /app/Config/routes.php file.
Under Cake 1.3, if your application has an AppController (check if the file app/app_controller.php exists), you can put this code in the beforeFilter method:
debug($this->params);
It will print an array on your app pages when you are in debug mode, with the name of the controller and the action used.
Array
(
...
[controller] => controller_name
[action] => action_name
...
)
If the AppController does not contain any beforeFilter method, you can just create it:
function beforeFilter()
{
debug($this->params);
}
With CodeIgniter I'm trying to create a URL structure that uses a title string as the entire URI; so for example: www.example.com/this-is-a-title-string
I'm pretty confident I need to use the url_title() function in the URL Helper along with the routes.php config folder but I'm stuck bringing it all together.
Where do I define the URI and how is it caught by the routes folder?
Seems to be a straight forward problem but I'm getting stuck creating the URLs end-to-end. What am I missing?
I thought about a catch-all in the routes folder: $route['(.*)'] = "welcome/controller/$1"; ....but how would this work with multiple functions inside a particular controller? ...and maybe it's not even the right way to solve.
You can send all requests to a driver with something like this:
$route['(:any)'] = "welcome/function";
Then use the _remap function to route requests inside the controller.
However, using URL's as you suggest limits the CI functionality. Try something better like www.example.com/article/this-is-a-title-string
$route['article/(:any)'] = "articles/index";
and in article (controller), use _remap...
If you're going to re-route every request, you should extend CI_Router.
The actual implementation depends on what you're doing. If you customize CI_Router, you can do it AFTER the code that checks routes.php, so that you can keep routes.php available for future customization.
If the URI contains the controller, function, and parameters, you can parse it within your extended CI_Router and then continue with the request like normal.
If the URI is arbitrary, then you'll need something (file, db, etc) that maps the URI to the correct controller/function/parameters. Using blog posts as an example, you can search for the URI (aka post-slug in WordPress) in the db and grab the corresponding record. Then forward the request to something like "articles/view/ID".
We develop a zend framework application and want that signup pages and login pages were on our domain for example http://domain.com (now all pages are on http://domain.com) and other pages (where you have to be redirected after authentification) on subdomain: http://subdomain.domain.com.
Could you please tell how to solve it?
Thank you for any ideas.
I've done this kind of thing in a major ZF app of mine. It's a complicated 3-part question, but hopefully this will get you started in the right direction.
First is the session cookie. You'll need to use a wildcard domain parameter when you set the session cookie. In your Bootstrap or somewhere prior to when you would normally start your session, include a line such as:
Zend_Session::start(array('cookie_domain' => '.domain.com'));
Note the dot (".") prior to "domain.com". This makes the cookie applicable for domain.com as well as all subdomains under it.
Second is the URL's throughout your site. You can use the Redirector action helper's gotoUrl() method. At the end of an action method when you want to redirect the user, use a line like this:
$this->_redirector->gotoUrl('http://domain.com/somewhere/else');
Of course, you may want to assemble the URL string by other means such as storing the domain in a configuration parameter and concatenating the path using one of ZF's native methods of generating a URL path. See the documentation for Zend_Controller_Action_Helper_Redirector for more. You'll also need to be careful about all URL's on your site and make sure the right domain is included in each link.
Third is how your app interprets routes when subdomains are involved. There are a few ways to accomplish this, but one is to create a module within your app that corresponds to each subdomain you want to use. Then use a Controller Plugin to intercept ZF's normal routing mechanism and set the module name appropriately based on the subdomain. Something like:
class My_Controller_Plugin_RouteMySubdomains extends Zend_Controller_Plugin_Abstract {
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$hostname = $request->getHttpHost();
if (strlen($hostname) > strlen('domain.com')) {
$moduleName = preg_replace("/\.domain\.com$/", '', $hostname);
$request->setModuleName($moduleName);
}
}
}
You'll need to tell ZF to use this plugin. If you're using Zend_Application with an application.ini file for basic configuration, you'll need to add a line like this:
resources.frontController.plugins.routeMySubdomains = "My_Controller_Plugin_RouteMySubdomains"
Good luck!