forked from wallabag/wallabag
Use custom event instead of Doctrine ones
This give us ability to use Entry ID to determine where to store images and it’s then more easy to remove them when we remove the entry.
This commit is contained in:
@ -6,6 +6,7 @@ use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
use GuzzleHttp\Client;
|
||||
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
class DownloadImages
|
||||
{
|
||||
@ -17,27 +18,17 @@ class DownloadImages
|
||||
private $mimeGuesser;
|
||||
private $wallabagUrl;
|
||||
|
||||
public function __construct(Client $client, $baseFolder, LoggerInterface $logger)
|
||||
public function __construct(Client $client, $baseFolder, $wallabagUrl, LoggerInterface $logger)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->baseFolder = $baseFolder;
|
||||
$this->wallabagUrl = rtrim($wallabagUrl, '/');
|
||||
$this->logger = $logger;
|
||||
$this->mimeGuesser = new MimeTypeExtensionGuesser();
|
||||
|
||||
$this->setFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Since we can't inject CraueConfig service because it'll generate a circular reference when injected in the subscriber
|
||||
* we use a different way to inject the current wallabag url.
|
||||
*
|
||||
* @param string $url Usually from `$config->get('wallabag_url')`
|
||||
*/
|
||||
public function setWallabagUrl($url)
|
||||
{
|
||||
$this->wallabagUrl = rtrim($url, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup base folder where all images are going to be saved.
|
||||
*/
|
||||
@ -52,23 +43,24 @@ class DownloadImages
|
||||
/**
|
||||
* Process the html and extract image from it, save them to local and return the updated html.
|
||||
*
|
||||
* @param int $entryId ID of the entry
|
||||
* @param string $html
|
||||
* @param string $url Used as a base path for relative image and folder
|
||||
* @param string $url Used as a base path for relative image and folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function processHtml($html, $url)
|
||||
public function processHtml($entryId, $html, $url)
|
||||
{
|
||||
$crawler = new Crawler($html);
|
||||
$result = $crawler
|
||||
->filterXpath('//img')
|
||||
->extract(array('src'));
|
||||
|
||||
$relativePath = $this->getRelativePath($url);
|
||||
$relativePath = $this->getRelativePath($entryId);
|
||||
|
||||
// download and save the image to the folder
|
||||
foreach ($result as $image) {
|
||||
$imagePath = $this->processSingleImage($image, $url, $relativePath);
|
||||
$imagePath = $this->processSingleImage($entryId, $image, $url, $relativePath);
|
||||
|
||||
if (false === $imagePath) {
|
||||
continue;
|
||||
@ -86,24 +78,27 @@ class DownloadImages
|
||||
* - re-saved it (for security reason)
|
||||
* - return the new local path.
|
||||
*
|
||||
* @param int $entryId ID of the entry
|
||||
* @param string $imagePath Path to the image to retrieve
|
||||
* @param string $url Url from where the image were found
|
||||
* @param string $relativePath Relative local path to saved the image
|
||||
*
|
||||
* @return string Relative url to access the image from the web
|
||||
*/
|
||||
public function processSingleImage($imagePath, $url, $relativePath = null)
|
||||
public function processSingleImage($entryId, $imagePath, $url, $relativePath = null)
|
||||
{
|
||||
if (null == $relativePath) {
|
||||
$relativePath = $this->getRelativePath($url);
|
||||
if (null === $relativePath) {
|
||||
$relativePath = $this->getRelativePath($entryId);
|
||||
}
|
||||
|
||||
$this->logger->debug('DownloadImages: working on image: '.$imagePath);
|
||||
|
||||
$folderPath = $this->baseFolder.'/'.$relativePath;
|
||||
|
||||
// build image path
|
||||
$absolutePath = $this->getAbsoluteLink($url, $imagePath);
|
||||
if (false === $absolutePath) {
|
||||
$this->logger->log('error', 'Can not determine the absolute path for that image, skipping.');
|
||||
$this->logger->error('DownloadImages: Can not determine the absolute path for that image, skipping.');
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -111,15 +106,15 @@ class DownloadImages
|
||||
try {
|
||||
$res = $this->client->get($absolutePath);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->log('error', 'Can not retrieve image, skipping.', ['exception' => $e]);
|
||||
$this->logger->error('DownloadImages: Can not retrieve image, skipping.', ['exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$ext = $this->mimeGuesser->guess($res->getHeader('content-type'));
|
||||
$this->logger->log('debug', 'Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]);
|
||||
$this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]);
|
||||
if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) {
|
||||
$this->logger->log('error', 'Processed image with not allowed extension. Skipping '.$imagePath);
|
||||
$this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping '.$imagePath);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -133,7 +128,7 @@ class DownloadImages
|
||||
}
|
||||
|
||||
if (false === $im) {
|
||||
$this->logger->log('error', 'Error while regenerating image', ['path' => $localPath]);
|
||||
$this->logger->error('DownloadImages: Error while regenerating image', ['path' => $localPath]);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -141,16 +136,16 @@ class DownloadImages
|
||||
switch ($ext) {
|
||||
case 'gif':
|
||||
$result = imagegif($im, $localPath);
|
||||
$this->logger->log('debug', 'Re-creating gif');
|
||||
$this->logger->debug('DownloadImages: Re-creating gif');
|
||||
break;
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
$result = imagejpeg($im, $localPath, self::REGENERATE_PICTURES_QUALITY);
|
||||
$this->logger->log('debug', 'Re-creating jpg');
|
||||
$this->logger->debug('DownloadImages: Re-creating jpg');
|
||||
break;
|
||||
case 'png':
|
||||
$result = imagepng($im, $localPath, ceil(self::REGENERATE_PICTURES_QUALITY / 100 * 9));
|
||||
$this->logger->log('debug', 'Re-creating png');
|
||||
$this->logger->debug('DownloadImages: Re-creating png');
|
||||
}
|
||||
|
||||
imagedestroy($im);
|
||||
@ -158,24 +153,47 @@ class DownloadImages
|
||||
return $this->wallabagUrl.'/assets/images/'.$relativePath.'/'.$hashImage.'.'.$ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all images for the given entry id.
|
||||
*
|
||||
* @param int $entryId ID of the entry
|
||||
*/
|
||||
public function removeImages($entryId)
|
||||
{
|
||||
$relativePath = $this->getRelativePath($entryId);
|
||||
$folderPath = $this->baseFolder.'/'.$relativePath;
|
||||
|
||||
$finder = new Finder();
|
||||
$finder
|
||||
->files()
|
||||
->ignoreDotFiles(true)
|
||||
->in($folderPath);
|
||||
|
||||
foreach ($finder as $file) {
|
||||
@unlink($file->getRealPath());
|
||||
}
|
||||
|
||||
@rmdir($folderPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the folder where we are going to save images based on the entry url.
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $entryId ID of the entry
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getRelativePath($url)
|
||||
private function getRelativePath($entryId)
|
||||
{
|
||||
$hashUrl = hash('crc32', $url);
|
||||
$relativePath = $hashUrl[0].'/'.$hashUrl[1].'/'.$hashUrl;
|
||||
$hashId = hash('crc32', $entryId);
|
||||
$relativePath = $hashId[0].'/'.$hashId[1].'/'.$hashId;
|
||||
$folderPath = $this->baseFolder.'/'.$relativePath;
|
||||
|
||||
if (!file_exists($folderPath)) {
|
||||
mkdir($folderPath, 0777, true);
|
||||
}
|
||||
|
||||
$this->logger->log('debug', 'Folder used for that url', ['folder' => $folderPath, 'url' => $url]);
|
||||
$this->logger->debug('DownloadImages: Folder used for that Entry id', ['folder' => $folderPath, 'entryId' => $entryId]);
|
||||
|
||||
return $relativePath;
|
||||
}
|
||||
@ -208,7 +226,7 @@ class DownloadImages
|
||||
return $absolute->get_uri();
|
||||
}
|
||||
|
||||
$this->logger->log('error', 'Can not make an absolute link', ['base' => $base, 'url' => $url]);
|
||||
$this->logger->error('DownloadImages: Can not make an absolute link', ['base' => $base, 'url' => $url]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user