Foreach in CodeIgniter - php

I want to select some news excluded the first 4 and I got a error
Invalid argument supplied for foreach:
Model:
public function get_all_news_home()
{
$exclude = array();
$this->load->database();
$last_news_query = $this->db->query("SELECT * FROM News WHERE Type = 1 AND Ready='Y' ORDER BY Date DESC LIMIT 4");
$last_news = $this->db->query($last_news_query);
$last_news = ($last_news->num_rows()) ? $last_news->result_array() : NULL;
foreach ($last_news as $ln)
{
array_push($exclude,array('id' => $ln['ID']));
}
$newsIds = implode(',', array_values($exclude));
$all_news = $this->db->query("SELECT * FROM News WHERE News.Ready = 'Y' AND News.ID NOT IN ('$newsIds') ORDER BY Date DESC LIMIT 12");
if($all_news->num_rows())
{
$all_news = $all_news->result_array();
}
else
{
$all_news = NULL;
}
return $all_news;
}
Controller:$this->data["all_news"] = &$this->site_news->get_all_news_home();

change this. you should check for null condition before passing it to foreach.
public function get_all_news_home()
{
$exclude = array();
$this->load->database();
$last_news_query = $this->db->query("SELECT * FROM News WHERE Type = 1 AND Ready='Y' ORDER BY Date DESC LIMIT 4");
$last_news = $this->db->query($last_news_query);
$last_news = ($last_news->num_rows()) ? $last_news->result_array() : NULL;
$all_news = NULL;
if($last_news!=NULL){
foreach ($last_news as $ln)
{
array_push($exclude,array('id' => $ln['ID']));
}
$newsIds = implode(',', array_values($exclude));
$all_news = $this->db->query("SELECT * FROM News WHERE News.Ready = 'Y' AND News.ID NOT IN ('$newsIds') ORDER BY Date DESC LIMIT 12");
if($all_news->num_rows())
{
$all_news = $all_news->result_array();
}
}
return $all_news;
}

I think this simple function should work nicely for you. Please use this simple function and let us know what happened.
public function get_all_news_home()
{
$this->load->database();
$all_news = $this->db->query("SELECT * FROM News WHERE Type = 1 AND Ready = 'Y' ORDER BY Date DESC LIMIT 4, 12");
if($all_news->num_rows())
{
$all_news = $all_news->result_array();
}
else
{
$all_news = NULL;
}
return $all_news;
}

$exclude = array();
$this->load->database();
$last_news = $this->db->query("SELECT * FROM News WHERE Type = 1 AND Ready='Y' ORDER BY Date DESC LIMIT 4");
//$last_news = $this->db->query($last_news_query);
//remove this line you are re-executing the query.
$last_news = ($last_news->num_rows()) ? $last_news->result_array() : NULL;
//before foreach add if condition
if (!is_null($last_news)) {
//add your code
}
Adding if condition before foreach is always a good practice. I hope this would help you.

Related

How can i order two tables?

I have two tables : users ('ID' 'username' '...') and connectivities('ID' 'following_ID' '...')
Each time one user follows another, an entry is created in connectivities. The followers are sorted in descending order after a query by user ID. Now I do not want to sort the followers by ID but by the entries in connectivities. So that always the last new follower is displayed first.
public function getFollowers($offset = false,$limit = null){
if (empty($this->user_id) || !is_numeric($this->user_id)) {
return false;
}
else if (!empty($limit) && !is_numeric($limit)) {
return false;
}
$user_id = $this->user_id;
$t_users = T_USERS;
$t_conn = T_CONNECTIV;
self::$db->join("{$t_conn} c","c.follower_id = u.user_id AND c.type = 1","INNER");
self::$db->where("c.following_id",$user_id);
self::$db->orderBy("u.user_id","DESC");
if (!empty($offset) && is_numeric($offset)) {
self::$db->where("u.user_id",$offset,'<');
}
$users = self::$db->get("{$t_users} u",$limit);
$data = array();
foreach ($users as $key => $user_data) {
$user_data = $this->userData($user_data);
$user_data->is_following = false;
if (IS_LOGGED) {
$this->user_id = self::$me->user_id;
$user_data->is_following = $this->isFollowing($user_data->user_id);
}
$data[] = $user_data;
}
return $data;
}
If I have changed self :: $ db-> orderBy ("u.user_id", "DESC"); to self :: $ db-> orderBy ("c.id", "DESC"); that works as well but always the same ex 20 entries are displayed.
These are then always repeated. I think the problem is the offset.
Does somebody has any idea?
invoke $db->orderBy twice, to sort rows by u.userid desc, c.id desc
self::$db->join("{$t_conn} c","c.follower_id = u.user_id AND c.type = 1","INNER");
self::$db->where("c.following_id",$user_id);
self::$db->orderBy("u.user_id desc","c.id desc");

