how to free codeigniter results while calling the same model twice - php

I have a situation, I have written a base model in codeigniter, all models extend from it, the base model has a function
public function load_all_by_keys($array, $limit = 0, $offset = 0) {
if ($limit) {
$query = $this->database->get_where($this::DB_TABLE, $array, $limit, $offset);
} else {
$query = $this->database->get_where($this::DB_TABLE, $array);
}
$ret_val = array();
$class = get_class($this);
foreach ($query->result() as $row) {
$model = new $class;
$model->populate($row);
$ret_val[$row->{$this::DB_TABLE_PK}] = $model;
}
return $ret_val;
}
in this function I am able to get lets say for instance, schools which are of category Abet
$abet = new School_Model();
// this query will get all schools with by column category whose value is Abet, thats fine
$abetSchools = $abet-?load_all_by_keys(array('category'=>'Abet'));
$primary = new School_Model();
// This second query fails with the error Fatal error: Call to a member function result() on a non-object
$primarySchools = $primary-?load_all_by_keys(array('category'=>'Primary'))
Can someone help

$this->db->flush_cache()
This function deletes all items from the Active Record cache (Reference http://ellislab.com/codeigniter/user-guide/database/active_record.html#caching)

Related

unable to get data though model function code igniter

I have created one new function in a existing controller, in which I am accessing a model's function which has a query to get the list.
I have loaded the model in controller. This model function works with other function but not working for new created function.
class Cart extends CI_Controller
{
function Cart()
{
parent::__construct();
$this->mdl_common->checkUserSession();
$this->load->model('mdl_friend_web');
$this->load->model('api/mdl_friend','mdl_friend_api');
$this->load->model('mdl_cart_web');
$this->load->library('pagination');
}
//works for this function
function ajax_get_cart_list($offset = 0)
{
is_ajax();
$this->load->model('mdl_cart_web');
$limit = PER_PAGE;
$s_data = $_POST;
$carts = $this->mdl_cart_web->get_cart_list($limit,$offset,$s_data)->result_array();
$totalRows = $this->mdl_cart_web->get_total_cart_product($s_data)->num_rows();
$data = $this->mdl_common->pagination_data('cart/get_cart_list/',$totalRows,$limit,'show_data');
$data['carts'] = $carts;
$data['total_cart'] = $totalRows;
$html = $this->load->view('cart/ajax_cart_list',$data,true);
echo $html;
}
//not working for this
function calculate_distance()
{
$limit = '';
$delivery = 0;
$previousName = '';
$count = 0;
$oneShop = '0';
is_ajax();
// $this->load->model('mdl_cart_web');
$lat1 = $_POST['lat1'];
$long1 = $_POST['long1'];
// $user_id = $_POST['user_id'];
$user_id = $this->session->userdata('user_id');
$carts = $this->mdl_cart_web->get_cart_list($limit,0,'')->result_array();
$response = array();
$data['carts'] = $carts;
foreach($data['carts'] as $row) {
echo $row['store_latitude'];
}
}
model
<?php
class Mdl_cart_web extends CI_Model
{
/*=================================================================================
Get cart list
==================================================================================*/
function get_cart_list($limit,$offset,$data)
{
$this->db->select('c.*,p.*,s.name as store_name,s.latitude as store_latitude,s.longitude as store_longitude,count(r.product_id) as review , IFNULL(AVG(r.star),0) as avg_star,i.*',false);
$this->db->join('p_product as p','c.product_id = p.product_id','left');
$this->db->join('p_product_image as i','c.product_id = i.product_id','left');
$this->db->join('p_product_review as r','c.product_id = r.product_id','left');
$this->db->join('p_store as s','s.store_id = p.store_id','left');
$this->db->limit($limit,$offset);
$this->db->where('c.user_id',$this->session->userdata('user_id'));
$this->db->group_by('c.cart_id');
$this->db->from('p_cart as c');
return $this->db->get();
}
?>
I am not able to get the array data.I can see blank alert.
What is going wrong here? Please help.Thank you.
I think you are writing your query not properly try this:
$this->db->select('c.*,p.*,s.name as store_name,s.latitude as store_latitude,s.longitude as store_longitude,count(r.product_id) as review , IFNULL(AVG(r.star),0) as avg_star,i.*',false);
$this->db->from('p_cart as c');
$this->db->join('p_product as p','c.product_id = p.product_id','left');
$this->db->join('p_product_image as i','c.product_id = i.product_id','left');
$this->db->join('p_product_review as r','c.product_id = r.product_id','left');
$this->db->join('p_store as s','s.store_id = p.store_id','left');
$this->db->limit($limit, $offset);
$this->db->where('c.user_id', $this->session->userdata('user_id'));
$this->db->group_by('c.cart_id');
return $this->db->get();
As Above comment and after seeing your question that the model works fine for the one function and not for the other so I think that loading a model is what you have to look properly.
I see that in your not working function you have noticed some basic problems.
You have commented the model loading code after is_ajax(). // $this->load->model('mdl_cart_web'); so first remove that comment and try again.
Send Correct and proper data to the model. Please Check this below line of code that is executing properly or not.
In Your Not working model.
$carts = $this->mdl_cart_web->get_cart_list($limit,0,'')->result_array();
In Your Working Model:
$carts = $this->mdl_cart_web->get_cart_list($limit,$offset,$s_data)->result_array();
And One thing I want if you are using the same model in more functions in the same controller then you should use __construct()
public function __construct() {
parent::__construct ();
$this->load->model('mdl_cart_web');
}
By adding a model into the __construct() you can use it in the entire controller and all of the functions.

Automatically sort all Arrays in controller when getting from database PHP

So I have this controller that passes an associative array called $pagedata to the view. Inside this array are 3 more associative arrays, and the view renders 3 select elements with the array data as options. I want to sort the 3 arrays but I don't want to write sort 3 times here or add order_by into the query methods, because there are dozens of similar pages and I don't want to write hundreds of sort method calls. I was told I could solve this in the constructor. I was wondering if there's an OOP solution that lets me automatically sort all child arrays inside $pagedata.
class Sku extends CI_Controller {
protected $pagedata = array();
public function __construct()
{
parent::__construct();
$this->load->model('mc');
}
public function inventory()
{
$this->pagedata['class_ids'] = $this->mc->get_class_ids();
$this->pagedata['retail_readys'] = $this->mc->get_all_retail_ready();
$this->pagedata['statuses'] = $this->mc->get_all_status();
}
}
Edit:
I'm exploring using an ArrayObject or wrapping $pagedata in an object and watch for changes.
ok this will be painfull for codeigniter but yes a kind of solution
public function __construct()
{
parent::__construct();
$this->load->model('mc');
$class_ids = $this->mc->get_class_ids();
$class_ids = $this->sortAscending($class_ids, $key);
$this->pagedata['class_ids'] = $class_ids;
$retail_readys = $this->mc->get_all_retail_ready();
$class_ids = $this->sortAscending($class_ids, $key);
$this->pagedata['class_ids'] = $class_ids;
$statuses = $this->mc->get_all_status();
$statuses = $this->sortAscending($class_ids, $key);
$this->pagedata['statuses'] = $statuses;
}
function sortAscending($accounts, $key)
{
$ascending = function($accountA, $accountB) use ($key) {
if ($accountA[$key] == $accountB[$key]) {
return 0;
}
return ($accountA[$key] < $accountB[$key]) ? -1 : 1;
};
usort($accounts, $ascending);
return $accounts;
}
public function inventory()
{
// already get values
//$this->pagedata['class_ids'] = $this->mc->get_class_ids();
//$this->pagedata['retail_readys'] = $this->mc->get_all_retail_ready();
//$this->pagedata['statuses'] = $this->mc->get_all_status();
$this->load->view('index',$this->pagedata);
}
public function another_function()
{
// already get values
//$this->pagedata['class_ids'] = $this->mc->get_class_ids();
//$this->pagedata['retail_readys'] = $this->mc->get_all_retail_ready();
//$this->pagedata['statuses'] = $this->mc->get_all_status();
$this->load->view('another page',$this->pagedata);
}

Codeigniter: Call to a member function result_array() on a non-object

I'm using Codeigniter to build a webapp and I received this error:
Fatal error: Call to a member function result_array() on a
non-object in /var/www/application/controllers/people.php on line 29
This is the people.php class:
public function __construct()
{
parent::__construct();
}
function People() {
}
function view($id) {
echo "Hello world " . $id;
}
function all() {
$this->load->model('people_model', '', TRUE);
$allContacts = $this->people_model->get_all_contacts();
$results = array();
foreach ($allContacts->result_array() as $row) {
$eachrow = array("personID"=>$row['personID'],"fName"=>$row['fName'],"lName"=>$row['lName'],"phoneNumber"=>"",
"emailAddress"=>$row['emailAddress'],"address"=>$row['address'],"city"=>$row['city'],"state"=>$row['state'],"zip"=>$row['zip']);
$results = push_array($results, $eachrow);
}
foreach ($results as $row) {
$phoneData = $this->people_model->get_phone_by_id($row['personID']);
$phoneNumbers = "";
foreach ($phoneData->result_array() as $row2) {
$phoneNumbers = $row2['type'] . " " . $row2['phoneNumber'] . " " . $row2['extension'];
}
$results['phoneNumber'] = $phoneNumbers;
}
$data['title']="Page Title Goes Here";
$data['username']="Your Username";
$this->load->view('header', $data);
$this->load->view('people_results', $results);
$this->load->view('footer');
}
}
Here is the people_model class:
function __construct()
{
// Call the Model constructor
parent::__construct();
}
function get_all_contacts() {
$query = $this->db->query('SELECT * FROM person');
return $query->result();
}
function get_phone_by_id($id) {
$query = $this->db->query('SELECT * FROM phoneNumber WHERE personID = '.$id);
return $query->result();
}
}
The only thing I might question in database.php is if the hostname needs a port number, but I don't think that helped when I tried it.
I just tried adding (based on similar question in side bar)
$this->mydb = $this->load->database('realDB', TRUE);
to the people_model and changing the db to mydb and received this error:
You have specified an invalid database connection group.
and this is my line in database.php:
$db['default']['database'] = 'realDB';
Thanks for all your help.
since get_all_contacts is already using the result() function in your model, you can't also use the result_array() function in your controller. result_array() would be a method of the $query object. The quick and dirty way to get this working(which might break other stuff if its also using the get_all_contacts method) would be to change your get all contacts function to the following:
function get_all_contacts() {
$query = $this->db->query('SELECT * FROM person');
return $query;
}
however, if you want to be smarter about it and not risk breaking other stuff, you can pass a param from the controller, and only return query if its set like so:
REVISED CONTROLLER LINE**
$allContacts = $this->people_model->get_all_contacts(true);
REVISED MODEL CODE
function get_all_contacts($special = false) {
$query = $this->db->query('SELECT * FROM person');
if($special)
{
return $query;
}
return $query->result();
}

Multiple Query in one model in joomla 2.5

Can I do 2 separate queries in a model in joomla 2.5 ?
If it is possible, how do you do this?
This is my model:
<?php
defined('_JEXEC') or die();
jimport( 'joomla.application.component.modellist' );
class AnagraficheModelServiziassociatiaggiuntivi extends JModelList
{
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array('id_servizi_aggiuntivi', 'id_persona', 'id_servizio', 'nome_servizio', 'cod_servizio', 'id_tipologia_socio', 'nome_servizio');
}
parent::__construct($config);
}
function getListQuery()
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('id_servizi_aggiuntivi, id_persona , id_servizio , nome_servizio');
$query->from('#__servizi_aggiuntivi as serviziaggiuntivi, #__elenco_servizi');
$query->where('cod_servizio=id_servizio');
$result1 = $db->loadObjectList();
//$db->setQuery($query);
$query = $db->getQuery(true);
$query->select('id_tipologia_socio, id_servizio as cod_servizio, nome_servizio');
$query->from('#__associazione_servizi as serviziassociati, #__elenco_servizi');
$query->where('cod_servizio=id_servizio');
$result1 = $db->loadObjectList();
return $query;
}
protected function populateState($ordering = null, $direction = null)
{
// Load the filter state.
$search = $this->getUserStateFromRequest($this->context.'.filter.search', 'filter_search');
$this->setState('filter.search', $search);
// List state information.
parent::populateState($ordering, $direction);
}
}
?>
This doesn't work, but if I delete the second query it works great!
In my opinion, the problem is in the function getListQuery(). In this function I want insert 2 queries not 1 query! Is it possible?
The short answer is no. getListQuery should return a query. You can't get it to return two queries.
Instead, you likely want to override the getItems function to process the items after the first query runs. You can either adjust or add items using something like the following:
public function getItems() {
// load items from the parent getItems function, which will call getListQuery to handle your first query.
//It only adds items if the first query works.
if ($items = parent::getItems()) {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('id_tipologia_socio, id_servizio as cod_servizio, nome_servizio');
$query->from('#__associazione_servizi as serviziassociati, #__elenco_servizi');
$query->where('cod_servizio=id_servizio');
$result1 = $db->setQuery($query)->loadObjectList();
// this is a simple way to merge the objects. You could do other processing (loops, etc) to meld the information together
$items = (object) array_merge((array) $items, (array) $restult1);
}
return $items;
}

