dreamfactory php script post.post_process payload modify - php

Hi I'm using Dreamfactory as REST API backend and I need a PHP script to pre process a POST api request that can modify my received payload from this:
{“Time”:“2018-12-21T07:49:23”,“BME680”:{“Temperature”:20.3,“Humidity”:41.8,“Pressure”:1021.1,“Gas”:286.65}
to this:
{“Time”:“2018-12-21T07:49:23”,“Temperature”:20.3,“Humidity”:41.8,“Pressure”:1021.1,“Gas”:286.65}
How can I acive this with a PHP script ?

First, let's define a helper function which makes the result friendly
function getFriendlyResult(k, input) {
var output = {};
for (var key in input) {
if (key !== k) output[key] = input[key];
}
for (var innerKey in input[k]) output[innerKey] = input[innerKey];
return output;
}
and you can call it like:
getFriendlyResult(“BME680”, {“Time”:“2018-12-21T07:49:23”,“BME680”:{“Temperature”:20.3,“Humidity”:41.8,“Pressure”:1021.1,“Gas”:286.65});
EDIT
To achieve this in PHP, you can call json_decode and pass your JSON, like
$resultArray = json_decode($input, true);
and then implement the same algorithm in PHP as I described above in Javascript.
EDIT
This is an untested implementation in PHP:
function getFriendlyResult($k, $input) {
$output = array();
foreach ($input as $key => $value) {
if ($key !== $k) $output[$key] = $value;
}
foreach ($input[$k] as $innerKey => $innerValue) {
$output[$innerKey] = $innerValue;
}
return $output;
}
$result = json_decode($yourJSON, true);

Related

How to get index of array of object without using loop in PHP

I need to get index of from array of objects without using loop as per the key name using PHP. Here I am explaining my code below.
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
$key = array_search('Jack', $arr);
echo $key;exit;
Here my code does not give any output. By using some key name I need the index of that object present inside array and also I dont want to use any loop. I need Is ther any PHP in build method so that I can get the result directly.
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
function myfunction($v){return $v['name'];}
echo array_search('Jack', array_map( 'myfunction', $arr ));
<?php
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
//calling function searchByName
$key = searchByName('Jasck',$arr);
if($key != '-1'){
print_r($arr[$key]);
}else{
echo "No match found";
}
//function to chek if the name is there or not.
function searchByName($name, $array) {
foreach ($array as $key => $val) {
if ($val['name'] == $name) {
return $key;
}
}
return '-1';
}
sandbox

adapting Python code into PHP with a reference issue

I'm trying to convert some python code into PHP and I have some difficulties to get the same output.
Actually, I think the problem is about working with a dictionary by reference in Python, more difficult in PHP
Here is my Python code :
import json
from pprint import pprint
a=["/",
"/page1.html",
"/cocktails/receipe/page1.html",
"/cocktails/receipe/page2.html",
"/cocktails/page3.html",
"/article/magazine",
"/article/mood/page1.html"]
def create(path,dictionaryandarray):
#print(path[0],dictionary)
if not path:
return
for ele in dictionaryandarray:
if 'name' in ele and ele['name'] == path[0]:
ele.setdefault('children',[])
if (path[1:]):
create(path[1:],ele['children'])
return
newvalue={'name':path[0]}
if (path[1:]):
newvalue['children']=[]
dictionaryandarray.append(newvalue)
if (path[1:]):
create(path[1:], dictionaryandarray[-1]['children'])
d = []
for i in a:
parts = [j for j in i.split('/') if j != '']
create(parts ,d)
data={'name':'/','children':d}
data=json.dumps(data, indent=4, sort_keys=False)
# pprint(data)
print(data)
and here is my PHP code :
<?php
$rows=[
"page1.html",
"/cocktails/receipe/page1.html",
"/cocktails/receipe/page2.html",
"/cocktails/page3.html",
"/article/magazine",
"/article/mood/page1.html"];
$res = [];
$i=0;
foreach($rows as $row){
$suffix = preg_replace("#https?://[^/]*#", "", $row);
$parts = array_values(array_filter(preg_split("#[/\?]#", $suffix)));
create($parts, $res);
}
$data=['name' => '/','children' =>$res];
$data= json_encode($data, true);
header('Content-Type: application/json');
echo $data;
function create($path, &$res){
if (empty($path))
return;
if (is_null($res))
return;
foreach ($res as $key => $ele){
if (array_key_exists("name", $ele) && $ele['name'] == $path[0]){
if (!array_key_exists("children", $ele)){
$res[$key]['children'] = [];
}
if (count($path) > 1){
create(array_slice($path, 1), $res[$key]['children']);
}
return;
}
}
$newvalue = ["name" => $path[0]];
if (count($path)>1){
$newvalue['children'] = [];
}
$res[] = $newvalue;
if (count($path)> 1){
create(array_slice($path, 1), end($res)['children']);
}
}
what I'm getting is that the $res variable is not populated as python do. I tryed to pass it by reference but get the same problem.
May be there is a way to populate it the same way than Python do, but I don't know how to do.
Any help is appreciated, thanks
PHP's foreach is implemented as call-by-value instead of call-by-reference. So your $ele['children'] assignments are doing nothing. Also, mix doing return with pass-by-reference doesn't help.
You may convert your create() to full call-by-reference style like this:
<?php
function create($path, &$res){
if (empty($path))
return;
if (is_null($res))
return;
foreach ($res as $key => $ele){
if (array_key_exists("name", $ele) && $ele['name'] == $path[0]){
if (!array_key_exists("children", $ele)){
$res[$key]['children'] = [];
}
if (count($path) > 1){
create(array_slice($path, 1), $res[$key]['children']);
}
return;
}
}
$newvalue = ["name" => $path[0]];
if (count($path)>1){
$newvalue['children'] = [];
}
$res[] = $newvalue;
if (count($path)> 1){
create(array_slice($path, 1), end($res)['children']);
}
}
Then you should simply rewrite $res = create($parts, $res); to create($parts, $res);. Things should work.

create dynamic PHP variables from a database

I have an array of names that I'd like to convert to variables. These are names of tests generated from a database (so if a new test is added a new index would be added to the array), our tests are updated on a regular basis so I don't want to hard-code my variables, I want to generate them dynamically.
I've tried this code:
$data = array();
foreach($tests as $v) {
$$v = ${};
array_push($data, $v);
}
My aim is to create the variables dynamically and then add to them for each instance of a test being taken, for example, if 6 people have had one of our instant tests, the variable 'instant' will have the value 6. Am I on the right track? Thanks!
***** UPDATE *****
Im trying to populate a morris.js chart using these variables, everything works when hard coded like so:
$pos = 0;
$neg = 0;
$pen = 0;
$cont = 0;
$misc = 0;
foreach ($data as $item) {
if ($item['result'] === 'Positive') {
$pos++;
} elseif ($item['result'] === 'Negative') {
$neg++;
} elseif ($item['result'] === 'Pending') {
$pen++;
} elseif ($item['result'] === 'Contact the Clinic') {
$cont++;
} else {
$misc++;
}
}
$res = array("Positive"=>$pos, "Negative"=>$neg, "Pending"=>$pen, "Contact the Clinic"=>$cont, "Misc"=>$misc);
$data = json_encode($res);
This gives me:
But im tryng to populate it dynamically from our databases so that if a new test / result set is added I don't have to go in and manually update the code, This is giving me data but no values as im not sure how to dynamically create variables based on the data:
/* Create dynamic variables: */
$vars = array();
foreach($tests as $k => $v) {
array_push($vars, $v);
$$v = extract($vars);
/* Loop through each instance and create a count for all matching instances */
foreach($data as $item){
if($item['name'] === $k){
${$v}++;
}
}
}
Is giving me the labels but with no value:
{"Positive","Negative","Pending","Contact the Clinic","Misc"}
Im currently using the Codeigniter (latest release) Cheers
Well if you use mysqli, you could do it like this:
// your query stuff:
$stmt->query($query);
$data = $stmt->fetch_assoc();
// just for example data contains:
// array('id'=>1,'name'=>'Andy')
foreach($data as $field => $value) {
${$field} = $value;
}
// then output:
echo $name; // should output 'Andy';
What about double dollar ?
You can read it here
http://php.net/manual/en/language.variables.variable.php

How to download STANDARD-XML metadata from RETS using PHRETS

Is there any solution to download STANDARD-XML metadata from RETS using PHRETS?
Currently am able to extract each class metadata as an array using PHRETS function GetMetadataTable and combining & converting to XML format.
But then recently I found difference in single STANDARD-XML metadata(of entire resources and classes) and individual class metadata. Using metadata viewer service RETSMD.com(built on PHRETS) also, the class name getting from STANDARD-XML metadata is different and unable to view the details.
Note: I got the STANDARD-XML metadata via direct browser log-in using credentials, like this
http://rets.login.url/GetMetadata?Type=METADATA-TABLE&Format=STANDARD-XML&ID=0
Anyone faced the same? Is there any solution using PHP?
Thanks in Advance!
I got a solution by modifying PHRETS library.
Added a new function there with following code,
if (empty($this->capability_url['GetMetadata'])) {
die("GetServerInformation() called but unable to find GetMetadata location. Failed login?\n");
}
$optional_params['Type'] = 'METADATA-SYSTEM';
$optional_params['ID'] = '*';
$optional_params['Format'] = 'STANDARD-XML';
//request server information
$result = $this->RETSRequest($this->capability_url['GetMetadata'], $optional_params );
if (!$result) {
return false;
}
list($headers, $body) = $result;
$xml = $this->ParseXMLResponse($body);
Note: Main thing to note is,
$optional_params['ID'] = '*';
Should be '*' instead '0'
If anyone is still unable to retrieve STANDARD-XML data from the CREA DDF data feed using PhRETS v2.x.x, I created a fork to the ./src/Parsers/Search/OneX.php file. You can add the following protected methods to the end of the file:
protected function parseDDFStandardXMLData(&$xml)
{
// we can only work with an array
$property_details = json_decode(json_encode($xml), true);
$retn = array();
if(! empty($property_details['RETS-RESPONSE']['PropertyDetails'])) {
foreach($property_details['RETS-RESPONSE']['PropertyDetails'] as $property_array) {
$retn[] = $this->parseArrayElements(null, $property_array);
}
}
return $retn;
}
protected function parseArrayElements($parent_key, $element)
{
// three possible $element types
// 1. scalar value
// 2. sub-array
// 3. SimpleXMLElement Object
$retn = array();
if(is_object($element)) {
$element = json_decode(json_encode($element), true);
}
if(is_array($element)) {
foreach($element as $node_key => $node) {
$key = $node_key;
if(! empty($parent_key)) {
$key = $parent_key . '|' . $key;
}
if(is_array($node) || is_object($node)) {
$nodes = $this->parseArrayElements($key, $node);
if(!empty($nodes)) {
foreach($nodes as $k => $n) {
$retn[$k] = $n;
}
}
}else{
$retn[$key] = $node;
}
}
}else{
$retn[$parent_key] = $element;
}
return $retn;
}
protected function parseRecordFromArray(&$array, Results $rs)
{
$r = new Record;
foreach($rs->getHeaders() as $key => $name) {
$r->set($name, $array[$name]);
}
return $r;
}
Then replace the parseRecords() method with:
protected function parseRecords(Session $rets, &$xml, $parameters, Results $rs)
{
if (isset($xml->DATA)) {
foreach ($xml->DATA as $line) {
$rs->addRecord($this->parseRecordFromLine($rets, $xml, $parameters, $line, $rs));
}
}elseif (isset($xml->{"RETS-RESPONSE"}->PropertyDetails)) {
$data = $this->parseDDFStandardXMLData($xml);
if(! empty($data)) {
$fields_saved = false;
foreach ($data as $line) {
if(!$fields_saved) {
$rs->setHeaders(array_keys($line));
}
$rs->addRecord($this->parseRecordFromArray($line, $rs));
}
}
}
}
The line, }elseif (isset($xml->{"RETS-RESPONSE"}->PropertyDetails)) { in the latter method does the trick to identify the STANDARD-XML RETS-RESPONSE node and parse the data.
Hope this helps,
Cheers!

Customize json_decode behaviour

I have a JSON string returned by a REST API which follows:
'{"success":true,"product":{"id":"2","category_id":"2","type":"9","name":".ch","description":"","visible":"1","domain_options":"0","stock":"0","qty":"0","autosetup":"2","subdomain":"","owndomain":"0","tax":"0","upgrades":"","sort_order":"0","client_limit":"0","rel":"Product","paytype":"DomainRegular","m_setup":"0.00","q_setup":"0.00","s_setup":"0.00","a_setup":"0.00","b_setup":"0.00","t_setup":"0.00","p4_setup":"0.00","p5_setup":"0.00","d_setup":"0.00","w_setup":"0.00","h_setup":"0.00","m":"0.00","q":"0.00","s":"0.00","a":"0.00","b":"0.00","t":"0.00","p4":"0.00","p5":"0.00","d":"0.00","w":"0.00","h":"0.00","ptype":"DomainsType","options":"3","module":"13","server":"","tlds":null,"periods":{"1":{"product_id":"2","period":"1","register":"17.00","transfer":"17.00","renew":"17.00"}},"tag_name":".ch","tag_description":"","free_domain":"0","product_id":"2","not_renew":"0","epp":true,"ns":["ns3.dfinet.ch","ns4.dfinet.ch","",""],"nsips":"|||","tld":".ch","nsip":["","","",""],"asciimode":true,"app_id":"1","app_ns1":"","app_ns2":"","app_ns3":"","app_ns4":"","app_ip1":"","app_ip2":"","app_ip3":"","app_ip4":"","emails":{"AfterRegistrarRegistration":"28","AfterRegistrarRenewal":"29","AfterRegistrarTransfer":"30","expiringDomain":"54"}},"config":false,"call":"getProductDetails","server_time":1412061849}'
I am trying to convert this to an object and then serve an XML for a soap webservice, what I was doing up to now was
retrieving the result from the rest API -> convert it to object with json_decode($obj)
serve the soap handle() with the converted object
The problem is that, with the following JSON, there are some properties that are "numeric" but not sequential, so the JSON convert the string to an object as follows:
$o = new stdClass();
$o->1 = 'a string';
The problem is that when soap converts object to XML, the node named <1> is an invalid XML markup.
What can I do to "pre-parse" the JSON and convert all of those fake objects to sequentials arrays?
EDIT: Solution based on dmikam answer
I did something cleaner based on the proposed solution:
function fixVariables($variables)
{
if (!is_array($variables) && !is_object($variables)) {
return $variables;
}
foreach ($variables as $k => &$variable) {
if (is_object($variable)) {
if (is_numeric(key($variable))) {
$values = array();
foreach ($variable as $value) {
$values[] = $value;
}
$variable = $values;
unset($values);
}
$this->fixVariables($variable);
} elseif (is_array($variable)) {
if (is_numeric(key($variable))) {
$variable = array_values($variable);
}
$this->fixVariables($variable);
}
}
return $variables;
}
Well, I think you could walk through the resulting parsed object and convert all items that contains numeric indexes into arrays. The function would be something like this:
function fixJsonObject($obj){
if (is_object($obj)){
foreach(get_object_vars($obj) as $key=>$value){
$obj->$key = fixJsonObject($obj->$key);
if (is_numeric($key)){
return (array)$obj;
}
}
}elseif (is_array($obj)){
foreach($obj as $key=>$value){
$obj[$key] = fixJsonObject($obj[$key]);
}
}
return $obj;
}
$json = json_decode('{your: "json"}');
$json = fixJsonObject($json);
I have tested it a bitand looks like it works.

Categories