I am working on a script to upload a JSON file with all our COmpany data from our previous CRM system into a MYSQL database using laravel and i am running into an issue will parsing the json data. I have converted it to an array and run a foreach to upload each company, but it is throwing an error saying it cant convert from array to string. Im unsure what i am doing wrong here, my code is below as well as one company (all are very similar):
public function uploadCompanies()
{
$json = File::get("database/data/accounts.json");
$data = json_decode($json);
foreach($data as $item) {
DB::table('ucustomers')->insert(
[
'dynamics_guid' => $item->accountid,
'customer_code' => $item->mc_unleashedcode,
'customer_name' => $item->name,
'phone_number' => $item->telephone1,
'fax_number' => $item->fax,
'email' => $item->emailaddress1,
'website' => $item->websiteurl,
'override_reps' => [],
'updated_at' => date('Y-m-d H:i')
]
);
}
}
accounts.json
[
{
"#odata.etag": "W/\"145746454\"",
"name": "Core Pharmacy",
"opendeals": 0,
"modifiedon": "2020-08-29T14:11:19Z",
"address1_stateorprovince": "VIC",
"telephone1": "03 9338 1504",
"accountid": "5b46f158-d8ef-e911-a812-000d3a799888",
"websiteurl": null,
"mc_unleashedcode": "C1000096",
"fax": "03 9334 5030"
"emailaddress1": "tullamarine#locale.com.au",
}
]
ERROR
ErrorException
Array to string conversion
at vendor/laravel/framework/src/Illuminate/Support/Str.php:488
484|
485| $result = array_shift($segments);
486|
487| foreach ($segments as $segment) {
> 488| $result .= (array_shift($replace) ?? $search).$segment;
489| }
490|
491| return $result;
492| }
+8 vendor frames
9 app/Unleashed/DynamicsUpload.php:52
Illuminate\Database\Query\Builder::insert()
10 app/Console/Commands/InsertDynamicsData.php:41
App\Unleashed\DynamicsUpload::uploadCompanies()
Your problem is. you try to assign array to string when insert:
public function uploadCompanies()
{
$json = File::get("database/data/accounts.json");
$data = json_decode($json);
foreach($data as $item) {
DB::table('ucustomers')->insert(
[
'dynamics_guid' => $item->accountid,
'customer_code' => $item->mc_unleashedcode,
'customer_name' => $item->name,
'phone_number' => $item->telephone1,
'fax_number' => $item->fax,
'email' => $item->emailaddress1,
'website' => $item->websiteurl,
'override_reps' => [], // error on this one
'updated_at' => date('Y-m-d H:i')
]
);
}
}
there are 2 solution to fixed it.
if you want to insert array to table direct you need to encode it like below:
public function uploadCompanies()
{
$json = File::get("database/data/accounts.json");
$data = json_decode($json);
foreach($data as $item) {
DB::table('ucustomers')->insert(
[
'dynamics_guid' => $item->accountid,
'customer_code' => $item->mc_unleashedcode,
'customer_name' => $item->name,
'phone_number' => $item->telephone1,
'fax_number' => $item->fax,
'email' => $item->emailaddress1,
'website' => $item->websiteurl,
'override_reps' => json_encode([]), // need to encode first
'updated_at' => date('Y-m-d H:i')
]
);
}
}
solution 2 is using model for create:
but first you need to cast override_reps field to array. so laravel will handle it for you
// assume you model name Customer
class Customer extends Model
{
protected $casts =[
'override_reps'=>'array',
];
}
// on controller
public function uploadCompanies()
{
$json = File::get("database/data/accounts.json");
$data = json_decode($json);
foreach($data as $item) {
Customer::create(
[
'dynamics_guid' => $item->accountid,
'customer_code' => $item->mc_unleashedcode,
'customer_name' => $item->name,
'phone_number' => $item->telephone1,
'fax_number' => $item->fax,
'email' => $item->emailaddress1,
'website' => $item->websiteurl,
'override_reps' => [],//lavavel model will encode it before insert
'updated_at' => date('Y-m-d H:i')
]
);
}
}
Related
Working on an element-api.php file from a Craft CMS project. Has a lot of helper functions. I added a category called disciplines. I'm trying to expose the values for each entry.
Here's the whole helper function I'm working on:
// Get all projects, by date, newest first
function getAllProjects() {
$caseStudies = [];
$query = \craft\elements\Entry::find();
$query->section('caseStudies');
$query->orderBy('postDate desc');
foreach ($query->all() as $page) {
$isPublic = $page->public;
$parent = $page->getSection()->handle;
if ($isPublic) {
$serviceData = [];
foreach ($page->modules->all() as $module) {
switch ($module->type->handle) {
case 'service':
$service = $module->service->one();
if ($service) {
$serviceData[] = [
'id' => $service->service->one()->id,
'title' => $service->service->one()->title,
];
}
break;
}
}
$coverColor = [
'r' => $page->coverColor ? $page->coverColor->r : 0,
'g' => $page->coverColor ? $page->coverColor->g : 0,
'b' =>$page->coverColor ? $page->coverColor->b : 0,
];
$caseStudies[] = [
'id' => $page->id,
'title' => $page->title,
'meta' => [
'navigationColor' => $page->navigationColor->value,
'title' => $page->metaTitle ? $page->metaTitle : $page->title,
'description' => $page->metaDescription,
],
'slug' => $page->slug,
'postDate' => date("d-m-Y",$page->postDate->getTimestamp()),
'json' => UrlHelper::url("work/{$page->slug}.json"),
'parent' => $parent,
'headline' => $page->headline,
'client' => $parent === 'caseStudies' ? $page->client->one()->title : null,
'services' => $serviceData,
'discipline' => array_map(function (CategoryModel $category) {
return [
'id' => $category->id,
'title' => $category->title,
];
}, $page->discipline->find()),
'cover' => handelImages($page->cover->all()),
'coverColor' => $coverColor,
'coverVideo' => [
'source' => $page->coverVideo
]
];
}
}
return $caseStudies;
}
Everything works except in the caseStudies array I have added this line:
'discipline' => array_map(function (CategoryModel $category) {
return [
'id' => $category->id,
'title' => $category->title,
];
}, $page->discipline->find()),
which returns the error: Argument 1 passed to {closure}() must be an instance of CategoryModel, instance of craft\elements\Category given
site is at Craft 3.3.15. Element-Api plugin is 2.6.0
'dispiplines' => array_map('strval', $page->discipline->all())
This worked. Found a tag example right on the github page https://github.com/craftcms/element-api
i want when Foreach my Data , For Loop Add Data to Resume Array , exmaple :
Source :
foreach($getusers as $val) // 2record get data from bank But Just 1 record add to Array :(
{
$arr_data =array([
'username'=> $sec->dekey($val->user_username),
'info' => $sec->dekey($val->user_info),
'mobile' => $sec->dekey($val->user_phone),
'code' => $sec->dekey($val->user_code),
'jobside' => $val->user_jobside,
'status' => $val->user_status,
'datetime' => $val->datetime,
'userid' => $val->id,
]);
}
Export :
[{"username":"091584440004","info":"\u062d\u0627\u0646\u06cc\u0647 \u0631\u0648\u062d\u06cc","mobile":"09154479303","code":"091584440004","jobside":"EXPERT","status":"ACTIVE","datetime":"1399/08/13 - 19:26:37","userid":6}]
i want to :
[{"username":"091584440004", info ......]},[{"username":"0921538242",info ......]}, ....
Thanks .
You are overwriting your array instead of adding to it.
To initialise an array, you do:
$arr_data = []
And to append to it:
$arr_data[] = ['new' => 'entry'];
In your example:
$arr_data = [];
foreach($getusers as $val) {
$arr_data[] = [
'username'=> $sec->dekey($val->user_username),
'info' => $sec->dekey($val->user_info),
'mobile' => $sec->dekey($val->user_phone),
'code' => $sec->dekey($val->user_code),
'jobside' => $val->user_jobside,
'status' => $val->user_status,
'datetime' => $val->datetime,
'userid' => $val->id,
];
}
Currently I can get the json data from my excel file with format like this
sample.xlsx
$excel = Importer::make('Excel');
$excel->hasHeader(true);
$excel->load($savePath.$fileName);
$collection = $excel->getCollection();
if(sizeof($collection[1]) == 5)
{
return $collection;
}
else
{
return redirect()
->back()
->with(['errors'=> [0=> 'Please provide date in file according to your format.']])
->with('modal',$modal);
}
output
[{"id":1,"first_name":"j.doe17","last_name":"Jun Doe","email":"j.doe#gmail.com","birthdate":{"date":"1996-09-07 00:00:00.000000","timezone_type":3,"timezone":"Asia\/Taipei"}},{"id":2,"first_name":"j.doe18","last_name":"Jun Doe","email":"jan.doe#gmail.com","birthdate":{"date":"1996-09-07 00:00:00.000000","timezone_type":3,"timezone":"Asia\/Taipei"}}]
Now I'm trying to use this code, just insert those json data to my database table > tbl_sampleimport
foreach ($collection->toArray() as $key => $value) {
foreach ($value as $row) {
$insert_data[] = array(
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'email' => $row['email'],
'birthdate' => $row['birthdate'],
'created_at' => now(),
'updated_at' => now(),
);
}
}
DB::table('tbl_sampleimport')->insert($insert_data);
My Table tbl_sampleimport
But this gives me an error like this Illegal string offset 'first_name'
Laravel : v5.8.*
cyber-duck/laravel-excel
use json_decode() to convert into array
$arr = json_decode($collection, true);
foreach($arr as $row) {
$insert_data[] = array(
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'email' => $row['email'],
'birthdate' => $row['birthdate']['date'],
'created_at' => now(),
'updated_at' => now(),
);
}
API result:
php laravel
the article_user and article_title is repeated.
i use transformer to transform my data.
public function transform(ArticleComment $comments)
{
$articleInfo = $comments->article;
$user = UserInfo::select('real_name')->find($articleInfo->created_user_id);
return [
'article_user' => $user->real_name,
'article_title' => $articleInfo->title,
'is_evaluator' => $comments->is_evaluation,
'comment_created_user' => $comments->user,
'created_at' => $comments->created_at,
'comment_content' => $comments->content,
'replied_comment' => $comments->reply,
'replied_user' => $comments->repliedUser,
];
}
}
i want it like this
article_info:{
article_user: "",
article_title: "",
}
article_comment:{
content: "",
is_evaluator: 0,
...
}
how to optimize it ?
what should i do ?
the response
You can use simple arrays to format your response. In your case it should be:
public function transform(ArticleComment $comments)
{
$articleInfo = $comments->article;
$user = UserInfo::select('real_name')->find($articleInfo->created_user_id);
return [
'article_info' => [
'article_user' => $user->real_name,
'article_title' => $articleInfo->title
],
'article_comment' => [
'is_evaluator' => $comments->is_evaluation,
'comment_created_user' => $comments->user,
'created_at' => $comments->created_at,
'comment_content' => $comments->content,
'replied_comment' => $comments->reply,
'replied_user' => $comments->repliedUser
]
];
}
I never used generators in PHP. I understand the way to use it :
Foreach an array to do some tasks for each value like greping a specific line into a big file to remove some caracteres..
What I need :
I need to retrieve all bands from my dabatase. Sure I have the 'limit' argument to don't exceed the PHP's memory (there're 30 000 bands..).
I have to filters values and return a new array to the client into my REST API.
What I want to know :
Is it interesting for me to create a method into a trait called 'generator' to perform the code bellow ?
In all cases, I have to create a new array to return it into my method
$bands = Models\Bands::find($bandsParameters);
$json = [];
foreach ($bands as $band) {
$followers = $band->getFollowers();
$followersArr = [];
foreach ($followers as $follower) {
$followerImage = $follower->getImage();
$followerObj = (object)[
'id' => $follower->id,
'username' => $follower->username,
'image' => $followerImage->url,
'online' => $follower->online,
'createdOn' => $follower->createdOn,
'updatedOn' => $follower->updatedOn,
'lastLogin' => $follower->lastLogin,
];
$followersArr[] = $followerObj;
}
$info = $band->getInfo($bandInfoParameters)->getFirst();
$bandObj = (object)[
'id' => $band->id,
'name' => $band->name,
'style' => $band->styles,
'country' => $band->country,
'summary' => isset($info->summary) ? $info->summary : null,
'followers' => $followersArr,
'createdOn' => $band->createdOn,
'updatedOn' => $band->updatedOn,
'authoredBy' => $band->authoredBy,
'updatedBy' => $band->updatedBy,
];
$json[] = $bandObj;
}
return ['key' => 'bands', 'value' => $json];