first commit
This commit is contained in:
141
bundles/KupShop/CDNBundle/Controller/CDNController.php
Normal file
141
bundles/KupShop/CDNBundle/Controller/CDNController.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user