How to Count Nested Child from single table Laravel - php

Relation method
User model:
public function children()
{
return $this->hasMany(self::class, 'referrer_id')->with('children');
}
Controller Method:
$user = User::with('children')->where('id',$this->request->UserId)->get();
Response
{
"status": true,
"status_code": "Success",
"message": true,
"payload": {
"profile": [
{
"id": 1,
"referrer_id": null,
"name": "beciwerugy",
"username": "lahaky",
"email": "figo#mailinator.com",
"children": [
{
"id": 3,
"referrer_id": 1,
"name": "asd",
"username": "asde",
"email": "asda#asd.com",
"children": [
{
"id": 4,
"referrer_id": 3,
"name": "asd",
"username": "asde12",
"email": "as12a#asd.com",
]
}
]
}
]
}
]
}
]
}
}
I want to count all nestedchild at once
Currently im getting all nested child in ther list
but i just want count

Related

PHP remove items from recursive array if id don't match

I'm struggling to remove item from recursive array if parent id don't match. All I want to display separate tree for each tree number. I didn't find any solution with SQL so now I am retrieving top nodes of that tree number and removing array those items don't have that top node ids. I already have tree structure, below I'm providing the structure of array.
{
"196": {
"id": "196",
"username": "test1",
"parent_id": null,
"children": [
{
"id": "197",
"parent_id": "196",
"flower_id": null,
"username": "test1",
"children": []
},
{
"id": "198",
"parent_id": "196",
"flower_id": "1690587",
"username": "test3",
"children": [
{
"id": "213",
"parent_id": "198",
"flower_id": "5197062",
"username": "test33",
"children": []
}
]
},
{
"id": "199",
"parent_id": "196",
"flower_id": "1690587",
"username": "test2",
"children": [
{
"id": "205",
"parent_id": "199",
"flower_id": null,
"username": null,
"children": [
{
"id": "207",
"parent_id": "205",
"flower_id": null,
"username": null,
"children": []
}
]
},
{
"id": "212",
"parent_id": "199",
"flower_id": "6794158",
"username": "gunu",
"children": []
}
]
}
]
}
}
Here is what I'm doing doing
function recursive_unset(&$array, $parentIds = array()) {
foreach ($array as $key => &$value) {
if(!in_array($value['parent_id'], $parentIds)) {
unset($array[$key]);
}
if (is_array($value['children'])) {
$this->recursive_unset($value, $parentIds);
}
}
}
This is how I'm calling this function $data = $this->recursive_unset($array, [198,199]);
Any help is appreciated.
Thanks in advance.

Laravel hasMany relationship custom select result empty

