mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Uploaded (non secure) attachments live now in public/
That way the attachment files can now be loaded much quicker (without invoking a controller). Also added thumbnailing for pictures in tables.
This commit is contained in:
parent
1b28006267
commit
4fe10b6169
21 changed files with 552 additions and 21 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -26,3 +26,7 @@
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
###< symfony/webpack-encore-bundle ###
|
###< symfony/webpack-encore-bundle ###
|
||||||
|
|
||||||
|
###> liip/imagine-bundle ###
|
||||||
|
/public/media/cache/
|
||||||
|
###< liip/imagine-bundle ###
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
"license": "GPL-2.0-or-later",
|
"license": "GPL-2.0-or-later",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1.3",
|
"php": "^7.1.3",
|
||||||
|
"ext-bcmath": "*",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"ext-intl": "*",
|
"ext-intl": "*",
|
||||||
|
"ext-json": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
"doctrine/annotations": "^1.6",
|
"doctrine/annotations": "^1.6",
|
||||||
"florianv/swap": "^4.0",
|
"florianv/swap": "^4.0",
|
||||||
"friendsofsymfony/ckeditor-bundle": "^2.0",
|
"friendsofsymfony/ckeditor-bundle": "^2.0",
|
||||||
|
"liip/imagine-bundle": "^2.2",
|
||||||
"nyholm/psr7": "^1.1",
|
"nyholm/psr7": "^1.1",
|
||||||
"ocramius/proxy-manager": "2.1.*",
|
"ocramius/proxy-manager": "2.1.*",
|
||||||
"omines/datatables-bundle": "^0.3.1",
|
"omines/datatables-bundle": "^0.3.1",
|
||||||
|
@ -42,9 +46,7 @@
|
||||||
"twig/extensions": "^1.5",
|
"twig/extensions": "^1.5",
|
||||||
"twig/extra-bundle": "3.x-dev",
|
"twig/extra-bundle": "3.x-dev",
|
||||||
"twig/intl-extra": "3.x-dev",
|
"twig/intl-extra": "3.x-dev",
|
||||||
"webmozart/assert": "^1.4",
|
"webmozart/assert": "^1.4"
|
||||||
"ext-bcmath": "*",
|
|
||||||
"ext-json": "*"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"roave/security-advisories": "dev-master",
|
"roave/security-advisories": "dev-master",
|
||||||
|
|
223
composer.lock
generated
223
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "b991c6efd2c3ad84f8c1f76ae8efac2c",
|
"content-hash": "634b7b41a97404c6278ed91d1926f853",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "clue/stream-filter",
|
"name": "clue/stream-filter",
|
||||||
|
@ -1756,6 +1756,64 @@
|
||||||
],
|
],
|
||||||
"time": "2019-07-01T23:21:34+00:00"
|
"time": "2019-07-01T23:21:34+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "imagine/imagine",
|
||||||
|
"version": "1.2.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/avalanche123/Imagine.git",
|
||||||
|
"reference": "eec39b2092bc8008a92b8d63824476413dbe7511"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/avalanche123/Imagine/zipball/eec39b2092bc8008a92b8d63824476413dbe7511",
|
||||||
|
"reference": "eec39b2092bc8008a92b8d63824476413dbe7511",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "2.2.*",
|
||||||
|
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.4"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-gd": "to use the GD implementation",
|
||||||
|
"ext-gmagick": "to use the Gmagick implementation",
|
||||||
|
"ext-imagick": "to use the Imagick implementation"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-develop": "0.7-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Imagine\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Bulat Shakirzyanov",
|
||||||
|
"email": "mallluhuct@gmail.com",
|
||||||
|
"homepage": "http://avalanche123.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Image processing for PHP 5.3",
|
||||||
|
"homepage": "http://imagine.readthedocs.org/",
|
||||||
|
"keywords": [
|
||||||
|
"drawing",
|
||||||
|
"graphics",
|
||||||
|
"image manipulation",
|
||||||
|
"image processing"
|
||||||
|
],
|
||||||
|
"time": "2019-07-09T06:55:48+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "jdorn/sql-formatter",
|
"name": "jdorn/sql-formatter",
|
||||||
"version": "v1.2.17",
|
"version": "v1.2.17",
|
||||||
|
@ -1806,6 +1864,107 @@
|
||||||
],
|
],
|
||||||
"time": "2014-01-12T16:20:24+00:00"
|
"time": "2014-01-12T16:20:24+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "liip/imagine-bundle",
|
||||||
|
"version": "2.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/liip/LiipImagineBundle.git",
|
||||||
|
"reference": "2cf633e0f335a9f1f0bb9d55726a73aca9259ea4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/liip/LiipImagineBundle/zipball/2cf633e0f335a9f1f0bb9d55726a73aca9259ea4",
|
||||||
|
"reference": "2cf633e0f335a9f1f0bb9d55726a73aca9259ea4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"imagine/imagine": "^0.7.1|^1.1",
|
||||||
|
"php": "^7.1",
|
||||||
|
"symfony/asset": "^3.4|^4.2",
|
||||||
|
"symfony/filesystem": "^3.4|^4.2",
|
||||||
|
"symfony/finder": "^3.4|^4.2",
|
||||||
|
"symfony/framework-bundle": "^3.4|^4.2",
|
||||||
|
"symfony/options-resolver": "^3.4|^4.2",
|
||||||
|
"symfony/process": "^3.4|^4.2",
|
||||||
|
"symfony/templating": "^3.4|^4.2",
|
||||||
|
"symfony/translation": "^3.4|^4.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"amazonwebservices/aws-sdk-for-php": "^1.0",
|
||||||
|
"aws/aws-sdk-php": "^2.4",
|
||||||
|
"doctrine/cache": "^1.1",
|
||||||
|
"doctrine/orm": "^2.3",
|
||||||
|
"enqueue/enqueue-bundle": "^0.9",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"friendsofphp/php-cs-fixer": "^2.10",
|
||||||
|
"league/flysystem": "^1.0",
|
||||||
|
"psr/log": "^1.0",
|
||||||
|
"symfony/browser-kit": "^3.4|^4.2",
|
||||||
|
"symfony/console": "^3.4|^4.2",
|
||||||
|
"symfony/dependency-injection": "^3.4|^4.2",
|
||||||
|
"symfony/form": "^3.4|^4.2",
|
||||||
|
"symfony/phpunit-bridge": "^4.3",
|
||||||
|
"symfony/validator": "^3.4|^4.2",
|
||||||
|
"symfony/yaml": "^3.4|^4.2",
|
||||||
|
"twig/twig": "^1.34|^2.4"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"alcaeus/mongo-php-adapter": "required on PHP >= 7.0 to use mongo components with mongodb extension",
|
||||||
|
"amazonwebservices/aws-sdk-for-php": "required to use AWS version 1 cache resolver",
|
||||||
|
"aws/aws-sdk-php": "required to use AWS version 2/3 cache resolver",
|
||||||
|
"doctrine/mongodb-odm": "required to use mongodb-backed doctrine components",
|
||||||
|
"enqueue/enqueue-bundle": "^0.9 add if you like to process images in background",
|
||||||
|
"ext-exif": "required to read EXIF metadata from images",
|
||||||
|
"ext-gd": "required to use gd driver",
|
||||||
|
"ext-gmagick": "required to use gmagick driver",
|
||||||
|
"ext-imagick": "required to use imagick driver",
|
||||||
|
"ext-mongo": "required for mongodb components on PHP <7.0",
|
||||||
|
"ext-mongodb": "required for mongodb components on PHP >=7.0",
|
||||||
|
"league/flysystem": "required to use FlySystem data loader or cache resolver",
|
||||||
|
"monolog/monolog": "A psr/log compatible logger is required to enable logging",
|
||||||
|
"twig/twig": "required to use the provided Twig extension. Version 1.12 or greater needed"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-1.0": "1.7-dev",
|
||||||
|
"dev-master": "2.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Liip\\ImagineBundle\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Liip and other contributors",
|
||||||
|
"homepage": "https://github.com/liip/LiipImagineBundle/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "This bundle provides an image manipulation abstraction toolkit for Symfony-based projects.",
|
||||||
|
"homepage": "http://liip.ch",
|
||||||
|
"keywords": [
|
||||||
|
"bundle",
|
||||||
|
"image",
|
||||||
|
"imagine",
|
||||||
|
"liip",
|
||||||
|
"manipulation",
|
||||||
|
"photos",
|
||||||
|
"pictures",
|
||||||
|
"symfony",
|
||||||
|
"transformation"
|
||||||
|
],
|
||||||
|
"time": "2019-10-04T05:45:14+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "1.25.1",
|
"version": "1.25.1",
|
||||||
|
@ -6389,6 +6548,62 @@
|
||||||
"homepage": "http://symfony.com",
|
"homepage": "http://symfony.com",
|
||||||
"time": "2019-06-18T15:27:04+00:00"
|
"time": "2019-06-18T15:27:04+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/templating",
|
||||||
|
"version": "v4.3.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/templating.git",
|
||||||
|
"reference": "15407776e1fe250ed3fa1c1a679482c60c2affe3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/templating/zipball/15407776e1fe250ed3fa1c1a679482c60c2affe3",
|
||||||
|
"reference": "15407776e1fe250ed3fa1c1a679482c60c2affe3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1.3",
|
||||||
|
"symfony/polyfill-ctype": "~1.8"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psr/log": "~1.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"psr/log-implementation": "For using debug logging in loaders"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "4.3-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Templating\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Templating Component",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"time": "2019-08-26T08:26:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/translation",
|
"name": "symfony/translation",
|
||||||
"version": "v4.3.4",
|
"version": "v4.3.4",
|
||||||
|
@ -9023,12 +9238,12 @@
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^7.1.3",
|
"php": "^7.1.3",
|
||||||
|
"ext-bcmath": "*",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"ext-intl": "*",
|
"ext-intl": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-json": "*",
|
||||||
"ext-bcmath": "*",
|
"ext-mbstring": "*"
|
||||||
"ext-json": "*"
|
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"platform-overrides": {
|
"platform-overrides": {
|
||||||
|
|
|
@ -19,4 +19,5 @@ return [
|
||||||
Shivas\VersioningBundle\ShivasVersioningBundle::class => ['all' => true],
|
Shivas\VersioningBundle\ShivasVersioningBundle::class => ['all' => true],
|
||||||
FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true],
|
FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true],
|
||||||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||||
|
Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|
20
config/packages/liip_imagine.yaml
Normal file
20
config/packages/liip_imagine.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# See dos how to configure the bundle: https://symfony.com/doc/current/bundles/LiipImagineBundle/basic-usage.html
|
||||||
|
liip_imagine:
|
||||||
|
# valid drivers options include "gd" or "gmagick" or "imagick"
|
||||||
|
driver: "gd"
|
||||||
|
|
||||||
|
filter_sets:
|
||||||
|
thumbnail_sm:
|
||||||
|
quality: 70
|
||||||
|
filters:
|
||||||
|
thumbnail:
|
||||||
|
size: [150, 150]
|
||||||
|
mode: inset
|
||||||
|
|
||||||
|
thumbnail_md:
|
||||||
|
quality: 75
|
||||||
|
filters:
|
||||||
|
filters:
|
||||||
|
thumbnail:
|
||||||
|
size: [300, 300]
|
||||||
|
mode: inset
|
2
config/routes/liip_imagine.yaml
Normal file
2
config/routes/liip_imagine.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
_liip_imagine:
|
||||||
|
resource: "@LiipImagineBundle/Resources/config/routing.yaml"
|
|
@ -11,7 +11,7 @@ parameters:
|
||||||
banner: '' # The info text shown in the homepage
|
banner: '' # The info text shown in the homepage
|
||||||
use_gravatar: true # Set to false, if no Gravatar images should be used for user profiles.
|
use_gravatar: true # Set to false, if no Gravatar images should be used for user profiles.
|
||||||
default_currency: 'EUR' # The currency that should be used
|
default_currency: 'EUR' # The currency that should be used
|
||||||
media_directory: 'data/media/'
|
media_directory: 'public/media/'
|
||||||
db_version_fallback: '5.6' # Be sure to override this, in your .env with your real DB version
|
db_version_fallback: '5.6' # Be sure to override this, in your .env with your real DB version
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
@ -32,6 +32,9 @@ services:
|
||||||
resource: '../src/Controller'
|
resource: '../src/Controller'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
|
Liip\ImagineBundle\Service\FilterService:
|
||||||
|
alias: 'liip_imagine.service.filter'
|
||||||
|
|
||||||
app.doctrine.elementListener:
|
app.doctrine.elementListener:
|
||||||
class: App\Security\EntityListeners\ElementPermissionListener
|
class: App\Security\EntityListeners\ElementPermissionListener
|
||||||
public: false
|
public: false
|
||||||
|
|
2
data/media/.gitignore
vendored
2
data/media/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
# Ignore everything
|
|
||||||
*
|
|
3
public/media/.gitignore
vendored
Normal file
3
public/media/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Ignore everything except this .gitignore
|
||||||
|
d274.gif
|
||||||
|
!.gitignore
|
BIN
public/media/currency/2/test-5d95f7efefc33.webp
Normal file
BIN
public/media/currency/2/test-5d95f7efefc33.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
public/media/part/1108/test-5d9616224f44a.webp
Normal file
BIN
public/media/part/1108/test-5d9616224f44a.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
public/media/part/2/repositoryopengraphtemplate.png
Normal file
BIN
public/media/part/2/repositoryopengraphtemplate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
|
@ -37,6 +37,7 @@ use App\Entity\Attachments\Attachment;
|
||||||
use App\Entity\Attachments\FootprintAttachment;
|
use App\Entity\Attachments\FootprintAttachment;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use App\Services\AttachmentHelper;
|
use App\Services\AttachmentHelper;
|
||||||
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
use App\Services\ElementTypeNameGenerator;
|
use App\Services\ElementTypeNameGenerator;
|
||||||
use App\Services\EntityURLGenerator;
|
use App\Services\EntityURLGenerator;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
@ -54,14 +55,17 @@ class AttachmentDataTable implements DataTableTypeInterface
|
||||||
protected $entityURLGenerator;
|
protected $entityURLGenerator;
|
||||||
protected $attachmentHelper;
|
protected $attachmentHelper;
|
||||||
protected $elementTypeNameGenerator;
|
protected $elementTypeNameGenerator;
|
||||||
|
protected $attachmentURLGenerator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator, EntityURLGenerator $entityURLGenerator,
|
public function __construct(TranslatorInterface $translator, EntityURLGenerator $entityURLGenerator,
|
||||||
AttachmentHelper $attachmentHelper, ElementTypeNameGenerator $elementTypeNameGenerator)
|
AttachmentHelper $attachmentHelper, AttachmentURLGenerator $attachmentURLGenerator,
|
||||||
|
ElementTypeNameGenerator $elementTypeNameGenerator)
|
||||||
{
|
{
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->entityURLGenerator = $entityURLGenerator;
|
$this->entityURLGenerator = $entityURLGenerator;
|
||||||
$this->attachmentHelper = $attachmentHelper;
|
$this->attachmentHelper = $attachmentHelper;
|
||||||
$this->elementTypeNameGenerator = $elementTypeNameGenerator;
|
$this->elementTypeNameGenerator = $elementTypeNameGenerator;
|
||||||
|
$this->attachmentURLGenerator = $attachmentURLGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getQuery(QueryBuilder $builder)
|
protected function getQuery(QueryBuilder $builder)
|
||||||
|
@ -89,7 +93,7 @@ class AttachmentDataTable implements DataTableTypeInterface
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<img alt="%s" src="%s" class="%s">',
|
'<img alt="%s" src="%s" class="%s">',
|
||||||
'Part image',
|
'Part image',
|
||||||
$this->entityURLGenerator->viewURL($context),
|
$this->attachmentURLGenerator->getThumbnailURL($context),
|
||||||
'img-fluid hoverpic'
|
'img-fluid hoverpic'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ use App\Entity\Parts\PartLot;
|
||||||
use App\Entity\Parts\Storelocation;
|
use App\Entity\Parts\Storelocation;
|
||||||
use App\Entity\Parts\Supplier;
|
use App\Entity\Parts\Supplier;
|
||||||
use App\Services\AmountFormatter;
|
use App\Services\AmountFormatter;
|
||||||
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
use App\Services\Attachments\PartPreviewGenerator;
|
use App\Services\Attachments\PartPreviewGenerator;
|
||||||
use App\Services\EntityURLGenerator;
|
use App\Services\EntityURLGenerator;
|
||||||
use App\Services\ToolsTreeBuilder;
|
use App\Services\ToolsTreeBuilder;
|
||||||
|
@ -65,15 +66,18 @@ class PartsDataTable implements DataTableTypeInterface
|
||||||
protected $treeBuilder;
|
protected $treeBuilder;
|
||||||
protected $amountFormatter;
|
protected $amountFormatter;
|
||||||
protected $previewGenerator;
|
protected $previewGenerator;
|
||||||
|
protected $attachmentURLGenerator;
|
||||||
|
|
||||||
public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator,
|
public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator,
|
||||||
TreeBuilder $treeBuilder, AmountFormatter $amountFormatter, PartPreviewGenerator $previewGenerator)
|
TreeBuilder $treeBuilder, AmountFormatter $amountFormatter,
|
||||||
|
PartPreviewGenerator $previewGenerator, AttachmentURLGenerator $attachmentURLGenerator)
|
||||||
{
|
{
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->treeBuilder = $treeBuilder;
|
$this->treeBuilder = $treeBuilder;
|
||||||
$this->amountFormatter = $amountFormatter;
|
$this->amountFormatter = $amountFormatter;
|
||||||
$this->previewGenerator = $previewGenerator;
|
$this->previewGenerator = $previewGenerator;
|
||||||
|
$this->attachmentURLGenerator = $attachmentURLGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getQuery(QueryBuilder $builder)
|
protected function getQuery(QueryBuilder $builder)
|
||||||
|
@ -164,7 +168,7 @@ class PartsDataTable implements DataTableTypeInterface
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<img alt="%s" src="%s" class="%s">',
|
'<img alt="%s" src="%s" class="%s">',
|
||||||
'Part image',
|
'Part image',
|
||||||
$this->urlGenerator->viewURL($preview_attachment),
|
$this->attachmentURLGenerator->getThumbnailURL($preview_attachment),
|
||||||
'img-fluid hoverpic'
|
'img-fluid hoverpic'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ abstract class Attachment extends NamedDBElement
|
||||||
/**
|
/**
|
||||||
* When the path begins with one of this placeholders
|
* When the path begins with one of this placeholders
|
||||||
*/
|
*/
|
||||||
public const INTERNAL_PLACEHOLDER = ['%BASE%', '%MEDIA%'];
|
public const INTERNAL_PLACEHOLDER = ['%BASE%', '%MEDIA%', '%SECURE%'];
|
||||||
|
|
||||||
/** @var array Placeholders for attachments which using built in files. */
|
/** @var array Placeholders for attachments which using built in files. */
|
||||||
public const BUILTIN_PLACEHOLDER = ['%FOOTPRINTS%', '%FOOTPRINTS3D%'];
|
public const BUILTIN_PLACEHOLDER = ['%FOOTPRINTS%', '%FOOTPRINTS3D%'];
|
||||||
|
@ -156,6 +156,23 @@ abstract class Attachment extends NamedDBElement
|
||||||
return !in_array($tmp[0], array_merge(static::INTERNAL_PLACEHOLDER, static::BUILTIN_PLACEHOLDER), false);
|
return !in_array($tmp[0], array_merge(static::INTERNAL_PLACEHOLDER, static::BUILTIN_PLACEHOLDER), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this attachment is saved in a secure place.
|
||||||
|
* This means that it can not be accessed directly via a web request, but must be viewed via a controller.
|
||||||
|
* @return bool True, if the file is secure.
|
||||||
|
*/
|
||||||
|
public function isSecure() : bool
|
||||||
|
{
|
||||||
|
//After the %PLACEHOLDER% comes a slash, so we can check if we have a placholder via explode
|
||||||
|
$tmp = explode("/", $this->path);
|
||||||
|
|
||||||
|
if (empty($tmp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tmp[0] === '%SECURE%';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the attachment file is using a builtin file. (see BUILTIN_PLACEHOLDERS const for possible placeholders)
|
* Checks if the attachment file is using a builtin file. (see BUILTIN_PLACEHOLDERS const for possible placeholders)
|
||||||
* If a file is built in, the path is shown to user in url field (no sensitive infos are provided)
|
* If a file is built in, the path is shown to user in url field (no sensitive infos are provided)
|
||||||
|
|
|
@ -75,7 +75,8 @@ class AttachmentHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the absolute filepath of the attachment. Null is returned, if the attachment is externally saved.
|
* Returns the absolute filepath of the attachment. Null is returned, if the attachment is externally saved,
|
||||||
|
* or is not existing.
|
||||||
* @param Attachment $attachment The attachment for which the filepath should be determined
|
* @param Attachment $attachment The attachment for which the filepath should be determined
|
||||||
* @return string|null
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
|
@ -95,7 +96,13 @@ class AttachmentHelper
|
||||||
if ($path === null) {
|
if ($path === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return realpath($path);
|
|
||||||
|
$tmp = realpath($path);
|
||||||
|
//If path is not existing realpath returns false.
|
||||||
|
if ($tmp === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
156
src/Services/Attachments/AttachmentURLGenerator.php
Normal file
156
src/Services/Attachments/AttachmentURLGenerator.php
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* part-db version 0.1
|
||||||
|
* Copyright (C) 2005 Christoph Lechner
|
||||||
|
* http://www.cl-projects.de/
|
||||||
|
*
|
||||||
|
* part-db version 0.2+
|
||||||
|
* Copyright (C) 2009 K. Jacobs and others (see authors.php)
|
||||||
|
* http://code.google.com/p/part-db/
|
||||||
|
*
|
||||||
|
* Part-DB Version 0.4+
|
||||||
|
* Copyright (C) 2016 - 2019 Jan Böhmer
|
||||||
|
* https://github.com/jbtronics
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Attachments;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Entity\Attachments\Attachment;
|
||||||
|
use App\Services\AttachmentHelper;
|
||||||
|
use Liip\ImagineBundle\Service\FilterService;
|
||||||
|
use Symfony\Component\Asset\Package;
|
||||||
|
use Symfony\Component\Asset\Packages;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
|
||||||
|
class AttachmentURLGenerator
|
||||||
|
{
|
||||||
|
protected $assets;
|
||||||
|
protected $public_path;
|
||||||
|
protected $pathResolver;
|
||||||
|
protected $urlGenerator;
|
||||||
|
protected $attachmentHelper;
|
||||||
|
protected $filterService;
|
||||||
|
|
||||||
|
public function __construct(Packages $assets, AttachmentPathResolver $pathResolver,
|
||||||
|
UrlGeneratorInterface $urlGenerator, AttachmentHelper $attachmentHelper,
|
||||||
|
FilterService $filterService)
|
||||||
|
{
|
||||||
|
$this->assets = $assets;
|
||||||
|
$this->pathResolver = $pathResolver;
|
||||||
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
$this->attachmentHelper = $attachmentHelper;
|
||||||
|
$this->filterService = $filterService;
|
||||||
|
|
||||||
|
|
||||||
|
//Determine a normalized path to the public folder (assets are relative to this folder)
|
||||||
|
$this->public_path = $this->pathResolver->parameterToAbsolutePath('public');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the absolute file path to a version relative to the public folder, that can be passed to asset
|
||||||
|
* Asset Component functions.
|
||||||
|
* @param string $absolute_path The absolute path that should be converted.
|
||||||
|
* @param string|null $public_path The public path to which the relative pathes should be created.
|
||||||
|
* The path must NOT have a trailing slash!
|
||||||
|
* If this is set to null, the global public/ folder is used.
|
||||||
|
* @return string|null The relative version of the string. Null if the absolute path was not a child folder
|
||||||
|
* of public path
|
||||||
|
*/
|
||||||
|
public function absolutePathToAssetPath(string $absolute_path, ?string $public_path = null) : ?string
|
||||||
|
{
|
||||||
|
if ($public_path === null) {
|
||||||
|
$public_path = $this->public_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Our absolute path must begin with public path or we can not use it for asset pathes.
|
||||||
|
if (strpos($absolute_path, $public_path) !== 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return the part relative after public path.
|
||||||
|
return substr($absolute_path, strlen($public_path) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a URL under which the attachment file can be viewed.
|
||||||
|
* @param Attachment $attachment
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getViewURL(Attachment $attachment) : string
|
||||||
|
{
|
||||||
|
$absolute_path = $this->attachmentHelper->toAbsoluteFilePath($attachment);
|
||||||
|
if ($absolute_path === null) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'The given attachment is external or has no valid file, so no URL can get generated for it!
|
||||||
|
Use Attachment::getURL() to get the external URL!'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$asset_path = $this->absolutePathToAssetPath($absolute_path);
|
||||||
|
//If path is not relative to public path or marked as secure, serve it via controller
|
||||||
|
if ($asset_path === null || $attachment->isSecure()) {
|
||||||
|
return $this->urlGenerator->generate('attachment_view', ['id' => $attachment->getID()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Otherwise we can serve the relative path via Asset component
|
||||||
|
return $this->assets->getUrl($asset_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a URL to an thumbnail of the attachment file.
|
||||||
|
* @param Attachment $attachment
|
||||||
|
* @param string $filter_name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getThumbnailURL(Attachment $attachment, string $filter_name = 'thumbnail_sm') : string
|
||||||
|
{
|
||||||
|
if (!$attachment->isPicture()) {
|
||||||
|
throw new \InvalidArgumentException('Thumbnail creation only works for picture attachments!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$absolute_path = $this->attachmentHelper->toAbsoluteFilePath($attachment);
|
||||||
|
if ($absolute_path === null) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'The given attachment is external or has no valid file, so no URL can get generated for it!
|
||||||
|
Use Attachment::getURL() to get the external URL!'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$asset_path = $this->absolutePathToAssetPath($absolute_path);
|
||||||
|
//If path is not relative to public path or marked as secure, serve it via controller
|
||||||
|
if ($asset_path === null || $attachment->isSecure()) {
|
||||||
|
return $this->urlGenerator->generate('attachment_view', ['id' => $attachment->getID()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Otherwise we can serve the relative path via Asset component
|
||||||
|
return $this->filterService->getUrlOfFilteredImage($asset_path, 'thumbnail_sm');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a download link to the file associated with the attachment
|
||||||
|
* @param Attachment $attachment
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDownloadURL(Attachment $attachment) : string
|
||||||
|
{
|
||||||
|
//Redirect always to download controller, which sets the correct headers for downloading:
|
||||||
|
$this->urlGenerator->generate('attachment_download', ['id' => $attachment->getID()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ use App\Entity\PriceInformations\Currency;
|
||||||
use App\Entity\UserSystem\Group;
|
use App\Entity\UserSystem\Group;
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use App\Exceptions\EntityNotSupportedException;
|
use App\Exceptions\EntityNotSupportedException;
|
||||||
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
use Symfony\Component\HttpKernel\HttpCache\Store;
|
use Symfony\Component\HttpKernel\HttpCache\Store;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
|
||||||
|
@ -60,10 +61,12 @@ class EntityURLGenerator
|
||||||
* @var UrlGeneratorInterface
|
* @var UrlGeneratorInterface
|
||||||
*/
|
*/
|
||||||
protected $urlGenerator;
|
protected $urlGenerator;
|
||||||
|
protected $attachmentURLGenerator;
|
||||||
|
|
||||||
public function __construct(UrlGeneratorInterface $urlGenerator)
|
public function __construct(UrlGeneratorInterface $urlGenerator, AttachmentURLGenerator $attachmentURLGenerator)
|
||||||
{
|
{
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
$this->attachmentURLGenerator = $attachmentURLGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,7 +141,8 @@ class EntityURLGenerator
|
||||||
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
||||||
return $entity->getURL();
|
return $entity->getURL();
|
||||||
}
|
}
|
||||||
return $this->urlGenerator->generate('attachment_view', ['id' => $entity->getID()]);
|
//return $this->urlGenerator->generate('attachment_view', ['id' => $entity->getID()]);
|
||||||
|
return $this->attachmentURLGenerator->getViewURL($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Otherwise throw an error
|
//Otherwise throw an error
|
||||||
|
@ -151,7 +155,7 @@ class EntityURLGenerator
|
||||||
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
if ($entity->isExternal()) { //For external attachments, return the link to external path
|
||||||
return $entity->getURL();
|
return $entity->getURL();
|
||||||
}
|
}
|
||||||
return $this->urlGenerator->generate('attachment_download', ['id' => $entity->getID()]);
|
return $this->attachmentURLGenerator->getDownloadURL($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Otherwise throw an error
|
//Otherwise throw an error
|
||||||
|
|
19
symfony.lock
19
symfony.lock
|
@ -141,9 +141,25 @@
|
||||||
"guzzlehttp/psr7": {
|
"guzzlehttp/psr7": {
|
||||||
"version": "1.6.1"
|
"version": "1.6.1"
|
||||||
},
|
},
|
||||||
|
"imagine/imagine": {
|
||||||
|
"version": "1.2.2"
|
||||||
|
},
|
||||||
"jdorn/sql-formatter": {
|
"jdorn/sql-formatter": {
|
||||||
"version": "v1.2.17"
|
"version": "v1.2.17"
|
||||||
},
|
},
|
||||||
|
"liip/imagine-bundle": {
|
||||||
|
"version": "1.8",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes-contrib",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "1.8",
|
||||||
|
"ref": "1d42bc3f713130582e6e0c475c49bc327ab0a2a2"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"./config/packages/liip_imagine.yaml",
|
||||||
|
"./config/routes/liip_imagine.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"monolog/monolog": {
|
"monolog/monolog": {
|
||||||
"version": "1.24.0"
|
"version": "1.24.0"
|
||||||
},
|
},
|
||||||
|
@ -550,6 +566,9 @@
|
||||||
"./config/packages/test/swiftmailer.yaml"
|
"./config/packages/test/swiftmailer.yaml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/templating": {
|
||||||
|
"version": "v4.3.4"
|
||||||
|
},
|
||||||
"symfony/test-pack": {
|
"symfony/test-pack": {
|
||||||
"version": "v1.0.5"
|
"version": "v1.0.5"
|
||||||
},
|
},
|
||||||
|
|
|
@ -56,7 +56,7 @@ class AttachmentPathResolverTest extends WebTestCase
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
self::$projectDir_orig = realpath(self::$kernel->getProjectDir());
|
self::$projectDir_orig = realpath(self::$kernel->getProjectDir());
|
||||||
self::$projectDir = str_replace('\\', '/', self::$projectDir_orig);
|
self::$projectDir = str_replace('\\', '/', self::$projectDir_orig);
|
||||||
self::$media_path = self::$projectDir . '/data/media';
|
self::$media_path = self::$projectDir . '/public/media';
|
||||||
self::$footprint_path = self::$projectDir . '/public/img/footprints';
|
self::$footprint_path = self::$projectDir . '/public/img/footprints';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
72
tests/Services/Attachments/AttachmentURLGeneratorTest.php
Normal file
72
tests/Services/Attachments/AttachmentURLGeneratorTest.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* part-db version 0.1
|
||||||
|
* Copyright (C) 2005 Christoph Lechner
|
||||||
|
* http://www.cl-projects.de/
|
||||||
|
*
|
||||||
|
* part-db version 0.2+
|
||||||
|
* Copyright (C) 2009 K. Jacobs and others (see authors.php)
|
||||||
|
* http://code.google.com/p/part-db/
|
||||||
|
*
|
||||||
|
* Part-DB Version 0.4+
|
||||||
|
* Copyright (C) 2016 - 2019 Jan Böhmer
|
||||||
|
* https://github.com/jbtronics
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Tests\Services\Attachments;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
|
use App\Services\BuiltinAttachmentsFinder;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
|
||||||
|
class AttachmentURLGeneratorTest extends WebTestCase
|
||||||
|
{
|
||||||
|
protected const PUBLIC_DIR = "/public";
|
||||||
|
|
||||||
|
protected static $service;
|
||||||
|
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
//Get an service instance.
|
||||||
|
self::bootKernel();
|
||||||
|
self::$service = self::$container->get(AttachmentURLGenerator::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['/public/test.jpg', 'test.jpg'],
|
||||||
|
['/public/folder/test.jpg', 'folder/test.jpg'],
|
||||||
|
['/not/public/test.jpg', null],
|
||||||
|
['/public/', ''],
|
||||||
|
['not/absolute/test.jpg', null]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataProvider
|
||||||
|
* @param $input
|
||||||
|
* @param $expected
|
||||||
|
*/
|
||||||
|
public function testabsolutePathToAssetPath($input, $expected)
|
||||||
|
{
|
||||||
|
$this->assertEquals($expected, static::$service->absolutePathToAssetPath($input, static::PUBLIC_DIR));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue