Codeigniter Bootstrap add and edit record simultaneously - mysql

I have a MySQL Table, related to Codeigniter project that is used to maintain the details of files as follows (tbl_documents) :
+-----+---------+-------+------------+-----------+--------+---------+--------+
| id | file_no | name | subject_id | folder_no | row_no | rack_no | status |
+-----+---------+-------+------------+-----------+--------+---------+--------+
| 100 | GSP/01 | Test | 1 | 1 | 1 | 2 | 1 |
| 101 | GSP/02 | Test1 | 2 | 2 | 1 | 3 | 1 |
| 102 | GSP/03 | Test2 | 1 | 2 | 1 | 3 | 1 |
| 103 | GSP/04 | Test3 | 3 | 2 | 2 | 1 | 1 |
| 104 | GSP/05 | Test4 | 4 | 1 | 1 | 1 | 1 |
+-----+---------+-------+------------+-----------+--------+---------+--------+
subject_id is referenced from the following table (tbl_subjects) :
+------------+--------------+--------+
| subject_id | subject_name | status |
+------------+--------------+--------+
| 1 | A/01 | 1 |
| 2 | A/02 | 1 |
| 3 | A/03 | 1 |
| 4 | B/01 | 1 |
| 5 | B/02 | 1 |
| 6 | C/01 | 1 |
+------------+--------------+--------+
insert, update & delete records are working fine. If I edit record using an existing subject_id in the tbl_subject, the functionality is working properly. But I want to edit a record in the tbl_documents table, while inserting new subject to the tbl_subject table, the functionality is not working (My Requirement). My question is mainly aim to subject_id (s). I used the following lines in my controller.
Controller
public function store($id = null)
{
$this->form_validation->set_rules('name', "File/Document Name", 'required');
if ($this->form_validation->run()) {
$subject_id = $this->input->post('subject_id');
$sub_data = [];
$sub_data = array(
'subject_name' => $subject_id,
'status' => 1
);
$data = array(
'file_no' => $this->input->post('file_no'),
'name' => $this->input->post('file_name'),
'subject_id' => $this->input->post('subject_id'),
'folder_no' => $this->input->post('folder_no'),
'rack_no' => $this->input->post('rack_no'),
'row_no' => $this->input->post('row_no'),
'status' => 1
);
}
if ($this->form_validation->run() && $this->documents_model->save($data, $id, $sub_data)) {
if ($id)
$message = 'File/ Document Details have been Updated successfully..!!';
else
$message = 'File/ Document details have been saved successfully..!!';
$this->session->set_flashdata('message', $message);
redirect('documents');
} else {
redirect('documents');
}
}
Documents_model
public function save($item, $id, $sub_data = [])
{
$this->db->trans_start();
if (!empty($sub_data)) {
$this->db->insert('tbl_subjects', $sub_data);
$data['subject_id'] = $this->db->insert_id();
}
if ($id) {
$this->db->update('tbl_documents', $item, array('id' => $id));
} else {
$this->db->insert('tbl_documents', $item);
}
$this->db->trans_complete();
return $this->db->trans_status();
}
Subject Part of View
<div class="form-group">
<label for="subject_id">New Subject</label>
<div class="input-group">
<select class="form-control select2" name="subject_id" id="subject_id" style="width: 100%">
<option value=""> Select a New Subject</option>
<?php
$id = !empty($subjects) ? $subjects->subject_id : '';
foreach ($subjects as $sub) {
$selected = "";
if ($id == $sub->subject_id)
$selected = "selected";
echo "<option value= '$sub->subject_id' $selected>$sub-
>subject_name</option>";
}
?>
</select>
<span class="input-group-addon x" aria-describedby="sizing-addon2"
style="padding: 2px 4px !important;"> <a style="cursor: pointer" id="add-subject"
title="Add New Subject"><i style="color: #337ab7 !important;" class="fa fa-2x fa-plus-
circle"></i></a>
</span>
</div>
</div>
<script type="text/javascript">
$(document).on('click', '#add-subject', function (e) {
e.preventDefault();
bootbox.prompt("Enter New Subject", function (result) {
if (result !== null && result !== '') {
$('#subject_id').append('<option>' + result + '</option>')
.val(result);
$("#subject_id").val(result).trigger("change");
}
});
});
</script>

