Create a blank array from a model in cakephp - php

hi,
I have a working model and I want to be able to just create an array from it but with only the key names and just have them empty.
To illustrate, my model Client comes from the clients table, and for example when I do this:
$this->Client->find( 'first' );
I get the following array (json encoded):
{
Client: {
id: "39",
name: "andrux",
phone: "1234567890",
email: "me#andrux.com",
city_id: "2"
},
City: {
id: "2",
city_name: "andruxville"
}
}
As you can see, I set this model to have a relationship with the City model, so I get both Client and City arrays as a result of my find method.
Now I need to get the same array but without values, and I just can't find an answer for this, I have tried some solutions but none have worked the way I want, for example I tried using array_map function and the schema method of the model but that just gives me the column names of the clients table, which I can set to null if I want but what about the City model?
The end result I want is the following:
{
Client: {
id: "",
name: "",
phone: "",
email: "",
city_id: ""
},
City: {
id: "",
city_name: ""
}
}
Anyone knows how to accomplish this? I rather find a way of doing this the cakephp way - if there is one - but any solution that gets me to my desired result will be greatly appreciated.
Thanks guys!

Well, if its ok, you could create a custom function in your model and pass in the result to it, like:
//can be added to your model
function reset_values($array, $replace_with) {
foreach ($array as $key => $arr) {
if(is_array($arr)) $res[$key] = reset_values($arr,$replace_with);
else $res[$key] = $replace_with;
}
return $res;
}
$resetedArr = reset_values($arr, null); //replace values with null
echo "<pre>"; print_r($resetedArr);

Related

How to use whereIn for column array?

I have data from a table structured like so:
table: students
{
id:
name:
classes: [
{
name: "gym"
},
{
name: "science"
},
{
name: "math"
},
{
name: "english"
}
]
}
reference array: science, math
How do I return only records that match the values found in the reference array. For example, if the reference array contains math and science then all records returned from the student table will need to have those values in the classes array name field.
I'm trying to use whereIn, but it does not accept a column (array) and field as the first parameter.
This might help:
Student::select("*")->whereIn('classes', $referencearray)
->get();

Search in Json column with Laravel

In my emails table, I have a column named To with column-type Json. This is how values are stored:
[
{
"emailAddress": {
"name": "Test",
"address": "test#example.com"
}
},
{
"emailAddress": {
"name": "Test 2",
"address": "test2#example.com"
}
}
]
Now I want a collection of all emails sent to "test#example.com". I tried:
DB::table('emails')->whereJsonContains('to->emailAddress->address', 'test#example.com')->get();
(see https://laravel.com/docs/5.7/queries#json-where-clauses)
but I do not get a match. Is there a better way to search using Laravel (Eloquent)?
In the debugbar, I can see that this query is "translated" as:
select * from `emails` where json_contains(`to`->'$."emailAddress"."address"', '\"test#example.com\"'))
The arrow operator doesn't work in arrays. Use this instead:
DB::table('emails')
->whereJsonContains('to', [['emailAddress' => ['address' => 'test#example.com']]])
->get()
I haven't used the json column but as the documentation refers, the below code should work fine.
DB::table('emails')
->where('to->emailAddresss->address','test#example.com')
->get();
In case to store array in json format. And just have an array list of IDs, I did this.
items is the column name and $item_id is the term I search for
// $item_id = 2
// items = '["2","7","14","1"]'
$menus = Menu::whereJsonContains('items', $item_id)->get();
Checkout the Laravel API docs for the whereJsonContains method
https://laravel.com/api/8.x/Illuminate/Database/Query/Builder.html#method_whereJsonContains
Using Eloquent => Email::where('to->emailAddress->address','test#example.com')->get();
You can use where clause with like condition
DB::table('emails')->where('To','like','%test#example.com%')->get();
Alternatively, if you have Model mapped to emails table names as Email using Eloquent
Email::where('To','like','%test#example.com%')->get();

Why my loop return me only "array"