I have tables, users, profiles, contacts. 1 user has 1 profile, 1 profile has many contacts, I want to get profile with filtered contact and selected column (I don't want get all column). I success with coding below
UserController.php
$profile = $user->with(['profile.emails', 'profile.phones'])->first();
User.php
public function profile()
{
return $this->hasOne(Profile::class);
}
Profile.php
public function emails()
{
return $this->hasMany(Contact::class)
->where('type', 'email');
}
public function phones()
{
return $this->hasMany(Contact::class)
->where('type', 'phone');
}
result data like this
{
"username": "user",
"email": "user#mail.com",
"profile": {
"first_name": "Alex",
"last_name": "Ariana",
"emails": [
{
"id": 1,
"profile_id": 1,
"type": "email",
"prefix": "Personal",
"value": "alex#mail.com",
"is_primary": 0,
},
{
"id": 2,
"profile_id": 1,
"type": "email",
"prefix": "Business",
"value": "business#mail.com",
"is_primary": 1,
}
],
"phones": [
{
"id": 3,
"profile_id": 1,
"type": "phone",
"prefix": "45",
"value": "564637345345",
"is_primary": 1,
}
]
}
}
but then I add select on the relation like this
public function emails()
{
return $this->hasMany(Contact::class)
->select([DB::raw('IFNULL(prefix, "Email") AS type'), 'value AS url', 'is_primary'])
->where('type', 'email');
}
public function phones()
{
return $this->hasMany(Contact::class)
->select(['prefix', 'value AS number', 'is_primary'])
->where('type', 'phone');
}
then I got empty contact data like this
{
"id": 1,
"username": "user",
"email": "user#mail.com",
"profile": {
"first_name": "Alex",
"last_name": "Ariana",
"emails": [ ],
"phones": [ ]
}
}
Why this is happen?, if I access from user via hasManyThrough it works, but when I use hasMany, it result empty.

Laravel pass parameter to its distant relationship (translate children)

I have categories with id, parent_id, slug , pivot table category_language which columns are id,category_id,language_id,value
As you can see I can translate parent category, but can't send desired $lang_id to children translations, so each children having all translations
here is what I get:
{
"id": 1,
"parent_id": 0,
"slug": "personal-computers",
"created_at": "2019-12-27 15:05:31",
"updated_at": "2019-12-27 15:05:31",
"children": [
{
"id": 3,
"parent_id": 1,
"slug": "accessories-for-pc",
"created_at": "2019-12-27 15:05:32",
"updated_at": "2019-12-27 15:05:32",
"translations": [
{
"id": 1,
"code": "en",
"name": "English",
"pivot": {
"category_id": 3,
"language_id": 1,
"value": "Acc for PC",
"id": 7
}
},
{
"id": 2,
"code": "ru",
"name": "Русский",
"pivot": {
"category_id": 3,
"language_id": 2,
"value": "Аксессуары для ноутбуков и ПК",
"id": 8
}
},
{
"id": 3,
"code": "ro",
"name": "Romana",
"pivot": {
"category_id": 3,
"language_id": 3,
"value": "aksessuari-dlya-noutbukov-i-pk-ro",
"id": 9
}
}
]
}
],
"translations": [
{
"id": 1,
"code": "en",
"name": "English",
"pivot": {
"category_id": 1,
"language_id": 1,
"value": "PC",
"id": 1
}
}
]
}
Controller:
return Category::with('children')
->with(array('translations'=>function($query) use ($lang_id){
$query->where('language_id',$lang_id);
}))
->where('parent_id',0)->first();
Model
class Category extends Model
{ ..
public function translations()
{
return $this->belongsToMany('App\Models\Translation','category_language', 'category_id' ,'language_id' )->withPivot('value','id');
}
public function children()
{
return $this->hasMany( 'App\Models\Category' , 'parent_id' , 'id' )->with('translations');
}
}
you can add condition in children method
public function children()
{
return $this->hasMany( 'App\Models\Category' , 'parent_id' , 'id' )->with('translations')->where('language_id', 1);
}
Dry7 answer was close to the one I've implemented later, so I upvoted him.
Finally in model I've added: ...->where('language_id',helper_SetCorrectLangIdForQuery());
and function helper_SetCorrectLangIdForQuery is using global helper of Laravel request()->lang . If lang=enz, than it takes default language from another helper.

Laravel - pluck fields from relations

i'm new in laravel and php and now i wanna create a rest api
I have this query:
$questions = Question::with(
array('picture' => function($query){
$query>select('question_id','picture_name')>pluck('picture_name')>all();
},
'user'=>function($query){
$query->select('id','image','name');
}))->get()->toArray();
my query return this json:
{
"questions:": [
{
"id": 1,
"title": "23",
"caption": "last",
"address": "lsdbabfd",
"picture": [
{
"question_id": 1,
"picture_name": "1527484678.jpg"
},
{
"question_id": 1,
"picture_name": "1527485120.jpg"
}
],
"user": {
"id": 1,
"image": "defaultPicture",
"name": "alex"
}
}
]
}
but i want this json:
{
"questions:": [
{
"id": 1,
"title": "23",
"caption": "last",
"address": "lsdbabfd",
"picture": [
"1527484678.jpg",
"1527485120.jpg"
],
"user": {
"id": 1,
"image": "defaultPicture",
"name": "alex"
}
}
]
}
how can i do that?
i already tried to do that with Laravel pluck method and Eloquent Mutators
you can add attribute method
class Question extends Model
{
...
protected $appends = ['pictures'];
public function getPicturesAttribute()
{
return $this->pictures->pluck('picture_id');
}
}

Elasticsearch Updating / Deleting Nested

I've gone through a few examples and documentations and kind find a solution update a nested object in the this result set.
I can add one (if one does not exist)
I can append to it (if one does exist)
Can't figure out how to delete a selected entry.
Is there a method I can use (using the php client) to add an entry if it does not exist / update an entry if it does exist / delete the second entry.
I'm inheriting this problem and am new to Elastic search.
Thanks.
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "products",
"_type": "categories",
"_id": "AUpRjtKZfXI7LIe9OpNx",
"_score": 1,
"_source": {
"name": "Primary",
"description": "Primary Category",
"slug": "Primary",
"created": "2014-12-16 00:25:22",
"parent": [
{
"name": "First One",
"description": "Test",
"id": "ae74ea4e2e865ed3fd60c18a06e69c65",
"slug": "first-one"
},
{
"name": "Second One",
"description": "Testing Again",
"id": "c8dbe5143c8dfd6957fa33e6cea7a0a8",
"slug": "second-one"
}
]
}
}
]
}
}
Do you want to do all three in the same operation?
Deleting the second nested object is achieved through a script which removes the second element:
PUT /products
{
"mappings": {
"categories": {
"properties": {
"parent": {
"type": "nested",
"properties": {
"name": { "type": "string" },
"description": { "type": "string" },
"id": { "type": "string", "index": "not_analyzed" },
"slug": { "type": "string" }
}
}
}
}
}
}
PUT /products/categories/1
{
"name": "Primary",
"description": "Primary Category",
"slug": "Primary",
"created": "2014-12-16 00:25:22",
"parent": [
{
"name": "First One",
"description": "Test",
"id": "ae74ea4e2e865ed3fd60c18a06e69c65",
"slug": "first-one"
},
{
"name": "Second One",
"description": "Testing Again",
"id": "c8dbe5143c8dfd6957fa33e6cea7a0a8",
"slug": "second-one"
}
]
}
POST /products/categories/1/_update
{
"script" : "ctx._source.parent.remove(1)",
"lang": "groovy"
}
GET /products/categories/1
So in PHP code (using the official PHP client), the update would look like:
$params = [
'index' => 'products',
'type' => 'categories',
'id' => 1,
'body' => [
'script' => 'ctx._source.parent.remove(1)',
'lang' => 'groovy'
]
];
$result = $client->update($params);

Categories