Codeigniter Call to a member function row() on bool - php

I am getting error in my model file
An uncaught Exception was encountered
Type: Error
Message: Call to a member function row() on bool
Filename: application/models/Ledger_model.php
Line Number: 47
Backtrace:
File: application/controllers/Purchase.php
Line: 56
Function: get_branch_from_ledger_id
File: index.php
Line: 315
Function: require_once
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Ledger_model extends CI_Model
{
function __construct() {
parent::__construct();
}
public function index(){
}
/*
return all discount details to display list
*/
public function get_records(){
return $this->db->select('l.*,a.group_title')
->from('ledger l')
->join('account_group a','a.id = l.accountgroup_id')
->get()
->result();
}
public function get_records_by_accountgroup_category($category)
{
return $this->db->select('l.*,a.group_title')
->from('ledger l')
->join('account_group a','a.id = l.accountgroup_id')
->where_in('category',$category)
->get()
->result();
}
function get_single_record($id)
{
return $this->db->get_where("ledger",array('id'=>$id))->row();
}
function get_branch_from_ledger_id($id)
{
return $this->db->select('l.*,a.branch_id')
->from('ledger l')
->join('account_group a','a.id = l.accountgroup_id')
->where('l.id',$id)
->get()
->row()
->branch_id;
}
// public function get_records_by_branch($branch_id)
// {
// return $this->db->select('l.*,b.branch_name as branch_name,ag.category as category')
// ->from('ledger l')
// ->join('account_group ag','l.accountgroup_id = ag.id')
// ->join('account_group_branch agb','agb.account_group_id = l.accountgroup_id')
// ->join('branch b','b.branch_id = agb.branch_id')
// ->where('b.branch_id',$branch_id)
// ->get()
// ->result();
// }
function add_record($data)
{
if($this->db->insert('ledger',$data))
{
return $this->db->insert_id();
}else
{
return FALSE;
}
}
function edit_record($data,$id)
{
$this->db->where('id',$id);
if($this->db->update('ledger',$data)){
// echo $this->db->last_query();
// exit;
return true;
}else{
return false;
}
}
function delete_record($id)
{
// $ledger = $this->db->get_where('ledger',array('accountgroup_id'=>$id))->result();
// $no_ledger = sizeof($ledger);
// echo $no_users;
// exit;
// if($no_ledger > 0)
// {
// return $no_ledger;
// }
// else
// {
$this->db->where('id', $id);
if($this->db->delete('ledger'))
{
return true;
}
else
{
return false;
}
// }
}
public function getBranch()
{
$this->db->select('branch_id,branch_name');
$branch = $this->db->get('branch');
return $array = $branch->result_array();
}
public function getAccountGroup()
{
$this->db->select('id,group_title');
$acc_group = $this->db->get('account_group');
return $array = $acc_group->result_array();
}
public function addModel($data){
$sql = "insert into discount (discount_name,discount_value,user_id) values(?,?,?)";
if($this->db->query($sql,$data)){
return TRUE;
}
else{
return FALSE;
}
}
public function getRecord($id){
$sql = "select * from discount where discount_id = ?";
if($query = $this->db->query($sql,array($id))){
return $query->result();
}
else{
return FALSE;
}
}
public function editModel($data,$id){
$sql = "update discount set discount_name = ?,discount_value = ? where discount_id = ?";
if($this->db->query($sql,array($data['discount_name'],$data['discount_value'],$id))){
return TRUE;
}
else{
return FALSE;
}
}
public function deleteModel($id){
$sql = "delete from discount where discount_id = ?";
if($this->db->query($sql,array($id))){
return TRUE;
}
else{
return FALSE;
}
}
public function addLedger($data)
{
$this->db->insert('ledger', $data);
return $this->db->insert_id();
}
public function getledgerWithJoin($id)
{
$this->db->select('L.*,B.branch_name,A.group_title');
$this->db->from('ledger AS L');// I use aliasing make joins easier
$this->db->join('branch AS B', 'B.id = L.branch_id', 'INNER');
$this->db->join('account_group AS A', 'A.id = L.accountgroup_id', 'INNER');
$this->db->where('L.id',$id);
$q = $this->db->get();
if( $q->num_rows() > 0 )
{
return $q->row();
}
return FALSE;
}
public function getledgerById($id)
{
$q = $this->db->get_where('ledger', array('id' => $id), 1);
if( $q->num_rows() > 0 )
{
return $q->row();
}
return FALSE;
}
public function updateLedger($ledgerDetail,$id)
{
$ledgerData = array(
'branch_id' => $ledgerDetail['branch_id'],
'type' => $ledgerDetail['type'],
'title' => $ledgerDetail['title'],
'accountgroup_id' => $ledgerDetail['accountgroup_id'],
'opening_balance' => $ledgerDetail['opening_balance'],
'closing_balance' => $ledgerDetail['closing_balance'],
);
$this->db->where('id', $id);
if($this->db->update('ledger', $ledgerData)) {
return true;
}
return false;
}
public function getBillerLedgerDetail($ledger_id){
$user = $this->db->get_where('biller', array('ledger_id' => $ledger_id))->row();
if(is_null($user)){
return false;
}else{
return $user->biller_id;
}
}
public function getCustomerLedgerDetails($ledger_id){
$user = $this->db->get_where('customer', array('ledger_id' => $ledger_id))->row();
if(is_null($user)){
return false;
}else{
return $user->customer_id;
}
}
public function getBankLedgerDetails($ledger_id){
$user = $this->db->get_where('bank_account', array('ledger_id' => $ledger_id))->row();
if(is_null($user)){
return false;
}else{
return true;
}
}
public function getSuppliersLedgerDetails($ledger_id){
$user = $this->db->get_where('suppliers', array('ledger_id' => $ledger_id))->row();
if(is_null($user)){
return false;
}else{
return true;
}
}
public function getPurchaserLedgerDetails($ledger_id){
$user = $this->db->get_where('users', array('ledger_id' => $ledger_id))->row();
if(is_null($user)){
return false;
}else{
return $user->id;
}
}
public function deleteLedger($id)
{
if($this->db->delete('ledger', array('id' => $id))) {
return true;
}
return FALSE;
}
}
?>

