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:
Jan Böhmer 2019-10-05 20:30:27 +02:00
parent 1b28006267
commit 4fe10b6169
21 changed files with 552 additions and 21 deletions

4
.gitignore vendored
View file

@ -26,3 +26,7 @@
npm-debug.log
yarn-error.log
###< symfony/webpack-encore-bundle ###
###> liip/imagine-bundle ###
/public/media/cache/
###< liip/imagine-bundle ###

View file

@ -3,13 +3,17 @@
"license": "GPL-2.0-or-later",
"require": {
"php": "^7.1.3",
"ext-bcmath": "*",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-intl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-gd": "*",
"doctrine/annotations": "^1.6",
"florianv/swap": "^4.0",
"friendsofsymfony/ckeditor-bundle": "^2.0",
"liip/imagine-bundle": "^2.2",
"nyholm/psr7": "^1.1",
"ocramius/proxy-manager": "2.1.*",
"omines/datatables-bundle": "^0.3.1",
@ -42,9 +46,7 @@
"twig/extensions": "^1.5",
"twig/extra-bundle": "3.x-dev",
"twig/intl-extra": "3.x-dev",
"webmozart/assert": "^1.4",
"ext-bcmath": "*",
"ext-json": "*"
"webmozart/assert": "^1.4"
},
"require-dev": {
"roave/security-advisories": "dev-master",

223
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b991c6efd2c3ad84f8c1f76ae8efac2c",
"content-hash": "634b7b41a97404c6278ed91d1926f853",
"packages": [
{
"name": "clue/stream-filter",
@ -1756,6 +1756,64 @@
],
"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",
"version": "v1.2.17",
@ -1806,6 +1864,107 @@
],
"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",
"version": "1.25.1",
@ -6389,6 +6548,62 @@
"homepage": "http://symfony.com",
"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",
"version": "v4.3.4",
@ -9023,12 +9238,12 @@
"prefer-lowest": false,
"platform": {
"php": "^7.1.3",
"ext-bcmath": "*",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-intl": "*",
"ext-mbstring": "*",
"ext-bcmath": "*",
"ext-json": "*"
"ext-json": "*",
"ext-mbstring": "*"
},
"platform-dev": [],
"platform-overrides": {

View file

@ -19,4 +19,5 @@ return [
Shivas\VersioningBundle\ShivasVersioningBundle::class => ['all' => true],
FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true],
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true],
];

View 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

View file

@ -0,0 +1,2 @@
_liip_imagine:
resource: "@LiipImagineBundle/Resources/config/routing.yaml"

View file

@ -11,7 +11,7 @@ parameters:
banner: '' # The info text shown in the homepage
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
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
services:
@ -32,6 +32,9 @@ services:
resource: '../src/Controller'
tags: ['controller.service_arguments']
Liip\ImagineBundle\Service\FilterService:
alias: 'liip_imagine.service.filter'
app.doctrine.elementListener:
class: App\Security\EntityListeners\ElementPermissionListener
public: false

View file

@ -1,2 +0,0 @@
# Ignore everything
*

3
public/media/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Ignore everything except this .gitignore
d274.gif
!.gitignore

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View file

@ -37,6 +37,7 @@ use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Parts\Part;
use App\Services\AttachmentHelper;
use App\Services\Attachments\AttachmentURLGenerator;
use App\Services\ElementTypeNameGenerator;
use App\Services\EntityURLGenerator;
use Doctrine\ORM\QueryBuilder;
@ -54,14 +55,17 @@ class AttachmentDataTable implements DataTableTypeInterface
protected $entityURLGenerator;
protected $attachmentHelper;
protected $elementTypeNameGenerator;
protected $attachmentURLGenerator;
public function __construct(TranslatorInterface $translator, EntityURLGenerator $entityURLGenerator,
AttachmentHelper $attachmentHelper, ElementTypeNameGenerator $elementTypeNameGenerator)
AttachmentHelper $attachmentHelper, AttachmentURLGenerator $attachmentURLGenerator,
ElementTypeNameGenerator $elementTypeNameGenerator)
{
$this->translator = $translator;
$this->entityURLGenerator = $entityURLGenerator;
$this->attachmentHelper = $attachmentHelper;
$this->elementTypeNameGenerator = $elementTypeNameGenerator;
$this->attachmentURLGenerator = $attachmentURLGenerator;
}
protected function getQuery(QueryBuilder $builder)
@ -89,7 +93,7 @@ class AttachmentDataTable implements DataTableTypeInterface
return sprintf(
'<img alt="%s" src="%s" class="%s">',
'Part image',
$this->entityURLGenerator->viewURL($context),
$this->attachmentURLGenerator->getThumbnailURL($context),
'img-fluid hoverpic'
);
}

