Commit ded2e8b3 authored by Reinis Mazeiks's avatar Reinis Mazeiks
Browse files

Implement basic 3d model uploading

parent 45e4610d
<?php declare(strict_types=1);
namespace Scandi\Product3DGraphQl\Api\Data;
use Magento\Framework\Api\ExtensibleDataInterface;
......@@ -6,9 +7,9 @@ use Magento\Framework\Api\ExtensibleDataInterface;
interface Model3DInterface extends ExtensibleDataInterface
{
/**
* @return int
* @return mixed
*/
public function getId(): int;
public function getId();
/**
* @param $id
......@@ -48,4 +49,6 @@ interface Model3DInterface extends ExtensibleDataInterface
* @return void
*/
public function setFile($file);
public function getResourceUrl(): string;
}
<?php declare(strict_types=1);
namespace Scandi\Product3DGraphQl\Helper;
use Scandi\Product3DGraphQl\Model\ResourceModel\Model3D\Collection as ModelCollection;
use Scandi\Product3DGraphQl\Model\ResourceModel\Model3D\CollectionFactory as ModelCollectionFactory;
class Model3DProvider
{
/** @var ModelCollectionFactory */
protected $model3dCollectionFactory;
/**
* Model3DProvider constructor.
* @param ModelCollectionFactory $model3dCollectionFactory
*/
public function __construct(ModelCollectionFactory $model3dCollectionFactory)
{
$this->model3dCollectionFactory = $model3dCollectionFactory;
}
public function getModelsForProductId($productId) {
/** @var ModelCollection $collection */
$collection = $this->model3dCollectionFactory->create();
$collection->addProductFilter($productId);
return $collection;
}
}
......@@ -3,6 +3,7 @@
namespace Scandi\Product3DGraphQl\Model;
use \Magento\Framework\Model\AbstractModel;
use Magento\Store\Model\StoreManagerInterface;
use Scandi\Product3DGraphQl\Api\Data\Model3DInterface;
class Model3D extends AbstractModel implements Model3DInterface
......@@ -11,6 +12,18 @@ class Model3D extends AbstractModel implements Model3DInterface
const URL = 'url';
const FILE = 'file';
/** @var StoreManagerInterface */
protected $storeManager;
/**
* Model3D constructor.
* @param StoreManagerInterface $storeManager
*/
public function __construct(StoreManagerInterface $storeManager)
{
$this->storeManager = $storeManager;
}
/**
* Initialize resource model
* @return void
......@@ -34,7 +47,7 @@ class Model3D extends AbstractModel implements Model3DInterface
*/
public function setProductId($id)
{
$this->setData(self::PRODUCT_ID);
$this->setData(self::PRODUCT_ID, $id);
}
/**
......@@ -51,7 +64,7 @@ class Model3D extends AbstractModel implements Model3DInterface
*/
public function setUrl($url)
{
$this->setData(self::URL);
$this->setData(self::URL, $url);
}
/**
......@@ -68,7 +81,12 @@ class Model3D extends AbstractModel implements Model3DInterface
*/
public function setFile($file)
{
$this->setData(self::FILE);
$this->setData(self::FILE, $file);
}
public function getResourceUrl(): string
{
return $this->storeManager->getStore()->getBaseUrl() . $this->getUrl();
}
}
......@@ -29,6 +29,23 @@ class Model3DRepository implements Model3DRepositoryInterface
/** @var Model3DSearchResultInterfaceFactory */
protected $searchResultFactory;
/**
* Model3DRepository constructor.
* @param Model3DResource $model3dResource
* @param Model3DFactory $modelFactory
* @param Model3DCollectionFactory $collectionFactory
* @param CollectionProcessorInterface $collectionProcessor
* @param Model3DSearchResultInterfaceFactory $searchResultFactory
*/
public function __construct(Model3DResource $model3dResource, Model3DFactory $modelFactory, Model3DCollectionFactory $collectionFactory, CollectionProcessorInterface $collectionProcessor, Model3DSearchResultInterfaceFactory $searchResultFactory)
{
$this->model3dResource = $model3dResource;
$this->modelFactory = $modelFactory;
$this->collectionFactory = $collectionFactory;
$this->collectionProcessor = $collectionProcessor;
$this->searchResultFactory = $searchResultFactory;
}
/**
* @param $id
* @return Model3DInterface
......
......@@ -22,7 +22,5 @@ class Model3D extends AbstractDb
{
$this->_init(self::TABLE, self::FIELD_ID);
}
}
<?php declare(strict_types=1);
namespace Scandi\Product3DGraphQl\Model;
use Exception;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\MediaStorage\Model\File\UploaderFactory;
class Upload
{
/** @var UploaderFactory */
protected $uploaderFactory;
/** @var ScopeConfigInterface */
protected $scopeConfig;
/** @var Filesystem */
protected $fileSystem;
/** @var string */
protected $uploadFolder;
/** @var string[] */
protected $allowedExtensions;
/**
* Upload constructor.
* @param UploaderFactory $uploaderFactory
* @param ScopeConfigInterface $scopeConfig
* @param Filesystem $fileSystem
* @param string $uploadFolder
* @param string[] $allowedExtensions
*/
public function __construct(
UploaderFactory $uploaderFactory,
ScopeConfigInterface $scopeConfig,
Filesystem $fileSystem,
string $uploadFolder = 'scandi/product_3d_models/',
array $allowedExtensions = ['glb']
) {
$this->uploaderFactory = $uploaderFactory;
$this->scopeConfig = $scopeConfig;
$this->fileSystem = $fileSystem;
$this->uploadFolder = $uploadFolder;
$this->allowedExtensions = $allowedExtensions;
}
/**
* @param $file
* @return array
* @throws Exception
*/
public function uploadFile($file)
{
$uploader = $this->uploaderFactory->create(['fileId' => $file]);
$uploader->setAllowedExtensions($this->allowedExtensions)
->setAllowRenameFiles(true)
->setFilesDispersion(true)
->setAllowCreateFolders(true);
return $uploader->save($this->getUploadPath());
}
protected function getUploadPath()
{
return $this->fileSystem->getDirectoryWrite(DirectoryList::MEDIA)
->getAbsolutePath($this->uploadFolder);
}
}
<?php declare(strict_types=1);
namespace Scandi\Product3DGraphQl\Observer\Product;
use Magento\Backend\App\Action\Context;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Registry;
use Scandi\Product3DGraphQl\Api\Data\Model3DInterface;
use Scandi\Product3DGraphQl\Api\Data\Model3DInterfaceFactory;
use Scandi\Product3DGraphQl\Api\Model3DRepositoryInterface;
use Scandi\Product3DGraphQl\Model\Upload;
class Save implements ObserverInterface
{
/** @var Registry */
protected $registry;
/** @var Upload */
protected $upload;
/** @var Context */
protected $context;
/** @var Model3DRepositoryInterface */
protected $modelRepository;
/** @var Model3DInterfaceFactory */
protected $modelFactory;
/**
* Save constructor.
* @param Registry $registry
* @param Upload $upload
* @param Context $context
* @param Model3DRepositoryInterface $modelRepository
* @param Model3DInterfaceFactory $modelFactory
*/
public function __construct(Registry $registry, Upload $upload, Context $context, Model3DRepositoryInterface $modelRepository, Model3DInterfaceFactory $modelFactory)
{
$this->registry = $registry;
$this->upload = $upload;
$this->context = $context;
$this->modelRepository = $modelRepository;
$this->modelFactory = $modelFactory;
}
public function execute(EventObserver $observer)
{
$product = $this->registry->registry('product');
$post = $observer->getDataObject();
$this->processModelDeletion($post);
$models = $this->context->getRequest()->getFiles('models', -1);
if ($models != '-1') {
$this->addModels($models, $product);
}
}
protected function processModelDeletion($post)
{
if (isset($post['remove_model'])) {
foreach ($post['remove_model'] as $id => $keep) {
if ($keep === "0") {
$this->modelRepository->delete(
$this->modelRepository->getById($id)
);
}
}
}
}
protected function addModels($models, ProductInterface $product)
{
foreach ($models as $model) {
if ($model['tmp_name'] === '') {
continue;
}
$uploadedFile = $this->upload->uploadFile($model);
/** @var Model3DInterface $newModel */
$newModel = $this->modelFactory->create();
$newModel->setFile($uploadedFile['name']);
$newModel->setUrl($uploadedFile['file']);
$newModel->setProductId($product->getId());
$this->modelRepository->save($newModel);
}
}
}
<?php declare(strict_types=1);
namespace Scandi\Product3DGraphQl\Ui\DataProvider\Product\Form\Modifier;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Registry;
use Magento\Ui\Component\Form\Fieldset;
use Scandi\Product3DGraphQl\Helper\Model3DProvider;
use Scandi\Product3DGraphQl\Model\Model3D;
class ProductModels extends AbstractModifier
{
/** @var Registry */
protected $registry;
/** @var Model3DProvider */
protected $model3dProvider;
/**
* ProductDownloads constructor.
* @param Registry $registry
* @param Model3DProvider $model3dProvider
*/
public function __construct(Registry $registry, Model3DProvider $model3dProvider)
{
$this->registry = $registry;
$this->model3dProvider = $model3dProvider;
}
public function modifyMeta(array $meta)
{
$meta['scandi_model3d'] = [
'arguments' => [
'data' => [
'config' => [
'label' => __('3D Models'),
'sortOrder' => 50,
'collapsible' => true,
'componentType' => Fieldset::NAME,
]
]
],
'children' => $this->getModelFields()
];
return $meta;
}
protected function getModelFields()
{
$fields = [];
/** @var Product $product */
$product = $this->registry->registry('current_product');
$models = $this->model3dProvider->getModelsForProductId($product->getId());
// check if this works. was models[i] before
$fields['scandi.models.new'] = [
'arguments' => [
'data' => [
'config' => [
'formElement' => 'file',
'dataScope' => 'scandi.models[]',
'componentType' => 'field',
'visible' => 1,
'required' => 0,
'label' => __('Add New 3D Model')
]
]
]
];
foreach ($models as $i => $model) {
$scope = sprintf("data.product.remove_model[%d]", $model->getId());
$fields[$scope] = [
'arguments' => [
'data' => [
'config' => [
'formElement' => 'checkbox',
'componentType' => 'field',
'description' => $model->getFile(),
'dataScope' => $scope,
'checked' => true,
'value' => true,
'visible' => 1,
'required' => 0,
'label' => __('File: %1', $model->getFile()),
'comment' => $this->getFileLink($model)
]
]
]
];
}
return $fields;
}
protected function getFileLink(Model3D $model)
{
return sprintf(
'<a href="%s" target="_blank">%s</a>',
$model->getResourceUrl(), $model->getFile()
);
}
/**
* {@inheritdoc}
*/
public function modifyData(array $data)
{
return $data;
}
}
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="productDownloads" xsi:type="array">
<item name="class" xsi:type="string">Scandi\Product3DGraphQl\Ui\DataProvider\Product\Form\Modifier\ProductModels</item>
<item name="sortOrder" xsi:type="number">20</item>
</item>
</argument>
</arguments>
</virtualType>
</config>
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_product_save_after">
<observer name="scandi_product_model_save" instance="Scandi\Product3DGraphQl\Observer\Product\Save"/>
</event>
</config>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment