Magento 2 access Rest API interface from root file - php

I have created a script file in root and I want to create a new customer from that file below is my code for that.
use Magento\Framework\App\Bootstrap;
//use Magento\Customer\Api\Data\CustomerInterface;
require __DIR__ . '/../../app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$obj = $bootstrap->getObjectManager();
$obj->get('Magento\Framework\App\State')->setAreaCode('frontend');
$customerData = [
'customer' => [
'email' => 'demo#user.com',
'firstname' => 'John',
'lastname' => 'Wick',
],
'password' => 'John123'
];
$customer=$obj->get('\Magento\Customer\Api\AccountManagementInterface');
$customer->createAccount($customerData);
but when i run this code it gives me below error.
Fatal error: Uncaught TypeError: Argument 1 passed to Magento\Customer\Model\AccountManagement\Interceptor::createAccount() must be an instance of Magento\Customer\Api\Data\CustomerInterface, array given, called in C:\wamp64\www\mg\m2\rest\v3\Customer.php on line 82 and defined in C:\wamp64\www\mg\m2\generated\code\Magento\Customer\Model\AccountManagement\Interceptor.php:124
Stack trace:
0 C:\wamp64\www\mg\m2\rest\v3\Customer.php(82): Magento\Customer\Model\AccountManagement\Interceptor->createAccount(Array)
1 C:\wamp64\www\mg\m2\rest\v3\api.php(7): require_once('C:\wamp64\www\m...')
2 {main}
thrown in
C:\wamp64\www\mg\m2\generated\code\Magento\Customer\Model\AccountManagement\Interceptor.php on line
124
Please help. actually i want to access web api method directly from code and get response so that i can modify that response accordingly. because we already have app running in magento 1.9. so we don't want to change response

It's just like the error message says. You have to pass an implementation of Magento\Customer\Api\Data\CustomerInterface to the createAccount method.
So instead of passing a simple array like $customerData, you should create a new instance of a CustomerInterface implementation instead ... and fill it with the required data.
Searching through their github repo I found this:
Magento\Customer\Model\Data\Customer
https://github.com/magento/magento2/search?utf8=%E2%9C%93&q=%22implements+Magento%5CCustomer%5CApi%5CData%5CCustomerInterface%22&type=
So unless you want to create your own implementation, this is what you should pass to createAccount
You should be able to create one via the factory like so:
try {
$objectManager = $bootstrap->getObjectManager();
$objectManager->get(Magento\Framework\App\State::class)
->setAreaCode(\Magento\Framework\App\Area::AREA_FRONTEND);
/** #var \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory */
$customerFactory = $objectManager->create(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class);
$customer = $customerFactory->create();
$customer
->setEmail('justincase#test123.xyz')
->setFirstname('Justin')
->setLastname('Case');
/** #var \Magento\Customer\Api\AccountManagementInterface $accountManager */
$accountManager = $objectManager->create(\Magento\Customer\Api\AccountManagementInterface::class);
$accountManager->createAccount($customer);
} catch (Exception $e) {
echo $e->getMessage();
}
Ok, since I was curious, I quickly (lol) installed magento2 myself. With the above example I was able to create a customer on a fresh magento2 install.

Related

Cant access Firestore documents from PHP scripts with API key

