cakephp and containable behaviour - php

I have the following json:
{
"Companies":[
{
"CompanyPersonTask":{
"company_id":"502d1844-3638-44dc-824c-14f02e0cc009",
"person_id":"2",
"task_id":"1"
},
"Company":{
"id":"502d1844-3638-44dc-824c-14f02e0cc009",
"name":"mostro",
"Office":[
{
"id":"502d1844-b90c-44f5-84c5-14f02e0cc009",
"company_id":"502d1844-3638-44dc-824c-14f02e0cc009",
"region":"Emilia-Romagna",
"city":"Rozzemilia",
"address":"-",
"phone":"-",
"legal_office":true
}
],
"CompanyPersonTask":[
{
"company_id":"502d1844-3638-44dc-824c-14f02e0cc009",
"person_id":"2",
"task_id":"1"
}
]
},
"Person":{
"id":"2",
"first_name":"Carlo",
"last_name":"Giusti",
"home_address":"Russi",
"job_address":null,
"phone":null,
"fax":null,
"mail":null,
"full_name":"Giusti Carlo",
"OfficePersonTask":[
],
"CompanyPersonTask":[
{
"company_id":"502d1844-3638-44dc-824c-14f02e0cc009",
"person_id":"2",
"task_id":"1"
}
]
},
"Task":{
"id":"1",
"short_name":"Proprietario",
"full_name":null,
"info":null,
"OfficePersonTask":[
],
"CompanyPersonTask":[
{
"company_id":"502d1844-3638-44dc-824c-14f02e0cc009",
"person_id":"2",
"task_id":"1"
}
]
}
}
]
}
That is created by this method, inside CompanyPersonTask model:
public function getCompaniesByRegion($region){
$this->recursive = 2;
return $this->find('all');
}
but I want my json to be formatted like this:
{
"Companies":[
{
"Company":{
"id":"502d1844-3638-44dc-824c-14f02e0cc009",
"name":"mostro",
"Office":[
{
"id":"502d1844-b90c-44f5-84c5-14f02e0cc009",
"company_id":"502d1844-3638-44dc-824c-14f02e0cc009",
"region":"Emilia-Romagna",
"city":"Rozzemilia",
"address":"-",
"phone":"-",
"legal_office":true
}
]
},
"Person":{
"id":"2",
"first_name":"Carlo",
"last_name":"Giusti",
"home_address":"Russi",
"job_address":null,
"phone":null,
"fax":null,
"mail":null,
"full_name":"Giusti Carlo"
}
}
]
}
How can I modify my method?

Use Containable behavior to filter result data.
For more explanation refer this link.

You can check unbindModel in cake php to remove the relation on the fly. This will prevent the data from the unwanted table. Check this.
<?php
$this->Model->unbindModel(
array('associationType' => array('associatedModelClassName'))
);

Related

Laravel - Modify Fetched Data With Pagination

I want to format some column fetched from database but didn't know how. I use Laravel 8.x. Here's the snippet :
GarageController.php
$q = Garage::with('relative')->paginate(15);
return response()->json($q);
the output
{
"data": [
{
"id": 39819,
"name": "john",
"date": "2020-12-20", // i want to format this with date_format()
"relative": {
"rid": 912039,
"rname": "ROV" // and i just want this value instead of all columns
}
},
{
"id": 38178,
"name": "danny",
"date": "2020-12-20", // and this too
"relative": {
"rid": 182738,
"rname": "YIV"
}
}
],
"links": {
.....
},
"meta": {
....
}
}
The model, the garage have is belong to relative (relative could have many garage).
public function relative() {
return $this->belongsTo(Relative::class, 'relative', 'rid');
}
I tried accessor, but it didn't change anything
public function getDateAttributes($value) {
return date_format(date_create($value), 'd/m/Y');
}
Any help would be appreciated. Thank you.
I think you just need to remove s from the getDateAttributes
From
public function getDateAttributes($value) {
return date_format(date_create($value), 'd/m/Y');
}
To
public function getDateAttribute($value) {
return date_format(date_create($value), 'd/m/Y');
}

