diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 4cf67858fe287..8e6011c09a27f 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -13,20 +13,16 @@ */ namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery; -use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider; +use Magento\Framework\App\ObjectManager; use Magento\Backend\Block\Media\Uploader; +use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\FileSystemException; -use Magento\Framework\Storage\FileNotFoundException; -use Magento\Framework\Storage\StorageProvider; -use Magento\Framework\View\Element\AbstractBlock; +use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider; use Magento\MediaStorage\Helper\File\Storage\Database; /** * Block for gallery content. - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Content extends \Magento\Backend\Block\Widget { @@ -59,21 +55,11 @@ class Content extends \Magento\Backend\Block\Widget * @var Database */ private $fileStorageDatabase; - /** - * @var StorageProvider - */ - private $storageProvider; - - /** - * @var \Magento\Framework\Filesystem\Directory\ReadInterface - */ - private $mediaDirectory; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig - * @param StorageProvider $storageProvider * @param array $data * @param ImageUploadConfigDataProvider $imageUploadConfigDataProvider * @param Database $fileStorageDatabase @@ -82,7 +68,6 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Framework\Json\EncoderInterface $jsonEncoder, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, - StorageProvider $storageProvider, array $data = [], ImageUploadConfigDataProvider $imageUploadConfigDataProvider = null, Database $fileStorageDatabase = null @@ -90,12 +75,10 @@ public function __construct( $this->_jsonEncoder = $jsonEncoder; $this->_mediaConfig = $mediaConfig; parent::__construct($context, $data); - $this->mediaDirectory = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); $this->imageUploadConfigDataProvider = $imageUploadConfigDataProvider ?: ObjectManager::getInstance()->get(ImageUploadConfigDataProvider::class); $this->fileStorageDatabase = $fileStorageDatabase ?: ObjectManager::getInstance()->get(Database::class); - $this->storageProvider = $storageProvider; } /** @@ -174,49 +157,10 @@ public function getAddImagesButton() ); } - /** - * Sync images to database - * - * @param string $fileName - */ - private function syncImageToDatabase(string $fileName): void - { - if ($this->fileStorageDatabase->checkDbUsage() && - !$this->mediaDirectory->isFile($this->_mediaConfig->getMediaPath($fileName)) - ) { - $this->fileStorageDatabase->saveFileToFilesystem( - $this->_mediaConfig->getMediaPath($fileName) - ); - } - } - - /** - * Returns file metadata as an associative array - * - * @param string $fileName - * @return array - * @throws FileNotFoundException - */ - private function getFileMetadata(string $fileName): array - { - $metadata = []; - try { - $info = $this->storageProvider->get('media') - ->getMetadata($this->_mediaConfig->getMediaPath($fileName)); - $metadata['size'] = $info['size']; - } catch (FileSystemException $e) { - $metadata['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('small_image'); - $metadata['size'] = 0; - $this->_logger->warning($e); - } - return $metadata; - } - /** * Returns image json * * @return string - * @throws FileNotFoundException */ public function getImagesJson() { @@ -226,14 +170,24 @@ public function getImagesJson() is_array($value['images']) && count($value['images']) ) { + $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); $images = $this->sortImagesByPosition($value['images']); foreach ($images as &$image) { $image['url'] = $this->_mediaConfig->getMediaUrl($image['file']); - $this->syncImageToDatabase($image['file']); - if (isset($image['image_metadata']) && is_array($image['image_metadata'])) { - $image = array_replace_recursive($image, $image['image_metadata']); - } else { - $image = array_replace_recursive($image, $this->getFileMetadata($image['file'])); + if ($this->fileStorageDatabase->checkDbUsage() && + !$mediaDir->isFile($this->_mediaConfig->getMediaPath($image['file'])) + ) { + $this->fileStorageDatabase->saveFileToFilesystem( + $this->_mediaConfig->getMediaPath($image['file']) + ); + } + try { + $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); + $image['size'] = $fileHandler['size']; + } catch (FileSystemException $e) { + $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('small_image'); + $image['size'] = 0; + $this->_logger->warning($e); } } return $this->_jsonEncoder->encode($images); diff --git a/app/code/Magento/Catalog/Block/Product/Gallery.php b/app/code/Magento/Catalog/Block/Product/Gallery.php index 2e9dcd1fe6952..54f848a92e958 100644 --- a/app/code/Magento/Catalog/Block/Product/Gallery.php +++ b/app/code/Magento/Catalog/Block/Product/Gallery.php @@ -11,13 +11,9 @@ */ namespace Magento\Catalog\Block\Product; -use Magento\Framework\Storage\FileNotFoundException; use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Media\Config; -use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Data\Collection; -use Magento\Framework\Registry; -use Magento\Framework\Storage\StorageProvider; /** * Product gallery block @@ -30,37 +26,22 @@ class Gallery extends \Magento\Framework\View\Element\Template /** * Core registry * - * @var Registry + * @var \Magento\Framework\Registry */ protected $_coreRegistry = null; - /** - * @var StorageProvider - */ - private $storageProvider; - /** - * @var Config - */ - private $mediaConfig; - /** * @param \Magento\Framework\View\Element\Template\Context $context - * @param Registry $registry + * @param \Magento\Framework\Registry $registry * @param array $data - * @param StorageProvider $storageProvider - * @param Config $mediaConfig */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, - Registry $registry, - array $data = [], - StorageProvider $storageProvider = null, - Config $mediaConfig = null + \Magento\Framework\Registry $registry, + array $data = [] ) { $this->_coreRegistry = $registry; parent::__construct($context, $data); - $this->storageProvider = $storageProvider ?? ObjectManager::getInstance()->get(StorageProvider::class); - $this->mediaConfig = $mediaConfig ?? ObjectManager::getInstance()->get(Config::class); } /** @@ -140,24 +121,16 @@ public function getImageFile() */ public function getImageWidth() { - $file = $this->getCurrentImage()->getFile(); - if (!$file) { - return false; - } - $productMediaFile = $this->mediaConfig->getMediaPath($file); - - $mediaStorage = $this->storageProvider->get('media'); - if ($mediaStorage->has($productMediaFile)) { - try { - $meta = $mediaStorage->getMetadata($productMediaFile); - $size = $meta['size']; - if ($size > 600) { + $file = $this->getCurrentImage()->getPath(); + + if ($this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->isFile($file)) { + $size = getimagesize($file); + if (isset($size[0])) { + if ($size[0] > 600) { return 600; } else { - return (int) $size; + return (int) $size[0]; } - } catch (FileNotFoundException $e) { - return false; } } diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php index fda3d0abced7f..3e7cc3ee962b9 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php @@ -8,7 +8,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; -use Magento\Framework\Storage\StorageProvider; +use Magento\Framework\Exception\LocalizedException; /** * Upload product image action controller @@ -52,15 +52,9 @@ class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterf */ private $productMediaConfig; - /** - * @var StorageProvider - */ - private $storageProvider; - /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory - * @param StorageProvider $storageProvider * @param \Magento\Framework\Image\AdapterFactory $adapterFactory * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\Product\Media\Config $productMediaConfig @@ -68,7 +62,6 @@ class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterf public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Framework\Controller\Result\RawFactory $resultRawFactory, - StorageProvider $storageProvider, \Magento\Framework\Image\AdapterFactory $adapterFactory = null, \Magento\Framework\Filesystem $filesystem = null, \Magento\Catalog\Model\Product\Media\Config $productMediaConfig = null @@ -81,7 +74,6 @@ public function __construct( ->get(\Magento\Framework\Filesystem::class); $this->productMediaConfig = $productMediaConfig ?: ObjectManager::getInstance() ->get(\Magento\Catalog\Model\Product\Media\Config::class); - $this->storageProvider = $storageProvider; } /** @@ -92,7 +84,6 @@ public function __construct( public function execute() { try { - /** @var \Magento\MediaStorage\Model\File\Uploader $uploader */ $uploader = $this->_objectManager->create( \Magento\MediaStorage\Model\File\Uploader::class, ['fileId' => 'image'] @@ -102,18 +93,11 @@ public function execute() $uploader->addValidateCallback('catalog_product_image', $imageAdapter, 'validateUploadFile'); $uploader->setAllowRenameFiles(true); $uploader->setFilesDispersion(true); - $mediaDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); - $baseImagePath = $this->productMediaConfig->getBaseTmpMediaPath(); $result = $uploader->save( - $mediaDirectory->getAbsolutePath($baseImagePath) + $mediaDirectory->getAbsolutePath($this->productMediaConfig->getBaseTmpMediaPath()) ); - $origFile = $this->productMediaConfig->getTmpMediaPath($result['file']); - $storage = $this->storageProvider->get('media'); - $content = $mediaDirectory->readFile($origFile); - $storage->put($origFile, $content); - $this->_eventManager->dispatch( 'catalog_product_gallery_upload_image_after', ['result' => $result, 'action' => $this] diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index f220fa0ef0444..5b0aa0c496ecd 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -13,7 +13,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; /** - * Catalog image helper + * Catalog image helper. * * @api * @SuppressWarnings(PHPMD.TooManyFields) @@ -166,8 +166,7 @@ public function __construct( $this->_assetRepo = $assetRepo; $this->viewConfig = $viewConfig; $this->viewAssetPlaceholderFactory = $placeholderFactory - ?: ObjectManager::getInstance() - ->get(PlaceholderFactory::class); + ?: ObjectManager::getInstance()->get(PlaceholderFactory::class); $this->mediaConfig = $mediaConfig ?: ObjectManager::getInstance()->get(CatalogMediaConfig::class); } @@ -574,9 +573,6 @@ public function save() * Return resized product image information * * @return array - * @deprecated Magento is not responsible for image resizing anymore. This method works with local filesystem only. - * Service that provides resized images should guarantee that the image sizes correspond to requested ones. - * Use `getWidth()` and `getHeight()` instead. */ public function getResizedImageInfo() { diff --git a/app/code/Magento/Catalog/Model/Config/Source/Web/CatalogMediaUrlFormat.php b/app/code/Magento/Catalog/Model/Config/Source/Web/CatalogMediaUrlFormat.php index 0ceeeb596655d..f24044fc92c95 100644 --- a/app/code/Magento/Catalog/Model/Config/Source/Web/CatalogMediaUrlFormat.php +++ b/app/code/Magento/Catalog/Model/Config/Source/Web/CatalogMediaUrlFormat.php @@ -24,7 +24,7 @@ public function toOptionArray() 'value' => CatalogMediaConfig::IMAGE_OPTIMIZATION_PARAMETERS, 'label' => __('Image optimization based on query parameters') ], - ['value' => CatalogMediaConfig::HASH, 'label' => __('Legacy mode (unique hash per image variant)')] + ['value' => CatalogMediaConfig::HASH, 'label' => __('Unique hash per image variant (Legacy mode)')] ]; } } diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index d333ea589b997..0c3e008fa8bb5 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -6,7 +6,6 @@ namespace Magento\Catalog\Model; use Magento\Framework\File\Uploader; -use Magento\Framework\Storage\StorageProvider; /** * Catalog image uploader @@ -74,11 +73,6 @@ class ImageUploader */ private $allowedMimeTypes; - /** - * @var StorageProvider - */ - private $storageProvider; - /** * ImageUploader constructor * @@ -90,9 +84,7 @@ class ImageUploader * @param string $baseTmpPath * @param string $basePath * @param string[] $allowedExtensions - * @param StorageProvider $storageProvider * @param string[] $allowedMimeTypes - * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase, @@ -103,7 +95,6 @@ public function __construct( $baseTmpPath, $basePath, $allowedExtensions, - StorageProvider $storageProvider, $allowedMimeTypes = [] ) { $this->coreFileStorageDatabase = $coreFileStorageDatabase; @@ -115,7 +106,6 @@ public function __construct( $this->basePath = $basePath; $this->allowedExtensions = $allowedExtensions; $this->allowedMimeTypes = $allowedMimeTypes; - $this->storageProvider = $storageProvider; } /** @@ -230,11 +220,6 @@ public function moveFileFromTmp($imageName, $returnRelativePath = false) $baseTmpImagePath, $baseImagePath ); - - $storage = $this->storageProvider->get('media'); - $content = $this->mediaDirectory->readFile($baseImagePath); - $storage->put($baseImagePath, $content); - } catch (\Exception $e) { throw new \Magento\Framework\Exception\LocalizedException( __('Something went wrong while saving the file(s).') diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index c5dce0df14755..a9907c1661bd8 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -1540,11 +1540,7 @@ public function getMediaGalleryImages() } $image['url'] = $this->getMediaConfig()->getMediaUrl($image['file']); $image['id'] = $image['value_id']; - - // @deprecated 'path' should not be used - // The file can be absent in local filesystem if remote storage is used $image['path'] = $directory->getAbsolutePath($this->getMediaConfig()->getMediaPath($image['file'])); - $images->addItem(new \Magento\Framework\DataObject($image)); } $this->setData('media_gallery_images', $images); diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php index e56fb8e59d0e9..225a3a4c44a9b 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php @@ -11,7 +11,6 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; use Magento\Framework\EntityManager\Operation\ExtensionInterface; -use Magento\Framework\Storage\StorageProvider; use Magento\MediaStorage\Model\File\Uploader as FileUploader; use Magento\Store\Model\StoreManagerInterface; @@ -89,10 +88,6 @@ class CreateHandler implements ExtensionInterface * @var \Magento\Store\Model\StoreManagerInterface */ private $storeManager; - /** - * @var StorageProvider - */ - private $storageProvider; /** * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool @@ -103,7 +98,6 @@ class CreateHandler implements ExtensionInterface * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb * @param \Magento\Store\Model\StoreManagerInterface|null $storeManager - * @param StorageProvider $storageProvider * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( @@ -114,8 +108,7 @@ public function __construct( \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, - \Magento\Store\Model\StoreManagerInterface $storeManager = null, - StorageProvider $storageProvider = null + \Magento\Store\Model\StoreManagerInterface $storeManager = null ) { $this->metadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); $this->attributeRepository = $attributeRepository; @@ -125,7 +118,6 @@ public function __construct( $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->fileStorageDb = $fileStorageDb; $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); - $this->storageProvider = $storageProvider ?: ObjectManager::getInstance()->get(StorageProvider::class); } /** @@ -253,6 +245,7 @@ public function getAttribute() 'media_gallery' ); } + return $this->attribute; } @@ -297,8 +290,7 @@ protected function processNewAndExistingImages($product, array &$images) $data['position'] = isset($image['position']) ? (int)$image['position'] : 0; $data['disabled'] = isset($image['disabled']) ? (int)$image['disabled'] : 0; $data['store_id'] = (int)$product->getStoreId(); - $stat = $this->mediaDirectory->stat($this->mediaConfig->getMediaPath($image['file'])); - $data['image_metadata']['size'] = $stat['size']; + $data[$this->metadata->getLinkField()] = (int)$product->getData($this->metadata->getLinkField()); $this->resourceModel->insertGalleryValueInStore($data); @@ -374,20 +366,20 @@ protected function moveImageFromTmp($file) $file = $this->getFilenameFromTmp($this->getSafeFilename($file)); $destinationFile = $this->getUniqueFileName($file); - $tmpMediaPath = $this->mediaConfig->getTmpMediaPath($file); - $mediaPath = $this->mediaConfig->getMediaPath($destinationFile); - $this->mediaDirectory->renameFile( - $tmpMediaPath, - $mediaPath - ); - $this->fileStorageDb->renameFile( - $this->mediaConfig->getTmpMediaShortUrl($file), - $this->mediaConfig->getMediaShortUrl($destinationFile) - ); + if ($this->fileStorageDb->checkDbUsage()) { + $this->fileStorageDb->renameFile( + $this->mediaConfig->getTmpMediaShortUrl($file), + $this->mediaConfig->getMediaShortUrl($destinationFile) + ); - $storage = $this->storageProvider->get('media'); - $content = $this->mediaDirectory->readFile($mediaPath); - $storage->put($mediaPath, $content); + $this->mediaDirectory->delete($this->mediaConfig->getTmpMediaPath($file)); + $this->mediaDirectory->delete($this->mediaConfig->getMediaPath($destinationFile)); + } else { + $this->mediaDirectory->renameFile( + $this->mediaConfig->getTmpMediaPath($file), + $this->mediaConfig->getMediaPath($destinationFile) + ); + } return str_replace('\\', '/', $destinationFile); } diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 6a0032ca694a5..7c2a53768fd47 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -14,8 +14,7 @@ use Magento\Framework\Image as MagentoImage; use Magento\Framework\Serialize\SerializerInterface; use Magento\Catalog\Model\Product\Image\ParamsBuilder; -use Magento\Framework\Storage\StorageInterface; -use Magento\Framework\Storage\StorageProvider; +use Magento\Framework\Filesystem\Driver\File as FilesystemDriver; /** * Image operations @@ -204,9 +203,9 @@ class Image extends \Magento\Framework\Model\AbstractModel private $serializer; /** - * @var StorageInterface + * @var FilesystemDriver */ - private $storage; + private $filesystemDriver; /** * Constructor @@ -223,12 +222,12 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param ImageFactory $viewAssetImageFactory * @param PlaceholderFactory $viewAssetPlaceholderFactory * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param StorageProvider $storageProvider * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param SerializerInterface $serializer * @param ParamsBuilder $paramsBuilder + * @param FilesystemDriver $filesystemDriver * @throws \Magento\Framework\Exception\FileSystemException * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.UnusedLocalVariable) @@ -246,30 +245,27 @@ public function __construct( ImageFactory $viewAssetImageFactory, PlaceholderFactory $viewAssetPlaceholderFactory, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - StorageProvider $storageProvider, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], SerializerInterface $serializer = null, - ParamsBuilder $paramsBuilder = null + ParamsBuilder $paramsBuilder = null, + FilesystemDriver $filesystemDriver = null ) { $this->_storeManager = $storeManager; $this->_catalogProductMediaConfig = $catalogProductMediaConfig; - - $this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->_coreFileStorageDatabase = $coreFileStorageDatabase; - $this->_imageFactory = $imageFactory; - $this->viewAssetImageFactory = $viewAssetImageFactory; - - $this->storage = $storageProvider->get('media'); - parent::__construct($context, $registry, $resource, $resourceCollection, $data); + $this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $this->_imageFactory = $imageFactory; $this->_assetRepo = $assetRepo; $this->_viewFileSystem = $viewFileSystem; $this->_scopeConfig = $scopeConfig; + $this->viewAssetImageFactory = $viewAssetImageFactory; $this->viewAssetPlaceholderFactory = $viewAssetPlaceholderFactory; $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); $this->paramsBuilder = $paramsBuilder ?: ObjectManager::getInstance()->get(ParamsBuilder::class); + $this->filesystemDriver = $filesystemDriver ?: ObjectManager::getInstance()->get(FilesystemDriver::class); } /** @@ -437,20 +433,19 @@ public function setBaseFile($file) { $this->_isBaseFilePlaceholder = false; - if ($file == 'no_selection' || empty($file)) { + $this->imageAsset = $this->viewAssetImageFactory->create( + [ + 'miscParams' => $this->getMiscParams(), + 'filePath' => $file, + ] + ); + if ($file == 'no_selection' || !$this->_fileExists($this->imageAsset->getSourceFile())) { $this->_isBaseFilePlaceholder = true; $this->imageAsset = $this->viewAssetPlaceholderFactory->create( [ 'type' => $this->getDestinationSubdir(), ] ); - } else { - $this->imageAsset = $this->viewAssetImageFactory->create( - [ - 'miscParams' => $this->getMiscParams(), - 'filePath' => $file, - ] - ); } $this->_baseFile = $this->imageAsset->getSourceFile(); @@ -682,7 +677,12 @@ public function getDestinationSubdir() public function isCached() { $path = $this->imageAsset->getPath(); - return is_array($this->loadImageInfoFromCache($path)) || $this->_mediaDirectory->isExist($path); + try { + $isCached = is_array($this->loadImageInfoFromCache($path)) || $this->filesystemDriver->isExists($path); + } catch (FileSystemException $e) { + $isCached = false; + } + return $isCached; } /** @@ -854,20 +854,35 @@ public function clearCache() { $directory = $this->_catalogProductMediaConfig->getBaseMediaPath() . '/cache'; $this->_mediaDirectory->delete($directory); - $this->storage->deleteDir($directory); $this->_coreFileStorageDatabase->deleteFolder($this->_mediaDirectory->getAbsolutePath($directory)); $this->clearImageInfoFromCache(); } + /** + * First check this file on FS + * + * If it doesn't exist - try to download it from DB + * + * @param string $filename + * @return bool + */ + protected function _fileExists($filename) + { + if ($this->_mediaDirectory->isFile($filename)) { + return true; + } else { + return $this->_coreFileStorageDatabase->saveFileToFilesystem( + $this->_mediaDirectory->getAbsolutePath($filename) + ); + } + } + /** * Return resized product image information * * @return array * @throws NotLoadInfoImageException - * @deprecated Magento is not responsible for image resizing anymore. This method works with local filesystem only. - * Service that provides resized images should guarantee that the image sizes correspond to requested ones. - * Use `getWidth()` and `getHeight()` instead. */ public function getResizedImageInfo() { diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 12e3c6b53d701..14daac0147abf 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -12,7 +12,6 @@ use Magento\Catalog\Model\Indexer\Product\Price\PriceTableResolver; use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler; -use Magento\Catalog\Model\ResourceModel\Category; use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; use Magento\CatalogUrlRewrite\Model\Storage\DbStorage; @@ -24,6 +23,7 @@ use Magento\Framework\Indexer\DimensionFactory; use Magento\Store\Model\Indexer\WebsiteDimensionProvider; use Magento\Store\Model\Store; +use Magento\Catalog\Model\ResourceModel\Category; /** * Product collection @@ -2337,35 +2337,49 @@ public function addPriceDataFieldFilter($comparisonFormat, $fields) * @SuppressWarnings(PHPMD.NPathComplexity) * @since 101.0.1 * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Zend_Db_Statement_Exception */ public function addMediaGalleryData() { if ($this->getFlag('media_gallery_added')) { return $this; } + if (!$this->getSize()) { return $this; } - if (!$this->isLoaded()) { - $this->load(); - } - $records = $this->getMediaGalleryResource()->getMediaRecords( - $this->getStoreId(), - $this->getLoadedIds() - ); + + $items = $this->getItems(); + $linkField = $this->getProductEntityMetadata()->getLinkField(); + + $select = $this->getMediaGalleryResource() + ->createBatchBaseSelect( + $this->getStoreId(), + $this->getAttribute('media_gallery')->getAttributeId() + )->reset( + Select::ORDER // we don't care what order is in current scenario + )->where( + 'entity.' . $linkField . ' IN (?)', + array_map( + function ($item) use ($linkField) { + return (int) $item->getOrigData($linkField); + }, + $items + ) + ); + $mediaGalleries = []; - foreach ($records as $record) { - $mediaGalleries[$record['entity_id']][] = $record; + foreach ($this->getConnection()->fetchAll($select) as $row) { + $mediaGalleries[$row[$linkField]][] = $row; } - foreach ($this->getItems() as $item) { + foreach ($items as $item) { $this->getGalleryReadHandler() ->addMediaDataToProduct( $item, - $mediaGalleries[$item->getId()] ?? [] + $mediaGalleries[$item->getOrigData($linkField)] ?? [] ); } + $this->setFlag('media_gallery_added', true); return $this; } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php index 6acda0e574828..a9741cd8e1ec7 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php @@ -6,8 +6,6 @@ namespace Magento\Catalog\Model\ResourceModel\Product; -use Magento\Framework\DB\Select; -use Magento\Framework\DB\Sql\ColumnValueExpression; use Magento\Store\Model\Store; /** @@ -35,12 +33,9 @@ class Gallery extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb protected $metadata; /** - * Gallery constructor. - * * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool * @param string $connectionName - * @throws \Exception */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, @@ -50,6 +45,7 @@ public function __construct( $this->metadata = $metadataPool->getMetadata( \Magento\Catalog\Api\Data\ProductInterface::class ); + parent::__construct($context, $connectionName); } @@ -126,14 +122,19 @@ public function loadDataFromTableByValueId( * @param int $attributeId * @return array * @since 101.0.0 - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Zend_Db_Statement_Exception */ - public function loadProductGalleryByAttributeId($product, $attributeId = null) + public function loadProductGalleryByAttributeId($product, $attributeId) { - $result = $this->getMediaRecords($product->getStoreId(), [$product->getId()], true); + $select = $this->createBaseLoadSelect( + $product->getData($this->metadata->getLinkField()), + $product->getStoreId(), + $attributeId + ); + + $result = $this->getConnection()->fetchAll($select); + $this->removeDuplicates($result); + return $result; } @@ -143,7 +144,6 @@ public function loadProductGalleryByAttributeId($product, $attributeId = null) * @param int $entityId * @param int $storeId * @param int $attributeId - * @deprecated Misleading method, methods relies on autoincrement field instead of entity ID * @return \Magento\Framework\DB\Select * @throws \Magento\Framework\Exception\LocalizedException * @since 101.0.0 @@ -159,35 +159,6 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId) return $select; } - /** - * Returns media entries from database - * - * @param int $storeId - * @param array $entityIds - * @param bool $preserveSortOrder - * @return array - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Zend_Db_Statement_Exception - */ - public function getMediaRecords(int $storeId, array $entityIds, bool $preserveSortOrder = false) : array - { - $output = []; - $select = $this->createBatchBaseSelect($storeId) - ->where('cpe.entity_id IN (?)', $entityIds); - if (!$preserveSortOrder) { - // due to performance consideration it is better to do not use sorting for this query - $select->reset(Select::ORDER); - } - $cursor = $this->getConnection()->query($select); - while ($row = $cursor->fetch()) { - if (!empty($row['image_metadata'])) { - $row['image_metadata'] = $this->getSerializer()->unserialize($row['image_metadata']); - } - $output[] = $row; - } - return $output; - } - /** * Create batch base select * @@ -195,10 +166,9 @@ public function getMediaRecords(int $storeId, array $entityIds, bool $preserveSo * @param int $attributeId * @return \Magento\Framework\DB\Select * @throws \Magento\Framework\Exception\LocalizedException - * @SuppressWarnings(PHPMD.UnusedFormalParameter) Media gallery doesn't support other attributes than media_galley * @since 101.0.1 */ - public function createBatchBaseSelect($storeId, $attributeId = null) + public function createBatchBaseSelect($storeId, $attributeId) { $linkField = $this->metadata->getLinkField(); @@ -221,10 +191,6 @@ public function createBatchBaseSelect($storeId, $attributeId = null) ['entity' => $this->getTable(self::GALLERY_VALUE_TO_ENTITY_TABLE)], $mainTableAlias . '.value_id = entity.value_id', [$linkField] - )->joinInner( - ['cpe' => $this->getTable('catalog_product_entity')], - sprintf('cpe.%1$s = entity.%1$s', $linkField), - ['entity_id' => 'cpe.entity_id'] )->joinLeft( ['value' => $this->getTable(self::GALLERY_VALUE_TABLE)], implode( @@ -253,15 +219,16 @@ public function createBatchBaseSelect($storeId, $attributeId = null) 'disabled' => $this->getConnection()->getIfNullSql('`value`.`disabled`', '`default_value`.`disabled`'), 'label_default' => 'default_value.label', 'position_default' => 'default_value.position', - 'disabled_default' => 'default_value.disabled', - 'image_metadata' => new ColumnValueExpression( - 'JSON_MERGE_PATCH(default_value.image_metadata, value.image_metadata)' - ) + 'disabled_default' => 'default_value.disabled' ])->where( + $mainTableAlias . '.attribute_id = ?', + $attributeId + )->where( $mainTableAlias . '.disabled = 0' )->order( $positionCheckSql . ' ' . \Magento\Framework\DB\Select::SQL_ASC ); + return $select; } @@ -390,9 +357,6 @@ public function insertGalleryValueInStore($data) $this->getTable(self::GALLERY_VALUE_TABLE) ); - if (!empty($data['image_metadata'])) { - $data['image_metadata'] = $this->getSerializer()->serialize($data['image_metadata']); - } $this->getConnection()->insert( $this->getTable(self::GALLERY_VALUE_TABLE), $data diff --git a/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php b/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php index ead68c897f95f..49d150a31750c 100644 --- a/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php +++ b/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php @@ -47,10 +47,11 @@ public function __construct( $this->mediaConfig = $mediaConfig; $this->filesystem = $filesystem; $this->mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $this->mediaDirectory->create($this->mediaConfig->getBaseMediaPath()); } /** - * @inheritdoc + * {@inheritdoc} */ public function getPath() { @@ -58,7 +59,7 @@ public function getPath() } /** - * @inheritdoc + * {@inheritdoc} */ public function getBaseUrl() { diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Config/CatalogClone/Media/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Config/CatalogClone/Media/ImageTest.php new file mode 100644 index 0000000000000..23f0aec5b69a2 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Config/CatalogClone/Media/ImageTest.php @@ -0,0 +1,153 @@ +eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attributeCollection = $this->getMockBuilder( + \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class + ) + ->disableOriginalConstructor() + ->getMock(); + + $this->attributeCollectionFactory = $this->getMockBuilder( + \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory::class + ) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $this->attributeCollectionFactory->expects($this->any())->method('create')->will( + $this->returnValue($this->attributeCollection) + ); + + $this->attribute = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->escaperMock = $this->getMockBuilder( + \Magento\Framework\Escaper::class + ) + ->disableOriginalConstructor() + ->setMethods(['escapeHtml']) + ->getMock(); + + $helper = new ObjectManager($this); + $this->model = $helper->getObject( + \Magento\Catalog\Model\Config\CatalogClone\Media\Image::class, + [ + 'eavConfig' => $this->eavConfig, + 'attributeCollectionFactory' => $this->attributeCollectionFactory, + 'escaper' => $this->escaperMock, + ] + ); + } + + /** + * @param string $actualLabel + * @param string $expectedLabel + * @return void + * + * @dataProvider getPrefixesDataProvider + */ + public function testGetPrefixes(string $actualLabel, string $expectedLabel): void + { + $entityTypeId = 3; + /** @var \Magento\Eav\Model\Entity\Type|\PHPUnit_Framework_MockObject_MockObject $entityType */ + $entityType = $this->getMockBuilder(\Magento\Eav\Model\Entity\Type::class) + ->disableOriginalConstructor() + ->getMock(); + $entityType->expects($this->once())->method('getId')->willReturn($entityTypeId); + + /** @var AbstractFrontend|\PHPUnit_Framework_MockObject_MockObject $frontend */ + $frontend = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend::class) + ->setMethods(['getLabel']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $frontend->expects($this->once())->method('getLabel')->willReturn($actualLabel); + + $this->attributeCollection->expects($this->once())->method('setEntityTypeFilter')->with($entityTypeId); + $this->attributeCollection->expects($this->once())->method('setFrontendInputTypeFilter')->with('media_image'); + + $this->attribute->expects($this->once())->method('getAttributeCode')->willReturn('attributeCode'); + $this->attribute->expects($this->once())->method('getFrontend')->willReturn($frontend); + + $this->attributeCollection->expects($this->any())->method('getIterator') + ->willReturn(new \ArrayIterator([$this->attribute])); + + $this->eavConfig->expects($this->any())->method('getEntityType')->with(Product::ENTITY) + ->willReturn($entityType); + + $this->escaperMock->expects($this->once())->method('escapeHtml')->with($actualLabel) + ->willReturn($expectedLabel); + + $this->assertEquals([['field' => 'attributeCode_', 'label' => $expectedLabel]], $this->model->getPrefixes()); + } + + /** + * @return array + */ + public function getPrefixesDataProvider(): array + { + return [ + [ + 'actual_label' => 'testLabel', + 'expected_label' => 'testLabel', + ], + [ + 'actual_label' => ' '<media-image-attributelabel', + ], + ]; + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php index b49decf96452d..0316b2e374d2f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php @@ -230,6 +230,46 @@ public function testAddProductCategoriesFilter() $this->collection->addCategoriesFilter([$conditionType => $values]); } + public function testAddMediaGalleryData() + { + $attributeId = 42; + $rowId = 4; + $linkField = 'row_id'; + $mediaGalleriesMock = [[$linkField => $rowId]]; + $itemMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->setMethods(['getOrigData']) + ->getMock(); + $attributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) + ->disableOriginalConstructor() + ->getMock(); + $selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->getMock(); + $metadataMock = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadataInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->collection->addItem($itemMock); + $this->galleryResourceMock->expects($this->once())->method('createBatchBaseSelect')->willReturn($selectMock); + $attributeMock->expects($this->once())->method('getAttributeId')->willReturn($attributeId); + $this->entityMock->expects($this->once())->method('getAttribute')->willReturn($attributeMock); + $itemMock->expects($this->atLeastOnce())->method('getOrigData')->willReturn($rowId); + $selectMock->expects($this->once())->method('reset')->with(Select::ORDER)->willReturnSelf(); + $selectMock->expects($this->once())->method('where')->with('entity.' . $linkField . ' IN (?)', [$rowId]) + ->willReturnSelf(); + $this->metadataPoolMock->expects($this->once())->method('getMetadata')->willReturn($metadataMock); + $metadataMock->expects($this->once())->method('getLinkField')->willReturn($linkField); + + $this->connectionMock->expects($this->once())->method('fetchOne')->with($selectMock)->willReturn(42); + $this->connectionMock->expects($this->once())->method('fetchAll')->with($selectMock)->willReturn( + [['row_id' => $rowId]] + ); + $this->galleryReadHandlerMock->expects($this->once())->method('addMediaDataToProduct') + ->with($itemMock, $mediaGalleriesMock); + + $this->assertSame($this->collection, $this->collection->addMediaGalleryData()); + } + /** * Test addTierPriceDataByGroupId method. * diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php index 43c1abc91a1a9..47ef3c999125f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php @@ -5,8 +5,6 @@ */ namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Product; -use Magento\Framework\DB\Sql\ColumnValueExpression; - /** * Unit test for product media gallery resource. */ @@ -282,4 +280,200 @@ public function testBindValueToEntityRecordExists() $entityId = 1; $this->resource->bindValueToEntity($valueId, $entityId); } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testLoadGallery() + { + $productId = 5; + $storeId = 1; + $attributeId = 6; + $getTableReturnValue = 'table'; + $quoteInfoReturnValue = + 'main.value_id = value.value_id AND value.store_id = ' . $storeId + . ' AND value.entity_id = entity.entity_id'; + $quoteDefaultInfoReturnValue = + 'main.value_id = default_value.value_id AND default_value.store_id = 0' + . ' AND default_value.entity_id = entity.entity_id'; + + $positionCheckSql = 'testchecksql'; + $resultRow = [ + [ + 'value_id' => '1', + 'file' => '/d/o/download_7.jpg', + 'label' => null, + 'position' => '1', + 'disabled' => '0', + 'label_default' => null, + 'position_default' => '1', + 'disabled_default' => '0', + ], + ]; + + $this->connection->expects($this->once())->method('getCheckSql')->with( + 'value.position IS NULL', + 'default_value.position', + 'value.position' + )->will($this->returnValue($positionCheckSql)); + $this->connection->expects($this->once())->method('select')->will($this->returnValue($this->select)); + $this->select->expects($this->at(0))->method('from')->with( + [ + 'main' => $getTableReturnValue, + ], + [ + 'value_id', + 'file' => 'value', + 'media_type' + ] + )->willReturnSelf(); + $this->select->expects($this->at(1))->method('joinInner')->with( + ['entity' => $getTableReturnValue], + 'main.value_id = entity.value_id', + ['entity_id'] + )->willReturnSelf(); + $this->product->expects($this->at(0))->method('getData') + ->with('entity_id')->willReturn($productId); + $this->product->expects($this->at(1))->method('getStoreId')->will($this->returnValue($storeId)); + $this->connection->expects($this->exactly(2))->method('quoteInto')->withConsecutive( + ['value.store_id = ?'], + ['default_value.store_id = ?'] + )->willReturnOnConsecutiveCalls( + 'value.store_id = ' . $storeId, + 'default_value.store_id = ' . 0 + ); + $this->connection->expects($this->any())->method('getIfNullSql')->will( + $this->returnValueMap([ + [ + '`value`.`label`', + '`default_value`.`label`', + 'IFNULL(`value`.`label`, `default_value`.`label`)' + ], + [ + '`value`.`position`', + '`default_value`.`position`', + 'IFNULL(`value`.`position`, `default_value`.`position`)' + ], + [ + '`value`.`disabled`', + '`default_value`.`disabled`', + 'IFNULL(`value`.`disabled`, `default_value`.`disabled`)' + ] + ]) + ); + $this->select->expects($this->at(2))->method('joinLeft')->with( + ['value' => $getTableReturnValue], + $quoteInfoReturnValue, + [] + )->willReturnSelf(); + $this->select->expects($this->at(3))->method('joinLeft')->with( + ['default_value' => $getTableReturnValue], + $quoteDefaultInfoReturnValue, + [] + )->willReturnSelf(); + $this->select->expects($this->at(4))->method('columns')->with([ + 'label' => 'IFNULL(`value`.`label`, `default_value`.`label`)', + 'position' => 'IFNULL(`value`.`position`, `default_value`.`position`)', + 'disabled' => 'IFNULL(`value`.`disabled`, `default_value`.`disabled`)', + 'label_default' => 'default_value.label', + 'position_default' => 'default_value.position', + 'disabled_default' => 'default_value.disabled' + ])->willReturnSelf(); + $this->select->expects($this->at(5))->method('where')->with( + 'main.attribute_id = ?', + $attributeId + )->willReturnSelf(); + $this->select->expects($this->at(6))->method('where') + ->with('main.disabled = 0')->willReturnSelf(); + $this->select->expects($this->at(8))->method('where') + ->with('entity.entity_id = ?', $productId) + ->willReturnSelf(); + $this->select->expects($this->once())->method('order') + ->with($positionCheckSql . ' ' . \Magento\Framework\DB\Select::SQL_ASC) + ->willReturnSelf(); + $this->connection->expects($this->once())->method('fetchAll') + ->with($this->select) + ->willReturn($resultRow); + + $this->assertEquals($resultRow, $this->resource->loadProductGalleryByAttributeId($this->product, $attributeId)); + } + + public function testInsertGalleryValueInStore() + { + $data = [ + 'value_id' => '8', + 'store_id' => 0, + 'provider' => '', + 'url' => 'https://www.youtube.com/watch?v=abcdfghijk', + 'title' => 'New Title', + 'description' => 'New Description', + 'metadata' => 'New metadata', + ]; + + $this->connection->expects($this->once())->method('describeTable')->willReturn($this->fields); + $this->connection->expects($this->any())->method('prepareColumnValue')->willReturnOnConsecutiveCalls( + '8', + 0, + '', + 'https://www.youtube.com/watch?v=abcdfghijk', + 'New Title', + 'New Description', + 'New metadata' + ); + + $this->resource->insertGalleryValueInStore($data); + } + + public function testDeleteGalleryValueInStore() + { + $valueId = 4; + $entityId = 6; + $storeId = 1; + + $this->connection->expects($this->exactly(3))->method('quoteInto')->withConsecutive( + ['value_id = ?', (int)$valueId], + ['entity_id = ?', (int)$entityId], + ['store_id = ?', (int)$storeId] + )->willReturnOnConsecutiveCalls( + 'value_id = ' . $valueId, + 'entity_id = ' . $entityId, + 'store_id = ' . $storeId + ); + + $this->connection->expects($this->once())->method('delete')->with( + 'table', + 'value_id = 4 AND entity_id = 6 AND store_id = 1' + )->willReturnSelf(); + + $this->resource->deleteGalleryValueInStore($valueId, $entityId, $storeId); + } + + public function testCountImageUses() + { + $results = [ + [ + 'value_id' => '1', + 'attribute_id' => 90, + 'value' => '/d/o/download_7.jpg', + 'media_type' => 'image', + 'disabled' => '0', + ], + ]; + + $this->connection->expects($this->once())->method('select')->will($this->returnValue($this->select)); + $this->select->expects($this->at(0))->method('from')->with( + [ + 'main' => 'table', + ], + '*' + )->willReturnSelf(); + $this->select->expects($this->at(1))->method('where')->with( + 'value = ?', + 1 + )->willReturnSelf(); + $this->connection->expects($this->once())->method('fetchAll') + ->with($this->select) + ->willReturn($results); + $this->assertEquals($this->resource->countImageUses(1), count($results)); + } } diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 9f43c8a69b5e5..d5b318f671726 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -813,7 +813,6 @@ default="0" comment="Is Disabled"/> - diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index a9b5dd2084c35..d4bd6927d4345 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -479,8 +479,7 @@ "label": true, "position": true, "disabled": true, - "record_id": true, - "image_metadata": true + "record_id": true }, "index": { "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID": true, diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index 034f68bdab9d4..ec69baeb92cb9 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -314,8 +314,7 @@ protected function prepareVariations() 'canEdit' => 0, 'newProduct' => 0, 'attributes' => $this->getTextAttributes($variationOptions), - 'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image') - ->getUrl(), + 'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image')->getUrl(), '__disableTmpl' => true ]; $productIds[] = $product->getId(); diff --git a/app/code/Magento/MediaStorage/Console/Command/ImagesResizeCommand.php b/app/code/Magento/MediaStorage/Console/Command/ImagesResizeCommand.php index 526774a3e6bcd..d592a004e111a 100644 --- a/app/code/Magento/MediaStorage/Console/Command/ImagesResizeCommand.php +++ b/app/code/Magento/MediaStorage/Console/Command/ImagesResizeCommand.php @@ -86,7 +86,8 @@ protected function configure() $this->setName('catalog:images:resize') ->setDescription( 'Creates resized product images ' . - '(Deprecated: see https://docs.magento.com/m2/ee/user_guide/configuration/general/web.html#url-options' + '(Not relevant when image resizing is offloaded from Magento. ' . + 'See https://docs.magento.com/m2/ee/user_guide/configuration/general/web.html#url-options )' ) ->setDefinition($this->getOptionsList()); } diff --git a/app/code/Magento/MediaStorage/Service/ImageResize.php b/app/code/Magento/MediaStorage/Service/ImageResize.php index 145fcd1b85f4f..d061ddbd3dc46 100644 --- a/app/code/Magento/MediaStorage/Service/ImageResize.php +++ b/app/code/Magento/MediaStorage/Service/ImageResize.php @@ -19,7 +19,6 @@ use Magento\Framework\Image\Factory as ImageFactory; use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig; use Magento\Framework\App\State; -use Magento\Framework\Storage\StorageProvider; use Magento\Framework\View\ConfigInterface as ViewConfig; use \Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage; use Magento\Store\Model\StoreManagerInterface; @@ -100,11 +99,6 @@ class ImageResize */ private $storeManager; - /** - * @var StorageProvider - */ - private $storageProvider; - /** * @param State $appState * @param MediaConfig $imageConfig @@ -118,7 +112,6 @@ class ImageResize * @param Filesystem $filesystem * @param Database $fileStorageDatabase * @param StoreManagerInterface $storeManager - * @param StorageProvider $storageProvider * @throws \Magento\Framework\Exception\FileSystemException * @internal param ProductImage $gallery * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -135,8 +128,7 @@ public function __construct( Collection $themeCollection, Filesystem $filesystem, Database $fileStorageDatabase = null, - StoreManagerInterface $storeManager = null, - StorageProvider $storageProvider = null + StoreManagerInterface $storeManager = null ) { $this->appState = $appState; $this->imageConfig = $imageConfig; @@ -152,7 +144,6 @@ public function __construct( $this->fileStorageDatabase = $fileStorageDatabase ?: ObjectManager::getInstance()->get(Database::class); $this->storeManager = $storeManager ?? ObjectManager::getInstance()->get(StoreManagerInterface::class); - $this->storageProvider = $storageProvider ?? ObjectManager::getInstance()->get(StorageProvider::class); } /** @@ -346,15 +337,10 @@ private function resize(array $imageParams, string $originalImagePath, string $o $image->save($imageAsset->getPath()); - $mediastoragefilename = $this->mediaDirectory->getRelativePath($imageAsset->getPath()); if ($this->fileStorageDatabase->checkDbUsage()) { + $mediastoragefilename = $this->mediaDirectory->getRelativePath($imageAsset->getPath()); $this->fileStorageDatabase->saveFile($mediastoragefilename); } - - $this->storageProvider->get('media')->put( - $mediastoragefilename, - $this->mediaDirectory->readFile($mediastoragefilename) - ); } /** diff --git a/app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php b/app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php index 74913b444e63a..f0e1efa7806e4 100644 --- a/app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php +++ b/app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php @@ -6,27 +6,25 @@ namespace Magento\MediaStorage\Test\Unit\Service; use Magento\Catalog\Model\Product\Image\ParamsBuilder; -use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig; -use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage; -use Magento\Catalog\Model\View\Asset\Image as AssetImage; use Magento\Catalog\Model\View\Asset\ImageFactory as AssetImageFactory; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\App\State; -use Magento\Framework\Config\View; +use Magento\Catalog\Model\View\Asset\Image as AssetImage; use Magento\Framework\DataObject; use Magento\Framework\Filesystem; -use Magento\Framework\Image; use Magento\Framework\Image\Factory as ImageFactory; -use Magento\Framework\Storage\StorageInterface; +use Magento\Framework\Image; +use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig; +use Magento\Framework\App\State; use Magento\Framework\View\ConfigInterface as ViewConfig; -use Magento\MediaStorage\Helper\File\Storage\Database; -use Magento\MediaStorage\Service\ImageResize; +use Magento\Framework\Config\View; +use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage; use Magento\Store\Model\StoreManagerInterface; use Magento\Theme\Model\Config\Customization as ThemeCustomizationConfig; use Magento\Theme\Model\ResourceModel\Theme\Collection; +use Magento\MediaStorage\Helper\File\Storage\Database; +use Magento\Framework\App\Filesystem\DirectoryList; /** - * Class ImageResizeTest test for \Magento\MediaStorage\Service\ImageResize + * Class ImageResizeTest * * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -34,7 +32,7 @@ class ImageResizeTest extends \PHPUnit\Framework\TestCase { /** - * @var ImageResize + * @var \Magento\MediaStorage\Service\ImageResize */ protected $service; @@ -122,17 +120,11 @@ class ImageResizeTest extends \PHPUnit\Framework\TestCase * @var string */ private $testfilepath; - /** * @var \PHPUnit\Framework\MockObject\MockObject|StoreManagerInterface */ private $storeManager; - /** - * @var StorageInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $storage; - /** * @inheritDoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -157,16 +149,10 @@ protected function setUp() $this->filesystemMock = $this->createMock(Filesystem::class); $this->databaseMock = $this->createMock(Database::class); $this->storeManager = $this->getMockForAbstractClass(StoreManagerInterface::class); - $storageProvider = $this->createMock(\Magento\Framework\Storage\StorageProvider::class); - $this->storage = $this->getMockForAbstractClass(StorageInterface::class); - $storageProvider->expects($this->any()) - ->method('get') - ->with('media') - ->willReturn($this->storage); $this->mediaDirectoryMock = $this->getMockBuilder(Filesystem::class) ->disableOriginalConstructor() - ->setMethods(['getAbsolutePath','isFile','getRelativePath', 'readFile']) + ->setMethods(['getAbsolutePath','isFile','getRelativePath']) ->getMock(); $this->filesystemMock->expects($this->any()) @@ -215,7 +201,8 @@ protected function setUp() $this->viewMock->expects($this->any()) ->method('getMediaEntities') ->willReturn( - ['product_small_image' => [ + ['product_small_image' => + [ 'type' => 'small_image', 'width' => 75, 'height' => 75 @@ -236,7 +223,7 @@ protected function setUp() ->method('getStores') ->willReturn([$store]); - $this->service = new ImageResize( + $this->service = new \Magento\MediaStorage\Service\ImageResize( $this->appStateMock, $this->imageConfigMock, $this->productImageMock, @@ -248,8 +235,7 @@ protected function setUp() $this->themeCollectionMock, $this->filesystemMock, $this->databaseMock, - $this->storeManager, - $storageProvider + $this->storeManager ); } @@ -292,14 +278,6 @@ function () { ->method('saveFile') ->with($this->testfilepath); - $this->mediaDirectoryMock->expects($this->any()) - ->method('readFile') - ->with($this->testfilepath) - ->willReturn('image data'); - $this->storage->expects($this->once()) - ->method('put') - ->with($this->testfilepath, 'image data'); - $generator = $this->service->resizeFromThemes(['test-theme']); while ($generator->valid()) { $generator->next(); @@ -338,14 +316,6 @@ public function testResizeFromImageNameMediaStorageDatabase() ->method('saveFile') ->with($this->testfilepath); - $this->mediaDirectoryMock->expects($this->any()) - ->method('readFile') - ->with($this->testfilepath) - ->willReturn('image data'); - $this->storage->expects($this->once()) - ->method('put') - ->with($this->testfilepath, 'image data'); - $this->service->resizeFromImageName($this->testfilename); } } diff --git a/app/code/Magento/MediaStorage/etc/di.xml b/app/code/Magento/MediaStorage/etc/di.xml index 061c3be1bbe4a..5cdcbb3b2b9a9 100644 --- a/app/code/Magento/MediaStorage/etc/di.xml +++ b/app/code/Magento/MediaStorage/etc/di.xml @@ -31,11 +31,4 @@ Magento\MediaStorage\Service\ImageResizeScheduler\Proxy - - - - pub/media - - - diff --git a/app/code/Magento/Theme/Test/Unit/Block/Adminhtml/Wysiwyg/Files/ContentTest.php b/app/code/Magento/Theme/Test/Unit/Block/Adminhtml/Wysiwyg/Files/ContentTest.php new file mode 100644 index 0000000000000..7fe3b25cf97b2 --- /dev/null +++ b/app/code/Magento/Theme/Test/Unit/Block/Adminhtml/Wysiwyg/Files/ContentTest.php @@ -0,0 +1,220 @@ +_helperStorage = $this->createMock(\Magento\Theme\Helper\Storage::class); + $this->_urlBuilder = $this->createMock(\Magento\Backend\Model\Url::class); + $this->_request = $this->createMock(\Magento\Framework\App\RequestInterface::class); + + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $constructArguments = $objectManagerHelper->getConstructArguments( + \Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Content::class, + [ + 'urlBuilder' => $this->_urlBuilder, + 'request' => $this->_request, + 'storageHelper' => $this->_helperStorage + ] + ); + $this->_filesContent = $objectManagerHelper->getObject( + \Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Content::class, + $constructArguments + ); + } + + /** + * @dataProvider requestParamsProvider + * @param array $requestParams + */ + public function testGetNewFolderUrl($requestParams) + { + $expectedUrl = 'some_url'; + + $this->_helperStorage->expects( + $this->once() + )->method( + 'getRequestParams' + )->will( + $this->returnValue($requestParams) + ); + + $this->_urlBuilder->expects( + $this->once() + )->method( + 'getUrl' + )->with( + 'adminhtml/*/newFolder', + $requestParams + )->will( + $this->returnValue($expectedUrl) + ); + + $this->assertEquals($expectedUrl, $this->_filesContent->getNewfolderUrl()); + } + + /** + * @dataProvider requestParamsProvider + * @param array $requestParams + */ + public function testGetDeleteFilesUrl($requestParams) + { + $expectedUrl = 'some_url'; + + $this->_helperStorage->expects( + $this->once() + )->method( + 'getRequestParams' + )->will( + $this->returnValue($requestParams) + ); + + $this->_urlBuilder->expects( + $this->once() + )->method( + 'getUrl' + )->with( + 'adminhtml/*/deleteFiles', + $requestParams + )->will( + $this->returnValue($expectedUrl) + ); + + $this->assertEquals($expectedUrl, $this->_filesContent->getDeleteFilesUrl()); + } + + /** + * @dataProvider requestParamsProvider + * @param array $requestParams + */ + public function testGetOnInsertUrl($requestParams) + { + $expectedUrl = 'some_url'; + + $this->_helperStorage->expects( + $this->once() + )->method( + 'getRequestParams' + )->will( + $this->returnValue($requestParams) + ); + + $this->_urlBuilder->expects( + $this->once() + )->method( + 'getUrl' + )->with( + 'adminhtml/*/onInsert', + $requestParams + )->will( + $this->returnValue($expectedUrl) + ); + + $this->assertEquals($expectedUrl, $this->_filesContent->getOnInsertUrl()); + } + + /** + * Data provider for requestParams + * @return array + */ + public function requestParamsProvider() + { + return [ + [ + 'requestParams' => [ + \Magento\Theme\Helper\Storage::PARAM_THEME_ID => 1, + \Magento\Theme\Helper\Storage::PARAM_CONTENT_TYPE => Storage::TYPE_IMAGE, + \Magento\Theme\Helper\Storage::PARAM_NODE => 'root', + ] + ] + ]; + } + + public function testGetTargetElementId() + { + $expectedRequest = 'some_request'; + + $this->_request->expects( + $this->once() + )->method( + 'getParam' + )->with( + 'target_element_id' + )->will( + $this->returnValue($expectedRequest) + ); + + $this->assertEquals($expectedRequest, $this->_filesContent->getTargetElementId()); + } + + public function testGetContentsUrl() + { + $expectedUrl = 'some_url'; + + $expectedRequest = 'some_request'; + + $requestParams = [ + \Magento\Theme\Helper\Storage::PARAM_THEME_ID => 1, + \Magento\Theme\Helper\Storage::PARAM_CONTENT_TYPE => Storage::TYPE_IMAGE, + \Magento\Theme\Helper\Storage::PARAM_NODE => 'root', + ]; + + $this->_urlBuilder->expects( + $this->once() + )->method( + 'getUrl' + )->with( + 'adminhtml/*/contents', + ['type' => $expectedRequest] + $requestParams + )->will( + $this->returnValue($expectedUrl) + ); + + $this->_request->expects( + $this->once() + )->method( + 'getParam' + )->with( + 'type' + )->will( + $this->returnValue($expectedRequest) + ); + + $this->_helperStorage->expects( + $this->once() + )->method( + 'getRequestParams' + )->will( + $this->returnValue($requestParams) + ); + + $this->assertEquals($expectedUrl, $this->_filesContent->getContentsUrl()); + } +} diff --git a/app/etc/di.xml b/app/etc/di.xml index 85d05b6be38fa..a11b8fd5a2506 100644 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1814,13 +1814,4 @@ configured_block_cache - - - - Magento\Framework\Storage\AdapterFactory\LocalFactory - Magento\Framework\Storage\AdapterFactory\AwsS3Factory - Magento\Framework\Storage\AdapterFactory\AzureFactory - - - diff --git a/composer.json b/composer.json index ac005f9da6a1e..db34b0a9c2fd0 100644 --- a/composer.json +++ b/composer.json @@ -35,14 +35,11 @@ "colinmollenhour/php-redis-session-abstract": "~1.4.0", "composer/composer": "^1.6", "elasticsearch/elasticsearch": "~2.0||~5.1||~6.1", - "guzzlehttp/guzzle": "^6.3.3", - "league/flysystem": "^1.0", - "league/flysystem-aws-s3-v3": "^1.0", - "league/flysystem-azure-blob-storage": "^0.1.6", "magento/composer": "1.6.x-dev", "magento/magento-composer-installer": ">=0.1.11", "magento/zendframework1": "~1.14.2", "monolog/monolog": "^1.17", + "wikimedia/less.php": "~1.8.0", "paragonie/sodium_compat": "^1.6", "pelago/emogrifier": "^2.0.0", "php-amqplib/php-amqplib": "~2.7.0||~2.10.0", @@ -55,7 +52,6 @@ "tedivm/jshrink": "~1.3.0", "tubalmartin/cssmin": "4.1.1", "webonyx/graphql-php": "^0.13.8", - "wikimedia/less.php": "~1.8.0", "zendframework/zend-captcha": "^2.7.1", "zendframework/zend-code": "~3.3.0", "zendframework/zend-config": "^2.6.0", @@ -83,7 +79,8 @@ "zendframework/zend-text": "^2.6.0", "zendframework/zend-uri": "^2.5.1", "zendframework/zend-validator": "^2.6.0", - "zendframework/zend-view": "~2.11.2" + "zendframework/zend-view": "~2.11.2", + "guzzlehttp/guzzle": "^6.3.3" }, "require-dev": { "allure-framework/allure-phpunit": "~1.2.0", diff --git a/composer.lock b/composer.lock index 1236d2b0ae82f..144614ba2279d 100644 --- a/composer.lock +++ b/composer.lock @@ -1,95 +1,11 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "522d676db5baf5864a824409c54948fc", + "content-hash": "d9bed7b45c83f9133bdec76acac8b796", "packages": [ - { - "name": "aws/aws-sdk-php", - "version": "3.133.24", - "source": { - "type": "git", - "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "726426e1514be5220d55ecf02eb1f938a3b4a105" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/726426e1514be5220d55ecf02eb1f938a3b4a105", - "reference": "726426e1514be5220d55ecf02eb1f938a3b4a105", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-simplexml": "*", - "guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4.1", - "mtdowling/jmespath.php": "^2.5", - "php": ">=5.5" - }, - "require-dev": { - "andrewsville/php-token-reflection": "^1.4", - "aws/aws-php-sns-message-validator": "~1.0", - "behat/behat": "~3.0", - "doctrine/cache": "~1.4", - "ext-dom": "*", - "ext-openssl": "*", - "ext-pcntl": "*", - "ext-sockets": "*", - "nette/neon": "^2.3", - "phpunit/phpunit": "^4.8.35|^5.4.3", - "psr/cache": "^1.0", - "psr/simple-cache": "^1.0", - "sebastian/comparator": "^1.2.3" - }, - "suggest": { - "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", - "doctrine/cache": "To use the DoctrineCacheAdapter", - "ext-curl": "To send requests using cURL", - "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", - "ext-sockets": "To use client-side monitoring" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Aws\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Amazon Web Services", - "homepage": "http://aws.amazon.com" - } - ], - "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", - "homepage": "http://aws.amazon.com/sdkforphp", - "keywords": [ - "amazon", - "aws", - "cloud", - "dynamodb", - "ec2", - "glacier", - "s3", - "sdk" - ], - "time": "2020-02-27T19:13:45+00:00" - }, { "name": "braintree/braintree_php", "version": "3.35.0", @@ -341,16 +257,16 @@ }, { "name": "composer/composer", - "version": "1.9.3", + "version": "1.9.2", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "1291a16ce3f48bfdeca39d64fca4875098af4d7b" + "reference": "7a04aa0201ddaa0b3cf64d41022bd8cdcd7fafeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/1291a16ce3f48bfdeca39d64fca4875098af4d7b", - "reference": "1291a16ce3f48bfdeca39d64fca4875098af4d7b", + "url": "https://api.github.com/repos/composer/composer/zipball/7a04aa0201ddaa0b3cf64d41022bd8cdcd7fafeb", + "reference": "7a04aa0201ddaa0b3cf64d41022bd8cdcd7fafeb", "shasum": "" }, "require": { @@ -417,7 +333,7 @@ "dependency", "package" ], - "time": "2020-02-04T11:58:49+00:00" + "time": "2020-01-14T15:30:32+00:00" }, { "name": "composer/semver", @@ -482,16 +398,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.3", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "0c3e51e1880ca149682332770e25977c70cf9dae" + "reference": "7ac1e6aec371357df067f8a688c3d6974df68fa5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/0c3e51e1880ca149682332770e25977c70cf9dae", - "reference": "0c3e51e1880ca149682332770e25977c70cf9dae", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7ac1e6aec371357df067f8a688c3d6974df68fa5", + "reference": "7ac1e6aec371357df067f8a688c3d6974df68fa5", "shasum": "" }, "require": { @@ -538,7 +454,7 @@ "spdx", "validator" ], - "time": "2020-02-14T07:44:31+00:00" + "time": "2019-07-29T10:31:59+00:00" }, { "name": "composer/xdebug-handler", @@ -1034,178 +950,6 @@ ], "time": "2019-09-25T14:49:45+00:00" }, - { - "name": "league/flysystem", - "version": "1.0.64", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "d13c43dbd4b791f815215959105a008515d1a2e0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/d13c43dbd4b791f815215959105a008515d1a2e0", - "reference": "d13c43dbd4b791f815215959105a008515d1a2e0", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "php": ">=5.5.9" - }, - "conflict": { - "league/flysystem-sftp": "<1.0.6" - }, - "require-dev": { - "phpspec/phpspec": "^3.4", - "phpunit/phpunit": "^5.7.26" - }, - "suggest": { - "ext-fileinfo": "Required for MimeType", - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "description": "Filesystem abstraction: Many filesystems, one API.", - "keywords": [ - "Cloud Files", - "WebDAV", - "abstraction", - "aws", - "cloud", - "copy.com", - "dropbox", - "file systems", - "files", - "filesystem", - "filesystems", - "ftp", - "rackspace", - "remote", - "s3", - "sftp", - "storage" - ], - "time": "2020-02-05T18:14:17+00:00" - }, - { - "name": "league/flysystem-aws-s3-v3", - "version": "1.0.24", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", - "reference": "4382036bde5dc926f9b8b337e5bdb15e5ec7b570" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/4382036bde5dc926f9b8b337e5bdb15e5ec7b570", - "reference": "4382036bde5dc926f9b8b337e5bdb15e5ec7b570", - "shasum": "" - }, - "require": { - "aws/aws-sdk-php": "^3.0.0", - "league/flysystem": "^1.0.40", - "php": ">=5.5.0" - }, - "require-dev": { - "henrikbjorn/phpspec-code-coverage": "~1.0.1", - "phpspec/phpspec": "^2.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Flysystem\\AwsS3v3\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "description": "Flysystem adapter for the AWS S3 SDK v3.x", - "time": "2020-02-23T13:31:58+00:00" - }, - { - "name": "league/flysystem-azure-blob-storage", - "version": "0.1.6", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-azure-blob-storage.git", - "reference": "97215345f3c42679299ba556a4d16d4847ee7f6d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-azure-blob-storage/zipball/97215345f3c42679299ba556a4d16d4847ee7f6d", - "reference": "97215345f3c42679299ba556a4d16d4847ee7f6d", - "shasum": "" - }, - "require": { - "guzzlehttp/psr7": "^1.5", - "league/flysystem": "^1.0", - "microsoft/azure-storage-blob": "^1.1", - "php": ">=5.6" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\AzureBlobStorage\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "time": "2019-06-07T20:42:16+00:00" - }, { "name": "magento/composer", "version": "1.6.x-dev", @@ -1368,94 +1112,6 @@ ], "time": "2019-11-26T15:09:40+00:00" }, - { - "name": "microsoft/azure-storage-blob", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/Azure/azure-storage-blob-php.git", - "reference": "6a333cd28a3742c3e99e79042dc6510f9f917919" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/6a333cd28a3742c3e99e79042dc6510f9f917919", - "reference": "6a333cd28a3742c3e99e79042dc6510f9f917919", - "shasum": "" - }, - "require": { - "microsoft/azure-storage-common": "~1.4", - "php": ">=5.6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "MicrosoftAzure\\Storage\\Blob\\": "src/Blob" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Azure Storage PHP Client Library", - "email": "dmsh@microsoft.com" - } - ], - "description": "This project provides a set of PHP client libraries that make it easy to access Microsoft Azure Storage Blob APIs.", - "keywords": [ - "azure", - "blob", - "php", - "sdk", - "storage" - ], - "time": "2020-01-02T07:18:59+00:00" - }, - { - "name": "microsoft/azure-storage-common", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/Azure/azure-storage-common-php.git", - "reference": "be4df800761d0d0fa91a9460c7f42517197d57a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/be4df800761d0d0fa91a9460c7f42517197d57a0", - "reference": "be4df800761d0d0fa91a9460c7f42517197d57a0", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "~6.0", - "php": ">=5.6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "MicrosoftAzure\\Storage\\Common\\": "src/Common" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Azure Storage PHP Client Library", - "email": "dmsh@microsoft.com" - } - ], - "description": "This project provides a set of common code shared by Azure Storage Blob, Table, Queue and File PHP client libraries.", - "keywords": [ - "azure", - "common", - "php", - "sdk", - "storage" - ], - "time": "2020-01-02T07:15:54+00:00" - }, { "name": "monolog/monolog", "version": "1.25.3", @@ -1534,63 +1190,6 @@ ], "time": "2019-12-20T14:15:16+00:00" }, - { - "name": "mtdowling/jmespath.php", - "version": "2.5.0", - "source": { - "type": "git", - "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "52168cb9472de06979613d365c7f1ab8798be895" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/52168cb9472de06979613d365c7f1ab8798be895", - "reference": "52168cb9472de06979613d365c7f1ab8798be895", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "symfony/polyfill-mbstring": "^1.4" - }, - "require-dev": { - "composer/xdebug-handler": "^1.2", - "phpunit/phpunit": "^4.8.36|^7.5.15" - }, - "bin": [ - "bin/jp.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-4": { - "JmesPath\\": "src/" - }, - "files": [ - "src/JmesPath.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Declaratively specify how to extract elements from a JSON document", - "keywords": [ - "json", - "jsonpath" - ], - "time": "2019-12-30T18:03:34+00:00" - }, { "name": "paragonie/random_compat", "version": "v9.99.99", @@ -1916,16 +1515,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.25", + "version": "2.0.23", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "c18159618ed7cd7ff721ac1a8fec7860a475d2f0" + "reference": "c78eb5058d5bb1a183133c36d4ba5b6675dfa099" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c18159618ed7cd7ff721ac1a8fec7860a475d2f0", - "reference": "c18159618ed7cd7ff721ac1a8fec7860a475d2f0", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c78eb5058d5bb1a183133c36d4ba5b6675dfa099", + "reference": "c78eb5058d5bb1a183133c36d4ba5b6675dfa099", "shasum": "" }, "require": { @@ -2004,7 +1603,7 @@ "x.509", "x509" ], - "time": "2020-02-25T04:16:50+00:00" + "time": "2019-09-17T03:41:22+00:00" }, { "name": "psr/container", @@ -2371,16 +1970,16 @@ }, { "name": "seld/phar-utils", - "version": "1.1.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0" + "reference": "84715761c35808076b00908a20317a3a8a67d17e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8800503d56b9867d43d9c303b9cbcc26016e82f0", - "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/84715761c35808076b00908a20317a3a8a67d17e", + "reference": "84715761c35808076b00908a20317a3a8a67d17e", "shasum": "" }, "require": { @@ -2409,22 +2008,22 @@ ], "description": "PHAR file format utilities, for when PHP phars you up", "keywords": [ - "phar" + "phra" ], - "time": "2020-02-14T15:25:33+00:00" + "time": "2020-01-13T10:41:09+00:00" }, { "name": "symfony/console", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f512001679f37e6a042b51897ed24a2f05eba656" + "reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f512001679f37e6a042b51897ed24a2f05eba656", - "reference": "f512001679f37e6a042b51897ed24a2f05eba656", + "url": "https://api.github.com/repos/symfony/console/zipball/e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f", + "reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f", "shasum": "" }, "require": { @@ -2487,11 +2086,11 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2020-01-25T12:44:29+00:00" + "time": "2020-01-10T21:54:01+00:00" }, { "name": "symfony/css-selector", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -2544,7 +2143,7 @@ }, { "name": "symfony/event-dispatcher", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -2672,7 +2271,7 @@ }, { "name": "symfony/filesystem", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -2722,7 +2321,7 @@ }, { "name": "symfony/finder", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -2771,16 +2370,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.14.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38" + "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", - "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", + "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", "shasum": "" }, "require": { @@ -2792,7 +2391,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -2825,20 +2424,20 @@ "polyfill", "portable" ], - "time": "2020-01-13T11:15:53+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.14.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2" + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/34094cfa9abe1f0f14f48f490772db7a775559f2", - "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", "shasum": "" }, "require": { @@ -2850,7 +2449,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -2884,20 +2483,20 @@ "portable", "shim" ], - "time": "2020-01-13T11:15:53+00:00" + "time": "2019-11-27T14:18:11+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.14.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "5e66a0fa1070bf46bec4bea7962d285108edd675" + "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/5e66a0fa1070bf46bec4bea7962d285108edd675", - "reference": "5e66a0fa1070bf46bec4bea7962d285108edd675", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/4b0e2222c55a25b4541305a053013d5647d3a25f", + "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f", "shasum": "" }, "require": { @@ -2906,7 +2505,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -2942,11 +2541,11 @@ "portable", "shim" ], - "time": "2020-01-13T11:15:53+00:00" + "time": "2019-11-27T16:25:15+00:00" }, { "name": "symfony/process", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -5499,16 +5098,16 @@ }, { "name": "allure-framework/allure-php-api", - "version": "1.1.7", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/allure-framework/allure-php-commons.git", - "reference": "243c9a2259b60c1b7a9d298d4fb3fc72b4f64c18" + "reference": "2c62a70d60eca190253a6b80e9aa4c2ebc2e6e7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-php-commons/zipball/243c9a2259b60c1b7a9d298d4fb3fc72b4f64c18", - "reference": "243c9a2259b60c1b7a9d298d4fb3fc72b4f64c18", + "url": "https://api.github.com/repos/allure-framework/allure-php-commons/zipball/2c62a70d60eca190253a6b80e9aa4c2ebc2e6e7f", + "reference": "2c62a70d60eca190253a6b80e9aa4c2ebc2e6e7f", "shasum": "" }, "require": { @@ -5548,7 +5147,7 @@ "php", "report" ], - "time": "2020-02-05T16:43:19+00:00" + "time": "2020-01-09T10:26:09+00:00" }, { "name": "allure-framework/allure-phpunit", @@ -5600,18 +5199,102 @@ ], "time": "2017-11-03T13:08:21+00:00" }, + { + "name": "aws/aws-sdk-php", + "version": "3.133.8", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "c564fcccd5fc7b5e8514d1cbe35558be1e3a11cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c564fcccd5fc7b5e8514d1cbe35558be1e3a11cd", + "reference": "c564fcccd5fc7b5e8514d1cbe35558be1e3a11cd", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4.1", + "mtdowling/jmespath.php": "^2.5", + "php": ">=5.5" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "phpunit/phpunit": "^4.8.35|^5.4.3", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Aws\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "time": "2020-02-05T19:12:47+00:00" + }, { "name": "behat/gherkin", - "version": "v4.6.1", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/Behat/Gherkin.git", - "reference": "25bdcaf37898b4a939fa3031d5d753ced97e4759" + "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/25bdcaf37898b4a939fa3031d5d753ced97e4759", - "reference": "25bdcaf37898b4a939fa3031d5d753ced97e4759", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/ab0a02ea14893860bca00f225f5621d351a3ad07", + "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07", "shasum": "" }, "require": { @@ -5657,7 +5340,7 @@ "gherkin", "parser" ], - "time": "2020-02-27T11:29:57+00:00" + "time": "2019-01-16T14:22:17+00:00" }, { "name": "cache/cache", @@ -5921,31 +5604,31 @@ }, { "name": "consolidation/annotated-command", - "version": "4.1.0", + "version": "2.12.0", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "33e472d3cceb0f22a527d13ccfa3f76c4d21c178" + "reference": "512a2e54c98f3af377589de76c43b24652bcb789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/33e472d3cceb0f22a527d13ccfa3f76c4d21c178", - "reference": "33e472d3cceb0f22a527d13ccfa3f76c4d21c178", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/512a2e54c98f3af377589de76c43b24652bcb789", + "reference": "512a2e54c98f3af377589de76c43b24652bcb789", "shasum": "" }, "require": { - "consolidation/output-formatters": "^4.1", - "php": ">=7.1.3", - "psr/log": "^1|^2", - "symfony/console": "^4|^5", - "symfony/event-dispatcher": "^4|^5", - "symfony/finder": "^4|^5" + "consolidation/output-formatters": "^3.4", + "php": ">=5.4.5", + "psr/log": "^1", + "symfony/console": "^2.8|^3|^4", + "symfony/event-dispatcher": "^2.5|^3|^4", + "symfony/finder": "^2.5|^3|^4" }, "require-dev": { "g1a/composer-test-scenarios": "^3", "php-coveralls/php-coveralls": "^1", "phpunit/phpunit": "^6", - "squizlabs/php_codesniffer": "^3" + "squizlabs/php_codesniffer": "^2.7" }, "type": "library", "extra": { @@ -5953,11 +5636,48 @@ "symfony4": { "require": { "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + }, + "phpunit4": { + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } } } }, "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -5976,7 +5696,7 @@ } ], "description": "Initialize Symfony Console commands from annotated command class methods.", - "time": "2020-02-07T03:35:30+00:00" + "time": "2019-03-08T16:55:03+00:00" }, { "name": "consolidation/config", @@ -6061,33 +5781,74 @@ }, { "name": "consolidation/log", - "version": "2.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/consolidation/log.git", - "reference": "446f804476db4f73957fa4bcb66ab2facf5397ff" + "reference": "b2e887325ee90abc96b0a8b7b474cd9e7c896e3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/log/zipball/446f804476db4f73957fa4bcb66ab2facf5397ff", - "reference": "446f804476db4f73957fa4bcb66ab2facf5397ff", + "url": "https://api.github.com/repos/consolidation/log/zipball/b2e887325ee90abc96b0a8b7b474cd9e7c896e3a", + "reference": "b2e887325ee90abc96b0a8b7b474cd9e7c896e3a", "shasum": "" }, "require": { "php": ">=5.4.5", "psr/log": "^1.0", - "symfony/console": "^4|^5" + "symfony/console": "^2.8|^3|^4" }, "require-dev": { "g1a/composer-test-scenarios": "^3", "php-coveralls/php-coveralls": "^1", "phpunit/phpunit": "^6", - "squizlabs/php_codesniffer": "^3" + "squizlabs/php_codesniffer": "^2" }, "type": "library", "extra": { + "scenarios": { + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + }, + "phpunit4": { + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -6106,35 +5867,34 @@ } ], "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", - "time": "2020-02-07T01:22:27+00:00" + "time": "2019-01-01T17:30:51+00:00" }, { "name": "consolidation/output-formatters", - "version": "4.1.0", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/consolidation/output-formatters.git", - "reference": "eae721c3a916707c40d4390efbf48d4c799709cc" + "reference": "99ec998ffb697e0eada5aacf81feebfb13023605" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/eae721c3a916707c40d4390efbf48d4c799709cc", - "reference": "eae721c3a916707c40d4390efbf48d4c799709cc", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/99ec998ffb697e0eada5aacf81feebfb13023605", + "reference": "99ec998ffb697e0eada5aacf81feebfb13023605", "shasum": "" }, "require": { "dflydev/dot-access-data": "^1.1.0", - "php": ">=7.1.3", - "symfony/console": "^4|^5", - "symfony/finder": "^4|^5" + "php": ">=5.4.0", + "symfony/console": "^2.8|^3|^4", + "symfony/finder": "^2.5|^3|^4" }, "require-dev": { "g1a/composer-test-scenarios": "^3", "php-coveralls/php-coveralls": "^1", - "phpunit/phpunit": "^6", - "squizlabs/php_codesniffer": "^3", - "symfony/var-dumper": "^4", - "symfony/yaml": "^4", + "phpunit/phpunit": "^5.7.27", + "squizlabs/php_codesniffer": "^2.7", + "symfony/var-dumper": "^2.8|^3|^4", "victorjonsson/markdowndocs": "^1.3" }, "suggest": { @@ -6146,11 +5906,50 @@ "symfony4": { "require": { "symfony/console": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^6" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony3": { + "require": { + "symfony/console": "^3.4", + "symfony/finder": "^3.4", + "symfony/var-dumper": "^3.4" + }, + "config": { + "platform": { + "php": "5.6.32" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + }, + "scenario-options": { + "create-lockfile": "false" } } }, "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { @@ -6169,30 +5968,30 @@ } ], "description": "Format text by applying transformations provided by plug-in formatters.", - "time": "2020-02-07T03:22:30+00:00" + "time": "2019-05-30T23:16:01+00:00" }, { "name": "consolidation/robo", - "version": "1.4.12", + "version": "1.4.11", "source": { "type": "git", "url": "https://github.com/consolidation/Robo.git", - "reference": "eb45606f498b3426b9a98b7c85e300666a968e51" + "reference": "5fa1d901776a628167a325baa9db95d8edf13a80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/Robo/zipball/eb45606f498b3426b9a98b7c85e300666a968e51", - "reference": "eb45606f498b3426b9a98b7c85e300666a968e51", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/5fa1d901776a628167a325baa9db95d8edf13a80", + "reference": "5fa1d901776a628167a325baa9db95d8edf13a80", "shasum": "" }, "require": { - "consolidation/annotated-command": "^2.11.0|^4.1", - "consolidation/config": "^1.2.1", - "consolidation/log": "^1.1.1|^2", - "consolidation/output-formatters": "^3.1.13|^4.1", - "consolidation/self-update": "^1.1.5", - "grasmash/yaml-expander": "^1.4", - "league/container": "^2.4.1", + "consolidation/annotated-command": "^2.11.0", + "consolidation/config": "^1.2", + "consolidation/log": "~1", + "consolidation/output-formatters": "^3.1.13", + "consolidation/self-update": "^1", + "grasmash/yaml-expander": "^1.3", + "league/container": "^2.2", "php": ">=5.5.0", "symfony/console": "^2.8|^3|^4", "symfony/event-dispatcher": "^2.5|^3|^4", @@ -6204,13 +6003,20 @@ "codegyre/robo": "< 1.0" }, "require-dev": { + "codeception/aspect-mock": "^1|^2.1.1", + "codeception/base": "^2.3.7", + "codeception/verify": "^0.3.2", "g1a/composer-test-scenarios": "^3", + "goaop/framework": "~2.1.2", + "goaop/parser-reflection": "^1.1.0", "natxet/cssmin": "3.0.4", - "patchwork/jsqueeze": "^2", + "nikic/php-parser": "^3.1.5", + "patchwork/jsqueeze": "~2", "pear/archive_tar": "^1.4.4", "php-coveralls/php-coveralls": "^1", - "phpunit/phpunit": "^5.7.27", - "squizlabs/php_codesniffer": "^3" + "phpunit/php-code-coverage": "~2|~4", + "sebastian/comparator": "^1.2.4", + "squizlabs/php_codesniffer": "^2.8" }, "suggest": { "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", @@ -6238,11 +6044,8 @@ "require": { "symfony/console": "^2.8" }, - "require-dev": { - "phpunit/phpunit": "^4.8.36" - }, "remove": [ - "php-coveralls/php-coveralls" + "goaop/framework" ], "config": { "platform": { @@ -6255,7 +6058,7 @@ } }, "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -6274,7 +6077,7 @@ } ], "description": "Modern task runner", - "time": "2020-02-18T17:31:26+00:00" + "time": "2019-10-29T15:50:02+00:00" }, { "name": "consolidation/self-update", @@ -7239,16 +7042,16 @@ }, { "name": "jms/serializer", - "version": "1.14.1", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/serializer.git", - "reference": "ba908d278fff27ec01fb4349f372634ffcd697c0" + "reference": "ee96d57024af9a7716d56fcbe3aa94b3d030f3ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/ba908d278fff27ec01fb4349f372634ffcd697c0", - "reference": "ba908d278fff27ec01fb4349f372634ffcd697c0", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/ee96d57024af9a7716d56fcbe3aa94b3d030f3ca", + "reference": "ee96d57024af9a7716d56fcbe3aa94b3d030f3ca", "shasum": "" }, "require": { @@ -7301,13 +7104,13 @@ "MIT" ], "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" - }, { "name": "Asmir Mustafic", "email": "goetas@gmail.com" + }, + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" } ], "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", @@ -7319,7 +7122,7 @@ "serialization", "xml" ], - "time": "2020-02-22T20:59:37+00:00" + "time": "2019-04-17T08:12:16+00:00" }, { "name": "league/container", @@ -7386,6 +7189,90 @@ ], "time": "2017-05-10T09:20:27+00:00" }, + { + "name": "league/flysystem", + "version": "1.0.63", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "8132daec326565036bc8e8d1876f77ec183a7bd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8132daec326565036bc8e8d1876f77ec183a7bd6", + "reference": "8132daec326565036bc8e8d1876f77ec183a7bd6", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": ">=5.5.9" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7.10" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2020-01-04T16:30:31+00:00" + }, { "name": "lusitanian/oauth", "version": "v0.8.11", @@ -7623,6 +7510,63 @@ "homepage": "http://vfs.bovigo.org/", "time": "2019-10-30T15:31:00+00:00" }, + { + "name": "mtdowling/jmespath.php", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "52168cb9472de06979613d365c7f1ab8798be895" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/52168cb9472de06979613d365c7f1ab8798be895", + "reference": "52168cb9472de06979613d365c7f1ab8798be895", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "symfony/polyfill-mbstring": "^1.4" + }, + "require-dev": { + "composer/xdebug-handler": "^1.2", + "phpunit/phpunit": "^4.8.36|^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": [ + "src/JmesPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "time": "2019-12-30T18:03:34+00:00" + }, { "name": "mustache/mustache", "version": "v2.13.0", @@ -7912,16 +7856,16 @@ }, { "name": "php-webdriver/webdriver", - "version": "1.8.1", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/php-webdriver/php-webdriver.git", - "reference": "262ea0d209c292e0330be1041424887bbbffef04" + "reference": "3e33ee3b8a688d719c55acdd7c6788e3006e1d3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/262ea0d209c292e0330be1041424887bbbffef04", - "reference": "262ea0d209c292e0330be1041424887bbbffef04", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/3e33ee3b8a688d719c55acdd7c6788e3006e1d3e", + "reference": "3e33ee3b8a688d719c55acdd7c6788e3006e1d3e", "shasum": "" }, "require": { @@ -7953,12 +7897,12 @@ } }, "autoload": { - "psr-4": { - "Facebook\\WebDriver\\": "lib/" - }, "files": [ "lib/Exception/TimeoutException.php" - ] + ], + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7973,7 +7917,7 @@ "selenium", "webdriver" ], - "time": "2020-02-17T08:14:38+00:00" + "time": "2020-02-10T15:04:25+00:00" }, { "name": "phpcollection/phpcollection", @@ -8135,38 +8079,41 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.1.0", + "version": "4.3.4", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e" + "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", - "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", + "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", "shasum": "" }, "require": { - "ext-filter": "^7.1", - "php": "^7.2", - "phpdocumentor/reflection-common": "^2.0", - "phpdocumentor/type-resolver": "^1.0", - "webmozart/assert": "^1" + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", + "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "^1", - "mockery/mockery": "^1" + "doctrine/instantiator": "^1.0.5", + "mockery/mockery": "^1.0", + "phpdocumentor/type-resolver": "0.4.*", + "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-master": "4.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "phpDocumentor\\Reflection\\": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", @@ -8177,14 +8124,10 @@ { "name": "Mike van Riel", "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-02-22T12:28:44+00:00" + "time": "2019-12-28T18:55:12+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -8421,16 +8364,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.11", + "version": "0.12.7", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "ca5f2b7cf81c6d8fba74f9576970399c5817e03b" + "reference": "07fa7958027fd98c567099bbcda5d6a0f2ec5197" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ca5f2b7cf81c6d8fba74f9576970399c5817e03b", - "reference": "ca5f2b7cf81c6d8fba74f9576970399c5817e03b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/07fa7958027fd98c567099bbcda5d6a0f2ec5197", + "reference": "07fa7958027fd98c567099bbcda5d6a0f2ec5197", "shasum": "" }, "require": { @@ -8456,7 +8399,7 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", - "time": "2020-02-16T14:00:29+00:00" + "time": "2020-01-20T21:59:06+00:00" }, { "name": "phpunit/php-code-coverage", @@ -9650,7 +9593,7 @@ }, { "name": "symfony/browser-kit", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", @@ -9709,7 +9652,7 @@ }, { "name": "symfony/config", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", @@ -9773,16 +9716,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "ec60a7d12f5e8ab0f99456adce724717d9c1784a" + "reference": "6faf589e1f6af78692aed3ab6b3c336c58d5d83c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ec60a7d12f5e8ab0f99456adce724717d9c1784a", - "reference": "ec60a7d12f5e8ab0f99456adce724717d9c1784a", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6faf589e1f6af78692aed3ab6b3c336c58d5d83c", + "reference": "6faf589e1f6af78692aed3ab6b3c336c58d5d83c", "shasum": "" }, "require": { @@ -9842,11 +9785,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2020-01-31T09:49:27+00:00" + "time": "2020-01-21T07:39:36+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -9907,16 +9850,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "491a20dfa87e0b3990170593bc2de0bb34d828a5" + "reference": "c33998709f3fe9b8e27e0277535b07fbf6fde37a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/491a20dfa87e0b3990170593bc2de0bb34d828a5", - "reference": "491a20dfa87e0b3990170593bc2de0bb34d828a5", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c33998709f3fe9b8e27e0277535b07fbf6fde37a", + "reference": "c33998709f3fe9b8e27e0277535b07fbf6fde37a", "shasum": "" }, "require": { @@ -9958,11 +9901,11 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2020-01-31T09:11:17+00:00" + "time": "2020-01-04T13:00:46+00:00" }, { "name": "symfony/mime", - "version": "v5.0.4", + "version": "v5.0.3", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", @@ -10024,7 +9967,7 @@ }, { "name": "symfony/options-resolver", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -10078,22 +10021,22 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.14.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "6842f1a39cf7d580655688069a03dd7cd83d244a" + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6842f1a39cf7d580655688069a03dd7cd83d244a", - "reference": "6842f1a39cf7d580655688069a03dd7cd83d244a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6f9c239e61e1b0c9229a28ff89a812dc449c3d46", + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46", "shasum": "" }, "require": { "php": ">=5.3.3", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.10" + "symfony/polyfill-php72": "^1.9" }, "suggest": { "ext-intl": "For best performance" @@ -10101,7 +10044,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -10136,20 +10079,20 @@ "portable", "shim" ], - "time": "2020-01-17T12:01:36+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.14.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "419c4940024c30ccc033650373a1fe13890d3255" + "reference": "af23c7bb26a73b850840823662dda371484926c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/419c4940024c30ccc033650373a1fe13890d3255", - "reference": "419c4940024c30ccc033650373a1fe13890d3255", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/af23c7bb26a73b850840823662dda371484926c4", + "reference": "af23c7bb26a73b850840823662dda371484926c4", "shasum": "" }, "require": { @@ -10159,7 +10102,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -10195,20 +10138,20 @@ "portable", "shim" ], - "time": "2020-01-13T11:15:53+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.14.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf" + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf", - "reference": "46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", "shasum": "" }, "require": { @@ -10217,7 +10160,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.14-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -10250,11 +10193,11 @@ "portable", "shim" ], - "time": "2020-01-13T11:15:53+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -10304,7 +10247,7 @@ }, { "name": "symfony/yaml", - "version": "v4.4.4", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", @@ -10494,16 +10437,16 @@ }, { "name": "webmozart/assert", - "version": "1.7.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "aed98a490f9a8f78468232db345ab9cf606cf598" + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598", - "reference": "aed98a490f9a8f78468232db345ab9cf606cf598", + "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", "shasum": "" }, "require": { @@ -10538,7 +10481,7 @@ "check", "validate" ], - "time": "2020-02-14T12:15:55+00:00" + "time": "2019-11-24T13:36:37+00:00" }, { "name": "weew/helpers-array", diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php new file mode 100644 index 0000000000000..569cf2357675c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -0,0 +1,165 @@ +objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var \Magento\Framework\Filesystem $filesystem */ + $this->filesystem = $this->objectManager->get(\Magento\Framework\Filesystem::class); + $this->mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + /** @var $uploader \Magento\MediaStorage\Model\File\Uploader */ + $this->imageUploader = $this->objectManager->create( + \Magento\Catalog\Model\ImageUploader::class, + [ + 'baseTmpPath' => 'catalog/tmp/category', + 'basePath' => 'catalog/category', + 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], + 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] + ] + ); + } + + /** + * @return void + */ + public function testSaveFileToTmpDir(): void + { + $fileName = 'magento_small_image.jpg'; + $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $fixtureDir = realpath(__DIR__ . '/../_files'); + $filePath = $tmpDirectory->getAbsolutePath($fileName); + copy($fixtureDir . DIRECTORY_SEPARATOR . $fileName, $filePath); + + $_FILES['image'] = [ + 'name' => $fileName, + 'type' => 'image/jpeg', + 'tmp_name' => $filePath, + 'error' => 0, + 'size' => 12500, + ]; + + $this->imageUploader->saveFileToTmpDir('image'); + $filePath = $this->imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; + $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($filePath))); + } + + /** + * Test that method rename files when move it with the same name into base directory. + * + * @return void + * @magentoDataFixture Magento/Catalog/_files/catalog_category_image.php + * @magentoDataFixture Magento/Catalog/_files/catalog_tmp_category_image.php + */ + public function testMoveFileFromTmp(): void + { + $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . 'magento_small_image_1.jpg'; + + $this->assertFileNotExists($this->mediaDirectory->getAbsolutePath($expectedFilePath)); + + $this->imageUploader->moveFileFromTmp('magento_small_image.jpg'); + + $this->assertFileExists($this->mediaDirectory->getAbsolutePath($expectedFilePath)); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage File validation failed. + * @return void + */ + public function testSaveFileToTmpDirWithWrongExtension(): void + { + $fileName = 'text.txt'; + $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $filePath = $tmpDirectory->getAbsolutePath($fileName); + $file = fopen($filePath, "wb"); + fwrite($file, 'just a text'); + + $_FILES['image'] = [ + 'name' => $fileName, + 'type' => 'text/plain', + 'tmp_name' => $filePath, + 'error' => 0, + 'size' => 12500, + ]; + + $this->imageUploader->saveFileToTmpDir('image'); + $filePath = $this->imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; + $this->assertFalse(is_file($this->mediaDirectory->getAbsolutePath($filePath))); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage File validation failed. + * @return void + */ + public function testSaveFileToTmpDirWithWrongFile(): void + { + $fileName = 'file.gif'; + $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $filePath = $tmpDirectory->getAbsolutePath($fileName); + $file = fopen($filePath, "wb"); + fwrite($file, 'just a text'); + + $_FILES['image'] = [ + 'name' => $fileName, + 'type' => 'image/gif', + 'tmp_name' => $filePath, + 'error' => 0, + 'size' => 12500, + ]; + + $this->imageUploader->saveFileToTmpDir('image'); + $filePath = $this->imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; + $this->assertFalse(is_file($this->mediaDirectory->getAbsolutePath($filePath))); + } + + /** + * @inheritdoc + */ + public static function tearDownAfterClass() + { + parent::tearDownAfterClass(); + $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\Filesystem::class + ); + /** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */ + $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory->delete('tmp'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php index f348372f2029a..89b91ab57e51a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php @@ -338,7 +338,11 @@ private function getProductInstance(?int $storeId = null): ProductInterface { /** @var ProductInterface $product */ $product = $this->productFactory->create(); - $product->setId($this->getProduct()->getId()); + $product->setData( + $this->productLinkField, + $this->getProduct()->getData($this->productLinkField) + ); + if ($storeId) { $product->setStoreId($storeId); } diff --git a/dev/tests/integration/testsuite/Magento/Csp/Model/Policy/Renderer/SimplePolicyHeaderRendererTest.php b/dev/tests/integration/testsuite/Magento/Csp/Model/Policy/Renderer/SimplePolicyHeaderRendererTest.php index 12ed71b708b88..93e7833038a42 100644 --- a/dev/tests/integration/testsuite/Magento/Csp/Model/Policy/Renderer/SimplePolicyHeaderRendererTest.php +++ b/dev/tests/integration/testsuite/Magento/Csp/Model/Policy/Renderer/SimplePolicyHeaderRendererTest.php @@ -58,8 +58,6 @@ public function testRenderRestrictMode(): void foreach ($header as $item) { $contentSecurityPolicyContent[] = $item->getFieldValue(); } - } else { - $contentSecurityPolicyContent = [$header->getFieldValue()]; } $this->assertEquals(['default-src https://magento.com \'self\';'], $contentSecurityPolicyContent); } @@ -86,8 +84,6 @@ public function testRenderRestrictWithReportingMode(): void foreach ($header as $item) { $contentSecurityPolicyContent[] = $item->getFieldValue(); } - } else { - $contentSecurityPolicyContent = [$header->getFieldValue()]; } $this->assertEquals( ['default-src https://magento.com \'self\'; report-uri /csp-reports/; report-to report-endpoint;'], diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt index 6a7c814f50524..f54defbd57604 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt @@ -14,5 +14,3 @@ dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressRepositoryTest.ph dev/tests/api-functional/testsuite/Magento/Framework/Model/Entity/HydratorTest.php dev/tests/api-functional/testsuite/Magento/Integration/Model/AdminTokenServiceTest.php dev/tests/api-functional/testsuite/Magento/Integration/Model/CustomerTokenServiceTest.php -lib/internal/Magento/Framework/Storage/AdapterFactory/AwsS3Factory.php -lib/internal/Magento/Framework/Storage/AdapterFactory/AzureFactory.php diff --git a/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php b/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php index 2adff8162e5a3..dc3e63fcc7df8 100644 --- a/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php +++ b/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php @@ -19,11 +19,6 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr */ protected $isRedirect = false; - /** - * @var bool - */ - private $headersSent; - /** * @inheritdoc */ @@ -33,10 +28,6 @@ public function getHeader($name) $headers = $this->getHeaders(); if ($headers->has($name)) { $header = $headers->get($name); - // zend-http >= 2.10.11 can return \ArrayIterator instead of a single Header - if ($header instanceof \ArrayIterator) { - $header = $header->current(); - } } return $header; } diff --git a/lib/internal/Magento/Framework/Storage/AdapterFactory/AdapterFactoryInterface.php b/lib/internal/Magento/Framework/Storage/AdapterFactory/AdapterFactoryInterface.php deleted file mode 100644 index 56794bbd29fcf..0000000000000 --- a/lib/internal/Magento/Framework/Storage/AdapterFactory/AdapterFactoryInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - default/location - - - -``` - -`default/location` is a default path in local filesystem, relative to Magento root. - -Now, in a PHP class that uses the declared storage, use the same `\Magento\Framework\Storage\StorageProvider` to get it: - -```php -/** - * @var \Magento\Framework\Storage\StorageProvider - */ -private $storageProvider; - -public function doSomething() -{ - $storage = $this->storageProvider->get('storage-name') - $storage->put('path.txt', $content); -} -``` - -## Configuring Storage - -A storage can be configured in `env.php`: - -```php -'storage' => [ - 'storage-name' => [ - 'adapter' => 'aws_s3', - 'options' => [ - 'client' => [ - 'credentials' => [ - 'key' => '', - 'secret' => '' - ], - 'region' => '', - 'version' => 'latest', - ], - 'bucket' => '', - ], - ], - 'media' => [ - // this is default configuration, so it doesn't need to be configured explicitly like so - 'adapter' => 'local', - 'options' => [ - 'root' => 'pub/media' - ] - ] -] -``` - -Different providers have different `options` available for configuration. -Under the hood, Magento Storage relies on [Flysystem](https://github.com/thephpleague/flysystem) library, so`options` might reflect options required by a corresponding storage adapter implemented for Flysystem. - -## Storage Providers - -By default, Magento Storage provides support for the following storage providers: - -* Local filesystem (based on `\League\Flysystem\Adapter\Local`) - * Adapter name: `local` - * Options: - ```php - [ - 'root' => 'path/relative/to/magento/root' - ] - ``` -* AWS S3 V3 (based on `\League\Flysystem\AwsS3v3\AwsS3Adapter`) - * Adapter name: `aws_s3` - * Options: - ```php - [ - 'client' => [ - 'credentials' => [ - 'key' => '', - 'secret' => '' - ], - 'region' => '', - 'version' => 'latest', - ], - 'bucket' => '', - 'prefix' => '', - ] - ``` -* Azure Blob storage (based on `\League\Flysystem\AzureBlobStorage\AzureBlobStorageAdapter`) - * Adapter name: `ms_azure` - * Options: - ```php - [ - 'connection_string' => '', - 'container_name' => '', - 'prefix' => '', - ] - ``` - -Additional adapters can be added by: -1. Creating an adapter factory implementing `\Magento\Framework\Storage\AdapterFactory\AdapterFactoryInterface` -2. Registering the factory in `Magento\Framework\Storage\StorageProvider` via `di.xml`: - ```xml - - - - My\Storage\AdapterFactory - - - - ``` - -The factory is registered as a "string" (name of the class). -That's because in most cases only a few adapters will be really created for a single application, and we don't want to create unnecessary factory instances. diff --git a/lib/internal/Magento/Framework/Storage/RootViolationException.php b/lib/internal/Magento/Framework/Storage/RootViolationException.php deleted file mode 100644 index 3ea41bfb57073..0000000000000 --- a/lib/internal/Magento/Framework/Storage/RootViolationException.php +++ /dev/null @@ -1,17 +0,0 @@ -filesystem = $filesystem; - } - - /** - * @inheritDoc - */ - public function put($path, $contents, array $config = []): bool - { - return $this->filesystem->put($path, $contents, $config); - } - - /** - * @inheritDoc - */ - public function deleteDir($dirname): bool - { - try { - $result = $this->filesystem->deleteDir($dirname); - } catch (\League\Flysystem\RootViolationException $exception) { - throw new \Magento\Framework\Storage\RootViolationException($exception->getMessage()); - } - return $result; - } - - /** - * @inheritDoc - */ - public function getMetadata($path): ?array - { - try { - $metadata = $this->filesystem->getMetadata($path); - } catch (\League\Flysystem\FileNotFoundException $exception) { - throw new \Magento\Framework\Storage\FileNotFoundException( - $exception->getMessage() - ); - } - if ($metadata === false) { - $metadata = null; - } - return $metadata; - } - - /** - * @inheritDoc - */ - public function has($path): bool - { - return $this->filesystem->has($path); - } -} diff --git a/lib/internal/Magento/Framework/Storage/StorageAdapterProvider.php b/lib/internal/Magento/Framework/Storage/StorageAdapterProvider.php deleted file mode 100644 index bcd5fe806c0c3..0000000000000 --- a/lib/internal/Magento/Framework/Storage/StorageAdapterProvider.php +++ /dev/null @@ -1,63 +0,0 @@ -objectManager = $objectManager; - $this->config = $config; - } - - /** - * Create storage adapter based on its name with provided options - * - * @param string $adapterName - * @param array $options - * @return AdapterInterface|null - */ - public function create(string $adapterName, array $options) :? AdapterInterface - { - if (!isset($this->config[$adapterName])) { - throw new InvalidStorageConfigurationException( - "Configured adapter '$adapterName' is not supported" - ); - } - $adapterFactoryClass = $this->config[$adapterName]; - $adapterFactory = $this->objectManager->get($adapterFactoryClass); - if (!$adapterFactory instanceof AdapterFactoryInterface) { - throw new InvalidStorageConfigurationException( - "Configured storage adapter factory '$adapterFactory' must implement " . - "'\Magento\Framework\Storage\AdapterFactory\AdapterFactoryInterface'" - ); - } - return $adapterFactory->create($options); - } -} diff --git a/lib/internal/Magento/Framework/Storage/StorageInterface.php b/lib/internal/Magento/Framework/Storage/StorageInterface.php deleted file mode 100644 index 4cf965b2287cd..0000000000000 --- a/lib/internal/Magento/Framework/Storage/StorageInterface.php +++ /dev/null @@ -1,57 +0,0 @@ -get(''), - * where $storageProvider is an instance of \Magento\Framework\Storage\StorageProvider - */ -interface StorageInterface -{ - /** - * Create a file or update if exists. - * - * @param string $path The path to the file. - * @param string $contents The file contents. - * @param array $config An optional configuration array. - * - * @return bool True on success, false on failure. - */ - public function put($path, $contents, array $config = []): bool; - - /** - * Delete a directory. - * - * @param string $dirname - * - * @throws RootViolationException Thrown if $dirname is empty. - * - * @return bool True on success, false on failure. - */ - public function deleteDir($dirname): bool; - - /** - * Get a file's metadata. - * - * @param string $path The path to the file. - * - * @throws FileNotFoundException - * - * @return array|false The file metadata or false on failure. - */ - public function getMetadata($path): ?array; - - /** - * Check whether a file exists. - * - * @param string $path - * - * @return bool - */ - public function has($path): bool; -} diff --git a/lib/internal/Magento/Framework/Storage/StorageProvider.php b/lib/internal/Magento/Framework/Storage/StorageProvider.php deleted file mode 100644 index bad0813f33002..0000000000000 --- a/lib/internal/Magento/Framework/Storage/StorageProvider.php +++ /dev/null @@ -1,102 +0,0 @@ - $localPath) { - $this->storageConfig[$storageName] = [ - 'adapter' => LocalFactory::ADAPTER_NAME, - 'options' => [ - 'root' => BP . '/' . $localPath, - ], - ]; - $envStorageConfig = $envConfig->get('storage/' . $storageName); - if ($envStorageConfig) { - $this->storageConfig[$storageName] = array_replace( - $this->storageConfig[$storageName], - $envStorageConfig - ); - } - } - $this->filesystemFactory = $filesystemFactory; - $this->storageFactory = $storageFactory; - $this->adapterProvider = $adapterProvider; - } - - /** - * Get storage by its name - * - * @param string $storageName - * @return StorageInterface - */ - public function get(string $storageName): StorageInterface - { - if (!isset($this->storage[$storageName])) { - if (isset($this->storageConfig[$storageName])) { - $config = $this->storageConfig[$storageName]; - if (empty($config['adapter']) || empty($config['options'])) { - throw new InvalidStorageConfigurationException( - "Incorrect configuration for storage '$storageName': required field " . - "'adapter' and/or 'options' is not defined" - ); - } - $adapter = $this->adapterProvider->create($config['adapter'], $config['options']); - $filesystem = $this->filesystemFactory->create(['adapter' => $adapter]); - $this->storage[$storageName] = $this->storageFactory->create(['filesystem' => $filesystem]); - } else { - throw new UnsupportedStorageException("No storage with name '$storageName' is declared"); - } - } - return $this->storage[$storageName]; - } -} diff --git a/lib/internal/Magento/Framework/Storage/UnsupportedStorageException.php b/lib/internal/Magento/Framework/Storage/UnsupportedStorageException.php deleted file mode 100644 index 8267fea85319e..0000000000000 --- a/lib/internal/Magento/Framework/Storage/UnsupportedStorageException.php +++ /dev/null @@ -1,13 +0,0 @@ -componentRegistrar = $this->createMock(\Magento\Framework\Component\ComponentRegistrar::class); + } + + /** + * @param array $context + * @param string $path + * @param array $pathValues + * @dataProvider dataProviderContextByPath + */ + public function testGetContextByPath($context, $path, $pathValues) + { + $this->componentRegistrar->expects($this->any()) + ->method('getPaths') + ->willReturnMap($pathValues); + $this->context = new Context($this->componentRegistrar); + $this->assertEquals($context, $this->context->getContextByPath($path)); + } + + /** + * @return array + */ + public function dataProviderContextByPath() + { + return [ + [ + [Context::CONTEXT_TYPE_MODULE, 'Magento_Module'], + '/app/code/Magento/Module/Block/Test.php', + [ + [Context::CONTEXT_TYPE_MODULE, ['Magento_Module' => '/app/code/Magento/Module']], + [Context::CONTEXT_TYPE_THEME, []], + ] + ], + [ + [Context::CONTEXT_TYPE_THEME, 'frontend/Some/theme'], + '/app/design/area/theme/test.phtml', + [ + [Context::CONTEXT_TYPE_MODULE, []], + [Context::CONTEXT_TYPE_THEME, ['frontend/Some/theme' => '/app/design/area/theme']], + ] + ], + [ + [Context::CONTEXT_TYPE_LIB, 'lib/web/module/test.phtml'], + '/lib/web/module/test.phtml', + [ + [Context::CONTEXT_TYPE_MODULE, []], + [Context::CONTEXT_TYPE_THEME, []], + ] + ], + ]; + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid path given: "invalid_path". + */ + public function testGetContextByPathWithInvalidPath() + { + $this->componentRegistrar->expects($this->any()) + ->method('getPaths') + ->willReturnMap([ + [ComponentRegistrar::MODULE, ['/path/to/module']], + [ComponentRegistrar::THEME, ['/path/to/theme']] + ]); + $this->context = new Context($this->componentRegistrar); + $this->context->getContextByPath('invalid_path'); + } + + /** + * @param string $path + * @param array $context + * @param array $registrar + * @dataProvider dataProviderPathToLocaleDirectoryByContext + */ + public function testBuildPathToLocaleDirectoryByContext($path, $context, $registrar) + { + $paths = []; + foreach ($registrar as $module) { + $paths[$module[1]] = $module[2]; + } + $this->componentRegistrar->expects($this->any()) + ->method('getPath') + ->willReturnMap($registrar); + $this->context = new Context($this->componentRegistrar); + $this->assertEquals($path, $this->context->buildPathToLocaleDirectoryByContext($context[0], $context[1])); + } + + /** + * @return array + */ + public function dataProviderPathToLocaleDirectoryByContext() + { + return [ + [ + BP . '/app/code/Magento/Module/i18n/', + [Context::CONTEXT_TYPE_MODULE, 'Magento_Module'], + [[ComponentRegistrar::MODULE, 'Magento_Module', BP . '/app/code/Magento/Module']] + ], + [ + BP . '/app/design/frontend/Magento/luma/i18n/', + [Context::CONTEXT_TYPE_THEME, 'frontend/Magento/luma'], + [[ComponentRegistrar::THEME, 'frontend/Magento/luma', BP . '/app/design/frontend/Magento/luma']] + ], + + [ + null, + [Context::CONTEXT_TYPE_MODULE, 'Unregistered_Module'], + [[ComponentRegistrar::MODULE, 'Unregistered_Module', null]] + ], + [ + null, + [Context::CONTEXT_TYPE_THEME, 'frontend/Magento/unregistered'], + [[ComponentRegistrar::THEME, 'frontend/Magento/unregistered', null]] + ], + [BP . '/lib/web/i18n/', [Context::CONTEXT_TYPE_LIB, 'lib/web/module/test.phtml'], []], + ]; + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid context given: "invalid_type". + */ + public function testBuildPathToLocaleDirectoryByContextWithInvalidType() + { + $this->componentRegistrar->expects($this->never()) + ->method('getPath'); + $this->context = new Context($this->componentRegistrar); + $this->context->buildPathToLocaleDirectoryByContext('invalid_type', 'Magento_Module'); + } +}