How to check all database for availability in CI 2 - codeigniter

I have config file database.php with 5 databases.
How can I get 500 error with message "Site is not available" in all pages, if one of a database is not available?

I found it very interesting your question and have been doing some research to solve your problem.
I tell you my solution: the first is to activate the hooks, so in your config.php file make this change:
$config['enable_hooks'] = TRUE;
Once activated the hooks, you need to create a new hook, for it in the file config/hooks.php put something like the following:
$hook['post_controller_constructor'] = array(
'class' => 'DBTest',
'function' => 'index',
'filename' => 'dbtest.php',
'filepath' => 'hooks',
'params' => array(),
);
Thus, your hook kicks in once the controller has been instantiated, but has run no method yet. This is neccesary to use $CI = &get_instance()
To finish create the file /application/hooks/dbtest.php with content similar to the following:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class DBTest {
function index() {
$CI = &get_instance();
$databases = array(
'mysqli://user1:pass1#host1/db1',
'mysqli://user2:pass2#host2/db2',
'mysqli://user3:pass3#host3/db3',
'mysqli://user4:pass4#host4/db4',
'mysqli://user5:pass5#host5/db5',
);
foreach ($databases as $dsn) {
$db_name = substr(strrchr($dsn, '/'), 1);
$CI->load->database($dsn);
$CI->load->dbutil();
if(!$CI->dbutil->database_exists($db_name)) {
// if connection details incorrect show error
show_error("Site is not available: can't connect to database $db_name");
}
}
}
}
You must use dsn for $CI->load->database() in this way we can handle the error instead of Code Igniter when it tries to load the database.
Hope this helps.

Related

codeigniter config form_validation with subfolders not working

I have using a lot config form_validation file. It's working good!
But now I'm trying to get it work with controller in subfolder
/controllers/panel/users.php
My form_validation config file looks like
$config = array(
'panel/users/edit/' => array(
array('field' => 'login', 'label' => 'Логин', 'rules' => "trim|required|valid_email")
)
And my Users controller is
public function edit($user_id = FALSE)
{
if ($this->input->post('save'))
{
$this->load->library('form_validation');
if ($this->form_validation->run())
{
// Do some
}
}
}
But $this->form_validation->run() is always return FALSE
It isn't designed to work this way, there was a relevant change to ruri_string() #122 which would have fixed this but it had other repercussions and needs to be rethought.
You can call your validation rule group explicitly (drop the trailing slash from your rule group name)
if ($this->form_validation->run('panel/users/edit'))
or, if appropriate in your situation, workaround this by prepending uri->segment(1) to the auto-detected rule group.
application/libraries/MY_Form_validation.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation {
function run($group = '')
{
// Prepend URI to match subfolder controller validation rules
$uri = ($group == '') ? $this->CI->uri->segment(1) . $this->CI->uri->ruri_string() : $group;
return parent::run($uri);
}
}

Class 'JTable' not found

I am using Joomla 2.5.11 . I have a php file stored in the /public_html/joomtest/components/com_jumi/files which is pasted below.
I have a PHP form which is stored in the same location i.e /public_html/joomtest/components/com_jumi/files.
I want the PHP form to call the PHP script so that an article is created in Joomla. But whenever the PHP script is called, I receive the below error
Fatal error: Class 'JTable' not found
and the line on which Joomla throws error is
$table = JTable::getInstance('Content', 'JTable', array());
PHP script
<?php
$table = JTable::getInstance('Content', 'JTable', array());
$data = array(
'catid' => 8,
'title' => 'SOME TITLE',
'introtext' => 'SOME TEXT',
'fulltext' => 'SOME TEXT',
'state' => 0,
);
if (!$table->bind($data))
{
$this->setError($table->getError());
return false;
}
if (!$table->check())
{
$this->setError($table->getError());
return false;
}
if (!$table->store())
{
$this->setError($table->getError());
return false;
}
?>
</body>
</html>
I tried putting in
require_once('/libraries/joomla/database/table.php');
but this again didnt work. Please help.
You need to define path of table file you want to use. Use the following code for include the specific table. For example:
JTable::addIncludePath(JPATH_SITE.DS.'components'.DS.'com_content'.DS.'tables');
And then call your table like below:
$con_table = JTable::getInstance('Content', 'JTable', array());
Hope this will work. Good Luck.

Fatal error: Class 'CI_Model' not found on production server, works locally

We're building a web application with CodeIgniter 2.1.4. It's in the crawling stages. Right now, it only has a basic logging and registering system.
What we've so far functions as expected locally, but when we try it online, we get the following error:
Fatal error: Class 'CI_Model' not found in /home4/csurmeli/public_html/other/ems/system/core/Common.php on line 174
It doesn't make any sense since we haven't changed any of the core files. And our online server is well established.
Any suggestions?
The controller calling login:
function login(){
if($this->session->userdata('userid') !== false){
redirect(base_url()."index.php/users/success");
}
$data['error'] = 0;
if($_POST){
$this->load->model('user');
$username = $this->input->post('username',true);
$password = $this->input->post('password',true);
$user = $this->user->login($username,$password);
if(!$user){
$data['error']=1;
redirect(base_url()."index.php/users/error");
}else{
$this->session->set_userdata('userid',$user['userid']);
$this->session->set_userdata('privilege',$user['privilege']);
redirect(base_url()."index.php/users/success");
}
}
$this->load->view('header');
$this->load->view('login',$data);
$this->load->view('footer');
}
Model:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Class User Extends CI_Model{
public function __construct(){
parent::__construct();
}
function create_user($data){
if($data['is_sent']){
$query = array("username" => $data['username'],
"password" => $data['password'],
"email" => $data['email']
);
$this->db->insert('users',$query);
}
}
function login($username,$password){
$where = array(
'username'=>$username,
'password'=>$password
);
$this->db->select()->from('users')->where($where);
$query = $this->db->get();
return $query->first_row('array');
}
}
?>
if it works locally - its probably just an issue on the main index.php page
in index.php find the banners: SYSTEM FOLDER NAME and APPLICATION FOLDER NAME
then double check that the file path and the folder names are correct for your server.

Codeigniter: Extend CI_Lang class when controller loaded to use &get_instance()

I want to extend my CI_Lang class to get language values from the database. So I created a copy of the CI_Lang file and rewrote the load and construct functions.
private $CI;
function __construct()
{
parent::__construct();
log_message('debug', "Language Class Initialized");
$this->CI = &get_instance();
}
I enabled hooks in the config file and created a new hook:
$hook['post_controller_constructor'] = array(
'class' => 'MY_Lang',
'function' => '__construct',
'filename' => 'MY_Lang.php',
'filepath' => 'hooks'
);
This is working correctly. However, when I try to load languages, it's still using the old functions from CI_Lang and not the extended one. Any ideas?
Ok I found the solution without using any hooks.
First: I had to place MY_Lang.php to 'core' folder.
Second: "$this->CI = &get_instance();" has to be placed in the "load" function and not in the construct.
Hope it helps, its working here. :)

codeigniter datamapper relationship validation issues