Refactor if statements in PHP or another solution for if statements (not switch case)

I have some if statements in my code.
e.g:
if($option[0]->posts == 1 && $option[0]->pages == 1){
$results = $wpdb->get_results( 'SELECT * FROM '.$wpdb->prefix.'posts WHERE post_status="publish" AND (post_type="page" OR post_type="post") ORDER BY post_title ASC', OBJECT );
}
if($option[0]->pages == 1 && $option[0]->posts == 0){
$results = $wpdb->get_results( 'SELECT * FROM '.$wpdb->prefix.'posts WHERE post_status="publish" AND post_type="page" ORDER BY post_title ASC', OBJECT );
}
if($option[0]->pages == 0 && $option[0]->posts == 1){
$results = $wpdb->get_results( 'SELECT * FROM '.$wpdb->prefix.'posts WHERE post_status="publish" AND post_type="post" ORDER BY post_title ASC', OBJECT );
}
a bit pseudo code of the code above:
if foo = 1 and bar = 1 -> return foo and bar
if foo = 0 and bar = 1 -> return only bar
if foo = 1 and bar = 0 -> return only foo
if foo = 0 and bar = 0 -> return false
You see:
00
10
01
11
00
If I insert another variable I'll get a lot of more opportunities and that is realy bad. Because I'll get realy big if statements.
Can somebody tells me another opportunitie to achive the same result?
Thank you.
I'd do it like this:
$sql_condition = '( 1=2 '; // one fake-condition, just to make it possible to start with 'OR' later
foreach($option[0] as $key => $value) { // iterate through all possible conditions
if($value===1) { // maybe exclude $keys that should not be used here
$sql_condition.=' OR post_type="'.$key.'"';
}
}
$sql_condition.=')';
$results = $wpdb->get_results( 'SELECT * FROM '.$wpdb->prefix.'posts WHERE post_status="publish" AND '.$sql_condition.' ORDER BY post_title ASC', OBJECT );
Please try this code :
$sub_query = $operator = '';
if($option[0]->posts == 1)
{
$sub_query = 'post_type="page"';
$operator = ' OR';
}
if($option[0]->pages == 1)
{
$sub_query .= $operator.' post_type="post"';
}
if(empty($sub_query))
{
return false;
}
else
{
$results = $wpdb->get_results( 'SELECT * FROM '.$wpdb->prefix.'posts WHERE post_status="publish" AND ('.$sub_query.') ORDER BY post_title ASC', OBJECT );
}
Create an array($arr) and set the key like "0,0" and value like "$sql";
and your code will be like this:
$tempKey = $option[0]->pages . "," . $option[0]->posts;
if(isset($arr[$tempKey]) {
$results = $wpdb->get_results($arr[$tempKey]);
}
So when you want to add more pages and posts all you will do is to change the arr.
$types = [];
if ($option[0]->posts)
$types[] = '"post"';
if ($option[0]->pages)
$types[] = '"page"';
if (!$types)
return null;
$results = $wpdb->get_results( 'SELECT * FROM '.$wpdb->prefix.'posts WHERE post_status="publish" AND (post_type IN ('. implode(',', $types) .')) ORDER BY post_title ASC', OBJECT );

Return values for appropriate arguments

Is here any possible to write single return for both $strValues and $strThumbImages i need to return $strValues for every time but returning $strThumbImages is just when it is available..
function doSelectBranchRecords($objArray,$ImageId = NULL)
{
global $global_config;
$strWhereClause = '';
if ($objArray['frmNameSearch']) {
$strWhereClause.= " AND A.branch_ident = '".$objArray['frmNameSearch']."' ";
}
if ($objArray['frmLoanSearch']) {
$strWhereClause.= " AND A.loan_ident = '".$objArray['frmLoanSearch']."' ";
}
if ($objArray['frmBeneficiarySearch']) {
$strWhereClause.= " AND A.beneficiary_idents = '".$objArray['frmBeneficiarySearch']."' ";
}
if ($objArray['frmDateSearch']) {
$strDate = explode("-", $objArray['frmDateSearch']);
$strAccountstarted = $strDate[2].'-'.$strDate[1].'-'.$strDate[0];
$strWhereClause.= " AND A.account_started = '".$strAccountstarted."' ";
/*printArray($strWhereClause); exit;*/
}
if ($ImageId) {
$strThumbImages = $global_config["SiteGlobalUploadPath"].$ImageId;
return $strThumbImages;
}
$strSqlSelect = "SELECT A.*,B.branch_name FROM tbl_companydetails as A,tbl_branchdetails as B where A.branch_ident=B.branch_id $strWhereClause order by company_id DESC";
$strValues = SelectQry($strSqlSelect);
return $strValues;
}
A php function can't return more than one variable. You could get both results from the function by returning an array with either one or two keys in it, then do a check in your calling code to see what has been set. So the end of your function becomes:
...
}
$output = array();
if ($ImageId) {
$strThumbImages = $global_config["SiteGlobalUploadPath"].$ImageId;
$output['thumbImages'] = $strThumbImages;
}
$strSqlSelect = "SELECT A.*,B.branch_name FROM tbl_companydetails as A,tbl_branchdetails as B where A.branch_ident=B.branch_id $strWhereClause order by company_id DESC";
$strValues = SelectQry($strSqlSelect);
$output['strValues'] = $strValues;
return $output;
}
#Simon and #Suchit are right in that you cannot return more than one variable. But in php it is very straightforwarded to return a list with multiple items like so:
function getXYZ(){
return array(4,5,6);
}
list($x,$y,$z) = getXYZ();
So in your case this could look like so:
$strThumbImages = null;
if ($ImageId) {
$strThumbImages = $global_config["SiteGlobalUploadPath"].$ImageId;
}
$strSqlSelect = "SELECT A.*,B.branch_name FROM tbl_companydetails as A,tbl_branchdetails as B where A.branch_ident=B.branch_id $strWhereClause order by company_id DESC";
$strValues = SelectQry($strSqlSelect);
return array($strValues, $strThumbImages);
As above #Simon Brahan said you can not return more than one variable.
so you can use array with different keys.but you should also check if $ImageId is set and not null.
if (isset($ImageId) && !is_null($ImageId)) {
$strThumbImages = $global_config["SiteGlobalUploadPath"].$ImageId;
$output['thumbImages'] = $strThumbImages;
}
$strSqlSelect = "SELECT A.*,B.branch_name FROM tbl_companydetails as A,tbl_branchdetails as B where A.branch_ident=B.branch_id $strWhereClause order by company_id DESC";
$strValues = SelectQry($strSqlSelect);
$output['strValues'] = $strValues;
return $output;