View file

@ -39,6 +39,7 @@ use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Services\AmountFormatter;
use App\Services\Attachments\AttachmentURLGenerator;
use App\Services\Attachments\PartPreviewGenerator;
use App\Services\EntityURLGenerator;
use App\Services\ToolsTreeBuilder;
@ -65,15 +66,18 @@ class PartsDataTable implements DataTableTypeInterface
protected $treeBuilder;
protected $amountFormatter;
protected $previewGenerator;
protected $attachmentURLGenerator;
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->translator = $translator;
$this->treeBuilder = $treeBuilder;
$this->amountFormatter = $amountFormatter;
$this->previewGenerator = $previewGenerator;
$this->attachmentURLGenerator = $attachmentURLGenerator;
}
protected function getQuery(QueryBuilder $builder)
@ -164,7 +168,7 @@ class PartsDataTable implements DataTableTypeInterface
return sprintf(
'<img alt="%s" src="%s" class="%s">',
'Part image',
$this->urlGenerator->viewURL($preview_attachment),
$this->attachmentURLGenerator->getThumbnailURL($preview_attachment),
'img-fluid hoverpic'
);
}

View file

@ -64,7 +64,7 @@ abstract class Attachment extends NamedDBElement
/**
* 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. */
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);
}
/**
* 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)
* If a file is built in, the path is shown to user in url field (no sensitive infos are provided)

View file

@ -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
* @return string|null
*/
@ -95,7 +96,13 @@ class AttachmentHelper
if ($path === null) {
return null;
}
return realpath($path);
$tmp = realpath($path);
//If path is not existing realpath returns false.
if ($tmp === false) {
return null;
}
return $tmp;
}
/**

View 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()]);
}
}

View file

@ -45,6 +45,7 @@ use App\Entity\PriceInformations\Currency;
use App\Entity\UserSystem\Group;
use App\Entity\UserSystem\User;
use App\Exceptions\EntityNotSupportedException;
use App\Services\Attachments\AttachmentURLGenerator;
use Symfony\Component\HttpKernel\HttpCache\Store;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@ -60,10 +61,12 @@ class EntityURLGenerator
* @var UrlGeneratorInterface
*/
protected $urlGenerator;
protected $attachmentURLGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
public function __construct(UrlGeneratorInterface $urlGenerator, AttachmentURLGenerator $attachmentURLGenerator)
{
$this->urlGenerator = $urlGenerator;
$this->attachmentURLGenerator = $attachmentURLGenerator;
}
/**
@ -138,7 +141,8 @@ class EntityURLGenerator
if ($entity->isExternal()) { //For external attachments, return the link to external path
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
@ -151,7 +155,7 @@ class EntityURLGenerator
if ($entity->isExternal()) { //For external attachments, return the link to external path
return $entity->getURL();
}
return $this->urlGenerator->generate('attachment_download', ['id' => $entity->getID()]);
return $this->attachmentURLGenerator->getDownloadURL($entity);
}
//Otherwise throw an error

View file

@ -141,9 +141,25 @@
"guzzlehttp/psr7": {
"version": "1.6.1"
},
"imagine/imagine": {
"version": "1.2.2"
},
"jdorn/sql-formatter": {
"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": {
"version": "1.24.0"
},
@ -550,6 +566,9 @@
"./config/packages/test/swiftmailer.yaml"
]
},
"symfony/templating": {
"version": "v4.3.4"
},
"symfony/test-pack": {
"version": "v1.0.5"
},

View file

@ -56,7 +56,7 @@ class AttachmentPathResolverTest extends WebTestCase
self::bootKernel();
self::$projectDir_orig = realpath(self::$kernel->getProjectDir());
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';
}

View 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));
}
}