I need to set up the validation rules to validate the related items on a specific object, ie: A user can have no more than 3 products related to it.
I believe DataMapper can check for this validation using _related_max_size rule, but I can't figure out how to use it on the $validation array in the model.
So far I've tried this in both my user and product models:
var $validation = array(
'product' => array(
'rules' => array('max_size' => 3)
)
);
Can somebody show me an example on how to set up this at the model, controller and finally the view?
Edit: What I mean is, a user has many products, and can create a certain amount of them, let's say 3 products, when that amount is reached, the user can no longer create products, and this validation rule should not permit the user to create more products.
This would be the DB Schema:
Users table
------------------
id | username |
------------------
Products table
------------------------
id | user_id | name |
------------------------
More info here: http://codeigniter.com/forums/viewthread/178045/P500/
Thanks!
EDIT:
Ok, I got it all working now… Except, I need to do the following:
var $validation = array(
'product' => array(
'label' => 'productos',
'rules' => array('required','max_size' => $products_limit)
)
);
The $products_limit comes from the “plan” the user has associated, and it’s stored in the session when the user logs in. When I try to run this I get:
Parse error: syntax error, unexpected T_VARIABLE in /var/www/stocker/application/models/user.php on line 11
Is there any way to make this setting dynamic?
In model
var $validation = array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => array('required')
)
);
In controller. $this -> $object = new Your_model();
$object->validate();
if ($object->valid)
{ $object->save();
// Validation Passed
}
else
{ $data['error'] = $object->error;
// Validation Failed
}
In view.
echo $error->field_name
I never use Codeigniter before, but give me a chance to help you. So far I didn't found any built-in validation in Code-igniter (correct me if I'm wrong).
One workaround that I could think of is to Callback:Your own Validation Functions. Below is a snip. Pardon me if it didn't work as you want.
In Model: (create something like)
function product_limit($id)
{
$this->db->where('product_id',$id);
$query = $this->db->get('products');
if ($query->num_rows() > 3){
return true;
}
else{
return false;
}
}
In controller: (create something like)
function productkey_limit($id)
{
$this->product_model->product_exists($id);
}
public function index()
{
$this->form_validation->set_rules('username', 'Username', 'callback_product_limit');
}
For more information Please refer to the manual page which gives more complete. I am also new to CodeIgniter. But I hope this helps you, not complicate you.
First, set up a custom validation rule in libraries/MY_Form_validation.php
If the file doesn't exist, create it.
Contents of MY_Form_validation.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation
{
function __construct($config = array())
{
parent::__construct($config);
}
function valid_num_products()
{
//Perhaps it would be better to store a maxProducts column in your users table. That way, every user can have a different max products? (just a thought). For now, let's be static.
$maxProducts = 3;
//The $this object is not available in libraries, you must request an instance of CI then, $this will be known as $CI...Yes the ampersand is correct, you want it by reference because it's huge.
$CI =& get_instance();
//Assumptions: You have stored logged in user details in the global data array & You have installed DataMapper + Set up your Product and User models.
$p = new Product();
$count = $p->where('user_id', $CI->data['user']['id'])->count();
if($count>=$maxProducts) return false;
else return true;
}
}
Next, set up your rule in config/form_validation.php.
Contents of form_validation.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config = array
(
'addProduct' => array
(
array
(
'field' => 'name',
'label' => 'Product Name',
'rules' => 'required|valid_num_products'
)
)
);
Next, set up your error message in language/english/form_validation_lang.php. Add the following line:
$lang['valid_num_products'] = "Sorry, you have exceeded your maximum number of allowable products.";
Now in the Controller, you'll want something along the lines of:
class Products extends MY_In_Controller
{
function __construct()
{
parent::__construct();
$this->load->library('form_validation');
}
function add()
{
$p = $this->input->post();
//was there even a post to the server?
if($p){
//yes there was a post to the server. run form validation.
if($this->form_validation->run('addProduct')){
//it's safe to add. grab the user, create the product and save the relationship.
$u = new User($this->data['user']['id']);
$x = new Product();
$x->name = $p['name'];
$x->save($u);
}
else{
//there was an error. should print the error message we wrote above.
echo validation_errors();
}
}
}
}
Finally, you might wonder why I've inherited from MY_In_Controller. There is an excellent article written by Phil Sturgeon over on his blog entitled Keeping It Dry. In the post he explains how to write controllers that inherit from access-controlling Controllers. By using this paradigm, controllers that inherit from MY_In_Controller can be assumed to be logged in, and the $this->data['user']['id'] stuff is therefore assumed to be available. In fact, $this->data['user']['id'] is SET in MY_In_Controller. This helps you seperate your logic in such a way that you're not checking for logged in status in the constructors of your controllers, or (even worse) in the functions of them.

Resources