My Database table looks like this (rough outline):
+--------+-----------+-------------+---------+------------+------------+
| log_id | host_name | status | host_id | profile_id | event_date |
+--------+-----------+-------------+---------+------------+------------+
| 1 | site1 | Online | 2 | 1 | <*date*> |
+--------+-----------+-------------+---------+------------+------------+
| 2 | site1 | Online | 2 | 1 | <*date*> |
+--------+-----------+-------------+---------+------------+------------+
| 3 | site1 | Offline | 2 | 1 | <*date*> |
+--------+-----------+-------------+---------+------------+------------+
| 4 | site2 | Online | 4 | 1 | <*date*> |
+--------+-----------+-------------+---------+------------+------------+
| 5 | site2 | Maintenance | 4 | 1 | <*date*> |
+--------+-----------+-------------+---------+------------+------------+
Here are my codes:
VIEW:
<?php foreach($result as $row): ?>
['<?php echo $row->host_name;?>',<?php echo $this->help_model->filter_online($id,$row->host_id, 'Online');?>,
<?php echo $this->help_model->filter_online($id,$row->host_id, 'Offline');?>,
<?php echo $this->help_model->filter_online($id,$row->host_id,'Maintenance');?>],
<?php endforeach; ?>
CONTROLLER:
public function userreports()
{
$data['id']=$this->session->userdata('profile_id');
$this->session->set_userdata('from_date', '2015-01-01');
$from_date = $this->session->userdata('from_date');
$date = date('Y-m-d',now());
$this->session->set_userdata('to_date', $date);
$to_date = $this->session->userdata('to_date');
$data['result'] = $this->help_model->all_logs($this->session->userdata('profile_id'));
$this->load->view('squidtopus1-host-reports', $data);
}
MODEL:
function all_logs($id)
{
$id = $this->session->userdata('profile_id');
$this->db->select("*");
$this->db->from('server_log');
$this->db->where('profile_id',$id);
$query = $this->db->get()->result();
return $query;
}
function filter_online($data, $host_id, $status)
{
$from_date = $this->session->userdata('from_date');
$to_date = $this->session->userdata('to_date');
$id = $this->session->userdata('profile_id');
$this->db->select()->from('server_log');
$this->db->where('profile_id',$id);
$this->db->where('status',$status);
$this->db->where('host_id',$host_id);
$this->db->where('event_date >=',$from_date);
$this->db->where('event_date <=',$to_date);
$data = $this->db->get()->result();
$stat_count = 0;
foreach ($data as $row) {
$stat_count++;
}
return $stat_count;
}
The information that needs to displayed is shown properly, but the problem is that it repeatedly shows it for each row in the database that matches 'profile_id = $id'(in this case, profile_id=1).
Ideally it should show:
['site1', 2,1,0], ['site2', 1,0,1]
But instead it shows:
['site1', 2,1,0],['site1', 2,1,0],['site1', 2,1,0],['site2', 1,0,1],['site2', 1,0,1]
I can't determine where I've gone wrong... So any insight into solving this issue is greatly appreciated. Thanks ahead!
function all_logs($id)
{
$id = $this->session->userdata('profile_id');
$this->db->select("DISTINCT(host_id), host_name");
$this->db->from('server_log');
$this->db->where('profile_id',$id);
$query = $this->db->get()->result();
return $query;
}
try to change your function like above
Related
I have two tables such as below :
/* questions table */
| q_id | q_title |
| ------- | ---------------------- |
| 1 | What is your name? |
| ------- | ---------------------- |
| 2 | What is your gender? |
| ------- | ---------------------- |
| ... | |
/* options table */
| o_id | o_title | o_question_id |
| ------ | --------- | --------------- |
| 1 | George | 1 |
| ------ | --------- | --------------- |
| 2 | Sarah | 1 |
| ------ | --------- | --------------- |
| 3 | Michael | 1 |
| ------ | --------- | --------------- |
| 4 | Male | 2 |
| ------ | --------- | --------------- |
| 5 | Female | 2 |
| ------ | --------- | --------------- |
| ... | | |
How can I select from two tables as follows :
1. What is your name?
George
Sarah
Michael
2. What is your gender?
Male
Female
"JOIN" makes repetitive questions.
Where is my code wrong?
My controller :
/* controller */
$data['questions'] = $this->db->get('questions_tbl')->result();
$items_arr = array();
foreach ($data['questions'] as $option) {
$items_arr[] = $this->db->where('o_question_id', $option->q_id)->get('options_tbl')->result();
}
$data['options'] = $items_arr;
And my view :
/* view */
<?php foreach ($questions as $q) { ?>
<strong><?= $q->q_id ?>.<?= $q_title ?></strong>
<?php foreach ($options as $o) { ?>
<?php if ($o->o_question_id == $q->id) { ?>
<p><?= $o->o_title ?></p>
<?php } ?>
<?php } ?>
<?php } ?>
You will need to first select the questions, then for each question ID, select it's choices.
Below is an example:
function questions(){
$qtns = array();
$query = $this->db->get('questions_table');
foreach($query->result_array() as $one){
$one['choices'] = $this->questionChoices($one['id'];
$qtns[] = $one:
}
return $qtns;
}
function questionChoices(int $qtnID){
$this->db->where('o_questions_id', $qtnID);
$query = $this->db->get('options_table');
return $query->result_array();
}
Then from your view you can display the questions as:
<?php foreach($qtns as $one){ ?>
<strong><?= $one['q_id'] ?>.<?= $one['q_title'] ?></strong>
<?php foreach ($one['choices'] as $o) { ?>
<p><?= $o['o_title'] ?></p>
<?php } ?>
<?php } ?>
So i have database table named usermeta and have table structure like this :
-----------------------------------------------------------
| ummeta_id | user_id | meta_key | meta_value |
-----------------------------------------------------------
| 1 | 1 | fullname | John Doe |
| 2 | 1 | birthplace | New York |
| 3 | 1 | birthdate | 1990/01/01 |
| 4 | 1 | mobile | 0812-3456-7890 |
| 5 | 1 | email | john.doe#mail.com |
| 6 | 2 | fullname | Jon Wick |
| 7 | 2 | birthplace | Washington DC |
| 8 | 2 | birthdate | 1985/10/21 |
| 9 | 2 | mobile | 0890-1234-5678 |
| 10 | 2 | email | wickjohn#mail.com |
And i try to generate json data for all data from this database using Codeigniter (v 3.1.9) using Controller and Model.
This is my Model (model name: db_usermeta)
function userslist()
{
$query = $this->db->select('*')
->from('usermeta')
->get();
return $query->result();
}
This is my Controller
public function userlist()
{
header('Content-Type: application/json; charset=utf-8');
$query = $this->db_usermeta->userslist();
$json_data = array();
foreach ($query as $key)
{
$json_data[$key->meta_key] = $key->meta_value;
}
echo json_encode($json_data);
}
The result when i open using my browser to check the json data using web developer tool is only show last record, in this case only show data from user_id 2, like this:
{
"fullname":"John Wick",
"birthplace":"Washinton DC",
"birthdate":"1985/10/21",
"mobile":"0890-1234-5678",
"email":"wickjohn#mail.com"
}
What I want to achieve is to show all json data nested like this:
"data": [
{
"fullname":"John Doe",
"birthplace":"New York",
"birthdate":"1990/01/01",
"mobile":"0812-3456-7890",
"email":"john.doe#mail.com"
},
{
"fullname":"John Wick",
"birthplace":"Washinton DC",
"birthdate":"1985/10/21",
"mobile":"0890-1234-5678",
"email":"wickjohn#mail.com"
}
]
How can i achieve this? Did I make a mistake on my controller and model. I really appreciate your help.
your $key->meta_key is overwriting for every record. that's why only last record appeared. You don't actually need to loop through to get json data.
public function userlist()
{
header('Content-Type: application/json; charset=utf-8');
$query = $this->db_usermeta->userslist();
$json_data = array(array());
$user_id_map = array();
$index = 0;
foreach ($query as $key)
{
if(!isset($user_id_map[$key->user_id])){
$user_id_map[$key->user_id] = $index++;
}
$currentIndex = $user_id_map[$key->user_id];
$json_data[$currentIndex][$key->meta_key] = $key->meta_value;
}
echo json_encode($json_data);
}
just change your controller code to this and this will return json data.
Since the meta key fullname is same for both records, you need to change the key name to something unique
foreach ($query as $key)
{
$json_data[$key->meta_key] = $key->meta_value;
}
Change $json_data[$key->meta_key] to $json_data[$key->meta_key.$key->user_id]
or simply change it to $json_data[$key->ummeta_id]
Here is my table structure:
// pages
+----+-----------------------+--------+
| id | path | method |
+----+-----------------------+--------+
| 1 | list_role | get |
| 2 | make_role | post |
| 3 | edit_role/id | get |
| 4 | list_voucher/activate | get |
| 5 | list_voucher/activate | post |
| 6 | expire_voucher/id | get |
+----+-----------------------+--------+
// role_page
+---------+---------+
| role_id | page_id |
+---------+---------+
Now I want to insert multiple rows into role_page table according to this array: (noted that I have $role_id)
$arr = [['list_role', 'get'], ['list_voucher/activate', 'get']]
$role_id = 4; // for example
So the expected output is:
// role_page
+---------+---------+
| role_id | page_id |
+---------+---------+
| 4 | 1 |
| 4 | 4 |
+---------+---------+
How can I do that by a join?
Currently I do that by a loop on $arr like this:
$role_id = 4;
foreach($arr as $row) {
// match the page id
$page_id = pages::where('path', row[0])->where('method', row[1])->first();
// insert
$role_page = new role_page;
$role_page->role_id = $role_id;
$role_page->page_id = $page_id;
}
Try this
Page Model (you may have to customize this relation)
public function roles(){
return $this->belongsToMany(Role::class, 'role_page', 'page_id', 'role_id')
}
Then
$arr = [['list_role', 'get'], ['list_voucher/activate', 'get']]
$role_id = 4; // for example
$query = Page::query();
foreach ($arr as $page){
$query = $query->orWhere(function($query){
$query->where('path', $page[0])->where('method', $page[1]);
}
}
$pages =$query->get();
foreach($pages as $page){
$page->roles()->attach($role_id);
}
$page_id = pages::where('path', row[0])->where('method', row[1])->first();
This returns an object.
$page_id = pages::where('path', row[0])->where('method', row[1])->first()->id;
This will return just the id.
And then in your foreach you can:
role_page::create([
'page_id' => $page_id,
'role_id' => $role_id
]);
You do have to explicitly state in your role_page model that it's not plural if your not refering to it in a relationship way:
protected $table = 'role_page';
I wanted to check if the next TWO rows or ID is not NULL.
because if there is no succeeding TWO rows or ID then the income remains zero.
foreach ($data as $row)
{
if(($row->id + 2) != NULL) //I don't know what is the correct statement here
{
echo "<tr>";
echo "<td>".$row->id."</td>";
echo "<td>".$row->username."</td>";
echo "<td>"."650.00"."</td>";
echo "<td>".$row->remarks."</td>";
echo "<tr>";
}
else
{
echo "<tr>";
echo "<td>".$row->id."</td>";
echo "<td>".$row->username."</td>";
echo "<td>".$row->income."</td>";
echo "<td>".$row->remarks."</td>";
echo "<tr>";
}
}
Here is the table I want to achieve.
==================================
|ID | Username | Income | Remarks|
| 2 | user1 | 650.00 | |
| 3 | user2 | 650.00 | |
| 4 | user3 | 0.00 | |
| 5 | user4 | 0.00 | |
==================================
If I add a username then the next output will be this:
==================================
|ID | Username | Income | Remarks|
| 2 | user1 | 650.00 | |
| 3 | user2 | 650.00 | |
| 4 | user3 | 650.00 | |
| 5 | user4 | 0.00 | |
| 6 | user5 | 0.00 | |
==================================
You need to change your foreach to get the index.
foreach ($data as $index => $row)
Then you can address all rows relative to your current row with:
$row_two_ahead = $data[$index + 2];
you should check however if that row exists before you try to use it or you will get index out of range exceptions:
if (isset($data[$index + 2])) {
}
I solved the problem...
this is the code from my controller:
public function addUsername()
{
$data['id'] = NULL;
$data['username'] = $this->input->post('username');
$data['reward'] = 0.00;
$data['remarks'] = ' ';
$this->Matrix_model->addUsername($data);
$last = $this->Matrix_model->getLast();
$index = $last - 2; //I minus the last index with two
$this->Matrix_model->updateIncome($index); //and updated the income of that index
redirect('http://localhost/matrix/index.php/matrix');
}
and this is the code from my model:
public function addUsername($data)
{
$this->db->insert("income", $data);
}
public function getLast()
{
return $this->db->insert_id(); //this is the method to access the last id inserted
}
public function updateIncome($id)
{
$this->db->set("reward", 650);
$this->db->where("id", $id);
$this->db->update("income");
}
thank you and I'm sorry if other programmers didn't understand my questions
Is there any MySQL function that will optimize this code? A child ID getting all parent ID
function get_parents() {
$ids = array();
while($id) :
$query = "SELECT placement_id FROM referrals WHERE user_id = $id";
$query = $this->db->query($query);
$result = $query->row();
if(!isset($result->placement_id)) :
break;
elseif(isset($result->placement_id) && $result->placement_id == 2) :
break;
endif;
$id = $result->placement_id;
array_push($ids, $id);
if($result) :
continue;
endif;
break;
endwhile;
return $ids;
}
The code above will return all parent ID of given user_id, this will stop if nothing is found. I found this code too slow and heavy load.
My Table
relations table
| id | user_id | placement_id |
| 1 | 2 | NULL |
| 2 | 3 | 2 |
| 3 | 4 | 2 |
| 4 | 5 | 3 |
| 5 | 6 | 4 |
| 6 | 7 | 3 |
| 7 | 8 | 3 |
| 8 | 9 | 3 |
| 9 | 10 | 6 |
| 10 | 11 | 5 |
| 11 | 12 | 6 |
| 12 | 13 | 4 |
| 13 | 14 | 3 |
| 14 | 15 | 9 |
| 15 | 16 | 10 |
user_id is the child and parent is placement_id
You can rewrite you code as:
function get_parents() {
$ids = array();
while($id){
$query = "SELECT placement_id FROM referrals WHERE user_id = $id";
$query = $this->db->query($query);
$result = $query->row();
if(isset($result->placement_id) && $result->placement_id !== 2)
{
$id = $result->placement_id;
array_push($ids, $id);
}
}
return $ids;
}
It excludes some additional function calls such continue,break etc. Also, Make sure you have INT as type of user_id with indexing on this column.
I would personally do something like this:
<?php
define('MAX_NEST_DEPTH', 15);
function get_parent($child_id) {
$child_id = (int) $child_id;
$parents = array();
$counter = 0;
do {
$sql = "SELECT placement_id
FROM referrals
WHERE user_id = {$child_id}";
$query = $this->db->query($query);
$result = $query->row();
$child_id = (int) $result->placement_id;
$parent[] = $child_id;
$counter++;
}
while ($child_id != 0 || $counter == MAX_NEST_DEPTH);
return $parents;
}
You wont get around the query in a loop here, mysql does not support n-level-nested SELECT, otherwise we could just do it in one go.