Codeigniter user tracking for visitors - php

I am working on Codeigniter site and trying to implement User tracking functionality for visitors only (not registered users).
I want to track ( ip address, from_page, to_page, time_stamp) on every page redirect and as I want to track only temporary users I would need to access database too, to check whether account exists or not.
My question is where to write my code, so that Codeigniter automatically checks before each redirect, (keep in mind, that place should have rights to access database or sessions).
Checking in each controller file will make so much redundant code and I don't think htaccess file could do it .
-Thanks

There are multiple ways to do this:
One is to create a helper file, say trackuser_helper.php in the helpers folder. Create a function to do the tracking in this file (say trackUser()). Then autoload this file inside config/autoload.phplike so:
/*
| -------------------------------------------------------------------
| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array('trackuser'); //ignore the '_helper.php' portion of the filename
Now you can just call trackUser() in every controller.
The second option which in my opinion is better is to use Hooks provided by CodeIgniter
These are defined inside config/hooks.php like so:
$hook['pre_controller'][] = array(
'class' => 'MyClass',
'function' => 'Myfunction',
'filename' => 'Myclass.php',
'filepath' => 'hooks',
'params' => array('param1', 'param2', 'etc')
);
The array index correlates to the name of the particular hook point you want to use. In the above example the hook point is pre_controller. A list of hook points is found below. The following items should be defined in your associative hook array:
1.Class - The name of the class you wish to invoke. If you prefer to use
a procedural function instead of a class, leave this item blank.
2.Function - The function name you wish to call. filename The file name
containing your class/function.
3.Filepath - The name of the directory
containing your script. Note: Your script must be located in a
directory INSIDE your application folder, so the file path is
relative to that folder. For example, if your script is located in
application/hooks, you will simply use hooks as your filepath. If
your script is located in application/hooks/utilities you will use
hooks/utilities as your filepath. No trailing slash.
4.Params - Any parameters you wish to pass to your script.
This item is optional.
This specifies which function call you want to execute before each controller load. This way you do not even need to add trackuser() to each controller. These hooks can be pre_controller or post_controller. You can read more about hooks at the CI documentation.

Related

Create folder/Sub-folder in Code-igniter

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

CakePHP - Change Controller name in URL

I have a legacy application built in CakePHP 2.2.3
One part of the application has controller file which has been named SymposiumsController.php. This resulted in URL's such as:
domain.com/symposiums
domain.com/symposiums/view/23
The problem is that 'symposiums' isn't a real (English language) word; it should be 'symposia'.
I want to rename my URL's so they are like this:
domain.com/symposia
domain.com/symposia/view/23
I tried to do this by editing app/Config/Routes.php to use this:
Router::connect('symposia/:action', array('controller' => 'symposiums'));
However all this does is redirects domain.com/symposia to domain.com/symposiums which therefore makes no difference to what the user sees in the URL.
To put it simply I don't want 'symposiums' exposed anywhere in my URLs. I want them all to use 'symposia' in it's place.
I read http://book.cakephp.org/2.0/en/development/routing.html but can't see how to do this. Does anyone have a solution? Surely I don't have to rename controllers/models and DB tables to do this?
I don't know if this makes a difference but I also have admin routing switched on so my SymposiumsController.php also has functions such as:
admin_add()
admin_delete()
admin_edit($id)
Any help is appreciated.
Here is the code for this specific redirection:
Router::connect('/:controller/:action/:id',
array('controller' => 'symposiums', 'action' => 'view', 1)
);
:controller => Give the name new name of controller e.g. symposia
:action => Give the name new name of action e.g. view
:id => Give the name new name of controller e.g. 23
But if you need to redirect more than one action then I suggest you to rename the controller.
Note: If you rename the controller or create new Routers then you would need to make sure in the all application modify the link to new controller name.
Source: Cakephp Router

CodeIgniter HMVC user specific module structure

Im using CI-HMVC stock.
Id like to have a module structure like this:
application
modules
userabc
moduleA
controllers
models
views
moduleB
...
userDEF
moduleC
...
Is this an incorrect way of module organization? Is there another common way of doing something like this?
Im wanting to seperate the users module folders and use them in a URL like this:
userABC.domain.com/module/controller/method
userBCD.domain.com/module/controller/method
You can use that structure if you want, but keep in mind the following:
You must define each user's directory as a module location:
// application/config/config.php
$config['modules_locations'] = array(
// Absolute path // Relative from default application dir
APPPATH.'modules/userABC/' => '../modules/userABC/',
APPPATH.'modules/userDEF/' => '../modules/userDEF/',
APPPATH.'modules/userGHI/' => '../modules/userGHI/',
// etc.
);
You might be able to do this dynamically, but remember that config.php is loaded pretty early so you may need a pre_system hook.
The other thing, which is important if you want all users' modules accessible regardless of which subdomain is active: Order matters!
If userA has a module called "blog" and so does userB, only userA's will ever get loaded (assuming you define userA's module path first). If you're certain no two modules will share the same name, this won't matter as much, but you may suffer a performance hit as the loader will go through the whole stack of module locations until it finds the requested one.
It sounds like you should define a single module_location depending on what user's site is loaded (the subdomain). Something like:
// Get this value dynamically (not sure how you need to do it)
$current_user = 'userABC';
$config['modules_locations'] = array(
APPPATH.'modules/'.$current_user.'/' => '../modules/'.$current_user.'/'
);
Adding submodules in codeigniter you need to defile moudules direcotry in config file like this.
$config['modules_locations'] = array(
APPPATH.'modules/' => '../modules/backend/',
APPPATH.'modules/frontend/' => '../modules/frontend/',
);

How do I block certain URLs using CodeIgniter?

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.

Get to parent folder in codeigniter

I'm putting an DOMpdf creator in my Codeigniter application, but now i need to get an require_once to the parent folder. Somehow Codeigniter doesn't allow me to do this the "normal" way.
This is my require_once
require_once("../dompdf_config.inc.php");
How can I make this work in Codeigniter?
Try something like:
//APPPATH gives you path till application/ folder
require_once(APPPATH.'your_DOMpdf_file_path');
Hope it helps
To load a config file in CodeIgniter, you can call the $this->config->load() method.
To load one of your custom config files you will use the following
function within the controller that needs it:
$this->config->load('filename');
Where filename is the name of your config file, without the .php file
extension.
If you need to load multiple config files normally they will be merged
into one master config array. Name collisions can occur, however, if
you have identically named array indexes in different config files. To
avoid collisions you can set the second parameter to TRUE and each
config file will be stored in an array index corresponding to the name
of the config file. Example:
// Stored in an array with this prototype: $this->config['blog_settings'] = $config
$this->config->load('blog_settings', TRUE);
Please see the section entitled Fetching Config Items below to learn
how to retrieve config items set this way.
The third parameter allows you to suppress errors in the event that a
config file does not exist:
$this->config->load('blog_settings', FALSE, TRUE);
http://codeigniter.com/user_guide/libraries/config.html

Categories