How to read 2 dimensional array data using Google Sheets API? - php

i'm new to Google Sheets API,
currently i am develop a system to send data to google sheets.
And while im trying to send the data, it shows error like: Invalid values [0][0]
Below is my code line.
`
$client = getClientAuth();
$spreadsheet_ID = $this->spreadsheet->spreadsheetId;
$range = "Sheet1";
$values = $this->sheetData;
$this->service = new Sheets($client);
$body = new ValueRange([
'majorDimension' => 'ROWS',
'values' => [array_map(function($nv) {
return (is_null($nv)) ? "" : $nv;
},$values)]
]);
$params = ['valueInputOption' => 'RAW'];
$insert = ['insertDataOption' => 'INSERT_ROWS'];
//executing the request
$data = $this->service->spreadsheets_values->append($spreadsheet_ID, $range,
$body, $params, $insert);
return $data;
`

From your error message and your showing script, I thought that in your situation, $values might be a 2-dimensional array. I think that if $values is a 1-dimensional array, your script works. And also, please include 'insertDataOption' => 'INSERT_ROWS' in $params. So, in this case, how about the following modification?
From:
$body = new ValueRange([
'majorDimension' => 'ROWS',
'values' => [array_map(function($nv) {
return (is_null($nv)) ? "" : $nv;
},$values)]
]);
$params = ['valueInputOption' => 'RAW'];
$insert = ['insertDataOption' => 'INSERT_ROWS'];
//executing the request
$data = $this->service->spreadsheets_values->append($spreadsheet_ID, $range,
$body, $params, $insert);
To:
$body = new ValueRange([
'majorDimension' => 'ROWS',
'values' => array_map(function($row) {
return array_map(function($col) {
return (is_null($col)) ? "" : $col;
}, $row);
}, $values)
]);
$params = ['valueInputOption' => 'RAW', 'insertDataOption' => 'INSERT_ROWS'];
$data = $service->spreadsheets_values->append($spreadsheet_ID, $range, $body, $params);
or
$body = new Google_Service_Sheets_ValueRange([
'majorDimension' => 'ROWS',
'values' => array_map(function($row) {
return array_map(function($col) {
return (is_null($col)) ? "" : $col;
}, $row);
}, $values)
]);
$params = ['valueInputOption' => 'RAW', 'insertDataOption' => 'INSERT_ROWS'];
$data = $service->spreadsheets_values->append($spreadsheet_ID, $range, $body, $params);
Note:
When the arrow function is used, I think that the following modification can be used.
From
'values' => array_map(function($row) {
return array_map(function($col) {
return (is_null($col)) ? "" : $col;
}, $row);
}, $values)
To
'values' => array_map(fn($row) => array_map(fn($col) => (is_null($col)) ? "" : $col, $row), $values)

Related

Change response format of REST API

I'm working on my REST API responses with PHP.
Here is my backend that generates the responses:
$query = $this->db->query("SELECT some_params from some_table ");
$result = $query->result();
foreach($result as $row){
$obj[] = array(
'title' => $row['title'],
'price' => $row['price'],
);
}
print_r(json_encode($obj));
and with that I have the following response: an array of json objects
[
{
"title":"Marketing",
"price":"0"
},
{
"title":"SAP B1",
"price":"10"
}
]
What I would like to do is return a new object, something like this:
{
"apiVersion": "2.0",
"data": {
{
"title":"Marketing",
"price":"0"
},
{
"title":"SAP B1",
"price":"10"
}
}
}
Does anyone have any idea how I could implement this? thanks!
You can easily have a class or function to do that for you. Some thing like below should help,
// provided you are using php > 7 . otherwise parmas
// can become $data, $apiversion ( without typecasting )
function api_reponse(array $data, string $apiVersion)
{
return json_encode([
'apiVersion' => $apiVersion,
'data' => $data
])
}
You can then use,
$query = $this->db->query("SELECT some_params from some_table ");
$result = $query->result();
foreach($result as $row){
$obj[] = array(
'title' => $row['title'],
'price' => $row['price'],
);
}
print_r( api_response($obj, '2.0') );

PHP SoapClient not getting substructures