I am new to Firebase/Firestore. I have created 2 projects that access the same data in Firestore.
One is in android and the other a web app in php. I am able to access data in android app but in PHP app
i had to create an API key in the credentials page. I want to use Firestore on trial basis initially but am not able to access the documents . It gives an error
Fatal error: Uncaught RuntimeException: Credentials fetcher does not implement Google\Auth\UpdateMetadataInterface in C:\xampp\htdocs\FirestoreProject\vendor\google\auth\src\FetchAuthTokenCache.php:190 Stack trace: #0 C:\xampp\htdocs\FirestoreProject\vendor\google\gax\src\CredentialsWrapper.php(197): Google\Auth\FetchAuthTokenCache->updateMetadata(Array, 'https://firesto...') #1 [internal function]: Google\ApiCore\CredentialsWrapper->Google\ApiCore{closure}(Object(stdClass)) #2 C:\xampp\htdocs\FirestoreProject\vendor\grpc\grpc\src\lib\ServerStreamingCall.php(44): Grpc\Call->startBatch(Array) #3 C:\xampp\htdocs\FirestoreProject\vendor\grpc\grpc\src\lib\BaseStub.php(364): Grpc\ServerStreamingCall->start(Object(Google\Cloud\Firestore\V1\BatchGetDocumentsRequest), Array, Array) #4 C:\xampp\htdocs\FirestoreProject\vendor\grpc\grpc\src\lib\BaseStub.php(589): Grpc\BaseStub->Grpc{closure}('/google.firesto...', Object(Google\Cloud\Firestore\V1\BatchGetDocumentsRequest), Array, Array, Array) #5 C:\xampp\htdocs\FirestoreProject\ve in C:\xampp\htdocs\FirestoreProject\vendor\google\auth\src\FetchAuthTokenCache.php on line 190
I have installed composer and updated the dependencies and gRPC.
My index.php file reads
<?php
session_start();
require_once 'vendor/autoload.php';
require_once "Firestore.php";
$apiKey = 'WWWWWWWWWWWWWWWWWWWWWW';
$url ='https://console.firebase.google.com/project/prject-ID/firestore?
key=Aasdads';
$fs = new Firestore('Users');
print_r($fs->getDocument('9427349073'));
return;
?>
My Firestore.php file reads
<?php
use Google\Cloud\Core\Exception\GoogleException;
use Google\Cloud\Firestore\FirestoreClient;
class Firestore
{
protected $db;
protected $name; // $name is name of collection
public function __construct(string $collection) // $collection =
// 'Users'
{
if (isset($this)) {
try {
$this->db = new FirestoreClient([
'projectId' => 'XXXXXXXXXXXXXXXXXXX'
]);
$this->name = $collection;
} catch (GoogleException $e) {
print_r($e->getMessage());
}
}else{
}
}
public function getDocument(string $name) // $name is name of document
{
return $this->db->collection($this->name)->document($name)-
>snapshot()->data();
}
}
?>
I tried activating the Credentials Page but they are asking for Credit card for billing to start trial , which i dont have. Cant we test the database without activating the Credentials? What is the difference between testing and trial basis usage ?
Please help
regards
Sanjish
I have made a test.php file after creating a service account and pointing to the key.json file on command prompt using set GOOGLE_APPLICATION_CREDENTIALS
<?php
require_once 'vendor/autoload.php';
session_start();
use Google\Cloud\Firestore\FirestoreClient;
initialize();
function initialize()
{
// Create the Cloud Firestore client
$db = new FirestoreClient([
'projectId' => 'Valbhai-xxx'
]);
$usersRef = $db->collection('Users'); // This works
$snapshot = $usersRef->documents(); // This does not work , gives
// the same error
foreach ($snapshot as $user) {
printf('User: %s' . PHP_EOL, $user->client_name());
}
}
?>
I reproduced your issue on my computer and I noticed that this is because PHP is ignoring the environment variable GOOGLE_APPLICATION_CREDENTIALS, because this is not defined for the user Apache(or httpd) in order to fix this I modified the initialization by using this code block
$db = new FirestoreClient([
'keyFilePath' => '/path/to/credentials.json',
'projectId' => 'my-project-id'
]);
With keyFilePath (this parameter is documented here), Firestore library going to search the GCP credentials using the string of the path instead the environment variable

Odoo XML-RPC Traceback (most recent call last)

