Skip to main content

Joomla Custom API Routes for Components

Ας πούμε ότι το component σου λέγεται test.

1. Webservices Plugin

Path: plugins/webservices/test/test.php

class PlgWebservicesTest extends CMSPlugin
{
private $router;

public function onBeforeApiRoute(&$router)
{
$this->router = $router;

$router->createCRUDRoutes('v1/test/orders', 'orders', ['component' => 'com_test']);

// Custom route for fetching orders assigned to a specific driver
$this->createDriverOrdersRoute('v1/test/orders/driver', 'orders', ['component' => 'com_test']);
}

/**
* Create route for fetching orders assigned to a specific driver
*
* @param string $baseName The base route name
* @param string $controller The controller name
* @param array $defaults Default route parameters
*
* @return void
*
* @since 1.0.1
*/
private function createDriverOrdersRoute($baseName, $controller, $defaults)
{
$publicGets = false;
$getDefaults = array_merge(['public' => $publicGets], $defaults);

$routes = [
new Route(['GET'], $baseName . '/:id', $controller . '.getDriverOrders', ['id' => '(\d+)'], $getDefaults),
];

$this->router->addRoutes($routes);
}
}

Key Line

new Route(['GET'], $baseName . '/:id', $controller . '.getDriverOrders', ['id' => '(\d+)'], $getDefaults);
  • getDriverOrders είναι η συνάρτηση που καλείται από τον controller στο api/components/com_test/Controller/OrdersController.php.
  • Η default συνάρτηση για εμφάνιση λίστας είναι displayList — αν χρησιμοποιήσεις αυτή αντί για custom, θα φορτώσει ό,τι επιστρέφει η getListQuery του com_test/src/Model/OrdersModel.php.

2. API Controller (Χρήση Model Filter)

Path: api/components/com_test/Controller/OrdersController.php

namespace Test\Component\Test\Api\Controller;

\defined('_JEXEC') or die;

use Joomla\CMS\MVC\Controller\ApiController;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\Uri\Uri;
use Tobscure\JsonApi\Exception\InvalidParameterException;
use Joomla\CMS\Language\Text;

class OrdersController extends ApiController
{
protected $contentType = 'orders';
protected $default_view = 'orders';

/**
* Orders list view with filtering of data based on driver
*
* @return static A BaseController object to support filtering drivers.
*
* @since 4.0.0
* @throws InvalidParameterException
*/
public function getDriverOrders()
{
$filter = InputFilter::getInstance();

// Set filter for the model
$driverId = $this->input->getInt('id', 0);

if ($driverId > 0) {
$this->modelState->set('filter.driver', $filter->clean($driverId, 'INT'));
} else {
$error = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'id');
throw new InvalidParameterException($error, 400, null, 'registrationDateStart');
}

// Call the orders model list
return parent::displayList();
}
}

Αυτό ορίζει ένα filter που το πιάνει η getListQuery στο model.


3. Component Model

Path: components/com_test/src/models/OrdersModel.php

protected function getListQuery()
{
$db = $this->getDbo();
$query = $db->getQuery(true);

$query->select(
$this->getState('list.select', 'DISTINCT a.*')
);

$query->from($db->quoteName('#__test_orders', 'a'));

// Filter by search in title
$search = $this->getState('filter.search');

if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('a.id = ' . (int) substr($search, 3));
} else {
$search = $db->Quote('%' . $db->escape($search, true) . '%');
$query->where('( a.name LIKE ' . $search . ' )');
}
}

// Filtering driver
$filter_driver = $this->state->get("filter.driver");
if ($filter_driver) {
$query->where("a.driver = '" . $db->escape($filter_driver) . "'");
}

// Only new or processing orders
$query->where('a.status!=2 AND a.status!=5');

// Add the list ordering clause
$orderCol = $this->state->get('list.ordering', 'id');
$orderDirn = $this->state->get('list.direction', 'DESC');

if ($orderCol && $orderDirn) {
$query->order($db->escape($orderCol . ' ' . $orderDirn));
}

return $query;
}

Το βασικό κομμάτι για φιλτράρισμα βάσει driver:

// Filtering driver
$filter_driver = $this->state->get("filter.driver");
if ($filter_driver) {
$query->where("a.driver = '" . $db->escape($filter_driver) . "'");
}

4. Εναλλακτικά: Full Custom Response (Χωρίς Model)

Αν δεν θέλεις να χρησιμοποιήσεις το Joomla component model, μπορείς να χειριστείς τα πάντα απευθείας στον controller.

Path: api/components/com_test/Controller/OrdersController.php

namespace Test\Component\Test\Api\Controller;

\defined('_JEXEC') or die;

use Joomla\CMS\MVC\Controller\ApiController;
use Joomla\CMS\Factory;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\Uri\Uri;
use Tobscure\JsonApi\Exception\InvalidParameterException;
use Joomla\CMS\Language\Text;

class OrdersController extends ApiController
{
protected $contentType = 'orders';
protected $default_view = 'orders';

public function getDriverOrders()
{
$this->app->getSession()->set('application.queue', $this->app->getMessageQueue());

header('Content-Type: application/json');

// Uncomment these 3 lines for test purposes to check the response
// $response_data = null;
// echo new JsonResponse($response_data, 'Check', true);
// $this->app->close();

// Get the input
$input = $this->input;
$driverId = $input->getInt('id', 0);

// Get the database object
$db = Factory::getDbo();

// Build the query to get orders assigned to the specified driver_id
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__test_orders'))
->where($db->quoteName('driver') . ' = ' . $db->quote($driverId));

// Execute the query
$db->setQuery($query);
$orders = $db->loadObjectList();

// Return the result as JSON response
echo new JsonResponse($orders, 'Check', false);
$this->app->close();
}
}

API - Postman

Θα δεις λίγο το API του Joomla πώς δουλεύει. Έχει μια εφαρμογή Postman μέσα στον υπολογιστή. Αποσυνδέσου και φτιάξε δικό σου account ή άστο ως έχει.

Πατάς κάτω "Run in Postman".