how to filter JSON data rows

I want to show data that include in specified categories. but the white page is my result
the function should search in json to display the rows that contain in specified categories.
for example: i need to display the users that contain cat 1 and cat 2 .
the result should list all name in rows that contain the specified category like this:
Steve
Stafin
Sara
if you needed any other question or problem in my describe, just tell me to let you know.
I appreciate your tips
users.json:
{"data":[
{
"id":1,
"category_name":"Writers",
"users":{
"data":[
{
"name":"Steve",
"id":"1",
"cat":"1",
"description":{
"data":[
{
"instagram":"steveid"
}
]
}
},{
"name":"Stafin",
"id":"2",
"cat":"2",
"description":{
"data":[
{
"instagram":"stafinid"
}
]
}
},{
"name":"Jack",
"id":"3",
"cat":"3",
"description":{
"data":[
{
"instagram":"jackid"
}
]
}
},{
"name":"Sara",
"id":"3",
"cat":"2",
"description":{
"data":[
{
"instagram":"saraid"
}
]
}
}
]
}
}
]}
php:
$str = file_get_contents('http://localhost/json/users.json');
$json = json_decode($str, true);
function searchArray($searchkey, $searchval, $array) {
foreach ($array as $key => $val) {
if ($val[$searchkey] === $searchval) {
return $val;
}
}
return null;
}
//i didn't know how to describe users for each time in 'do while'
$user = searchArray('id', '3', $json['data'][0]['users']['data']);
$cat = ["1", "3"];
if (in_array($user['cat'], $cat)) {
echo $user['description']['data'][0]['instagram'];
}
the users.json is the json data
This //i didn't know how to describe users for each time in 'do while' is the root of the problem, because you cannot know unless program crawls the array and finds all the id's before it even starts looking for the cats.
This snippet will give the answer to the specific problem in this question.
foreach ($json['data'][0]['users']['data'] as $row) {
if (in_array($row['cat'],[1,2])) {
echo $row['name'],"\n";
}
}
It is unclear what other "queries" the function will need to answer. I leave it to you to construct a function that will handle the necessary cases.

Recursive menu in laravel

I am building a recursive menu in the following way:
public static function tree()
{
return static::with(implode('.', array_fill(0, 100, 'children')))->where('parent_id', '=', '0')
->join('company_components', 'id', '=', 'company_components.component_id')
->where('company_components.company_id', '=', auth('api')->user()->with('company')->first()->company_id)
->orderBy('id')
->get();
}
I get something like this:
[
{
"id":1,
"parent_id":0,
"name":"Cuentas",
"url":"",
"icon":"fa fa-user",
"deleted_at":null,
"created_at":"2019-05-26 18:57:02",
"updated_at":"2019-05-26 18:57:02",
"company_id":1,
"component_id":1,
"children":[
{
"id":2,
"parent_id":1,
"name":"Crear Cuenta",
"url":"/account/create",
"icon":"fa fa-circle-o",
"deleted_at":null,
"created_at":null,
"updated_at":null,
"children":[]
}
]
}
]
How can I avoid the empty array of the last elements (which no longer have children)?
Is there any way that the element is not created if "children" if it does not have more children?
$this->cleanMenu($menu);
public function cleanMenu($tree)
{
foreach($tree as $t) {
if (!$t->children->count() > 0) {
unset($t['children']);
} else {
$this->cleanMenu($t->children);
}
}
}
If there is a solution solving from the model without the need to iterate again, it would be phenomenal!
I hope help

Elasticsearch array format for multiple must terms

