CodeIgniter and autoloading the database library - codeigniter

I've got an issue connecting to the database with CodeIgniter.
In the model, if I do
$this->load->database();
then a query such as
$query = $this->db->get('articles', 10);
works and returns data. However, when I remove the load->database line and try autoloading the database library, using
$autoload['libraries'] = array('database');
in application/config/autoload.php, the above query fails. As it works when I explicitly load the library, it's not a problem with my database connection. I'm using CodeIgniter 2.0.2 (the current latest release).
As most of my pages use the database I'd like to autoload it to avoid having to load it anually in each model. Have I misunderstood the documentation regarding loading the database library or am I doing something wrong?

I know I am probably just answering a dead question but i had the same problem.
if you are using eclipse pdt or similar IDE and modified the system>core>model.php by adding some variables just before the constructor to get code completion then the autoload doesnt work
i dont know why but the fact is it doesnt work. I restored the core>model.php to original and autoload works fine. I dont get autoload now and its really a bad experience for new coder to CI.
If you have a workaround please comment so.

This is just an alternative if you still can't resolve the issue. Just extend the CI_Model and auto load the database library in the constructor. Then you can just make all other models inherit from that base class.
Example:
<?php
class My_Model extends CI_Model{
public function __construct(){
parent::__construct();
$this->load->database();
}
}
And the all others will start like :
<?php
class Some_Model extends MY_Model{}
This method has the other benefit that you don't have to include the loading code line in every model you create. Also you can easily push shared functionalities among models into the parent MY_Model class.
Hope it helps!

This is my database.php from my application/config/ directory
$active_group = 'default';
$active_record = TRUE;
$db['default']['hostname'] = 'mydbhost';
$db['default']['username'] = 'myusername';
$db['default']['password'] = 'mypassword';
$db['default']['database'] = 'mydatabase';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
Check yours looks like this and rerun through the user guide at http://codeigniter.com/user_guide/database/configuration.html and reread the comments in the autoload.php file in the config directory.
The relevant line in mine reads:
$autoload['libraries'] = array('database', 'form_validation', 'session');
You should be loading the db library like this:
$this->load->library('database');

The only thing I can think of is in your application/config/database.php file, the following line is set to false, instead of true.
//['autoinit'] Whether or not to automatically initialize the database.
$db['default']['autoinit'] = TRUE;
Everything else looks ok.

Shababhsiduque,
Just you we're right, at least in my case!
The workaround to getting the ide to work is creating the reference variables in ANOTHER CI project.
That is leave the system model as it is in the current project but modify it in another project.
Then change the php buildpath (project->properties->phpbuildpath) to the project with the variables.
Note this are settings for Aptana Studio 3.
Worked for me.

You could try PHP Autoload Class Magic function in this case.
function __autoload($class)
{
if(strpos($class, 'CI_') !== 0)
{
#include_once( APPPATH . 'libraries/'. $class . '.php' );
}
}
This code must copied inside the config.php (after the last line) within Application folder.
This code will automatically load libraries for you when its needed.
It might work. Happy coding.

In my case the problem was because there was another occurrence of $autoload['libraries'] inside the same file and it reset the array.

Related

Codeigniter loading library after session is set

I am using codeigniter with sqlite and I have created a new library for connecting the sqlite database. The sqlite database will connect only if the session is set.
LIBRARY (userdb)
$CI =& get_instance();
if( $CI->session->userdata('user') ){
$userId = $CI->session->userdata('user');
$this->conDb = new PDO("sqlite:" . BASEPATH . "sqlitedb/" . $userId . "/data.db");
}else{
$userId = '';
}
And I execute queries by using $query = $this->userdb->query($sql);
It works fine but the problem is that query only works if the page is refreshed after session is created otherwise it returns Call to a member function query() on a non-object error.
CONTROLLER
$sessiondata = array('user' => $userid);
$this->session->set_userdata($sessiondata);
$insert = $this->user_model->insert($data);
All this seems legit, if you set your userdata while the page/controller is loading it means that the librairies and other assets have been loaded already. So when your userdb library is loaded there is no sessions set yet.
You have two ways to fix this : Try to Load your library after loading your controller but for a db library this would be better to be in your config file so that it is auto loaded.
The other way would be to reload or redirect your current PAGE after the session isset. So that you can use your db library
Hope that helps You
NwK

