diff --git a/.gitignore b/.gitignore index a0f6acf5..00b9cd31 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ npm-debug.log yarn-error.log ###< symfony/webpack-encore-bundle ### + +###> liip/imagine-bundle ### +/public/media/cache/ +###< liip/imagine-bundle ### diff --git a/composer.json b/composer.json index 93f57c79..a016a2eb 100644 --- a/composer.json +++ b/composer.json @@ -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", diff --git a/composer.lock b/composer.lock index 807dc782..378cda36 100644 --- a/composer.lock +++ b/composer.lock @@ -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": { diff --git a/config/bundles.php b/config/bundles.php index a653a57a..18638810 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -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], ]; diff --git a/config/packages/liip_imagine.yaml b/config/packages/liip_imagine.yaml new file mode 100644 index 00000000..5a7319d0 --- /dev/null +++ b/config/packages/liip_imagine.yaml @@ -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 diff --git a/config/routes/liip_imagine.yaml b/config/routes/liip_imagine.yaml new file mode 100644 index 00000000..201cbd5d --- /dev/null +++ b/config/routes/liip_imagine.yaml @@ -0,0 +1,2 @@ +_liip_imagine: + resource: "@LiipImagineBundle/Resources/config/routing.yaml" diff --git a/config/services.yaml b/config/services.yaml index 589d7aaa..643ffecd 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -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 diff --git a/data/media/.gitignore b/data/media/.gitignore deleted file mode 100644 index 2e0e43de..00000000 --- a/data/media/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Ignore everything -* \ No newline at end of file diff --git a/public/media/.gitignore b/public/media/.gitignore new file mode 100644 index 00000000..420385b9 --- /dev/null +++ b/public/media/.gitignore @@ -0,0 +1,3 @@ +# Ignore everything except this .gitignore +d274.gif +!.gitignore \ No newline at end of file diff --git a/public/media/currency/2/test-5d95f7efefc33.webp b/public/media/currency/2/test-5d95f7efefc33.webp new file mode 100644 index 00000000..122741b6 Binary files /dev/null and b/public/media/currency/2/test-5d95f7efefc33.webp differ diff --git a/public/media/part/1108/test-5d9616224f44a.webp b/public/media/part/1108/test-5d9616224f44a.webp new file mode 100644 index 00000000..122741b6 Binary files /dev/null and b/public/media/part/1108/test-5d9616224f44a.webp differ diff --git a/public/media/part/2/repositoryopengraphtemplate.png b/public/media/part/2/repositoryopengraphtemplate.png new file mode 100644 index 00000000..d03dffd8 Binary files /dev/null and b/public/media/part/2/repositoryopengraphtemplate.png differ diff --git a/src/DataTables/AttachmentDataTable.php b/src/DataTables/AttachmentDataTable.php index d7424fee..93bbd06a 100644 --- a/src/DataTables/AttachmentDataTable.php +++ b/src/DataTables/AttachmentDataTable.php @@ -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( '%s', 'Part image', - $this->entityURLGenerator->viewURL($context), + $this->attachmentURLGenerator->getThumbnailURL($context), 'img-fluid hoverpic' ); } diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index e3d87bbd..85e59ceb 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -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( '%s', 'Part image', - $this->urlGenerator->viewURL($preview_attachment), + $this->attachmentURLGenerator->getThumbnailURL($preview_attachment), 'img-fluid hoverpic' ); } diff --git a/src/Entity/Attachments/Attachment.php b/src/Entity/Attachments/Attachment.php index a3a61d07..e62149c4 100644 --- a/src/Entity/Attachments/Attachment.php +++ b/src/Entity/Attachments/Attachment.php @@ -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) diff --git a/src/Services/AttachmentHelper.php b/src/Services/AttachmentHelper.php index fd06626b..e280115d 100644 --- a/src/Services/AttachmentHelper.php +++ b/src/Services/AttachmentHelper.php @@ -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; } /** diff --git a/src/Services/Attachments/AttachmentURLGenerator.php b/src/Services/Attachments/AttachmentURLGenerator.php new file mode 100644 index 00000000..7ed1896b --- /dev/null +++ b/src/Services/Attachments/AttachmentURLGenerator.php @@ -0,0 +1,156 @@ +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()]); + } +} \ No newline at end of file diff --git a/src/Services/EntityURLGenerator.php b/src/Services/EntityURLGenerator.php index c032cc2b..44ff15b6 100644 --- a/src/Services/EntityURLGenerator.php +++ b/src/Services/EntityURLGenerator.php @@ -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 diff --git a/symfony.lock b/symfony.lock index d8d76bac..98c1a9b1 100644 --- a/symfony.lock +++ b/symfony.lock @@ -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" }, diff --git a/tests/Services/Attachments/AttachmentPathResolverTest.php b/tests/Services/Attachments/AttachmentPathResolverTest.php index cd0c03d6..e8011202 100644 --- a/tests/Services/Attachments/AttachmentPathResolverTest.php +++ b/tests/Services/Attachments/AttachmentPathResolverTest.php @@ -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'; } diff --git a/tests/Services/Attachments/AttachmentURLGeneratorTest.php b/tests/Services/Attachments/AttachmentURLGeneratorTest.php new file mode 100644 index 00000000..eee43db9 --- /dev/null +++ b/tests/Services/Attachments/AttachmentURLGeneratorTest.php @@ -0,0 +1,72 @@ +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)); + } +} \ No newline at end of file