In this tutorial, you will learn how to integrate an external SDK into your plugin. By integrating an external SDK and adding a dependency between your plugin and a repository on Packagist, you can access the functionality of the external SDK.
In this tutorial, we will extend the functionality of the HelloWorld plugin by integrating Guzzle, a PHP HTTP client. We then use the external SDK to send an HTTP request to an API, e.g. the Packagist API, to retrieve certain information.
Below, you find an overview of the existing structure of our HelloWorld plugin.
HelloWorld/ ├── resources/ │ └── views/ │ └── content/ │ └── hello.twig │ ├── src/ │ ├── Providers/ │ │ ├── HelloWorldServiceProvider.php │ │ └── HelloWorldRouteServiceProvider.php │ │ │ └── Controllers/ │ └── ContentController.php │ ├── plugin.json // plugin information └── // additional files (Readme, license etc.)
In order to integrate the external SDK, we have to make changes to the following existing files. We also have to add a new folder with a new file:
plugin.json
guzzle_connector.php
file
ContentController.php
hello.twig
First, we have to specify the dependencies of our plugin to the Guzzle SDK by updating the plugin.json
file.
HelloWorld/plugin.json
{ "name":"HelloWorld", "description":"My first plugin", "namespace":"HelloWorld", "author":"Your name", "type":"template", "serviceProvider":"HelloWorld\\Providers\\HelloWorldServiceProvider", "dependencies" : { "guzzlehttp/guzzle": "6.3.*" } }
dependencies
. The value for this attribute consists of the repository name on Packagist, here guzzlehttp/guzzle
and the required version, e.g. version 6.3.*
. The asterisk means that any version starting with 6.3, e.g. 6.3.0, 6.3.1 or 6.3.2, is fine.
External PHP code can only be executed in PHP files that are saved in the lib folder. So, we create a new PHP file that will be the link between the plentymarkets plugin API and an external API.
We take the code example from Guzzle and make some adaptions so that the code fits our needs. Remember that we want to send an HTTP request to the Packagist API. Let's search packages by name.
HelloWorld/resources/lib/guzzle_connector.php
<?php $client = new \GuzzleHttp\Client(); $res = $client->request( 'GET', 'https://packagist.org/search.json', [ 'query' => ['q' => SdkRestApi::getParam('packagist_query')] ] ); /** @return array */ return json_decode($res->getBody(), true);
query
to add a query string to the request.SdkRestApi
is a helper class that enables the communication between plentymarkets plugins and external SDKs. This class provides information about the requests sent by the plugin.getParam
function of our query, we use packagist_query
. This variable will be described in the code explanation of our ContentController.string
is returned, it must be UTF-8 encoded.
In order to execute the previously created PHP file, we need to enable HTTP requests in the ContentController, add functionality to address the PHP response and process the returned data.
HelloWorld/src/Controllers/ContentController.php
<?php namespace HelloWorld\Controllers; use Plenty\Plugin\Controller; use Plenty\Plugin\Templates\Twig; use Plenty\Modules\Plugin\Libs\Contracts\LibraryCallContract; use Plenty\Plugin\Http\Request; /** * Class ContentController * @package HelloWorld\Controllers */ class ContentController extends Controller { /** * @param Twig $twig * @param LibraryCallContract $libCall * @param Request $request * @return string */ public function sayHello( Twig $twig, LibraryCallContract $libCall, Request $request ) { $packagistResult = $libCall->call( 'HelloWorld::guzzle_connector', ['packagist_query' => $request->get('search')] ); return $twig->render('HelloWorld::content.hello', ['packagistResult' => $packagistResult); } }
Request
allows us to obtain an instance of the current HTTP request and LibraryCallContract is used for addressing our PHP file and processing the response.$packagistResult
variable.call()
method requires the $libCall
parameter and an array of request parameters. In $libCall
, we state that our connector is located in the HelloWorld plugin: HelloWorld::guzzle_connector
.packagist_query
and assign the $request
parameter to it. This param allows us, to request any search term by adding search
to our URL.$packagistResult
is then passed to the render
function and available in our template.We mentioned above that we want to search Packagist packages by name. So when sending the HTTP request to get all packages with the name plentymarkets, e.g. with Postman, we receive the following response consisting of the results array and the total number of packages:
https://packagist.org/search.json?q=plentymarkets
{ "results": [ { "name": "plentymarkets/plugin-hack-api", "description": "API for plentymarkets plugin development with Hack", "url": "https://packagist.org/packages/plentymarkets/plugin-hack-api", "repository": "https://github.com/plentymarkets/plugin-hack-api", "downloads": 13, "favers": 1 }, { "name": "composer/installers", "description": "A multi-framework Composer library installer", "url": "https://packagist.org/packages/composer/installers", "repository": "https://github.com/composer/installers", "downloads": 4931419, "favers": 641 }, { "name": "alexcold/yii2-plentyconnector", "description": "PlentyMarkets SOAP API connector", "url": "https://packagist.org/packages/alexcold/yii2-plentyconnector", "repository": "https://github.com/alexcold/yii2-plentyconnector", "downloads": 10, "favers": 0 }, { "name": "plentymarkets/plugin-hello-world", "description": "Creates an empty frontend plugin for plentymarkets plugin development", "url": "https://packagist.org/packages/plentymarkets/plugin-hello-world", "repository": "https://github.com/plentymarkets/plugin-hello-world", "downloads": 12, "favers": 0 } ], "total": 4 }
In our TWIG template we don't need all the information of the JSON response. We only want to display the total number of packages, the package name and the package repository. If no packages were found, we want to display the text No entries.
HelloWorld/resources/views/content/hello.twig
<h1>Hello World!</h1> <p>{{ packagistResult.total }} Results</p> <ul> {% for packagistItem in packagistResult.results %} <li>{{ packagistItem.name }} : {{ packagistItem.repository }}</li> {% else %} <li>No entries</li> {% endfor %} </ul>
packagistResult
is defined in the ContentController and contains the information of our HTTP response.{{ packagistResult.total }}
to render the total number of results.{% for %}
loop, we loop over each item in the results array and list each package in the browser with name and repository by using the variables {{ packagistResult.name }}
and {{ packagistResult.repository }}
.{% else %}
clause will render No entries if no iteration took place because the sequence was empty.
Next, we deploy the plugin in a plugin set. Now, we are able to search for packages via the address bar of the browser. Open your browser and go to www.your-plentystore.com/hello
. The template will be rendered and an empty result list will be displayed.
By adding ?search=plentymarkets
to the URL, we will send an HTTP request to Packagist that returns all packages with the search word plentymarkets. The items of the result will be rendered in the result list. Requests are limited to prevent an overflow of queries.
HelloWorld
folder, the changes must be pushed to GitHub. You also have to update the plugin in your plentymarkets inbox by pulling the changes from GitHub. Finally, you have to deploy the plugin again to display the changes in your browser. You can also check out the branch for this tutorial on GitHub.