PHP code example of cedricziel / canva-extension-helper
1. Go to this page and download the library: Download cedricziel/canva-extension-helper library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
cedricziel / canva-extension-helper example snippets
namespace App\Controller\Canva;
use Canva\Error;
use Canva\HttpHelper;
use Canva\Publish\ErrorResponse;
use Canva\Publish\UploadRequest;
use Canva\Publish\UploadResponse;
use Canva\Request as CanvaRequest;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
/**
* @Route(path="/canva/extensions/publish", name="canva_publish")
*/
class PublishExtensionController extends AbstractController implements EventSubscriberInterface
{
private string $canvaSecret;
public function __construct(string $canvaSecret)
{
$this->canvaSecret = $canvaSecret;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
/**
* @Route("/configuration", name="_configuration", methods={"POST"})
*/
public function configuration(): Response
{
return $this->json(new ErrorResponse(Error::CODE_INVALID_REQUEST));
}
/**
* @Route("/resources/find", name="_resources_find", methods={"POST"})
*/
public function resourcesFind(): Response
{
return $this->json(new ErrorResponse(Error::CODE_INVALID_REQUEST));
}
/**
* @Route("/resources/get", name="_resources_get", methods={"POST"})
*/
public function resourcesGet(): Response
{
return $this->json(new ErrorResponse(Error::CODE_INVALID_REQUEST));
}
/**
* @Route("/resources/upload", name="_resources_upload")
*/
public function resourcesUpload(Request $request, HttpClientInterface $httpClient, SerializerInterface $serializer): Response
{
try {
/** @var UploadRequest $uploadRequest */
$uploadRequest = $serializer->deserialize($request->getContent(), UploadRequest::class, 'json');
foreach ($uploadRequest->getAssets() as $asset) {
// do something with the result
$httpClient->request('GET', $asset->getUrl());
}
return $this->json(new UploadResponse());
} catch (InvalidArgumentException $exception) {
return $this->json(new ErrorResponse(Error::CODE_INVALID_REQUEST));
}
}
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
$request = $event->getRequest();
// when a controller class defines multiple action methods, the controller
// is returned as [$controllerInstance, 'methodName']
if (is_array($controller)) {
$controller = $controller[0];
}
/**
* Every publish extension endpoint is invoked via POST and needs
* signature AND timestamp checking.
*/
if ($controller instanceof self) {
$timestampHeader = $request->headers->get(CanvaRequest::HEADER_TIMESTAMP);
if ($timestampHeader === null || !HttpHelper::verifyTimestamp($timestampHeader, time())) {
throw new HttpException(401, 'Timestamp skew is too large.');
}
$path = parse_url($request->getUri(), PHP_URL_PATH);
$operation = '';
switch (true) {
case str_ends_with($path, '/configuration'):
$operation = '/configuration';
break;
case str_ends_with($path, '/publish/resources/find'):
$operation = '/publish/resources/find';
break;
case str_ends_with($path, '/publish/resources/get'):
$operation = '/publish/resources/get';
break;
case str_ends_with($path, '/publish/resources/upload'):
$operation = '/publish/resources/upload';
break;
default:
throw new HttpException(401, 'Unknown operation');
}
$signature = HttpHelper::calculatePostSignature(
$timestampHeader,
$operation,
$request->getContent(),
$this->canvaSecret
);
$signatureHeader = $request->headers->get(CanvaRequest::HEADER_SIGNATURES);
if ($signatureHeader === null || !in_array($signature, explode(',', $signatureHeader), true)) {
throw new HttpException(401, 'Signatures do not match');
}
}
}
}
use Canva\Publish\GetResourceRequest;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
use Symfony\Component\Serializer\Serializer;
// the json chunk extracted from the request body
$request = '...';
$encoders = [new JsonEncoder()];
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$normalizers = [new ArrayDenormalizer(), new ObjectNormalizer(null, null, null, $extractor), new PropertyNormalizer(), new GetSetMethodNormalizer()];
/** @var GetResourceRequest $getResourceRequest */
$getResourceRequest = $serializer->deserialize($request, GetResourceRequest::class, 'json');
// allow a skew of 300 seconds
$leniency = 300;
// the timestamp at which the request was received
$localTimestamp = time();
// the timestamp at which the request was sent
$sentTimestamp = $_SERVER['HTTP_X_CANVA_TIMESTAMP'];
// returns a boolean whether the timestamps are close enough together
$timestampIsOkay = \Canva\HttpHelper::verifyTimestamp($sentTimestamp, $localTimestamp, $leniency)
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.