How I can update a json column in laravel? - php

This is a sample of data I get from user choices:
id:1,
title: 'foam',
add:'dry',
id:2,
title: 'flavor',
add:'milk'
id:3,
title: 'heat',
add:'hot'
id:1,
title: 'rost',
add:'robosta'
I want to put and sync each title based on user choices: I mean a user can select among 'flavor' title adds like 'milk', 'coconut' or 'banana', and so on.
I use this code but only update one title and the selected choice:
public function add($variation, $id, $title, $add, $quantity = 1)
{
$this->cart->variations()->syncWithoutDetaching([
$variation => [
'quantity' => quantity,
'toppings' => [['id'=> $id], 'title' => $title, 'add' => $add]],
]
]);
}
then I have this result:
[{"id":2," title": "flavor", "add": "milk"}]
while I need:
[{"id": "1", "title": "Flavour", "add": "Milk"},{"id": "2", "title": "Foam", "adds": "Dry"},{"id": "3", "title": "Heat", "adds": "Cold"},{"id": "4", "title": "Roast", "adds": "Robosta"}]
I added id to JSON to sync.
how I can sync or update the selected title and its add?

Related

Laravel groupBy and pluck some values

I am using laravel 8.x and building rest API project.
I am stuck with a query.
I have a table
id
name
type
color
1
Dog
animal
black
2
Dog
animal
yellow
3
Cat
animal
red
4
Cat
animal
white
I want to do something like that,
$animals->groupBy('name')->get()
and hope to get result like,
$animals=[
{
name: "dog",
type: "animal",
colors: ["black", "yellow"]
},
{
name: "cat",
type: "animal",
colors: ["red", "white"]
}
]
Anyone help me?
I will slightly improve the Erik answer.
$animals = Animals::all()->groupBy('name')->map(function($item) {
return [
'name' => $item[0]['name'], // the name always the same
'type' => $item[0]['type'], // if the type not change (as the name)
'colors' => $item->pluck('color')->unique()->toArray(),
];
})->values()->toArray();
I would use Laravel mapToGroups collection method
$data = Animal::get();
$animals = collect($data)->mapToGroups(function ($item) {
return [$item['name'] => $item];
})->map(function ($itemGoup, $name) {
return [
'name' => $name,
'type' => data_get($itemGoup, '0.type'),
'colors' => collect($itemGoup)->pluck('color')->unique()->values()->toArray(),
];
})->values()->toArray();
with output:
[
{
"name": "Dog",
"type": "animal",
"colors": ["black", "yellow"]
},
{
"name": "Cat",
"type": "animal",
"colors": ["red", "white"]
}
]

How can I build an object/array?

I am rather new to PHP so I don't know how to work with these datasets. I make a MySQL select and get back an object like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": "7.70"
},
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 3,
"dailyworkhourssum": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
I want to iterate through this and in the end it should look like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid1": true,
"categorid3": true,
"dailyworkhourssum1": "7.70",
"dailyworkhourssum3": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
What this does is that it merges tow fields together (if they have the same bookingdate )into one so that I can display it in a table without reoccurring dates.
My problem:
I don't know what this type of data is called.
I don't know how to create something like this.
I can add fields to this type of data with $data->newField = example so I think that this is an object.
In JS it's called an object, but in PHP you will use an associative array instead.
In your case, I think, you have an array of associative arrays. It looks like this:
$books = [
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 1,
"dailyworkhourssum" => "7.70"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 3,
"dailyworkhourssum" => "1.2"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-05",
"categoryid" => 3,
"dailyworkhourssum" => "7.70"
]
];
If you wanna merge an arrays with the same "bookingdate" then I recommend you to loop through this array and add its elements to another associative array with bookingdates as keys, and check, in case if there is such key already, then merge the arrays, like this:
$merged = [];
foreach ($books as $book) {
$date = $book['bookingdate'];
if (isset($merged[$date])) {
$merged[$date] = $merged[$date] + $book;
} else {
$merged[$date] = $book;
}
}
I think that it is not a valid code (no time, sorry), but I hope, you cautch the idea.
If you want a 'list' instead of an associative array, than you can do this:
$mergedList = array_values($merged);
Thus you will rid of string keys.
If I understood correctly, you obtain a table with 4 columns an a variable number of rows and you want to transform it to a table with a variable number of columns. For that, using a data structure where every item is different from the previous one can make everything harder than it needs. I'd suggest you use a fixed structure:
// I'm assuming you have a PHP array as starting point
$input = [
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 1,
'dailyworkhourssum' => '7.70',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 3,
'dailyworkhourssum' => '1.2',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-05',
'categoryid' => 3,
'dailyworkhourssum' => '7.70',
],
];
$output = [];
foreach ($input as $data) {
// We'll group by booking date
if (!isset($output[$data['bookingdate']])) {
$output[$data['bookingdate']] = [
'membername' => $data['membername'],
'bookingdate' => $data['bookingdate'],
'categoryid' => $data['categoryid'],
'dailyworkhourssum' => [],
];
}
// A single date may have several daily work hours
$output[$data['bookingdate']]['dailyworkhourssum'][] = $data['dailyworkhourssum'];
}
// We discard array keys (we only needed them to group)
echo json_encode(array_values($output));
[{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": ["7.70", "1.2"]
}, {
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": ["7.70"]
}]
Wherever you consume this JSON you just need to loop the dailyworkhourssum array. You may also want to loop the entire structure before printing the table and keep a counter in order to determine the maximum number of columns so you can draw empty cells where needed (tables are rectangular).

