Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .jeeves.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Mygento:
unsigned: true
default: 0
source: 'Mygento\Navigation\Model\Source\EntityType'
entity_slug:
entity_identifier:
type: varchar
nullable: true
comment: 'Link Identifier'
Expand Down
10 changes: 5 additions & 5 deletions Api/Data/ItemInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface ItemInterface
public const IS_ACTIVE = 'is_active';
public const NAME = 'name';
public const ENTITY_TYPE = 'entity_type';
public const ENTITY_SLUG = 'entity_slug';
public const ENTITY_IDENTIFIER = 'entity_identifier';
public const SORT_ORDER = 'sort_order';
public const STORE_ID = 'store_id';

Expand Down Expand Up @@ -71,14 +71,14 @@ public function getEntityType(): string;
public function setEntityType(string $entityType): self;

/**
* Get entity slug
* Get entity identifier
*/
public function getEntitySlug(): ?string;
public function getEntityIdentifier(): ?string;

/**
* Set entity slug
* Set entity identifier
*/
public function setEntitySlug(?string $entitySlug): self;
public function setEntityIdentifier(?string $entityIdentifier): self;

/**
* Get sort order
Expand Down
8 changes: 8 additions & 0 deletions Api/MenuRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ public function save(Data\MenuInterface $entity): Data\MenuInterface;
*/
public function getById(int $entityId): Data\MenuInterface;

/**
* Retrieve menu by code
*
* @throws \Magento\Framework\Exception\LocalizedException
* @return \Mygento\Navigation\Api\Data\MenuInterface
*/
public function getByCode(string $code): Data\MenuInterface;

/**
* Retrieve Menu entities matching the specified criteria
* @throws \Magento\Framework\Exception\LocalizedException
Expand Down
33 changes: 33 additions & 0 deletions Controller/Adminhtml/Item/Save.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Registry;
use Mygento\Base\Model\ImageUploader;
use Mygento\Navigation\Api\Data\ItemInterfaceFactory;
use Mygento\Navigation\Api\ItemRepositoryInterface;
use Mygento\Navigation\Controller\Adminhtml\Item;
Expand All @@ -23,6 +24,7 @@ class Save extends Item
public function __construct(
private readonly DataPersistorInterface $dataPersistor,
private readonly ItemInterfaceFactory $entityFactory,
private ImageUploader $imageUploader,
ItemRepositoryInterface $repository,
Registry $coreRegistry,
Context $context,
Expand Down Expand Up @@ -63,6 +65,16 @@ public function execute(): ResultInterface
$data['entity_id'] = null;
}
$entity->setData($data);
$entity->setImage($this->processImage($data, 'image') ?? '');

if (empty($data['entity_identifier'])) {
$this->messageManager->addErrorMessage(
__('The Entity Identifier is required. Please assign an entity.')->render(),
);
$this->dataPersistor->set('navigation_item', $data);

return $resultRedirect->setPath('*/*/edit', ['id' => $entity->getId()]);
}

try {
$this->repository->save($entity);
Expand All @@ -87,4 +99,25 @@ public function execute(): ResultInterface

return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
}

private function processImage(array $data, string $key): ?string
{
$value = $data[$key] ?? null;
if (!$value) {
return null;
}
if (!is_array($value)) {
return null;
}
$imageName = $value['0']['name'] ?? null;
if (!$imageName) {
return null;
}
if ($imageName && !isset($value[0]['tmp_name'])) {
return $imageName;
}

return $this->imageUploader->getBasePath()
. '/' . $this->imageUploader->moveFileFromTmp($imageName);
}
}
38 changes: 38 additions & 0 deletions Controller/Adminhtml/Item/Upload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/**
* @author Mygento Team
* @copyright 2023-2026 Mygento (https://www.mygento.com)
* @package Mygento_Navigation
*/

namespace Mygento\Navigation\Controller\Adminhtml\Item;

use Magento\Backend\App\Action;
use Magento\Framework\Controller\Result\Json;
use Magento\Framework\Controller\Result\JsonFactory;
use Mygento\Base\Model\ImageUploader;

