Posting an ArrayValue to Firestore from PHP does not work - php

I'm working on a project that is using Google Firestore version 1 beta 1.
However, there was no PHP SDK provided for it, so I have to use the REST API.
I found this guide online that explains exactly how to do that:
https://engineering.flosports.tv/google-cloud-firestore-document-crud-with-php-1df1c084e45b
After going through the guide, I was able to conclude the example worked as I expected.
However, I need to use ArrayValues, and I get the following error when I try to:
string(612) "{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"array_value\" at 'document.fields[1].value': Proto field is not repeating, cannot start list.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "document.fields[1].value",
"description": "Invalid JSON payload received. Unknown name \"array_value\" at 'document.fields[1].value': Proto field is not repeating, cannot start list."
}
]
}
]
}
}
"
I am running the sample file from command line like this:
php index.php
Here is index.php
<?php
include("firestore.php");
use PHPFireStore\FireStoreApiClient;
use PHPFireStore\FireStoreDocument;
$firestore = new FireStoreApiClient(
'XXXXXX', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
);
$document = new FireStoreDocument();
$document->setString('person', 'Jason'); // this works fine
$document->setArray('my-array', array("cats","dogs","birds")); // this does not work
$firestore->addDocument('people', $document);
Here is firestore.php
<?php
namespace PHPFireStore {
class FireStoreDocument {
private $fields = [];
private $name = null;
private $createTime = null;
private $updateTime = null;
/**
Example:
{
"name": "projects/{project_id}/databases/(default)/documents/{collectionName}/{docu
"fields": {
"hello": {
"doubleValue": 3
}
},
"createTime": "2017-10-18T21:27:33.186235Z",
"updateTime": "2017-10-18T21:27:33.186235Z"
}
*/
public function __construct($json=null) {
if ($json !== null) {
$data = json_decode($json, true, 16);
// Meta properties
$this->name = $data['name'];
$this->createTime = $data['createTime'];
$this->updateTime = $data['updateTime'];
// Fields
foreach ($data['fields'] as $fieldName => $value) {
$this->fields[$fieldName] = $value;
}
}
}
public function getName() {
return $this->name;
}
public function setString($fieldName, $value) {
$this->fields[$fieldName] = [
'stringValue' => $value
];
}
public function setDouble($fieldName, $value) {
$this->fields[$fieldName] = [
'doubleValue' => floatval($value)
];
}
public function setArray($fieldName, $value) {
$this->fields[$fieldName] = [
'arrayValue' => $value
];
}
public function setBoolean($fieldName, $value) {
$this->fields[$fieldName] = [
'booleanValue' => !!$value
];
}
public function setInteger($fieldName, $value) {
$this->fields[$fieldName] = [
'integerValue' => intval($value)
];
}
public function setGeopoint($fieldName, $value) {
$this->fields[$fieldName] = [
'geoPointValue' => array(
'latitude' => (float)41.3819409,
'longitude' => (float)-73.5299525
)
];
}
public function get($fieldName) {
if (array_key_exists($fieldName, $this->fields)) {
return reset($this->fields);
}
throw new Exception('No such field');
}
public function toJson() {
return json_encode([
'fields' => $this->fields
]);
}
}
class FireStoreApiClient {
private $apiRoot = 'https://firestore.googleapis.com/v1beta1/';
private $project;
private $apiKey;
function __construct($project, $apiKey) {
$this->project = $project;
$this->apiKey = $apiKey;
}
private function constructUrl($method, $params=null) {
$params = is_array($params) ? $params : [];
return (
$this->apiRoot . 'projects/' . $this->project . '/' .
'databases/(default)/' . $method . '?key=' . $this->apiKey . '&' . h
);
}
private function get($method, $params=null) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $this->constructUrl($method, $params),
CURLOPT_USERAGENT => 'cURL'
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
private function post($method, $params, $postBody) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $this->constructUrl($method, $params),
CURLOPT_HTTPHEADER => array('Content-Type: application/json','Content-Le
CURLOPT_USERAGENT => 'cURL',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postBody
));
$response = curl_exec($curl);
var_dump($response);
curl_close($curl);
return $response;
}
private function put($method, $params, $postBody) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => array('Content-Type: application/json','Content-Le
CURLOPT_URL => $this->constructUrl($method, $params),
CURLOPT_USERAGENT => 'cURL',
CURLOPT_POSTFIELDS => $postBody
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
private function patch($method, $params, $postBody) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => array('Content-Type: application/json','Content-Le
CURLOPT_URL => $this->constructUrl($method, $params),
CURLOPT_USERAGENT => 'cURL',
CURLOPT_POSTFIELDS => $postBody
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
private function delete($method, $params) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_URL => $this->constructUrl($method, $params),
CURLOPT_USERAGENT => 'cURL'
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
public function getDocument($collectionName, $documentId) {
if ($response = $this->get("documents/$collectionName/$documentId")) {
return new FireStoreDocument($response);
}
}
/**
This does not work
*/
public function setDocument($collectionName, $documentId, $document) {
return $this->put(
"documents/$collectionName/$documentId",
[ ],
$document->toJson()
);
}
public function updateDocument($collectionName, $documentId, $document, $documentExi
$params = [];
if ($documentExists !== null) {
$params['currentDocument.exists'] = !!$documentExists;
}
return $this->patch(
"documents/$collectionName/$documentId",
$params,
$document->toJson()
);
}
public function deleteDocument($collectionName, $documentId) {
return $this->delete(
"documents/$collectionName/$documentId", []
);
}
public function addDocument($collectionName, $document) {
return $this->post(
"documents/$collectionName",
[],
$document->toJson()
);
}
}
}
Also, this is the version of PHP I am using:
php -v
PHP 7.1.10-1+ubuntu14.04.1+deb.sury.org+1 (cli) (built: Sep 29 2017 17:33:22) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.1.10-1+ubuntu14.04.1+deb.sury.org+1, Copyright (c)
1999-2017, by Zend Technologies

