How to modify the view of the string in dropDownList? - yii2

I've got a table
| id|title|parent|
|---|-----|------|
| 1 | ABC | null |
| 2 | DEF | 1 |
| 3 | GHI | null |
|----------------|
I prepare data for dropDownList
$a = Model::find()->select('id, title, parent')->all();
$b = ArrayHelper::map($a, 'id', 'title');
<?= $form->field($modelForm, 'parent')->dropDownList($b); ?>
When I choose 'parent' ('parent' has a foreign key to 'id') I see next list:
ABC
DEF
GHI
But I want something like that to see in dropdown list:
ABC
DEF => 1
GHI
or
ABC
DEF (1)
GHI
What should I do to add parent column to the name of the proposed string?

You need to just change this line.
$b = ArrayHelper::map($a, 'id', function($model){
return $model->title.'=>'.$model->parent;
});
OR
$b = ArrayHelper::map($a, 'id', function($model){
return $model->title.'('.$model->parent.' )';
});

Related

Making a tree with MySQL datas

I have a MySQL table like this:
+------+-----------------+---------+------------+
| id | name | refferal| reference |
+------+-----------------+---------+------------+
| 1 | Alex Muller | 1 | null |
| 2 | John Doe | 2 | 1 |
| 3 | Tom Foe | 3 | 1 |
| 4 | Harry Pott | 4 | 3 |
| 5 | Kate Garry | 5 | 3 |
| 6 | Mike Blue | 6 | 4 |
+------+-----------------+---------+------------+
(more data than this...)
I need to turn that data to JSON file with Laravel. Like this:
[{"id":1,"name":"Alex Muller","parent":0},
{"id":2,"name":"John Doe","parent":1},
{"id":3,"name":"Tom Foe","parent":1},
{"id":4,"name":"Harry Pott","parent":3},
{"id":5,"name":"Kate Garry","parent":3},
{"id":6,"name":"Mike Blue","parent":4}]
At the and of this I will get a tree view like this:
TREE
I just made this json file with my own write. And I don't know what to do. I'm waiting your answers. Thank you.
If you want to add extra fields like "parent" in your example you can use map on the collection:
$users = User::where(function($query){
...
})->get()->map(function($user){
return array(
"id" => $user->id,
"name" => $user->name,
"parent" => *INTEGER*
);
})->toJson();
Or if you just want to encode the model attributes, you can use toJson serialization directly with the collection:
$users = User::User::where(function($query){
...
})->get()->toJson();
for further information, refer to the links:
https://laravel.com/docs/collections
https://laravel.com/docs/eloquent-serialization#serializing-to-json
On the model get the keys you need and then with map() change the key reference to parent, on that check if is null the reference to put a 0 then encode the array for json with json_encode.
$array = Model::get(['id', 'name', 'reference'])
->map(function($model){
return [
'id' => $model->id,
'name' => $model->name,
'parent' => is_null($reference->reference)? 0 : $reference->reference,
];
})
->toArray();
Then just make a json with that array:
echo json_encode($array);

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);

Select columns in Mysql like an array of multiple values

I have tables for example called 'city':
+-----+---------------------+
| id | name |
+-----+---------------------+
| 2 | Amsterdam |
| 3 | The Hague |
| 8 | Barcelona |
| 10 | Rome |
| 11 | Paris |
| 12 | Rotterdam |
I need to select columns information in this format:
Array
(
[0] => Array
(
[Amsterdam] => 2
[The_Hague] => 3
...
)
)
I do not want to select the information like, and mapping that information to needed format:
Array
(
[0] => Array
(
[title] => Amsterdam
[value] => 2
)
[1] => Array
(
[title] => The_Hague
[value] => 3
)
)
Can I do it by using concat, json or something else?
it looks like you are using PHP. If so, you can do this:
/* fetch associative array */
while ($row = $result->fetch_assoc()) {
printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
}
see https://www.php.net/manual/en/mysqli-result.fetch-assoc.php

How do I insert multiple value if there is only one value in form