class Upload extends \Magento\Backend\App\Action
{
public function __construct(
private ImageUploader $imageUploader,
private JsonFactory $resultJsonFactory,
Action\Context $context,
) {
parent::__construct($context);
}

public function execute(): Json
{
$imageId = $this->_request->getParam('param_name', 'image');

try {
$result = $this->imageUploader->saveFileToTmpDir($imageId);
} catch (\Exception $e) {
$result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
}

return $this->resultJsonFactory->create()->setData($result);
}
}
26 changes: 26 additions & 0 deletions Model/Builder/CustomLink.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* @author Mygento Team
* @copyright 2023-2026 Mygento (https://www.mygento.com)
* @package Mygento_Navigation
*/

declare(strict_types=1);

namespace Mygento\Navigation\Model\Builder;

class CustomLink implements DataBuilderInterface
{
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function addData(array $items, array $entityIds, int $storeId): array
{
foreach ($items as &$item) {
$item['link'] = $item['entity_identifier'] ?? null;
}

return $items;
}
}
16 changes: 16 additions & 0 deletions Model/Builder/DataBuilderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* @author Mygento Team
* @copyright 2023-2026 Mygento (https://www.mygento.com)
* @package Mygento_Navigation
*/

declare(strict_types=1);

namespace Mygento\Navigation\Model\Builder;

interface DataBuilderInterface
{
public function addData(array $items, array $entityIds, int $storeId): array;
}
63 changes: 63 additions & 0 deletions Model/Builder/LinkBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/**
* @author Mygento Team
* @copyright 2023-2026 Mygento (https://www.mygento.com)
* @package Mygento_Navigation
*/

declare(strict_types=1);

namespace Mygento\Navigation\Model\Builder;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\UrlInterface;

class LinkBuilder implements DataBuilderInterface
{
private const TABLE_URL_REWRITE = 'url_rewrite';

public function __construct(
private ResourceConnection $resourceConnection,
private UrlInterface $urlBuilder,
private string $urlRewriteEntityType,
private string $targetPathPattern,
) {}

public function addData(array $items, array $entityIds, int $storeId): array
{
$requestPaths = $this->getRequestPaths($entityIds, $storeId);
foreach ($items as &$item) {
$entityId = (int) ($item['entity_identifier'] ?? 0);
$path = $requestPaths[$entityId] ?? sprintf($this->targetPathPattern, $entityId);
$item['link'] = $this->urlBuilder->getDirectUrl($path, ['_scope' => $storeId]);
}
unset($item);

return $items;
}

private function getRequestPaths(array $entityIds, int $storeId): array
{
$ids = array_map('intval', $entityIds);
if (!$ids) {
return [];
}

$connection = $this->resourceConnection->getConnection();
$select = $connection->select()
->from(
['ur' => $this->resourceConnection->getTableName(self::TABLE_URL_REWRITE)],
['entity_id', 'request_path'],
)
->where('ur.entity_type = ?', $this->urlRewriteEntityType)
->where('ur.store_id = ?', $storeId)
->where('ur.redirect_type = ?', 0)
->where('ur.is_autogenerated = ?', 1)
->where('ur.metadata IS NULL')
->where('ur.entity_id IN (?)', $ids)
->order('ur.url_rewrite_id ASC');

return $connection->fetchPairs($select);
}
}
49 changes: 49 additions & 0 deletions Model/EntityLabelResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/**
* @author Mygento Team
* @copyright 2023-2026 Mygento (https://www.mygento.com)
* @package Mygento_Navigation
*/

namespace Mygento\Navigation\Model;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Cms\Api\BlockRepositoryInterface;
use Magento\Cms\Api\PageRepositoryInterface;
use Magento\Framework\Exception\LocalizedException;

class EntityLabelResolver
{
public function __construct(
private PageRepositoryInterface $pageRepository,
private BlockRepositoryInterface $blockRepository,
private ProductRepositoryInterface $productRepository,
) {}

public function resolve(string $entityType, ?string $entityId): ?string
{
try {
return match ($entityType) {
'cms_page' => sprintf(
'[Page ID: %d] %s',
$entityId,
$this->pageRepository->getById($entityId)->getTitle(),
),
'cms_block' => sprintf(
'[Block ID: %d] %s',
$entityId,
$this->blockRepository->getById($entityId)->getTitle(),
),
'catalog_product' => sprintf(
'[Product ID: %d] %s',
$entityId,
$this->productRepository->getById($entityId)->getName(),
),
default => null,
};
} catch (LocalizedException $e) {
return null;
}
}
}
81 changes: 81 additions & 0 deletions Model/FileInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/**
* @author Mygento Team
* @copyright 2023-2026 Mygento (https://www.mygento.com)
* @package Mygento_Navigation
*/

namespace Mygento\Navigation\Model;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\File\Mime;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\Filesystem\ExtendedDriverInterface;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\StoreManagerInterface;

class FileInfo
{
private ?WriteInterface $mediaDirectory = null;

public function __construct(
private Filesystem $filesystem,
private Mime $mime,
private StoreManagerInterface $storeManager,
) {}

public function getUrl(string $fileName): string
{
$mediaBaseUrl = $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);

return rtrim($mediaBaseUrl, '/') . '/' . $fileName;
}

public function getMediaUrl(string $fileName): string
{
return '/' . UrlInterface::URL_TYPE_MEDIA . '/' . $fileName;
}

public function isExist(string $fileName): bool
{
$filePath = $this->getFilePath($fileName);

return $this->getMediaDirectory()->isExist($filePath);
}

public function getStat($fileName): array
{
$filePath = $this->getFilePath($fileName);

return $this->getMediaDirectory()->stat($filePath);
}

public function getMimeType($fileName)
{
if ($this->getMediaDirectory()->getDriver() instanceof ExtendedDriverInterface) {
return $this->mediaDirectory->getDriver()->getMetadata($fileName)['mimetype'];
}

return $this->mime->getMimeType(
$this->getMediaDirectory()->getAbsolutePath(
$this->getFilePath($fileName),
),
);
}

private function getFilePath(string $fileName): string
{
return ltrim($fileName, '/');
}

private function getMediaDirectory(): WriteInterface
{
if ($this->mediaDirectory === null) {
$this->mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
}

return $this->mediaDirectory;
}
}
Loading
Loading