Commit 88882dc2 authored by aaa's avatar aaa

20180215 initial commit. Works (using print_r)

parents
#guzzle rest endpoint
## Description:
This module repeats/relays an external API through the internal Drupal REST authentication/authorisation mechanism.
This is an extension to guzzlerestgenerator . It adds REST support to each guzzle_node. This exposes any external api defined in guzzle_node as a drupal8 REST point. Also, node_view_permissions module is also recommended.
## Usage administration-side:
First you enable from REST-UI guzzle node
and set permissions/auth types etc
Add a guzzle_node (just like adding content) .
There you define:
- external API ,
- headers (eg APIkey etc.)
- Body (in case of POST/PUT)
Then you need to define access.
## Usage external-client-side:
You can connect with urls like :
http://mydrupal.com/api/relay/getalbums?_format=hal_json&param1=Ubuntu&param2=Music
this will relay your request as
http://myjsonserver/albums/Ubuntu/Music
To Do:
- Implement POST
- Implement PUT
- Implement access per SPECIFIC guzzle_node (per role or user)
name: d8_guzzlenode_rest
type: module
description: D8 add REST exports to guzzlerestgenerator module . Example Url is http://example/myurlalias?_format=json&id1=3&param1=hello&param2=bye this will call external REST restpoint.com/hello/bye
core: 8.x
package: Custom
version: '8.x-0.5jon-2018021b'
dependencies:
- guzzlerestgenerator
\ No newline at end of file
<?php
/**
* @file
* Contains d8_guzzlenode_rest.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function d8_guzzlenode_rest_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the d8_guzzlenode_rest module.
case 'help.page.d8_guzzlenode_rest':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('D8 add REST exports to guzzlerestgenerator module') . '</p>';
return $output;
default:
}
}
/**
* Implements hook_theme().
*/
function d8_guzzlenode_rest_theme() {
return [
'd8_guzzlenode_rest' => [
'render element' => 'children',
],
];
}
<?php
namespace Drupal\d8_guzzlenode_rest\Plugin\rest\resource;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
use Drupal\guzzlerestgenerator\Http\GuzzleDrupalHttp; // DEPENDS on guzzlerestgenerator module
use Symfony\Component\HttpFoundation\Request;
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "guzzlenode_rest_resource",
* label = @Translation("Guzzlenode rest resource"),
* uri_paths = {
* "canonical" = "/api/relay/{nid}",
*
* }
* )
*/
class GuzzlenodeRestResource extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $currentRequest;
protected $nid=0;
protected $param1=0;
protected $param2=0;
/**
* Constructs a new GuzzlenodeRestResource object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user,
Request $currentRequest //Added by Jon 180213
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
$this->currentRequest = $currentRequest;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('d8_guzzlenode_rest'),
$container->get('current_user'),
$container->get('request_stack')->getCurrentRequest() //Added by Jon 180213
);
}
/*
public function get($nid=0) {
}
public function get($nid=0,$param1=0) {
}
public function get() {
echo '{message: invalid # of paremters DEBUG msg}';
}
*/
/**
* Responds to GET requests.
*
* Returns a list of bundles for specified entity.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
//public function get() { //ORIGINAL
public function get($nid=0) {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
//$entities = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple(); //ORIG WORKED
$entities = \Drupal::entityTypeManager()
->getStorage('node')
->loadByProperties(['type' => 'guzzle_rest']); //LOAD ONLY guzzle nodes
//->loadMultiple();
//$entities = \Drupal::entityTypeManager()->getStorage('external_entity_type')->loadByProperties(['type' => 'extent001']); // get specific entity JON TEST
//$get_node_id = $this->currentRequest->get('id1'); //get URL REST node id drupal.com/restapi/?myname=john
$get_param1 = $this->currentRequest->get('param1'); //get URL REST node id drupal.com/restapi/?myname=john
$get_param2 = $this->currentRequest->get('param2'); //get URL REST node id drupal.com/restapi/?myname=john
//$node_id_from_arg = $nid;
//$node_id_from_alias=\Drupal::service('path.alias_manager')->getAliasByPath('/node/'.$nid); //GET path alias from node_ideg drupal.com/restapi/myalbum
//Todo Do some chech if $nid is number
$node_id_from_alias="0";
//if ($nid!=0)
$node_id_from_alias=\Drupal::service('path.alias_manager')->getPathByAlias('/'.$nid); //GET node_id from path alias drupal.com/restapi/myalbum
$node_id_from_alias=str_replace("/node/", "", $node_id_from_alias);
\Drupal::logger('DEBUG guzzlenode_rest')->notice("PARAMS: nid=$nid ,node_id_from_alias = $node_id_from_alias , param1=$get_param1, param2=$get_param2 "); //DEBUG
// JON NOTE : BUG at this moment it shows ONLY 1 guzzlenode (even if you have more)
foreach ($entities as $entity) {
// $result[$entity->id()] = $entity->title->value; // OK WORKS returns all titles
//if(($entity->getType() == 'guzzle_rest') && ( $entity->id()==$get_node_id) ){ //ok works Example with URL like drupal.com/restapi/?myname=john
if( ( $entity->id()==$nid) || ( $entity->id()==$node_id_from_alias) ){ // test URLs like drupal.com/restapi/4 or drupal.com/restapi/myalbum
//$result[$entity->id()] = $entity->title->value;
// Retrieve node fields to perform REST request
$endpoint_url = $entity->get('field_guzzle_endpoint_url')->uri;
$request_method = $entity->get('field_guzzle_request_method')->value;
$raw_headers = $entity->get('field_guzzle_raw_headers')->value;
$payload_data = $entity->get('field_guzzle_data_payload')->value;
//$status = $entity->get('status')->value; //JON try to get Published status @@@@@@@@@@@@@@
if (isset($get_param1)){
$endpoint_url=$endpoint_url.'/'.$get_param1; // ******** Might need to sanitaze
if (isset($get_param2)){
$endpoint_url=$endpoint_url.'/'.$get_param2; // ******** Might need to sanitaze
}
}// END of if (isset($get_param1)){
\Drupal::logger('DEBUG guzzlenode_rest URI')->notice(" endpoint_url=$endpoint_url ");
// Perform GuzzleDrupalHttp request
$check = new GuzzleDrupalHttp();
// Function call to retrieve cities
$response = $check->performRequest($endpoint_url,$request_method,$raw_headers,$payload_data);
$contents = (string) $response->getBody();
if($response->getStatusCode() == '200'){
if($contents != ''){
//check for permission here
///$result[$entity->id()]=$contents; //add all instances as a ARRAY (not need this at this time OK WORKS) // solution #3 (escaped chars)
//$result=$contents;// ok WORKS // solution #1 (escaped chars)
print_r($contents);//ok WORKS // solution #2
}else{
print_r('200 '.$response->getReasonPhrase());
}
}
else{
// $result[$entity->id()] = $entity->title->value;
///$result[$entity->id()]=$contents; //add all instances as a ARRAY (not need this at this time OK WORKS)// solution #3 (escaped chars)
// $result=$contents; // ok WORKS // solution #1 (escaped chars)
print_r($contents);//ok WORKS // solution #2
echo '</br>Response Status Code: ';
print_r($response->getStatusCode());
echo '</br>Reason Phrase: ';
print_r($response->getReasonPhrase());
}
die(); // ### NOTE: This assumes that we only want 1 guzzlenode entity each time (this mshould be correct - solution #3 will not work with die() )
};// END of if($node->getType() == 'guzzle_rest'){
} // END of foreach ($entities as $entity) {
$response = new ResourceResponse($result);
$response->addCacheableDependency($result);
return $response;
//return new ResourceResponse("Implement REST State GET!");
}
}
<?php
namespace Drupal\d8_guzzlenode_rest\Plugin\rest\resource;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "guzzlenode_rest_resource",
* label = @Translation("Guzzlenode rest resource"),
* uri_paths = {
* "canonical" = "/api/relay"
* }
* )
*/
class GuzzlenodeRestResource extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* Constructs a new GuzzlenodeRestResource object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('d8_guzzlenode_rest'),
$container->get('current_user')
);
}
/**
* Responds to GET requests.
*
* Returns a list of bundles for specified entity.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function get() {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
$entities = \Drupal::entityTypeManager()
->getStorage('node')
->loadMultiple();
foreach ($entities as $entity) {
$result[$entity->id()] = $entity->title->value;
}
$response = new ResourceResponse($result);
$response->addCacheableDependency($result);
return $response;
//return new ResourceResponse("Implement REST State GET!");
}
}
<?php
namespace Drupal\d8_guzzlenode_rest\Plugin\rest\resource;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
use Drupal\guzzlerestgenerator\Http\GuzzleDrupalHttp; // DEPENDS on guzzlerestgenerator module
use Symfony\Component\HttpFoundation\Request;
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "guzzlenode_rest_resource",
* label = @Translation("Guzzlenode rest resource"),
* uri_paths = {
* "canonical" = "/api/relay"
* }
* )
*/
class GuzzlenodeRestResource extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $currentRequest;
/**
* Constructs a new GuzzlenodeRestResource object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user,
Request $currentRequest //Added by Jon 180213
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
$this->currentRequest = $currentRequest;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('d8_guzzlenode_rest'),
$container->get('current_user'),
$container->get('request_stack')->getCurrentRequest() //Added by Jon 180213
);
}
/**
* Responds to GET requests.
*
* Returns a list of bundles for specified entity.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function get() {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
//$entities = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple(); //ORIG WORKED
$entities = \Drupal::entityTypeManager()
->getStorage('node')
->loadByProperties(['type' => 'guzzle_rest']); //LOAD ONLY guzzle nodes
//->loadMultiple();
//$entities = \Drupal::entityTypeManager()->getStorage('external_entity_type')->loadByProperties(['type' => 'extent001']); // get specific entity JON TEST
$get_node_id = $this->currentRequest->get('id1'); //get URL REST node id drupal.com/restapi/?myname=john
// JON NOTE : BUG at this moment it shows ONLY 1 guzzlenode (even if you have more)
foreach ($entities as $entity) {
// $result[$entity->id()] = $entity->title->value; // OK WORKS returns all titles
if(($entity->getType() == 'guzzle_rest') && ( $entity->id()==$get_node_id) ){
//$result[$entity->id()] = $entity->title->value;
// Retrieve node fields to perform REST request
$endpoint_url = $entity->get('field_guzzle_endpoint_url')->uri;
$request_method = $entity->get('field_guzzle_request_method')->value;
$raw_headers = $entity->get('field_guzzle_raw_headers')->value;
$payload_data = $entity->get('field_guzzle_data_payload')->value;
//$status = $entity->get('status')->value; //JON try to get Published status @@@@@@@@@@@@@@
// Perform GuzzleDrupalHttp request
$check = new GuzzleDrupalHttp();
// Function call to retrieve cities
$response = $check->performRequest($endpoint_url,$request_method,$raw_headers,$payload_data);
$contents = (string) $response->getBody();
if($response->getStatusCode() == '200'){
if($contents != ''){
//check for permission here
///$result[$entity->id()]=$contents; //add all instances as a ARRAY (not need this at this time OK WORKS) // solution #3 (escaped chars)
//$result=$contents;// ok WORKS // solution #1 (escaped chars)
print_r($contents);//ok WORKS // solution #2
}else{
print_r('200 '.$response->getReasonPhrase());
}
}
else{
// $result[$entity->id()] = $entity->title->value;
///$result[$entity->id()]=$contents; //add all instances as a ARRAY (not need this at this time OK WORKS)// solution #3 (escaped chars)
// $result=$contents; // ok WORKS // solution #1 (escaped chars)
print_r($contents);//ok WORKS // solution #2
echo '</br>Response Status Code: ';
print_r($response->getStatusCode());
echo '</br>Reason Phrase: ';
print_r($response->getReasonPhrase());
}
//die();
};// END of if($node->getType() == 'guzzle_rest'){
} // END of foreach ($entities as $entity) {
$response = new ResourceResponse($result);
$response->addCacheableDependency($result);
return $response;
//return new ResourceResponse("Implement REST State GET!");
}
}
<?php
namespace Drupal\d8_guzzlenode_rest\Plugin\rest\resource;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
use Drupal\guzzlerestgenerator\Http\GuzzleDrupalHttp; // DEPENDS on guzzlerestgenerator module
use Symfony\Component\HttpFoundation\Request;
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "guzzlenode_rest_resource",
* label = @Translation("Guzzlenode rest resource"),
* uri_paths = {
* "canonical" = "/api/relay/{nid}",
*
* }
* )
*/
class GuzzlenodeRestResource extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $currentRequest;
protected $nid=0;
protected $param1=0;
protected $param2=0;
/**
* Constructs a new GuzzlenodeRestResource object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user,
Request $currentRequest //Added by Jon 180213
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
$this->currentRequest = $currentRequest;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('d8_guzzlenode_rest'),
$container->get('current_user'),
$container->get('request_stack')->getCurrentRequest() //Added by Jon 180213
);
}
/*
public function get($nid=0) {
}
public function get($nid=0,$param1=0) {
}
public function get() {
echo '{message: invalid # of paremters DEBUG msg}';
}
*/
/**
* Responds to GET requests.
*
* Returns a list of bundles for specified entity.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
//public function get() { //ORIGINAL
public function get($nid=0) {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
//$entities = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple(); //ORIG WORKED
$entities = \Drupal::entityTypeManager()