🔧 Extender el WebService — recursos personalizados
Actualizado: 2024-12-01
PrestaShop permite exponer cualquier ObjectModel a traves de la API REST agregando la propiedad $webserviceParameters. Ademas se pueden agregar campos virtuales (calculados) al recurso.
#Exponer un ObjectModel via WebService
Agregar $webserviceParameters al ObjectModel
php
<?php
class MyModuleItem extends ObjectModel
{
public $name;
public $description;
public $active;
public $price;
public $date_add;
public static $definition = [
'table' => 'mymodule_item',
'primary' => 'id_mymodule_item',
'multilang' => true,
'fields' => [
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
'price' => ['type' => self::TYPE_FLOAT, 'validate' => 'isPrice'],
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
'name' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 255],
'description' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'],
],
];
// ── Exponer via WebService ──
protected $webserviceParameters = [
'objectsNodeName' => 'mymodule_items', // Nodo XML plural
'objectNodeName' => 'mymodule_item', // Nodo XML singular
'fields' => [
'id_mymodule_item' => [], // Campos extra a exponer
'active' => [],
'price' => [],
],
// Campos de asociaciones (relaciones N:N)
'associations' => [
'categories' => [
'resource' => 'category',
'fields' => ['id' => []],
],
],
];
}
#Agregar campos virtuales
Campos virtuales (calculados) en el recurso WS
php
<?php
// En el ObjectModel, agregar metodo getWsFieldName() para campos virtuales
// El metodo debe seguir el patron getWs{FieldName}()
class MyModuleItem extends ObjectModel
{
// ... (resto de la clase)
/**
* Campo virtual: precio con IVA (calculado en PHP, no en DB).
* Accesible como 'price_with_tax' en la API.
*/
public function getWsPriceWithTax(): float
{
$taxRate = 0.21; // IVA 21%
return round($this->price * (1 + $taxRate), 2);
}
/**
* Campo virtual: nombre completo del recurso.
*/
public function getWsFullName(): string
{
$lang = Context::getContext()->language->id;
return $this->name[$lang] ?? '';
}
protected $webserviceParameters = [
'objectsNodeName' => 'mymodule_items',
'objectNodeName' => 'mymodule_item',
'fields' => [
// Campos de la BD
'price' => ['sqlId' => 'price'],
'active' => ['sqlId' => 'active'],
// Campos virtuales (calculados)
'price_with_tax' => [
'getter' => 'getWsPriceWithTax',
'setter' => false, // Solo lectura
'sqlId' => false, // No hay columna en BD
],
'full_name' => [
'getter' => 'getWsFullName',
'setter' => false,
'sqlId' => false,
],
],
];
}
#Hook actionWebserviceResources
Registrar el recurso en el WebService via hook
php
<?php
// En mymodule.php
public function install(): bool
{
return parent::install()
&& $this->registerHook('addWebserviceResources');
}
/**
* Registra los nuevos recursos en el sistema WebService.
* Los recursos aparecen en Parametros Avanzados → WebService → Permisos.
*/
public function hookAddWebserviceResources(array $params): array
{
return [
'mymodule_items' => [
'description' => 'Items del modulo MyModule',
'class' => 'MyModuleItem',
'forbidden_method' => ['DELETE'], // Metodos prohibidos
],
];
}
// ── Despues de instalar el modulo, el recurso aparece en:
// Parametros Avanzados → WebService → Editar clave → Permisos
// y se puede acceder en:
// GET https://mitienda.com/api/mymodule_items
// GET https://mitienda.com/api/mymodule_items/42
// POST https://mitienda.com/api/mymodule_items
// PUT https://mitienda.com/api/mymodule_items/42
#Limitar acceso por IP o clave
Restringir acceso al WebService por IP
php
<?php
// ── Restriccion de IP en el BO ──
// Parametros Avanzados → WebService → Editar clave → IPs permitidas
// Dejar vacio para permitir cualquier IP
// ── Restriccion personalizada desde un modulo ──
public function install(): bool
{
return parent::install()
&& $this->registerHook('actionWebserviceCheckAuthentication');
}
public function hookActionWebserviceCheckAuthentication(array $params): void
{
// $params['authentication_key'] = la API key usada
// $params['request'] = objeto WebserviceRequest
$allowedIps = ['192.168.1.0/24', '10.0.0.5'];
$clientIp = $_SERVER['REMOTE_ADDR'] ?? '';
// Verificar si la IP esta en la lista blanca
$isAllowed = false;
foreach ($allowedIps as $ip) {
if ($ip === $clientIp || $this->ipInRange($clientIp, $ip)) {
$isAllowed = true;
break;
}
}
if (!$isAllowed) {
// Bloquear la peticion
header('HTTP/1.1 403 Forbidden');
die(json_encode(['error' => 'IP not allowed']));
}
}
private function ipInRange(string $ip, string $cidr): bool
{
if (strpos($cidr, '/') === false) {
return $ip === $cidr;
}
[$subnet, $mask] = explode('/', $cidr);
return (ip2long($ip) & ~((1 << (32 - $mask)) - 1)) === ip2long($subnet);
}
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.