It sounds like there were no results, so there was nothing to get. Try this to check for results before you attempt to grab it.
function get_branch_from_ledger_id($id)
{
$rows = $this->db->select('l.*,a.branch_id')
->from('ledger l')
->join('account_group a','a.id = l.accountgroup_id')
->where('l.id',$id)
->get();
return $rows ? $rows->row()->branch_id : false;
}

Related

Laravel 5.2 Undefined index: latitude

Hello why I have this execption:
This is controller:
public function addnew(Request $request)
{
$data = \Input::except(array('_token')) ;
$rule=array(
'restaurant_type' => 'required',
'restaurant_name' => 'required',
'restaurant_address' => 'required',
'restaurant_logo' => 'mimes:jpg,jpeg,gif,png'
);
$validator = \Validator::make($data,$rule);
if ($validator->fails())
{
return redirect()->back()->withErrors($validator->messages());
}
$inputs = $request->all();
if(!empty($inputs['id'])){
$restaurant_obj = Restaurants::findOrFail($inputs['id']);
}else{
$restaurant_obj = new Restaurants;
}
//Slug
if($inputs['restaurant_slug']=="")
{
$restaurant_slug = str_slug($inputs['restaurant_name'], "-");
}
else
{
$restaurant_slug =str_slug($inputs['restaurant_slug'], "-");
}
//Logo image
$restaurant_logo = $request->file('restaurant_logo');
if($restaurant_logo){
\File::delete(public_path() .'/upload/restaurants/'.$restaurant_obj->restaurant_logo.'-b.jpg');
\File::delete(public_path() .'/upload/restaurants/'.$restaurant_obj->restaurant_logo.'-s.jpg');
$tmpFilePath = 'upload/restaurants/';
$hardPath = substr($restaurant_slug,0,100).'_'.time();
$img = Image::make($restaurant_logo);
$img->fit(120, 120)->save($tmpFilePath.$hardPath.'-b.jpg');
$img->fit(98, 98)->save($tmpFilePath.$hardPath. '-s.jpg');
$restaurant_obj->restaurant_logo = $hardPath;
}
$user_id=Auth::User()->id;
$restaurant_obj->user_id = $user_id;
$restaurant_obj->restaurant_type = $inputs['restaurant_type'];
$restaurant_obj->restaurant_name = $inputs['restaurant_name'];
$restaurant_obj->restaurant_slug = $restaurant_slug;
$address = $restaurant_obj->restaurant_address = $inputs['restaurant_address'];
$restaurant_obj->restaurant_description = $inputs['restaurant_description'];
//ne radi??
$getGeoCode = Geocode::make()->address($address);
if($getGeoCode){
$latitude = $getGeoCode->latitude();
$longitude = $getGeoCode->longitude();
$restaurant_obj->latitude = $inputs['latitude'];
$restaurant_obj->longitude = $inputs['longitude'];
}
$restaurant_obj->open_monday = $inputs['open_monday'];
$restaurant_obj->open_tuesday = $inputs['open_tuesday'];
$restaurant_obj->open_wednesday = $inputs['open_wednesday'];
$restaurant_obj->open_thursday = $inputs['open_thursday'];
$restaurant_obj->open_friday = $inputs['open_friday'];
$restaurant_obj->open_saturday = $inputs['open_saturday'];
$restaurant_obj->open_sunday = $inputs['open_sunday'];
$restaurant_obj->save();
if(!empty($inputs['id'])){
\Session::flash('flash_message', 'Changes Saved');
return \Redirect::back();
}else{
\Session::flash('flash_message', 'Added');
return \Redirect::back();
}
}
This is model:
class Restaurants extends Model
{
protected $table = 'restaurants';
protected $fillable = ['type', 'restaurant_name','restaurant_slug','restaurant_description','restaurant_address','delivery_charge','restaurant_logo', 'latitude', 'longitude'];
public $timestamps = false;
public function restaurants()
{
return $this->hasMany('App\Restaurants', 'id');
}
public static function getRestaurantsInfo($id)
{
return Restaurants::find($id);
}
public static function getUserRestaurant($id)
{
return Restaurants::where('user_id',$id)->count();
}
public static function getMenuCategories($id)
{
return Categories::where('restaurant_id',$id)->count();
}
public static function getMenuItems($id)
{
return Menu::where('restaurant_id',$id)->count();
}
public static function getOrders($id)
{
return Order::where('restaurant_id',$id)->count();
}
public static function getTotalRestaurants()
{
return Restaurants::count();
}
public function scopeSearchByKeyword($query, $keyword)
{
if ($keyword!='') {
$query->where(function ($query) use ($keyword) {
$query->where("restaurant_address", "LIKE","%$keyword%")
->orWhere("restaurant_name", "LIKE", "%$keyword%");
});
}
return $query;
}
public static function getRestaurantOwnerInfo()
{
$rest=Restaurants::find($id);
return User::find($rest->user_id);
}
}
I try everything that can remember composer dump-autoload, php artisan migrate:rollback, and again make migration etc. I have fields in my db latitude and longitude. Thanks.
It seems you're wanting to do the following by the code you posted:
if($getGeoCode){
$restaurant_obj->latitude = $getGeoCode->latitude();
$restaurant_obj->longitude = $getGeoCode->longitude();
}
$inputs['latitude'] doesnt existe . add latidue into your rule validation to make sur or do dd(Input:all()) to make sure $inputs['latitude'] exist