Using the link provided by #JRLtechwriting, I have gotten this to work.
Here is the link: http://googlecloudplatform.github.io/google-cloud-php/#/docs/google-cloud/v0.53.0/firestore/firestoreclient
From command line on Ubuntu 14.04 I had to do this:
sudo apt-get install php7.1-dev php-pear phpunit libz-dev
sudo pecl install protobuf
sudo pecl install grpc
sudo composer require google/cloud
# append BOTH apache2 php.ini AND command line php.ini with the following:
# extension=protobuf.so
# extension=grpc.so
sudo apachectl graceful
Then I wrote this code:
<?php
require "vendor/autoload.php"; // composer
$path = "/xxx/firebase_auth.json"; // this file is provided by google
$config = array(
"projectId" => "xxx",
"keyFile" => json_decode(file_get_contents($path), true)
);
$firestore = new FirestoreClient($config);
$collection = $firestore->collection('people');
$person = $collection->add([
'person_id' => '3'
]);
$document = $firestore->document('people/'.$person->id());
$firestore->runTransaction(function (Transaction $transaction) use ($document) {
$transaction->update($document, [
['path' => 'person', 'value' => 'Jason'],
['path' => 'my-array', 'value' =>array(
"cats",
"dogs",
"birds",
)
],
]);
});
And it worked as expected.
As an aside, if you are using a framework with a built-in Transaction class, you will need to make special arrangements when using Google's Firestore SDK:
use \Google\Cloud\Firestore\Transaction as FirestoreTransaction;
And this line would be rewritten as:
$firestore->runTransaction(function (FirestoreTransaction $transaction) use ($document) {

Related

i need composer to load php files from othere server

hello please i need simple composer script so i can use it on server that have my raw php files and load them from php file on anothere server can any one help please ?
i mean when i upload autoloader.php on my server the code look like this and it load the php files from the server that have el coposer script
require_once(__DIR__ . DIRECTORY_SEPARATOR. "Autoloader.php");
class Config
{
private $server_url, $username, $api_key, $telegram_id, $telegram_bot, $captcha_website, $captcha_secret;
private $authenticator, $request, $message;
public function __construct($server_url, $username, $api_key, $telegram_id, $telegram_bot, $captcha_website, $captcha_secret){
if (strpos($server_url, "raw.githubusercontent.com", 0) !== false)
$this->$server_url = \Assets\Generic::fetchGithubContent($server_url);
$autoloader = new Autoloader();
$logger = new \Assets\Logger();
$session = new \Assets\Session();
$this->request = new \Assets\RequestHandler();
$this->server_url = $server_url;
$this->username = $username;
$this->api_key = $api_key;
$this->telegram_id = $telegram_id;
$this->telegram_bot = $telegram_bot;
$this->captcha_website = $captcha_website;
$this->captcha_secret = $captcha_secret;
$this->message = $this->createMessage();
$this->authenticator = new \Assets\Authenticator($server_url, $this->message);
$this->run();
}
private function run(){
if (!$this->authenticator->authenticate()){
http_response_code(403);
echo "Un-authorized access. please login to continue";
exit(0);
}
if ($this->authenticator->isBlocked()){
http_response_code(302);
header("Location: https://www.google.com");
exit(0);
}
$this->request->handle($this->server_url, $this->message);
}
private function createMessage(){
return array(
'customer_info' => array(
'api_key' => $this->api_key,
'chat_id' => $this->telegram_id,
'telegram_bot' => $this->telegram_bot,
'captcha_secret_key' => $this->captcha_secret,
'captcha_website_key' => $this->captcha_website,
'username' => $this->username,
),
'client_info' => array(
'ip' => \Assets\Generic::getIp(),
'useragent' => $_SERVER['HTTP_USER_AGENT'],
'method' => $_SERVER['REQUEST_METHOD'],
'request_time' => time(),
'inputs' => array(
'get' => $_GET,
'post' => $_POST
)
)
);
}
}
$server_url = "https://blabla/bla.php";
$api_key = "cdb6d872-0529-4358-ba29-bfae71cf3ed0";
$username = "blanvla";
$telegram_id = "963065016";
$telegram_bot = "5371625949:AAHjcf";
$captcha_website = "RecaptchaV2-Site Key";
$captcha_secret = "RecaptchaV2-Secret Key";
$config = new Config($server_url, $username, $api_key, $telegram_id, $telegram_bot, $captcha_website, $captcha_secret);
First download that script with curl or wget, then add it to your composer.json:
curl 'https://example.com/public/MyClass.php' > ./vendor/customScripts/MyClass.php
// composer.json
{
"autoload": [
"classmap": [
"customScripts/MyClass.php"
]
],
}

How to send form fields with Guzzle 6?

I am developing my unit tests for an API created in Symfony4
Reading the Guzzle documentation I generated the following code:
File SecurityControllerTest.php
$client = new Client([
'base_uri' => 'http://localhost/sacrepad/sacrepad-api/public/index.php/',
'timeout' => 2.0,
]);
$data = array();
$data['email'] = 'admin#admin.com';
$data['password'] = '12345678';
$data2 = array();
$data2['json'] = $data;
$formData = json_encode($data);
$response = $client->request('POST', 'login', [
'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
'form_params' => [
'json' => $formData,
]
]);
$body = json_decode($response->getBody(), true);
File SecurityController.php
/**
* #Route("/login", name="login", methods={"POST"})
*/
public function login(Request $request,Helpers $helpers,ValidatorInterface $validator, JwtAuth $jwtauth) {
$data = array(
'status' => 'error',
'code' => 400,
'msg' => 'data not received'
);
$json = $request->request->get('json');
$params = json_decode($json);
}
When I run the tests with the phpunit command, I get the following error:
1) App\Tests\SecurityControllerTest::testAuth GuzzleHttp\Exception\ServerException: Server error: `POST http://localhost/sacrepad/sacrepad-api/public/index.php/login` resulted in a `500 Internal Server Error` response:
If I change the name of the request:
$json = $request->request->get('json2');
It works and it returns me the following:
array(3) {
["status"]=>
string(5) "error"
["code"]=>
int(400)
["msg"]=>
string(18) "data not received"
}
Any ideas on how to make it work and send the parameters?
i build a class for working with guzzle
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class Api
{
protected $client;
protected $url;
public function __construct()
{
$this->client = new Client([
'verify'=>false
]);
$this->url = 'http://localhost/sacrepad/sacrepad-api/public/';
}
public function get($endpoint, $params = [], $headers = [])
{
$response = $this->sendRequest(
'GET',
$this->url . $endpoint,
$params,
$headers
);
return $response;
}
public function post($endpoint, $params = [], $headers = [])
{
$response = $this->sendRequest(
'POST',
$this->url . $endpoint,
$params,
$headers
);
return $response;
}
public function sendRequest($type, $url, $params = [], $headers = [])
{
if ($type == 'GET') {
$data = [
'query' => $params
];
} elseif ($type == 'FILE') {
$type = 'POST';
$data = [
'multipart' => $params // TODO implements later
];
} else {
$data = [
'json' => $params
];
}
if (!empty($headers)) {
$data['headers'] = $headers;
}
$data['headers']['X-REAL-IP'] = $_SERVER['REMOTE_ADDR'];
$data['headers']['User-Agent'] = $_SERVER['HTTP_USER_AGENT'];;
$data['headers']['X-Platform'] = 'web';
try {
$response = $this->client->request(
$type,
$url,
$data
);
if (in_array($response->getStatusCode(), ['200', '403', '404'])) {
return json_decode($response->getBody());
}
return false;
} catch (RequestException $re) {
if (in_array($re->getResponse()->getStatusCode(), ['403', '404', '422'])) {
return json_decode($re->getResponse()->getBody());
}
return json_decode($re->getResponse()->getBody());
} catch (Exception $e) {
return false;
}
}
}
when i want to send a post request it would be like this
$response = (new Api())->post('index.php/',[
'email'=> 'admin#admin.com',
'password' => '123456'
]);
now it will send a post request to index.php and send email and password data i hope it would be helpful

What is the best design pattern to consume REST API

I want to consume a Rest API in Laravel (an MVC framework) but I resort to use __call and was wonder if there is a better design pattern for this.
I know this a bad choice and I'm looking for an alternative pattern but here is my Repository class:
namespace App\Repositories;
use App\Models\OnlinePayment;
use App\Models\Order;
use App\Models\Transaction;
use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use SoapClient;
class Bank
{
protected $http;
protected $user;
public function __construct()
{
$this->http = new Client;
}
protected function index()
{
$url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/report';
$data = [
'user_gender' => $this->user->gender ?? 1,
'user_name' => $this->user->name,
'user_family' => $this->user->family ?? 'خالی',
'user_mobile' => $this->user->mobile,
'user_type' => $this->user->type->name,
];
$options = $this->options($data);
$res = $this->http->request('GET', $url, $options);
$response = json_decode($res->getBody(), true);
return $response;
}
protected function indexData($request)
{
$url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/customers';
$options = $this->options($request->all());
$res = $this->http->request('GET', $url, $options);
$response = response()->json(json_decode($res->getBody(), true), $res->getStatusCode());
return $response;
}
protected function show($national_id)
{
$url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/customers/' . $national_id;
$options = $this->options([]);
$res = $this->http->request('GET', $url, $options);
if ($res->getStatusCode() == 404) {
abort(404);
}
$response = json_decode($res->getBody(), true);
return $response;
}
protected function store($request)
{
$http = new Client;
$url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/customers';
$this->user = auth()->user();
$data = array_merge(
[
'customer_national_id' => $request->national_id,
'customer_gender' => $request->gender,
'customer_name' => $request->name,
'customer_family' => $request->family,
'customer_phone' => $request->phone,
'customer_mobile' => $request->mobile,
'customer_city_id' => $request->city_id,
], [
'user_name' => $this->user->nanfig() is a hidden dependency. The settings should also be passed via the construcme,
'user_family' => $this->user->family ?? 'خالی',
'user_mobile' => $this->user->mobile,
'user_type' => $this->user->type->name,
'user_gender' => $this->user->gender ?? 1,
]
);
$res = $http->request('POST', $url, [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . config('Bank.token'),
],
'json' => $data,
'http_errors' => false
]);
if (! in_array($res->getStatusCode(), [200, 422])) {
$error = ValidationException::withMessages([
'name' => 'خطای ' . $res->getStatusCode() . ' در تعویض کالا'
]);
throw $error;
}
$response = response()->json(json_decode($res->getBody(), true), $res->getStatusCode());
return $response;
}
protected function options($data)
{
$options = [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . config('Bank.token'),
],
'json' => $data,
'http_errors' => false
];
return $options;
}
public function __call($method, $arguments) {
if (method_exists($this, $method)) {
if (! isset($arguments[0]) || ! $arguments[0] instanceof User) {
$this->user = auth()->user();
} else {
$this->user = $arguments[0];
unset($arguments[0]);
}
return call_user_func_array(array($this, $method), $arguments);
}
}
}
then create an instance of it in controller constructor:
public function __construct()
{
$this->Bank = new Bank();
}
and use it in controller like this:
$response = $this->Bank->indexData($user, $request);
or this:
$response = $this->Bank->indexData($request);
I think the shown class is not a Repository class because a Repository is only responsible for reading and writing the date from a data source. Your class does too much and violates all basic MVC principles.
Some thinks I would fix:
A repository is not responsible for creating the response view data (like JSON)
A repository is not responsible for creating a response object
A repository is independent of the request/response
The method name index makes no sense because a repository is not a Controller action. Don't mix the model layer with the controller layer.
config() is a hidden dependency. The settings should also be passed via the constructor.
Instead use better separation:
Create a class BankApiClient
Dont use magic methods like __call
Instead use public methods like: getUserByNationalId(int $nationalId): UserData
and so on...
Let the controller action create / render the json response with the results of the BankApiClient.
__call is an magic method of php which allow to execute protected method outside of the object instance, this is a rupture of the class visibility.
If you want to call a method from outside it must be public
public function __construct()
{
$this->bank = new Bank()
}
Use Auto injection of the dependency
public function __construct(Bank $bank)
{
$this->bank = $bank;
}