I want to return for each vehicule of the API the brand name and the model name
i'm actualy using this loop:
$vehiculecount=count($data);
for($x = 0; $x < $vehiculecount; $x++) {
echo $data[$x];
echo $data[brand][name];
echo "<br>";
}
That actualy return me only :
Array
Array
Array
Array
Array
Array
...
This is what i'm getting in PHP with curl to an API :
{
totalResult: "150",
nbPageList: 2,
createdAt: "2018-05-28T09:23:05+0200",
updatedAt: "2018-05-28T10:55:14+0200",
reference: "5nqts",
reportNumber: 5,
country: "FR",
state: "vehicle.state.parc",
brand: {
reference: "56f50a85cb0f8",
name: "CITROEN"
},
model: {
reference: "57f4d339e38e3",
name: "C3 AIRDREAM BUSINESS"
},
I want to get only 'brand''name' for each vehicle for exemple.
Thx a lot for your help !
First, you should dump, as debugging purpose, the $data object in your loop.
Then, you should see that inside your loop, to acces to an element by its number, you have to use the indexed access like this :
echo $data[$x][brand][name];
Also, to access the brand and name index, you have to use string-key index like this : $data[$x]['brand']['name']

MongoDB update not working with existing array [duplicate]

In MongoDB how do you use $set to update a nested value?
For example, consider a collection people with the following document:
{
_id: ObjectId("5a7e395e20a31e44e0e7e284"),
name: "foo",
address: { street: "123", town: "bar" }
}
How do I update the street field embedded in the address document from "123" to "Main Street"?
Using the dot notation:
db.people.update({ }, { $set: { "address.street": "Main Street" } })
In addition to Niels' answer, also do verify the "type" of the nested value. In my case, it was a "string" formed from json. Though this might be unlikely, but do ensure that the value has the right type.

Modify cake association result array

I am in a problem of modifying the cake association hierarchy,I am new to cakephp , below is the snippet of code.
Current Code
$this->Cateogory->find('all');
The output of the above expression is of the below form :
[
{
"Category": {
"id": "37",
"title": "Inner Title",
"color": "#ffffff",
"phone-number": ""
},
"CategoryHas": [],
"PhoneNumberhas": []
}
]
Requirement :-
I am creating API for third party consumption , now the third party has given the output format as below. I want the the output to be of below form.
[
{
"Category": {
"id": "37",
"title": "Inner Title",
"color": "#ffffff",
"phone-number": "",
"CategoryHas": [],
"PhoneNumberhas": []
}
}
]
I am searching on this problem for past 1 day and I consider that I need to make a custom PHP function to solve the problem.
Thanks in advance :
Just use a loop
To convert the array of the first format to an array of the second format - just use a loop e.g.:
foreach ($stuff as &$row) {
$row['Category']['CategoryHas'] = $row['CategoryHas'];
$row['Category']['PhoneNumberhas'] = $row['PhoneNumberhas'];
unset($row['CategoryHas'], $row['PhoneNumberhas']);
}
This would be appropriate to put in your controller if it's only needed in one place.
If you always, always want your results in that format, use an afterFind method (or a behavior) to implement the same logic:
// In the category model
public function afterFind($results, $primary = false) {
foreach ($results as &$row) {
if (isset($row['CategoryHas'])) {
$row['Category']['CategoryHas'] = $row['CategoryHas'];
}
if (isset($row['PhoneNumberhas'])) {
$row['Category']['PhoneNumberhas'] = $row['PhoneNumberhas'];
}
unset($row['CategoryHas'], $row['PhoneNumberhas']);
}
return $results;
}
Be wary of choosing this option - it means that your models act unconventionally, potentially meaning plugins don't work and other developers (or you, tomorrow) are confused by the way the models act.
Your association names are pretty strange. Why are they not better named? You can use proper names internally and reformat it when sending it.
If this is just about getting the API response into a silly format that doesn't provide additional benefit use JSON views and change the structure of the array in the view as needed. This section of the book explains it in detail, read it. Example taken from the book:
// Controller code
class CategoriesController extends AppController {
public function index() {
// ... get the categories
$this->set(compact('categories'));
}
}
// View code - app/View/Posts/json/index.ctp
foreach ($categories &$row) {
if (isset($row['CategoryHas'])) {
$row['Category']['CategoryHas'] = $row['CategoryHas'];
}
if (isset($row['PhoneNumberhas'])) {
$row['Category']['PhoneNumberhas'] = $row['PhoneNumberhas'];
}
unset($row['CategoryHas'], $row['PhoneNumberhas']);
}
echo json_encode(compact('categories'));
I would convince the client and bring some arguments for a proper response format and structure. Most clients usually don't know what they want. Sometimes you have smart asses who think they need something specific but can explain why. Check JSend or http://jsonapi.org/ on how to implement a proper API response format. Understand the reasons for these formats and bring these arguments to the client.

Categories