Skip to content

Commit 43dee04

Browse files
committed
added command to fetch media from url, fixed erroneus 404 not found error page upon media deletion, updated composer.json required php extensions, updated php-fpm dockerfile to include jpeg support
1 parent 447d7a3 commit 43dee04

File tree

5 files changed

+164
-40
lines changed

5 files changed

+164
-40
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
/**
4+
* SiteBase
5+
* PHP Version 8.3
6+
*
7+
* @category CMS / Framework
8+
* @package Degami\Sitebase
9+
* @author Mirko De Grandis <degami@github.com>
10+
* @license MIT https://opensource.org/licenses/mit-license.php
11+
* @link https://github.com/degami/sitebase
12+
*/
13+
14+
namespace App\Site\Commands\Media;
15+
16+
use App\App;
17+
use App\Base\Abstracts\Commands\BaseCommand;
18+
use App\Site\Models\MediaElement;
19+
use Degami\Basics\Exceptions\BasicException;
20+
use DI\DependencyException;
21+
use DI\NotFoundException;
22+
use Exception;
23+
use InvalidArgumentException;
24+
use Phpfastcache\Exceptions\PhpfastcacheSimpleCacheException;
25+
use Symfony\Component\Console\Input\InputInterface;
26+
use Symfony\Component\Console\Output\OutputInterface;
27+
use Symfony\Component\Console\Command\Command;
28+
use SplFileInfo;
29+
use Symfony\Component\Console\Input\InputArgument;
30+
31+
class FetchFromUrl extends BaseCommand
32+
{
33+
protected function configure()
34+
{
35+
$this->setDescription('Fetch Media Element from url')
36+
->addArgument('url', InputArgument::REQUIRED, 'Url to fetch')
37+
->addArgument('target', InputArgument::OPTIONAL, 'Target path');
38+
}
39+
40+
/**
41+
* @throws BasicException
42+
* @throws DependencyException
43+
* @throws NotFoundException
44+
* @throws PhpfastcacheSimpleCacheException
45+
* @throws \Throwable
46+
*/
47+
protected function execute(InputInterface $input, OutputInterface $output): int
48+
{
49+
$media_path = App::getDir(App::MEDIA);
50+
$url = $input->getArgument('url');
51+
$target_path = $input->getArgument('target');
52+
if (is_null($target_path)) {
53+
$parsed = parse_url($url);
54+
$file_name = basename($parsed['path']);
55+
$target_path = $media_path . DS . $file_name;
56+
} else {
57+
try {
58+
/** @var MediaElement $element */
59+
$element = MediaElement::loadBy('path', $target_path);
60+
if ($element->isDirectory()) {
61+
$parsed = parse_url($url);
62+
$file_name = basename($parsed['path']);
63+
$target_path = $element->getPath() . DS . $file_name;
64+
} else {
65+
$this->getIo()->error("$target_path is existing and is not a folder");
66+
return Command::FAILURE;
67+
}
68+
} catch (Exception $e) {
69+
if (!($e instanceof \App\Base\Exceptions\NotFoundException)) {
70+
throw $e;
71+
}
72+
// path is not existing
73+
}
74+
}
75+
if (!str_starts_with($target_path, $media_path)) {
76+
throw new Exception("Target path must be under ".$media_path);
77+
}
78+
79+
$this->getIo()->info("Downloading $url to $target_path");
80+
$mediaElement = MediaElement::createFromUrl($url, $target_path);
81+
$mediaElement->persist();
82+
83+
$this->getIo()->success("Media Element downloaded to ".$mediaElement->getPath());
84+
85+
return Command::SUCCESS;
86+
}
87+
}

app/site/controllers/Admin/Cms/Media.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use App\Base\Abstracts\Models\BaseCollection;
3232
use Degami\Basics\Html\TagElement;
3333
use App\Site\Models\DownloadableProduct;
34+
use Exception;
3435