Strange query generated in Codeigniter

Below is my code where I am calling three methods from three models to retrieve counts as below.
$this->load->model('orders_model');
$order_count = $this->orders_model->count_orders(array("executive_id" => $this->id));
$this->load->model('activities_model');
$activity_count = $this->activities_model->count_activities(array("users_id" => $this->id));
$this->load->model('leads_model');
$leads_count = $this->leads_model->count_leads(array("users_id" => $this->id));
And this is the query I am getting:
SELECT COUNT(*) AS numrows FROM orders, activities, leads WHERE executive_id = '5' AND users_id = '5' AND users_id = '5'
which leads to a database error
Why is this happening?
Orders_model
class Orders_model extends CI_Model {
public function __construct() {
$this->load->database();
}
public function get_orders($order_id = FALSE) {
if ($order_id === FALSE) {
$query = $this->db->get('orders');
return $query->result();
}
$this->db->where('id', $order_id);
$query = $this->db->get('orders');
return $query->result();
}
public function add_order($order_data = FALSE) {
if (!$order_data === FALSE) {
if (is_array($order_data)) {
return $this->db->insert('orders', $order_data);
} else {
return false;
}
} else {
return false;
}
}
public function update_order($order_update_data = FALSE, $order_update_condition = FALSE) {
if (!($order_update_data === FALSE && $order_update_condition === FALSE)) {
if (is_array($order_update_data) && is_array($order_update_condition)) {
return $this->db->update('orders', $order_update_data, $order_update_condition);
} else {
return false;
}
} else {
return false;
}
}
public function get_custom_orders($order_custom_condition = FALSE) {
if (!$order_custom_condition === FALSE) {
if (is_array($order_custom_condition)) {
#echo "Yes a parameter is passed which is also an array";
$this->db->where($order_custom_condition);
$query = $this->db->get('orders');
return $query->result();
}
}
}
public function get_last_ref_id() {
$query = $this->db->query('select sprx_ref_id from orders where id in (select max(id) from orders)');
foreach ($query->result() as $row) {
return $row->sprx_ref_id;
}
}
public function fetch_orders($limit, $start, $order_custom_condition) {
$this->db->limit($limit, $start);
$this->db->order_by("id", "desc");
$this->db->where($order_custom_condition);
$query = $this->db->get();
return $query->result();
}
public function count_orders($order_custom_condition) {
$this->db->where($order_custom_condition);
return $this->db->count_all_results('orders', FALSE);
}
}
Activities_model
class Activities_model extends CI_Model {
public function __construct() {
$this->load->database();
}
public function get_activities($activity_id = FALSE) {
if ($activity_id === FALSE) {
$query = $this->db->get('activities');
return $query->result();
}
$this->db->where('id', $activity_id);
#$this->db->order_by('id','ASC');
$query = $this->db->get('activities');
return $query->result();
}
public function add_activity($activity_data = FALSE) {
if (!$activity_data === FALSE) {
if (is_array($activity_data)) {
return $this->db->insert('activities', $activity_data);
} else {
return false;
}
} else {
return false;
}
}
public function update_activity($activity_update_data = FALSE, $activity_update_condition = FALSE) {
if (!($activity_update_data === FALSE && $activity_update_condition)) {
if (is_array($activity_update_data) && is_array($activity_update_condition)) {
return $this->db->update('activities', $activity_update_data, $activity_update_condition);
} else {
return false;
}
} else {
return false;
}
}
public function get_custom_activities($activity_custom_condition = FALSE) {
if (!$activity_custom_condition === FALSE) {
if (is_array($activity_custom_condition)) {
#echo "Yes a parameter is passed which is also an array";
$this->db->where($activity_custom_condition);
$query = $this->db->get('activities');
return $query->result();
}
}
}
public function fetch_activities($limit, $start, $custom_condition) {
$this->db->limit($limit, $start);
$this->db->order_by("id", "desc");
$this->db->where($custom_condition);
$query = $this->db->get();
return $query->result();
}
public function count_activities($custom_condition) {
$this->db->where($custom_condition);
return $this->db->count_all_results('activities', FALSE);
}
}
Leads_model
class Leads_model extends CI_Model {
public function __construct() {
$this->load->database();
}
public function get_leads($lead_id = FALSE) {
if ($lead_id === FALSE) {
$query = $this->db->get('leads');
return $query->result();
}
$this->db->where('id', $lead_id);
$query = $this->db->get('leads');
return $query->result();
}
public function add_lead($lead_data = FALSE) {
if (!$lead_data === FALSE) {
if (is_array($lead_data)) {
return $this->db->insert('leads', $lead_data);
} else {
return false;
}
} else {
return false;
}
}
public function update_lead($lead_update_data = FALSE, $lead_update_condition = FALSE) {
if (!($lead_update_data === FALSE && $lead_update_condition)) {
if (is_array($lead_update_data) && is_array($lead_update_condition)) {
return $this->db->update('leads', $lead_update_data, $lead_update_condition);
} else {
return false;
}
} else {
return false;
}
}
public function get_custom_leads($lead_custom_condition = FALSE) {
if (!$lead_custom_condition === FALSE) {
if (is_array($lead_custom_condition)) {
#echo "Yes a parameter is passed which is also an array";
$this->db->where($lead_custom_condition);
$query = $this->db->get('leads');
return $query->result();
} else {
return false;
}
} else {
return false;
}
}
public function fetch_leads($limit, $start, $lead_custom_condition) {
$this->db->limit($limit, $start);
$this->db->order_by("id", "desc");
$this->db->where($lead_custom_condition);
$query = $this->db->get();
return $query->result();
}
public function count_leads($lead_custom_condition) {
$this->db->where($lead_custom_condition);
return $this->db->count_all_results('leads', FALSE);
}
}
As far as i understand, you are surprised why the query builder uses additional parameter from the previous query.
You've to reset your Query according to docs
which means all your "count_" functions should be like
public function count_leads($lead_custom_condition) {
$this->db->where($lead_custom_condition);
return $this->db->count_all_results('leads');
}
obviously you did set the false flag on purpose - but i'm not sure why ;)
I believe that the error message is only a symptom, not the actual cause of the issue
. The way I read your code is that the count_*() methods in each of the 3 models should return the count from their respective tables only.
However, the way you wrote your count functions results in the query builder adding the tables and conditions to the overall query, not executing them just on the single tables
$this->db->where($custom_condition); <-- this adds a new where condition using "and" operator
return $this->db->count_all_results('activities', FALSE); <-- just adds another table without resetting the others
I would add a $this->db->reset_query(); line as the 1st line in each of the 3 count_*() methods to force the query builder to start from scratch.
The problem is due to using the second argument to $this->db->count_all_results(). When you set the second argument to FALSE then $this->db will not clear any select statements from its cache. Then each successive call to count_all_results() will include the table from any prior call to the function. The solution is simple - don't use the second parameter.
Change
return $this->db->count_all_results('activities', FALSE);
to
return $this->db->count_all_results('activities');
Not related to your problem but something that will improve your code is changing this
public function get_orders($order_id = FALSE) {
if ($order_id === FALSE) {
$query = $this->db->get('orders');
return $query->result();
}
$this->db->where('id', $order_id);
$query = $this->db->get('orders');
return $query->result();
}
to
public function get_orders($order_id = NULL) {
if (!empty($order_id))
{
$this->db->where('id', $order_id);
}
$query = $this->db->get('orders');
return $query->result();
}
Changing the argument default to NULL and using !empty($order_id) helps because it protects against and empty string or empty array being given as the argument. (Ready about empty() here.)
This new logic also keeps the code DRY - your not repeating the two line of code to get and return results.
Many of your other model functions could be cleaner too. For instance
public function add_order($order_data = FALSE) {
if (!$order_data === FALSE) {
if (is_array($order_data)) {
return $this->db->insert('orders', $order_data);
} else {
return false;
}
} else {
return false;
}
}
would be cleaner written like this
public function add_order($order_data = NULL) {
if (!empty($order_data) && is_array($order_data))
{
return $this->db->insert('orders', $order_data);
}
return false;
}
Sorry for nitpicking your code - I couldn't help myself.