Paginating query results with Codeigniter

I'm new to Codeigniter and PHP in general, so bear with me.
I'm attempting to use the codeigniter pagination class to paginate the results returned from a query. The code below works fine with static queries that don't require any parameters passing. However, it seems to break down when attempting to pass a variable as a parameter in the URL e.g.
localhost/index.php/termsbyletter/index/a
where 'a' is the $letter variable passed to the controller/model.
PHP isn't outputting any errors and the query performs as expected, as does the record_count function within the model. The result is that all of the query results are displayed, but all on the same page, which stays the same when the pagination links are clicked.
Also, in the model, is there a more efficient way of returning the row count than running the query twice? I've read on here that this is necessary, and I haven't had any success trying to pass this value any other way.
Here is my controller:
<?php
class Termsbyletter extends CI_Controller
{
public function __construct() {
parent:: __construct();
$this->load->helper("url");
$this->load->model("terms_by_letter");
$this->load->library("pagination");
}
public function index($letter) {
$config = array();
$config["base_url"] = base_url() . 'index.php/termsbyletter/index/' . $letter;
$config["total_rows"] = $this->terms_by_letter->record_count($letter);
$config["per_page"] = 3;
$config["uri_segment"] = 5;
$this->pagination->initialize($config);
$page = ($this->uri->segment(5)) ? $this->uri->segment(5) : 0;
$data["results"] = $this->terms_by_letter->term($config["per_page"], $page, $letter);
echo $this->pagination->create_links();
$this->load->view("/templates/header");
$this->load->view("/terms/index", $data);
$this->load->view("/templates/footer");
}
}
and the model:
class Terms_by_letter extends CI_Model
{
public function __construct() {
parent::__construct();
$this->load->database();
}
public function record_count($letter) {
$query = $this->db->query("SELECT * FROM news WHERE LEFT(slug, 1) = '$letter'");
return $query->num_rows();
}
public function term($limit, $start, $letter) {
$this->db->limit($limit, $start);
$query = $this->db->query("SELECT * FROM news WHERE LEFT(slug, 1) = '$letter'");
if ($query->num_rows() > 0) {
foreach ($query->result() as $row) {
$data[] = $row;
}
return $data;
}
return false;
}
}
and I'm using something like this to output the results in the view:
<?php
foreach($results as $data) {
echo $data->slug "<br>";
}
?>
<p><?php echo $links; ?></p>
You're trying to mix active records with normal CI queries and that won't work. Change the query to:
$query = $this->db->query("SELECT * FROM news WHERE LEFT(slug, 1) = '$letter' LIMIT $start, $limit");
Either that or go the active record route entirely with:
$this->db->limit($limit, $start);
$this->db->where('LEFT(slug,1)',$letter);
$this->db->get('news');
As far as I know there is no way to return all the results you need with a single query, the controller needs total records to figure out the pagination, then it needs to select just the records for one page.
You could however just write the query once and change the parameters a bit.
public function term($limit, $start, $letter) {
if($limit > 0)
{
$this->db->limit($limit, $start);
}
$this->db->where('LEFT(slug,1)',$letter);
$this->db->get('news');
Then in your controller you'd get the count like this:
$config["total_rows"] = $this->terms_by_letter->term(0,0,$letter);

Categories