Related

When input type submit is clicked, generate a query

beginner here. I'm currently making a matching system where owners will register their entries. Once it is done, I will click the "match" button and it'll generate the match. The logic for matching depends on the weight.
For example, if owner 1 and owner 2 registered an entry/ies that has 1900 weight, they'll
automatically be matched. (As you can see at the 2nd table)
How can I achieve these goals of mine? Thank you guys in advance.
tbl_entry
|id| entryName| lightBand| weight |
|---| --------| ----- |---------|
| 1 | owner1 | 1 | 1900 |
| 2 | owner1 | 2 | 1920 |
| 3 | owner2 | 3 | 1900 |
| 4 | owner3 | 4 | 1910 |
| 5 | owner4 | 5 | 1910 |
tbl_matching
| id |fightID| entryName| lightBand| weight | entryName| lightband1| weight1|
|---- |--------| --------| ----- |---------|-------- |----------|--------|
| 1 | 1 | owner1 | 1 | 1900 | owner2 | 3 | 1900 |
| 2 | 2 | owner3 | 4 | 1910 | owner4 | 5 | 1910 |
| 3 | - | owner2 | - | - | - | - | - |
HTML:
<form action="transaction/match" method="POST">
<input type="submit" name="doMatch"> match
</form>
Controller:
public function match {
$formSubmit = $this->input->post('doMatch');
// do the matching query here
}
(hyphen/dash) <<<< means no correspondent player to match with.
Note: I'm using codeigniter3.
First of all, I never use <input type = "submit"> before, usually I use <input type="text"> and put the submit in button.
Let's say you have
<input type="text" name="entryName">
<input type="text" name="weight">
... etc
you can put this in your Controller (for later, you should use Control -> Model)
$weight = $this->input->post('weight'); //get your weight input
//get the opponent data based on weight input
$result = $this->db->get_where('tbl_entry', ['weight' => $weight])->row_array();
//check if the result is not null
if ($result != null) {
$submit = [
//I assume that your ID is autoincrement
'fightID' => 'fight ID', //you can make a function for fight ID and put the result like $fight_ID
'entryName' => $this->input->post('entryName'),
'lightBand' => $this->input->post('lightBand'),
'weight' => $weight,
];
$data[] = array_merge($submit, $result); //merge the entry and the result into 1 array
$this->db->insert('tbl_matching', $data); //insert it into your table matching
}
else {
//like above, but just change it to '-' instead of input->post
}

Laravel 7 select from table with two columns having ids from a Single Table