How do I combine two statement will be one query?

Here an example queries to get two type of icons..
$fetchIcon = array();
$queryIcon = $db->query("SELECT * FROM icon_code WHERE icon_type = 'icon'");
while ($fIcon = $db->fetch_assoc($queryIcon)) {
$fetchIcon[] = $fIcon;
}
$fetchOther = array();
$queryOther = $db->query("SELECT * FROM icon_code WHERE icon_type = 'other'");
while ($fOther = $db->fetch_assoc($queryOther)) {
$fetchOther[] = $fOther;
}
Then I use foreach to show an ouput on the same page.
foreach ($fetchIcon as $Icon) {
echo $Icon['IconName']; // select option for Icon
}
foreach ($fetchOther as $Other) {
echo $Other['IconName']; // select option for other icon
}
Question :
How do I combine the two statement will be one query?
SELECT * FROM icon_code
WHERE icon_type = 'icon'
or icon_type = 'other'
ORDER BY icon_type
or
SELECT * FROM icon_code
WHERE icon_type in ('icon', 'other')
ORDER BY icon_type
The order byis optional to get the order by type.
SELECT *
FROM icon_code
WHERE icon_type IN ('icon', 'other')
and then
$fetchIcon = array();
$fetchOther = array();
while($row = mysql_fetch_assoc($result)) {
switch($row['icon_type']) {
case 'icon':
$fetchIcon[] = $row;
break;
case 'other':
default:
$fetchOther[] = $row;
}
}
I would suggest using the IN function:
$queryOther = $db->query("SELECT * FROM icon_code WHERE icon_type IN ('other', 'icon'");

