Skip to content
Open
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
124 changes: 10 additions & 114 deletions core/components/minishop3/config/routes/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,128 +174,24 @@

$router->group('/extra-fields', function($router) use ($modx) {
$router->get('', function($params) use ($modx) {
try {
/** @var \MiniShop3\Services\ExtraFieldsService $service */
$service = new \MiniShop3\Services\ExtraFieldsService($modx);

$class = $_GET['class'] ?? null;
$criteria = $class ? ['class' => $class] : [];

$fields = $service->getFields($criteria);

return Response::success([
'fields' => $fields,
'total' => count($fields)
]);
} catch (\Exception $e) {
$modx->log(\MODX\Revolution\modX::LOG_LEVEL_ERROR, '[ExtraFields API] ' . $e->getMessage());
return Response::error('Failed to load extra fields: ' . $e->getMessage(), HttpStatus::INTERNAL_SERVER_ERROR);
}
$controller = new \MiniShop3\Controllers\Api\Manager\ExtraFieldsController($modx);
return $controller->getList(array_merge($_GET, $params));
});
$router->get('/{id}', function($params) use ($modx) {
$id = (int)($params['id'] ?? 0);

if (!$id) {
return Response::error('Field ID is required', HttpStatus::BAD_REQUEST);
}

$field = $modx->getObject(\MiniShop3\Model\msExtraField::class, $id);

if (!$field) {
return Response::error('Field not found', HttpStatus::NOT_FOUND);
}

$data = $field->toArray();

$extraFieldsUtil = new \MiniShop3\Utils\ExtraFields($modx);
$data['column_exists'] = $extraFieldsUtil->columnExists($field->get('class'), $field->get('key'));

return Response::success(['field' => $data]);
$controller = new \MiniShop3\Controllers\Api\Manager\ExtraFieldsController($modx);
return $controller->get($params);
});
$router->post('', function($params) use ($modx) {
try {
$data = json_decode(file_get_contents('php://input'), true);

if (empty($data)) {
return Response::error('Request body is empty', HttpStatus::BAD_REQUEST);
}

/** @var \MiniShop3\Services\ExtraFieldsService $service */
$service = new \MiniShop3\Services\ExtraFieldsService($modx);

$result = $service->createField($data);

if (!$result['success']) {
return Response::error($result['message'], HttpStatus::BAD_REQUEST);
}

return Response::success([
'message' => $result['message'],
'field' => $result['data'],
'migration' => $result['migration']
]);
} catch (\Exception $e) {
$modx->log(\MODX\Revolution\modX::LOG_LEVEL_ERROR, '[ExtraFields API] ' . $e->getMessage());
return Response::error('Failed to create field: ' . $e->getMessage(), HttpStatus::INTERNAL_SERVER_ERROR);
}
$controller = new \MiniShop3\Controllers\Api\Manager\ExtraFieldsController($modx);
return $controller->create();
});
$router->put('/{id}', function($params) use ($modx) {
$id = (int)($params['id'] ?? 0);

if (!$id) {
return Response::error('Field ID is required', HttpStatus::BAD_REQUEST);
}

try {
$data = json_decode(file_get_contents('php://input'), true);

if (empty($data)) {
return Response::error('Request body is empty', HttpStatus::BAD_REQUEST);
}

/** @var \MiniShop3\Services\ExtraFieldsService $service */
$service = new \MiniShop3\Services\ExtraFieldsService($modx);

$result = $service->updateField($id, $data);

if (!$result['success']) {
return Response::error($result['message'], HttpStatus::BAD_REQUEST);
}

return Response::success([
'message' => $result['message'],
'field' => $result['data']
]);
} catch (\Exception $e) {
$modx->log(\MODX\Revolution\modX::LOG_LEVEL_ERROR, '[ExtraFields API] ' . $e->getMessage());
return Response::error('Failed to update field: ' . $e->getMessage(), HttpStatus::INTERNAL_SERVER_ERROR);
}
$controller = new \MiniShop3\Controllers\Api\Manager\ExtraFieldsController($modx);
return $controller->update($params);
});
$router->delete('/{id}', function($params) use ($modx) {
$id = (int)($params['id'] ?? 0);

if (!$id) {
return Response::error('Field ID is required', HttpStatus::BAD_REQUEST);
}

try {
/** @var \MiniShop3\Services\ExtraFieldsService $service */
$service = new \MiniShop3\Services\ExtraFieldsService($modx);

$result = $service->deleteField($id);

if (!$result['success']) {
return Response::error($result['message'], HttpStatus::BAD_REQUEST);
}

return Response::success([
'message' => $result['message'],
'migration' => $result['migration']
]);
} catch (\Exception $e) {
$modx->log(\MODX\Revolution\modX::LOG_LEVEL_ERROR, '[ExtraFields API] ' . $e->getMessage());
return Response::error('Failed to delete field: ' . $e->getMessage(), HttpStatus::INTERNAL_SERVER_ERROR);
}
$controller = new \MiniShop3\Controllers\Api\Manager\ExtraFieldsController($modx);
return $controller->delete($params);
});

}, [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
<?php

namespace MiniShop3\Controllers\Api\Manager;

use MiniShop3\Router\HttpStatus;
use MiniShop3\Router\Response;
use MiniShop3\Services\ExtraFieldsService;
use MODX\Revolution\modX;

/**
* Manager API for extra-fields CRUD (Vue ExtraFieldsManager).
*
* @package MiniShop3\Controllers\Api\Manager
*/
class ExtraFieldsController
{
protected modX $modx;

protected ExtraFieldsService $service;

public function __construct(modX $modx)
{
$this->modx = $modx;
/** @var ExtraFieldsService $service */
$service = $modx->services->get('ms3_extra_fields');
$this->service = $service;
}

/**
* GET /api/mgr/extra-fields
*/
public function getList(array $params = []): array
{
try {
$class = $params['class'] ?? null;
$criteria = $class ? ['class' => $class] : [];
$fields = $this->service->getFields($criteria);

return Response::success([
'fields' => $fields,
'total' => count($fields),
])->getData();
} catch (\Exception $e) {
$this->logError($e);

return Response::error(
'Failed to load extra fields: ' . $e->getMessage(),
HttpStatus::INTERNAL_SERVER_ERROR
)->getData();
}
}

/**
* GET /api/mgr/extra-fields/{id}
*/
public function get(array $params = []): array
{
$id = (int)($params['id'] ?? 0);

if (!$id) {
return Response::error('Field ID is required', HttpStatus::BAD_REQUEST)->getData();
}

$field = $this->service->getField($id);

if ($field === null) {
return Response::error('Field not found', HttpStatus::NOT_FOUND)->getData();
}

return Response::success(['field' => $field])->getData();
}

/**
* POST /api/mgr/extra-fields
*/
public function create(): array
{
try {
$data = $this->readJsonBody();

if ($data === []) {
return Response::error('Request body is empty', HttpStatus::BAD_REQUEST)->getData();
}

$result = $this->service->createField($data);

if (!$result['success']) {
return Response::error($result['message'], HttpStatus::BAD_REQUEST)->getData();
}

return Response::success([
'message' => $result['message'],
'field' => $result['data'],
'migration' => $result['migration'],
])->getData();
} catch (\Exception $e) {
$this->logError($e);

return Response::error(
'Failed to create field: ' . $e->getMessage(),
HttpStatus::INTERNAL_SERVER_ERROR
)->getData();
}
}

/**
* PUT /api/mgr/extra-fields/{id}
*/
public function update(array $params = []): array
{
$id = (int)($params['id'] ?? 0);

if (!$id) {
return Response::error('Field ID is required', HttpStatus::BAD_REQUEST)->getData();
}

try {
$data = $this->readJsonBody();

if ($data === []) {
return Response::error('Request body is empty', HttpStatus::BAD_REQUEST)->getData();
}

$result = $this->service->updateField($id, $data);

if (!$result['success']) {
return Response::error($result['message'], HttpStatus::BAD_REQUEST)->getData();
}

return Response::success([
'message' => $result['message'],
'field' => $result['data'],
])->getData();
} catch (\Exception $e) {
$this->logError($e);

return Response::error(
'Failed to update field: ' . $e->getMessage(),
HttpStatus::INTERNAL_SERVER_ERROR
)->getData();
}
}

/**
* DELETE /api/mgr/extra-fields/{id}
*/
public function delete(array $params = []): array
{
$id = (int)($params['id'] ?? 0);

if (!$id) {
return Response::error('Field ID is required', HttpStatus::BAD_REQUEST)->getData();
}

try {
$result = $this->service->deleteField($id);

if (!$result['success']) {
return Response::error($result['message'], HttpStatus::BAD_REQUEST)->getData();
}

return Response::success([
'message' => $result['message'],
'migration' => $result['migration'],
])->getData();
} catch (\Exception $e) {
$this->logError($e);

return Response::error(
'Failed to delete field: ' . $e->getMessage(),
HttpStatus::INTERNAL_SERVER_ERROR
)->getData();
}
}

/**
* @return array<string, mixed>
*/
private function readJsonBody(): array
{
$data = json_decode(file_get_contents('php://input'), true);

return is_array($data) ? $data : [];
}

private function logError(\Exception $e): void
{
$this->modx->log(modX::LOG_LEVEL_ERROR, '[ExtraFields API] ' . $e->getMessage());
}
}
4 changes: 4 additions & 0 deletions core/components/minishop3/src/ServiceRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class ServiceRegistry
'class' => \MiniShop3\Services\ExtraFields\RepeaterFieldService::class,
'interface' => null,
],
'ms3_extra_fields' => [
'class' => \MiniShop3\Services\ExtraFieldsService::class,
'interface' => null,
],
'ms3_product_image' => [
'class' => \MiniShop3\Services\Product\ProductImageService::class,
'interface' => null,
Expand Down
39 changes: 32 additions & 7 deletions core/components/minishop3/src/Services/ExtraFieldsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,42 @@ public function getFields(array $criteria = []): array

$result = [];
foreach ($fields as $field) {
$data = $field->toArray();
$result[] = $this->formatField($field);
}

$data['column_exists'] = $this->extraFieldsUtil->columnExists(
$field->get('class'),
$field->get('key')
);
return $result;
}

/**
* Get single extra field by ID (with column_exists flag).
*
* @return array<string, mixed>|null
*/
public function getField(int $id): ?array
{
/** @var msExtraField|null $field */
$field = $this->modx->getObject(msExtraField::class, $id);

$result[] = $data;
if (!$field) {
return null;
}

return $result;
return $this->formatField($field);
}

/**
* @return array<string, mixed>
*/
private function formatField(msExtraField $field): array
{
$data = $field->toArray();

$data['column_exists'] = $this->extraFieldsUtil->columnExists(
$field->get('class'),
$field->get('key')
);

return $data;
}

/**
Expand Down
Loading