getting relational results from three tables into one nested array

i have googled for solution to my problem but nun helped me.
here i have three tables items, feeds and images. each item has one feed and one or more images.
i have 3 functions. one is to return records from items table the second one receives feeds_id (foreign key in items table) then return records from feeds table. the third function is to return all images related to items_id.
those functions are :
* To get all items in database:
function get_items(){
return $query = Database::getInstance('db')
->table('items')
->columns(
'id',
'items.rowid',
'items.feed_id as feed_id',
'title' )
->findAll();
}
* To get feed data from feeds table :
function get_feeds($id){
return $query = Database::getInstance('db')
->table('feeds')
->eq('id',$id)
->findAll();
}
* To get image data from images table :
function get_images($id){
return $query = Database::getInstance('db')
->table('images')
->columns('items_id','src as image_url',
'title as image_title',
'alt')
->eq('items_id',$id)
->findAll();
}
Then i have the following code to call those function and display the result in jsonformat:
$response['items'] = array();
$response['feeds'] = array();
$response['images'] = array();
foreach ($items = get_items() as $item) {
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
);
foreach ($feeds = get_feeds((int)$item['feed_id']) as $feed) {
$response['feeds'][] = array(
'title' => $feed['title'],
'logo_url' => $feed['logo_url'],
'site_url' => $feed['site_url'],
);
}
foreach ($images = get_images($item['id']) as $image) {
$response['images'][] = array(
'id' => $image['items_id'],
'url' => $image['image_url'],
'thumb' => $_SERVER['SERVER_NAME'] . /myServer/images/thumbs/'. 'thumb_'.basename($image['image_url']),
'title' => $image['image_title'],
'alt' => $image['alt']
);
}
}
echo json_encode($response, JSON_PRETTY_PRINT);
so, my expectation is to get json output like:
"items": [
{
"id": ,
"feed_id":
"title":
"feeds": [
{
"title": ,
"logo_url": ,
"site_url": "
}
]
"images": [
{
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{
....
}
]
}]
i mean each item array should include nested arrays of its related data coming from get_feeds and get_images functions.
instead of that, i get response like :
//here i select two items from my db
"items": [
{ //first_item
"id": ,
"feed_id":
"title":
},
{ //second_item
"id": ,
"feed_id":
"title":
}
],
"feeds": [
{ // feed data for first item
"title": ,
"logo_url": ,
"site_url": "
},
{ // feed data for second item
"title": ,
"logo_url": ,
"site_url": "
}
],
"images": [
{ // image data for first item
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{ // other images data
....
}
]
}]
as you see i am getting output without keeping relation between items, feeds and images, all of them are shown independently.
my queries are fine but i am suspecting error in my foreach statements.
i could fix this issue by joining those tree tables in one query, but i don't want to do that because i need to do validation and other operations to output comes from each table.
i appreciate your help
i found the solution. it is very easy :)
it is just like:
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
'feeds' => array(
)
'images' => array(
)
);

javascript / jquery Accessing JSON array by both name and index