I'm trying to get the response of A SOAP Service, but I can't get the subcollections data.
When I call the ws method using a soap client software I get the next response:
<WSGLMSuit.METHODNAME xmlns="http://tempuri.org/">
<Sdtpolizadetalle>
<Empresa>1</Empresa>
<DscEmpresa>TEST</DscEmpresa>
<Rama>22</Rama>
<DscRama>COMBINADO FAMILIAR</DscRama>
<Poliza>000000</Poliza>
<DscRiesgo/>
<InicioVigencia>2019-03-18</InicioVigencia>
<FinVigencia>2019-09-18</FinVigencia>
<Productor>3311</Productor>
<NombreProductor>TEST</NombreProductor>
<Tomador>
<CodTomador>336028</CodTomador>
<NombreTomador>TEST</NombreTomador>
<Domicilio>SAAVEDRA 1174 Dpto. 0</Domicilio>
<Localidad>TRES ARROYOS</Localidad>
<CodigoPostal>7500</CodigoPostal>
</Tomador>
<DscMoneda>PESOS</DscMoneda>
<CantidadCuotas>3</CantidadCuotas>
<Suplementos>
<Suplemento>
<Suplemento>0</Suplemento>
<TipoOperacion>02</TipoOperacion>
<SubTipoOperacion>000</SubTipoOperacion>
<DscOperacion>GENERAL</DscOperacion>
<InicioVigencia>2019-03-18</InicioVigencia>
<FinVigencia>2019-09-18</FinVigencia>
<Prima>2515.95</Prima>
<Premio>3104.68</Premio>
<Cuotas>
<Cuota>
<NroCuota>1</NroCuota>
<Vencimiento>2019-03-18</Vencimiento>
<Estado>Pagada</Estado>
<Importe>519.68</Importe>
<NroCupon>1</NroCupon>
</Cuota>
<Cuota>
<NroCuota>2</NroCuota>
<Vencimiento>2019-04-18</Vencimiento>
<Estado>Vencida</Estado>
<Importe>517.00</Importe>
<NroCupon>2</NroCupon>
</Cuota>
<Cuota>
<NroCuota>3</NroCuota>
<Vencimiento>2019-05-18</Vencimiento>
<Estado>Impaga</Estado>
<Importe>517.00</Importe>
<NroCupon>3</NroCupon>
</Cuota>
</Cuotas>
</Suplemento>
</Suplementos>
</Sdtpolizadetalle>
<Sesionexpirada>false</Sesionexpirada>
</WSGLMSuit.METHODNAMEResponse>
So, I made a function in PHP with SoapClient class to make same request and get the result parsed as JSON but it doesn't giving me the "Suplementos" collection and its data.
{
"Sdtpolizadetalle": {
"Empresa": 1,
"DscEmpresa": "TEST",
"Rama": 22,
"DscRama": "COMBINADO FAMILIAR",
"Poliza": 129031,
"DscRiesgo": "",
"InicioVigencia": "2019-03-18",
"FinVigencia": "2019-09-18",
"Productor": 3311,
"NombreProductor": "TEST",
"Tomador": {
"CodTomador": 336028,
"NombreTomador": "TEST",
"Domicilio": "SAAVEDRA 1174 Dpto. 0",
"Localidad": "TRES ARROYOS",
"CodigoPostal": "7500"
},
"DscMoneda": "PESOS",
"CantidadCuotas": 3,
"Suplementos": {} // <--- HERE IS THE ISSUE
},
"Sesionexpirada": false
}
The PHP function is:
$wsdl = "http://wsdlservice.org?wsdl";
$params = $request->getParsedBody();
$options = array(
'soap_version' => SOAP_1_2,
'style' => SOAP_DOCUMENT,
'use' => SOAP_LITERAL,
'exceptions' => true,
'trace' => 1,
'cache_wsdl' => WSDL_CACHE_NONE,
'encoding' => 'UTF-8'
);
$soap = new SoapClient($wsdl, $options);
$clientRes = $soap->METHODNAME($params);
return json_encode($clientRes, JSON_PRETTY_PRINT);
Finally I got a solution. I found a function for parsing XML string to Array. So what I do is get the response as XML, save it into a file and parse it with that function. Code better than words:
function xmlToArray($xml, $options = array())
{
$defaults = array(
'namespaceSeparator' => ':',
'attributePrefix' => '#',
'alwaysArray' => array(),
'autoArray' => true,
'textContent' => '$',
'autoText' => true,
'keySearch' => false,
'keyReplace' => false
);
$options = array_merge($defaults, $options);
$namespaces = $xml->getDocNamespaces();
$namespaces[''] = null;
$attributesArray = array();
foreach ($namespaces as $prefix => $namespace) {
foreach ($xml->attributes($namespace) as $attributeName => $attribute) {
if ($options['keySearch']) $attributeName =
str_replace($options['keySearch'], $options['keyReplace'], $attributeName);
$attributeKey = $options['attributePrefix']
. ($prefix ? $prefix . $options['namespaceSeparator'] : '')
. $attributeName;
$attributesArray[$attributeKey] = (string)$attribute;
}
}
$tagsArray = array();
foreach ($namespaces as $prefix => $namespace) {
foreach ($xml->children($namespace) as $childXml) {
$childArray = xmlToArray($childXml, $options);
list($childTagName, $childProperties) = each($childArray);
if ($options['keySearch'])
$childTagName = str_replace($options['keySearch'], $options['keyReplace'], $childTagName);
if ($prefix)
$childTagName = $prefix . $options['namespaceSeparator'] . $childTagName;
if (!isset($tagsArray[$childTagName])) {
$tagsArray[$childTagName] =
in_array($childTagName, $options['alwaysArray']) || !$options['autoArray']
? array($childProperties)
: $childProperties;
} elseif (
is_array($tagsArray[$childTagName]) && array_keys($tagsArray[$childTagName])
=== range(0, count($tagsArray[$childTagName]) - 1)
) {
$tagsArray[$childTagName][] = $childProperties;
} else {
$tagsArray[$childTagName] = array($tagsArray[$childTagName], $childProperties);
}
}
}
$textContentArray = array();
$plainText = trim((string)$xml);
if ($plainText !== '') $textContentArray[$options['textContent']] = $plainText;
$propertiesArray = !$options['autoText'] || $attributesArray || $tagsArray || ($plainText === '')
? array_merge($attributesArray, $tagsArray, $textContentArray) : $plainText;
return array(
$xml->getName() => $propertiesArray
);
}
$params = array('key' => 'value') // params needed to make the request
$options = array(
'trace' => 1,
'exceptions' => true
);
try {
$soap = new SoapClient($url, $options);
$soap->method($params); // replace method name
$xmlResponse = $soap->__getLastResponse();
} catch (Exception $e) {
die(
json_encode(
[
'error' => 'Cannot request to WS. ' . $e->getMessage()
]
)
);
// save the response into an xml file for parse
// it and return its content as json
if (file_put_contents('response.xml', $xmlResponse)) {
$xmlNode = simplexml_load_file($this->tempPath);
$arrayData = xmlToArray($xmlNode);
unlink('response.xml');
return json_encode($arrayData, JSON_PRETTY_PRINT);
} else {
return json_encode(['error' => 'Error saving the response into file.']);
}

Turn a array into a variable for send in PHPMailer

Im trying to turn a array that haves another array from a SQL select into a unique variable to send it for users by PHPMailer, I tried to place the array on variable of PHPMailer so didnt works, thats why Im trying this way that looks a little bit difficult
public static function getUsersByEmail($email) {
$sql = DB::prepare(
"SELECT username FROM users WHERE email=:email ORDER BY id LIMIT 10"
);
$sql->bindParam('email', $email);
$sql->execute();
$accounts = $sql->fetchAll(PDO::FETCH_ASSOC);
return $accounts; // its array
}
public function recoverUsername($email) {
if (User::emailHasAccounts($email) == true) {
$accounts = [User::getUsersByEmail($email)];
$str = implode(",", $accounts); // imploding array
$mail = new Mail([
'email' => $email,
'subject' => SITENAME,
'template' => 'accountslist',
'variables' => json_encode([
'email' => $email,
'accountList' => $str,
'date' => date('d/m/y h:i')
]),
'time' => time(),
'next_attemp' => time(),
'attemps' => 0,
'status' => 0
]);
// $mail->dbInsert();
return true;
} else {
echo "erro";
return false;
}
}
Solution (for PHP 5.5 <)
$accounts = getAccounts();
$rr = array_column($accounts, 'username');
$array = implode(',', $accounts);
$getaccounts = array_map(function ($accounts) {
return $accounts['username'];
}, $accounts);
$var = implode('<br>', $getaccounts);

Zabbix Reading the Api

I'm getting Informations from the Zabbix Api with a PHP library. At the moment I get the "lastvalue" from the json Array:
try {
// connect to Zabbix-API
$api = new ZabbixApi($api_url, $username, $password);
$params = array(
'groupids' => '2',
'real_items' =>TRUE,
'monitored_items' =>TRUE,
'search' => array('name' => 'Disk root used p'),
'selectFunctions' => 'extend',
'output' => 'extend',
'sortfield' => 'name',
'limit' => '1'
);
$trends = $api->itemGet($params); // get data from api
$names = array();
foreach($trends as $trend) { // loop through the returned data
$names[] = $trend->lastvalue;
}
//print_r($names);
} catch(Exception $e) {
// Exception in ZabbixApi catched
echo $e->getMessage();
}
But now I want to get the "lastvalue" plus the "name" of the Item in this Array for example like that: "name"+"lastvalue". How can I get both of them into my array $names[]?
Here is my answer from my comments, hope its what you are looking for!
$trends = $api->itemGet($params);
$names = array();
foreach($trends as $trendKey => $trendValue)
{
$names[$trendKey] = $trendValue;
}
#Test the names array
foreach ($names as $nameKey => $nameValue)
{
print("{$nameKey} = {$nameValue}<br />");
}
Return value:
groupids = 2
real_items = TRUE
...
sortfield = name
limit = 1

PHP - Arrays and Foreach

I searched in Google and consulted the PHP documentation, but couldn't figure out how the following code works:
$some='name=Licensing Module;nextduedate=2013-04-10;status=Active|name=Test Addon;nextduedate=2013-04-11;status=Active';
function getActiveAddons($somet) {
$addons = array( );
foreach ($somet as $addon) {
if ($addon['status'] == 'Active') {
$addons[] = $addon['name'];
continue;
}
}
return $addons;
}
echo (count( getActiveAddons( $some ) ) ? implode( '<br />', getActiveAddons( $some ) ) : 'None');
The code always echo's None.
Please help me in this.
I don't know where you got this code from but you've initialized $some the wrong way. It is expected as an array like this:
$some = array(
array(
'name' => 'Licensing Module',
'nextduedate' => '2013-04-10',
'status' => 'Active'
),
array(
'name' => 'Test Addon'
'nextduedate' => '2013-04-11',
'status' => 'Active'
)
);
I guess the article you've read is expecting you to parse the original string into this format.
You can achieve this like this:
$string = 'name=Licensing Module;nextduedate=2013-04-10;status=Active|name=Test Addon;nextduedate=2013-04-11;status=Active';
$result = array();
foreach(explode('|', $string) as $record) {
$item = array();
foreach(explode(';', $record) as $column) {
$keyval = explode('=', $column);
$item[$keyval[0]] = $keyval[1];
}
$result[]= $item;
}
// now call your function
getActiveAddons($result);
$some is not an array so foreach will not operate on it. You need to do something like
$some = array(
array(
'name' => 'Licensing Module',
'nextduedate' => '2013-04-10',
'status' => 'Active'
),
array(
'name' => 'Test Addon',
'nextduedate' => '2013-04-11',
'status'=> 'Active'
)
);
This will create a multidimensional array that you can loop through.
function getActiveAddons($somet) {
$addons = array( );
foreach ($somet as $addon) {
foreach($addon as $key => $value) {
if ($key == 'status' && $value == 'Active') {
$addons[] = $addon['name'];
continue;
}
}
}
return $addons;
}
First, your $some variable is just a string. You could parse the string into an array using explode(), but it's easier to just start as an array:
$some = array(
array(
"name" => "Licensing Module",
"nextduedate" => "2013-04-10",
"status" => "Active",
),
array(
"name" => "Test Addon",
"nextduedate" => "2013-04-11",
"status" => "Active",
)
);
Now, for your function, you are on the right track, but I'll just clean it up:
function getActiveAddons($somet) {
if (!is_array($somet)) {
return false;
}
$addons = array();
foreach ($somet as $addon) {
if ($addon['status'] == 'Active') {
$addons[] = $addon['name'];
}
}
if (count($addons) > 0) {
return $addons;
}
return false;
}
And finally your output (you were calling the function twice):
$result = getActiveAddons($some);
if ($result === false) {
echo "No active addons!";
}
else {
echo implode("<br />", $result);
}

Categories