Files
2024-12-17 17:34:10 +01:00

393 lines
11 KiB
PHP

<?php
/**
* @package JEM
* @copyright (C) 2013-2024 joomlaeventmanager.net
* @copyright (C) 2005-2009 Christoph Lukes
* @license https://www.gnu.org/licenses/gpl-3.0 GNU/GPL
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Log\Log;
/**
* Model: Attendee
*/
class JemModelAttendee extends BaseDatabaseModel
{
/**
* attendee id
*
* @var int
*/
protected $_id = null;
/**
* Category data array
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$jinput = Factory::getApplication()->input;
$array = $jinput->get('id', 0, 'array');
if(is_array($array))
{
$this->setId((int)$array[0]);
}
}
/**
* Method to set the identifier
*
* @access public
* @param int category identifier
*/
public function setId($id)
{
// Set category id and wipe data
$this->_id = $id;
$this->_data = null;
}
/**
* Method to get data
*
* @access public
* @return array
*/
public function getData()
{
if (!$this->_loadData()) {
$this->_initData();
}
return $this->_data;
}
/**
* Method to load data
*
* @access protected
* @return boolean True on success
*/
protected function _loadData()
{
// Lets load the content if it doesn't already exist
if (empty($this->_data))
{
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('r.*','u.name AS username', 'a.title AS eventtitle', 'a.waitinglist', 'a.maxbookeduser', 'a.minbookeduser', 'a.recurrence_type', 'a.seriesbooking'));
$query->from('#__jem_register as r');
$query->join('LEFT', '#__users AS u ON (u.id = r.uid)');
$query->join('LEFT', '#__jem_events AS a ON (a.id = r.event)');
$query->where(array('r.id= '.$db->quote($this->_id)));
$this->_db->setQuery($query);
$this->_data = $this->_db->loadObject();
// Merge status and waiting
if (!empty($this->_data) && !empty($this->_data->waiting) && ($this->_data->status == 1)) {
$this->_data->status = 2;
}
return (boolean) $this->_data;
}
return true;
}
/**
* Method to initialise the data
*
* @access protected
* @return boolean True on success
*/
protected function _initData()
{
// Lets load the content if it doesn't already exist
if (empty($this->_data))
{
$data = Table::getInstance('jem_register', '');
$data->username = null;
if (empty($data->eventtitle)) {
$jinput = Factory::getApplication()->input;
$eventid = $jinput->getInt('eventid', 0);
$table = $this->getTable('Event', 'JemTable');
$table->load($eventid);
if (!empty($table->title)) {
$data->eventtitle = $table->title;
$data->event = $table->id;
$data->maxbookeduser = $table->maxbookeduser;
$data->minbookeduser = $table->minbookeduser;
$data->recurrence_type = $table->recurrence_type;
$data->seriesbooking = $table->seriesbooking;
}
$data->waitinglist = isset($table->waitinglist) ? $table->waitinglist : 0;
}
$this->_data = $data;
}
return true;
}
public function toggle()
{
$attendee = $this->getData();
if (!$attendee->id) {
$this->setError(Text::_('COM_JEM_MISSING_ATTENDEE_ID'));
return false;
}
$row = Table::getInstance('jem_register', '');
$row->bind($attendee);
$row->waiting = ($attendee->waiting || ($attendee->status == 2)) ? 0 : 1;
if ($row->status == 2) {
$row->status = 1;
}
return $row->store();
}
/**
* Method to store the attendee
*
* @access public
* @return boolean True on success
*
*/
public function store($data)
{
$eventid = $data['event'];
$userid = $data['uid'];
$id = !empty($data['id']) ? (int)$data['id'] : 0;
$status = isset($data['status']) ? $data['status'] : false;
// Split status and waiting
if ($status !== false) {
if ($status == 2) {
$data['status'] = 1;
$data['waiting'] = 1;
} elseif ($status == 1) {
$data['waiting'] = 0;
}
}
// $row = $this->getTable('jem_register', '');
$row = Table::getInstance('jem_register', '');
if ($id > 0) {
$row->load($id);
$old_data = clone $row;
}
// bind it to the table
if (!$row->bind($data)) {
Factory::getApplication()->enqueueMessage($row->getError(), 'error');
return false;
}
// sanitise id field
$row->id = (int)$row->id;
$db = Factory::getContainer()->get('DatabaseDriver');
// Check if user is already registered to this event
$query = $db->getQuery(true);
$query->select(array('COUNT(id) AS count'));
$query->from('#__jem_register');
$query->where('event = '.$db->quote($eventid));
$query->where('uid = '.$db->quote($userid));
if ($row->id) {
$query->where('id != '.$db->quote($row->id));
}
$db->setQuery($query);
$cnt = $db->loadResult();
if ($cnt > 0) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_ERROR_USER_ALREADY_REGISTERED'), 'warning');
return false;
}
// Are we saving from an item edit?
if ($row->id) {
} else {
if ($row->status === 0) {
// todo: add "invited" field to store such timestamps?
} else { // except status "invited"
$row->uregdate = gmdate('Y-m-d H:i:s');
}
// Get event
$query = $db->getQuery(true);
$query->select(array('id','maxplaces','waitinglist','recurrence_first_id','recurrence_type','seriesbooking','singlebooking'));
$query->from('#__jem_events');
$query->where('id= '.$db->quote($eventid));
$db->setQuery($query);
$event = $db->loadObject();
// If recurrence event, save series event
$events = array();
if($event->recurrence_type){
// Retrieving seriesbooking
$seriesbooking = $data["seriesbooking"];
$singlebooking = $data["singlebooking"];
// If event has 'seriesbooking' active
if($event->seriesbooking && $seriesbooking && !$singlebooking){
//GEt date and time now
$dateFrom = date('Y-m-d', time());
$timeFrom = date('H:i', time());
// Get the all recurrence events of serie from now
$query = $db->getQuery(true);
$query->select(array('id','recurrence_first_id','maxplaces','waitinglist','recurrence_type','seriesbooking','singlebooking'));
$query->from('#__jem_events as a');
$query->where('((a.recurrence_first_id = 0 AND a.id = ' . (int)($event->recurrence_first_id?$event->recurrence_first_id:$event->id) . ') OR a.recurrence_first_id = ' . (int)($event->recurrence_first_id?$event->recurrence_first_id:$event->id) . ")");
$query->where("(a.dates > '" . $dateFrom . "' OR a.dates = '" . $dateFrom . "' AND dates >= '" . $timeFrom . "')");
$db->setQuery($query);
$events = $db->loadObjectList();
}
}
if (!isset($events) || !count ($events)){
$events [] = clone $event;
}
foreach ($events as $e) {
// Check if user is registered to each series event
$query = $db->getQuery(true);
$query->select(array('COUNT(id) AS count'));
$query->from('#__jem_register');
$query->where('event = '.$db->quote($e->id));
$query->where('uid = '.$db->quote($userid));
$db->setQuery($query);
$cnt = $db->loadResult();
if ($cnt > 0) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_ERROR_USER_ALREADY_REGISTERED') . '[id: ' . $e->id . ']', 'warning');
continue;
}
$row_aux= clone $row;
$row_aux->event = $e->id;
// Get register information of the event
$query = $db->getQuery(true);
$query->select(array('COUNT(id) AS registered', 'COALESCE(SUM(waiting), 0) AS waiting'));
$query->from('#__jem_register');
$query->where('status = 1 AND event = ' . $db->quote($e->id));
$db->setQuery($query);
$register = $db->loadObject();
// If no one is registered yet, $register is null!
if (is_null($register)) {
$register = new stdClass;
$register->registered = 0;
$register->waiting = 0;
$register->booked = 0;
} else {
$register->booked = $register->registered + $register->waiting;
}
// put on waiting list ?
if (($event->maxplaces > 0) && ($status == 1)) // there is a max and user will attend
{
// check if the user should go on waiting list
if ($register->booked >= $event->maxplaces) {
if (!$event->waitinglist) {
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_ERROR_REGISTER_EVENT_IS_FULL'), 'warning');
return false;
} else {
$row_aux->waiting = 1;
}
}else{
$row_aux->status = $status;
}
}else{
$row_aux->status = $status;
}
// Make sure the data is valid
if (!$row_aux->check()) {
$this->setError($row->getError());
return false;
}
// Store it in the db
if (!$row_aux->store()) {
Factory::getApplication()->enqueueMessage($row->getError(), 'error');
return false;
}
}
return $row;
}
}
/**
* Method to set status of registered
*
* @param array $pks IDs of the attendee records
* @param int $value Status value: -1 - "not attending", 0 - "invited", 1 - "attending", 2 - "on waiting list"
* @return boolean True on success.
*/
public function setStatus($pks, $value = 1)
{
// Sanitize the ids.
$pks = (array)$pks;
\Joomla\Utilities\ArrayHelper::toInteger($pks);
if (empty($pks)) {
$this->setError(Text::_('JERROR_NO_ITEMS_SELECTED'));
return false;
}
// Split status and waiting
if ($value == 2) {
$status = 1;
$waiting = 1;
} else {
$status = (int)$value;
$waiting = 0;
}
try {
$db = Factory::getContainer()->get('DatabaseDriver');
$db->setQuery(
'UPDATE #__jem_register' .
' SET status = '.$status.', waiting = '.$waiting.
' WHERE id IN ('.implode(',', $pks).')'
);
if ($db->execute() === false) {
throw new Exception($db->getErrorMsg());
}
} catch (Exception $e) {
JemHelper::addLogEntry($e->getMessage(), __METHOD__, Log::ERROR);
$this->setError($e->getMessage());
return false;
}
// JemHelper::addLogEntry("Registration status of record(s) ".implode(', ', $pks)." set to $value", __METHOD__, Log::DEBUG);
return true;
}
}