I'm new one on Odoo, and I don't have experience with the system and try to follow the documentation how they do it.
For my first thing what I need is to connect external PHP web application whit our Odoo system.
I see this is possible and I follow the steps on that documentation: Odoo Documentation
So I'm stick here:
$common = ripcord::client("$url/xmlrpc/2/common");
$common->version();
When I execute that lines of code I get that error:
[faultString] => Traceback (most recent call last):
File "/home/odoo/src/odoo/12.0/odoo/addons/base/controllers/rpc.py", line 63, in xmlrpc_2
response = self._xmlrpc(service)
File "/home/odoo/src/odoo/12.0/odoo/addons/base/controllers/rpc.py", line 42, in _xmlrpc
params, method = loads(data)
File "/usr/lib/python3.5/xmlrpc/client.py", line 1000, in loads
p.close()
File "/usr/lib/python3.5/xmlrpc/client.py", line 447, in close
parser.Parse(b"", True) # end of data
xml.parsers.expat.ExpatError: no element found: line 1, column 0
I use demo URL (https://demo.odoo.com/) which their recommend. And from first example I get username, password, database name, successfully. But after that I cannot do anything.
UPDATE:
That is my PHP class which I call for testing:
require_once(__DIR__ . '/Ripcode/ripcord.php');
class Ripcode
{
private $_url = 'https://demo.odoo.com/';
private $_server = [];
private $_connection = null;
private $_common = null;
public function __construct()
{
$this->_server = \ripcord::client($this->_url . 'start')->start();
$common = \ripcord::client($this->_url . "xmlrpc/2/common");
$common->version();
$models = \ripcord::client($this->_url . "xmlrpc/2/object");
$uid = $common->authenticate(
$this->_server['database'],
$this->_server['user'],
$this->_server['password'],
array()
);
showArray([
'server' => $this->_server,
'uid' => $uid
]);
showArray([
'server' => $this->_server,
'models' => $models,
'uid' => $uid
'common' => $common->version()
]);
}
}
The problem is ripcord. I tested one cloned from https://github.com/poef/ripcord with an Odoo v12 running locally and debugged from the reception of the request all the way through until the response is sent. Everything works seamlessly until it gets to ripcord.
May I suggest using another XML-RPC client?

Sightengine API not working correctly?

I have recently come across an API called Sightengine which checks images for nudity, violence and some more things. I have followed their site to set up this API and got the following code in my PHP-file:
require __DIR__."/../Sightengine/src/SightengineClient.php";
require __DIR__."/../Sightengine/src/Check.php";
$filterImage = new Sightengine\SightengineClient('189981095', '5snnKqMiPU8cx2fHuUff');
$resultFilterImage = $filterImage->check(['nudity'])->set_url('https://d3m9459r9kwism.cloudfront.net/img/examples/example7.jpg');
Now, this should work and give back a JSON with information in it about how nude the picture is, but when trying to run this, it gives me the follow error:
Fatal error: Uncaught Error: Class 'GuzzeleHttp\Client' not found in C:\xampp\htdocs\ugesco\Sightengine\src\SightengineClient.php:13
Stack trace:
#0 C:\xampp\htdcos\ugesco\Controller\controller.php(234):
Sightengine\SightengineClient->__construct('my user key', 'my pass key')
#1 {main}
thrown in C:\xampp\htdocs\Ugesco\Sightengine\src\SightengineClient.php on line 13
Now, what I get out of this is that the class GuzzleHttp\Client can't be found in the SightengineClient.php-file. Thing is, I copied this from the Sightengine-company their Github, so I have no clue why it is not there..?
This is the code in the SightengineClient.php:
<?php
namespace Sightengine;
class SightengineClient {
private $api_user;
private $api_secret;
private $endpoint = 'https://api.sightengine.com/';
private $http;
function __construct($api_user, $api_secret) {
$this->api_user = $api_user;
$this->api_secret = $api_secret;
$this->http = new \GuzzleHttp\Client(['base_uri' => $this->endpoint, 'User-Agent' => 'SE-SDK-PHP' . '1.0']);
}
public function feedback($model, $modelClass, $image) {
$url = '1.0/feedback.json';
if (filter_var($image, FILTER_VALIDATE_URL)) {
$r = $this->http->request('GET', $url, ['query' => ['api_user' => $this->api_user, 'api_secret' => $this->api_secret, 'model' => $model,'class' => $modelClass,'url' => $image]]);
return json_decode($r->getBody());
}
else {
$file = fopen($image, 'r');
$r = $this->http->request('POST', $url, ['query' => ['api_user' => $this->api_user, 'api_secret' => $this->api_secret, 'model' => $model,'class' => $modelClass],'multipart' => [['name' => 'media','contents' => $file]]]);
return json_decode($r->getBody());
}
}
public function check($models) {
return new Check($this->api_user, $this->api_secret, $models);
}
}
As you can see on line 13 it wants to make a new GuzzeleHttp\Client but that Client-class is nowhere to be found. You can check their Github yourself: https://github.com/Sightengine/client-php
This is a real company who offers packages of image checks for money, so how could this be that their code is not working anymore (or is this an easy fix?).
Thanks in advance!
It does work if you perform a proper install using composer:
composer require sightengine/client-php
guzzlehttp/guzzle is correctly listed as a dependency in the composer.json file: https://github.com/Sightengine/client-php/blob/master/composer.json

unable to load the GetMyMessagesRequestType class when calling the namespace

I am unable to load the GetMyMessagesRequestType class from the ebay-sdk which is in the following namespace :
use DTS\eBaySDK\Trading\Services;
use DTS\ebaySDK\Trading\Types;
when i call the following:
use DTS\eBaySDK\Shopping\Services;
use DTS\ebaySDK\Shopping\Types;
the class in question which ebayTime loads perfectly :
$service = new Services\ShoppingService();
// Create the request object.
$request = new Types\GeteBayTimeRequestType();
// Send the request to the service operation.
$response = $service->geteBayTime($request);
// Output the result of calling the service operation.
printf("The official eBay time is: %s\n", $response->Timestamp->format('H:i (\G\M\T) \o\n l jS Y'));
this code works.
but the code i have changed now looks like this :
$service = new Services\TradingService([
'authToken'=> "",
'credentials' => [
'appId' => '',
'certId' => '',
'devId' => ''
],
'siteId'=>0
]);
$request = new Types\GetMyMessagesRequestType();
and i get the following error message :
Attempted to load class "GetMyMessagesRequestType" from namespace "DTS\ebaySDK\Trading\Types".
Did you forget a "use" statement for "DTS\eBaySDK\Trading\Types\GetMyMessagesRequestType"
any ideas this is one little thing i am unable to fix to complete the project?
When you changed the use statements to DTS\ebaySDK\Shopping\Types, the class you're trying to instantiate is looking in the wrong namespace: DTS\ebaySDK\Shopping\Types\GetMyMessagesRequestType does not exist.
Either change the offending line from:
$request = new Types\GetMyMessagesRequestType();
into (note the leading backslash):
$request = new \DTS\eBaySDK\Trading\Types\GetMyMessagesRequestType();
Or add a use statement to the correct namespace:
use DTS\eBaySDK\Trading\Types\GetMyMessagesRequestType;
$request = new GetMyMessagesRequestType();

Using value from previous test case in PHPUnit

I am trying to assign a value to a variable inside the first testing function and then use it in other testing functions inside the class.
right now in my code the second function fails due to this error:
1) ApiAdTest::testApiAd_postedAdCreated
GuzzleHttp\Exception\ClientException: Client error: 404
and i dont know why. this is how the code looks like:
class ApiAdTest extends PHPUnit_Framework_TestCase
{
protected $adId;
private static $base_url = 'http://10.0.0.38/adserver/src/public/';
private static $path = 'api/ad/';
//start of expected flow
public function testApiAd_postAd()
{
$client = new Client(['base_uri' => self::$base_url]);
$response = $client->post(self::$path, ['form_params' => [
'name' => 'bellow content - guzzle testing'
]]);
$data = json_decode($response->getBody());
$this->adId = $data->id;
$code = $response->getStatusCode();
$this->assertEquals($code, 200);
}
public function testApiAd_postedAdCreated()
{
$client = new Client(['base_uri' => self::$base_url]);
$response = $client->get(self::$path.$this->adId);
$code = $response->getStatusCode();
$data = json_decode($response->getBody());
$this->assertEquals($code, 200);
$this->assertEquals($data->id, $this->adId);
$this->assertEquals($data->name, 'bellow content - guzzle testing');
}
in the phpunit doumintation https://phpunit.de/manual/current/en/fixtures.html i see i can define a
a variable inside the setUp method and then use it as i want but in my case i only know the value after the first post executes. any idea how can i use $this->adId in the second function??
Unit tests by definition should not rely on one another. You will end up with unstable and fragile tests which are then hard to debug the moment they start failing, since the cause is in another test case.
There is no guarantee in which order the tests execute in PHPUnit by default.
PHPUnit supports the #depends annotation to achieve what you want, the docs have the same warning though.

Categories