Skip to content

Commit

Permalink
MAGETWO-85063: Create a framework for dynamically composing what's ne…
Browse files Browse the repository at this point in the history
…w content
  • Loading branch information
rossbrandon committed Dec 15, 2017
1 parent 42996a4 commit da443ff
Show file tree
Hide file tree
Showing 21 changed files with 1,480 additions and 280 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\ReleaseNotification\Model\Connector\Http;

use Magento\ReleaseNotification\Model\ContentProviderInterface;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Backend\Model\Auth\Session;
use Psr\Log\LoggerInterface;
use Magento\Framework\HTTP\ClientInterface;

/**
* Class HttpContentProvider
*
* Requests the release notification content data via an HTTP call to a REST API
*/
class HttpContentProvider implements ContentProviderInterface
{
/**
* Path to the configuration value which contains an URL that provides the release notification data.
*
* @var string
*/
private static $notificationUrlConfigPath = 'releaseNotification/url/content';

/**
* Version query parameter value for default release notification content if version specific content is not found.
*
* @var string
*/
private static $defaultContentVersion = 'default';

/**
* @var ClientInterface
*/
private $httpClient;

/**
* @var ScopeConfigInterface
*/
private $config;

/**
* @var ProductMetadataInterface
*/
private $productMetadata;

/**
* @var Session
*/
private $session;

/**
* @var ResponseResolver
*/
private $responseResolver;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param ClientInterface $httpClient
* @param ScopeConfigInterface $config
* @param ProductMetadataInterface $productMetadata
* @param Session $session
* @param ResponseResolver $responseResolver
* @param LoggerInterface $logger
*/
public function __construct(
ClientInterface $httpClient,
ScopeConfigInterface $config,
ProductMetadataInterface $productMetadata,
Session $session,
ResponseResolver $responseResolver,
LoggerInterface $logger
) {
$this->httpClient = $httpClient;
$this->config = $config;
$this->productMetadata = $productMetadata;
$this->session = $session;
$this->responseResolver = $responseResolver;
$this->logger = $logger;
}

/**
* @inheritdoc
*/
public function getContent()
{
$result = false;

$url = $this->buildUrl(
$this->config->getValue(self::$notificationUrlConfigPath),
[
'version' => $this->getTargetVersion(),
'edition' => $this->productMetadata->getEdition(),
'locale' => $this->session->getUser()->getInterfaceLocale()
]
);

try {
$response = $this->getResponse($url);
if ($response == "[]") {
$response = $this->getDefaultContent();
}
$status = $this->httpClient->getStatus();
$result = $this->responseResolver->getResult($response, $status);
} catch (\Exception $e) {
$this->logger->warning(
sprintf(
'Retrieving the release notification content from the Magento Marketing service has failed: %s',
!empty($response) ? $response : 'Response body is empty.'
)
);
$this->logger->critical(
new \Exception(
sprintf('Magento Marketing service CURL connection error: %s', $e->getMessage())
)
);
}

return $result;
}

/**
* Returns the default content as a fallback if there is no content retrieved from the service/
*
* @return string
*/
private function getDefaultContent()
{
$url = $this->buildUrl(
$this->config->getValue(self::$notificationUrlConfigPath),
[
'version' => self::$defaultContentVersion,
'edition' => $this->productMetadata->getEdition(),
'locale' => $this->session->getUser()->getInterfaceLocale()
]
);
return $this->getResponse($url);
}

/**
* Returns the response body from the HTTP client
*
* @param $url
*
* @return string
*/
private function getResponse($url)
{
$this->httpClient->get($url);
return $this->httpClient->getBody();
}

/**
* Returns the current Magento version used to retrieve the release notification content.
* Version information after the dash (-) character is removed (ex. -dev or -rc).
*
* @return string
*/
private function getTargetVersion()
{
$metadataVersion = $this->productMetadata->getVersion();
$version = strstr($metadataVersion, '-', true);

return !$version ? $metadataVersion : $version;
}

/**
* Builds the URL to request the release notification content data based on passed query parameters.
*
* @param $baseUrl
* @param $queryData
* @return string
*/
private function buildUrl($baseUrl, $queryData)
{
$query = http_build_query($queryData, '', '&');
$baseUrl .= '?' . $query;
return $baseUrl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\ReleaseNotification\Model\Connector\Http;

use Magento\Framework\Serialize\SerializerInterface;
use Magento\ReleaseNotification\Model\Connector\ResponseHandlerInterface;

/**
* Class ResponseResolver
*
* Extract result from http response. Call response handler by status.
*/
class ResponseResolver
{
/**
* @var SerializerInterface
*/
private $serializer;

/**
* @var array
*/
private $responseHandlers;

/**
* @param SerializerInterface $serializer
* @param ResponseHandlerInterface[] $responseHandlers
*/
public function __construct(
SerializerInterface $serializer,
array $responseHandlers = []
) {
$this->serializer = $serializer;
$this->responseHandlers = $responseHandlers;
}

/**
* @param string $response
* @param int $status
* @return bool|string
*/
public function getResult($response, $status)
{
$result = false;
$responseBody = $this->serializer->unserialize($response);
if (array_key_exists($status, $this->responseHandlers)) {
$result = $this->responseHandlers[$status]->handleResponse($responseBody);
}

return $result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\ReleaseNotification\Model\Connector\ResponseHandler;

use Magento\ReleaseNotification\Model\Connector\ResponseHandlerInterface;

/**
* Class NotificationResponse
*
* Retrieves release notification data from the response body
*/
class NotificationResponse implements ResponseHandlerInterface
{
/**
* @param array $responseBody
*
* @return array|false
*/
public function handleResponse(array $responseBody)
{
return !empty($responseBody) ? $responseBody : false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\ReleaseNotification\Model\Connector;

/**
* Class ResponseHandlerInterface
*
* Represents an interface for response handler which process response body.
*/
interface ResponseHandlerInterface
{
/**
* @param array $responseBody
* @return bool|string
*/
public function handleResponse(array $responseBody);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\ReleaseNotification\Model;

/**
* Class ContentProviderInterface
*
* Requests the release notification content data from a defined service
*/
interface ContentProviderInterface
{
/**
* Retrieves the release notification content data.
*
* Returns received content or FALSE in case of failure.
*
* @return string|false
*/
public function getContent();
}
Loading

0 comments on commit da443ff

Please sign in to comment.