I'm working on elasticsearch (2.3) and am trying to create a search query. For elasticsearch I need JSON, but I start with a simple php array and encode it to JSON afterwards.
I have a problem with creating the right array format.
This is a small part of the code I'm using:
$params['body']['query']['filtered']['filter']['bool']['must']["term"]['pprCategories']= "category1";
$params['body']['query']['filtered']['filter']['bool']['must_not']['exists']['field'] = "field1";
With an if statement I add a new line:
$params['body']['query']['filtered']['filter']['bool']['must']['term']['country_name']= "country1";
So the total code is:
$params['body']['query']['filtered']['filter']['bool']['must']["term"]['pprCategories']= "category1";
$params['body']['query']['filtered']['filter']['bool']['must_not']['exists']['field'] = "field1";
$params['body']['query']['filtered']['filter']['bool']['must']['term']['country_name']= "country1";
#output
echo "<pre>";
print_r(json_encode($params, JSON_PRETTY_PRINT));
echo "</pre>";
The is the actual result I get from the query I built:
{
"body": {
"query": {
"filtered": {
"filter": {
"bool": {
"must": {
"term": {
"pprCategories": "category1",
"country_name": "country1"
}
},
"must_not": {
"exists": {
"field": "field1"
}
}
}
}
}
}
}
}
However, the desired result would be as follows, i.e. with two elements in the bool/must array:
{
"body": {
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"pprCategories": "category1"
}
},
{
"term": {
"country_name": "country1"
}
}
],
"must_not": {
"exists": {
"field": "field1"
}
}
}
}
}
}
}
}
As you can see the bool/must array contains two conditions instead of just one: pprCategories and country_name are two different 'must' conditions.
Thanks for helping me out!
If you want to add several conditions, you need to understand that bool/must should be an array. You can make your code work like this:
// first create the bool/must array with a single term condition
$params['body']['query']['filtered']['filter']['bool']['must'] = [
[
'term' => [
'pprCategories' => "category1";
]
]
];
// add the must_not condition
$params['body']['query']['filtered']['filter']['bool']['must_not']['exists']['field'] = "field1";
// test your condition
if (...) {
// now add a second constraint to the bool/must array
$params['body']['query']['filtered']['filter']['bool']['must'][] = [
'term' => [
'country_name' => "country1"
]
];
}
I think you should be going this way before taking it to json.
$params['body']['query']['filtered']['filter']['bool']['must'][0]["term"]['pprCategories']= "category1";
$params['body']['query']['filtered']['filter']['bool']['must'][1]["term"]['country_name']= "country1";
$params['body']['query']['filtered']['filter']['bool']['must'][2]["term"]['population_name']= "population1";
$params['body']['query']['filtered']['filter']['bool']['must'][3]["term"]['kilometers_amount']= "55145";

Accessing Data in Array

I retrieved data from my database like below and the array response. I am trying to access products and display the pids. How can get this done.
I retrieved data from my database like below and the array response. I am trying to access products and display the pids. How can get this done.
PS: Beginner with laravel. Please help
$amazon_products = Group::where('id',$auth_data)->with('products')->get();
return $amazon_products
[
{
"id":1,
"title":"Shipment",
"id":1,
"created_at":"2018-04-15 23:55:00",
"updated_at":"2018-04-16 00:10:52",
"products":[
{
"id":3,
"name":"MacBook",
"pid":"050",
"group_id":null,
"user_id":1,
"created_at":"2018-04-16 11:06:08",
"updated_at":"2018-04-16 11:06:08",
"pivot":{
"category_id":1,
"product_id":3,
"created_at":"2018-04-16 11:06:08",
"updated_at":"2018-04-16 11:06:08"
}
}
]
},
{
"id":2,
"title":"Gaming",
"id":1,
"created_at":"2018-04-15 23:55:30",
"updated_at":"2018-04-15 23:55:30",
"products":[
{
"id":1,
"name":"Samsung",
"pid":"024",
"group_id":null,
"user_id":1,
"created_at":"2018-04-16 00:14:20",
"updated_at":"2018-04-16 05:31:05",
"pivot":{
"group_id":2,
"customer_id":1,
"created_at":"2018-04-16 05:33:08",
"updated_at":"2018-04-16 05:33:08"
}
}
]
}
]
Below is the model for my group
Group
public function products()
{
return $this->belongsToMany('App\Product','group_product','group_id','product_id')
->withTimestamps();
}
List the product pids after eager loading the products:
...->get()->load('products')->lists('products.pid');

Categories