CodeIgniter MySQL query where not working after a label - php

i am trying to get result from database conditionally.
like where a = 1 and b != 2 and so much conditions...
here is my code sample
$u = $this->ion_auth->user()->row()->id;
$hide=$this->find_hide_post();
$friend=$this->get_all_contacts();
after this i start my main query
$this->db->where('user_id',$u);
foreach($friend as $fr)
{
foreach($fr as $f)
{
if($f->sub_id !=$u)
{
$this->db->or_where('user_id', $f->sub_id);
}
elseif($f->obj_id !=$u)
{
$this->db->or_where('user_id', $f->obj_id);
}
$this->db->where('time >', $f->time);
}
}
i get good correct result, but whenever i add these lines i didnt get correct result. but i need to remove those posts from result.
foreach($hide as $h)
{
$this->db->where('id !=', $h->post_id);
}
lastly i get through this way
$result=$this->db->get('my_wall');
$row=$result->result();
print_r($row);
the result is:
Array
(
[0] => stdClass Object
(
[id] => 18
[user_id] => 19
[post] =>
[img] => public/users/wall/pic/Messenger14.png
[doc] =>
[video] =>
[link] =>
[link_name] =>
[access_id] =>
[like] => 0
[time] => 1340792296
)
[1] => stdClass Object
(
[id] => 19
[user_id] => 19
[post] => This is my test Documents
[img] =>
[doc] => public/users/wall/doc/19/20745322_temp.pdf
[video] =>
[link] =>
[link_name] =>
[access_id] =>
[like] => 0
[time] => 1340792743
)
and i want to avoid those post where id is not 19 or like something. but my last query is not working :(, result is same.

It's because your logic is not mixing well with CodeIgniter's Active Record class. You cannot mix or_where and where or else you'll get fuzzy logic. You'll need to fix your logic in order for your query to be proper. Here's what I suggest.
Rewrite your foreach statements to pack everything into an array.
$ids = array();
foreach ($friend as $fr) {
foreach($fr as $f) {
if (...) {
$ids[] = $f->sub_id;
}
}
$this->db->where('time >', $f->time);
}
... And so on. When you're finished with your foreach statement, add the following line instead.
$this->db->where_in('user_id', $ids);
This should give you the ability to properly render your SQL statement with:
foreach($hide as $h)
{
$this->db->where('id !=', $h->post_id);
}

Related

Explode foreach to new array

I have JSON API response which look something like this
Array
(
[sections] => Array
(
[0] => Array
(
[id] => 115000089967
[url] => xxxxx
[html_url] => ArticleHTML1
[category_id] => 204458828
[position] => 0
[sorting] => manual
[created_at] => 2016-12-19T14:56:23Z
[updated_at] => 2017-02-03T08:23:04Z
[name] => ArticleName1
[description] =>
[outdated] =>
)
[1] => Array
(
[id] => 207077828
[url] => xxxxxx
[html_url] => ArticleHTML2
[category_id] => 204458828
[position] => 1
[sorting] => manual
[created_at] => 2016-11-14T09:28:30Z
[updated_at] => 2017-02-02T09:15:42Z
[name] => ArticleName2
[description] =>
[outdated] =>
)
)
[page] => 1
[per_page] => 30
[page_count] => 1
[sort_by] => position
[sort_order] => asc
)
I have successfully iterated this with foreach, so return looks like this:
ArticleName1 ArticleHTML1
ArticleName2 ArticleHTML2
So I took [name] and [html_url] from each like this:
$details1 = array('name');
$details2 = array('html_url');
foreach($sections['sections'] as $article) {
foreach($details1 as $detail) {
echo "$article[$detail] ";
}
foreach($details2 as $detail) {
echo "$article[$detail]\n";
}
}
But what I want next is that, that response should be exploded to one single array like this:
Array
(
[0] => ArticleName1 ArticleHTML1
[1] => ArticleName2 ArticleHTML2
)
I already managed to explode those to individual arrays:
foreach($sections['sections'] as $article) {
foreach($details1 as $detail) {
$name = "$article[$detail] ";
}
foreach($details2 as $detail) {
$url = "$article[$detail]\n";
}
$string = $name . $url;
$array = explode(' ', $string, 1);
print_r($array);
}
but I need just one array.
How? I'm lost or just doesn't understand, am I even close?
EDIT
The thing here is that the JSON dump is pretty large and I only need few things (name and url). So I was thinking that I first grab the whole thing, then I just take the names and urls (like the first foreach is doing), and then put those back to array. Because from those names and urls I need only last 12 keys, and taking those from sinlge array would be easy.
Tho it would be perfect, if I could sort out the keys which I don't want, in the first place. That would solve my problem. Then I wouldn't need a new array etc.
You're making this much more difficult than it needs to be. It's just a single loop:
$array = array();
foreach ($sections['sections'] as $article) {
$array[] = $article['name'] . ' ' . $article['html_url'];
}

CakePHP Model Query Return Data Formating

I'm looking for a way to make it so cake returns all database data in the same format/structure... Currently it returns two different types of format depending on the relationship.
If a model 'B' is associated with the current model 'A' being queried it will then place model associations for 'B' underneath it as you can see in [User] below. I want it so that all queries use that structure.
example:
$this->find('all', ....
returns:
Array
(
[0] => Array
(
[UserGroup] => Array
(
[id] => 53
[user_id] => 100003332014851
[media_id] =>
[name] => john
[description] => qwasdfad
)
[User] => Array
(
[id] => 100003332014851
[session_id] => ssm2qbrotmm13ho1ipm8ii2492
[username] =>
[password] => -1
[Planner] => Array
(
)
[Purchase] => Array
(
)
[Listing] => Array
(
)
)
)
I want this to look like:
Array
(
[0] => Array
(
[UserGroup] => Array
(
[id] => 53
[user_id] => 100003332014851
[media_id] =>
[name] => john
[description] => qwasdfad
[User] => Array
(
[id] => 100003332014851
[session_id] => ssm2qbrotmm13ho1ipm8ii2492
[username] =>
[password] => -1
[Planner] => Array
(
)
[Purchase] => Array
(
)
[Listing] => Array
(
)
)
)
)
)
In CakePHP, the find() method return data like your first format. But If you want to format like second one then you have to process it by hand (try to avoid this if possible)
$data = $this->find('all');
$assocs = Set::extract('/User', $data); // extracting all `User` array
foreach($assocs as $key => $assoc) {
unset($data[$key]['User']); // removing the associate `User` from `$data`
$data[$key]['UserGroup']['User'] = $assoc['User']; // adding associate under `UserGroup`
}
ended up doing this... it changes the output to what we need. The top level item does not have a header which is fine I just adjusted our scripts for that... maybe this will help somebody else if they need a custom idea
also no guarantee this covers all possible results but so far it works with all the queries we have.
class AppModel extends Model {
function afterFind($results, $primary) {
//if this is a primary, structure like a secondary so entire site is same format
if ($primary) {
$class = get_class($this);
//simple fix for primary
foreach ($results as $key => $result) {
$result = $this->formatData($result, $class);
$results[$key] = $result;
}
}
return $results;
}
function formatData($result, $class) {
$array = array();
if (isset($result[$class])) {
$array = $result[$class];
unset($result[$class]);
}
$array += $result;
return $array;
}
You can also use contain in this case along with find as UserGroup.User for your desired result

Cannot print data into "view"

I have a page that I would like to show the data from the database.
I can print_r($sale) and it shows the data that I am after - $sale is set in the controller but I cannot seem to do <?php $sale['name'] ?> it shows nothing.
Print_r:
Array ( [0] => stdClass Object ( [id] => 48 [name] => Jess McKenzie [location] => Auckland [bedrooms] => 5 [bathrooms] => 1 [condition] => Fair [description] =>
hii
[price] => 30.00000 [imagename] => purple.jpg [thumbname] => purple_thumb.jpg ) [1] => stdClass Object ( [id] => 49 [name] => jzmwebdevelopment [location] => Auckland [bedrooms] => 15 [bathrooms] => 4 [condition] => OK [description] =>
zebra
[price] => 25.00000 [imagename] => Zebra.jpg [thumbname] => Zebra_thumb.jpg ) )
Model:
function getSalesContent($id = NULL) {
$this->db->where('id', $id);
$query = $this->db->get('sales', 1);
if($query->num_rows() > 0) {
$row = $query->result_array();
return $row;
}else{
return FALSE;
} # End IF
} # End getSalesContent
It's returning an array of objects.
To show the first element returned you would use
$sale[0]->name;
To cycle through all of the values you could use a foreach loop
foreach($sale as $s){
print $s->name;
}
$query->result_array() returns an array of arrays, you would use $sale['name'] in a foreach loop.
$query->result() returns an array of stdclass objects, you would use $sale->name in a foreach loop.
I cannot seem to do $sale->name it
shows nothing.
Open your index.php file and add error_reporting(E_ALL) to the top. If you were error reporting you'd be able to see your mistakes with helpful error messages telling you exactly what went wrong. Just set it to 0 for when you go live.
I have tried <?php $sale['name'] ?> and get nothing
You need an echo statement: <?php echo $sale['name'] ?>
If $sale is the output you posted, <?php echo $sale[0]->name ?> should print Jess McKenzie

Problems with array when getting data from a database

I'm trying to get some data from my database, and then pass it into an array for later use. I am using MySQLi for my driver.
Here's my code:
// Build a query to get skins from the database
$stmt = $mysqli->prepare('SELECT id, name, description, author, timestamp, url, preview_filename FROM `skins` LIMIT 0, 5');
$stmt->execute();
$stmt->bind_result($result['id'], $result['name'], $result['desc'], $result['auth'], $result['time'], $result['url'], $result['preview']);
// The skins array holds all the skins on the current page, to be passed to index.html
$skins = array();
$i = 0;
while($stmt->fetch())
{
$skins[$i] = $result;
$i++;
}
print_r($skins);
The problem is, when this executes, the $skins array contains the last result row from the query. This is the print_r of $skins:
Array
(
[0] => Array
(
[id] => 3
[name] => sdfbjh
[desc] => isdbf
[auth] => dfdf
[time] => 1299970810
[url] => http://imgur.com/XyYxs.png
[preview] => 011e5.png
)
[1] => Array
(
[id] => 3
[name] => sdfbjh
[desc] => isdbf
[auth] => dfdf
[time] => 1299970810
[url] => http://imgur.com/XyYxs.png
[preview] => 011e5.png
)
[2] => Array
(
[id] => 3
[name] => sdfbjh
[desc] => isdbf
[auth] => dfdf
[time] => 1299970810
[url] => http://imgur.com/XyYxs.png
[preview] => 011e5.png
)
)
As you can see, the last result from the query is populating all of the array entries for some reason.
Can anyone explain this behaviour and tell me what I'm doing wrong? Thanks. :)
EDIT: Here's the solution:
while($stmt->fetch())
{
foreach($result as $key=>$value)
{
$tmp[$key] = $value;
}
$skins[$i] = $tmp;
$i++;
}
Quoting the (now) first note on the mysqli::fetch manual page, emphasis mine :
the problem is that the $row returned is reference and not data.
So, when you write $array[] = $row, the $array will be filled up with the last element of the dataset.

PHP function return value nested array removed

I have a function that builds a collection of user objects from the database:
public static function GetUsersByGroup($instanceID, $groupID)
{
$col = null;
if($groupID != null)
{
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_USERGROUP_MEMBERS,array ($instanceID, $groupID));
}
else
{
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID);
}
echo "this is the collection I am going to return: <pre>";
print_r($col);
echo "</pre>";
return $col;
}
The method has some debug output at the bottom, but the point is if I call that method with a null groupid param i.e it runs the second condition, it prints out a nice indication of the collection that I expected to receive, which is great.
However ..
Here is my calling method:
echo "<br> Collection passed through is: </br>";
$collection = UserGroup::GetUsersByGroup($this->GetInstance()->id,$grouplist->GetCurrentCommandParam());
print_r($collection);
$userlist->UpdateCollection($collection);
$userlist->DeSelect();
The intresting thing is the output:
this is the collection I am going to return:
Collection Object
(
[_valueType:protected] => User
[_isBasicType:protected] =>
[_validateFunc:protected] =>
[_collection:protected] => Array
(
[0] => User Object
(
[valid] =>
[validationMessage] =>
[id] => 29
[table:private] => user
[fields:private] => Array
(
[title] => mrs
[fname] => Kirsty
[lname] => Howden
[email] => kirsty2#softyolk.com
[password] => xxxxxxxx
[lastlogin] => 2009-07-05 15:20:13
[instanceID] => 2
[deliveryAddress] =>
[invoiceAddress] =>
[tel] => 01752848484
[isAdmin] => 0
[disabled] => 0
[mustAuthorise] =>
[usergroupID] =>
)
[validationRules:private] => Array
(
)
[_profileStartTime:protected] =>
[_profileTag:protected] =>
)
[1] => User Object
(
[valid] =>
[validationMessage] =>
[id] => 31
[table:private] => user
[fields:private] => Array
(
[title] => master
[fname] => Seb
[lname] => Howden
[email] => seb#antithug.co.uk
[password] => xxxxxxxxx
[lastlogin] => 2009-07-09 02:02:24
[instanceID] => 2
[deliveryAddress] => saltash
[invoiceAddress] => saltash
[tel] => 8908908
[isAdmin] => 0
[disabled] => 0
[mustAuthorise] =>
[usergroupID] =>
)
[validationRules:private] => Array
(
)
[_profileStartTime:protected] =>
[_profileTag:protected] =>
)
)
)
Collection passed through is:
this is the collection I am going to return:
Collection Object
(
[_valueType:protected] => User
[_isBasicType:protected] =>
[_validateFunc:protected] =>
[_collection:protected] => Array
(
)
)
Collection Object ( [_valueType:protected] => User [_isBasicType:protected] => [_validateFunc:protected] => [_collection:protected] => Array ( ) )
The object returned has been modified??
If the GetUsersByGroup method is called with a userGroupID i.e the first case, then output is all as expected.
If i remove the conditional from the method and simply return $col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID); then all output is as expected.
It seems that the else condition executes correctly, and then is corrupted on return, but this only happens if the else condition is present, remove the else condition, and simply return the result of the method call in the else condition, and all is as expected.
Any idea please?
Thanks
ADDED THE UserGroup::GetCollection Method (this is a deep rabbit hole though, could go on)
protected static function GetCollection($class, $sqlID, $params = null)
{
$dal = DAL::GetInstance(); //not to be confused with the Instance object, this is an instance of DAL
$collection = new Collection($class);
$items = $dal->QueryForAssoc($sqlID,$params);
foreach($items as $item)
{
$itemObject = new $class();
$itemObject->LoadFromList($item);
$collection->add($itemObject);
}
return $collection;
}
To further clarify the follwing works fine ::
public static function GetUsersByGroup($instanceID, $groupID)
{
$col = null;
//if($groupID != null)
//{
//$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_USREGROUP_MEMBERS,array ($instanceID, $groupID));
//}
//else
//{
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID);
// }
return $col;
}
I only see the issue if the line is in the else block.
The likely problem here lies in your UserGroup::GetCollection function. PHP 5 passes all objects by reference, so if you are doing any sort of modification in this routine based on the way you are retrieving these objects, then this modification will persist after UserGroup::GetCollection has finished.
I would examine carefully the differences between these two function calls and make sure there are no object changes happening in UserGroup::GetCollection.
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_USERGROUP_MEMBERS,array ($instanceID, $groupID));
vs.
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID);
Turns out the method is being called twice, the second call is using the other condition, and returning a blank collection (the problem result).
By setting an echo in each condition I could see as they are called, and first the null case is called and then the non null.
The actual error is that I had a stateful list calling the method twice in the same postback. Hard to catch.
Thanks for looking

Categories