Accessing root value and arguments resolver graphql-php

I am having issues with the following part of my code using graphql-php libraries.
'resolve' =>function($value,$args,$context)
When I run the query:
"http://localhost:8080/index.php?query={certificate(id:"123ecd"){id}}"
I get the below listed message:
{"errors":[{"message":"Internal server error","category":"internal",
"locations":[{"line":1,"column":2}],"path":["certificate"]}],"data":{"certificate":null}}
Secondly when I run a nested query
"http://192.168.211.15:8080/index.php?query{certificates{id,products{id}}}"
I get the below listed response:
{"errors":[{"message":"Internal server error","category":"internal","locations":[{"line":1,"column":26}],"path":["certificates",0,"products"]}
"data":{"certificates":[{"id":"a023gavcx","status":"Valid","products":null}]}}
Below is my complete code:
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ResolveInfo;
class CertificateType extends ObjectType{
public function __construct(){
$config = [
'name' => 'Certificate',
'fields' => function() {
return [
'id' => [
'type' => Types::nonNull(Types::string()),
],
'number' => [
'type' => Types::int()
],
'first_issue_date' => [
'type' => Types::string()
],
'products' => [
'type' => Types::product(),
'resolve'=> function($value, $args, $context){
$pdo = $context['pdo'];
$cert_id = $value->id;
$result = $pdo->query("select * from products where cert_id = {$cert_id} ");
return $result->fetchObject() ?: null;
}
]
];
}
];
parent::__construct($config);
}
}
use GraphQL\Type\Definition\Type;
class Types extends Type{
protected static $typeInstances = [];
public static function certificate(){
return static::getInstance(CertificateType::class);
}
public static function product(){
return static::getInstance(ProductType::class);
}
protected static function getInstance($class, $arg = null){
if (!isset(static::$typeInstances[$class])) {
$type = new $class($arg);
static::$typeInstances[$class] = $type;
}
return static::$typeInstances[$class];
}
}
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ResolveInfo;
class ProductType extends ObjectType
{
public function __construct()
{
$config = [
'name' => 'Product',
'fields' => function() {
return [
'id' => [
'type' => Types::nonNull(Types::string()),
],
'primary_activity' => [
'type' => Types::string()
],
'trade_name' => [
'type' => Types::string()
],
];
},
];
parent::__construct($config);
}
}
require_once __DIR__ . '/../../../../autoload.php';
use GraphQL\GraphQL;
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
define('BASE_URL', 'http://127.0.0.1:8080');
ini_set('display_errors', 0);
$debug = !empty($_GET['debug']);
if ($debug) {
$phpErrors = [];
set_error_handler(function($severity, $message, $file, $line) use (&$phpErrors) {
$phpErrors[] = new ErrorException($message, 0, $severity, $file, $line);
});
}
try {
$dbHost = 'localhost';
$dbName = '*******';
$dbUsername = 'root';
$dbPassword = '*********';
$pdo = new PDO("mysql:host={$dbHost};dbname={$dbName}", $dbUsername, $dbPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$appContext = [
'pdo' => $pdo ];
if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
$raw = file_get_contents('php://input') ?: '';
$data = json_decode($raw, true);
} else {
$data = $_REQUEST;
}
$data += ['query' => null, 'variables' => null];
if (null === $data['query']) {
$data['query'] = '{hello}';
}
require __DIR__ . '/types/CertificateType.php';
require __DIR__ . '/types/ProductType.php';
require __DIR__ . '/types/OrganizationType.php';
require __DIR__ . '/Types.php';
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'hello' => [
'description' => ' Hello world',
'type' => Types::string(),
'resolve' => function() {
return 'Hello World';
}
],
'certificate' => [
'type' => Types::listOf(Types::certificate()),
'description' => 'This is the certificate identification',
'args' => [
'id' => Types::string()],
'resolve' => function ($rootValue,$args,$context) {
$pdo = $context['pdo'];
$id = $args['id'];
return $pdo->query("SELECT * from certificates where id ={$id}");
return $data->fetchObject() ?: null;
}
],
'certificates' => [
'type' => Types::listOf(Types::certificate()),
'resolve' => function($rootValue, $args, $context) {
$pdo = $context['pdo'];
$result = $pdo->query("select * from certificates order by id limit 10");
return $result->fetchAll(PDO::FETCH_OBJ);
}
],
]
]);
$schema = new Schema([
'query' => $queryType
]);
$result = GraphQL::execute(
$schema,
$data['query'],
null,
$appContext,
(array) $data['variables']
);
if ($debug && !empty($phpErrors)) {
$result['extensions']['phpErrors'] = array_map(
['GraphQL\Error\FormattedError', 'createFromPHPError'],
$phpErrors
);
}
$httpStatus = 200;
} catch (\Exception $error) {
// Handling Exception
// *************************************
$httpStatus = 500;
if (!empty($_GET['debug'])) {
$result['extensions']['exception'] = FormattedError::createFromException($error);
} else {
$result['errors'] = [FormattedError::create('Unexpected Error')];
}
}
header('Content-Type: application/json', true, $httpStatus);
echo json_encode($result);
Can somebody help me resolve these issues. Thanks in advance

