I have a table named user. The id is generated on the fly.
I have a HABTM table. I am trying to insert a record during the user registration. For some reason I can't get the user's id and the user_id to match.
This looks correct, even my array reflects the right information, but the actual data stored is not right.
code:
$this->request->data['User']['id'] = String::uuid();
$this->request->data['Company']['Company'][0]['user_id'] = $this->request->data['User']['id'];
returned array:
Array
(
[User] => Array
(
[email_address] => asdf#asdf.com
[id] => 4fc9a939-3e24-4c79-85d1-6c28e4ca782d
)
[Company] => Array
(
[Company] => Array
(
[0] => Array
(
[id] => 4fc9a939-1840-4c1b-8bd2-6c28e4ca782d
[company_id] => 4fc990dd-edb0-4559-bb7b-6a00e4ca782d
[user_id] => 4fc9a939-3e24-4c79-85d1-6c28e4ca782d
)
)
)
)
So it appears that it would work based on the array I got, but it doesn't save like that. Help is much appreciated.
Maybe because cake autogenerates id to UUID (when field is string and length is 36) take a look at CakePHP API - Model->save()
Related
I'm having trouble with putting this question to words so ill just use a simple example, hope the title sortof got my problem across.
I'm creating a blog site where I can create blogposts and people can post comments. This is all saved in JSON except for login details which are saved in MySQL.
Now saving the blogposts go fine but I'm now trying to save comments.
Lets say the blogpost array looks like this:
Array
(
[0] => Array
(
[id] => 0
[title] => first blogpost
[content] => blogpost text
)
[1] => Array
(
[id] => 1
[title] => second blogpost
[content] => blogpost 2 text
)
)
Now someone writes a comment on 'second blogpost', I save it into an array like this(user taken from MySQL):
Array
(
[user] => myusername
[comment] => first post was better!
)
Now I want to merge them like this:
Array
(
[0] => Array
(
[id] => 0
[title] => first blogpost
[content] => blogpost text
)
[1] => Array
(
[id] => 1
[title] => second blogpost
[content] => blogpost 2 text
[comments] => Array
(
[user] => myusername
[comment] => first post was better!
)
)
)
I tried searching for a while and I'd expect this to be somewhere on the site already but I can't find it. I tried a couple variations of array_push and array_merge but it always ended up replacing the relevant blogpost instead of adding onto it.
EDIT: Someone noted the new array can't just float around, I think it's better now.
If you had any related key between posts and comments ( like having post_id in comment array ) that would make more sense to merge/put them.
I assume that's your blogpost
Array
(
[0] => Array
(
[id] => 0
[title] => first blogpost
[content] => blogpost text
)
[1] => Array
(
[id] => 1
[title] => second blogpost
[content] => blogpost 2 text
)
)
And your comments should be like:
Array
(
[user] => myusername
[comment] => first post was better!
[post_id] => 1
)
That way, you would be able to find the matched blogpost.
But, outside of your data structure, here is an example to merge an item into an element of an array of array.
A nested loop example.
foreach($posts as &$post){
foreach($comments as $comment){
if($post['id'] == $comment['post_id']){
$post['comments'][] = $comment;
}
}
}
the key here is sending each reference of the element into loop by &$post and then just manipulate them in loop.
Working with indexed arrays. (Like you already have index names as post_id and a comments index as an empty array)
foreach($comments as $comment){
$posts[$comment['post_id']]['comments'][] = $comment;
}
When the blogpost is updated, I assume you can get the id of that blogpost.
Then you can check if your data structure already has a key "comments". If it does not, add the key and create an array containing the comment and the user as the first array.
If it already exists, add a new array with the user and the comment so that there can be multiple comments for each blogpost.
For example using array_map:
$blogPosts = array_map(function ($blogPost) use ($blogPostId, $comment) {
if ($blogPost["id"] === $blogPostId) {
isset($blogPost["comments"]) ? $blogPost["comments"][] = $comment : $blogPost["comments"] = [$comment];
return $blogPost;
}
return $blogPost;
}, $blogPosts);
Php demo
So I fixed it after a bit of thinking
This is the final structure:
Array
(
[0] => Array
(
[id] => 0
[title] => 1st post
[content] => 1st post works!
[date] => 21-01-2019
[comments] => Array
(
[0] => Array
(
[user] => Me
[comment] => hey 1
[date] => 12:02 21-01-2019
)
[1] => Array
(
[user] => Me
[comment] => hey 2
[date] => 12:03 21-01-2019
)
)
)
)
I added a timestamp because of a suggestion here. It's also a simplified version of what I actually use, I tried adding many more comments and on multiple posts which both work.
This is the code, I should mention the ID is in the URL and it's saved as JSON:
$filename = file.json;
$currentArray = json_decode(file_get_contents($filename), true);
$comment = $_POST['comment'];
$username = $_SESSION['username'];
$date = date("H:i d-m-Y");
$id = $_GET['id'];
Pretty straightforward so far, here is how the array is created:
$currentArray[$id]["comments"][] = array (
'user' => $username,
'comment' => $comment,
'date' => $date
);
[$id] saves it to the correct post, ["comments"] saves it to the comments key(or creates it) and the last [] gives every comment a different index inside the ["comments"].
$newJSON = json_encode($currentArray, JSON_PRETTY_PRINT);
file_put_contents($filename, $newJSON);
And lastly encoding it and saving it to JSON.
Hope this helps someone.
This question is more of like requiring an architecture and correct approach, then actual code.
Stating it so that people shouldn't flag it as "We cannot code for you..." etc.
I get a response from the API in JSON which I converted to an associated array using json_decode as:
Array
(
[statusCode] => 200
[data] => Array
(
[objects] => Array
(
[0] => deals
[1] => contacts
[2] => accounts
)
[deals] => Array
(
[0] => dealName
[1] => ApprovedBy
[2] => ApprovedDate
[3] => CloseDate
)
[contacts] => Array
(
[0] => contectName
[1] => email
[2] => firstName
[3] => lastName
)
[accounts] => Array
(
[0] => accountName
[1] => creationDate
[2] => ApprovedDate
[3] => accountNumber
)
)
)
So the structure is as:
In response's data array against key "objects", I have an array of objects i.e deals, contacts, accounts.
And for each element in the objects array as the key, an array of fields exist.
I have to show the objects in a drop down say "Objects" and upon selection of a value say "deals" I want to show elements of deals array in a second drop-down "Fields".
[DONE] Also for the options in the dropdowns, values should be the same as actual elements and not numeric values.
json_decode(string, true) gives associated array but with numeric keys. So keys should be same as their associated values like:
[deals] => deals
[contacts] => contacts
[accounts] => accounts
In the view, I have a table with a number of rows, each row having its own pair of these drop-downs.
If each row has its own drop-down, then I also have to take care avoiding updating second drop-down in wrong places. As each drop-down is an array of objects[] & object_fields[], should I use the index of this array in DOM, get next sibling in DOM, or to assign a unique id to each row for the population of correct drop-down at correct row?
How should I achieve these, what should be the correct way?
I cannot use ajax/getJson() as to reduce the number of requests to API and I do have all the required data available. Just need to use it but needed meticulous approach regarding architecture.
Should I pass on Json object to view and process it in javascript in view? Will this be a better approach?
Thanks
UPDATE:
Point 2 of the question is DONE.
I am getting data from an api (that I cannot query agains, just get lump of data), and then I need to query against those data like I would do using database. Only It would be great if I could do it recursively.
Data example
[0] => Array
(
[id] => 1
[url] => https://domain.com/api/1.0/item/1/
[name] => some_item
[category] => some category
[created_by] => Array
(
[id] => 1
[screen_name] => tomino
)
[current_user_domain_access] => Array
(
[is_active] => 1
[is_administrator] => 1
)
[alerts_enabled] => 0
)
(much shortened version)
I receive an array of objects like that and then I need to select/filter/search by values.
Something like this
SomeModel::find(['category'=>'some category','current_user_domain_access' => ['is_administrator' => 1]]);
Is that something that would be possible in PHP? I was thinking about flattening the array, but then there might be key conflicts
1) select data : You can select data by (array_name->id),(array_name->url) and so on...
2)Filter : add conditions according to requirement
3)search : in_array(),array_search
I am trying to make pretty query result like doctrine, and other ORM
for example with relational table article and article_category.
i want to get query result like this :
Array
(
[0] => Array
(
[id] => 1
[title] => I am article title
[slug] => i-am-article-title
[category] => Array
(
[id] => 1
[name] => Category Name
[slug] => category-name
)
)
[1] => Array
(
[id] => 2
[title] => How to coding
[slug] => how-to-coding
[category] => Array
(
[id] => 4
[name] => Tutorial Area
[slug] => tutorial-area
)
)
)
i know this is basic, but i am want to know for create that result in very simple way.
thanks for all advice
UPDATED.
for to get that result, I am change using eloquent laravel framework.. . :)
No, you can't get this information in this way directly from your database if you are using a Relational Database like MySQL or PostgreSQL
You can get the effect you wish in two queries and insert the subquery array to your result array, or you can have a different table for your categories and do a JOIN with SQL.
As a note, other database systems return just what you asked, consider switching to MongoDB (a No-SQL solution) it returns an object just like you wished
I have a following return value from Yii framework query, using the methods and classes built in Yii:
Array
(
[0] => Array
(
[id] => 1
[title] => Developer
)
[1] => Array
(
[id] => 2
[title] => Tester
)
)
I would like to (using nothing but Yii), rearange this like:
Array
(
[1] => Developer
[2] => Tester
)
Meaning, I will not group the results in a specific index of the array, and I will enlist them all in one array, AND my key/indexes will represent the value of ID field from my table, and value of those keys will be values from my "role" field from my table.
Is this possible and how?
You can use the following method, defined here:
CHtml::listData($yourArray, 'id', 'title');