I need to know how can I insert or update a value in my DB for a invoice form if the value of the input that I need to save is only one time?
I have a invoice form where I select a product in every row, and finally I have the input(user_id) with the value I need to save with the rest of the inputs
Like per example, I choose in the invoice:
10 tomatoes
5 garlics
2 beans
and finally there is my Id (user_id, not the Id of PRODUCTOS table that is unique)
Id=1
Here is the schema of my table, and how save or update until now:
| cantidad | nombre del producto | Id |
+------------+---------------------+-------+
| 10 | Tomatoes | 1 |
| 5 | garlics | 0 |
| 2 | beans | 0 |
Here what I need to save or update:
| cantidad | nombre del producto | Id |
+------------+---------------------+-------+
| 10 | Tomatoes | 1 |
| 5 | garlics | 1 |
| 2 | beans | 1 |
Here is the code:
$conn->beginTransaction();
$sql = "INSERT INTO PRODUCTOS
(cantidad, nombreProd, Id)
VALUES ";
$insertQuery = array();
$insertData = array();
foreach ($_POST['cantidad'] as $i => $cantidad) {
$insertQuery[] = '(?, ?, ?)';
$insertData[] = $_POST['cantidad'][$i];
$insertData[] = $_POST['nombreProd'][$i];
$insertData[] = $_POST['Id'][$i];
}
if (!empty($insertQuery)) {
$sql .= implode(', ', $insertQuery);
$stmt = $conn->prepare($sql);
$stmt->execute($insertData);
}
$conn->commit();
Thank you
So you have a single userID you want to INSERT for each product record. I can probably provide a better answer if you post the output of print_r($_POST), but basically in your foreach $POST loop, keep the user ID static:
foreach ($_POST['cantidad'] as $i => $cantidad) {
$insertQuery[] = '(?, ?, ?)';
$insertData[] = $_POST['cantidad'][$i];
$insertData[] = $_POST['nombreProd'][$i];
$insertData[] = $_POST['Id']; //OR $insertData[] = $_POST['Id'][0], depending on $_POST array
}

laravel check for record existence before inserting, the efficient way

Let's say I have table named groups with these data:
+----+---------+------+-------+
| id | user_id | name | color |
+----+---------+------+-------+
| 1 | 1 | foo | green |
| 2 | 1 | bar | red |
| 3 | 1 | baz | |
| 4 | 2 | baz | grey |
| 5 | 3 | foo | blue |
| 6 | 3 | baz | |
| 7 | 4 | baz | brown |
| 8 | 4 | foo | |
| 9 | 4 | qux | black |
+----+---------+------+-------+
I'm going to read a csv file and convert it to an array of data like this:
[
[
'user_id' => 2,
'name' => 'foo'
],
[
'user_id' => 2,
'name' => 'bar'
],
[
'user_id' => 2,
'name' => 'baz'
],
[
'user_id' => 2,
'name' => 'qux'
],
[
'user_id' => 2,
'name' => 'tux'
],
]
and insert only new data into database, and skip what already exist in database, in this example, group baz for user 2.
In Eloquent there are some useful methods like firstOrCreate() or findOrNew() that seems to be what I need, but these methods are for only one record, and if I use them I should run them per file line.
while($line = $this->decoder->decode($this->file) {
$row = Group::firstOrCreate($line);
}
Is there any better solution with running less queries?
Use INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO table (user_id,name) VALUES(1, "test") ON DUPLICATE KEY UPDATE name=VALUES(name)
For Laravel check this question
You can just load the file directly into a table and ignore duplicate entries. All you need is a unique index on the column which should not have duplicates. Then you do
LOAD DATA INFILE 'file_name.csv'
IGNORE
INTO TABLE tbl_name
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
(user_id, #var)
SET name = do_some_voodoo(#var);
And that's it. Read more about this command here.
Test:
/*sample data*/
shell> cat test.csv
Name|Value
Anna|hello
Ben |Test
East|whatever
Anna|This line should be ignored
Bob |
/*creating destination table in database*/
mysql> create table phpload(a varchar(50) primary key, b varchar(50));
Query OK, 0 rows affected (0.03 sec)
/*Test script*/
<?php
// Create connection
$con=mysqli_connect("localhost","root","r00t","playground");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql = "LOAD DATA LOCAL INFILE '/home/developer/test.csv' IGNORE INTO TABLE phpload FIELDS TERMINATED BY '|' (a, #b) SET b = UPPER(#b);";
$result = mysqli_query($con, $sql) or die(mysqli_error());
mysqli_close($con);
?>
/*executing*/
shell> php test.php
mysql> select * from phpload;
+------+----------+
| a | b |
+------+----------+
| Name | VALUE |
| Anna | HELLO |
| Ben | TEST |
| East | WHATEVER |
| Bob | |
+------+----------+
5 rows in set (0.00 sec)
Works absolutely fine.