142 lines
4.1 KiB
PHP
142 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace KupShop\CDNBundle\Controller;
|
|
|
|
use KupShop\KupShopBundle\Util\System\UrlFinder;
|
|
use Psr\Log\LoggerInterface;
|
|
use Query\Operator;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
|
|
class CDNController extends AbstractController
|
|
{
|
|
/** @var LoggerInterface */
|
|
protected $logger;
|
|
|
|
/**
|
|
* @required
|
|
*/
|
|
public function setLogger(LoggerInterface $logger): void
|
|
{
|
|
$this->logger = $logger;
|
|
}
|
|
|
|
/**
|
|
* @Route("/_cdn/", methods={"POST"})
|
|
*
|
|
* @return Response
|
|
*/
|
|
public function WebhookAction(Request $request)
|
|
{
|
|
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
|
|
$data = json_decode($request->getContent(), true);
|
|
$this->logger->notice('CDN Webhook Request', [
|
|
'url' => $request->getUri(),
|
|
'data' => $data,
|
|
]);
|
|
|
|
/* Status finished */
|
|
if ($data['Status'] === 3) {
|
|
$photo = sqlQueryBuilder()
|
|
->select('p.id id, p.filename, p.descr, v.id_cdn id_video')
|
|
->from('photos', 'p')
|
|
->innerJoin('p', 'videos', 'v', 'p.id = v.id_photo')
|
|
->where(Operator::equals(['id_cdn' => $data['VideoGuid']]))
|
|
->execute()
|
|
->fetch();
|
|
if ($photo) {
|
|
$img = new \Photos();
|
|
$img->newImage($photo['id']);
|
|
if (!$img->refreshVideoThumbnail($photo)) {
|
|
$this->logger->notice('CDN Webhook Failed', [
|
|
'url' => $request->getUri(),
|
|
'data' => $data,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return new Response('OK', 200);
|
|
}
|
|
|
|
return new Response('', 400);
|
|
}
|
|
|
|
/**
|
|
* @Route("/_cdn/typekit/{id}")
|
|
*
|
|
* @return Response
|
|
*/
|
|
public function typekitAction(string $id, UrlFinder $urlFinder)
|
|
{
|
|
$url = "https://use.typekit.net/{$id}.css";
|
|
|
|
$response = $this->downloadToResponse($url);
|
|
$css = $response->getContent();
|
|
|
|
// Remove tracking url
|
|
$css = preg_replace('@^.*https://p\.typekit\.net.*$@m', '', $css);
|
|
|
|
if ($urlFinder->hasCDN()) {
|
|
// Replace font urls
|
|
$css = preg_replace('@https://use\.typekit\.net@m', $urlFinder->staticUrlAbsolute('/_cdn/font'), $css);
|
|
}
|
|
|
|
$response->setContent($css);
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* @Route("/_cdn/font/{path}", requirements={"path":".*"})
|
|
*
|
|
* @return Response
|
|
*/
|
|
public function typekitFontAction(Request $request, string $path)
|
|
{
|
|
$url = "https://use.typekit.net/{$path}?{$request->getQueryString()}";
|
|
|
|
return $this->downloadToResponse($url);
|
|
}
|
|
|
|
protected function downloadToResponse(string $url): Response
|
|
{
|
|
$ch = curl_init();
|
|
$headers = [];
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
// this function is called by curl for each header received
|
|
curl_setopt($ch, CURLOPT_HEADERFUNCTION,
|
|
function ($curl, $header) use (&$headers) {
|
|
$len = strlen($header);
|
|
$header = explode(':', $header, 2);
|
|
if (count($header) < 2) { // ignore invalid headers
|
|
return $len;
|
|
}
|
|
|
|
$headers[strtolower(trim($header[0]))][] = trim($header[1]);
|
|
|
|
return $len;
|
|
}
|
|
);
|
|
|
|
$data = curl_exec($ch);
|
|
|
|
unset($headers['content-length']);
|
|
|
|
$response = new Response($data);
|
|
$response->headers->replace($headers);
|
|
|
|
// Force cacheable
|
|
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
|
|
$response->setPublic();
|
|
$response->setMaxAge(3600);
|
|
|
|
return $response;
|
|
}
|
|
}
|