init
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Esun\MultiLocaleTranslation\Model\Config\Backend;
|
||||
|
||||
use Magento\Config\Model\Config\Backend\File;
|
||||
use Magento\Framework\App\Filesystem\DirectoryList;
|
||||
use Magento\Framework\Exception\LocalizedException;
|
||||
use Magento\Framework\Filesystem;
|
||||
use Magento\Framework\Filesystem\DriverInterface;
|
||||
|
||||
class ServiceAccountFile extends File
|
||||
{
|
||||
private const REQUIRED_FIELDS = ['type', 'project_id', 'private_key', 'client_email'];
|
||||
|
||||
private string $oldCredentialFile = '';
|
||||
private string $credentialFileToDelete = '';
|
||||
|
||||
public function __construct(
|
||||
\Magento\Framework\Model\Context $context,
|
||||
\Magento\Framework\Registry $registry,
|
||||
\Magento\Framework\App\Config\ScopeConfigInterface $config,
|
||||
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
|
||||
\Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
|
||||
\Magento\Config\Model\Config\Backend\File\RequestData\RequestDataInterface $requestData,
|
||||
Filesystem $filesystem,
|
||||
private readonly DriverInterface $fileDriver,
|
||||
?\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
|
||||
?\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
|
||||
array $data = []
|
||||
) {
|
||||
parent::__construct(
|
||||
$context,
|
||||
$registry,
|
||||
$config,
|
||||
$cacheTypeList,
|
||||
$uploaderFactory,
|
||||
$requestData,
|
||||
$filesystem,
|
||||
$resource,
|
||||
$resourceCollection,
|
||||
$data
|
||||
);
|
||||
$this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
|
||||
$this->_maxFileSize = 64;
|
||||
}
|
||||
|
||||
public function beforeSave(): static
|
||||
{
|
||||
$this->oldCredentialFile = basename((string)$this->getOldValue());
|
||||
$file = $this->getFileData();
|
||||
$deleteRequested = is_array($this->getValue()) && !empty($this->getValue()['delete']);
|
||||
|
||||
if ($file !== []) {
|
||||
$this->validateServiceAccountFile((string)$file['tmp_name']);
|
||||
}
|
||||
|
||||
parent::beforeSave();
|
||||
|
||||
$newFile = basename((string)$this->getValue());
|
||||
if ($file !== [] && $newFile !== '') {
|
||||
$this->fileDriver->changePermissions($this->getCredentialPath($newFile), 0600);
|
||||
}
|
||||
|
||||
if ($this->oldCredentialFile !== ''
|
||||
&& ($deleteRequested || ($newFile !== '' && $newFile !== $this->oldCredentialFile))
|
||||
) {
|
||||
$this->credentialFileToDelete = $this->oldCredentialFile;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function afterSave(): static
|
||||
{
|
||||
parent::afterSave();
|
||||
|
||||
if ($this->credentialFileToDelete !== '') {
|
||||
$oldPath = $this->getCredentialPath($this->credentialFileToDelete);
|
||||
if ($this->fileDriver->isExists($oldPath)) {
|
||||
$this->fileDriver->deleteFile($oldPath);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function _getAllowedExtensions(): array
|
||||
{
|
||||
return ['json'];
|
||||
}
|
||||
|
||||
private function validateServiceAccountFile(string $path): void
|
||||
{
|
||||
try {
|
||||
$credentials = json_decode(
|
||||
$this->fileDriver->fileGetContents($path),
|
||||
true,
|
||||
32,
|
||||
JSON_THROW_ON_ERROR
|
||||
);
|
||||
} catch (\Throwable $exception) {
|
||||
throw new LocalizedException(__('The service account JSON file is invalid.'));
|
||||
}
|
||||
|
||||
if (!is_array($credentials) || ($credentials['type'] ?? '') !== 'service_account') {
|
||||
throw new LocalizedException(__('The uploaded JSON is not a Google service account key.'));
|
||||
}
|
||||
foreach (self::REQUIRED_FIELDS as $field) {
|
||||
if (!is_string($credentials[$field] ?? null) || trim($credentials[$field]) === '') {
|
||||
throw new LocalizedException(__('The service account JSON is missing "%1".', $field));
|
||||
}
|
||||
}
|
||||
|
||||
$privateKey = openssl_pkey_get_private($credentials['private_key']);
|
||||
if ($privateKey === false) {
|
||||
throw new LocalizedException(__('The service account private key is invalid.'));
|
||||
}
|
||||
}
|
||||
|
||||
private function getCredentialPath(string $filename): string
|
||||
{
|
||||
return $this->_mediaDirectory->getAbsolutePath(
|
||||
'esun/multilocale_translation/google/' . basename($filename)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user