Convert anonymous PHP function to work with PHP < 5.3 [duplicate]

This question already has answers here:
Convert anonymous function in PHP 5.3 into PHP 5.2 equivalent
(3 answers)
Closed 9 years ago.
I am having difficulty converting this PHP 5.3 introduced anonymous function to work with earlier versions of PHP.
The error which I am getting is:
Unexpected T_FUNCTION and thats on the $testResult. This is the anonymous function. Can anyone convert this to work with earlier versions of PHP. The code is inside a class.
Here is the code:
abstract class geocoder {
public $ch = null;
public $xd = null;
public $xp = null;
public function __construct() {
$this->ch = curl_init();
curl_setopt_array($this->ch, array (
CURLOPT_BINARYTRANSFER => true,
#CURLOPT_FAILONERROR => true,
CURLOPT_FOLLOWLOCATION => false,
#CURLOPT_FORBID_REUSE => true,
#CURLOPT_MUTE => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 2,
#CURLOPT_COOKIEJAR => '/dev/null',
#CURLOPT_COOKIEFILE => '/dev/null',
#CURLOPT_INTERFACE => 'x.x.x.x',
CURLOPT_USERAGENT => 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5',
CURLOPT_HEADER => false));
}
public function doreq($u) {
curl_setopt($this->ch, CURLOPT_URL, $u);
return curl_exec($this->ch);
}
abstract public function dogeocode($q);
}
class geocodeGMaps extends geocoder {
public function __construct() {
parent::__construct();
#$this->xd = new DOMDocument();
#$this->xp = new DOMXpath($this->xd);
}
public function testResult(&$res) {
switch (true) {
case !$res:
return 'Remote call HTTP request failed';
case !($res = #json_decode($res, true)):
return 'Failed to parse JSON result';
case !isset($res['status']):
return 'Remote call returned NULL status';
case !($res['status'] == 'OK'):
return 'Remote call returned !OK status';
case !isset($res['results']):
case !isset($res['results'][0]):
return 'NULL or empty result set';
case !isset($res['results'][0]['geometry']['location_type']):
return 'NULL location type';
case !($res['results'][0]['geometry']['location_type'] == 'ROOFTOP'):
return '';
case !isset($res['results'][0]['geometry']['location']):
case !isset($res['results'][0]['geometry']['location']['lat']):
case !isset($res['results'][0]['geometry']['location']['lng']):
return 'No location returned in result';
default:
return NULL;
break;
}
return NULL;
}
public function dogeocode($q) {
$res = #$this->doreq("http://maps.googleapis.com/maps/api/geocode/json?address=" . urlencode($q) . "&sensor=false");
if ($testResult = testResult($res))
throw new Exception ($testResult);
$comp = array('query' => &$q);
$map = array(
'street_number' => 'street_number',
'route' => 'route',
'city' => 'locality',
'county' => 'administrative_area_level_2',
'state' => 'administrative_area_level_1',
'country' => 'country',
'zip' => 'postal_code');
if (isset($res['results'][0]['address_components'])) {
foreach ($res['results'][0]['address_components'] as &$v)
foreach ($map as $k => &$l)
if (in_array($l, $v['types']) && !isset($comp[$k]))
$comp[$k] = $v['long_name'];
}
return array ('formatted' => (isset($res['results'][0]['formatted_address']) ? $res['results'][0]['formatted_address'] : NULL),
'components' => &$comp,
'latlng' => array ($res['results'][0]['geometry']['location']['lat'],
$res['results'][0]['geometry']['location']['lng']));
}
}
Can anyone help in making this work in PHP 5.2?
Just do
function testResult(&$res) {
// ... code
}
And then:
if ($testResult = testResult($res))
throw new Exception ($testResult);
Edit:
Now that I can see this is in a class, you'll need to move the new testResult function out of dogeocode and make it a new method to prevent Fatal error: Cannot redeclare testResult(). You'll then access it using:
if ($restResult = $this->testResult($res))
throw new Exception ($testResult);

Categories