I am very much hoping you can help me with this as I've spent all too much time on this. First, my JSON formatting is unfortunately not very mutable and I have moved it to a number of different formats to support both some jquery and a php-based search. Each time I move it, the search will work and the rest of the site will break or vice-versa.
Is it possible to access a JSON array by both name and index number? Here is my JSON (stored in PHP file and being retrieved & converted successfully to valid JSON):
<?php
$contents = array(
'Song Name #1 by Artist Name #1 (maininfo)' => array(
'contentid' => '1',
'aname' => 'Artist Name',
'sname' => 'Song Name',
'main' => 'core content #1',
'maininfo' => 'url')
),
'Song Name #2 by Artist Name #2 (maininfo)' => array(
'contentid' => '2',
'aname' => 'Artist Name',
'sname' => 'Song Name',
'main' => 'core content #2',
'maininfo' => 'url')
);
?>
My search works when something in the array title is matched on, otherwise it returns no matches so I must leave the array title as-is.
Another part of my project uses jquery and has the following:
parse(jsonobj[0][1]['sname']) //successfully already returning 'Song Name'
The above will ONLY work when the array title is not provided (e.g. 'Song Name #1 by Artist Name #1 (maininfo)' => array( becomes simply array(.
For those curious, file is being converted to JSON using:
var jsonobj;
$.ajax({
url: 'getjson.php',
dataType: "json",
success: function (doc) {
jsonobj = doc;
}
});
On the PHP side, when getjson.php is called the JSON array (above) is loaded in and converted to valid JSON using:
$final = array($final_contents);
header('Content-type: application/json');
echo json_encode($final);
Note: $final_contents is just $contents with an additional header added. See Searching JSON array for values and accessing surrounding keys/values; output as JSON for the PHP I have running specifically.
Thank you in advance.
JavaScript does not support arrays with named indexes. You should encode it as a JSON object instead.
var $contents = {
"Song Name #1 by Artist Name #1 (maininfo)": {
"contentid": 1,
"aname": "Artist Name",
"sname": "Song Name",
"main": "core content #1",
"maininfo": "url"
},{
"Song Name #2 by Artist Name #2 (maininfo)": {
"contentid": 2,
"aname": "Artist Name",
"sname": "Song Name",
"main": "core content #2",
"maininfo": "url"
}
};
Although it would probably be better to arrange it this way (here's a fiddle to demonstrate:
var songs = [
{
"contentid": 1,
"artist": "Artist Name",
"title": "Song Title 1",
"main": "core content #1",
"maininfo": "url"
},
{
"contentid": 2,
"artist": "Artist Name",
"title": "Song Title 2",
"main": "core content #2",
"maininfo": "url"
}
];
Then you can search through your songs list by id, or iterate through to filter on specific field values. For instance to find all songs whose titles start with "Song Title":
var findAllSongs = function(prop, value){
var result = new Array();
for (var i = 0; i < songs.length; i++) {
var song = songs[i];
if (song[prop] && (song[prop] === value || song[prop].search(value) >= 0)){
result.push(song);
}
}
return result;
};
var song = findAllSongs("title","Song Title 2")[0];
alert(song.contentid);
// Outputs "2"
The php equivalent of my json above is:
$songs = array(
array(
"contentid" => 1,
"artist" => "Artist Name",
"title" => "Song Title 1",
"main" => "core content #1",
"maininfo" => "url",
),
array(
"contentid" => 2,
"artist" => "Artist Name",
"title" => "Song Title 2",
"main" => "core content #2",
"maininfo" => "url",
)
);
If you're using PHP 5.4 or higher, you can use the short syntax:
$songs = [
[
"contentid" => 1,
"artist" => "Artist Name",
"title" => "Song Title 1",
"main" => "core content #1",
"maininfo" => "url",
],[
"contentid" => 2,
"artist" => "Artist Name",
"title" => "Song Title 2",
"main" => "core content #2",
"maininfo" => "url",
]
];
Then you can turn it into JSON by using your current method:
json_encode($songs);
You are having array. convert it to json using following code (json_encode) and echo so that jquery can receive it:
$jsonVar = json_encode($contents);
echo $jsonVar;
Update:
Code to call json using ajax is:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
Alternatively you can use shorthand for it:
$.getJSON( "ajax/test.json", function( data ) {
var items = [];
$.each( data, function( key, val ) {
items.push( "<li id='" + key + "'>" + val + "</li>" );
});
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
});
Of course the file being sent should be in json format, that is:
{
"one": "Singular sensation",
"two": "Beady little eyes",
"three": "Little birds pitch by my doorstep"
}
for that you need to convert the array into json.

How would this PHP array look in Javascript?

I got a little lazy and just used PHP to store all these values, I should be using Javascript to do this though. Whats the best way to do the following in Javascript? I would then be using jQuery's .each function to loop through it.
$accessories = array (
array('name' => 'Chrome pull out wire Basket 500 & 600 wide ', 'price' => '60'),
array('name' => 'Chrome shoe rack 2 Tier', 'price' => '95'),
array('name' => 'Chrome Shoe Rack 3 Tier', 'price' => '145'),
array('name' => 'Chrome pull out trouser rack', 'price' => '40'),
array('name' => 'Pull out tie rack', 'price' => '135'),
array('name' => 'Pull Down hanging Rail 450mm to 1190mm width', 'price' => '33.50'),
array('name' => 'Corner Hanging Rail', 'price' => '33.50')
);
JavaScript doesn't have associative arrays, so you'd have to build it as a series of objects in an array.
var accessories = [
{ 'name' : 'Chrome pull out...', 'price' : 60 },
{ 'name' : 'Chrome shoe rack..', 'price' : 95 }
];
You could then cycle over it using $.each as you requested:
$.each( accessories, function(){
alert( this.name );
});
Fiddle: http://jsfiddle.net/jonathansampson/HXwMc/
Quickly Convert PHP Array to JSON
You can get the above structure easily by passing the array through json_encode():
echo json_encode( $accessories );
It would probably look like this:
var array = [
{"name": "Chrome pull out wire Basket 500 & 600 wide ", "price": "60"},
{"name": "Chrome shoe rack 2 Tier", "price": "95"},
{"name": "Chrome Shoe Rack 3 Tier", "price": "145"},
{"name": "Chrome pull out trouser rack", "price": "40"},
{"name": "Pull out tie rack", "price": "135"},
{"name": "Pull Down hanging Rail 450mm to 1190mm width", "price": "33.50"},
{"name": "Corner Hanging Rail", "price": "33.50"}
];
Note that this is an array of objects. JavaScript doesn't have associative arrays, those are objects.
As Jonathan noted, that's an array of objects in Javascript. It would look like this
var accessories = [
{
name: 'hello',
price: 1.00,
},
{
name: 'world',
price: 2.50,
}
]

Categories