I'm using Laravel 5.7. and GuzzleHttp 6.0 to get API response
from endpoint
I'm passing query data from Blade form to this function.
public static function prhmulti($multisearch, $start ,$end)
{ $city = $multisearch['city'];
$client = new Client([
'base_uri' => 'https://avoindata.prh.fi/tr/',
'query' => [
'totalResults' => 'true',
'maxResults' => '1000',
'registeredOffice'=> $city,
'companyForm'=>'OY',
'companyRegistrationFrom'=>$start,
'companyRegistrationTo'=>$end,
],
'defaults'=>[
'timeout' => 2.0,
'cookies' => true,
'headers' => [
'content-type' => 'application/json',
'User-Agent' =>"GuzzleHttp/Laravel-App-5.7, Copyright MikroMike"
]]]);
$res = $client->request('GET','v1');
$ResData = json_decode($res->getBody()->getContents());
dd ($ResData) gives all data from API response.
But I am not able to return JSON back to other function
return $this->multisave($ResData);
public static function multisave (data $ResData)
This will parse JSON and
{
foreach ($data->results as $company) {
$name = $company->name;
$Addr = $company->addresses;
$businessId = $company->businessId;
$companyForm = $company->companyForm;
$registrationDate = $company->registrationDate;
foreach ($company->addresses as $Addr) {
$city = $Addr->city;
$postcode = $Addr->postCode;
$street = $Addr->street;
}
}
save data to Mysql.
$NewCompany = new Company();
$NewCompany = Company::updateOrCreate($array,[
[ 'vat_id', $businessId],
[ 'name', $name],
[ 'form',$companyForm],
[ 'street', $Addr],
[ 'postcode', $postcode],
[ 'city', $city],
[ 'regdate', $registrationDate],
]);
}
IF Parse part and Save part is inside same function code works ok(save only one company),
but I need to separate them because later on it's easier to maintain.
Error which I am getting to return $ResData
" Using $this when not in object context"
Information is in JSON array.
Also foreach part save ONLY one company ?
foreach ($data->results as $company) {
$name = $company->name;
$Addr = $company->addresses;
$businessId = $company->businessId;
$companyForm = $company->companyForm;
$registrationDate = $company->registrationDate;
foreach ($company->addresses as $Addr) {
$city = $Addr->city;
$postcode = $Addr->postCode;
$street = $Addr->street;
}
So : 1) What is best way to create own function for parse JSON
and other for save data to DB?
2) As foreach loop save only one company data, What is
best way to fix it?
Thanks MikroMike.
Resolved my own question for saving companies to db
First get total number inside Array
use for-loop to make counting
use foreach-loop extract information per single company as object.
$data = json_decode($res->getBody()->getContents());
$total = $data->totalResults;
for ($i = 0; $i < $total; $i++){
$NewCompany = new Company();
foreach ($data->results as $company)
{
$name = $company->name;
$businessId = $company->businessId;
$companyForm = $company->companyForm;
$registrationDate = $company->registrationDate;
$array = [];
Arr::set($array, 'vat_id', $businessId);
Arr::set($array, 'name', $name );
Arr::set($array, 'form', $companyForm);
Arr::set($array, 'regdate', $registrationDate);
$NewCompany = Company::updateOrCreate($array,[
[ 'vat_id', $businessId],
[ 'name', $name],
[ 'form',$companyForm],
[ 'regdate', $registrationDate],
]);
}// END OF MAIN FOREACH
}// END OF For loop
}// END OF FUCNTION
} // END OF CLASS
I am working on Yii2. I have developed an API which will save the incoming records from the client. A client can send an image so I am saving its name and then uploading in the folder. Along with the name of the image I am also sending data with it. All the data except the image name are saved. Below is my API call.
public function actionAddnew()
{
$fp = fopen('preinstall.txt', 'w+');
fwrite($fp, file_get_contents('php://input'));
fclose($fp);
$inputs = json_decode(file_get_contents('php://input'));
return PreInstallations::saveAll($inputs);
}
The function saveAll is
public static function saveAll($inputs)
{
$coutner = 0;
$arr_status = [];
foreach ($inputs as $input) {
$s = new PreInstallations;
foreach ((array)$input as $key => $value) {
if ($key != 'image_names') {
if ($s->hasAttribute($key)) {
$s->$key = $value;
}
}
}
$user = Yii::$app->user;
if (isset($input->auth_key) && Users::find()->where(['auth_key' => $input->auth_key])->exists()) {
$user = Users::find()->where(['auth_key' => $input->auth_key])->one();
}
$s->created_by = $user->id;
if (PreInstallations::find()->where(['ref_no' => $input->ref_no])->exists()) {
$arr_status[] = ['install_id' => $input->install_id, 'status' => 2, 'messages' => "Ref # Already exists"];
continue;
}
$s->sync_date = date('Y-m-d H:i:sāā');
if ($s->save()) {
if ($s->pre_install_status == 'Pre Installed') {
Meters::change_status_byinstall($s->meter_msn, Meters::$status_titles[8]);
}
$arr_status[] = ['install_id' => $input->install_id, 'status' => 1];
$coutner++;
if (isset($input->site_images_name)) {
foreach ($input->site_images_name as $img) {
$image2 = new PreInstallationImagesSite;
$image2->image_name = $img->image_name;
$image2->pre_install_id = $s->id;
$image2->save();
}
}
}
else {
$arr_status[] = ['install_id' => $input->install_id, 'status' => 0, 'messages' => $s->errors];
}
}
return ['status' => 'OK', 'details' => $arr_status, 'records_saved' => $coutner];
}
Below part of above code saves the images name
if (isset($input->site_images_name)) {
foreach ($input->site_images_name as $img) {
$image2 = new PreInstallationImagesSite;
$image2->image_name = $img->image_name;
$image2->pre_install_id = $s->id;
$image2->save();
}
}
For testing purpose API call is made from POSTMAN with below details
[{
"ref_no": "20371521444700U",
"meter_msn" :"002999001189",
"billing_msn" : "74516" ,
"latitude": "36.2703169",
"longitude": "78.178266",
"tarrif": "07",
"s_load": "07",
"customer_id" :"37010673625",
"pre_install_status": "Pre Installed",
"site_issues" : "No issue",
"install_id" : "20371521444700U_1521263491",
"created_date": "2018-03-17 10:12:12",
"consumer_name": "HDA PUMPING STATION SEVERAGE UNO.8 LATIFABAD HYD",
"consumer_address" :"HDA PUMPING STATION SEVERAGE UNO.8 LATIFABAD HYD",
"auth_key": "key",// replaced the original auth key with key
"ct_ratio": "200/5",
"ct_ratio_quantity":"4",
"cable_type":"37/83",
"cable_length":"11",
"atb_installed": "Yes",
"meter_type":"L.T.TOU",
"site_images_name":["20371521444700U_1522299780_site_1.jpg"]
}]
When I Send the request I am getting an error
{
"name": "PHP Notice",
"message": "Trying to get property of non-object",
"code": 8,
"type": "yii\\base\\ErrorException",
"file": "E:\\xampp\\htdocs\\inventory-web\\common\\models\\PreInstallations.php",
"line": 137,
"stack-trace": [
"#0 E:\\xampp\\htdocs\\inventory-web\\common\\models\\PreInstallations.php(137): yii\\base\\ErrorHandler->handleError(8, 'Trying to get p...', 'E:\\\\xampp\\\\htdocs...', 137, Array)",
"#1 E:\\xampp\\htdocs\\inventory-web\\api\\modules\\v1\\controllers\\PreinstallationController.php(36): common\\models\\PreInstallations::saveAll(Array)",
"#2 [internal function]: api\\modules\\v1\\controllers\\PreinstallationController->actionAddnew()",
"#3 E:\\xampp\\htdocs\\inventory-web\\vendor\\yiisoft\\yii2\\base\\InlineAction.php(57): call_user_func_array(Array, Array)",
"#4 E:\\xampp\\htdocs\\inventory-web\\vendor\\yiisoft\\yii2\\base\\Controller.php(156): yii\\base\\InlineAction->runWithParams(Array)",
"#5 E:\\xampp\\htdocs\\inventory-web\\vendor\\yiisoft\\yii2\\base\\Module.php(523): yii\\base\\Controller->runAction('addnew', Array)",
"#6 E:\\xampp\\htdocs\\inventory-web\\vendor\\yiisoft\\yii2\\web\\Application.php(102): yii\\base\\Module->runAction('v1/preinstallat...', Array)",
"#7 E:\\xampp\\htdocs\\inventory-web\\vendor\\yiisoft\\yii2\\base\\Application.php(380): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))",
"#8 E:\\xampp\\htdocs\\inventory-web\\api\\web\\index.php(35): yii\\base\\Application->run()",
"#9 {main}"
]
}
The line 137 is $image2->image_name = $img->image_name;.
The Image model is
public function rules()
{
return [
[['pre_install_id'], 'required'],
[['pre_install_id', 'image_upload_flag'], 'integer'],
[['image_name'], 'string', 'max' => 255],
[['pre_install_id'], 'exist', 'skipOnError' => true, 'targetClass' => PreInstallations::className(), 'targetAttribute' => ['pre_install_id' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'pre_install_id' => 'Pre Install ID',
'image_name' => 'Image Name',
'image_upload_flag' => 'Image Upload Flag',
];
}
I must be missing something that I don't know. Any help would be highly appreciated.
I have a large excel document (2000+ lines) that uses the cells to specify a tree structure and I would like to parse that into a .json file. The excel-exported .csv document is formatted as follows, where in the excel file a comma would be an empty cell:
Layer1category1,,,,,
,Layer2category,,,,
...
,,,,Layer5category1,
,,,,,item1
,,,,,item2
,,,,Layer5category2,
,,,,,item1
,,,Layer4category2,,
...
Layer1category2,,,,,
...
Layer1category8,,,,, // this is the last category in the uppermost layer
In summary, Layer n categories are prefaced with n-1 commas and followed by 6-n commas, and rows prefaced with 5 commas are the final layer, which is in the format of a string and has many fields other than its name.
I would like this to be converted to a .json file similar to the following. I use "name" because aside from a name each field is also tied to a lot of statistics that also needs to go into the json file.
{"name" : "Layer1category1",
"children": [
{"name" : "Layer2category1",
"children" : [
{"name" : "Layer3category1"
"children" : [
...
{"name" : "Layer5category1",
"children" : [{"name" : "item1"}, {"name" : "item2"}],}
{"name" : "Layer5category2",
"children" : [{"name" : "item1"}],}
{"name" : "Layer4category2",
"children" : [
...
]}
"name" : "Layer1category2",
"children" : [ ... ]
}
Does anyone have any suggestions for how I can approach this? The csv to json converters I have found do not support multi-layered structures. Thanks!
I faced with the same issue and wrote simple php script:
Input
Level I,Level II,Level III,Level IV,Level V,Level VI,Level VII,Level VIII,,,,,,,,,,,,,,,,,,
Role Profile,,,,,,,,,,,,,,,,,,,,,,,,,
,Development,,,,,,,,,,,,,,,,,,,,,,,,
,,Security,,,,,,,,,,,,,,,,,,,,,,,
,,Cloud,,,,,,,,,,,,,,,,,,,,,,,
,,,Cloud technologies,,,,,,,,,,,,,,,,,,,,,,
,,,,IaaS,,,,,,,,,,,,,,,,,,,,,
,,,,,Amazon Web Service (AWS),,,,,,,,,,,,,,,,,,,,
,,,,,Microsoft Azure,,,,,,,,,,,,,,,,,,,,
,,,,,Google Compute Engine (GCE),,,,,,,,,,,,,,,,,,,,
,,,,,OpenStack,,,,,,,,,,,,,,,,,,,,
Output
{
"Role Profile":{
"Development":{
"Security":{},
"Cloud":{
"Cloud technologies":{
"IaaS":{
"Amazon Web Service (AWS)":{},
"Microsoft Azure":{},
"Google Compute Engine (GCE)":{},
"OpenStack":{}
}
}
}
}
}
}
Code
<?php
$fn = "skills.csv"; // input file name
$hasHeader = true; // input file has header, we will skip first line
//
function appendItem( &$r, $lvl, $item ) {
if ( $lvl ) {
$lvl--;
end( $r );
appendItem( $r[key($r)], $lvl, $item );
} else {
$r[$item] = array();
}
}
$r = array();
if ( ( $handle = fopen( $fn, "r" ) ) !== FALSE ) {
$header = true;
while ( ( $data = fgetcsv( $handle, 1000, "," ) ) !== FALSE ) {
if ( $header and $hasHeader ) {
$header = false;
} else {
$lvl = 0;
foreach( $data as $dv ) {
$v = trim( $dv );
if ( $v ) {
appendItem( $r, $lvl, $v );
break;
}
$lvl++;
}
}
}
}
echo json_encode( $r );
?>