run multiple select quires in one page using codeigniter

Hello any one can tell that how to load two function from model class in controller one method. I want to run multiple select quires in one page using codeigniter:
Controller
public function property_detail( $id )
{
$this->load->model('insertmodel');
$select1 = $this->insertmodel->find($id);
$select2 = $this->insertmodel->detail_list();
$data = array();
$this->load->view('home/property_detail', ['select1'=>$select1], ['select2'=>$select2]);
//$this->load->view('home/property_detail', ['select2'=>$select2]);
}
Model
public function find( $id )
{
$query = $this->db->from('article')->where(['id'=> $id])->get();
if( $query->num_rows() )
return $query->row();
return false;
}
public function detail_list(){
$query1 = $this->db->query("select * from article");
return $query1->result();
}
In Controller
public function property_detail( $id )
{
$this->load->model('insertmodel');
$data['select1'] = $this->insertmodel->find($id);
$data['select2'] = $this->insertmodel->detail_list();
$this->load->view('home/property_detail', $data);
}
In Model
public function find($id)
{
$query = $this->db->get_where('article', array('id' => $id), 0, 0)->get();
if( $query->num_rows() > 0 )
{
$result = $query->result_array();
return $result;
}
else
{
return false;
}
}
public function detail_list()
{
$query1 = $this->db->query("select * from article");
$result = $query1->result_array();
return $result;
}
In View
foreach ($select2 as $item) {
# your foreach lop goes here
}
As well check empty() before passing it to the foreach loop
As an alternative to #Rijin's useful answer newMethod() can make calls to the existing model methods. This might be useful if you don't want to break the interface already created for the model because you are using find($id) and detail_list() in other code.
Model:
public function find($id)
{
$query = $this->db->from('article')->where(['id' => $id])->get();
if($query->num_rows())
return $query->row();
return false;
}
public function detail_list()
{
$query1 = $this->db->query("select * from article");
return $query1->result();
}
public function newMethod($id)
{
$result['select1'] = $this->find($id);
if($result['select1'] !== FALSE)
{
$result['select2'] = $this->detail_list();
return $result;
}
return FALSE;
}
Controller:
public function property_detail($id)
{
$this->load->model('insertmodel');
$data = $this->insertmodel->newMethod($id);
$this->load->view('home/property_detail', $data);
}
Model :
public function find( $id )
{
$query = $this->db->from('article')->where(['id'=> $id])->get();
if( $query->num_rows() )
return $query->row();
return false;
}
public function detail_list()
{
$query1 = $this->db->query("select * from article");
return $query1->result();
}
Controller :
public function property_detail( $id )
{
$this->load->model('insertmodel');
$data['select1'] = $this->insertmodel->newMethod($id);
$data['select2'] = $this->insertmodel->detail_list();
$this->load->view('home/property_detail', $data);
}

