开发Prestashop类CRM集成模块:如何创建REST端点?
Got it, let's break down how to implement robust REST endpoints for your Prestashop module that plays nicely with your Vue.js frontend. I've worked on similar CRM integrations with Prestashop, so here's a practical, Prestashop-native approach tailored to your needs:
Prestashop has a built-in routing mechanism for modules, so you don't need to hack together custom URL handling. This will naturally fit your {baseUrl}/mymodule/actionname pattern.
First, register your routes in your module's main file (e.g., mymodule.php) using the moduleRoutes hook:
public function install() { return parent::install() && $this->registerHook('moduleRoutes'); } public function hookModuleRoutes() { return [ // Auth routes (login/register) 'module-mymodule-auth-login' => [ 'controller' => 'auth', 'rule' => 'mymodule/login', 'params' => ['fc' => 'module', 'module' => 'mymodule', 'controller' => 'auth'] ], 'module-mymodule-auth-register' => [ 'controller' => 'auth', 'rule' => 'mymodule/register', 'params' => ['fc' => 'module', 'module' => 'mymodule', 'controller' => 'auth'] ], // Customer/Order export routes 'module-mymodule-customers-export' => [ 'controller' => 'customers', 'rule' => 'mymodule/customers/export', 'params' => ['fc' => 'module', 'module' => 'mymodule', 'controller' => 'customers'] ], 'module-mymodule-orders-export' => [ 'controller' => 'orders', 'rule' => 'mymodule/orders/export', 'params' => ['fc' => 'module', 'module' => 'mymodule', 'controller' => 'orders'] ], // Settings route 'module-mymodule-settings-save' => [ 'controller' => 'settings', 'rule' => 'mymodule/save-settings', 'params' => ['fc' => 'module', 'module' => 'mymodule', 'controller' => 'settings'] ] ]; }
Each route maps to a controller file in your module's controllers/front/ directory (e.g., auth.php, customers.php).
Your controllers need to handle GET/POST requests, skip Prestashop's default template rendering, and return clean JSON responses for Vue. Here's an example Auth controller:
// controllers/front/auth.php class MyModuleAuthModuleFrontController extends ModuleFrontController { public function initContent() { parent::initContent(); $this->setTemplate(false); // Disable Prestashop's template output $requestMethod = $_SERVER['REQUEST_METHOD']; $action = $this->getActionFromRoute(); // Or use Tools::getValue('action') if you prefer switch ($action) { case 'login': $requestMethod === 'POST' ? $this->handleLogin() : $this->returnMethodNotAllowed(); break; case 'register': $requestMethod === 'POST' ? $this->handleRegister() : $this->returnMethodNotAllowed(); break; default: $this->returnJson(['status' => 'error', 'message' => 'Invalid action'], 400); } } private function handleLogin() { $email = Tools::getValue('email'); $password = Tools::getValue('password'); // Use Prestashop's native customer auth $customer = new Customer(); $authSuccess = $customer->getByEmail($email, $password); if ($authSuccess) { $this->returnJson([ 'status' => 'success', 'data' => [ 'id' => $customer->id, 'email' => $customer->email, 'firstname' => $customer->firstname ] ]); } else { $this->returnJson(['status' => 'error', 'message' => 'Invalid credentials'], 401); } } // Helper methods for consistent responses private function returnJson($data, $statusCode = 200) { http_response_code($statusCode); header('Content-Type: application/json'); echo json_encode($data); exit; } private function returnMethodNotAllowed() { $this->returnJson(['status' => 'error', 'message' => 'Method not allowed'], 405); } private function getActionFromRoute() { // Extract action from the request URI (e.g., /mymodule/login -> 'login') $uriParts = explode('/', $_SERVER['REQUEST_URI']); return end($uriParts); } }
For export controllers (customers/orders), you'd write similar logic to fetch data using Prestashop's ORM (e.g., Customer::getCustomers() or Order::getOrders()) and return it as JSON.
Your hooks for customer sync, cart, and order events can directly trigger CRM sync logic, or you can expose a REST endpoint to trigger sync manually (for your Vue frontend):
// In mymodule.php public function hookActionCustomerAdd($params) { $newCustomer = $params['newCustomer']; $this->syncCustomerToCRM($newCustomer); } private function syncCustomerToCRM(Customer $customer) { // Format customer data to match your CRM's API schema $crmPayload = [ 'external_id' => $customer->id, 'email' => $customer->email, 'name' => $customer->firstname . ' ' . $customer->lastname, 'created_at' => $customer->date_add ]; // Send to CRM (use Prestashop's Tools::file_get_contents() or Guzzle if you install it) $crmResponse = Tools::file_get_contents( 'your-crm-api-url/customers', false, stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => json_encode($crmPayload) ] ]) ); // Log success/failure for debugging if (!$crmResponse) { PrestaShopLogger::addLog( "Failed to sync customer #{$customer->id} to CRM", 3, // Error level null, 'MyModule' ); } }
To let Vue trigger manual sync, add a handleSyncCustomers() method in your Customers controller that loops through customers and calls syncCustomerToCRM().
Make your Vue API calls clean and consistent, and handle Prestashop's CSRF protection:
// src/utils/api.js const csrfToken = document.querySelector('meta[name="csrf-token"]').content; const baseUrl = `${window.location.origin}/mymodule`; export const apiClient = { async request(method, endpoint, data = {}) { const options = { method: method.toUpperCase(), headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken } }; if (method !== 'GET') { options.body = JSON.stringify(data); } const response = await fetch(`${baseUrl}/${endpoint}`, options); return await response.json(); }, // Example methods login(email, password) { return this.request('POST', 'login', { email, password }); }, exportCustomers() { return this.request('GET', 'customers/export'); }, saveSettings(settings) { return this.request('POST', 'save-settings', settings); } };
Use this client in your Vue components to make requests and handle responses (e.g., show success/error messages).
- Authentication: For protected endpoints (like exports, settings), verify the user is logged in:
If you need admin-only endpoints, checkif (!Context::getContext()->customer->isLogged()) { $this->returnJson(['status' => 'error', 'message' => 'Unauthorized'], 401); }Context::getContext()->employee->isLogged()instead. - Input Validation: Always sanitize inputs with
Tools::getValue()and validate data (e.g., email format, required fields) to prevent SQL injection/XSS. - Rate Limiting: Add basic rate limiting (e.g., track IP requests in the database) to prevent abuse.
- Logging: Use
PrestaShopLoggerto track API requests, errors, and sync events for debugging.
内容的提问来源于stack exchange,提问作者maciey_b