3536
/**
3637
* "Media" Admin Page
@@ -125,9 +126,14 @@ function ($el) {
125126
}
126127

127128
if ($this->getRequest()->query->get('media_id')) {
128-
$media = $this->containerCall([MediaElement::class, 'load'], ['id' => $this->getRequest()->query->get('media_id')]);
129-
if ($media->getParentId()) {
130-
$queryParams = ['parent_id' => $media->getParentId()];
129+
try {
130+
$media = $this->containerCall([MediaElement::class, 'load'], ['id' => $this->getRequest()->query->get('media_id')]);
131+
if ($media->getParentId()) {
132+
$queryParams = ['parent_id' => $media->getParentId()];
133+
}
134+
} catch (Exception $e) {
135+
// in case of media deletion, construct is called even after deletion with the same media_id, causing a 404 not found
136+
// if this catch is not here
131137
}
132138
}
133139

app/site/models/MediaElement.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,11 @@ public static function createFromUrl(string $url, ?string $destinationPath = nul
820820
if (!$contents) {
821821
throw new NotFoundException("No contents to download found on url " . $url);
822822
}
823+
$im = new \Imagick();
824+
$im->readImageBlob($contents); // carica l'immagine dalla stringa
825+
$im->stripImage(); // rimuove EXIF, ICC e altri metadati
826+
$cleanData = $im->getImageBlob(); // ottieni l'immagine pulita come stringa
827+
823828

824829
$destinationPath = rtrim($path, DS) . DS . ltrim($filename, DS);
825830

@@ -834,15 +839,15 @@ public static function createFromUrl(string $url, ?string $destinationPath = nul
834839
throw new DuplicateException(App::getInstance()->getUtils()->translate("%s is already existing into destination path", [$destinationPath]));
835840
}
836841

837-
@file_put_contents($destinationPath, $contents);
842+
@file_put_contents($destinationPath, $cleanData);
838843

839844
$out
840845
->setPath($destinationPath)
841846
->setFilename($filename)
842847
->setFilesize(intval(@filesize($destinationPath)))
843848
->setMimetype(@mime_content_type($destinationPath) ?: null)
844849
->setLazyload(false)
845-
->setUserId(App::getInstance()->getAuth()->getCurrentUser()?->getId())
850+
->setUserId(App::getInstance()->getAuth()->getCurrentUser()?->getId() ?: null)
846851
->setParentId($parent_id);
847852

848853
return $out;

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"ext-fileinfo": "*",
1717
"ext-zip": "*",
1818
"ext-redis": "*",
19+
"ext-gd": "*",
20+
"ext-simplexml": "*",
21+
"ext-imagick": "*",
1922
"php-di/php-di": "^6.0",
2023
"degami/php-forms-api": "dev-master",
2124
"degami/sql-schema": "dev-master",

docker/php-fpm/Dockerfile

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,62 @@ ENV GROUPNAME=$USER
55
ENV UID=1000
66
ENV GID=1000
77

8-
RUN addgroup \
9-
--gid "$GID" \
10-
"$GROUPNAME" \
11-
&& adduser \
12-
--disabled-password \
13-
--gecos "" \
14-
--home "$(pwd)" \
15-
--ingroup "$GROUPNAME" \
16-
--no-create-home \
17-
--uid "$UID" \
18-
$USER
19-
20-
RUN apk add zlib zlib-dev libpng libpng-dev git bash libffi libffi-dev libxml2 libxml2-dev libsodium libsodium-dev libzip libzip-dev
21-
RUN docker-php-ext-install pdo_mysql gd pdo fileinfo simplexml sodium zip
22-
RUN apk add npm ruby ruby-dev
23-
RUN apk add --update build-base libffi-dev
24-
RUN apk add --no-cache $PHPIZE_DEPS && pecl install xdebug && docker-php-ext-enable xdebug
25-
RUN apk add --no-cache $PHPIZE_DEPS && pecl install redis && docker-php-ext-enable redis
26-
RUN docker-php-ext-enable xdebug pdo_mysql gd fileinfo sodium
8+
# Creazione utente
9+
RUN addgroup --gid "$GID" "$GROUPNAME" \
10+
&& adduser --disabled-password --gecos "" --home "$(pwd)" --ingroup "$GROUPNAME" --no-create-home --uid "$UID" $USER
11+
12+
# Dipendenze di sistema
13+
RUN apk add --no-cache \
14+
bash \
15+
git \
16+
zlib zlib-dev \
17+
libpng libpng-dev \
18+
libjpeg-turbo-dev \
19+
freetype-dev \
20+
libffi libffi-dev \
21+
libxml2 libxml2-dev \
22+
libsodium libsodium-dev \
23+
libzip libzip-dev \
24+
imagemagick-dev \
25+
build-base \
26+
autoconf \
27+
pkgconfig \
28+
npm \
29+
ruby ruby-dev \
30+
openjdk11-jre \
31+
graphviz \
32+
wget \
33+
curl
34+
35+
# Compilazione GD con JPEG e FreeType
36+
RUN docker-php-ext-configure gd \
37+
--with-jpeg=/usr/include/ \
38+
--with-freetype=/usr/include/ \
39+
&& docker-php-ext-install -j$(nproc) gd pdo_mysql pdo fileinfo simplexml sodium zip
40+
41+
# PECL extensions
42+
RUN apk add --no-cache $PHPIZE_DEPS \
43+
&& pecl install xdebug redis imagick \
44+
&& docker-php-ext-enable xdebug redis imagick
45+
46+
# Node & Gulp
2747
RUN npm install -g gulp
28-
#RUN gem install compass compass-rgbapng
29-
RUN apk add graphviz plantuml
30-
RUN wget https://phpdoc.org/phpDocumentor.phar -O /usr/local/bin/phpdoc
31-
RUN chmod 775 /usr/local/bin/phpdoc
32-
RUN wget https://getcomposer.org/download/latest-stable/composer.phar -O /usr/local/bin/composer
33-
RUN chmod 775 /usr/local/bin/composer
34-
35-
RUN apk add openjdk11-jre
36-
RUN curl -L -o /usr/local/bin/plantuml.jar https://downloads.sourceforge.net/project/plantuml/plantuml.jar && \
37-
echo -e '#!/bin/sh\njava -jar /usr/local/bin/plantuml.jar \"$@\"' > /usr/local/bin/plantuml && \
38-
chmod +x /usr/local/bin/plantuml /usr/local/bin/plantuml.jar
39-
40-
RUN composer global require maglnet/composer-require-checker
41-
RUN composer global require ergebnis/composer-normalize
42-
43-
USER sitebase
48+
49+
# PlantUML
50+
RUN curl -L -o /usr/local/bin/plantuml.jar https://downloads.sourceforge.net/project/plantuml/plantuml.jar \
51+
&& echo -e '#!/bin/sh\njava -jar /usr/local/bin/plantuml.jar "$@"' > /usr/local/bin/plantuml \
52+
&& chmod +x /usr/local/bin/plantuml /usr/local/bin/plantuml.jar
53+
54+
# PHPDoc
55+
RUN wget https://phpdoc.org/phpDocumentor.phar -O /usr/local/bin/phpdoc \
56+
&& chmod 775 /usr/local/bin/phpdoc
57+
58+
# Composer
59+
RUN curl -L -o /usr/local/bin/composer https://getcomposer.org/download/latest-stable/composer.phar \
60+
&& chmod 775 /usr/local/bin/composer
61+
62+
# Composer global packages
63+
RUN composer global require maglnet/composer-require-checker \
64+
&& composer global require ergebnis/composer-normalize
65+
66+
USER sitebase

0 commit comments

Comments
 (0)