Undefined Offset: 0 - Codeigniter

When I send a Request to this Page including POST-DATA ({"bot_hw_id":"2147483647"}), i get the following error:
<p>Severity: Notice</p>
<p>Message: Undefined offset: 0</p>
<p>Filename: models/prometheus_model.php</p>
<p>Line Number: 26</p>
My Code:
Controller(update_bot function):
[code]public function update_bot()
{
$bot_data = json_decode($this->input->post('bot_data'));
$to_update = array(
'bot_last_update' => time(),
'bot_ip' => $_SERVER['REMOTE_ADDR'],
'bot_port' => $_SERVER['REMOTE_PORT']
);
$bot_data = $this->prometheus_model->get_bot_data_by_hw_id(/*$bot_data->{'bot_hw_id'}*/$bot_data->{'bot_hw_id'});
//echo $bot_data['bot_id'];
print_r($bot_data);
$this->prometheus_model->update('bots', array('bot_id' => $bot_data['bot_id']), $to_update);
//var_dump($bot_data);
}
Model(prometheus_model):
<?php
class Prometheus_model extends CI_Model {
var $tables = array(
'bots' => 'bots'
);
function __construct() {
parent::__construct();
}
public function tablename($table = NULL) {
if(! isset($table)) return FALSE;
return $this->tables[$table];
}
public function get($table, $where = array(), $single = FALSE, $order = NULL) {
$this->db->where($where);
if(isset($order)) {
$this->db->order_by($order);
}
$q = $this->db->get_where($this->tablename($table),$where);
$result = $q->result_array();
if($single) {
return $result[0];
}
return $result;
}
public function update($table, $where = array(), $data) {
$this->db->update($this->tablename($table),$data,$where);
return $this->db->affected_rows();
}
public function insert($table, $data) {
$this->db->insert($this->tablename($table),$data);
return $this->db->insert_id();
}
public function delete($table, $where = array()) {
$this->db->delete($this->tablename($table),$where);
return $this->db->affected_rows();
}
public function explicit($query) {
$q = $this->db->query($query);
if(is_object($q)) {
return $q->result_array();
} else {
return $q;
}
}
public function num_rows($table, $where = NULL) {
if(isset($where)){
$this->db->where($where);
}
$q = $this->db->get($table);
return $q->num_rows();
}
public function get_bot_data_by_hw_id($bot_hw_id) {
$q = $this->get('bots', array('bot_hw_id' => $bot_hw_id), TRUE);
return $q;
}
}
?>;
How can i fix this error?
First, I should mention that it's not absolutely a good and safe idea to query user input exactly without any process (as we see in your code). It's better to have different models at least for each table.
Anyway...
This way your function will be corrected:
public function get($table, $where = array(), $single = FALSE, $order = NULL) {
$this->db->where($where);
if(isset($order)) {
$this->db->order_by($order);
}
$q = $this->db->get_where($this->tablename($table),$where);
$result = $q->result_array();
// You should use $q->num_rows() to detect the number of returned rows
if($q->num_rows() == 1) {
// Return the first row:
return $result[0];
}
return $result;
}
It returns the first row when there is only one, and brings an array when $q->num_rows() is not equal to 1.
Hope it helps

