Skip to content

Commit

Permalink
ref: FileStructurePushCommand is now using EMS Archive
Browse files Browse the repository at this point in the history
  • Loading branch information
theus77 committed Oct 13, 2024
1 parent 5d75156 commit efe6d0f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,127 +6,58 @@

use EMS\CommonBundle\Commands;
use EMS\CommonBundle\Common\Admin\AdminHelper;
use EMS\CommonBundle\Common\PropertyAccess\PropertyAccessor;
use EMS\CommonBundle\Common\Command\AbstractCommand;
use EMS\CommonBundle\Contracts\CoreApi\CoreApiInterface;
use EMS\CommonBundle\Helper\EmsFields;
use EMS\CommonBundle\Json\JsonMenuNested;
use EMS\CommonBundle\Service\ElasticaService;
use EMS\Helpers\File\File as FileHelper;
use EMS\CommonBundle\Storage\Archive;
use EMS\Helpers\Html\MimeTypes;
use EMS\Helpers\Standard\Json;
use EMS\Helpers\Standard\Type;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;

class FileStructurePushCommand extends AbstractFileStructureCommand
class FileStructurePushCommand extends AbstractCommand
{
protected static $defaultName = Commands::FILE_STRUCTURE_PUSH;
private const ARGUMENT_FOLDER = 'folder';
private const OPTION_CONTENT_TYPE = 'content-type';
private string $folderPath;
private string $contentType;
private CoreApiInterface $coreApi;

public function __construct(ElasticaService $elasticaService, private readonly AdminHelper $adminHelper)
public function __construct(private readonly AdminHelper $adminHelper)
{
parent::__construct($elasticaService);
parent::__construct();
}

protected function configure(): void
{
parent::configure();
$this->setDescription('Push a JSON encoded file structure into a folder (and overwrite it)');
$this->addArgument(self::ARGUMENT_FOLDER, InputArgument::REQUIRED, 'Target folder');
$this
->addOption(self::OPTION_CONTENT_TYPE, null, InputOption::VALUE_OPTIONAL, 'Content type name', 'directory')
;
$this->setDescription('Push an EMS Archive file structure into a EMS Admin storage services (via the API)');
$this->addArgument(self::ARGUMENT_FOLDER, InputArgument::REQUIRED, 'Source folder');
}

protected function initialize(InputInterface $input, OutputInterface $output): void
{
parent::initialize($input, $output);
$this->folderPath = $this->getArgumentString(self::ARGUMENT_FOLDER);
$this->contentType = $this->getOptionString(self::OPTION_CONTENT_TYPE);
$this->coreApi = $this->adminHelper->getCoreApi();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$defaultAlias = $this->coreApi->meta()->getDefaultContentTypeEnvironmentAlias($this->contentType);
$document = $this->getDocument($defaultAlias);
if (null === $document) {
return self::EXECUTE_ERROR;
}
$propertyAccessor = PropertyAccessor::createPropertyAccessor();
$structureJson = Type::string($propertyAccessor->getValue($document->getData(), "[$this->structureField]"));
$structure = JsonMenuNested::fromStructure($structureJson);
$filesystem = new Filesystem();
foreach ($structure->getIterator() as $item) {
$path = \implode('/', $item->getPath(fn (JsonMenuNested $item) => $item->getLabel()));
$relativePath = \implode('/', [$this->folderPath, $path]);
if ($filesystem->exists($relativePath) && (\is_dir($relativePath) || 'folder' !== $item->getType())) {
continue;
}
$parent = $$item->getParent();
if (null === $parent) {
throw new \RuntimeException(\sprintf('Parent not found for %s', $path));
}
$parent->removeChild($item);
}
$finder = new Finder();
$finder->in($this->folderPath);
foreach ($finder as $key => $file) {
if (\is_file($key)) {
$fileHelper = FileHelper::fromFilename($key);
$mimeType ??= $fileHelper->mimeType;
$filename ??= $fileHelper->name;
$hash = $this->coreApi->file()->uploadFile($key, $mimeType, $filename);
$type = 'file';
$data = [
'file' => [
EmsFields::CONTENT_FILE_HASH_FIELD => $hash,
EmsFields::CONTENT_FILE_SIZE_FIELD => \filesize($key),
EmsFields::CONTENT_MIME_TYPE_FIELD => $mimeType,
EmsFields::CONTENT_FILE_NAME_FIELD => $file->getFilename(),
],
];
} elseif (\is_dir($key)) {
$type = 'folder';
$data = [];
} else {
continue;
}
$data['label'] = $file->getFilename();
$parent = null;
$current = null;
if ('' === $file->getRelativePath()) {
$parent = $structure;
}
foreach ($structure->getIterator() as $item) {
$path = \implode('/', $item->getPath(fn (JsonMenuNested $item) => $item->getLabel()));
if ($path === $file->getRelativePathname()) {
$current = $item;
}
if ($path === $file->getRelativePath()) {
$parent = $item;
}
}
if (null === $parent) {
throw new \RuntimeException(\sprintf('Parent item not found for %s', $key));
}
if (null === $current) {
$item = JsonMenuNested::create($type, $data);
$parent->addChild($item);
} else {
$current->setObject($data);
$algo = $this->coreApi->file()->getHashAlgo();
$archive = Archive::fromDirectory($this->folderPath, $algo);
$progressBar = $this->io->createProgressBar($archive->getCount());
foreach ($this->coreApi->file()->heads(...$archive->getHashes()) as $hash) {
$file = $archive->getFirstFileByHash($hash);
$uploadHash = $this->coreApi->file()->uploadFile($this->folderPath.DIRECTORY_SEPARATOR.$file->filename);
if ($uploadHash !== $hash) {
throw new \RuntimeException(\sprintf('Mismatched between the computed hash (%s) and the hash of the uploaded file (%s) for the file %s', $hash, $uploadHash, $file->filename));
}
$progressBar->advance();
}
$this->coreApi->data($this->contentType)->index($document->getId(), [
$this->structureField => Json::encode($structure->toArrayStructure()),
], true);
$progressBar->finish();
$hash = $this->coreApi->file()->uploadContents(Json::encode($archive), 'archive.json', MimeTypes::APPLICATION_JSON->value);
$this->io->newLine();
$this->io->success(\sprintf('Archive %s have been uploaded with the directory content of %s', $hash, $this->folderPath));

return self::EXECUTE_SUCCESS;
}
Expand Down
1 change: 0 additions & 1 deletion EMS/common-bundle/src/Resources/config/commands.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
<tag name="console.command" />
</service>
<service id="ems.command.file_structure.push" class="EMS\CommonBundle\Command\FileStructure\FileStructurePushCommand">
<argument type="service" id="EMS\CommonBundle\Service\ElasticaService"/>
<argument type="service" id="ems.helper.admin_api"/>
<tag name="console.command" />
</service>
Expand Down

0 comments on commit efe6d0f

Please sign in to comment.