My requirement?
If i am the logged in user with Id = 1, then through the Messages Table i want to select users from Users Table to whom i sent the message or from whome i received the message.
Table 1: Users
+----+------+-------+
| id | name | email |
+----+------+-------+
| 1 | a | ??? |
| 2 | b | ??? |
| 3 | c | ??? |
| 4 | d | ??? |
| 5 | e | ??? |
| 6 | f | ??? |
| 7 | g | ??? |
| 8 | h | ??? |
| 9 | i | ??? |
| 10 | j | ??? |
+----+------+-------+
Table 2: Messages
+----+---------+-------------+
| id | user_id | receiver_id |
+----+---------+-------------+
| 1 | 1 | 2 |
| 2 | 3 | 1 |
| 3 | 4 | 1 |
| 4 | 1 | 5 |
| 5 | 1 | 3 |
+----+---------+-------------+
User Model
public function messages()
{
return $this->belongsToMany(User::class, 'messages', 'user_id', 'receiver_id');
}
Message Model
public function user()
{
return $this->belongsTo(User::class);
}
So what i have tried so far?
$id = Auth::id();
$users = User::with(['messages' => function($query) use($id){
$query->where('user_id', $id)
->orWhere('received_id', $id)
->orderBy('created_at', 'DESC');
}])->get();
dd($users);
What is the expected result?
Using this query, i am getting all of my 10 users. Although i should only get 4 users(those with id's 2,3,4,5).
If the above query is wrong, or i should follow another method or i should created some sort of relationships Please help.
Hopefully you have understood the question, i am new to Laravel but i am learning.
Probably what you need is three relations(one to many) in the User model. One for sent messages, one for received messages and one for both, like this:
public function messagesSent()
{
return $this->hasMany(Message::class, 'user_id');
}
public function messagesReceived()
{
return $this->hasMany(Message::class, 'receiver_id');
}
public function messages()
{
return $this->messagesSent()->union($this->messagesReceived()->toBase());
}
Then you should be able to get user messages like this: User::with('messages')->get();
I think you should use a join statement or "whereHas" to select users who have any messages.
$id = Auth::id();
$users = User::whereHas('messages', function ($query) use($id){
$query->where('user_id', $id)
->orWhere('received_id', $id);
})
->get();
To have access to "messages" you should add "with" statement too.
Adding my own solution(i.e working) to this question.
User Model
public function sent()
{
return $this->hasMany(Message::class, 'user_id');
}
public function received()
{
return $this->hasMany(Message::class, 'receiver_id');
}
Query
$users = User::whereHas('sent', function ($query) use($id) {
$query->where('receiver_id', $id);
})->orWhereHas('received', function ($query) use($id) {
$query->where('user_id', $id);
})->get();
dd($users);

MySql Posting 2 tables

I am trying to learn mySql DB, I have 2 tables that I am working with, one for the users and one for the cats that the registered users post.
USERS:
+----+---------+------------------+----------+--------+
| id | name | email | password | cats |
+----+---------+------------------+----------+--------+
| 3 | omar | omar#hotmail.com | omar | [] |
| 14 | dana | dana#gmail.com | anad | [] |
| 7 | mama | mami#gmail.com | mama | [] |
| 9 | tata | tata#gmail.com | tata | [] |
+----+---------+------------------+----------+--------+
CATS:
+----+---------+----------------+---------+
| id | name | age | breed | ownerId |
+----+---------+--------+-------+---------+
| 5 | mimi | 2 | Grey | 14 |
| 10 | Negri | 19 | black | 3 |
+----+---------+----------------+---------+
What i want to do is, whenever a cat is posted in the CATS DB I want for that catId to appear in the USERS DB in the owner'sId cats array.
For example the cat Mimi has ID = 5 and the ownerID = 14. If you look in the users table, ID 14 corresponds to user Dana. I want the cats Id(5) to appear in Dana's cats array.
This is the code I have by now : the functions that posts a new cat in the CATS DB.
function addCat (catsData, connection){
let {name, age, breed, ownerId} = catsData;
const mySqlQuery = `insert into cats(name, age, breed, ownerId) values ('${name}', '${age}', '${breed}', '${ownerId}')`;
return new Promise ((resolve, reject) => {
connection.query(mySqlQuery,
function (error, results, fields) {
if(error){
reject(error);
} else {
resolve(results);
}
})
})
};
async function postCatsHandler(req, res, next) {
try {
let data = req.body;
const connection = req.app.get("mySqlConnection");
const addedCatId = await addCat(data, connection);
console.log("addedCatId::", addedCatId);
req.result ='{...data, id : addedCatId}'
next();
}
catch(error){
next(error);
}
};
Any tips or information is greatly valued.
Many thanks.

MySQL SUM returns unexpected value

I've been trying to use SUM() to total up some numeric values in my database, but it seems to be returning unexpected values. Here is the PHP-side for generating the SQL:
public function calcField(string $field, array $weeks)
{
$stmt = $this->conn->prepare('SELECT SUM(`'. $field .'`) AS r FROM `ws` WHERE `week` IN(?);');
$stmt->execute([implode(',', $weeks)]);
return $stmt->fetch(\PDO::FETCH_ASSOC)['r'];
}
Let's give it some example data for you folks at home:
$field = 'revenue';
$weeks = [14,15,16,17,18,19,20,21,22,23,24,25,26];
This returns this value:
4707.92
Without seeing the data, this may have seemed to have worked, but here's the rows for those weeks:
+----+------+------+---------+-------+---------+---------+------+----------+
| id | week | year | revenue | sales | gpm_ave | uploads | pool | sold_ave |
+----+------+------+---------+-------+---------+---------+------+----------+
| 2 | 14 | 2019 | 4707.92 | 292 | 13 | 0 | 1479 | 20 |
| 3 | 15 | 2019 | 4373.32 | 304 | 13 | 0 | 1578 | 19 |
| 4 | 16 | 2019 | 4513.10 | 275 | 14 | 0 | 1460 | 19 |
| 5 | 17 | 2019 | 4944.80 | 336 | 14 | 0 | 1642 | 20 |
| 6 | 18 | 2019 | 4343.87 | 339 | 13 | 0 | 1652 | 21 |
| 7 | 19 | 2019 | 3918.59 | 356 | 14 | 0 | 1419 | 25 |
| 8 | 20 | 2019 | 4091.20 | 247 | 19 | 0 | 1602 | 15 |
| 9 | 21 | 2019 | 4177.22 | 242 | 12 | 0 | 1588 | 15 |
| 10 | 22 | 2019 | 3447.88 | 227 | 18 | 0 | 1585 | 14 |
| 11 | 23 | 2019 | 3334.18 | 216 | 15 | 0 | 1675 | 13 |
| 12 | 24 | 2019 | 4736.15 | 281 | 13 | 0 | 1388 | 20 |
| 13 | 25 | 2019 | 4863.84 | 252 | 12 | 0 | 1465 | 17 |
| 14 | 26 | 2019 | 4465.95 | 281 | 21 | 0 | 1704 | 16 |
+----+------+------+---------+-------+---------+---------+------+----------+
As you can see, the total should be far greater than 4707.92 - and I notice that the first row revenue = 4707.92.
Here's what things get weird, if I add this into the function:
echo 'SELECT SUM(`'. $field .'`) AS r FROM `ws` WHERE `week` IN('. implode(',', $weeks) .');';
Which outputs:
SELECT SUM(revenue) AS r FROM ws WHERE week IN(14,15,16,17,18,19,20,21,22,23,24,25,26);
Copying and pasting this into MySQL CLI returns:
MariaDB [nmn]> SELECT SUM(revenue) AS r FROM ws WHERE week IN(14,15,16,17,18,19,20,21,22,23,24,25,26);
+----------+
| r |
+----------+
| 55918.02 |
+----------+
1 row in set (0.00 sec)
Which, looks a lot more accurate. However, that very same SQL statement returns the first row value rather than summing the column for those weeks.
This function gets triggered by an AJAX script:
$d = new Page\Snapshot\D();
# at the minute only outputting dump of values to see what happens
echo '<pre>'. print_r(
$d->getQuarterlySnapshot(new Page\Snapshot\S(), new App\Core\Date(), $_POST['quarter'], '2019'),
1
). '</pre>';
The function $d->getQuarterlySnapshot function:
public function getQuarterlySnapshot(S $s, Date $date, int $q, string $year)
{
switch($q)
{
case 1:
$start = $year. '-01-01 00:00:00';
$end = $year. '-03-31 23:59:59';
break;
case 2:
$start = $year. '-04-01 00:00:00';
$end = $year. '-06-30 23:59:59';
break;
case 3:
$start = $year. '-07-01 00:00:00';
$end = $year. '-09-30 23:59:59';
break;
case 4:
$start = $year. '-10-01 00:00:00';
$end = $year. '-12-31 23:59:59';
break;
}
$weeks = $date->getWeeksInRange('2019', 'W', $start, $end);
foreach ($weeks as $key => $week){$weeks[$key] = $week[0];}
return [
'rev' => $s->calcField('revenue', $weeks),
'sales' => $s->calcField('sales', $weeks),
'gpm_ave' => $s->calcField('gpm_ave', $weeks),
'ul' => $s->calcField('uploads', $weeks),
'pool' => $s->calcField('pool', $weeks),
'sold_ave' => $s->calcField('sold_ave', $weeks)
];
}
So I don't overwrite the value anywhere (that I can see at least). How do I use SUM() with the IN() conditional?
As pointed out in the comments by #MadhurBhaiya:
Comma separated week_id values is passing as a single string in the query: week_id in ('1,2,3...,15') . MySQL implicitly typecasts this to 1 and thus gets the first row only. You will need to change the query preparation code
Led me to breaking up the single ? into named parameters using a foreach loop:
public function calcField(string $field, array $weeks)
{
$data = [];
$endKey = end(array_keys($weeks));
$sql = 'SELECT SUM(`'. $field .'`) AS r FROM `ws` WHERE `week` IN(';
foreach ($weeks as $key => $week)
{
$sql .= ':field'. $key;
$sql .= ($key !== $endKey ? ',' : '');
$data[':field'. $key] = $week;
}
$sql .= ');';
$stmt = $this->conn->prepare($sql);
$stmt->execute($data);
return $stmt->fetch(\PDO::FETCH_ASSOC)['r'];
}
Now each numeric value is treated individually, which, is getting me the expected value.
Yes, it is showing only first row data in your query because you have mentioned where week IN (1,2,3,4,5,6,7,8,9,10,11,12,13); and your data shows that you have week 13 and 1 to 12 does not exist in your data from IN clause of your query.
You are selecting only the row with week 13, the week 1-12 is not existing in your data. That's why the result of your query is 43.900001525878906
Solution 1:
You might want to change the values in your IN()because you are filtering your data by the column week.
SELECT SUM(`revenue`) as `r` FROM `ws` WHERE `week` IN (13,14,15,16,17,18,19,20,21,22,23,24,25);
Solution 2:
You can change the week in your where clause to id
SELECT SUM(`revenue`) as `r` FROM `ws` WHERE `id` IN (1,2,3,4,5,6,7,8,9,10,11,12,13);

Laravel 5.6 How to take duplicated datas from column

And that i want to print each topic_id's count
show.blade.php
#foreach($questions as $question)
{{ $question->topic_id }}
#endforeach
ExamsController#index
$topics = Topic::all();
return view('exams.show', compact('topics','questions'));
Just want to take duplicated datas count and print.
| id | topic_id |
| ---|:--------:|
| 1 | 4 |
| 2 | 9 |
| 3 | 5 |
| 4 | 5 |
| 5 | 2 |
| 6 | 4 |
| 7 | 5 |
that i wanted result is count of each topic_id duplicates. its like
| id | topic_id |
| ---|:--------:|
| 1 | 4 |
| 6 | 4 |
2
| id | topic_id |
| ---|:--------:|
| 3 | 5 |
| 4 | 5 |
| 7 | 5 |
count = 3
You could make use of groupBy
$duplicates = Topic::selectRaw("count('id') as total, topic_id")
->groupBy('topic_id')
->get();
// pass the duplicates along with other variables to the view
return view('exams.show', compact('topics','questions', 'duplicates'));
and in your view you could do
#foreach ($duplicates as $duplicate)
{{ $duplicate->topic_id }} - {{ $duplicate->total }}
#endforeach
maybe you can use collection feature on laravel to group data by topic_id
$topic = Topic::all();
$topicArray = $topic->groupBy('topic_id')->toArray();
in your view you can simply use $topicArray to display your data & count its duplicate
#foreach ($topicArray as $key => $value)
#foreach ($value as $key2 => $value2)
| {{ $value2['id'] }} | {{ $value2['topic_id'] }} |<br>
#endforeach
count {{ count($value) }}<br><br>
#endforeach
I am not sure what duplicated datas you mean, but I believe you are looking for a distinct.
The distinct method allows you to force the query to return distinct
results
https://laravel.com/docs/5.6/queries#selects
$topics = Topic::distinct()->get();