Multiple Tables in Zend based on the Quick Start Guide Example

I am new to Zend and have been attempting to follow the Zend Quick Start Guide's example of using Data Mappers and extending Zend_Db_Table_Abstract. I think I've grasped the general concepts, but I am now wondering, how I would go about modifying the guide's example code to allow for multiple tables.
Here is the part of the code I am currently interested in modifying:
protected $_dbTable;
public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Application_Model_DbTable_Guestbook');
}
return $this->_dbTable;
}
I have changed it to this:
protected $_dbTables;
public function setDbTable($dbTable, $tableName)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table data gateway provided');
}
$this->_dbTables[$tableName] = $dbTable;
return $this;
}
public function getDbTables()
{
if (null === $this->_dbTables) {
$this->setDbTable('Application_Model_DbTable_Courses', 'courses');
$this->setDbTable('Application_Model_DbTable_CourseTimes', 'course_times');
}
return $this->_dbTables;
}
Is this a correct way to go about implementing multiple tables within the Data Mapper pattern or would you do it differently? Thanks for your help in advance!
Assuming that you want to return data from related tables, you should either add queries with joins to one Zend_Db_Table or use Zend_Db_Table_Relationships to fetch associated data. The benefit of using Joins is that you will only do one query over many when using Relationships. The drawback is that joined tables wont return Zend_Db_Table_Row objects (iirc), but since you are going to map them onto your Domain objects anyway, it's not that much of an issue.
Structurally, you can do like I suggested in How to change Zend_Db_Table name within a Model to insert in multiple tables. Whether you create a Gateway of Gateways or simply aggregate the Table Gateways in the DataMapper directly is really up to you. Just compose them as you see fit.
I'm not sure if it's the best practice, but, this is my abstract mapper:
<?php
abstract class Zf_Model_DbTable_Mapper
{
protected $_db;
protected $_dbTable = null;
protected $_systemLogger = null;
protected $_userLogger = null;
public function __construct()
{
$this->_systemLogger = Zend_Registry::get('systemLogger');
$this->_userLogger = Zend_Registry::get('userLogger');
// Set the adapter
if(null !== $this->_dbTable)
{
$tableName = $this->_dbTable;
$this->_db = $this->$tableName->getAdapter();
}
}
public function __get($value)
{
if(isset($this->$value))
{
return $this->$value;
}
$dbTable = 'Model_DbTable_' . $value;
$mapper = 'Model_' . $value;
if(class_exists($dbTable))
{
return new $dbTable;
}
elseif(class_exists($mapper))
{
return new $mapper;
}
else
{
throw new Exception("The property, DbTable or Mapper \"$value\" doesn't exists");
}
}
public function __set($key,$value)
{
$this->$key = $value;
}
public function getById($id)
{
$resource = $this->getDefaultResource();
$id = (int)$id;
$row = $resource->fetchRow('id =' . $id);
if (!$row) {
throw new Exception("Count not find row $id");
}
return $row;
}
public function getAll()
{
$resource = $this->getDefaultResource();
return $resource->fetchAll()->toArray();
}
public function save(Zf_Model $Model)
{
$dbTable = $this->getDefaultResource();
$data = $Model->toArray();
if(false === $data) return false;
if(false === $Model->isNew())
{
if(1 == $dbTable->update($data, 'id =' . (int)$Model->getId()))
{
return $Model;
}
}
else
{
$id = $dbTable->insert($data);
if($id)
{
$Model->setId($id);
return $Model;
}
}
return false;
}
public function remove($id)
{
return $this->getDefaultResource()->delete('id =' . (int) $id);
}
protected function getDefaultResource()
{
if(empty($this->_dbTable))
{
throw new Exception('The $_dbTable property was not set.');
}
$classname = 'Model_DbTable_' . $this->_dbTable;
if(!class_exists($classname))
{
throw new Exception("The Model_DbTable_\"$classname\" class was not found.");
}
return new $classname;
}
protected function getDefaultModel()
{
return current($this->_models);
}
protected function getResources()
{
return $this->_resources;
}
}
And this is one for my implemented mappers:
<?php
class Model_TwitterPostsMapper extends Zf_Model_DbTable_Mapper
{
/*
* Data Source
* #var string Zend_Db_Table name
*/
protected $_dbTable = 'TwitterPosts';
public function recordExists($Item)
{
$row = $this->TwitterPosts->fetchRow($this->TwitterPosts->select()->where('status_id =?', $Item->getSource()->getStatusId()));
if($row)
{
return $row->id;
}
return false;
}
public function getLastUpdate($options)
{
$select = $this->TwitterPosts->select()
->setIntegrityCheck(false)
->from(array('t' => 'twt_tweets'), 't.created_at')
->join(array('u' => 'twt_users'), 't.user_id = u.id', '')
->order('t.created_at DESC');
if($options['user_id'])
{
$select->where("t.user_id = ?", $options['user_id']);
}
if($options['terms'])
{
if(is_array($options['terms']))
{
$condition = '';
foreach($options['terms'] as $i => $term)
{
$condition .= ($i > 0) ? ' OR ' : '';
$condition .= $this->getAdapter()->quoteInto('content LIKE ?',"%$term%");
}
if($condition)
{
$select->where($condition);
}
}
}
return $this->TwitterPosts->fetchRow($select)->created_at;
}
public function getSinceId($term = null)
{
$select = $this->TwitterPosts->select()->setIntegrityCheck(false)
->from('twt_tweets_content', 'status_id')
->where('MATCH(content) AGAINST(? IN BOOLEAN MODE)', "$term")
->order('status_id ASC')
->limit(1);
//echo $select; exit;
$tweet = $this->TwitterPosts->fetchRow($select);
if(null !== $tweet) return $tweet->status_id;
return 0;
}
public function getAllByStatusId($statuses_id)
{
$select = $this->TwitterPosts->select()
->setIntegrityCheck(false)
->from(array('t' => 'twt_tweets'), array('t.id', 't.user_id', 't.status_id','t.user_id'))
->join(array('u' => 'twt_users'), 't.user_id = u.id', array('u.screen_name', 'u.profile_image'))
->where('status_id IN(?)', $statuses_id);
$rows = $this->TwitterPosts->fetchAll($select);
$Posts = array();
foreach($rows as $row)
{
// Here we populate the models only with the specific method return data
$data = $row->toArray();
$Post = new Model_TwitterPost($data['id']);
$Post->populate($data);
$User = new Model_TwitterUser($data['user_id']);
$User->populate($data);
$Post->setUser($User);
$Posts[] = $Post;
}
return $Posts;
}
public function getAllSince($since_id)
{
$select = $this->TwitterPosts->select()
->setIntegrityCheck(false)
->from(array('t' => 'twt_tweets'), array('t.status_id','t.user_id'))
->join(array('u' => 'twt_users'), 't.user_id = u.id', array('u.screen_name', 'u.profile_image'))
->where('status_id > ?', $since_id)
->order('t.datetime DESC');
$rows = $this->TwitterPosts->fetchAll($select);
$Posts = array();
foreach($rows as $row)
{
// Here we populate the models only with the specific method return data
// TODO: This is not a truly lazy instatiation, since there's no way to get the not setted properties
$data = $row->toArray();
$Post = new Model_TwitterPost($data);
$User = new Model_TwitterUser($data);
$Post->setUser($User);
$Posts[] = $Post;
}
return $Posts;
}
public function getTotalRatedItems($options)
{
$options = $this->prepareOptions($options);
$select = $this->TwitterPosts->select()
->setIntegrityCheck(false)
->from(array('t' => 'twt_tweets'), array('COUNT(DISTINCT t.id) AS total','r.rate'))
->join(array('u' => 'twt_users'), 't.user_id = u.id', '')
->join(array('r' => 'twt_tweets_rate'), 't.id = r.tweet_id', array('r.rate'))
->group('r.rate')
->order('t.datetime DESC');
$select = $this->prepareSelect($select, $options);
$rates = $this->TwitterPosts->fetchAll($select)->toArray();
$itemsRated = array('Green' => 0, 'Yellow' => 0, 'Orange' => 0, 'Red' => 0, 'Gray' => 0);
foreach ($rates as $rate)
{
$itemsRated[$rate['rate']] = $rate['total'];
}
return $itemsRated;
}
public function getUsersActivity($options)
{
$options = $this->prepareOptions($options);
$select = $this->TwitterPosts->select()
->setIntegrityCheck(false)
->from(array('t' => 'twt_tweets'), array('COUNT(DISTINCT t.id) AS total','DATE(t.datetime) AS datetime'))
->join(array('u' => 'twt_users'), 't.user_id = u.id', '')
->joinLeft(array('r' => 'twt_tweets_rate'), 't.id = r.tweet_id', '')
->group('t.user_id')
->order('t.datetime DESC');
$select = $this->prepareSelect($select, $options);
$activity = $this->TwitterPosts->fetchAll($select)->toArray();
return $activity;
}
public static function prepareOptions($options)
{
if(!is_array($options))
{
$options = array();
}
date_default_timezone_set('America/Sao_Paulo');
if(Zend_Date::isDate($options['start_date']))
{
$date = new Zend_Date($options['start_date']);
$date->setTime('00:00:00');
$date->setTimezone('UTC');
$options['start_date'] = $date->toString('yyyy-MM-dd HH:mm:ss');
}
if(Zend_Date::isDate($options['end_date']))
{
$date = new Zend_Date($options['end_date']);
$date->setTime('23:59:59');
$date->setTimezone('UTC');
$options['end_date'] = $date->toString('yyyy-MM-dd HH:mm:ss');
}
date_default_timezone_set('UTC');
$options['mainTerms'] = array();
if(!empty($options['terms']) && !is_array($options['terms']))
{
$options['mainTerms'] = explode(' ', $options['terms']);
}
if(!is_array($options['terms']))
{
$options['terms'] = array();
}
if($options['group_id'] || $options['client_id'])
{
$TwitterSearches = new Model_DbTable_TwitterSearches();
$options['terms'] = array_merge($TwitterSearches->getList($options),$options['terms']);
if(empty($options['terms']))
{
$options['terms'] = array();
}
}
return $options;
}
public static function prepareSelect($select, $options)
{
if($options['start_date'])
{
$select->where('t.datetime >= ?', $options['start_date']);
}
if($options['end_date'])
{
$select->where('t.datetime <= ?', $options['end_date']);
}
foreach($options['mainTerms'] as $mainTerm)
{
$select->where('t.content LIKE ?', "%$mainTerm%");
}
if($options['user_id'])
{
$select->where("t.user_id = ?", $options['user_id']);
}
if($options['terms'])
{
$select->where('MATCH (t.content) AGASINT(?)', $options['terms']);
}
if($options['rate'])
{
if($options['rate'] == 'NotRated')
{
$select->where('r.rate IS NULL');
}
else
{
$select->where('r.rate = ?', $options['rate']);
}
}
if($options['last_update'])
{
$select->where('t.created_at > ?', $options['last_update']);
}
if($options['max_datetime'])
{
$select->where('t.created_at < ?', $options['max_datetime']);
}
return $select;
}
}
The Model:
<?php
class Model_TwitterPost extends Zf_Model
{
private $_name = 'twitter';
protected $_properties = array(
'id',
'status_id',
'user_id',
'content'
);
protected $_User = null;
public function setUser(Zf_Model $User)
{
$this->_User = $User;
}
public function getUser()
{
return $this->_User;
}
public function getPermalink()
{
return 'http://twitter.com/' . $this->screen_name . '/' . $this->status_id;
}
public function hasTerm($term)
{
if(preg_match("/\b$term\b/i", $this->getContent()))
{
return true;
}
return false;
}
public function getEntityName()
{
return $this->_name;
}
public function getUserProfileLink()
{
return $this->getUser()->getProfileLink() . '/status/' . $this->getStatusId();
}
}
Abstract model (Generic Object):
<?php
abstract class Zf_Model
{
protected $_properties = array();
protected $_modified = array();
protected $_data = array();
protected $_new = true;
protected $_loaded = false;
public function __construct($id=false)
{
$id = (int)$id;
if(!empty($id))
{
$this->_data['id'] = (int)$id;
$this->setNew(false);
}
}
public function populate($data)
{
if(is_array($data) && count($data))
{
foreach($data as $k => $v)
{
if(in_array($k,$this->_properties))
{
$this->_data[$k] = $v;
}
}
}
$this->setLoaded(true);
}
public function setNew($new=true)
{
$this->_new = (bool)$new;
}
public function isNew()
{
return $this->_new;
}
public function setLoaded($loaded = true)
{
$this->_loaded = (bool)$loaded;
}
public function isLoaded()
{
return $this->_loaded;
}
public function __call($methodName, $args) {
if(method_exists($this, $methodName))
{
return $this->$methodName($args);
}
$property = $methodName;
if (preg_match('~^(set|get)(.*)$~', $methodName, $matches))
{
$filter = new Zend_Filter_Word_CamelCaseToUnderscore();
$property = strtolower($filter->filter($matches[2]));
if(in_array($property, $this->_properties))
{
if('set' == $matches[1])
{
$this->_data[$property] = $args[0];
if(true === $this->isLoaded())
{
$this->_modified[$property] = true;
}
return $this;
}
elseif('get' == $matches[1])
{
if(array_key_exists($property, $this->_data))
{
return $this->_data[$property];
}
throw new Exception("The property $property or $methodName() method was not setted for " . get_class($this));
}
}
}
throw new Exception("The property '$property' doesn't exists.");
}
public function __get($key)
{
if(isset($this->_data[$key]))
{
return $this->_data[$key];
}
return $this->$key;
}
public function __set($key,$value)
{
if(array_key_exists($key,$this->_properties))
{
$this->_data[$key] = $value;
return;
}
$this->$key = $value;
}
public function getId()
{
return (!$this->_data['id']) ? null : $this->_data['id'];
}
public function toArray()
{
// If it's a new object
if(true === $this->isNew())
{
return $this->_data;
}
// Else, if it's existing object
$data = array();
foreach($this->_modified as $k=>$v)
{
if($v)
{
$data[$k] = $this->_data[$k];
}
}
if(count($data))
{
return $data;
}
return false;
}
public function reload()
{
$this->_modified = array();
}
}

Categories