Files
MokoSuiteLibrary/source/packages/plg_system_mokosuitelibrary/src/Helper/ReservationHelper.php
T
Jonathan Miller fffdd32f64
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
feat: full scaffolding — manifests, Extension, provider, SQL (7 tables), 4 helpers (Catalog, Checkout, Reservation, Fine), language files
2026-06-23 11:01:13 -05:00

94 lines
2.8 KiB
PHP

<?php
namespace Moko\Plugin\System\MokoSuiteLibrary\Helper;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseInterface;
/**
* Library reservations — holds, queue management, notification on availability.
*/
class ReservationHelper
{
public static function reserve(int $itemId, int $patronId): object
{
$db = Factory::getContainer()->get(DatabaseInterface::class);
$now = Factory::getDate()->toSql();
// Get next position in queue
$query = $db->getQuery(true)
->select('COALESCE(MAX(position), 0) + 1')
->from($db->quoteName('#__mokosuitelibrary_reservations'))
->where($db->quoteName('item_id') . ' = ' . (int) $itemId)
->where($db->quoteName('status') . ' IN (' . $db->quote('waiting') . ', ' . $db->quote('ready') . ')');
$db->setQuery($query);
$position = (int) $db->loadResult();
$reservation = (object) [
'item_id' => (int) $itemId,
'patron_id' => (int) $patronId,
'position' => $position,
'status' => 'waiting',
'created' => $now,
];
$db->insertObject('#__mokosuitelibrary_reservations', $reservation, 'id');
return $reservation;
}
public static function fulfillNext(int $itemId, int $holdDays = 3): ?object
{
$db = Factory::getContainer()->get(DatabaseInterface::class);
$now = Factory::getDate()->toSql();
$expires = Factory::getDate('+' . $holdDays . ' days')->toSql();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__mokosuitelibrary_reservations'))
->where($db->quoteName('item_id') . ' = ' . (int) $itemId)
->where($db->quoteName('status') . ' = ' . $db->quote('waiting'))
->order('position ASC')
->setLimit(1);
$db->setQuery($query);
$reservation = $db->loadObject();
if (!$reservation) {
return null;
}
$query = $db->getQuery(true)
->update($db->quoteName('#__mokosuitelibrary_reservations'))
->set($db->quoteName('status') . ' = ' . $db->quote('ready'))
->set($db->quoteName('notified_at') . ' = ' . $db->quote($now))
->set($db->quoteName('expires_at') . ' = ' . $db->quote($expires))
->where($db->quoteName('id') . ' = ' . (int) $reservation->id);
$db->setQuery($query);
$db->execute();
return $reservation;
}
public static function getQueue(int $itemId): array
{
$db = Factory::getContainer()->get(DatabaseInterface::class);
$query = $db->getQuery(true)
->select('r.*, p.name AS patron_name')
->from($db->quoteName('#__mokosuitelibrary_reservations', 'r'))
->join('INNER', $db->quoteName('#__mokosuitelibrary_patrons', 'p') . ' ON p.id = r.patron_id')
->where($db->quoteName('r.item_id') . ' = ' . (int) $itemId)
->where($db->quoteName('r.status') . ' IN (' . $db->quote('waiting') . ', ' . $db->quote('ready') . ')')
->order('r.position ASC');
$db->setQuery($query);
return $db->loadAssocList() ?: [];
}
}