isset() on codeigniter objects

How can I achieve something that looks like:
if (isset($this->session->flashdata('user_profile'))) {}
without:
Fatal error: Call to a member function flashdata() on a non-object in ...
The issue is that it returns an error when that thing isn't set rather than continue as one might expect. If it is set, everything works out fine.
...
I have also tried:
$tmp = $this->session->flashdata('user_profile');
if ($tmp) {
but to no avail.
you don't need isset(); cause CI methods returns false or true
just do
if($this->session->flashdata()){ }
and your error is cause you are surely not loading the session library:
so do this:
$this->load->library('session');
if($this->session->flashdata()){ }
if you prefer (i preferr) you can autoload the session library changing this in your config/autoload.php file:
$autoload['libraries'] = array('session');
so now you don't have to load anytime the session library cause CI autoloads that for you
You can check the existence of $this->session first
if (isset($this->session) && isset($this->session->flashdata('user_profile'))) {
}
For proper validation you must do this method. Weather the values becomes NULL sometimes.
$sessusr=$this->session->userdata('username');
if(isset($sessusr) && trim($sessusr!=''))
{
//to do
}
Have you auto load the session library if not go to config/autoload.php open it and try to add session libarary it will look like this $autoload['libraries'] = array('session'); if you have auto loaded the library than the alternative approach is:
if(!empty($this->session->flashdata('user_profile')): echo $this->session->flashdata('user_profile'); endif;

codeigniter hmvc routes not working properly

I installed HMVC by wiredesignz but the routes from application/modules/xxx/config/routes.php didn't get recognized at all.
Here is an example:
In application/modules/pages/config/routes.php I have:
$route['pages/admin/(:any)'] = 'admin/$1';
$route['pages/admin'] = 'admin';
If I type the URL, domain.com/admin/pages/create it is not working, the CI 404 Page not found appears.
If I move the routes to application/config/routes.php it works just fine.
How do I make it work without putting all the admin routes in main routes.php?
I searched the web for over 4 hours but found no answers regarding this problem. I already checked if routes.php from modules is loading and is working just fine, but any routes I put inside won't work.
I found a way of making the routes from modules working just fine, I don't know if is the ideal solution but works fine so far:
open your application/config/routes.php and underneath $route['404_override'] = ''; add the following code:
$modules_path = APPPATH.'modules/';
$modules = scandir($modules_path);
foreach($modules as $module)
{
if($module === '.' || $module === '..') continue;
if(is_dir($modules_path) . '/' . $module)
{
$routes_path = $modules_path . $module . '/config/routes.php';
if(file_exists($routes_path))
{
require($routes_path);
}
else
{
continue;
}
}
}
the following solution works fine even if config folder or routes.php is missing from your module folder
Here's the thing: the module's routes.php only gets loaded when that module is "invoked", otherwise CI would have to load all route configurations from all modules in order to process each request (which does not happen).
You'll have to use your main application's routes.php to get this to work. You aren't using the pages segment in your URL, therefore the routing for that module never gets loaded.
I know that's what you wanted to avoid, but unfortunately it's not possible unless you want to get "hacky".
Here's the routing I use to map requests for admin/module to module/admin, maybe you can use it:
// application/config/routes.php
$route['admin'] = "dashboard/admin"; // dashboard is a module
$route['admin/([a-zA-Z_-]+)/(:any)'] = "$1/admin/$2";
$route['admin/([a-zA-Z_-]+)'] = "$1/admin/index";
$route['(:any)/admin'] = "admin/$1";
You just need this https://gist.github.com/Kristories/5227732.
Copy MY_Router.php into application/core/

Define custom variable in config.php and access it in view

I have defined image_path in config.php and now need to access this variable in views like we use base_url().
Hos is it possible?
You would need to extend the url_helper. See the "Extending Helpers" section in the documentation.
In short, create a file name MY_url_helper.php in your application/helpers folder. (Assuming $config['subclass_prefix'] = 'MY_', in your config file.)
Add the following method.
if ( ! function_exists('image_path'))
{
function image_path()
{
$CI =& get_instance();
return $CI->config->item('image_path');
}
}
This should do the trick.
Use constants.php, that's what it's for, this is out of my constants.php for image paths.
/*Constant paths*/
define('LOGO_PATH',APPPATH.'assets/images/manulogos/');
define('PROD_IMAGE_PATH',APPPATH.'../assets/images/prod_images/');
Then you just call the constant where you need it.
$imageName = $this->doUpload($control,PROD_IMAGE_PATH,$image,'all')

Codeigniter global_xss_filtering

In my codeigniter config I have $config['global_xss_filtering'] = TRUE;. In my admin section I have a ckeditor which generates the frontend content.
Everything that is typed and placed inside the editor works fine, images are displayed nice, html is working. All except flash. Whenever I switch to html mode and paste a youtube code piece it is escaped and the code is visible on the frontpage instead of showing a youtube movie.
If I set $config['global_xss_filtering'] = FALSE; the youtube code is passed like it should. This is because 'object', 'embed' etc are flagged as "naughty" by CI and thus escaped.
How can I bypass the xss filtering for this one controller method?
Turn it off by default then enable it for places that really need it.
For example, I have it turned off for all my controllers, then enable it for comments, pages, etc.
One thing you can do is create a MY_Input (or MY_Security in CI 2) like the one in PyroCMS and override the xss_clean method with an exact copy, minus the object|embed| part of the regex.
http://github.com/pyrocms/pyrocms/blob/master/system/pyrocms/libraries/MY_Security.php
It's one hell of a long way around, but it works.
Perhaps we could create a config option could be created listing the bad elements for 2.0?
My case was that I wanted global_xss_filtering to be on by default but sometimes I needed the $_POST (pst you can do this to any global php array e.g. $_GET...) data to be raw as send from the browser, so my solution was to:
open index.php in root folder of the project
added the following line of code $unsanitized_post = $_POST; after $application_folder = 'application'; (line #92)
then whenever I needed the raw $_POST I would do the following:
global $unsanitized_post;
print_r($unsanitized_post);
In CodeIgniter 2.0 the best thing to do is to override the xss_clean on the core CI library, using MY_Security.php put this on application/core folder then using /application/config.php
$config['xss_exclude_uris'] = array('controller/method');
here's the MY_Security.php https://gist.github.com/slick2/39f54a5310e29c5a8387:
<?php
/**
* CodeIgniter version 2
* Note: Put this on your application/core folder
*/
class MY_Security extends CI_Security {
/**
* Method: __construct();
* magic
*/
function __construct()
{
parent::__construct();
}
function xss_clean($str, $is_image = FALSE)
{
$bypass = FALSE;
/**
* By pass controllers set in /application/config/config.php
* config.php
* $config['xss_exclude_uris'] = array('controller/method')
*/
$config = new CI_Config;
$uri = new CI_URI;
$uri->_fetch_uri_string();
$uri->_explode_segments();
$controllers_list = $config->item('xss_exclude_uris');
// we need controller class and method only
if (!empty($controllers_list))
{
$segments = array(0 => NULL, 1 => NULL);
$segments = $uri->segment_array();
if (!empty($segments))
{
if (!empty($segments[1]))
{
$action = $segments[0] . '/' . $segments[1];
}
else
{
$action = $segments[0];
}
if (in_array($action, $controllers_list))
{
$bypass = TRUE;
}
}
// we unset the variable
unset($config);
unset($uri);
}
if ($bypass)
{
return $str;
}
else
{
return parent::xss_clean($str, $is_image);
}
}
}
Simple do the following on the views when displaying embedded object code like from YouTube and etc:
echo str_replace(array('<', '>'), array('<', '>'), $embed_filed);
The global XSS Filtering is only escaping (or converting) certain "dangerous" html tags like <html>
Simple Workaround:
Set $config['global_xss_filtering'] = TRUE;
Run your POST data through HTMLPurifier to remove any nasty <script> tags or javascript.
HTMLPurifier Docs
HTMLPurifier Codeigniter Integration
On the page where you receive the forms POST data use html_entity_decode() to undo what XSS filtering did.
//by decoding first, we remove everything that XSS filter did
//then we encode all characters equally.
$content = html_entity_decode($this->input->post('template_content'))
Then immediately run it through htmlentities()
$content = htmlentities($content);
Store as a Blob in MySQL database
When you want to display the
information to the user for editing run html_entity_decode()
This is how I did it. If anyone knows of a major flaw in what I did, please tell me. It seems to be working fine for me. Haven't had any unexpected errors.

Resources