├── .gitignore ├── registration.php ├── Adapter ├── ManagerInterface.php ├── FilesystemAdapterFactory.php ├── FilesystemManager.php └── AdapterInterface.php ├── Model ├── Pool │ ├── ModifierInterface.php │ ├── FileModifierPoolInterface.php │ ├── ModifierFactory.php │ ├── Modifier │ │ ├── CategoryImage.php │ │ ├── ProductImage.php │ │ └── CmsWysiwygImage.php │ └── FileModifierPool.php ├── Config │ └── Source │ │ └── Adapter.php └── Filesystem │ └── UploadManager.php ├── view ├── adminhtml │ ├── templates │ │ ├── browser │ │ │ ├── content │ │ │ │ ├── preview.phtml │ │ │ │ ├── files.phtml │ │ │ │ └── uploader.phtml │ │ │ ├── tree.phtml │ │ │ └── content.phtml │ │ ├── cms │ │ │ └── modal.phtml │ │ ├── filemanager │ │ │ └── content.phtml │ │ └── product │ │ │ └── form │ │ │ └── modal.phtml │ ├── layout │ │ ├── flagbit_flysystem_filesystem_contents.xml │ │ ├── cms_wysiwyg_images_index.xml │ │ ├── flagbit_flysystem_filemanager_index.xml │ │ └── flagbit_flysystem_filesystem_index.xml │ ├── web │ │ ├── js │ │ │ ├── category │ │ │ │ └── mediabrowser.js │ │ │ └── cms │ │ │ │ └── mediabrowserExtension.js │ │ └── css │ │ │ └── source │ │ │ └── _module.less │ └── ui_component │ │ └── category_form.xml └── base │ └── web │ ├── template │ └── form │ │ └── element │ │ └── mediabrowser.html │ └── js │ └── flysystemUtility.js ├── etc ├── adminhtml │ ├── routes.xml │ ├── events.xml │ ├── menu.xml │ └── di.xml ├── di.xml ├── module.xml ├── config.xml └── acl.xml ├── Test └── Unit │ ├── Model │ ├── Pool │ │ ├── TestModifiers │ │ │ ├── TestFileModifier001.php │ │ │ ├── TestFileModifier002.php │ │ │ ├── TestFileModifier003.php │ │ │ └── TestFileModifier004.php │ │ ├── ModifierFactoryTest.php │ │ ├── Modifier │ │ │ ├── ProductImageTest.php │ │ │ ├── CategoryImageTest.php │ │ │ └── CmsWysiwygImageTest.php │ │ └── FileModifierPoolTest.php │ └── Config │ │ └── Source │ │ └── AdapterTest.php │ ├── Block │ └── Adminhtml │ │ ├── Product │ │ └── ModalTest.php │ │ └── Filesystem │ │ ├── Content │ │ └── UploaderTest.php │ │ └── ContentTest.php │ ├── Helper │ └── ErrorsTest.php │ ├── Observer │ └── InsertModalToProductFormTest.php │ ├── Adapter │ ├── FilesystemAdapterFactoryTest.php │ └── FilesystemManagerTest.php │ └── Controller │ ├── DeleteFolderTest.php │ ├── UploadTest.php │ ├── NewFolderTest.php │ ├── TreeJsonTest.php │ ├── IndexTest.php │ ├── DeleteFilesTest.php │ ├── ContentsTest.php │ └── Filemanager │ └── IndexTest.php ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── Block └── Adminhtml │ ├── Product │ └── Modal.php │ └── Filesystem │ ├── Content │ ├── Uploader.php │ └── Files.php │ └── Tree.php ├── LICENSE ├── Observer └── InsertModalToProductForm.php ├── Controller └── Adminhtml │ ├── Filesystem │ ├── AbstractController.php │ ├── DeleteFolder.php │ ├── NewFolder.php │ ├── Upload.php │ ├── TreeJson.php │ ├── Index.php │ ├── DeleteFiles.php │ ├── Contents.php │ ├── Preview.php │ └── OnInsert.php │ └── Filemanager │ └── Index.php ├── composer.json ├── Helper ├── Errors.php └── Filesystem.php └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor 3 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 6 |
7 |
8 | 9 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Model/Pool/FileModifierPoolInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /view/adminhtml/layout/flagbit_flysystem_filesystem_contents.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /view/adminhtml/layout/cms_wysiwyg_images_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Test/Unit/Model/Pool/TestModifiers/TestFileModifier001.php: -------------------------------------------------------------------------------- 1 | getUrl('flagbit_flysystem/filesystem/index', 3 | [ 4 | 'target_element_id' => $this->getRequest()->getParam("target_element_id"), 5 | 'type' => 'file', 6 | 'identifier' => 'flagbit_cms_modal' 7 | ]); 8 | ?> 9 | -------------------------------------------------------------------------------- /etc/adminhtml/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /view/adminhtml/templates/browser/tree.phtml: -------------------------------------------------------------------------------- 1 | 6 |
7 |
8 | 13 |
14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /view/adminhtml/web/js/category/mediabrowser.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'Magento_Ui/js/form/element/abstract', 3 | 'uiRegistry' 4 | ], function (Element, reg) { 5 | 'use strict'; 6 | 7 | return Element.extend({ 8 | defaults: { 9 | listens: { 10 | value: 'changeValue' 11 | } 12 | }, 13 | 14 | flysystemvalue: '', 15 | 16 | changeValue: function(value) { 17 | if(value && value!=this.flysystemvalue) { 18 | this.flysystemvalue = value; 19 | 20 | var uploader = reg.get('category_form.category_form.content.image'); 21 | uploader.addFile(JSON.parse(value)); 22 | } 23 | } 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /view/adminhtml/layout/flagbit_flysystem_filemanager_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 35 | -------------------------------------------------------------------------------- /view/adminhtml/templates/product/form/modal.phtml: -------------------------------------------------------------------------------- 1 | getUrl('flagbit_flysystem/filesystem/index', 3 | [ 4 | 'target_element_id' => 'flysystem_image_path', 5 | 'type' => 'file', 6 | 'identifier' => 'product_gallery' 7 | ]); 8 | ?> 9 | 10 |
11 | 16 | 23 |
24 | -------------------------------------------------------------------------------- /Block/Adminhtml/Filesystem/Content/Uploader.php: -------------------------------------------------------------------------------- 1 | _getMediaType(); 32 | 33 | $this->getConfig()->setUrl( 34 | $this->_urlBuilder->getUrl('flagbit_flysystem/*/upload', ['type' => $type]) 35 | )->setFileField( 36 | \Flagbit\Flysystem\Helper\Config::FLYSYSTEM_UPLOAD_ID 37 | ); 38 | } 39 | 40 | /** 41 | * @return string|null 42 | */ 43 | protected function _getMediaType() 44 | { 45 | if ($this->hasData('media_type')) { 46 | return $this->_getData('media_type'); 47 | } 48 | return $this->getRequest()->getParam('type'); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /view/adminhtml/web/css/source/_module.less: -------------------------------------------------------------------------------- 1 | .folder-deletion-warning { 2 | color: #ff0000; 3 | } 4 | 5 | .flysystem-browser { 6 | .main-col { 7 | .breadcrumbs { 8 | list-style: none; 9 | padding-left: 0; 10 | 11 | li { 12 | display: inline-block; 13 | margin: 0 0.5rem 0.5rem 0; 14 | 15 | &:after { 16 | content: ''; 17 | margin: 0 0.5rem 0 0; 18 | } 19 | } 20 | } 21 | 22 | .file-row, 23 | .file-head { 24 | width: 100%; 25 | margin: 0; 26 | border: none; 27 | border-bottom: 1px solid #d4d4d4; 28 | 29 | &.selected { 30 | background-color: #ddf0ff; 31 | } 32 | 33 | .file-col { 34 | display: inline-block; 35 | padding: 3px 10px; 36 | border-left: 1px solid #eeeeee; 37 | 38 | &:first-child { 39 | border-left: none; 40 | } 41 | 42 | &.data-name { 43 | width: 350px; 44 | } 45 | 46 | &.data-size { 47 | width: 150px; 48 | } 49 | } 50 | } 51 | 52 | .file-head { 53 | background-color: #514943; 54 | color: #ffffff; 55 | font-weight: 600; 56 | 57 | .file-col { 58 | padding: 10px 10px; 59 | } 60 | } 61 | } 62 | } 63 | 64 | .flysystem-image-preview { 65 | display: none; 66 | position: absolute; 67 | top: 0; 68 | left: 0; 69 | width: 100%; 70 | background-color: #fff; 71 | padding: 20px; 72 | border: 1px solid #000; 73 | 74 | .preview-header { 75 | height: 30px; 76 | } 77 | 78 | .preview-wrapper { 79 | overflow: auto; 80 | } 81 | } -------------------------------------------------------------------------------- /view/adminhtml/ui_component/category_form.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 | 7 | text 8 | Category Image from Flysystem 9 | Select Image 10 | input 11 | Flagbit_Flysystem/form/element/mediabrowser 12 | flysystem_category_image 13 | 14 | flysystem_category_image 15 | file 16 | category_modal 17 | 18 | 45 19 | Flagbit_Flysystem/js/category/mediabrowser 20 | 21 | 22 | 23 |
24 |
-------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/AbstractController.php: -------------------------------------------------------------------------------- 1 | _flysystemManager = $flysystemManager; 37 | $this->_session = $session; 38 | parent::__construct($context); 39 | } 40 | 41 | /** 42 | * @return $this 43 | * @throws \Magento\Framework\Exception\LocalizedException 44 | */ 45 | protected function _initAction(): self 46 | { 47 | $this->getStorage(); 48 | return $this; 49 | } 50 | 51 | /** 52 | * @return Manager 53 | * @throws \Magento\Framework\Exception\LocalizedException 54 | */ 55 | public function getStorage(): Manager 56 | { 57 | $this->_flysystemManager->getAdapter(); 58 | return $this->_flysystemManager; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flagbit/magento2-flysystem", 3 | "description": "Flysystem integration for Magento2", 4 | "type": "magento2-module", 5 | "license": [ 6 | "GPL-3.0-or-later" 7 | ], 8 | "authors": [ 9 | { 10 | "name": "Robin Homberg", 11 | "email": "robin.homberg@flagbit.de", 12 | "role": "Developer" 13 | }, 14 | { 15 | "name": "Björn Meyer", 16 | "email": "bjoern.meyer@flagbit.de", 17 | "role": "DevOps" 18 | } 19 | ], 20 | "homepage": "https://github.com/flagbit/Magento2-Flysystem", 21 | "keywords": [ 22 | "magento", 23 | "magento2", 24 | "flysystem", 25 | "filesystem" 26 | ], 27 | "repositories": [ 28 | { 29 | "type": "composer", 30 | "url": "https://repo.magento.com/" 31 | } 32 | ], 33 | "require": { 34 | "php": ">=7.1.0", 35 | "league/flysystem": "^1.1.4", 36 | "league/flysystem-sftp": "^1.0", 37 | "magento/framework": ">=102.0.5", 38 | "magento/magento-composer-installer": "*", 39 | "magento/module-backend": ">=100.2.0" 40 | }, 41 | "require-dev": { 42 | "phpunit/phpunit": "^7.5", 43 | "roave/security-advisories": "dev-master" 44 | }, 45 | "suggest": { 46 | "flagbit/magento2-flysystem-s3": "S3 Adapter for Magento2 Flysystem integration" 47 | }, 48 | "autoload": { 49 | "files": [ 50 | "registration.php" 51 | ], 52 | "psr-4": { 53 | "Flagbit\\Flysystem\\": "" 54 | } 55 | }, 56 | "config": { 57 | "sort-packages": true 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Adapter/FilesystemAdapterFactory.php: -------------------------------------------------------------------------------- 1 | objectManager = $objectManager; 34 | $this->filesystemFactory = $filesystemFactory; 35 | } 36 | 37 | /** 38 | * @param FlysystemAdapter $adapter 39 | * @param \League\Flysystem\Config|array|null $config 40 | * @return FilesystemAdapter 41 | */ 42 | public function create(FlysystemAdapter $adapter, $config = null): FilesystemAdapter 43 | { 44 | $fileSystemObject = $this->filesystemFactory->create( 45 | [ 46 | 'adapter' => $adapter, 47 | 'config' => $config 48 | ] 49 | ); 50 | 51 | return $this->objectManager->create( 52 | FilesystemAdapter::class, 53 | [ 54 | 'filesystem' => $fileSystemObject 55 | ] 56 | ); 57 | } 58 | } -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/DeleteFolder.php: -------------------------------------------------------------------------------- 1 | _resultJson = $resultJsonFactory; 36 | parent::__construct($context, $flysystemManager, $session); 37 | } 38 | 39 | /** 40 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface 41 | */ 42 | public function execute() 43 | { 44 | try { 45 | $manager = $this->getStorage(); 46 | $path = $manager->getSession()->getCurrentPath(); 47 | $result = $manager->getAdapter()->deleteDir($path); 48 | } catch(\Exception $e) { 49 | $result = ['error' => true, 'message' => $e->getMessage()]; 50 | } 51 | 52 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 53 | $resultJson = $this->_resultJson->create(); 54 | return $resultJson->setData($result); 55 | } 56 | } -------------------------------------------------------------------------------- /view/base/web/js/flysystemUtility.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery' 3 | ], function($) { 4 | 5 | return function (data) { 6 | window.flysystemUtility = { 7 | init: function() { 8 | $('#preview-file-btn').on('click', function() { 9 | window.flysystemUtility.openPreview(data.previewUrl); 10 | }); 11 | 12 | $('#preview-close-btn').on('click', function() { 13 | window.flysystemUtility.closePreview(); 14 | }); 15 | 16 | if($('#open-wysiwyg-btn')) { 17 | $('#open-wysiwyg-btn').on('click', function() { 18 | MediabrowserUtility.openDialog(data.wysiwygUrl); 19 | }); 20 | } 21 | }, 22 | 23 | openPreview: function(url) { 24 | var modal = $('#modal_dialog_message').children().first(); 25 | var fileId = $(modal).find('[data-row=file].selected').attr('id'); 26 | 27 | return $.ajax({ 28 | url: url, 29 | data: { 30 | filename: fileId, 31 | form_key: FORM_KEY 32 | } 33 | }).done($.proxy(function(data) { 34 | console.log(data.error); 35 | if(!data.error) { 36 | var previewHtml = $('#flysystem-image-preview'); 37 | previewHtml.find('img').first().attr('src', data.url); 38 | previewHtml.show(); 39 | } 40 | }, this) 41 | ); 42 | }, 43 | 44 | closePreview: function() { 45 | var previewHtml = $('#flysystem-image-preview'); 46 | previewHtml.hide(); 47 | } 48 | }; 49 | 50 | window.flysystemUtility.init(); 51 | }; 52 | 53 | }); -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/NewFolder.php: -------------------------------------------------------------------------------- 1 | _resultJson = $resultJsonFactory; 36 | parent::__construct($context, $flysystemManager, $session); 37 | } 38 | 39 | /** 40 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface 41 | */ 42 | public function execute() 43 | { 44 | try { 45 | $manager = $this->getStorage(); 46 | /** @var \Magento\Framework\App\Request\Http\Proxy $request */ 47 | $request = $this->getRequest(); 48 | 49 | /** @phan-suppress-next-line PhanUndeclaredMethod */ 50 | $name = $request->getPost('name'); 51 | $path = rtrim($manager->getSession()->getCurrentPath(), '/'); 52 | $result = $manager->getAdapter()->createDir($path.'/'.$name); 53 | } catch(\Exception $e) { 54 | $result = ['error' => true, 'message' => $e->getMessage()]; 55 | } 56 | 57 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 58 | $resultJson = $this->_resultJson->create(); 59 | return $resultJson->setData($result); 60 | } 61 | } -------------------------------------------------------------------------------- /Helper/Errors.php: -------------------------------------------------------------------------------- 1 | _resultJson = $resultJsonFactory; 44 | $this->_uploadManager = $uploadManager; 45 | parent::__construct($context, $flysystemManager, $session); 46 | } 47 | 48 | /** 49 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface 50 | */ 51 | public function execute() 52 | { 53 | try { 54 | $manager = $this->getStorage(); 55 | $targetPath = $manager->getSession()->getCurrentPath(); 56 | $this->_uploadManager->upload($manager->getAdapter(), $targetPath); 57 | $result = ['error' => false]; 58 | } catch (\Exception $e) { 59 | $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; 60 | } 61 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 62 | $resultJson = $this->_resultJson->create(); 63 | return $resultJson->setData($result); 64 | } 65 | } -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/TreeJson.php: -------------------------------------------------------------------------------- 1 | _layoutFactory = $layoutFactory; 43 | $this->_resultJsonFactory = $resultJsonFactory; 44 | parent::__construct($context, $flysystemManager, $session); 45 | } 46 | 47 | /** 48 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface 49 | */ 50 | public function execute() 51 | { 52 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 53 | $resultJson = $this->_resultJsonFactory->create(); 54 | try { 55 | $this->_initAction(); 56 | /** @var \Magento\Framework\View\Layout $layout */ 57 | $layout = $this->_layoutFactory->create(); 58 | 59 | /** @var Tree $layoutBlock */ 60 | $layoutBlock = $layout->createBlock(Tree::class); 61 | 62 | /** @phan-suppress-next-line PhanUndeclaredMethod */ 63 | $resultJson->setJsonData($layoutBlock->getTreeJson()); 64 | } catch (\Exception $e) { 65 | $result = ['error' => true, 'message' => $e->getMessage()]; 66 | $resultJson->setData($result); 67 | } 68 | return $resultJson; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/Index.php: -------------------------------------------------------------------------------- 1 | _resultLayoutFactory = $resultLayoutFactory; 42 | $this->_resultJsonFactory = $resultJsonFactory; 43 | parent::__construct($context, $flysystemManager, $session); 44 | } 45 | 46 | /** 47 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Layout 48 | */ 49 | public function execute() 50 | { 51 | try { 52 | $this->_initAction(); 53 | 54 | $identifier = $this->getRequest()->getParam('identifier'); 55 | $this->getStorage()->setModalIdentifier($identifier); 56 | 57 | /** @var \Magento\Framework\View\Result\Layout $resultLayout */ 58 | $resultLayout = $this->_resultLayoutFactory->create(); 59 | $resultLayout->addHandle('overlay_popup'); 60 | return $resultLayout; 61 | } catch (\Exception $e) { 62 | $result = ['error' => true, 'message' => $e->getMessage()]; 63 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 64 | $resultJson = $this->_resultJsonFactory->create(); 65 | $resultJson->setData($result); 66 | return $resultJson; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Filemanager/Index.php: -------------------------------------------------------------------------------- 1 | _resultPageFactory = $resultPageFactory; 37 | } 38 | 39 | /** 40 | * @return Page|\Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page 41 | */ 42 | public function execute() 43 | { 44 | try { 45 | $this->_initAction(); 46 | $this->getStorage()->setModalIdentifier('filemanager'); 47 | $page = $this->_resultPageFactory->create()->addDefaultHandle(); 48 | $page = $this->_initPage($page); 49 | return $page; 50 | } catch (\Exception $e) { 51 | $page = $this->_resultPageFactory->create()->addDefaultHandle(); 52 | $page = $this->_initPage($page); 53 | return $page; 54 | } 55 | } 56 | 57 | /** 58 | * @param Page|\Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page $resultPage 59 | * @return Page|\Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page 60 | */ 61 | protected function _initPage($resultPage) 62 | { 63 | $resultPage->setActiveMenu('Flagbit_Flysystem::flysystem_page') 64 | ->addBreadcrumb(__('Flagbit Flysystem'), __('Flagbit Flysystem')); 65 | $resultPage->getConfig()->getTitle()->prepend(__('Flagbit Flysystem')); 66 | return $resultPage; 67 | } 68 | } -------------------------------------------------------------------------------- /Model/Pool/Modifier/CategoryImage.php: -------------------------------------------------------------------------------- 1 | _tmpManager = $tmpManager; 49 | $this->_manager = $manager; 50 | $this->_logger = $logger; 51 | } 52 | 53 | /** 54 | * @param array $data 55 | * @return string|null 56 | * @throws LocalizedException 57 | * @throws \League\Flysystem\FileNotFoundException 58 | * @throws \Magento\Framework\Exception\NoSuchEntityException 59 | */ 60 | public function modifyFile(array $data) 61 | { 62 | $this->filename = null; 63 | if(!isset($data['filename']) || empty($data['filename'])) { 64 | throw new LocalizedException(Errors::getErrorMessage(631)); 65 | } 66 | 67 | $this->filename = $data['filename']; 68 | 69 | $file = $this->createFileArray(); 70 | 71 | $result = $this->_tmpManager->createCategoryTmp($file); 72 | return json_encode($result); 73 | } 74 | 75 | /** 76 | * @return array 77 | * @throws LocalizedException 78 | * @throws \League\Flysystem\FileNotFoundException 79 | */ 80 | protected function createFileArray(): array { 81 | $file = [ 82 | 'name' => basename($this->filename), 83 | 'type' => $this->_manager->getAdapter()->getMimetype($this->filename), 84 | 'tmp_name' => $this->_tmpManager->getAbsoluteTmpPath($this->filename), 85 | 'error' => 0, 86 | 'size' => $this->_manager->getAdapter()->getSize($this->filename) 87 | ]; 88 | 89 | return $file; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/DeleteFiles.php: -------------------------------------------------------------------------------- 1 | _resultJson = $resultJsonFactory; 45 | $this->_flysystemHelper = $flysystemHelper; 46 | parent::__construct($context, $flysystemManager, $session); 47 | } 48 | 49 | /** 50 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface 51 | */ 52 | public function execute() 53 | { 54 | try { 55 | /** @var \Magento\Framework\App\Request\Http\Proxy $request */ 56 | $request = $this->getRequest(); 57 | 58 | /** @phan-suppress-next-line PhanUndeclaredMethod */ 59 | if (!$request->isPost()) { 60 | throw new \Exception(Errors::getErrorMessage(351)); 61 | } 62 | $files = $this->getRequest()->getParam('files'); 63 | $manager = $this->getStorage(); 64 | 65 | foreach($files as $file) { 66 | $file = $this->_flysystemHelper->idDecode($file); 67 | $manager->getAdapter()->delete($file); 68 | } 69 | $result = ['error' => false]; 70 | } catch(\Exception $e) { 71 | $result = ['error' => true, 'message' => $e->getMessage()]; 72 | } 73 | 74 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 75 | $resultJson = $this->_resultJson->create(); 76 | return $resultJson->setData($result); 77 | } 78 | } -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/Contents.php: -------------------------------------------------------------------------------- 1 | _resultLayoutFactory = $resultLayoutFactory; 43 | $this->_resultJsonFactory = $resultJsonFactory; 44 | parent::__construct($context, $flysystemManager, $session); 45 | } 46 | 47 | /** 48 | * @return Contents 49 | * @throws \Magento\Framework\Exception\LocalizedException 50 | */ 51 | protected function _saveSessionCurrentPath(): self 52 | { 53 | $this->getStorage()->getSession()->setCurrentPath( 54 | $this->_objectManager->get(Filesystem::class)->getCurrentPath() 55 | ); 56 | return $this; 57 | } 58 | 59 | /** 60 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Layout 61 | */ 62 | public function execute() 63 | { 64 | try { 65 | $this->_initAction()->_saveSessionCurrentPath(); 66 | /** @var \Magento\Framework\View\Result\Layout $resultLayout */ 67 | $resultLayout = $this->_resultLayoutFactory->create(); 68 | return $resultLayout; 69 | } catch (\Exception $e) { 70 | $result = ['error' => true, 'message' => $e->getMessage()]; 71 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */ 72 | $resultJson = $this->_resultJsonFactory->create(); 73 | $resultJson->setData($result); 74 | return $resultJson; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Model/Pool/Modifier/ProductImage.php: -------------------------------------------------------------------------------- 1 | _tmpManager = $tmpManager; 49 | $this->_manager = $manager; 50 | $this->_logger = $logger; 51 | } 52 | 53 | /** 54 | * @param array $data 55 | * @return string|null 56 | * @throws \League\Flysystem\FileNotFoundException 57 | * @throws \Magento\Framework\Exception\LocalizedException 58 | */ 59 | public function modifyFile(array $data) 60 | { 61 | $this->filename = null; 62 | if(!isset($data['filename']) || empty($data['filename'])) { 63 | throw new LocalizedException(Errors::getErrorMessage(631)); 64 | } 65 | 66 | $this->filename = $data['filename']; 67 | 68 | $file = $this->createFileArray($this->filename); 69 | 70 | $result = $this->_tmpManager->createProductTmp($file); 71 | 72 | return json_encode($result); 73 | } 74 | 75 | /** 76 | * @param string $filename 77 | * @return array 78 | * @throws \League\Flysystem\FileNotFoundException 79 | * @throws \Magento\Framework\Exception\LocalizedException 80 | */ 81 | protected function createFileArray(): array { 82 | $file = [ 83 | 'name' => basename($this->filename), 84 | 'type' => $this->_manager->getAdapter()->getMimetype($this->filename), 85 | 'tmp_name' => $this->_tmpManager->getAbsoluteTmpPath($this->filename), 86 | 'error' => 0, 87 | 'size' => $this->_manager->getAdapter()->getSize($this->filename) 88 | ]; 89 | 90 | return $file; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Test/Unit/Model/Pool/ModifierFactoryTest.php: -------------------------------------------------------------------------------- 1 | _objectManagerMock = $this->getMockBuilder(ObjectManager::class) 44 | ->disableOriginalConstructor() 45 | ->setMethods(['create']) 46 | ->getMock(); 47 | 48 | $this->_fileModifierMock = $this->getMockBuilder(TestFileModifier001::class) 49 | ->disableOriginalConstructor() 50 | ->getMock(); 51 | 52 | $this->_abstractHelperMock = $this->getMockBuilder(AbstractHelper::class) 53 | ->disableOriginalConstructor() 54 | ->getMock(); 55 | 56 | $this->_object = new ModifierFactory( 57 | $this->_objectManagerMock 58 | ); 59 | } 60 | 61 | public function testCreate(): void 62 | { 63 | $className = 'Flagbit\Flysystem\Model\Pool\Modifier\CmsWysiwygImage'; 64 | $data = ['modifiers' => []]; 65 | 66 | $this->_objectManagerMock->expects($this->once()) 67 | ->method('create') 68 | ->with($className, $data) 69 | ->willReturn($this->_fileModifierMock); 70 | 71 | $this->assertEquals($this->_fileModifierMock, $this->_object->create($className, $data)); 72 | } 73 | 74 | public function testCreateException(): void 75 | { 76 | $className = 'Magento\Framework\App\Helper\AbstractHelper'; 77 | $data = ['modifiers' => []]; 78 | 79 | $this->_objectManagerMock->expects($this->once()) 80 | ->method('create') 81 | ->with($className, $data) 82 | ->willReturn($this->_abstractHelperMock); 83 | 84 | $this->expectException(\InvalidArgumentException::class); 85 | $this->_object->create($className, $data); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Test/Unit/Observer/InsertModalToProductFormTest.php: -------------------------------------------------------------------------------- 1 | _loggerMock = $this->getMockBuilder(Monolog::class) 37 | ->disableOriginalConstructor() 38 | ->setMethods(['critical']) 39 | ->getMock(); 40 | 41 | $this->_blockMock = $this->getMockBuilder(Content::class) 42 | ->disableOriginalConstructor() 43 | ->setMethods(['setTemplate', 'addChild']) 44 | ->getMock(); 45 | 46 | $this->_observerMock = $this->getMockBuilder(Observer::class) 47 | ->disableOriginalConstructor() 48 | ->setMethods(['getBlock']) 49 | ->getMock(); 50 | 51 | $this->_object = new InsertModalToProductForm( 52 | $this->_loggerMock 53 | ); 54 | } 55 | 56 | public function testExecute(): void 57 | { 58 | $template = 'Flagbit_Flysystem::/product/form/gallery.phtml'; 59 | $block_id = 'flysystem-modal'; 60 | 61 | $this->_observerMock->expects($this->exactly(2)) 62 | ->method('getBlock') 63 | ->willReturn($this->_blockMock); 64 | 65 | $this->_blockMock->expects($this->once()) 66 | ->method('setTemplate') 67 | ->with($template); 68 | 69 | $this->_blockMock->expects($this->once()) 70 | ->method('addChild') 71 | ->with($block_id, Modal::class); 72 | 73 | $this->_object->execute($this->_observerMock); 74 | } 75 | 76 | public function testExecuteException(): void 77 | { 78 | $exception = new \Exception(); 79 | 80 | $this->_observerMock->expects($this->once()) 81 | ->method('getBlock') 82 | ->willThrowException($exception); 83 | 84 | $this->_loggerMock->expects($this->once()) 85 | ->method('critical') 86 | ->with($exception->getMessage()); 87 | 88 | $this->_object->execute($this->_observerMock); 89 | } 90 | } -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Local 8 | local 9 | 10 | 11 | FTP 12 | ftp 13 | 14 | 15 | SFTP 16 | sftp 17 | 18 | 19 | Null-Adapter 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Flagbit\Flysystem\Model\Pool\Modifier\CmsWysiwygImage 31 | flagbit_cms_modal 32 | 10 33 | 34 | 35 | Flagbit\Flysystem\Model\Pool\Modifier\CategoryImage 36 | category_modal 37 | 10 38 | 39 | 40 | Flagbit\Flysystem\Model\Pool\Modifier\ProductImage 41 | product_gallery 42 | 10 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Flagbit\Flysystem\Pool\OnInsertPool 51 | 52 | 53 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Filesystem/Preview.php: -------------------------------------------------------------------------------- 1 | _flysystemHelper = $flysystemHelper; 52 | $this->_tmpManager = $tmpManager; 53 | $this->_resultJsonFactory = $resultJsonFactory; 54 | $this->_logger = $logger; 55 | $this->_storeManager = $storeManager; 56 | parent::__construct($context, $flysystemManager, $session); 57 | } 58 | 59 | /** 60 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface 61 | */ 62 | public function execute() 63 | { 64 | try { 65 | $manager = $this->getStorage(); 66 | 67 | $filename = $this->getRequest()->getParam('filename'); 68 | $filename = $this->_flysystemHelper->idDecode($filename); 69 | 70 | $contents = $manager->getAdapter()->read($filename); 71 | 72 | $this->_tmpManager->writePreview($filename, $contents); 73 | 74 | $resultFile = $this->_tmpManager->getUserPreviewDir().'/'.basename($filename); 75 | 76 | /** @var \Magento\Store\Model\Store $store */ 77 | $store = $this->_storeManager->getStore(); 78 | 79 | /** @phan-suppress-next-line PhanUndeclaredMethod */ 80 | $url = $store->getBaseUrl(UrlInterface::URL_TYPE_MEDIA).'/'.$resultFile; 81 | 82 | $result = ['error' => false, 'url' => $url]; 83 | } catch (\Exception $e) { 84 | $result = ['error' => true, 'message' => $e->getMessage()]; 85 | $this->_logger->critical($e->getMessage()); 86 | } 87 | 88 | $resultJson = $this->_resultJsonFactory->create(); 89 | return $resultJson->setData($result); 90 | } 91 | } -------------------------------------------------------------------------------- /Model/Pool/Modifier/CmsWysiwygImage.php: -------------------------------------------------------------------------------- 1 | manager = $manager; 62 | $this->tmpManager = $tmpManager; 63 | $this->flysystemHelper = $flysystemHelper; 64 | $this->logger = $logger; 65 | } 66 | 67 | /** 68 | * @param array $data 69 | * @return string|null 70 | * @throws LocalizedException 71 | * @throws \League\Flysystem\FileExistsException 72 | * @throws \League\Flysystem\FileNotFoundException 73 | * @throws \Magento\Framework\Exception\NoSuchEntityException 74 | */ 75 | public function modifyFile(array $data) 76 | { 77 | $this->filename = null; 78 | if (!isset($data['filename']) || empty($data['filename'])) { 79 | throw new LocalizedException(Errors::getErrorMessage(631)); 80 | } 81 | $this->filename = $data['filename']; 82 | $this->as_is = (isset($data['as_is']) && $data['as_is']) ? $data['as_is'] : false; 83 | 84 | $content = $this->manager->getAdapter()->read($this->filename); 85 | 86 | $fullFilePath = trim($this->manager->getPath(), '/') . '/' . trim($this->filename, '/'); 87 | $mediaPath = trim($this->tmpManager->getDirectoryListMedia()->getAbsolutePath(), '/'); 88 | 89 | if (strpos($fullFilePath, $mediaPath) === false) { 90 | $this->filename = $this->tmpManager->writeWysiwygFile(basename($this->filename), $content); 91 | } else { 92 | $this->filename = trim(str_replace($mediaPath, '', $fullFilePath), '/'); 93 | } 94 | 95 | $image = $this->flysystemHelper->getImageHtmlDeclaration($this->filename, $this->as_is); 96 | return $image; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Magento2 Flysystem # 2 | 3 | Magento2 Flysystem Module from [Flagbit](https://www.flagbit.de/) integrate [Flysystem](https://flysystem.thephpleague.com/) 4 | an Abstraction for local and remote filesystems into Magento2 without overriding or breaking core media storage functions. 5 | 6 | ## Features ## 7 | 8 | * Integrate Flysystem to configure different file storages like **sftp**, **local** or **cloud** (S3). 9 | * Provide modularity to easily integrate more adapters in the projects which use it. 10 | * Integrate image modal for Magento2 product and category image uploads. 11 | * You can select from the same **file-pool** instead of uploading from local. 12 | * So you can select an image like in the image selector for cms pages and blocks. 13 | * ACL Configuration for insert, upload, delete files and for create, delete folders and more. 14 | * Separate media page for fast access to flysystem media files. No need for WYSIWYG-Editor Button. 15 | 16 | ## Flysystem Adapters ## 17 | * In core module integrated **local**, **ftp** and **sftp** adapters 18 | * [**S3** Flysystem Adapter](https://github.com/flagbit/Magento2-Flysystem-S3) (install the additional magento2 module) 19 | 20 | ## Wiki Pages ## 21 | 22 | * **User Guides** 23 | * [Installation & Configuration Guide](https://github.com/Flagbit/Magento2-Flysystem/wiki/Installation-&-Configuration-Guide) 24 | * [FAQ and Troubleshooting](https://github.com/Flagbit/Magento2-Flysystem/wiki/FAQ-and-Troubleshooting) 25 | * **Developer Guides** 26 | * [Integration of Flysystem to Magento2](https://github.com/Flagbit/Magento2-Flysystem/wiki/Integration-of-Flysystem-to-Magento2) 27 | * [API Guide Magento2 Flysystem](https://github.com/Flagbit/Magento2-Flysystem/wiki/API-Guide-Magento2-Flysystem) 28 | * [Integrate a new Flysystem Adapter](https://github.com/Flagbit/Magento2-Flysystem/wiki/Integrate-a-new-Flysystem-Adapter) 29 | * [Use Flysystem in custom modules](https://github.com/Flagbit/Magento2-Flysystem/wiki/Use-Flysystem-in-custom-modules) 30 | 31 | ## Screenshots ## 32 | 33 | **Backend Configuration** 34 | 35 | ![Magento2 Flysystem Backend Configuration](https://blog.flagbit.de/wp-content/uploads/2018/07/magento2_flysystem_backend_configuration.png "Magento2 Flysystem Backend Configuration") 36 | 37 | **Select Product Image** 38 | 39 | ![Magento2 Flysystem Select Product Image](https://blog.flagbit.de/wp-content/uploads/2018/07/magento2_flysystem_select_product_image.png "Magento2 Flysystem Select Product Image") 40 | 41 | **Select Category Image** 42 | 43 | ![Magento2 Flysystem Select Category Image](https://blog.flagbit.de/wp-content/uploads/2018/07/magento2_flysystem_select_category_image.png "Magento2 Flysystem Select Category Image") 44 | 45 | **Modal File View** 46 | 47 | ![Magento2 Flysystem Modal File View](https://blog.flagbit.de/wp-content/uploads/2018/07/magento2_flysystem_file_view.png "Magento2 Flysystem Modal File View") 48 | 49 | **ACL Configuration** 50 | 51 | ![Magento2 Flysystem ACL Configuration](https://blog.flagbit.de/wp-content/uploads/2018/07/magento2_flysystem_acl_configuration.png "Magento2 Flysystem ACL Configuration") 52 | 53 | **Browse Media Content** 54 | 55 | ![Magento2 Flysystem Browse Media Content](https://blog.flagbit.de/wp-content/uploads/2018/07/magento2_flysystem_browse_media_content.png "Magento2 Flysystem Browse Media Content") -------------------------------------------------------------------------------- /Adapter/FilesystemManager.php: -------------------------------------------------------------------------------- 1 | localAdapterFactory = $localAdapterFactory; 53 | $this->ftpAdapterFactory = $ftpAdapterFactory; 54 | $this->nullAdapterFactory = $nullAdapterFactory; 55 | $this->sftpAdapterFactory = $sftpAdapterFactory; 56 | } 57 | 58 | /** 59 | * @param array $config 60 | * @return SftpAdapter 61 | */ 62 | public function createSftpDriver(array $config): SftpAdapter 63 | { 64 | return $this->sftpAdapterFactory->create([ 65 | 'config' => $config 66 | ]); 67 | } 68 | 69 | /** 70 | * @param array $config 71 | * @return FtpAdapter 72 | */ 73 | public function createFtpDriver(array $config): FtpAdapter 74 | { 75 | return $this->ftpAdapterFactory->create([ 76 | 'config' => $config 77 | ]); 78 | } 79 | 80 | /** 81 | * @param string $root 82 | * @param int $writeFlags 83 | * @param int $linkHandling 84 | * @param array $permissions 85 | * @return LocalAdapter 86 | */ 87 | public function createLocalDriver(string $root, int $writeFlags = LOCK_EX, int $linkHandling = LocalAdapter::SKIP_LINKS, array $permissions = []): LocalAdapter 88 | { 89 | return $this->localAdapterFactory->create([ 90 | 'root' => $root, 91 | 'writeFlags' => $writeFlags, 92 | 'linkHandling' => $linkHandling, 93 | 'permissions' => $permissions 94 | ]); 95 | } 96 | 97 | /** 98 | * @return NullAdapter 99 | */ 100 | public function createNullDriver(): NullAdapter 101 | { 102 | return $this->nullAdapterFactory->create([]); 103 | } 104 | } -------------------------------------------------------------------------------- /Test/Unit/Adapter/FilesystemAdapterFactoryTest.php: -------------------------------------------------------------------------------- 1 | _objectManagerMock = $this->getMockBuilder(ObjectManager::class) 44 | ->disableOriginalConstructor() 45 | ->setMethods(['create']) 46 | ->getMock(); 47 | 48 | $this->_flysystemMock = $this->getMockBuilder(Filesystem::class) 49 | ->disableOriginalConstructor() 50 | ->getMock(); 51 | 52 | $this->_flysystemFactoryMock = $this->getMockBuilder(FilesystemFactory::class) 53 | ->disableOriginalConstructor() 54 | ->setMethods(['create']) 55 | ->getMock(); 56 | 57 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 58 | ->disableOriginalConstructor() 59 | ->getMock(); 60 | 61 | $this->_object = new FilesystemAdapterFactory( 62 | $this->_objectManagerMock, 63 | $this->_flysystemFactoryMock 64 | ); 65 | } 66 | 67 | 68 | public function testCreate(): void 69 | { 70 | /** @var Local|MockObject $adapterMock */ 71 | $adapterMock = $this->getMockBuilder(Local::class) 72 | ->disableOriginalConstructor() 73 | ->getMock(); 74 | 75 | $this->_flysystemFactoryMock->expects($this->once()) 76 | ->method('create') 77 | ->withAnyParameters() 78 | ->willReturn($this->_flysystemMock); 79 | 80 | $this->_objectManagerMock->expects($this->once()) 81 | ->method('create') 82 | ->with(FilesystemAdapter::class, ['filesystem' => $this->_flysystemMock]) 83 | ->willReturn($this->_flysystemAdapterMock); 84 | 85 | $this->assertEquals($this->_flysystemAdapterMock, $this->_object->create($adapterMock, [])); 86 | } 87 | 88 | public function testCreateInvalidConfig(): void 89 | { 90 | /** @var Local|MockObject $adapterMock */ 91 | $adapterMock = $this->getMockBuilder(Local::class) 92 | ->disableOriginalConstructor() 93 | ->getMock(); 94 | 95 | $this->_flysystemFactoryMock->expects($this->once()) 96 | ->method('create') 97 | ->withAnyParameters() 98 | ->willThrowException(new \LogicException()); 99 | 100 | $this->expectException(\LogicException::class); 101 | $this->_object->create($adapterMock, 'invalid'); 102 | } 103 | } -------------------------------------------------------------------------------- /Model/Pool/FileModifierPool.php: -------------------------------------------------------------------------------- 1 | factory = $factory; 49 | $this->flysystemManager = $flysystemManager; 50 | $this->modifiers = $this->sortAndFilter($modifiers); 51 | } 52 | 53 | /** 54 | * @return array 55 | */ 56 | public function getModifiers(): array 57 | { 58 | return $this->modifiers; 59 | } 60 | 61 | /** 62 | * Retrieve modifiers instantiated 63 | * 64 | * @return ModifierInterface[] 65 | * @throws LocalizedException 66 | */ 67 | public function getModifierInstances() 68 | { 69 | if ($this->modifierInstances) { 70 | return $this->modifierInstances; 71 | } 72 | 73 | foreach ($this->modifiers as $modifier) { 74 | if (!isset($modifier['class']) || empty($modifier['class'])) { 75 | throw new LocalizedException(__('The parameter "class" is missing. Set the "class" and try again.')); 76 | } 77 | 78 | $this->modifierInstances[$modifier['class']] = $this->factory->create($modifier['class']); 79 | } 80 | 81 | return $this->modifierInstances; 82 | } 83 | 84 | /** 85 | * Sorting modifiers according to sort order 86 | * 87 | * @param array $data 88 | * @return array 89 | */ 90 | protected function sortAndFilter(array $data) 91 | { 92 | usort($data, function (array $a, array $b) { 93 | $a['sortOrder'] = $this->getSortOrder($a); 94 | $b['sortOrder'] = $this->getSortOrder($b); 95 | 96 | if ($a['sortOrder'] == $b['sortOrder']) { 97 | return 0; 98 | } 99 | 100 | return ($a['sortOrder'] < $b['sortOrder']) ? -1 : 1; 101 | }); 102 | 103 | $filteredData = []; 104 | if($modalIdentifier = $this->flysystemManager->getModalIdentifier()) { 105 | foreach($data as $single) { 106 | if ( 107 | isset($single['scope']) && 108 | (!is_array($single['scope']) && $single['scope'] === $modalIdentifier || 109 | is_array($single['scope']) && in_array($modalIdentifier, $single['scope'])) 110 | ) { 111 | array_push($filteredData, $single); 112 | } 113 | } 114 | } 115 | $data = $filteredData; 116 | return $data; 117 | } 118 | 119 | /** 120 | * Retrieve sort order from array 121 | * 122 | * @param array $variable 123 | * @return int 124 | */ 125 | protected function getSortOrder(array $variable) 126 | { 127 | return (isset($variable['sortOrder']) && !empty($variable['sortOrder'])) ? $variable['sortOrder'] : 0; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Test/Unit/Model/Pool/Modifier/ProductImageTest.php: -------------------------------------------------------------------------------- 1 | _tmpManagerMock = $this->getMockBuilder(TmpManager::class) 49 | ->disableOriginalConstructor() 50 | ->setMethods(['createProductTmp', 'getAbsoluteTmpPath']) 51 | ->getMock(); 52 | 53 | $this->_managerMock = $this->getMockBuilder(Manager::class) 54 | ->disableOriginalConstructor() 55 | ->setMethods(['getAdapter']) 56 | ->getMock(); 57 | 58 | $this->_loggerMock = $this->getMockBuilder(Logger::class) 59 | ->disableOriginalConstructor() 60 | ->setMethods(['critical']) 61 | ->getMock(); 62 | 63 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 64 | ->disableOriginalConstructor() 65 | ->setMethods(['getMimetype', 'getSize']) 66 | ->getMock(); 67 | 68 | 69 | $this->_managerMock->expects($this->any()) 70 | ->method('getAdapter') 71 | ->willReturn($this->_flysystemAdapterMock); 72 | 73 | $this->_object = new ProductImage( 74 | $this->_tmpManagerMock, 75 | $this->_managerMock, 76 | $this->_loggerMock 77 | ); 78 | } 79 | 80 | public function testModifyFile(): void 81 | { 82 | $data = ['filename' => 'test.jpg']; 83 | 84 | $file = [ 85 | 'name' => basename($data['filename']), 86 | 'type' => 'mimetype/test', 87 | 'tmp_name' => 'test/path/'.$data['filename'], 88 | 'error' => 0, 89 | 'size' => 100 90 | ]; 91 | 92 | $result = [ 93 | 'name' => basename($data['filename']), 94 | 'url' => 'test.test/'.$data['filename'] 95 | ]; 96 | 97 | $this->_flysystemAdapterMock->expects($this->once()) 98 | ->method('getMimetype') 99 | ->with($data['filename']) 100 | ->willReturn($file['type']); 101 | 102 | $this->_tmpManagerMock->expects($this->once()) 103 | ->method('getAbsoluteTmpPath') 104 | ->with($data['filename']) 105 | ->willReturn($file['tmp_name']); 106 | 107 | $this->_flysystemAdapterMock->expects($this->once()) 108 | ->method('getSize') 109 | ->with($data['filename']) 110 | ->willReturn($file['size']); 111 | 112 | $this->_tmpManagerMock->expects($this->once()) 113 | ->method('createProductTmp') 114 | ->with($file) 115 | ->willReturn($result); 116 | 117 | $this->assertEquals(json_encode($result), $this->_object->modifyFile($data)); 118 | } 119 | 120 | public function testModifyFileException(): void 121 | { 122 | $data = ['invalid' => null]; 123 | 124 | $this->expectException(LocalizedException::class); 125 | $this->_object->modifyFile($data); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Test/Unit/Model/Pool/Modifier/CategoryImageTest.php: -------------------------------------------------------------------------------- 1 | _tmpManagerMock = $this->getMockBuilder(TmpManager::class) 49 | ->disableOriginalConstructor() 50 | ->setMethods(['createCategoryTmp', 'getAbsoluteTmpPath']) 51 | ->getMock(); 52 | 53 | $this->_managerMock = $this->getMockBuilder(Manager::class) 54 | ->disableOriginalConstructor() 55 | ->setMethods(['getAdapter']) 56 | ->getMock(); 57 | 58 | $this->_loggerMock = $this->getMockBuilder(Logger::class) 59 | ->disableOriginalConstructor() 60 | ->setMethods(['critical']) 61 | ->getMock(); 62 | 63 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 64 | ->disableOriginalConstructor() 65 | ->setMethods(['getMimetype', 'getSize']) 66 | ->getMock(); 67 | 68 | 69 | $this->_managerMock->expects($this->any()) 70 | ->method('getAdapter') 71 | ->willReturn($this->_flysystemAdapterMock); 72 | 73 | $this->_object = new CategoryImage( 74 | $this->_tmpManagerMock, 75 | $this->_managerMock, 76 | $this->_loggerMock 77 | ); 78 | } 79 | 80 | public function testModifyFile(): void 81 | { 82 | $data = ['filename' => 'test.jpg']; 83 | 84 | $file = [ 85 | 'name' => basename($data['filename']), 86 | 'type' => 'mimetype/test', 87 | 'tmp_name' => 'test/path/'.$data['filename'], 88 | 'error' => 0, 89 | 'size' => 100 90 | ]; 91 | 92 | $result = [ 93 | 'name' => basename($data['filename']), 94 | 'url' => 'test.test/'.$data['filename'] 95 | ]; 96 | 97 | $this->_flysystemAdapterMock->expects($this->once()) 98 | ->method('getMimetype') 99 | ->with($data['filename']) 100 | ->willReturn($file['type']); 101 | 102 | $this->_tmpManagerMock->expects($this->once()) 103 | ->method('getAbsoluteTmpPath') 104 | ->with($data['filename']) 105 | ->willReturn($file['tmp_name']); 106 | 107 | $this->_flysystemAdapterMock->expects($this->once()) 108 | ->method('getSize') 109 | ->with($data['filename']) 110 | ->willReturn($file['size']); 111 | 112 | $this->_tmpManagerMock->expects($this->once()) 113 | ->method('createCategoryTmp') 114 | ->with($file) 115 | ->willReturn($result); 116 | 117 | $this->assertEquals(json_encode($result), $this->_object->modifyFile($data)); 118 | } 119 | 120 | public function testModifyFileException(): void 121 | { 122 | $data = ['invalid' => null]; 123 | 124 | $this->expectException(LocalizedException::class); 125 | $this->_object->modifyFile($data); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Block/Adminhtml/Filesystem/Tree.php: -------------------------------------------------------------------------------- 1 | _flysystemManager = $flysystemManager; 46 | $this->_flysystemHelper = $flysystemHelper; 47 | $this->_serializer = $serializer; 48 | parent::__construct($context, $data); 49 | } 50 | 51 | /** 52 | * @return string|null 53 | * @throws \Exception 54 | */ 55 | public function getTreeJson() 56 | { 57 | $jsonArray = []; 58 | 59 | try { 60 | $path = $this->_flysystemHelper->getCurrentPath(); 61 | 62 | $contents = $this->_flysystemManager->getAdapter()->listContents($path); 63 | 64 | foreach ($contents as $contentKey => $content) { 65 | if ($content['type'] === 'dir' && $content['basename'][0] !== '.') { 66 | $jsonArray [] = [ 67 | 'text' => $this->_flysystemHelper->getShortFilename($content['path']), 68 | 'id' => $this->_flysystemHelper->idEncode('/' . $content['path']), 69 | 'path' => '/' . $content['path'], 70 | 'cls' => 'folder' 71 | ]; 72 | } 73 | } 74 | } catch (\Exception $e) { 75 | $this->_logger->error($e->getMessage()); 76 | $jsonArray = []; 77 | } 78 | 79 | $serialized = $this->_serializer->serialize($jsonArray); 80 | 81 | return $serialized ? $serialized : null; 82 | } 83 | 84 | /** 85 | * Json source URL 86 | * 87 | * @return string 88 | */ 89 | public function getTreeLoaderUrl(): string 90 | { 91 | return $this->getUrl('flagbit_flysystem/*/treeJson'); 92 | } 93 | 94 | /** 95 | * Root node name of tree 96 | * 97 | * @return \Magento\Framework\Phrase 98 | */ 99 | public function getRootNodeName(): \Magento\Framework\Phrase 100 | { 101 | return __('Storage Root'); 102 | } 103 | 104 | /** 105 | * Return tree node full path based on current path 106 | * 107 | * @return array 108 | */ 109 | public function getTreeCurrentPath(): array 110 | { 111 | $treePath = ['root']; 112 | if ($path = $this->_flysystemManager->getSession()->getCurrentPath()) { 113 | //$path = str_replace('/', '', $path); 114 | $relative = []; 115 | foreach (explode('/', $path) as $dirName) { 116 | if ($dirName) { 117 | $relative[] = $dirName; 118 | $treePath[] = $this->_flysystemHelper->idEncode(implode('/', $relative)); 119 | } 120 | } 121 | } 122 | return $treePath; 123 | } 124 | 125 | /** 126 | * @return string|null 127 | */ 128 | public function getTreeWidgetOptions() 129 | { 130 | $serialized = $this->_serializer->serialize([ 131 | "folderTree" => [ 132 | "rootName" => $this->getRootNodeName(), 133 | "url" => $this->getTreeLoaderUrl(), 134 | "currentPath" => array_reverse($this->getTreeCurrentPath()) 135 | ] 136 | ]); 137 | 138 | return $serialized ? $serialized : null; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Adapter/AdapterInterface.php: -------------------------------------------------------------------------------- 1 | _resultRawFactory = $rawFactory; 73 | $this->_flysystemHelper = $flysystemHelper; 74 | $this->_tmpManager = $tmpManager; 75 | $this->_logger = $logger; 76 | $this->_pool = $pool; 77 | parent::__construct($context, $flysystemManager, $session); 78 | } 79 | 80 | /** 81 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Raw|\Magento\Framework\Controller\ResultInterface|void 82 | */ 83 | public function execute() 84 | { 85 | try { 86 | $manager = $this->getStorage(); 87 | 88 | $filename = $this->getRequest()->getParam('filename'); 89 | $filename = $this->_flysystemHelper->idDecode($filename); 90 | 91 | $as_is = $this->getRequest()->getParam('as_is'); 92 | 93 | $contents = $manager->getAdapter()->read($filename); 94 | 95 | $this->_tmpManager->writeTmp($filename, $contents); 96 | 97 | $identifier = $manager->getModalIdentifier(); 98 | 99 | $modifierInstances = $this->_pool->getModifierInstances(); 100 | foreach($modifierInstances as $modifier) { 101 | $modifiedfilename = $modifier->modifyFile([ 102 | 'filename' => $filename, 103 | 'as_is' => $as_is 104 | ]); 105 | 106 | if(!empty($modifiedfilename)) { 107 | $filename = $modifiedfilename; 108 | } 109 | } 110 | 111 | /** @deprecated since version 0.2.1 use \Flagbit\Flysystem\Model\Pool\FileModifierPool instead */ 112 | $this->_eventManager->dispatch('flagbit_flysystem_oninsert_after', 113 | [ 114 | 'controller' => $this, 115 | 'filename' => $filename, 116 | 'manager' => $manager, 117 | 'modal_id' => $identifier, 118 | 'as_is' => $as_is 119 | ]); 120 | 121 | if (empty($this->_result)) { 122 | $this->setResult($filename); 123 | } 124 | } catch (\Exception $e) { 125 | $this->_logger->critical($e->getMessage()); 126 | } 127 | 128 | 129 | $resultRaw = $this->_resultRawFactory->create(); 130 | return $resultRaw->setContents($this->_result); 131 | } 132 | 133 | /** 134 | * @param string $result 135 | */ 136 | public function setResult(string $result) 137 | { 138 | $this->_result = $result; 139 | } 140 | } -------------------------------------------------------------------------------- /view/adminhtml/templates/browser/content/uploader.phtml: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 7 | escapeHtml(__('Browse Files...')) ?> 8 | 9 | 10 |
11 | 20 | 103 |
104 | -------------------------------------------------------------------------------- /Test/Unit/Controller/DeleteFolderTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 55 | ->disableOriginalConstructor() 56 | ->setMethods() 57 | ->getMock(); 58 | 59 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 60 | ->disableOriginalConstructor() 61 | ->setMethods(['getAdapter', 'getSession']) 62 | ->getMock(); 63 | 64 | $this->_sessionMock = $this->getMockBuilder(Session::class) 65 | ->disableOriginalConstructor() 66 | ->setMethods(['getCurrentPath']) 67 | ->getMock(); 68 | 69 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 70 | ->disableOriginalConstructor() 71 | ->setMethods(['create']) 72 | ->getMock(); 73 | 74 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 75 | ->disableOriginalConstructor() 76 | ->setMethods(['deleteDir']) 77 | ->getMock(); 78 | 79 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 80 | ->disableOriginalConstructor() 81 | ->setMethods(['setData']) 82 | ->getMock(); 83 | 84 | $this->_object = new DeleteFolder( 85 | $this->_contextMock, 86 | $this->_flysystemManagerMock, 87 | $this->_sessionMock, 88 | $this->_resultJsonFactoryMock 89 | ); 90 | } 91 | 92 | public function testExecute(): void 93 | { 94 | $currentPath = 'test/path/'; 95 | 96 | $this->_flysystemManagerMock->expects($this->exactly(2)) 97 | ->method('getAdapter') 98 | ->willReturn($this->_flysystemAdapterMock); 99 | 100 | $this->_flysystemManagerMock->expects($this->once()) 101 | ->method('getSession') 102 | ->willReturn($this->_sessionMock); 103 | 104 | $this->_sessionMock->expects($this->once()) 105 | ->method('getCurrentPath') 106 | ->willReturn($currentPath); 107 | 108 | $this->_flysystemAdapterMock->expects($this->once()) 109 | ->method('deleteDir') 110 | ->with($currentPath) 111 | ->willReturn(true); 112 | 113 | $this->_resultJsonFactoryMock->expects($this->once()) 114 | ->method('create') 115 | ->willReturn($this->_resultJsonMock); 116 | 117 | $this->_resultJsonMock->expects($this->once()) 118 | ->method('setData') 119 | ->with(true) 120 | ->willReturn($this->_resultJsonMock); 121 | 122 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 123 | } 124 | 125 | public function testExecuteException(): void 126 | { 127 | $exception = new \Exception(); 128 | 129 | $this->_flysystemManagerMock->expects($this->once()) 130 | ->method('getAdapter') 131 | ->willThrowException($exception); 132 | 133 | $this->_resultJsonFactoryMock->expects($this->once()) 134 | ->method('create') 135 | ->willReturn($this->_resultJsonMock); 136 | 137 | $this->_resultJsonMock->expects($this->once()) 138 | ->method('setData') 139 | ->with($this->arrayHasKey('message')) 140 | ->willReturn($this->_resultJsonMock); 141 | 142 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 143 | } 144 | } -------------------------------------------------------------------------------- /Helper/Filesystem.php: -------------------------------------------------------------------------------- 1 | _storeManager = $storeManager; 43 | $this->_imageHelper = $imageHelper; 44 | parent::__construct($context); 45 | } 46 | 47 | /** 48 | * Ext Tree node key name 49 | * 50 | * @return string 51 | */ 52 | public function getTreeNodeName(): string 53 | { 54 | return 'node'; 55 | } 56 | 57 | /** 58 | * Encode string to valid HTML id element, based on base64 encoding 59 | * 60 | * @param string $string 61 | * @return string 62 | */ 63 | public function idEncode(string $string): string 64 | { 65 | return strtr(base64_encode($string), '+/=', ':_-'); 66 | } 67 | 68 | 69 | /** 70 | * Revert opration to idEncode 71 | * 72 | * @param string $string 73 | * @return string 74 | */ 75 | public function idDecode(string $string): string 76 | { 77 | $string = strtr($string, ':_-', '+/='); 78 | return base64_decode($string); 79 | } 80 | 81 | /** 82 | * Return path of the current selected directory or root directory for startup 83 | * Try to create target directory if it doesn't exist 84 | * 85 | * @return string 86 | */ 87 | public function getCurrentPath(): string 88 | { 89 | if (!$this->_currentPath) { 90 | $currentPath = '/'; 91 | $path = $this->_getRequest()->getParam($this->getTreeNodeName()); 92 | if ($path && $path !== 'root') { 93 | $currentPath = $this->idDecode($path); 94 | } 95 | $this->_currentPath = $currentPath; 96 | } 97 | return $this->_currentPath; 98 | } 99 | 100 | /** 101 | * Reduce filename by replacing some characters with dots 102 | * 103 | * @param string $filename 104 | * @param int $maxLength 105 | * @return string 106 | */ 107 | public function getShortFilename(string $filename, int $maxLength = 20): string 108 | { 109 | $path = explode('/', $filename); 110 | $filename = $path[(count($path)-1)]; 111 | 112 | if (strlen($filename) <= $maxLength) { 113 | return $filename; 114 | } 115 | return substr($filename, 0, $maxLength) . '...'; 116 | } 117 | 118 | /** 119 | * @param string $filename 120 | * @param bool $renderAsTag 121 | * @return string 122 | * @throws \Magento\Framework\Exception\NoSuchEntityException 123 | */ 124 | public function getImageHtmlDeclaration(string $filename, bool $renderAsTag = false): string 125 | { 126 | /** @var \Magento\Store\Model\Store $store */ 127 | $store = $this->_storeManager->getStore(); 128 | 129 | /** @phan-suppress-next-line PhanUndeclaredMethod */ 130 | $mediaUrl = $store->getBaseUrl(UrlInterface::URL_TYPE_MEDIA); 131 | $mediaPath = '/'.trim($filename, '/'); 132 | $fileUrl = $mediaUrl.$filename; 133 | $directive = sprintf('{{media url="%s"}}', $mediaPath); 134 | if ($renderAsTag) { 135 | $html = sprintf('', $this->_imageHelper->isUsingStaticUrlsAllowed() ? $fileUrl : $directive); 136 | } else { 137 | if ($this->_imageHelper->isUsingStaticUrlsAllowed()) { 138 | $html = $fileUrl; // $mediaPath; 139 | } else { 140 | $directive = $this->urlEncoder->encode($directive); 141 | 142 | /** @phan-suppress-next-line PhanUndeclaredMethod */ 143 | $html = $store->getUrl( 144 | 'cms/wysiwyg/directive', 145 | [ 146 | '___directive' => $directive, 147 | '_escape_params' => false, 148 | ] 149 | ); 150 | } 151 | } 152 | return $html; 153 | } 154 | } -------------------------------------------------------------------------------- /Test/Unit/Controller/UploadTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 60 | ->disableOriginalConstructor() 61 | ->getMock(); 62 | 63 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 64 | ->disableOriginalConstructor() 65 | ->setMethods(['getAdapter', 'getSession']) 66 | ->getMock(); 67 | 68 | $this->_sessionMock = $this->getMockBuilder(Session::class) 69 | ->disableOriginalConstructor() 70 | ->setMethods(['getCurrentPath']) 71 | ->getMock(); 72 | 73 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 74 | ->disableOriginalConstructor() 75 | ->setMethods(['create']) 76 | ->getMock(); 77 | 78 | $this->_uploadManagerMock = $this->getMockBuilder(UploadManager::class) 79 | ->disableOriginalConstructor() 80 | ->setMethods(['upload']) 81 | ->getMock(); 82 | 83 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 84 | ->disableOriginalConstructor() 85 | ->getMock(); 86 | 87 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 88 | ->disableOriginalConstructor() 89 | ->setMethods(['setData']) 90 | ->getMock(); 91 | 92 | $this->_object = new Upload( 93 | $this->_contextMock, 94 | $this->_flysystemManagerMock, 95 | $this->_sessionMock, 96 | $this->_resultJsonFactoryMock, 97 | $this->_uploadManagerMock 98 | ); 99 | } 100 | 101 | public function testExecute(): void 102 | { 103 | $currentPath = '/test/path'; 104 | 105 | $this->_flysystemManagerMock->expects($this->atLeast(1)) 106 | ->method('getAdapter') 107 | ->willReturn($this->_flysystemAdapterMock); 108 | 109 | $this->_flysystemManagerMock->expects($this->once()) 110 | ->method('getSession') 111 | ->willReturn($this->_sessionMock); 112 | 113 | $this->_sessionMock->expects($this->once()) 114 | ->method('getCurrentPath') 115 | ->willReturn($currentPath); 116 | 117 | $this->_uploadManagerMock->expects($this->once()) 118 | ->method('upload') 119 | ->with($this->_flysystemAdapterMock, $currentPath); 120 | 121 | $this->_resultJsonFactoryMock->expects($this->once()) 122 | ->method('create') 123 | ->willReturn($this->_resultJsonMock); 124 | 125 | $this->_resultJsonMock->expects($this->once()) 126 | ->method('setData') 127 | ->with($this->arrayHasKey('error')) 128 | ->willReturn($this->_resultJsonMock); 129 | 130 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 131 | } 132 | 133 | public function testExecuteException(): void 134 | { 135 | $exception = new \Exception(); 136 | 137 | $this->_flysystemManagerMock->expects($this->atLeast(1)) 138 | ->method('getAdapter') 139 | ->willThrowException($exception); 140 | 141 | $this->_resultJsonFactoryMock->expects($this->once()) 142 | ->method('create') 143 | ->willReturn($this->_resultJsonMock); 144 | 145 | $this->_resultJsonMock->expects($this->once()) 146 | ->method('setData') 147 | ->with($this->arrayHasKey('errorcode')) 148 | ->willReturn($this->_resultJsonMock); 149 | 150 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 151 | } 152 | } -------------------------------------------------------------------------------- /Model/Filesystem/UploadManager.php: -------------------------------------------------------------------------------- 1 | _flysystemManager = $flysystemManager; 72 | $this->_flysystemFactory = $flysystemFactory; 73 | $this->_flysystemConfig = $flysystemConfig; 74 | $this->_logger = $logger; 75 | $this->_uploaderFactory = $uploaderFactory; 76 | 77 | $this->create(); 78 | $this->setUploadFile(); 79 | } 80 | 81 | /** 82 | * @return FilesystemAdapter|null 83 | */ 84 | public function create() 85 | { 86 | if(!$this->_adapter) { 87 | $this->_adapter = $this->_flysystemFactory->create($this->_flysystemManager->createLocalDriver(self::SERVER_TMP_PATH)); 88 | } 89 | return $this->_adapter; 90 | } 91 | 92 | /** 93 | * @return Uploader|null 94 | */ 95 | public function getUploader() 96 | { 97 | return $this->_uploader; 98 | } 99 | 100 | /** 101 | * @return FilesystemAdapter|null 102 | */ 103 | public function getAdapter() 104 | { 105 | return $this->_adapter; 106 | } 107 | 108 | /** 109 | * @param string $fileId 110 | * @return bool 111 | */ 112 | public function setUploadFile(string $fileId = \Flagbit\Flysystem\Helper\Config::FLYSYSTEM_UPLOAD_ID): bool 113 | { 114 | try { 115 | $this->_uploader = $this->_uploaderFactory->create(['fileId' => $fileId]); 116 | return true; 117 | } catch (\Exception $e) { 118 | $this->_logger->critical($e->getMessage()); 119 | return false; 120 | } 121 | } 122 | 123 | /** 124 | * @param array $file 125 | * @return void 126 | * @throws \Exception 127 | */ 128 | public function validateFileType(array $file) 129 | { 130 | $filetype = ''; 131 | 132 | if(isset($file['name'])) { 133 | $parts = explode('.', $file['name']); 134 | $supportedFileTypes = $this->_flysystemConfig->getSupportedFileTypes(); 135 | 136 | $filetype = $parts[count($parts)-1]; 137 | if(in_array($filetype, $supportedFileTypes)) { 138 | return; 139 | } 140 | } 141 | 142 | throw new \Exception(Errors::getErrorMessage(382, [$filetype])); 143 | } 144 | 145 | /** 146 | * @param FilesystemAdapter $adapter 147 | * @param string $targetPath 148 | * @return bool 149 | * @throws \Exception 150 | * @throws \League\Flysystem\FileExistsException 151 | * @throws \League\Flysystem\FileNotFoundException 152 | */ 153 | public function upload(FilesystemAdapter $adapter, string $targetPath): bool 154 | { 155 | $file = $this->getUploader()->validateFile(); 156 | 157 | $this->validateFileType($file); 158 | 159 | if(!isset($file['tmp_name'])) { 160 | throw new \Exception(Errors::getErrorMessage(501)); 161 | } 162 | 163 | $contents = $this->getAdapter()->read(basename($file['tmp_name'])); 164 | $filename = $file['name']; 165 | 166 | for($i = 1; $adapter->has($targetPath.'/'.$filename); $i++) { 167 | $fileparts = explode('.', $file['name']); 168 | if(is_array($fileparts)) { 169 | $fileparts[0] = $fileparts[0] . '_' . $i; 170 | $filename = implode('.', $fileparts); 171 | } 172 | } 173 | 174 | return $adapter->write($targetPath.'/'.$filename, $contents); 175 | } 176 | } -------------------------------------------------------------------------------- /Test/Unit/Controller/NewFolderTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 61 | ->disableOriginalConstructor() 62 | ->setMethods(['getRequest']) 63 | ->getMock(); 64 | 65 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 66 | ->disableOriginalConstructor() 67 | ->setMethods(['getAdapter', 'getSession']) 68 | ->getMock(); 69 | 70 | $this->_sessionMock = $this->getMockBuilder(Session::class) 71 | ->disableOriginalConstructor() 72 | ->setMethods(['getCurrentPath']) 73 | ->getMock(); 74 | 75 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 76 | ->disableOriginalConstructor() 77 | ->setMethods(['create']) 78 | ->getMock(); 79 | 80 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 81 | ->disableOriginalConstructor() 82 | ->setMethods(['createDir']) 83 | ->getMock(); 84 | 85 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 86 | ->disableOriginalConstructor() 87 | ->setMethods(['setData']) 88 | ->getMock(); 89 | 90 | $this->_httpMock = $this->getMockBuilder(Http::class) 91 | ->disableOriginalConstructor() 92 | ->setMethods(['getPost']) 93 | ->getMock(); 94 | 95 | $this->_contextMock->expects($this->once()) 96 | ->method('getRequest') 97 | ->willReturn($this->_httpMock); 98 | 99 | $this->_object = new NewFolder( 100 | $this->_contextMock, 101 | $this->_flysystemManagerMock, 102 | $this->_sessionMock, 103 | $this->_resultJsonFactoryMock 104 | ); 105 | } 106 | 107 | public function testExecute(): void 108 | { 109 | $foldername = 'test'; 110 | $currentPath = 'test/path/'; 111 | 112 | $this->_flysystemManagerMock->expects($this->exactly(2)) 113 | ->method('getAdapter') 114 | ->willReturn($this->_flysystemAdapterMock); 115 | 116 | $this->_httpMock->expects($this->once()) 117 | ->method('getPost') 118 | ->with('name') 119 | ->willReturn($foldername); 120 | 121 | $this->_flysystemManagerMock->expects($this->once()) 122 | ->method('getSession') 123 | ->willReturn($this->_sessionMock); 124 | 125 | $this->_sessionMock->expects($this->once()) 126 | ->method('getCurrentPath') 127 | ->willReturn($currentPath); 128 | 129 | $this->_flysystemAdapterMock->expects($this->once()) 130 | ->method('createDir') 131 | ->with('test/path/'.$foldername) 132 | ->willReturn(true); 133 | 134 | $this->_resultJsonFactoryMock->expects($this->once()) 135 | ->method('create') 136 | ->willReturn($this->_resultJsonMock); 137 | 138 | $this->_resultJsonMock->expects($this->once()) 139 | ->method('setData') 140 | ->with(true) 141 | ->willReturn($this->_resultJsonMock); 142 | 143 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 144 | } 145 | 146 | public function testExecuteException(): void 147 | { 148 | $exception = new \Exception(); 149 | 150 | $this->_flysystemManagerMock->expects($this->once()) 151 | ->method('getAdapter') 152 | ->willThrowException($exception); 153 | 154 | $this->_resultJsonFactoryMock->expects($this->once()) 155 | ->method('create') 156 | ->willReturn($this->_resultJsonMock); 157 | 158 | $this->_resultJsonMock->expects($this->once()) 159 | ->method('setData') 160 | ->with($this->arrayHasKey('message')) 161 | ->willReturn($this->_resultJsonMock); 162 | 163 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 164 | } 165 | } -------------------------------------------------------------------------------- /Test/Unit/Block/Adminhtml/Filesystem/Content/UploaderTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 60 | ->disableOriginalConstructor() 61 | ->setMethods(['getUrlBuilder', 'getMathRandom', 'getRequest', 'getFormKey']) 62 | ->getMock(); 63 | 64 | $this->_fileSizeMock = $this->getMockBuilder(Size::class) 65 | ->disableOriginalConstructor() 66 | ->getMock(); 67 | 68 | $this->_urlBuilderMock = $this->getMockBuilder(Url::class) 69 | ->disableOriginalConstructor() 70 | ->setMethods(['getUrl']) 71 | ->getMock(); 72 | 73 | $this->_mathRandomMock = $this->getMockBuilder(Random::class) 74 | ->disableOriginalConstructor() 75 | ->setMethods(['getUniqueHash']) 76 | ->getMock(); 77 | 78 | $this->_requestHttpMock = $this->getMockBuilder(Http::class) 79 | ->disableOriginalConstructor() 80 | ->setMethods(['getParam']) 81 | ->getMock(); 82 | 83 | $this->_formKeyMock = $this->getMockBuilder(FormKey::class) 84 | ->disableOriginalConstructor() 85 | ->setMethods(['getFormKey']) 86 | ->getMock(); 87 | 88 | $this->_objectManagerMock = $this->getMockBuilder(ObjectManager::class) 89 | ->disableOriginalConstructor() 90 | ->setMethods(['get']) 91 | ->getMock(); 92 | 93 | ObjectManager::setInstance($this->_objectManagerMock); 94 | 95 | $this->_contextMock->expects($this->once()) 96 | ->method('getUrlBuilder') 97 | ->willReturn($this->_urlBuilderMock); 98 | 99 | $this->_contextMock->expects($this->once()) 100 | ->method('getMathRandom') 101 | ->willReturn($this->_mathRandomMock); 102 | 103 | $this->_contextMock->expects($this->once()) 104 | ->method('getRequest') 105 | ->willReturn($this->_requestHttpMock); 106 | 107 | $this->_contextMock->expects($this->once()) 108 | ->method('getFormKey') 109 | ->willReturn($this->_formKeyMock); 110 | } 111 | 112 | public function testContructor(): void 113 | { 114 | $uniqueHash = 'id_test'; 115 | $uri = 'flagbit_flysystem/*/upload'; 116 | $url = 'test.test/'.$uri; 117 | $mediaType = 'test'; 118 | $formKey = 'test'; 119 | 120 | $this->_mathRandomMock->expects($this->once()) 121 | ->method('getUniqueHash') 122 | ->withAnyParameters() 123 | ->willReturn($uniqueHash); 124 | 125 | $this->_formKeyMock->expects($this->once()) 126 | ->method('getFormKey') 127 | ->willReturn($formKey); 128 | 129 | $this->_requestHttpMock->expects($this->once()) 130 | ->method('getParam') 131 | ->with('type') 132 | ->willReturn($mediaType); 133 | 134 | $this->_urlBuilderMock->expects($this->at(1)) 135 | ->method('getUrl') 136 | ->with($uri, $this->arrayHasKey('type')) 137 | ->willReturn($url); 138 | 139 | $this->_object = new Uploader( 140 | $this->_contextMock, 141 | $this->_fileSizeMock 142 | ); 143 | } 144 | 145 | public function testContructorWithMediaType(): void 146 | { 147 | $uniqueHash = 'id_test'; 148 | $uri = 'flagbit_flysystem/*/upload'; 149 | $url = 'test.test/'.$uri; 150 | $mediaType = 'test'; 151 | $formKey = 'test'; 152 | 153 | $this->_mathRandomMock->expects($this->once()) 154 | ->method('getUniqueHash') 155 | ->withAnyParameters() 156 | ->willReturn($uniqueHash); 157 | 158 | $this->_formKeyMock->expects($this->once()) 159 | ->method('getFormKey') 160 | ->willReturn($formKey); 161 | 162 | $this->_urlBuilderMock->expects($this->at(1)) 163 | ->method('getUrl') 164 | ->with($uri, $this->arrayHasKey('type')) 165 | ->willReturn($url); 166 | 167 | $this->_object = new Uploader( 168 | $this->_contextMock, 169 | $this->_fileSizeMock, 170 | ['media_type' => $mediaType] 171 | ); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Test/Unit/Adapter/FilesystemManagerTest.php: -------------------------------------------------------------------------------- 1 | _ftpAdapterMock = $this->getMockBuilder(Ftp::class) 67 | ->disableOriginalConstructor() 68 | ->getMock(); 69 | 70 | $this->_ftpAdapterFactoryMock = $this->getMockBuilder(FtpFactory::class) 71 | ->disableOriginalConstructor() 72 | ->setMethods(['create']) 73 | ->getMock(); 74 | 75 | $this->_sftpAdapterMock = $this->getMockBuilder(SftpAdapter::class) 76 | ->disableOriginalConstructor() 77 | ->getMock(); 78 | 79 | $this->_sftpAdapterFactoryMock = $this->getMockBuilder(SftpAdapterFActory::class) 80 | ->disableOriginalConstructor() 81 | ->setMethods(['create']) 82 | ->getMock(); 83 | 84 | $this->_localAdapterMock = $this->getMockBuilder(Local::class) 85 | ->disableOriginalConstructor() 86 | ->getMock(); 87 | 88 | $this->_localAdapterFactoryMock = $this->getMockBuilder(LocalFactory::class) 89 | ->disableOriginalConstructor() 90 | ->setMethods(['create']) 91 | ->getMock(); 92 | 93 | $this->_nullAdapterMock = $this->getMockBuilder(NullAdapter::class) 94 | ->disableOriginalConstructor() 95 | ->getMock(); 96 | 97 | $this->_nullAdapterFactoryMock = $this->getMockBuilder(NullAdapterFactory::class) 98 | ->disableOriginalConstructor() 99 | ->setMethods(['create']) 100 | ->getMock(); 101 | 102 | $this->_object = new FilesystemManager( 103 | $this->_localAdapterFactoryMock, 104 | $this->_ftpAdapterFactoryMock, 105 | $this->_nullAdapterFactoryMock, 106 | $this->_sftpAdapterFactoryMock 107 | ); 108 | } 109 | 110 | public function testCreateFtpDriver(): void 111 | { 112 | $config = [ 113 | 'config' => [] 114 | ]; 115 | 116 | $this->_ftpAdapterFactoryMock->expects($this->once()) 117 | ->method('create') 118 | ->with($this->arrayHasKey('config')) 119 | ->willReturn($this->_ftpAdapterMock); 120 | 121 | $this->assertEquals($this->_ftpAdapterMock, $this->_object->createFtpDriver($config)); 122 | } 123 | 124 | public function testCreateSftpDriver(): void 125 | { 126 | $config = [ 127 | 'config' => [] 128 | ]; 129 | 130 | $this->_sftpAdapterFactoryMock->expects($this->once()) 131 | ->method('create') 132 | ->with($this->arrayHasKey('config')) 133 | ->willReturn($this->_sftpAdapterMock); 134 | 135 | $this->assertEquals($this->_sftpAdapterMock, $this->_object->createSftpDriver($config)); 136 | } 137 | 138 | public function testCreateLocalDriver(): void 139 | { 140 | $root = 'test'; 141 | 142 | $this->_localAdapterFactoryMock->expects($this->once()) 143 | ->method('create') 144 | ->with($this->arrayHasKey('root')) 145 | ->willReturn($this->_localAdapterMock); 146 | 147 | $this->assertEquals($this->_localAdapterMock, $this->_object->createLocalDriver($root)); 148 | } 149 | 150 | public function testCreateLocalDriverException(): void 151 | { 152 | $root = 'invalid'; 153 | 154 | $this->_localAdapterFactoryMock->expects($this->once()) 155 | ->method('create') 156 | ->with($this->arrayHasKey('root')) 157 | ->willThrowException(new \LogicException()); 158 | 159 | $this->expectException(\LogicException::class); 160 | $this->assertEquals($this->_localAdapterMock, $this->_object->createLocalDriver($root)); 161 | } 162 | 163 | public function testCreateNullDriver(): void 164 | { 165 | $this->_nullAdapterFactoryMock->expects($this->once()) 166 | ->method('create') 167 | ->willReturn($this->_nullAdapterMock); 168 | 169 | $this->assertEquals($this->_nullAdapterMock, $this->_object->createNullDriver()); 170 | } 171 | 172 | } -------------------------------------------------------------------------------- /Test/Unit/Controller/TreeJsonTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 72 | ->disableOriginalConstructor() 73 | ->getMock(); 74 | 75 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 76 | ->disableOriginalConstructor() 77 | ->setMethods(['getAdapter']) 78 | ->getMock(); 79 | 80 | $this->_sessionMock = $this->getMockBuilder(Session::class) 81 | ->disableOriginalConstructor() 82 | ->getMock(); 83 | 84 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 85 | ->disableOriginalConstructor() 86 | ->setMethods(['create']) 87 | ->getMock(); 88 | 89 | $this->_layoutFactoryMock = $this->getMockBuilder(LayoutFactory::class) 90 | ->disableOriginalConstructor() 91 | ->setMethods(['create']) 92 | ->getMock(); 93 | 94 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 95 | ->disableOriginalConstructor() 96 | ->getMock(); 97 | 98 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 99 | ->disableOriginalConstructor() 100 | ->setMethods(['setData', 'setJsonData']) 101 | ->getMock(); 102 | 103 | $this->_layoutMock = $this->getMockBuilder(Layout::class) 104 | ->disableOriginalConstructor() 105 | ->setMethods(['createBlock']) 106 | ->getMock(); 107 | 108 | $this->_treeMock = $this->getMockBuilder(Tree::class) 109 | ->disableOriginalConstructor() 110 | ->setMethods(['getTreeJson']) 111 | ->getMock(); 112 | 113 | $this->_object = new TreeJson( 114 | $this->_contextMock, 115 | $this->_flysystemManagerMock, 116 | $this->_sessionMock, 117 | $this->_resultJsonFactoryMock, 118 | $this->_layoutFactoryMock 119 | ); 120 | } 121 | 122 | public function testExecute(): void 123 | { 124 | $treeJson = 'tree'; 125 | 126 | $this->_resultJsonFactoryMock->expects($this->once()) 127 | ->method('create') 128 | ->willReturn($this->_resultJsonMock); 129 | 130 | $this->_flysystemManagerMock->expects($this->once()) 131 | ->method('getAdapter') 132 | ->willReturn($this->_flysystemAdapterMock); 133 | 134 | $this->_layoutFactoryMock->expects($this->once()) 135 | ->method('create') 136 | ->willReturn($this->_layoutMock); 137 | 138 | $this->_layoutMock->expects($this->once()) 139 | ->method('createBlock') 140 | ->with(Tree::class) 141 | ->willReturn($this->_treeMock); 142 | 143 | $this->_treeMock->expects($this->once()) 144 | ->method('getTreeJson') 145 | ->willReturn($treeJson); 146 | 147 | $this->_resultJsonMock->expects($this->once()) 148 | ->method('setJsonData') 149 | ->with($treeJson) 150 | ->willReturn($this->_resultJsonMock); 151 | 152 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 153 | } 154 | 155 | public function testExecuteException(): void 156 | { 157 | $exception = new \Exception(); 158 | 159 | $this->_resultJsonFactoryMock->expects($this->once()) 160 | ->method('create') 161 | ->willReturn($this->_resultJsonMock); 162 | 163 | $this->_flysystemManagerMock->expects($this->once()) 164 | ->method('getAdapter') 165 | ->willThrowException($exception); 166 | 167 | $this->_resultJsonMock->expects($this->once()) 168 | ->method('setData') 169 | ->with($this->arrayHasKey('message')) 170 | ->willReturn($this->_resultJsonMock); 171 | 172 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 173 | } 174 | } -------------------------------------------------------------------------------- /Test/Unit/Controller/IndexTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 73 | ->disableOriginalConstructor() 74 | ->setMethods(['getRequest']) 75 | ->getMock(); 76 | 77 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 78 | ->disableOriginalConstructor() 79 | ->setMethods(['getAdapter', 'setModalIdentifier']) 80 | ->getMock(); 81 | 82 | $this->_sessionMock = $this->getMockBuilder(Session::class) 83 | ->disableOriginalConstructor() 84 | ->getMock(); 85 | 86 | $this->_resultLayoutFactoryMock = $this->getMockBuilder(LayoutFactory::class) 87 | ->disableOriginalConstructor() 88 | ->setMethods(['create']) 89 | ->getMock(); 90 | 91 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 92 | ->disableOriginalConstructor() 93 | ->setMethods(['create']) 94 | ->getMock(); 95 | 96 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 97 | ->disableOriginalConstructor() 98 | ->setMethods() 99 | ->getMock(); 100 | 101 | $this->_resultLayoutMock = $this->getMockBuilder(Layout::class) 102 | ->disableOriginalConstructor() 103 | ->setMethods(['addHandle']) 104 | ->getMock(); 105 | 106 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 107 | ->disableOriginalConstructor() 108 | ->setMethods(['setData']) 109 | ->getMock(); 110 | 111 | $this->_httpMock = $this->getMockBuilder(Http::class) 112 | ->disableOriginalConstructor() 113 | ->setMethods(['getParam']) 114 | ->getMock(); 115 | 116 | $this->_contextMock->expects($this->once()) 117 | ->method('getRequest') 118 | ->willReturn($this->_httpMock); 119 | 120 | $this->_object = new Index( 121 | $this->_contextMock, 122 | $this->_flysystemManagerMock, 123 | $this->_sessionMock, 124 | $this->_resultLayoutFactoryMock, 125 | $this->_resultJsonFactoryMock 126 | ); 127 | } 128 | 129 | public function testExecute(): void 130 | { 131 | $identifier = 'test'; 132 | 133 | $this->_flysystemManagerMock->expects($this->exactly(2)) 134 | ->method('getAdapter') 135 | ->willReturn($this->_flysystemAdapterMock); 136 | 137 | $this->_httpMock->expects($this->once()) 138 | ->method('getParam') 139 | ->with('identifier') 140 | ->willReturn($identifier); 141 | 142 | $this->_flysystemManagerMock->expects($this->once()) 143 | ->method('setModalIdentifier') 144 | ->with($identifier); 145 | 146 | $this->_resultLayoutFactoryMock->expects($this->once()) 147 | ->method('create') 148 | ->willReturn($this->_resultLayoutMock); 149 | 150 | $this->_resultLayoutMock->expects($this->once()) 151 | ->method('addHandle') 152 | ->with('overlay_popup'); 153 | 154 | $this->assertEquals($this->_resultLayoutMock, $this->_object->execute()); 155 | } 156 | 157 | public function testExecuteException(): void 158 | { 159 | $exception = new \Exception(); 160 | 161 | $this->_flysystemManagerMock->expects($this->once()) 162 | ->method('getAdapter') 163 | ->willThrowException($exception); 164 | 165 | $this->_resultJsonFactoryMock->expects($this->once()) 166 | ->method('create') 167 | ->willReturn($this->_resultJsonMock); 168 | 169 | $this->_resultJsonMock->expects($this->once()) 170 | ->method('setData') 171 | ->with($this->arrayHasKey('message')) 172 | ->willReturn($this->_resultJsonMock); 173 | 174 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 175 | } 176 | } -------------------------------------------------------------------------------- /Test/Unit/Controller/DeleteFilesTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 67 | ->disableOriginalConstructor() 68 | ->setMethods(['getRequest']) 69 | ->getMock(); 70 | 71 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 72 | ->disableOriginalConstructor() 73 | ->setMethods(['getAdapter']) 74 | ->getMock(); 75 | 76 | $this->_sessionMock = $this->getMockBuilder(Session::class) 77 | ->disableOriginalConstructor() 78 | ->getMock(); 79 | 80 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 81 | ->disableOriginalConstructor() 82 | ->setMethods(['create']) 83 | ->getMock(); 84 | 85 | $this->_flysystemHelperMock = $this->getMockBuilder(Filesystem::class) 86 | ->disableOriginalConstructor() 87 | ->setMethods(['idDecode']) 88 | ->getMock(); 89 | 90 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 91 | ->disableOriginalConstructor() 92 | ->setMethods(['delete']) 93 | ->getMock(); 94 | 95 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 96 | ->disableOriginalConstructor() 97 | ->setMethods(['setData']) 98 | ->getMock(); 99 | 100 | $this->_httpMock = $this->getMockBuilder(Http::class) 101 | ->disableOriginalConstructor() 102 | ->setMethods(['isPost', 'getParam']) 103 | ->getMock(); 104 | 105 | $this->_contextMock->expects($this->once()) 106 | ->method('getRequest') 107 | ->willReturn($this->_httpMock); 108 | 109 | $this->_object = new DeleteFiles( 110 | $this->_contextMock, 111 | $this->_flysystemManagerMock, 112 | $this->_sessionMock, 113 | $this->_resultJsonFactoryMock, 114 | $this->_flysystemHelperMock 115 | ); 116 | } 117 | 118 | 119 | public function testExecute(): void 120 | { 121 | $files = ['filea.jpg', 'fileb.png']; 122 | 123 | $this->_httpMock->expects($this->once()) 124 | ->method('isPost') 125 | ->willReturn(true); 126 | 127 | $this->_httpMock->expects($this->once()) 128 | ->method('getParam') 129 | ->with('files') 130 | ->willReturn($files); 131 | 132 | $this->_flysystemManagerMock->expects($this->exactly(3)) 133 | ->method('getAdapter') 134 | ->willReturn($this->_flysystemAdapterMock); 135 | 136 | $this->_flysystemHelperMock->expects($this->exactly(2)) 137 | ->method('idDecode') 138 | ->will($this->returnValueMap( 139 | [ 140 | [$files[0], 'encodeda'], 141 | [$files[1], 'encodedb'] 142 | ] 143 | )); 144 | 145 | $this->_flysystemAdapterMock->expects($this->at(0)) 146 | ->method('delete') 147 | ->with('encodeda') 148 | ->willReturn(true); 149 | 150 | $this->_flysystemAdapterMock->expects($this->at(1)) 151 | ->method('delete') 152 | ->with('encodedb') 153 | ->willReturn(true); 154 | 155 | $this->_resultJsonFactoryMock->expects($this->once()) 156 | ->method('create') 157 | ->willReturn($this->_resultJsonMock); 158 | 159 | $this->_resultJsonMock->expects($this->once()) 160 | ->method('setData') 161 | ->with($this->arrayHasKey('error')) 162 | ->willReturn($this->_resultJsonMock); 163 | 164 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 165 | } 166 | 167 | public function testExecuteException(): void 168 | { 169 | $this->_httpMock->expects($this->once()) 170 | ->method('isPost') 171 | ->willReturn(false); 172 | 173 | $this->_resultJsonFactoryMock->expects($this->once()) 174 | ->method('create') 175 | ->willReturn($this->_resultJsonMock); 176 | 177 | $this->_resultJsonMock->expects($this->once()) 178 | ->method('setData') 179 | ->with($this->arrayHasKey('message')) 180 | ->willReturn($this->_resultJsonMock); 181 | 182 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 183 | } 184 | } -------------------------------------------------------------------------------- /Test/Unit/Block/Adminhtml/Filesystem/ContentTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 54 | ->disableOriginalConstructor() 55 | ->setMethods(['getButtonList', 'getRequest', 'getUrlBuilder', 'getAuthorization']) 56 | ->getMock(); 57 | 58 | $this->_jsonEncoderMock = $this->getMockBuilder(Json::class) 59 | ->disableOriginalConstructor() 60 | ->getMock(); 61 | 62 | $this->_authorizationMock = $this->getMockBuilder(Authorization::class) 63 | ->disableOriginalConstructor() 64 | ->setMethods(['isAllowed']) 65 | ->getMock(); 66 | 67 | $this->_buttonListMock = $this->getMockBuilder(ButtonList::class) 68 | ->disableOriginalConstructor() 69 | ->getMock(); 70 | 71 | $this->_requestHttpMock = $this->getMockBuilder(Http::class) 72 | ->disableOriginalConstructor() 73 | ->setMethods(['getParam']) 74 | ->getMock(); 75 | 76 | $this->_urlBuilderMock = $this->getMockBuilder(Url::class) 77 | ->disableOriginalConstructor() 78 | ->setMethods(['getUrl']) 79 | ->getMock(); 80 | 81 | $this->_contextMock->expects($this->once()) 82 | ->method('getButtonList') 83 | ->willReturn($this->_buttonListMock); 84 | 85 | $this->_contextMock->expects($this->once()) 86 | ->method('getRequest') 87 | ->willReturn($this->_requestHttpMock); 88 | 89 | $this->_contextMock->expects($this->once()) 90 | ->method('getUrlBuilder') 91 | ->willReturn($this->_urlBuilderMock); 92 | 93 | $this->_contextMock->expects($this->once()) 94 | ->method('getAuthorization') 95 | ->willReturn($this->_authorizationMock); 96 | 97 | $this->_buttonListMock->expects($this->exactly(2)) 98 | ->method('remove') 99 | ->with($this->isType('string')); 100 | 101 | $this->_requestHttpMock->expects($this->at(0)) 102 | ->method('getParam') 103 | ->with('identifier') 104 | ->willReturn('flagbit_cms_modal'); 105 | 106 | $this->_authorizationMock->expects($this->exactly(4)) 107 | ->method('isAllowed') 108 | ->with($this->isType('string')) 109 | ->willReturn(true); 110 | 111 | $this->_buttonListMock->expects($this->exactly(6)) 112 | ->method('add') 113 | ->with($this->isType('string'), $this->isType('array'), 0, 0, 'header'); 114 | 115 | $this->_object = new Content( 116 | $this->_contextMock, 117 | $this->_jsonEncoderMock 118 | ); 119 | } 120 | 121 | public function testGetFileBrowserSetupObject(): void 122 | { 123 | $elementId = 'element_id'; 124 | $jsonString = 'jsonString'; 125 | $url = 'testUrl'; 126 | 127 | $this->_requestHttpMock->expects($this->once()) 128 | ->method('getParam') 129 | ->with('target_element_id') 130 | ->willReturn($elementId); 131 | 132 | $this->_urlBuilderMock->expects($this->exactly(5)) 133 | ->method('getUrl') 134 | ->withAnyParameters() 135 | ->willReturn($url); 136 | 137 | $this->_jsonEncoderMock->expects($this->once()) 138 | ->method('serialize') 139 | ->with($this->isType('array')) 140 | ->willReturn($jsonString); 141 | 142 | $this->assertEquals($jsonString, $this->_object->getFilebrowserSetupObject()); 143 | } 144 | 145 | public function testGetModalIdentifier(): void 146 | { 147 | $identifier = 'modal_id'; 148 | 149 | $this->_requestHttpMock->expects($this->once()) 150 | ->method('getParam') 151 | ->with('identifier') 152 | ->willReturn($identifier); 153 | 154 | $this->assertEquals($identifier, $this->_object->getModalIdentifier()); 155 | } 156 | 157 | public function testGetPreviewUrl(): void 158 | { 159 | $url = 'test.com/preview'; 160 | 161 | $this->_urlBuilderMock->expects($this->once()) 162 | ->method('getUrl') 163 | ->with($this->isType('string')) 164 | ->willReturn($url); 165 | 166 | $this->assertEquals($url, $this->_object->getPreviewUrl()); 167 | } 168 | 169 | public function testGetWysiwygModalUrl(): void 170 | { 171 | $url = 'test.com/test'; 172 | $targetElement = 'test_target'; 173 | 174 | $this->_requestHttpMock->expects($this->at(0)) 175 | ->method('getParam') 176 | ->with('target_element_id') 177 | ->willReturn($targetElement); 178 | 179 | $this->_urlBuilderMock->expects($this->once()) 180 | ->method('getUrl') 181 | ->with('cms/wysiwyg_images/index', [ 182 | 'target_element_id' => $targetElement 183 | ]) 184 | ->willReturn($url); 185 | 186 | $this->assertEquals($url, $this->_object->getWysiwygModalUrl()); 187 | } 188 | } -------------------------------------------------------------------------------- /Test/Unit/Model/Pool/FileModifierPoolTest.php: -------------------------------------------------------------------------------- 1 | 10, 66 | 'scope' => 'test_scope', 67 | 'class' => TestFileModifier001::class 68 | ], 69 | [ 70 | 'sortOrder' => 10, 71 | 'scope' => 'invalid_scope', 72 | 'class' => TestFileModifier002::class 73 | ], 74 | [ 75 | 'sortOrder' => 5, 76 | 'scope' => ['test_scope', 'invalid_scope'], 77 | 'class' => TestFileModifier003::class 78 | ], 79 | [ 80 | 'sortOrder' => 15, 81 | 'scope' => ['invalid_scope', 'invalid_scope2'], 82 | 'class' => TestFileModifier004::class 83 | ] 84 | ]; 85 | 86 | private $filteredModifiers = [ 87 | [ 88 | 'sortOrder' => 5, 89 | 'scope' => ['test_scope', 'invalid_scope'], 90 | 'class' => TestFileModifier003::class 91 | ], 92 | [ 93 | 'sortOrder' => 10, 94 | 'scope' => 'test_scope', 95 | 'class' => TestFileModifier001::class 96 | ] 97 | ]; 98 | 99 | 100 | /** 101 | * @throws \ReflectionException 102 | */ 103 | protected function setUp(): void 104 | { 105 | $this->_modifierFactoryMock = $this->getMockBuilder(ModifierFactory::class) 106 | ->disableOriginalConstructor() 107 | ->setMethods(['create']) 108 | ->getMock(); 109 | 110 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 111 | ->disableOriginalConstructor() 112 | ->setMethods(['getModalIdentifier']) 113 | ->getMock(); 114 | 115 | $this->_testFileModifierMock001 = $this->getMockBuilder(TestFileModifier001::class) 116 | ->disableOriginalConstructor() 117 | ->getMock(); 118 | 119 | $this->_testFileModifierMock002 = $this->getMockBuilder(TestFileModifier002::class) 120 | ->disableOriginalConstructor() 121 | ->getMock(); 122 | 123 | $this->_testFileModifierMock003 = $this->getMockBuilder(TestFileModifier003::class) 124 | ->disableOriginalConstructor() 125 | ->getMock(); 126 | 127 | $this->_testFileModifierMock004 = $this->getMockBuilder(TestFileModifier004::class) 128 | ->disableOriginalConstructor() 129 | ->getMock(); 130 | 131 | $this->_flysystemManagerMock->expects($this->any()) 132 | ->method('getModalIdentifier') 133 | ->willReturn($this->modalIdentifier); 134 | 135 | $this->_object = new FileModifierPool( 136 | $this->_modifierFactoryMock, 137 | $this->_flysystemManagerMock, 138 | $this->modifiers 139 | ); 140 | } 141 | 142 | public function testGetModifiers(): void 143 | { 144 | $this->assertEquals($this->filteredModifiers, $this->_object->getModifiers()); 145 | } 146 | 147 | public function testGetModifierInstances(): void 148 | { 149 | $expectedResult = [ 150 | TestFileModifier003::class => $this->_testFileModifierMock003, 151 | TestFileModifier001::class => $this->_testFileModifierMock001 152 | ]; 153 | 154 | $this->_modifierFactoryMock->expects($this->at(0)) 155 | ->method('create') 156 | ->with(TestFileModifier003::class) 157 | ->willReturn($this->_testFileModifierMock003); 158 | 159 | $this->_modifierFactoryMock->expects($this->at(1)) 160 | ->method('create') 161 | ->with(TestFileModifier001::class) 162 | ->willReturn($this->_testFileModifierMock001); 163 | 164 | $this->assertEquals($expectedResult, $this->_object->getModifierInstances()); 165 | 166 | $this->_modifierFactoryMock->expects($this->never()) 167 | ->method('create'); 168 | $this->assertEquals($expectedResult, $this->_object->getModifierInstances()); 169 | } 170 | 171 | public function testGetModifierInstancesException(): void 172 | { 173 | $invalidModifiers = [ 174 | 'test001' => [ 175 | 'sortOrder' => 10, 176 | 'scope' => 'test_scope' 177 | ] 178 | ]; 179 | 180 | $this->_object = new FileModifierPool( 181 | $this->_modifierFactoryMock, 182 | $this->_flysystemManagerMock, 183 | $invalidModifiers 184 | ); 185 | 186 | $this->expectException(LocalizedException::class); 187 | $this->_object->getModifierInstances(); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /Test/Unit/Controller/ContentsTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 79 | ->disableOriginalConstructor() 80 | ->setMethods(['getObjectManager']) 81 | ->getMock(); 82 | 83 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 84 | ->disableOriginalConstructor() 85 | ->setMethods(['getAdapter', 'getSession']) 86 | ->getMock(); 87 | 88 | $this->_sessionMock = $this->getMockBuilder(Session::class) 89 | ->disableOriginalConstructor() 90 | ->setMethods(['setCurrentPath']) 91 | ->getMock(); 92 | 93 | $this->_resultLayoutFactoryMock = $this->getMockBuilder(LayoutFactory::class) 94 | ->disableOriginalConstructor() 95 | ->setMethods(['create']) 96 | ->getMock(); 97 | 98 | $this->_resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class) 99 | ->disableOriginalConstructor() 100 | ->setMethods(['create']) 101 | ->getMock(); 102 | 103 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 104 | ->disableOriginalConstructor() 105 | ->setMethods() 106 | ->getMock(); 107 | 108 | $this->_objectManagerMock = $this->getMockBuilder(ObjectManager::class) 109 | ->disableOriginalConstructor() 110 | ->setMethods(['get']) 111 | ->getMock(); 112 | 113 | $this->_flysystemHelperMock = $this->getMockBuilder(Filesystem::class) 114 | ->disableOriginalConstructor() 115 | ->setMethods(['getCurrentPath']) 116 | ->getMock(); 117 | 118 | $this->_resultLayoutMock = $this->getMockBuilder(Layout::class) 119 | ->disableOriginalConstructor() 120 | ->getMock(); 121 | 122 | $this->_resultJsonMock = $this->getMockBuilder(Json::class) 123 | ->disableOriginalConstructor() 124 | ->setMethods(['setData']) 125 | ->getMock(); 126 | 127 | $this->_contextMock->expects($this->once()) 128 | ->method('getObjectManager') 129 | ->willReturn($this->_objectManagerMock); 130 | 131 | $this->_object = new Contents( 132 | $this->_contextMock, 133 | $this->_flysystemManagerMock, 134 | $this->_sessionMock, 135 | $this->_resultLayoutFactoryMock, 136 | $this->_resultJsonFactoryMock 137 | ); 138 | } 139 | 140 | 141 | public function testExecute(): void 142 | { 143 | $currentPath = 'test/path/'; 144 | 145 | $this->_flysystemManagerMock->expects($this->atMost(2)) 146 | ->method('getAdapter') 147 | ->willReturn($this->_flysystemAdapterMock); 148 | 149 | $this->_objectManagerMock->expects($this->once()) 150 | ->method('get') 151 | ->with(Filesystem::class) 152 | ->willReturn($this->_flysystemHelperMock); 153 | 154 | $this->_flysystemHelperMock->expects($this->once()) 155 | ->method('getCurrentPath') 156 | ->willReturn($currentPath); 157 | 158 | $this->_flysystemManagerMock->expects($this->once()) 159 | ->method('getSession') 160 | ->willReturn($this->_sessionMock); 161 | 162 | $this->_sessionMock->expects($this->once()) 163 | ->method('setCurrentPath') 164 | ->with($currentPath); 165 | 166 | $this->_resultLayoutFactoryMock->expects($this->once()) 167 | ->method('create') 168 | ->willReturn($this->_resultLayoutMock); 169 | 170 | $this->assertEquals($this->_resultLayoutMock, $this->_object->execute()); 171 | } 172 | 173 | public function testExecuteException(): void 174 | { 175 | $exception = new \Exception(); 176 | 177 | $this->_flysystemManagerMock->expects($this->atMost(2)) 178 | ->method('getAdapter') 179 | ->willThrowException($exception); 180 | 181 | $this->_resultJsonFactoryMock->expects($this->once()) 182 | ->method('create') 183 | ->willReturn($this->_resultJsonMock); 184 | 185 | $this->_resultJsonMock->expects($this->once()) 186 | ->method('setData') 187 | ->with($this->arrayHasKey('message')); 188 | 189 | $this->assertEquals($this->_resultJsonMock, $this->_object->execute()); 190 | } 191 | } -------------------------------------------------------------------------------- /Test/Unit/Controller/Filemanager/IndexTest.php: -------------------------------------------------------------------------------- 1 | _contextMock = $this->getMockBuilder(Context::class) 66 | ->disableOriginalConstructor() 67 | ->getMock(); 68 | 69 | $this->_flysystemManagerMock = $this->getMockBuilder(Manager::class) 70 | ->disableOriginalConstructor() 71 | ->setMethods(['getAdapter', 'setModalIdentifier']) 72 | ->getMock(); 73 | 74 | $this->_sessionMock = $this->getMockBuilder(Session::class) 75 | ->disableOriginalConstructor() 76 | ->getMock(); 77 | 78 | $this->_resultPageFactoryMock = $this->getMockBuilder(PageFactory::class) 79 | ->disableOriginalConstructor() 80 | ->setMethods(['create']) 81 | ->getMock(); 82 | 83 | $this->_resultPageMock = $this->getMockBuilder(Page::class) 84 | ->disableOriginalConstructor() 85 | ->setMethods(['addDefaultHandle', 'setActiveMenu', 'addBreadcrumb', 'getConfig']) 86 | ->getMock(); 87 | 88 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 89 | ->disableOriginalConstructor() 90 | ->getMock(); 91 | 92 | $this->_pageConfigMock = $this->getMockBuilder(Config::class) 93 | ->disableOriginalConstructor() 94 | ->setMethods(['getTitle']) 95 | ->getMock(); 96 | 97 | $this->_pageTitleMock = $this->getMockBuilder(Title::class) 98 | ->disableOriginalConstructor() 99 | ->setMethods(['prepend']) 100 | ->getMock(); 101 | 102 | $this->_object = new Index( 103 | $this->_contextMock, 104 | $this->_flysystemManagerMock, 105 | $this->_sessionMock, 106 | $this->_resultPageFactoryMock 107 | ); 108 | } 109 | 110 | public function testExecute(): void 111 | { 112 | $this->_flysystemManagerMock->expects($this->exactly(2)) 113 | ->method('getAdapter') 114 | ->willReturn($this->_flysystemAdapterMock); 115 | 116 | $this->_flysystemManagerMock->expects($this->once()) 117 | ->method('setModalIdentifier') 118 | ->with($this->isType('string')); 119 | 120 | $this->_resultPageFactoryMock->expects($this->once()) 121 | ->method('create') 122 | ->willReturn($this->_resultPageMock); 123 | 124 | $this->_resultPageMock->expects($this->once()) 125 | ->method('addDefaultHandle') 126 | ->willReturn($this->_resultPageMock); 127 | 128 | $this->_resultPageMock->expects($this->once()) 129 | ->method('setActiveMenu') 130 | ->with($this->isType('string')) 131 | ->willReturn($this->_resultPageMock); 132 | 133 | $this->_resultPageMock->expects($this->once()) 134 | ->method('addBreadcrumb') 135 | ->willReturn($this->_resultPageMock); 136 | 137 | $this->_resultPageMock->expects($this->once()) 138 | ->method('getConfig') 139 | ->willReturn($this->_pageConfigMock); 140 | 141 | $this->_pageConfigMock->expects($this->once()) 142 | ->method('getTitle') 143 | ->willReturn($this->_pageTitleMock); 144 | 145 | $this->_pageTitleMock->expects($this->once()) 146 | ->method('prepend'); 147 | 148 | $this->_object->execute(); 149 | } 150 | 151 | public function testExecuteException(): void 152 | { 153 | $exception = new \Exception('test'); 154 | 155 | $this->_flysystemManagerMock->expects($this->once()) 156 | ->method('getAdapter') 157 | ->willThrowException($exception); 158 | 159 | $this->_resultPageFactoryMock->expects($this->once()) 160 | ->method('create') 161 | ->willReturn($this->_resultPageMock); 162 | 163 | $this->_resultPageMock->expects($this->once()) 164 | ->method('addDefaultHandle') 165 | ->willReturn($this->_resultPageMock); 166 | 167 | $this->_resultPageMock->expects($this->once()) 168 | ->method('setActiveMenu') 169 | ->with($this->isType('string')) 170 | ->willReturn($this->_resultPageMock); 171 | 172 | $this->_resultPageMock->expects($this->once()) 173 | ->method('addBreadcrumb') 174 | ->willReturn($this->_resultPageMock); 175 | 176 | $this->_resultPageMock->expects($this->once()) 177 | ->method('getConfig') 178 | ->willReturn($this->_pageConfigMock); 179 | 180 | $this->_pageConfigMock->expects($this->once()) 181 | ->method('getTitle') 182 | ->willReturn($this->_pageTitleMock); 183 | 184 | $this->_pageTitleMock->expects($this->once()) 185 | ->method('prepend'); 186 | 187 | $this->_object->execute(); 188 | } 189 | } -------------------------------------------------------------------------------- /Test/Unit/Model/Pool/Modifier/CmsWysiwygImageTest.php: -------------------------------------------------------------------------------- 1 | _tmpManagerMock = $this->getMockBuilder(TmpManager::class) 61 | ->disableOriginalConstructor() 62 | ->setMethods(['writeWysiwygFile', 'getDirectoryListMedia']) 63 | ->getMock(); 64 | 65 | $this->_managerMock = $this->getMockBuilder(Manager::class) 66 | ->disableOriginalConstructor() 67 | ->setMethods(['getAdapter', 'getPath']) 68 | ->getMock(); 69 | 70 | $this->_filesystemHelperMock = $this->getMockBuilder(Filesystem::class) 71 | ->disableOriginalConstructor() 72 | ->setMethods(['getImageHtmlDeclaration']) 73 | ->getMock(); 74 | 75 | $this->_loggerMock = $this->getMockBuilder(Logger::class) 76 | ->disableOriginalConstructor() 77 | ->setMethods(['critical']) 78 | ->getMock(); 79 | 80 | $this->_flysystemAdapterMock = $this->getMockBuilder(FilesystemAdapter::class) 81 | ->disableOriginalConstructor() 82 | ->setMethods(['read']) 83 | ->getMock(); 84 | 85 | $this->_directoryListMock = $this->getMockBuilder(Write::class) 86 | ->disableOriginalConstructor() 87 | ->setMethods(['getAbsolutePath']) 88 | ->getMock(); 89 | 90 | $this->_managerMock->expects($this->any()) 91 | ->method('getAdapter') 92 | ->willReturn($this->_flysystemAdapterMock); 93 | 94 | $this->_object = new CmsWysiwygImage( 95 | $this->_managerMock, 96 | $this->_tmpManagerMock, 97 | $this->_filesystemHelperMock, 98 | $this->_loggerMock 99 | ); 100 | } 101 | 102 | public function testModifyFile(): void 103 | { 104 | $data = ['filename' => 'test/test.jpg', 'as_is' => true]; 105 | $content = 'test'; 106 | 107 | $managerPath = '/magento/test/'; 108 | $mediaPath = '/magento/pub/media/'; 109 | 110 | $newFile = 'wysiwyg/test.jpg'; 111 | $imageHtml = 'imageHtml'; 112 | 113 | $this->_flysystemAdapterMock->expects($this->once()) 114 | ->method('read') 115 | ->with($data['filename']) 116 | ->willReturn($content); 117 | 118 | $this->_managerMock->expects($this->once()) 119 | ->method('getPath') 120 | ->willReturn($managerPath); 121 | 122 | $this->_tmpManagerMock->expects($this->once()) 123 | ->method('getDirectoryListMedia') 124 | ->willReturn($this->_directoryListMock); 125 | 126 | $this->_directoryListMock->expects($this->once()) 127 | ->method('getAbsolutePath') 128 | ->willReturn($mediaPath); 129 | 130 | $this->_tmpManagerMock->expects($this->once()) 131 | ->method('writeWysiwygFile') 132 | ->with('test.jpg', $content) 133 | ->willReturn($newFile); 134 | 135 | $this->_filesystemHelperMock->expects($this->once()) 136 | ->method('getImageHtmlDeclaration') 137 | ->with($newFile, $data['as_is']) 138 | ->willReturn($imageHtml); 139 | 140 | $this->assertEquals($imageHtml, $this->_object->modifyFile($data)); 141 | } 142 | 143 | public function testModifyMediaFile(): void 144 | { 145 | $data = ['filename' => 'media/wysiwyg/test.jpg', 'as_is' => true]; 146 | $content = 'test'; 147 | 148 | $managerPath = '/magento/pub/'; 149 | $mediaPath = '/magento/pub/media/'; 150 | 151 | $newFile = 'wysiwyg/test.jpg'; 152 | $imageHtml = 'imageHtml'; 153 | 154 | $this->_flysystemAdapterMock->expects($this->once()) 155 | ->method('read') 156 | ->with($data['filename']) 157 | ->willReturn($content); 158 | 159 | $this->_managerMock->expects($this->once()) 160 | ->method('getPath') 161 | ->willReturn($managerPath); 162 | 163 | $this->_tmpManagerMock->expects($this->once()) 164 | ->method('getDirectoryListMedia') 165 | ->willReturn($this->_directoryListMock); 166 | 167 | $this->_directoryListMock->expects($this->once()) 168 | ->method('getAbsolutePath') 169 | ->willReturn($mediaPath); 170 | 171 | $this->_tmpManagerMock->expects($this->never()) 172 | ->method('writeWysiwygFile'); 173 | 174 | $this->_filesystemHelperMock->expects($this->once()) 175 | ->method('getImageHtmlDeclaration') 176 | ->with($newFile, $data['as_is']) 177 | ->willReturn($imageHtml); 178 | 179 | $this->assertEquals($imageHtml, $this->_object->modifyFile($data)); 180 | } 181 | 182 | public function testModifyFileException(): void 183 | { 184 | $data = ['invalid' => null]; 185 | 186 | $this->expectException(LocalizedException::class); 187 | $this->_object->modifyFile($data); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /Block/Adminhtml/Filesystem/Content/Files.php: -------------------------------------------------------------------------------- 1 | _flysystemManager = $flysystemManager; 71 | $this->_flysystemHelper = $flysystemHelper; 72 | $this->_flysystemConfig = $flysystemConfig; 73 | $this->_messageManager = $messageManager; 74 | $this->_messages = $messages; 75 | parent::__construct($context, $data); 76 | } 77 | 78 | /** 79 | * Prepared Files collection for current directory 80 | * 81 | * @return array 82 | */ 83 | public function getFiles(): array 84 | { 85 | try { 86 | if (count($this->_filesCollection) === 0) { 87 | $path = $this->_flysystemHelper->getCurrentPath(); 88 | 89 | $contents = $this->_flysystemManager->getAdapter()->listContents($path); 90 | foreach ($contents as $file) { 91 | if ($this->validateFile($file)) { 92 | $this->_filesCollection[] = $file; 93 | } 94 | } 95 | } 96 | } catch (\Exception $e) { 97 | $this->_messageManager->addErrorMessage($e->getMessage()); 98 | return []; 99 | } 100 | 101 | return $this->_filesCollection; 102 | } 103 | 104 | /** 105 | * @param array $file 106 | * @return bool 107 | * @throws \Exception 108 | */ 109 | public function validateFile(array $file): bool 110 | { 111 | $requiredValues = ['type' => null, 'basename' => null, 'path' => null]; 112 | if(!is_array($file) || count(array_diff_key($requiredValues, $file)) > 0) { 113 | throw new \Exception(Errors::getErrorMessage(201)); 114 | } 115 | 116 | if($file['type'] === 'file' && $file['basename'][0] !== '.') { 117 | $supportedFileTypes = $this->_flysystemConfig->getSupportedFileTypes(); 118 | if(in_array($this->getFileEnding($file), $supportedFileTypes)) { 119 | return true; 120 | } 121 | } 122 | 123 | return false; 124 | } 125 | 126 | /** 127 | * @return string 128 | */ 129 | public function getMessages(): string 130 | { 131 | $this->_messages->setMessages($this->_messageManager->getMessages()); 132 | return $this->_messages->getGroupedHtml(); 133 | } 134 | 135 | /** 136 | * Files collection count getter 137 | * 138 | * @return int 139 | */ 140 | public function getFilesCount(): int 141 | { 142 | return count($this->getFiles()); 143 | } 144 | 145 | /** 146 | * @param array $file 147 | * @return string|null 148 | */ 149 | public function getFileId(array $file) 150 | { 151 | if(!isset($file['path'])) { 152 | return null; 153 | } 154 | return $this->_flysystemHelper->idEncode($file['path']); 155 | } 156 | 157 | /** 158 | * @param array $file 159 | * @return string|null 160 | */ 161 | public function getFileShortName(array $file) { 162 | if(!isset($file['path'])) { 163 | return null; 164 | } 165 | return $this->_flysystemHelper->getShortFilename($file['path']); 166 | } 167 | 168 | /** 169 | * @param array $file 170 | * @return string 171 | */ 172 | public function getFileEnding(array $file): string { 173 | if(!isset($file['extension']) || empty($file['extension'])) { 174 | return 'unknown'; 175 | } 176 | 177 | return $file['extension']; 178 | } 179 | 180 | /** 181 | * @param array $file 182 | * @return string 183 | */ 184 | public function getFileSize(array $file): string { 185 | if(!isset($file['size'])) { 186 | return ''; 187 | } 188 | 189 | $size = $file['size'] / 1024 / 1024; 190 | if($size >= 1) { 191 | return round($size, 2) . ' MB'; 192 | } 193 | 194 | $size = $file['size'] / 1024; 195 | if($size >= 1) { 196 | return round($size, 2) . ' KB'; 197 | } 198 | 199 | return $file['size'] . ' Byte'; 200 | } 201 | 202 | /** 203 | * @param array $file 204 | * @return string 205 | */ 206 | public function getLastModified(array $file): string { 207 | if(isset($file['timestamp'])) { 208 | // because date returns false on failure 209 | $date = date('d-m-Y H:i', $file['timestamp']); 210 | if($date) { 211 | return $date; 212 | } 213 | } 214 | 215 | return ''; 216 | } 217 | 218 | /** 219 | * @param array $files 220 | * @return void 221 | */ 222 | public function setFilesCollection(array $files) 223 | { 224 | $this->_filesCollection = $files; 225 | } 226 | } 227 | --------------------------------------------------------------------------------