MySQL two selects but totally different

ok I have to tables they are along the same lines, but one that lists all stores that sell goods and one that is products that we sell.
Think of it like Fruit and Veg totally different.
What I need to work out is if there is 7 fruit and we need 8 listings then go and get a random veg and show it in the same results.
Here is what our query currently looks like. you will notice we can send a $count which we send as 8 but we may want to increase to 10 or even make it 4.
public function realcashoffers($state,$count)
{
$this->state = $state;
$this->number = $count;
//print count($this->JSONselect("business_stores","*",NULL,NULL),1);
print $this->JSONselect("approved_business, business_stores, Real_Cash_Offers"," *, group_concat(offer ORDER BY offer ASC SEPARATOR ',') as offers"," approved_business.id = business_stores.business_id AND Real_Cash_Offers.business_id = approved_business.id AND Real_Cash_Offers.storeid = business_stores.storeid AND business_stores.state = '{$this->state}'","GROUP BY id ORDER BY RAND(), approved_business.id DESC LIMIT {$this->number} ");
}
this->JSONselect goes to
//JSON select
public function JSONselect($table,$options,$where,$orderby)
{
$options = empty($options) ? "*" : $options;
$where = empty($where) ? "1=1" : $where;
$orderby = empty($orderby) ? "" : $orderby;
$qry = "SELECT $options FROM $table WHERE $where $orderby ";
//print $qry;
$result = mysql_query($qry) or die(json_encode(array("error",mysql_error())));
while(($row = mysql_fetch_assoc($result))){ $resultArray[] = $row; }
//print json_encode($resultArray);
return count($resultArray) < 1 ? print "[".json_encode(array("error"=>"sorry"))."]" : json_encode($resultArray);
}
If I understand correctly I think what your looking for is something along the lines of this;
Update the main function to determine if there were enough results and call the secondary query if not
public function realcashoffers($state,$count)
{
$this->state = $state;
$this->number = $count;
$result = $this->JSONselect("approved_business, business_stores, Real_Cash_Offers"," *, group_concat(offer ORDER BY offer ASC SEPARATOR ',') as offers"," approved_business.id = business_stores.business_id AND Real_Cash_Offers.business_id = approved_business.id AND Real_Cash_Offers.storeid = business_stores.storeid AND business_stores.state = '{$this->state}'","GROUP BY id ORDER BY RAND(), approved_business.id DESC LIMIT {$this->number} ");
$remaining = count($result) - $count;
if ($remaining) {
$result = array_merge($result, $this->JSONselect(.. enter secondary call here using $remaining as the limit..);
}
$this->JSONprint($result);
}
Update JSONselect to return the results instead of being responsible for printing them as well
public function JSONselect($table,$options,$where,$orderby)
{
$resultArray = array();
$options = empty($options) ? "*" : $options;
$where = empty($where) ? "1=1" : $where;
$orderby = empty($orderby) ? "" : $orderby;
$qry = "SELECT $options FROM $table WHERE $where $orderby ";
//print $qry;
$result = mysql_query($qry) or die(json_encode(array("error",mysql_error())));
while(($row = mysql_fetch_assoc($result))){ $resultArray[] = $row; }
//print json_encode($resultArray);
return $resultArray;
}
create JSONprint that will print the results returned
protected function JSONprint($resultArray) {
return count($resultArray) < 1 ? print "[".json_encode(array("error"=>"sorry"))."]" : json_encode($resultArray);
}

Categories