primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,204 @@
<?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\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Language\Text;
/**
* JEM Component attendee Model
*
* @package JEM
*
*/
class JemModelAttendee extends BaseDatabaseModel
{
/**
* Attendee id
*
* @var int
*/
protected $_id = null;
/**
* Attendee data array
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
*/
public function __construct()
{
parent::__construct();
$settings = JemHelper::globalattribs();
$this->regname = $settings->get('global_regname','1');
$array = Factory::getApplication()->input->get('cid', array(0), 'array');
$this->setId((int)$array[0]);
}
/**
* Method to set the identifier
*
* @access public
* @param int attendee/registration identifier
*/
public function setId($id)
{
// Set category id and wipe data
$this->_id = $id;
$this->_data = null;
}
/**
* Method to get attendee data
*
* @access public
* @return array
*/
public function getData()
{
if (!$this->_loadData()) {
$this->_initData();
}
return $this->_data;
}
/**
* Method to load attendee 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))
{
$query = 'SELECT r.*, ' . ($this->regname ? 'u.name' : 'u.username') . ' AS username '
. ' FROM #__jem_register AS r '
. ' LEFT JOIN #__users AS u ON u.id = r.uid '
. ' WHERE r.id = '.$this->_db->quote($this->_id)
;
$this->_db->setQuery($query);
$this->_data = $this->_db->loadObject();
return (boolean) $this->_data;
}
return true;
}
/**
* Method to initialise attendee 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;
$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 ? 0 : 1;
return $row->store();
}
/**
* Method to store the attendee
*
* @access public
* @return boolean True on success
*/
public function store($data)
{
$eventid = $data['event'];
$row = $this->getTable('jem_register', '');
// bind it to the table
if (!$row->bind($data)) {
\Joomla\CMS\Factory::getApplication()->enqueueMessage($this->_db->getErrorMsg(), 'error');
return false;
}
// sanitise id field
$row->id = (int) $row->id;
// Are we saving from an item edit?
if (!$row->id) {
$row->uregdate = gmdate('Y-m-d H:i:s');
$query = ' SELECT e.maxplaces, e.waitinglist, COUNT(r.id) as booked '
. ' FROM #__jem_events AS e '
. ' INNER JOIN #__jem_register AS r ON r.event = e.id '
. ' WHERE e.id = ' . $this->_db->Quote($eventid)
. ' AND r.status = 1 AND r.waiting = 0 '
. ' GROUP BY e.id ';
$this->_db->setQuery($query);
$details = $this->_db->loadObject();
// put on waiting list ?
if ($details->maxplaces > 0) // there is a max
{
// check if the user should go on waiting list
if ($details->booked >= $details->maxplaces)
{
if (!$details->waitinglist) {
\Joomla\CMS\Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_ERROR_REGISTER_EVENT_IS_FULL'), 'warning');
return false;
}
$row->waiting = 1;
}
}
}
// Make sure the data is valid
if (!$row->check()) {
$this->setError($row->getError());
return false;
}
// Store it in the db
if (!$row->store()) {
Factory::getApplication()->enqueueMessage($this->_db->getErrorMsg(), 'error');
return false;
}
return $row;
}
}
?>

View File

@ -0,0 +1,486 @@
<?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\Pagination\Pagination;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
/**
* JEM Component attendees Model
*
* @package JEM
*
*/
class JemModelAttendees extends BaseDatabaseModel
{
/**
* Attendees data array
*
* @access protected
* @var array
*/
protected $_data = null;
/**
* Attendees total
*
* @access protected
* @var integer
*/
protected $_total = null;
/**
* Event data
*
* @access protected
* @var object
*/
protected $_event = null;
/**
* Pagination object
*
* @access protected
* @var object
*/
protected $_pagination = null;
/**
* Event id
*
* @access protected
* @var int
*/
protected $_id = null;
/**
* Cached setting if name or username should be shown.
*
* @access protected
* @var int
*/
protected $_reguser = 1;
/**
* Constructor
*
*/
public function __construct()
{
parent::__construct();
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$settings = JemHelper::globalattribs();
$id = $app->input->getInt('id', 0);
$this->setId((int)$id);
$this->_reguser = $settings->get('global_regname', '1');
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.attendees.limitstart', 0);
}
$limit = $app->getUserStateFromRequest( 'com_jem.attendees.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->getUserStateFromRequest( 'com_jem.attendees.limitstart', 'limitstart', 0, 'int' );
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
//set unlimited if export or print action | task=export or task=print
$task = $app->input->getCmd('task', '');
$this->setState('unlimited', ($task == 'export' || $task == 'print') ? '1' : '');
}
/**
* Method to set the event identifier
*
* @access public
* @param int Event identifier
*/
public function setId($id)
{
// Set id and wipe data
$this->_id = $id;
$this->_event = null;
$this->_data = null;
}
/**
* Method to get data of the attendees.
*
* @access public
* @return array
*/
public function getData()
{
// Lets load the content if it doesn't already exist
if (empty($this->_data))
{
$query = $this->_buildQuery();
if ($this->getState('unlimited') == '') {
$this->_data = $this->_getList($query, $this->getState('limitstart'), $this->getState('limit'));
} else {
$pagination = $this->getPagination();
$this->_data = $this->_getList($query, $pagination->limitstart, $pagination->limit);
}
}
return $this->_data;
}
/**
* Method to get the total number of attendees
*
* @access public
* @return integer
*/
public function getTotal()
{
// Lets load the content if it doesn't already exist
if (empty($this->_total))
{
$query = $this->_buildQuery();
$this->_total = $this->_getListCount($query);
}
return $this->_total;
}
/**
* Method to get a pagination object for the attendees
*
* @access public
* @return integer
*/
public function getPagination()
{
// Lets load the content if it doesn't already exist
if (empty($this->_pagination))
{
$this->_pagination = new Pagination( $this->getTotal(), $this->getState('limitstart'), $this->getState('limit') );
}
return $this->_pagination;
}
/**
* Method to build the query for the attendees
*
* @access protected
* @return string
*/
protected function _buildQuery()
{
// Get the ORDER BY clause for the query
$orderby = $this->_buildContentOrderBy();
$where = $this->_buildContentWhere();
$query = 'SELECT r.*, u.username, u.name, u.email, a.created_by, a.published,'
. ' c.catname, c.id AS catid'
. ' FROM #__jem_register AS r'
. ' LEFT JOIN #__jem_events AS a ON r.event = a.id'
. ' LEFT JOIN #__users AS u ON u.id = r.uid'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.itemid = a.id'
. ' LEFT JOIN #__jem_categories AS c ON c.id = rel.catid'
. $where
. ' GROUP BY r.id'
. $orderby
;
return $query;
}
/**
* Method to build the orderby clause of the query for the attendees
*
* @access protected
* @return string
*/
protected function _buildContentOrderBy()
{
$app = Factory::getApplication();
$filter_order = $app->getUserStateFromRequest('com_jem.attendees.filter_order', 'filter_order', 'r.uregdate', 'cmd' );
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.attendees.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word' );
if ($this->_reguser && ($filter_order == 'u.username')) {
$filter_order = 'u.name';
}
$filter_order = InputFilter::getinstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getinstance()->clean($filter_order_Dir, 'word');
if ($filter_order == 'r.status') {
$orderby = ' ORDER BY '.$filter_order.' '.$filter_order_Dir.', r.waiting '.$filter_order_Dir.', u.name';
// $orderby = ' ORDER BY CASE WHEN r.status < 0 THEN r.status * (-3) WHEN r.status = 1 AND r.waiting > 0 THEN r.status + 1 ELSE r.status END '.$filter_order_Dir.', u.name';
} else {
$orderby = ' ORDER BY '.$filter_order.' '.$filter_order_Dir.', u.name';
}
return $orderby;
}
/**
* Method to build the where clause of the query for the attendees
*
* @access protected
* @return string
*/
protected function _buildContentWhere()
{
$app = Factory::getApplication();
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$canEdit = $user->can('edit', 'event', $this->_id, $user->id); // where cluase ensures user is the event owner
$filter = $app->getUserStateFromRequest('com_jem.attendees.filter', 'filter', 0, 'int');
$filter_status = $app->getUserStateFromRequest('com_jem.attendees.filter_status', 'filter_status', -2, 'int');
$search = $app->getUserStateFromRequest('com_jem.attendees.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
$where = array();
$where[] = 'r.event = '.$this->_db->Quote($this->_id);
if ($filter_status > -2) {
if ($filter_status >= 1) {
$waiting = $filter_status == 2 ? 1 : 0;
$filter_status = 1;
$where[] = '(a.waitinglist = 0 OR r.waiting = '.$waiting.')';
}
$where[] = 'r.status = '.$filter_status;
}
// First thing we need to do is to select only needed events
if (!$canEdit) {
$where[] = ' a.published = 1';
}
$where[] = ' c.published = 1';
$where[] = ' a.access IN (' . implode(',', $levels) . ')';
$where[] = ' c.access IN (' . implode(',', $levels) . ')';
// then if the user is the owner of the event
//commented out to let groupmember and admins too add attending users in frontend
//$where[] = ' a.created_by = '.$this->_db->Quote($user->id);
/*
* Search name or username (depends on global setting "reguser"
*/
if ($search && $filter == 1) {
$where[] = ' LOWER(u.name) LIKE \'%'.$search.'%\' ';
}
if ($search && $filter == 2) {
$where[] = ' LOWER(u.username) LIKE \'%'.$search.'%\' ';
}
$where2 = (count($where) ? ' WHERE ' . implode(' AND ', $where) : '');
return $where2;
}
/**
* Get event data
*
* @access public
* @return object
*/
public function getEvent()
{
if (empty($this->_event)) {
$query = 'SELECT a.id, a.alias, a.title, a.dates, a.enddates, a.times, a.endtimes, a.maxplaces, a.maxbookeduser, a.minbookeduser, a.reservedplaces, a.waitinglist, a.requestanswer, a.seriesbooking, a.singlebooking,'
. ' a.published, a.created, a.created_by, a.created_by_alias, a.locid, a.registra, a.unregistra,'
. ' a.recurrence_type, a.recurrence_first_id, a.recurrence_byday, a.recurrence_counter, a.recurrence_limit, a.recurrence_limit_date, a.recurrence_number,'
. ' a.access, a.attribs, a.checked_out, a.checked_out_time, a.contactid, a.datimage, a.featured, a.hits, a.version,'
. ' a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10,'
. ' a.introtext, a.fulltext, a.language, a.metadata, a.meta_keywords, a.meta_description, a.modified, a.modified_by'
. ' FROM #__jem_events AS a WHERE a.id = '.$this->_db->Quote($this->_id);
$this->_db->setQuery($query);
$this->_event = $this->_db->loadObject();
}
return $this->_event;
}
/**
* Delete registered users
*
* @access public
* @param array $cid array of attendee IDs
* @return true on success
*/
public function remove($cid = array())
{
if (is_array($cid) && count($cid))
{
\Joomla\Utilities\ArrayHelper::toInteger($cid);
$query = 'DELETE FROM #__jem_register WHERE id IN ('. implode(',', $cid) .') ';
$this->_db->setQuery($query);
if ($this->_db->execute() === false) {
throw new Exception($this->_db->getErrorMsg(), 1001);
}
// clear attendees cache
$this->_data = null;
}
return true;
}
###########
## USERS ##
###########
/**
* Get list of ALL active, non-blocked users incl. registrytion status if attendee.
*/
public function getUsers()
{
$query = $this->_buildQueryUsers();
$pagination = $this->getUsersPagination();
$rows = $this->_getList($query, $pagination->limitstart, $pagination->limit);
// Add registration status if available
$eventId = $this->_id;
$db = Factory::getContainer()->get('DatabaseDriver');
$qry = $db->getQuery(true);
// #__jem_register (id, event, uid, waiting, status, comment)
$qry->select(array('reg.uid, reg.status, reg.waiting, reg.places'));
$qry->from('#__jem_register As reg');
$qry->where('reg.event = ' . $eventId);
$db->setQuery($qry);
$regs = $db->loadObjectList('uid');
// JemHelper::addLogEntry((string)$qry . "\n" . print_r($regs, true), __METHOD__);
foreach ($rows as &$row) {
if (array_key_exists($row->id, $regs)) {
$row->status = $regs[$row->id]->status;
$row->places = $regs[$row->id]->places;
if ($row->status == 1 && $regs[$row->id]->waiting) {
++$row->status;
}
} else {
$row->status = -99;
$row->places = 0;
}
}
return $rows;
}
/**
* Get users registered on given event
*/
static public function getRegisteredUsers($eventId)
{
if (empty($eventId)) {
return array();
}
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
// #__jem_register (id, event, uid, waiting, status, comment)
$query->select(array('reg.uid, reg.status, reg.waiting, reg.id'));
$query->from('#__jem_register As reg');
$query->where('reg.event = ' . $eventId);
$db->setQuery($query);
$regs = $db->loadObjectList('uid');
// JemHelper::addLogEntry((string)$qry . "\n" . print_r($regs, true), __METHOD__);
return $regs;
}
/**
* users-Pagination
**/
public function getUsersPagination()
{
$jemsettings = JemHelper::config();
$app = Factory::getApplication();
$limit = $app->getUserStateFromRequest('com_jem.addusers.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$query = $this->_buildQueryUsers();
$total = $this->_getListCount($query);
// Create the pagination object
$pagination = new Pagination($total, $limitstart, $limit);
return $pagination;
}
/**
* users-query
*/
protected function _buildQueryUsers()
{
$app = Factory::getApplication();
// no filters, hard-coded
$filter_order = 'usr.name';
$filter_order_Dir = '';
$filter_type = '1';
$search = $app->getUserStateFromRequest('com_jem.selectusers.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('usr.id, usr.name'));
$query->from('#__users As usr');
// where
$where = array();
$where[] = 'usr.block = 0';
$where[] = 'NOT usr.activation > 0';
/* something to search for? (we like to search for "0" too) */
if ($search || ($search === "0")) {
switch ($filter_type) {
case 1: /* Search name */
$where[] = ' LOWER(usr.name) LIKE \'%' . $search . '%\' ';
break;
}
}
$query->where($where);
// ordering
// ensure it's a valid order direction (asc, desc or empty)
if (!empty($filter_order_Dir) && strtoupper($filter_order_Dir) !== 'DESC') {
$filter_order_Dir = 'ASC';
}
if ($filter_order != '') {
$orderby = $filter_order . ' ' . $filter_order_Dir;
if ($filter_order != 'usr.name') {
$orderby = array($orderby, 'usr.name'); // in case of (???) we should have a useful second ordering
}
} else {
$orderby = 'usr.name ' . $filter_order_Dir;
}
$query->order($orderby);
return $query;
}
}
?>

View File

@ -0,0 +1,121 @@
<?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;
require_once __DIR__ . '/eventslist.php';
/**
* Model-Calendar
*/
class JemModelCalendar extends JemModelEventslist
{
protected $_date = 0;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->setdate(time());
}
public function setdate($date)
{
$this->_date = $date;
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
# parent::populateState($ordering, $direction);
$app = Factory::getApplication();
$params = $app->getParams();
$task = $app->input->getCmd('task','','cmd');
$top_category = $params->get('top_category', 0);
$this->show_archived_events = $params->get('show_archived_events', 0);
$startdayonly = $params->get('show_only_start', false);
# params
$this->setState('params', $params);
# publish state
$this->_populatePublishState($task);
###########
## DATES ##
###########
#only select events within specified dates. (chosen month)
$monthstart = mktime(0, 0, 1, date('m', $this->_date), 1, date('Y', $this->_date));
$monthend = mktime(0, 0, -1, date('m', $this->_date)+1, 1, date('Y', $this->_date));
$filter_date_from = $this->_db->Quote(date('Y-m-d', $monthstart));
$filter_date_to = $this->_db->Quote(date('Y-m-d', $monthend));
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), '. $filter_date_from .') >= 0';
$this->setState('filter.calendar_from',$where);
$where = ' DATEDIFF(a.dates, '. $filter_date_to .') <= 0';
$this->setState('filter.calendar_to',$where);
##################
## TOP-CATEGORY ##
##################
if ($top_category) {
$children = JemCategories::getChilds($top_category);
if (count($children)) {
$where = 'rel.catid IN ('. implode(',', $children) .')';
$this->setState('filter.category_top', $where);
}
}
# set filter
$this->setState('filter.calendar_multiday',true);
$this->setState('filter.calendar_startdayonly',(bool)$startdayonly);
$this->setState('filter.groupby',array('a.id'));
$this->setState('filter.show_archived_events',(bool)$this->show_archived_events);
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
if ($items) {
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Create a new query object.
$query = parent::getListQuery();
// here we can extend the query of the Eventslist model
$query->select('DATEDIFF(a.enddates, a.dates) AS datesdiff, DAYOFMONTH(a.dates) AS start_day, YEAR(a.dates) AS start_year, MONTH(a.dates) AS start_month');
return $query;
}
}
?>

View File

@ -0,0 +1,478 @@
<?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\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Pagination\Pagination;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
/**
* JEM Component Categories Model
*
* @package JEM
*
*/
class JemModelCategories extends BaseDatabaseModel
{
/**
* Top category id
*
* @var int
*/
protected $_id = 0;
/**
* Event data array
*
* @var array
*/
protected $_data = null;
/**
* Categories total
*
* @var integer
*/
protected $_total = null;
/**
* Categories data array
*
* @var array
*/
protected $_categories = null;
/**
* Pagination object
*
* @var object
*/
protected $_pagination = null;
/**
* Show empty categories in list
*
* @var bool
*/
protected $_showemptycats = false;
/**
* Show subcategories
*
* @var bool
*/
protected $_showsubcats = false;
/**
* Show empty subcategories
*
* @var bool
*/
protected $_showemptysubcats = false;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$app = Factory::getApplication();
// Get the parameters of the active menu item
$params = $app->getParams('com_jem');
$id = $app->input->getInt('id', 0);
if (empty($id)) {
$id = $params->get('id', 1);
}
$this->_id = $id;
$this->_showemptycats = (bool)$params->get('showemptycats', 1);
$this->_showsubcats = (bool)$params->get('usecat', 1);
$this->_showemptysubcats = (bool)$params->get('showemptychilds', 1);
//get the number of events from database
$limit = $app->input->getInt('limit', $params->get('cat_num'));
$limitstart = $app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
}
/**
* Method to get the Categories
*
* @access public
* @return array
*/
public function getData()
{
$app = Factory::getApplication();
$params = $app->getParams();
// Lets load the content if it doesn't already exist
if (empty($this->_categories))
{
// include category itself but not if it's the root category
$parentCategory = ($this->_id > 1) ? $this->_getList($this->_buildQueryParentCategory(true)) : array();
$query = $this->_buildQuerySubCategories($this->_showemptycats);
$pagination = $this->getPagination();
$this->_categories = $this->_getList($query, $pagination->limitstart, $pagination->limit);
// Include parent category itself
$this->_categories = array_merge($parentCategory, $this->_categories);
foreach($this->_categories as $category) {
if ($this->_showsubcats) {
//child categories
// ensure parent shows at least all categories also shown in list
$showempty = $this->_showemptysubcats | ($category->id == $this->_id ? $this->_showemptycats : false);
$query = $this->_buildQuerySubCategories($showempty, $category->id);
$this->_db->setQuery($query);
$category->subcats = $this->_db->loadObjectList();
} else {
$category->subcats = array();
}
//Generate description
if (empty ($category->description)) {
$category->description = Text::_('COM_JEM_NO_DESCRIPTION');
} else {
//execute plugins
$category->text = $category->description;
$category->title = $category->catname;
PluginHelper::importPlugin('content');
$app->triggerEvent('onContentPrepare', array('com_jem.categories', &$category, &$params, 0));
$category->description = $category->text;
}
//create target link
// TODO: Move to view?
$task = $app->input->getCmd('task', '');
if ($task == 'archive') {
$category->linktext = Text::_('COM_JEM_SHOW_ARCHIVE');
$category->linktarget = Route::_(JemHelperRoute::getCategoryRoute($category->slug.'&task=archive'));
} else {
$category->linktext = Text::_('COM_JEM_SHOW_EVENTS');
$category->linktarget = Route::_(JemHelperRoute::getCategoryRoute($category->slug));
}
}
}
return $this->_categories;
}
/**
* Total nr of Categories
*
* @access public
* @return integer
*/
public function getTotal()
{
// Lets load the total nr if it doesn't already exist
if (empty($this->_total))
{
$query = $this->_buildQueryTotal();
$this->_total = $this->_getListCount($query);
}
return $this->_total;
}
/**
* Method to get the Categories events
*
* @access public
* @return array
*/
public function getEventdata($id)
{
$app = Factory::getApplication();
$params = $app->getParams('com_jem');
if (empty($this->_data[$id])) {
// Lets load the content
$query = $this->_buildDataQuery($id);
$this->_data[$id] = $this->_getList($query, 0, $params->get('detcat_nr'));
foreach ($this->_data[$id] as $i => &$item) {
$item->categories = $this->getCategories($item->id);
//remove events without categories (users have no access to them)
if (empty($item->categories)) {
unset ($this->_data[$id][$i]);
}
}
}
return $this->_data[$id];
}
/**
* Method get the event query
*
* @access private
* @return array
*/
protected function _buildDataQuery($id)
{
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$task = Factory::getApplication()->input->getCmd('task', '');
$id = (int)$id;
// First thing we need to do is to select only the requested events
if ($task == 'archive') {
$where = ' WHERE a.published = 2 AND rel.catid = '.$id;
} else {
$where = ' WHERE a.published = 1 AND rel.catid = '.$id;
}
// Second is to only select events assigned to category the user has access to
$where .= ' AND c.access IN (' . implode(',', $levels) . ')';
$where .= ' AND a.access IN (' . implode(',', $levels) . ')';
$query = 'SELECT DISTINCT a.id, a.dates, a.enddates, a.times, a.endtimes, a.title, a.locid, a.created, a.published,'
. ' a.recurrence_type, a.recurrence_first_id,'
. ' a.access, a.checked_out, a.checked_out_time, a.contactid, a.created, a.created_by, a.created_by_alias, a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10, a.datimage, a.featured,'
. ' a.fulltext, a.hits, a.introtext, a.language, a.maxplaces, a.metadata, a.meta_keywords, a.meta_description, a.modified, a.modified_by, a.registra, a.unregistra, a.waitinglist,'
. ' a.recurrence_byday, a.recurrence_counter, a.recurrence_limit, a.recurrence_limit_date, a.recurrence_number, a.version,'
. ' l.venue, l.street, l.postalCode, l.city, l.state, l.url, l.country, l.published AS l_published,'
. ' l.alias AS l_alias, l.checked_out AS l_checked_out, l.checked_out_time AS l_checked_out_time, l.created AS l_created, l.created_by AS l_createdby,'
. ' l.custom1 AS l_custom1, l.custom2 AS l_custom2, l.custom3 AS l_custom3, l.custom4 AS l_custom4, l.custom5 AS l_custom5, l.custom6 AS l_custom6, l.custom7 AS l_custom7, l.custom8 AS l_custom8, l.custom9 AS l_custom9, l.custom10 AS l_custom10,'
. ' l.id AS l_id, l.latitude, l.locdescription, l.locimage, l.longitude, l.map, l.meta_description AS l_meta_description, l.meta_keywords AS l_meta_keywords, l.modified AS l_modified, l.modified_by AS l_modified_by,'
. ' l.publish_up AS l_publish_up, l.publish_down AS l_publish_down, l.version AS l_version,'
. ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'
. ' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', a.locid, l.alias) ELSE a.locid END as venueslug'
. ' FROM #__jem_events AS a'
. ' LEFT JOIN #__jem_venues AS l ON l.id = a.locid'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.itemid = a.id'
. ' LEFT JOIN #__jem_categories AS c ON c.id = '.$id
. $where
. ' ORDER BY a.dates, a.times, a.created DESC'
;
return $query;
}
public function getCategories($id)
{
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$query = 'SELECT DISTINCT c.id, c.catname, c.access, c.checked_out AS cchecked_out,'
. ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END as catslug'
. ' FROM #__jem_categories AS c'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.catid = c.id'
. ' WHERE rel.itemid = '.(int)$id
. ' AND c.published = 1'
. ' AND c.access IN (' . implode(',', $levels) . ')'
;
$this->_db->setQuery($query);
return $this->_db->loadObjectList();
}
/**
* Method to get the subcategories query
* @param bool $emptycat include empty categories
* @param string $parent_id Parent ID of the subcategories
* @return string The query string
*/
protected function _buildQuerySubCategories($emptycat, $parent_id = null)
{
return $this->_buildQuery($emptycat, $parent_id);
}
/**
* Method to get the parent category query
* @param bool $emptycat include empty categories
* @param string $parent_id ID of the parent category
* @return string The query string
*/
protected function _buildQueryParentCategory($emptycat, $parent_id = null)
{
return $this->_buildQuery($emptycat, $parent_id, true);
}
/**
* Method to get the categories query
* @param bool $emptycat include empty categories
* @param string $parent_id
* @param bool $parentCategory
* @return string The query string
*/
protected function _buildQuery($emptycat, $parent_id = null, $parentCategory = false)
{
if (is_null($parent_id)) {
$parent_id = $this->_id;
}
$app = Factory::getApplication();
$jinput = $app->input;
$user = JemFactory::getUser();
$userId = $user->get('id');
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$jemsettings = JemHelper::config();
$ordering = 'c.lft ASC';
// build where clause
$where_sub = ' WHERE cc.published = 1';
if($parentCategory) {
$where_sub .= ' AND cc.id = '.(int) $parent_id;
} else {
$where_sub .= ' AND cc.parent_id = '.(int) $parent_id;
}
$where_sub .= ' AND cc.access IN (' . implode(',', $levels) . ')';
$where_sub .= ' AND i.access IN (' . implode(',', $levels) . ')';
// check archive task and ensure that only categories get selected
// if they contain a published/archived event
$task = $jinput->getCmd('task', '');
$format = $jinput->getCmd('format', '');
# inspired by JemModelEventslist
if ($task == 'archive') {
$where_sub .= ' AND i.published = 2';
} elseif (($format == 'raw') || ($format == 'feed')) {
$where_sub .= ' AND i.published = 1';
} else {
$show_unpublished = $user->can(array('edit', 'publish'), 'event', false, false, 1);
if ($show_unpublished) {
// global editor or publisher permission
$where_sub .= ' AND i.published IN (0, 1)';
} else {
// no global permission but maybe on event level
$where_sub_or = array();
$where_sub_or[] = '(i.published = 1)';
$jemgroups = $user->getJemGroups(array('editevent', 'publishevent'));
if (($userId !== 0) && ($jemsettings->eventedit == -1)) {
$jemgroups[0] = true; // we need key 0 to get unpublished events not attached to any jem group
}
// user permitted on that jem groups
if (is_array($jemgroups) && count($jemgroups)) {
$on_groups = array_keys($jemgroups);
// to allow only events with categories attached to allowed jemgroups use this line:
//$where_sub_or[] = '(i.published = 0 AND c.groupid IN (' . implode(',', $on_groups) . '))';
// to allow also events with categories not attached to disallowed jemgroups use this crazy block:
$where_sub_or[] = '(i.published = 0 AND '
. ' i.id NOT IN (SELECT rel3.itemid FROM #__jem_categories as c3 '
. ' INNER JOIN #__jem_cats_event_relations as rel3 '
. ' WHERE c3.id = rel3.catid AND c3.groupid NOT IN (0,' . implode(',', $on_groups) . ')'
. ' GROUP BY rel3.itemid)'
. ')';
// hint: above it's a not not ;-)
// meaning: Show unpublished events not connected to a category which is not one of the allowed categories.
}
// user permitted on own events
if (($userId !== 0) && ($user->authorise('core.edit.own', 'com_jem') || $jemsettings->eventowner)) {
$where_sub_or[] = '(i.published = 0 AND i.created_by = ' . $userId . ')';
}
$where_sub .= ' AND (' . implode(' OR ', $where_sub_or) . ')';
}
}
$where_sub .= ' AND c.id = cc.id';
// show/hide empty categories
$empty = $emptycat ? '' : ' HAVING assignedevents > 0';
// Parent category itself or its sub categories
$parentCategoryQuery = $parentCategory ? 'c.id='.(int)$parent_id : 'c.parent_id='.(int)$parent_id;
$query = 'SELECT c.*,'
. ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END AS slug,'
. ' ('
. ' SELECT COUNT(DISTINCT i.id)'
. ' FROM #__jem_events AS i'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.itemid = i.id'
. ' LEFT JOIN #__jem_categories AS cc ON cc.id = rel.catid'
. $where_sub
. ' GROUP BY cc.id'
. ' ) AS assignedevents'
. ' FROM #__jem_categories AS c'
. ' WHERE c.published = 1'
. ' AND '.$parentCategoryQuery
. ' AND c.access IN (' . implode(',', $levels) . ')'
. ' GROUP BY c.id '.$empty
. ' ORDER BY '.$ordering
;
return $query;
}
/**
* Method to build the Categories query without subselect
* That's enough to get the total value.
*
* @access private
* @return string
*/
protected function _buildQueryTotal()
{
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$query = 'SELECT DISTINCT c.id'
. ' FROM #__jem_categories AS c';
if (!$this->_showemptycats) {
$query .= ' INNER JOIN #__jem_cats_event_relations AS rel ON rel.catid = c.id '
. ' INNER JOIN #__jem_events AS e ON e.id = rel.itemid ';
}
$query .= ' WHERE c.published = 1'
. ' AND c.parent_id = ' . (int) $this->_id
. ' AND c.access IN (' . implode(',', $levels) . ')'
;
if (!$this->_showemptycats) {
$query .= ' AND e.access IN (' . implode(',', $levels) . ')';
$task = Factory::getApplication()->input->getCmd('task', '');
if($task == 'archive') {
$query .= ' AND e.published = 2';
} else {
$query .= ' AND e.published = 1';
}
}
return $query;
}
/**
* Method to get a pagination object for the events
*
* @access public
* @return integer
*/
public function getPagination()
{
// Lets load the content if it doesn't already exist
if (empty($this->_pagination)) {
$this->_pagination = new Pagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit'));
}
return $this->_pagination;
}
}
?>

View File

@ -0,0 +1,328 @@
<?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\Filter\InputFilter;
Use Joomla\Utilities\ArrayHelper;
use Joomla\Registry\Registry;
require_once __DIR__ . '/eventslist.php';
/**
* Model: Category
*
* \todo Remove all the collected stuff copied from somewhere but unused/useless.
*/
class JemModelCategory extends JemModelEventslist
{
protected $_id = null;
//protected $_data = null;
//protected $_childs = null;
//protected $_category = null;
//protected $_pagination= null;
protected $_item = null;
//protected $_articles = null;
//protected $_siblings = null;
protected $_children = null;
protected $_parent = null;
/**
* Constructor
*/
public function __construct()
{
$app = Factory::getApplication();
// Get the parameters of the active menu item
$params = $app->getParams();
$id = $app->input->getInt('id', 0);
if (empty($id)) {
$id = $params->get('id', 1);
}
$this->setId((int)$id);
parent::__construct();
}
/**
* Set Date
*/
public function setdate($date)
{
$this->_date = $date;
}
/**
* Method to set the category id
*/
public function setId($id)
{
// Set new category ID and wipe data
$this->_id = $id;
$this->_item = null;
//$this->_data = null;
}
/**
* set limit
* @param int value
*/
public function setLimit($value)
{
$this->setState('list.limit', (int) $value);
}
/**
* set limitstart
* @param int value
*/
public function setLimitStart($value)
{
$this->setState('list.start', (int) $value);
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
// Initiliase variables.
$app = Factory::getApplication('site');
$jemsettings = JemHelper::config();
$task = $app->input->getCmd('task','');
$format = $app->input->getCmd('format',false);
$pk = $app->input->getInt('id', 0);
$itemid = $pk . ':' . $app->input->getInt('Itemid', 0);
$this->setState('category.id', $pk);
$this->setState('filter.req_catid', $pk);
// Load the parameters. Merge Global and Menu Item params into new object
$params = $app->getParams();
$menuParams = new Registry;
if ($menu = $app->getMenu()->getActive()) {
// $menu_params = $menu->getParams();
// $menuParams->loadString($menu->params);
$menuParams->loadString($menu->getParams());
}
$mergedParams = clone $menuParams;
$mergedParams->merge($params);
$this->setState('params', $mergedParams);
# limit/start
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.category.'.$itemid.'.limitstart', 0);
}
if (empty($format) || ($format == 'html')) {
$limit = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.limit', 'limit', $jemsettings->display_num, 'int');
$this->setState('list.limit', $limit);
$limitstart = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('list.start', $limitstart);
}
# Search - variables
$search = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.filter_search', 'filter_search', '', 'string');
$this->setState('filter.filter_search', $search);
$month = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.filter_month', 'filter_month', '', 'string');
$this->setState('filter.filter_month', $month);
$filtertype = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.filter_type', 'filter_type', 0, 'int');
$this->setState('filter.filter_type', $filtertype);
# show open date events
# (there is no menu item option yet so show all events)
$this->setState('filter.opendates', 1);
# publish state
$this->_populatePublishState($task);
###########
## ORDER ##
###########
$filter_order = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.filter_order', 'filter_order', 'a.dates', 'cmd');
$filter_order_DirDefault = 'ASC';
// Reverse default order for dates in archive mode
if($task == 'archive' && $filter_order == 'a.dates') {
$filter_order_DirDefault = 'DESC';
}
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.category.'.$itemid.'.filter_order_Dir', 'filter_order_Dir', $filter_order_DirDefault, 'word');
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
$default_order_Dir = ($task == 'archive') ? 'DESC' : 'ASC';
if ($filter_order == 'a.dates') {
$orderby = array('a.dates ' . $filter_order_Dir, 'a.times ' . $filter_order_Dir, 'a.created ' . $filter_order_Dir);
} else {
$orderby = array($filter_order . ' ' . $filter_order_Dir,
'a.dates ' . $default_order_Dir, 'a.times ' . $default_order_Dir, 'a.created ' . $default_order_Dir);
}
$this->setState('filter.orderby',$orderby);
}
/**
* Get the events in the category
*/
public function getItems()
{
//$params = clone $this->getState('params');
$items = parent::getItems();
if ($items) {
return $items;
}
return array();
}
/**
* Method to get category data for the current category
*/
public function getCategory()
{
if (!is_object($this->_item)) {
$options = array();
if (isset($this->state->params)) {
$params = $this->state->params;
$options['countItems'] = ($params->get('show_cat_num_articles', 1) || !$params->get('show_empty_categories_cat', 0)) ? 1 : 0;
}
else {
$options['countItems'] = 0;
}
$where_pub = $this->_getPublishWhere('i');
if (!empty($where_pub)) {
$options['published_where'] = '(' . implode(' OR ', $where_pub) . ')';
} else {
// something wrong - fallback to published events
$options['published_where'] = 'i.published = 1';
}
$catId = $this->getState('category.id', 'root');
$categories = new JemCategories($catId, $options);
$this->_item = $categories->get($catId);
// Compute selected asset permissions.
if (is_object($this->_item)) { // a JemCategoryNode object
$user = JemFactory::getUser();
$asset = 'com_jem.category.'.$this->_item->id;
// Check general create permission.
if ($user->authorise('core.create', $asset)) {
$this->_item->getParams()->set('access-create', true);
}
$this->_children = $this->_item->getChildren();
$this->_parent = $this->_item->getParent();
if (empty($this->_parent)) {
$this->_parent = false;
}
$this->_rightsibling = $this->_item->getSibling();
$this->_leftsibling = $this->_item->getSibling(false);
}
else {
$this->_children = false;
$this->_parent = false;
}
}
return $this->_item;
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
//$params = $this->state->params;
//$jinput = Factory::getApplication()->input;
//$task = $jinput->getCmd('task','','cmd');
// Create a new query object.
$query = parent::getListQuery();
// here we can extend the query of the Eventslist model
return $query;
}
/**
* Get the parent categorie.
*/
public function getParent()
{
if (!is_object($this->_item)) {
$this->getCategory();
}
return $this->_parent;
}
/**
* Get the left sibling (adjacent) categories.
*/
public function &getLeftSibling()
{
if (!is_object($this->_item)) {
$this->getCategory();
}
return $this->_leftsibling;
}
/**
* Get the right sibling (adjacent) categories.
*/
public function &getRightSibling()
{
if (!is_object($this->_item)) {
$this->getCategory();
}
return $this->_rightsibling;
}
/**
* Get the child categories.
*/
public function &getChildren()
{
if (!is_object($this->_item)) {
$this->getCategory();
}
// Order subcategories
if ($this->_children) {
if (sizeof($this->_children)) {
$params = $this->getState()->get('params');
if ($params->get('orderby_pri') == 'alpha' || $params->get('orderby_pri') == 'ralpha') {
ArrayHelper::sortObjects($this->_children, 'title', ($params->get('orderby_pri') == 'alpha') ? 1 : -1);
}
}
}
return $this->_children;
}
}
?>

View File

@ -0,0 +1,152 @@
<?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;
require_once __DIR__ . '/eventslist.php';
/**
* Model Categorycal
*
* @package JEM
*/
class JemModelCategoryCal extends JemModelEventslist
{
/**
* Category id
*
* @var int
*/
protected $_id = null;
/**
* Date as timestamp useable for strftime()
*
* @var int
*/
protected $_date = null;
/**
* Constructor
*/
public function __construct()
{
$app = Factory::getApplication();
$params = $app->getParams();
$id = $app->input->getInt('id', 0);
if (empty($id)) {
$id = $params->get('id', 0);
}
$this->setdate(time());
$this->setId((int)$id);
parent::__construct();
}
public function setdate($date)
{
$this->_date = $date;
}
/**
* Method to set the category id
*
* @access public
* @param int category ID
*/
public function setId($id)
{
// Set new category ID and wipe data
$this->_id = $id;
//$this->_data = null;
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
$app = Factory::getApplication();
$params = $app->getParams();
$itemid = $app->input->getInt('Itemid', 0);
$task = $app->input->getCmd('task', '');
$startdayonly = $params->get('show_only_start', false);
$show_archived_events = $params->get('show_archived_events', 0);
# params
$this->setState('params', $params);
# publish state
$this->_populatePublishState($task);
###########
## DATES ##
###########
#only select events within specified dates. (chosen month)
$monthstart = mktime(0, 0, 1, date('m', $this->_date), 1, date('Y', $this->_date));
$monthend = mktime(0, 0, -1, date('m', $this->_date)+1, 1, date('Y', $this->_date));
$filter_date_from = date('Y-m-d', $monthstart);
$filter_date_to = date('Y-m-d', $monthend);
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), '. $this->_db->Quote($filter_date_from) .') >= 0';
$this->setState('filter.calendar_from', $where);
$where = ' DATEDIFF(a.dates, '. $this->_db->Quote($filter_date_to) .') <= 0';
$this->setState('filter.calendar_to', $where);
# set filter
$this->setState('filter.calendar_multiday', true);
$this->setState('filter.calendar_startdayonly', (bool)$startdayonly);
$this->setState('filter.filter_catid', $this->_id);
$this->setState('filter.show_archived_events',(bool)$show_archived_events);
$app->setUserState('com_jem.categorycal.catid'.$itemid, $this->_id);
# groupby
$this->setState('filter.groupby', array('a.id'));
}
/**
* Method to get the events
*
* @access public
* @return array
*/
public function getItems()
{
$items = parent::getItems();
if ($items) {
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Let parent create a new query object.
$query = parent::getListQuery();
// here we can extend the query of the Eventslist model
$query->select('DATEDIFF(a.enddates, a.dates) AS datesdiff,DAYOFMONTH(a.dates) AS start_day, YEAR(a.dates) AS start_year, MONTH(a.dates) AS start_month');
return $query;
}
}
?>

View File

@ -0,0 +1,276 @@
<?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\Language\Text;
require_once __DIR__ . '/eventslist.php';
/**
* Model-Day
*/
class JemModelDay extends JemModelEventslist
{
protected $_date = null;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$rawday = Factory::getApplication()->input->getInt('id', null);
$this->setDate($rawday);
}
/**
* Method to set the date
*
* @access public
* @param string
*/
public function setDate($date)
{
$app = Factory::getApplication();
# Get the params of the active menu item
$params = $app->getParams('com_jem');
# 0 means we have a direct request from a menuitem and without any params (eg: calendar module)
if ($date == 0) {
$dayoffset = $params->get('days');
$timestamp = mktime(0, 0, 0, date("m"), date("d") + $dayoffset, date("Y"));
$date = date('Y-m-d', $timestamp);
# a valid date has 8 characters (ymd)
} elseif (strlen($date) == 8) {
$year = substr($date, 0, -4);
$month = substr($date, 4, -2);
$day = substr($date, 6);
//check if date is valid
if (checkdate($month, $day, $year)) {
$date = $year.'-'.$month.'-'.$day;
} else {
//date isn't valid raise notice and use current date
$date = date('Ymd');
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_INVALID_DATE_REQUESTED_USING_CURRENT'), 'notice');
}
} else {
//date isn't valid raise notice and use current date
$date = date('Ymd');
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_INVALID_DATE_REQUESTED_USING_CURRENT'), 'notice');
}
$this->_date = $date;
}
/**
* Return date
*/
public function getDay()
{
return $this->_date;
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
# parent::populateState($ordering, $direction);
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$itemid = $app->input->getInt('id', 0) . ':' . $app->input->getInt('Itemid', 0);
$params = $app->getParams();
$task = $app->input->getCmd('task', '');
$requestVenueId = $app->input->getInt('locid', 0);
$requestCategoryId = $app->input->getInt('catid', 0);
$item = $app->input->getInt('Itemid', 0);
$locid = $app->getUserState('com_jem.venuecal.locid'.$item);
if ($locid) {
$this->setState('filter.filter_locid', $locid);
}
// maybe list of venue ids from calendar module
$locids = explode(',', $app->input->getString('locids', ''));
foreach ($locids as $id) {
if ((int)$id > 0) {
$venues[] = (int)$id;
}
}
if (!empty($venues)) {
$this->setState('filter.venue_id', $venues);
$this->setState('filter.venue_id.include', true);
}
$cal_category_catid = $app->getUserState('com_jem.categorycal.catid'.$item);
if ($cal_category_catid) {
$this->setState('filter.req_catid', $cal_category_catid);
}
// maybe list of venue ids from calendar module
$catids = explode(',', $app->input->getString('catids', ''));
foreach ($catids as $id) {
if ((int)$id > 1) { // don't accept 'root'
$cats[] = (int)$id;
}
}
if (!empty($cats)) {
$this->setState('filter.category_id', $cats);
$this->setState('filter.category_id.include', true);
}
################################
## EXCLUDE/INCLUDE CATEGORIES ##
################################
$catswitch = $params->get('categoryswitch', '');
# set included categories
if ($catswitch) {
$included_cats = trim($params->get('categoryswitchcats', ''));
if ($included_cats) {
$included_cats = explode(",", $included_cats);
$this->setState('filter.category_id', $included_cats);
$this->setState('filter.category_id.include', true);
}
}
# set excluded categories
if (!$catswitch) {
$excluded_cats = trim($params->get('categoryswitchcats', ''));
if ($excluded_cats) {
$excluded_cats = explode(",", $excluded_cats);
$this->setState('filter.category_id', $excluded_cats);
$this->setState('filter.category_id.include', false);
}
}
// maybe top category is given by calendar view
$top_category = $app->input->getInt('topcat', 0);
if ($top_category > 0) { // accept 'root'
$children = JemCategories::getChilds($top_category);
if (count($children)) {
$where = 'rel.catid IN ('. implode(',', $children) .')';
$this->setState('filter.category_top', $where);
}
}
# limit/start
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.day.'.$itemid.'.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.day.'.$itemid.'.limit', 'limit', $jemsettings->display_num, 'int');
$this->setState('list.limit', $limit);
$limitstart = $app->getUserStateFromRequest('com_jem.day.'.$itemid.'.limitstart', 'limitstart', 0, 'int');
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('list.start', $limitstart);
# Search
$search = $app->getUserStateFromRequest('com_jem.day.'.$itemid.'.filter_search', 'filter_search', '', 'string');
$this->setState('filter.filter_search', $search);
# FilterType
$filtertype = $app->getUserStateFromRequest('com_jem.day.'.$itemid.'.filter_type', 'filter_type', 0, 'int');
$this->setState('filter.filter_type', $filtertype);
# filter_order
$orderCol = $app->getUserStateFromRequest('com_jem.day.'.$itemid.'.filter_order', 'filter_order', 'a.dates', 'cmd');
$this->setState('filter.filter_ordering', $orderCol);
# filter_direction
$listOrder = $app->getUserStateFromRequest('com_jem.day.'.$itemid.'.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word');
$this->setState('filter.filter_direction', $listOrder);
$defaultOrder = ($task == 'archive') ? 'DESC' : 'ASC';
if ($orderCol == 'a.dates') {
$orderby = array('a.dates ' . $listOrder, 'a.times ' . $listOrder, 'a.created ' . $listOrder);
} else {
$orderby = array($orderCol . ' ' . $listOrder,
'a.dates ' . $defaultOrder, 'a.times ' . $defaultOrder, 'a.created ' . $defaultOrder);
}
$this->setState('filter.orderby', $orderby);
# params
$this->setState('params', $params);
# published
/// @todo bring given pub together with eventslist's unpub calculation (_populatePublishState())
$pub = explode(',', $app->input->getString('pub', ''));
$published = array();
// sanitize remote data
foreach ($pub as $val) {
if (((int)$val >= 1) && ((int)$val <= 2)) {
$published[] = (int)$val;
}
}
// default to 'published'
if (empty($published)) {
//$published[] = 1;
$this->_populatePublishState($task);
} else {
$this->setState('filter.published', $published);
}
# request venue-id
if ($requestVenueId) {
$this->setState('filter.req_venid', $requestVenueId);
}
# request cat-id
if ($requestCategoryId) {
$this->setState('filter.req_catid', $requestCategoryId);
}
# groupby
$this->setState('filter.groupby', array('a.id'));
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
if ($items) {
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Create a new query object.
$query = parent::getListQuery();
$requestVenueId = $this->getState('filter.req_venid');
if ($requestVenueId){
$query->where(' a.locid = '.$this->_db->quote($requestVenueId));
}
// Second is to only select events of the specified day
$query->where('('.$this->_db->quote($this->_date).' BETWEEN (a.dates) AND (IF (a.enddates >= a.dates, a.enddates, a.dates)) OR '.$this->_db->quote($this->_date).' = a.dates)');
return $query;
}
}
?>

View File

@ -0,0 +1,393 @@
<?php
/**
* @version 2.3.0
* @package JEM
* @copyright (C) 2013-2020 joomlaeventmanager.net
* @copyright (C) 2005-2009 Christoph Lukes
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
*/
defined('_JEXEC') or die;
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers');
// Create shortcuts to some parameters.
$params = $this->item->params;
$images = json_decode($this->item->datimage);
$attribs = json_decode($this->item->attribs);
$user = JemFactory::getUser();
$jemsettings = JemHelper::config();
$document = JFactory::getDocument();
// Add expiration date, if old events will be archived or removed
if ($jemsettings->oldevent > 0) {
$enddate = strtotime($this->item->enddates?:$this->item->dates);
$expDate = date("D, d M Y H:i:s", strtotime('+1 day', $enddate));
$document->addCustomTag('<meta http-equiv="expires" content="' . $expDate . '"/>');
}
JHtml::_('behavior.modal', 'a.flyermodal');
?>
<?php if ($params->get('access-view')) { /* This will show nothings otherwise - ??? */ ?>
<div id="jem" class="event_id<?php echo $this->item->did; ?> jem_event<?php echo $this->pageclass_sfx;?>"
itemscope="itemscope" itemtype="https://schema.org/Event">
<div class="buttons">
<?php
$btn_params = array('slug' => $this->item->slug, 'print_link' => $this->print_link);
echo JemOutput::createButtonBar($this->getName(), $this->permissions, $btn_params);
?>
</div>
<div class="clr"> </div>
<?php if ($this->params->get('show_page_heading', 1)) : ?>
<h1 class="componentheading">
<?php echo $this->escape($this->params->get('page_heading')); ?>
</h1>
<?php endif; ?>
<div class="clr"> </div>
<!-- Event -->
<h2 class="jem">
<?php
echo JText::_('COM_JEM_EVENT') . JemOutput::recurrenceicon($this->item);
echo JemOutput::editbutton($this->item, $params, $attribs, $this->permissions->canEditEvent, 'editevent');
echo JemOutput::copybutton($this->item, $params, $attribs, $this->permissions->canAddEvent, 'editevent');
?>
</h2>
<?php echo JemOutput::flyer($this->item, $this->dimage, 'event'); ?>
<dl class="event_info floattext">
<?php if ($params->get('event_show_detailstitle',1)) : ?>
<dt class="title"><?php echo JText::_('COM_JEM_TITLE'); ?>:</dt>
<dd class="title" itemprop="name"><?php echo $this->escape($this->item->title); ?></dd>
<?php
endif;
?>
<dt class="when"><?php echo JText::_('COM_JEM_WHEN'); ?>:</dt>
<dd class="when">
<?php
echo JemOutput::formatLongDateTime($this->item->dates, $this->item->times,$this->item->enddates, $this->item->endtimes);
echo JemOutput::formatSchemaOrgDateTime($this->item->dates, $this->item->times,$this->item->enddates, $this->item->endtimes);
?>
</dd>
<?php if ($this->item->locid != 0) : ?>
<dt class="where"><?php echo JText::_('COM_JEM_WHERE'); ?>:</dt>
<dd class="where"><?php
if (($params->get('event_show_detlinkvenue') == 1) && (!empty($this->item->url))) :
?><a target="_blank" href="<?php echo $this->item->url; ?>"><?php echo $this->escape($this->item->venue); ?></a><?php
elseif (($params->get('event_show_detlinkvenue') == 2) && (!empty($this->item->venueslug))) :
?><a href="<?php echo JRoute::_(JemHelperRoute::getVenueRoute($this->item->venueslug)); ?>"><?php echo $this->item->venue; ?></a><?php
else/*if ($params->get('event_show_detlinkvenue') == 0)*/ :
echo $this->escape($this->item->venue);
endif;
# will show "venue" or "venue - city" or "venue - city, state" or "venue, state"
$city = $this->escape($this->item->city);
$state = $this->escape($this->item->state);
if ($city) { echo ' - ' . $city; }
if ($state) { echo ', ' . $state; }
?>
</dd>
<?php
endif;
$n = is_array($this->categories) ? count($this->categories) : 0;
?>
<dt class="category"><?php echo $n < 2 ? JText::_('COM_JEM_CATEGORY') : JText::_('COM_JEM_CATEGORIES'); ?>:</dt>
<dd class="category">
<?php
$i = 0;
foreach ((array)$this->categories as $category) :
?><a href="<?php echo JRoute::_(JemHelperRoute::getCategoryRoute($category->catslug)); ?>"><?php echo $this->escape($category->catname); ?></a><?php
$i++;
if ($i != $n) :
echo ', ';
endif;
endforeach;
?>
</dd>
<?php
for ($cr = 1; $cr <= 10; $cr++) {
$currentRow = $this->item->{'custom'.$cr};
if (preg_match('%^http(s)?://%', $currentRow)) {
$currentRow = '<a href="'.$this->escape($currentRow).'" target="_blank">'.$this->escape($currentRow).'</a>';
}
if ($currentRow) {
?>
<dt class="custom<?php echo $cr; ?>"><?php echo JText::_('COM_JEM_EVENT_CUSTOM_FIELD'.$cr); ?>:</dt>
<dd class="custom<?php echo $cr; ?>"><?php echo $currentRow; ?></dd>
<?php
}
}
?>
<?php if ($params->get('event_show_hits')) : ?>
<dt class="hits"><?php echo JText::_('COM_JEM_EVENT_HITS_LABEL'); ?>:</dt>
<dd class="hits"><?php echo JText::sprintf('COM_JEM_EVENT_HITS', $this->item->hits); ?></dd>
<?php endif; ?>
<!-- AUTHOR -->
<?php if ($params->get('event_show_author') && !empty($this->item->author)) : ?>
<dt class="createdby"><?php echo JText::_('COM_JEM_EVENT_CREATED_BY_LABEL'); ?>:</dt>
<dd class="createdby">
<?php $author = $this->item->created_by_alias ? $this->item->created_by_alias : $this->item->author; ?>
<?php if (!empty($this->item->contactid2) && $params->get('event_link_author') == true) :
$needle = 'index.php?option=com_contact&view=contact&id=' . $this->item->contactid2;
$menu = JFactory::getApplication()->getMenu();
$item = $menu->getItems('link', $needle, true);
$cntlink = !empty($item) ? $needle . '&Itemid=' . $item->id : $needle;
echo JText::sprintf('COM_JEM_EVENT_CREATED_BY', JHtml::_('link', JRoute::_($cntlink), $author));
else :
echo JText::sprintf('COM_JEM_EVENT_CREATED_BY', $author);
endif;
?>
</dd>
<?php endif; ?>
<!-- PUBLISHING STATE -->
<?php if (!empty($this->showeventstate) && isset($this->item->published)) : ?>
<dt class="published"><?php echo JText::_('JSTATUS'); ?>:</dt>
<dd class="published">
<?php switch ($this->item->published) {
case 1: echo JText::_('JPUBLISHED'); break;
case 0: echo JText::_('JUNPUBLISHED'); break;
case 2: echo JText::_('JARCHIVED'); break;
case -2: echo JText::_('JTRASHED'); break;
} ?>
</dd>
<?php endif; ?>
</dl>
<!-- DESCRIPTION -->
<?php if ($params->get('event_show_description','1') && ($this->item->fulltext != '' && $this->item->fulltext != '<br />' || $this->item->introtext != '' && $this->item->introtext != '<br />')) { ?>
<h2 class="description"><?php echo JText::_('COM_JEM_EVENT_DESCRIPTION'); ?></h2>
<div class="description event_desc" itemprop="description">
<?php
if ($params->get('access-view')) {
echo $this->item->text;
}
/* optional teaser intro text for guests - NOT SUPPORTED YET */
elseif (0 /*$params->get('event_show_noauth') == true and $user->get('guest')*/ ) {
echo $this->item->introtext;
// Optional link to let them register to see the whole event.
if ($params->get('event_show_readmore') && $this->item->fulltext != null) {
$link1 = JRoute::_('index.php?option=com_users&view=login');
$link = new JUri($link1);
echo '<p class="readmore">';
echo '<a href="'.$link.'">';
if ($params->get('event_alternative_readmore') == false) {
echo JText::_('COM_JEM_EVENT_REGISTER_TO_READ_MORE');
} elseif ($readmore = $params->get('alternative_readmore')) {
echo $readmore;
}
if ($params->get('event_show_readmore_title', 0) != 0) {
echo JHtml::_('string.truncate', ($this->item->title), $params->get('event_readmore_limit'));
} elseif ($params->get('event_show_readmore_title', 0) == 0) {
} else {
echo JHtml::_('string.truncate', ($this->item->title), $params->get('event_readmore_limit'));
} ?>
</a>
</p>
<?php
}
} /* access_view / show_noauth */
?>
</div>
<?php } ?>
<!-- Contact -->
<?php if ($params->get('event_show_contact') && !empty($this->item->conid )) : ?>
<h2 class="contact"><?php echo JText::_('COM_JEM_CONTACT') ; ?></h2>
<dl class="location floattext">
<dt class="con_name"><?php echo JText::_('COM_JEM_NAME'); ?>:</dt>
<dd class="con_name">
<?php
$contact = $this->item->conname;
if ($params->get('event_link_contact') == true) :
$needle = 'index.php?option=com_contact&view=contact&id=' . $this->item->conid;
$menu = JFactory::getApplication()->getMenu();
$item = $menu->getItems('link', $needle, true);
$cntlink2 = !empty($item) ? $needle . '&Itemid=' . $item->id : $needle;
echo JText::sprintf('COM_JEM_EVENT_CONTACT', JHtml::_('link', JRoute::_($cntlink2), $contact));
else :
echo JText::sprintf('COM_JEM_EVENT_CONTACT', $contact);
endif;
?>
</dd>
<?php if ($this->item->contelephone) : ?>
<dt class="con_telephone"><?php echo JText::_('COM_JEM_TELEPHONE'); ?>:</dt>
<dd class="con_telephone">
<?php echo $this->escape($this->item->contelephone); ?>
</dd>
<?php endif; ?>
</dl>
<?php endif ?>
<?php $this->attachments = $this->item->attachments; ?>
<?php echo $this->loadTemplate('attachments'); ?>
<!-- Venue -->
<?php if (($this->item->locid != 0) && !empty($this->item->venue)) : ?>
<p></p>
<hr>
<div itemprop="location" itemscope="itemscope" itemtype="https://schema.org/Place">
<h2 class="location">
<?php
echo JText::_('COM_JEM_VENUE') ;
$itemid = $this->item ? $this->item->id : 0 ;
echo JemOutput::editbutton($this->item, $params, $attribs, $this->permissions->canEditVenue, 'editvenue');
echo JemOutput::copybutton($this->item, $params, $attribs, $this->permissions->canAddVenue, 'editvenue');
?>
</h2>
<?php echo JemOutput::flyer($this->item, $this->limage, 'venue'); ?>
<dl class="location">
<dt class="venue"><?php echo JText::_('COM_JEM_LOCATION'); ?>:</dt>
<dd class="venue">
<?php
if (!empty($this->item->venueslug)) :
echo '<a href="' . JRoute::_(JemHelperRoute::getVenueRoute($this->item->venueslug)) . '">' . $this->escape($this->item->venue) . '</a>';
else :
echo $this->escape($this->item->venue);
endif;
if (!empty($this->item->url)) :
echo '&nbsp;-&nbsp;<a target="_blank" href="' . $this->item->url . '">' . JText::_('COM_JEM_WEBSITE') . '</a>';
endif;
?>
</dd>
</dl>
<?php if ($params->get('event_show_detailsadress', '1')) : ?>
<dl class="location floattext" itemprop="address" itemscope
itemtype="https://schema.org/PostalAddress">
<?php if ($this->item->street) : ?>
<dt class="venue_street"><?php echo JText::_('COM_JEM_STREET'); ?>:</dt>
<dd class="venue_street" itemprop="streetAddress">
<?php echo $this->escape($this->item->street); ?>
</dd>
<?php endif; ?>
<?php if ($this->item->postalCode) : ?>
<dt class="venue_postalCode"><?php echo JText::_('COM_JEM_ZIP'); ?>:</dt>
<dd class="venue_postalCode" itemprop="postalCode">
<?php echo $this->escape($this->item->postalCode); ?>
</dd>
<?php endif; ?>
<?php if ($this->item->city) : ?>
<dt class="venue_city"><?php echo JText::_('COM_JEM_CITY'); ?>:</dt>
<dd class="venue_city" itemprop="addressLocality">
<?php echo $this->escape($this->item->city); ?>
</dd>
<?php endif; ?>
<?php if ($this->item->state) : ?>
<dt class="venue_state"><?php echo JText::_('COM_JEM_STATE'); ?>:</dt>
<dd class="venue_state" itemprop="addressRegion">
<?php echo $this->escape($this->item->state); ?>
</dd>
<?php endif; ?>
<?php if ($this->item->country) : ?>
<dt class="venue_country"><?php echo JText::_('COM_JEM_COUNTRY'); ?>:</dt>
<dd class="venue_country">
<?php echo $this->item->countryimg ? $this->item->countryimg : $this->item->country; ?>
<meta itemprop="addressCountry" content="<?php echo $this->item->country; ?>" />
</dd>
<?php endif; ?>
<!-- PUBLISHING STATE -->
<?php if (!empty($this->showvenuestate) && isset($this->item->locpublished)) : ?>
<dt class="venue_published"><?php echo JText::_('JSTATUS'); ?>:</dt>
<dd class="venue_published">
<?php switch ($this->item->locpublished) {
case 1: echo JText::_('JPUBLISHED'); break;
case 0: echo JText::_('JUNPUBLISHED'); break;
case 2: echo JText::_('JARCHIVED'); break;
case -2: echo JText::_('JTRASHED'); break;
} ?>
</dd>
<?php endif; ?>
<?php
for ($cr = 1; $cr <= 10; $cr++) {
$currentRow = $this->item->{'venue'.$cr};
if (preg_match('%^http(s)?://%', $currentRow)) {
$currentRow = '<a href="' . $this->escape($currentRow) . '" target="_blank">' . $this->escape($currentRow) . '</a>';
}
if ($currentRow) {
?>
<dt class="custom<?php echo $cr; ?>"><?php echo JText::_('COM_JEM_VENUE_CUSTOM_FIELD'.$cr); ?>:</dt>
<dd class="custom<?php echo $cr; ?>"><?php echo $currentRow; ?></dd>
<?php
}
}
?>
<?php if ($params->get('event_show_mapserv') == 1) : ?>
<?php echo JemOutput::mapicon($this->item, 'event', $params); ?>
<?php endif; ?>
</dl>
<?php if ($params->get('event_show_mapserv') == 2) : ?>
<?php echo JemOutput::mapicon($this->item, 'event', $params); ?>
<?php endif; ?>
<?php if ($params->get('event_show_mapserv') == 3) : ?>
<input type="hidden" id="latitude" value="<?php echo $this->item->latitude; ?>">
<input type="hidden" id="longitude" value="<?php echo $this->item->longitude; ?>">
<input type="hidden" id="venue" value="<?php echo $this->item->venue; ?>">
<input type="hidden" id="street" value="<?php echo $this->item->street; ?>">
<input type="hidden" id="city" value="<?php echo $this->item->city; ?>">
<input type="hidden" id="state" value="<?php echo $this->item->state; ?>">
<input type="hidden" id="postalCode" value="<?php echo $this->item->postalCode; ?>">
<?php echo JemOutput::mapicon($this->item, 'event', $params); ?>
<?php endif; ?>
<?php endif; /* event_show_detailsadress */ ?>
<?php if ($params->get('event_show_locdescription', '1') && $this->item->locdescription != ''
&& $this->item->locdescription != '<br />') : ?>
<h2 class="location_desc"><?php echo JText::_('COM_JEM_VENUE_DESCRIPTION'); ?></h2>
<div class="description location_desc" itemprop="description">
<?php echo $this->item->locdescription; ?>
</div>
<?php endif; ?>
<?php $this->attachments = $this->item->vattachments; ?>
<?php echo $this->loadTemplate('attachments'); ?>
</div>
<?php endif; ?>
<!-- Registration -->
<?php if ($this->showAttendees) : ?>
<p></p>
<hr>
<h2 class="register"><?php echo JText::_('COM_JEM_REGISTRATION'); ?>:</h2>
<?php echo $this->loadTemplate('attendees'); ?>
<?php endif; ?>
<?php if (!empty($this->item->pluginevent->onEventEnd)) : ?>
<p></p>
<hr>
<?php echo $this->item->pluginevent->onEventEnd; ?>
<?php endif; ?>
<div class="copyright">
<?php echo JemOutput::footer(); ?>
</div>
</div>
<?php }
?>

View File

@ -0,0 +1,559 @@
<?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\Pagination\Pagination;
use Joomla\CMS\Filter\InputFilter;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
// Base this model on the backend version.
require_once JPATH_ADMINISTRATOR . '/components/com_jem/models/event.php';
/**
* Editevent Model
*/
class JemModelEditevent extends JemModelEvent
{
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*/
protected function populateState()
{
$app = Factory::getApplication();
// Load state from the request.
$pk = $app->input->getInt('a_id', 0);
$this->setState('event.id', $pk);
$fromId = $app->input->getInt('from_id', 0);
$this->setState('event.from_id', $fromId);
$catid = $app->input->getInt('catid', 0);
$this->setState('event.catid', $catid);
$locid = $app->input->getInt('locid', 0);
$this->setState('event.locid', $locid);
$date = $app->input->getCmd('date', '');
$this->setState('event.date', $date);
$return = $app->input->get('return', '', 'base64');
$this->setState('return_page', base64_decode($return));
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
$this->setState('layout', $app->input->getCmd('layout', ''));
}
/**
* Method to get event data.
*
* @param integer The id of the event.
*
* @return mixed item data object on success, false on failure.
*/
public function getItem($itemId = null)
{
$jemsettings = JemHelper::config();
// Initialise variables.
$itemId = (int) (!empty($itemId)) ? $itemId : $this->getState('event.id');
$doCopy = false;
if (!$itemId && $this->getState('event.from_id')) {
$itemId = $this->getState('event.from_id');
$doCopy = true;
}
// Get a row instance.
$table = $this->getTable();
// Attempt to load the row.
$return = $table->load($itemId);
// Check for a table object error.
if ($return === false && $table->getError()) {
$this->setError($table->getError());
return false;
}
$properties = $table->getProperties(1);
$value = ArrayHelper::toObject($properties, 'stdClass');
if ($doCopy) {
$value->id = 0;
$value->author_ip = '';
$value->created = '';
$value->created_by = '';
$value->created_by_alias = '';
$value->modified = '';
$value->modified_by = '';
$value->version = '';
$value->hits = '';
$value->recurrence_type = 0;
$value->recurrence_first_id = 0;
$value->recurrence_counter = 0;
}
// Backup current recurrence values
if ($value->id) {
$value->recurr_bak = new stdClass;
foreach (get_object_vars($value) as $k => $v) {
if (strncmp('recurrence_', $k, 11) === 0) {
$value->recurr_bak->$k = $v;
}
}
}
// Convert attrib field to Registry.
$registry = new Registry();
$registry->loadString($value->attribs ?? '{}');
$globalregistry = JemHelper::globalattribs();
$value->params = clone $globalregistry;
$value->params->merge($registry);
// Compute selected asset permissions.
$user = JemFactory::getUser();
//$userId = $user->get('id');
//$asset = 'com_jem.event.' . $value->id;
//$asset = 'com_jem';
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('count(id)'));
$query->from('#__jem_register');
$query->where(array('event = ' . $db->quote($value->id), 'waiting = 0', 'status = 1'));
$db->setQuery($query);
$res = $db->loadResult();
$value->booked = (int)$res;
if (!empty($value->maxplaces)) {
$value->avplaces = $value->maxplaces - $value->booked;
}
// Get attachments - but not on copied events
$files = JemAttachment::getAttachments('event' . $value->id);
$value->attachments = $files;
// Preset values on new events
if (!$itemId) {
$catid = (int) $this->getState('event.catid');
$locid = (int) $this->getState('event.locid');
$date = $this->getState('event.date');
// ???
if (empty($value->catid) && !empty($catid)) {
$value->catid = $catid;
}
if (empty($value->locid) && !empty($locid)) {
$value->locid = $locid;
}
if (empty($value->dates) && JemHelper::isValidDate($date)) {
$value->dates = $date;
}
}
// Check edit permission.
$value->params->set('access-edit', $user->can('edit', 'event', $value->id, $value->created_by));
// Check edit state permission.
if (!$itemId && ($catId = (int) $this->getState('event.catid'))) {
// New item.
$cats = array($catId);
} else {
// Existing item (or no category)
$cats = false;
}
$value->params->set('access-change', $user->can('publish', 'event', $value->id, $value->created_by, $cats));
$value->author_ip = $jemsettings->storeip ? JemHelper::retrieveIP() : false;
$value->articletext = $value->introtext;
if (!empty($value->fulltext)) {
$value->articletext .= '<hr id="system-readmore" />' . $value->fulltext;
}
return $value;
}
protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false)
{
// JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
return parent::loadForm($name, $source, $options, $clear, $xpath);
}
/**
* Get the return URL.
*
* @return string return URL.
*/
public function getReturnPage()
{
return base64_encode($this->getState('return_page'));
}
############
## VENUES ##
############
/**
* Get venues-data
*/
public function getVenues()
{
$query = $this->buildQueryVenues();
$pagination = $this->getVenuesPagination();
$rows = $this->_getList($query, $pagination->limitstart, $pagination->limit);
return $rows;
}
/**
* venues-query
*/
protected function buildQueryVenues()
{
$app = Factory::getApplication();
$params = JemHelper::globalattribs();
$filter_order = $app->getUserStateFromRequest('com_jem.selectvenue.filter_order', 'filter_order', 'l.venue', 'cmd');
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.selectvenue.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word');
$filter_order = InputFilter::getinstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getinstance()->clean($filter_order_Dir, 'word');
$filter_type = $app->getUserStateFromRequest('com_jem.selectvenue.filter_type', 'filter_type', 0, 'int');
$search = $app->getUserStateFromRequest('com_jem.selectvenue.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('l.id','l.state','l.city','l.country','l.published','l.venue','l.ordering'));
$query->from('#__jem_venues as l');
// where
$where = array();
$where[] = 'l.published = 1';
/* something to search for? (we like to search for "0" too) */
if ($search || ($search === "0")) {
switch ($filter_type) {
case 1: /* Search venues */
$where[] = 'LOWER(l.venue) LIKE "%' . $search . '%"';
break;
case 2: // Search city
$where[] = 'LOWER(l.city) LIKE "%' . $search . '%"';
break;
case 3: // Search state
$where[] = 'LOWER(l.state) LIKE "%' . $search . '%"';
}
}
if ($params->get('global_show_ownedvenuesonly')) {
$user = JemFactory::getUser();
$userid = $user->get('id');
$where[] = ' created_by = ' . (int) $userid;
}
$query->where($where);
if (strtoupper($filter_order_Dir) !== 'DESC') {
$filter_order_Dir = 'ASC';
}
// ordering
if ($filter_order && $filter_order_Dir) {
$orderby = $filter_order . ' ' . $filter_order_Dir;
} else {
$orderby = array('l.venue ASC','l.ordering ASC');
}
$query->order($orderby);
return $query;
}
/**
* venues-Pagination
**/
public function getVenuesPagination()
{
$jemsettings = JemHelper::config();
$app = Factory::getApplication();
$limit = $app->getUserStateFromRequest('com_jem.selectvenue.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$query = $this->buildQueryVenues();
$total = $this->_getListCount($query);
// Create the pagination object
$pagination = new Pagination($total, $limitstart, $limit);
return $pagination;
}
##############
## CONTACTS ##
##############
/**
* Get contacts-data
*/
public function getContacts()
{
$query = $this->buildQueryContacts();
$pagination = $this->getContactsPagination();
$rows = $this->_getList($query, $pagination->limitstart, $pagination->limit);
return $rows;
}
/**
* contacts-Pagination
**/
public function getContactsPagination()
{
$jemsettings = JemHelper::config();
$app = Factory::getApplication();
$limit = $app->getUserStateFromRequest('com_jem.selectcontact.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$query = $this->buildQueryContacts();
$total = $this->_getListCount($query);
// Create the pagination object
$pagination = new Pagination($total, $limitstart, $limit);
return $pagination;
}
/**
* contacts-query
*/
protected function buildQueryContacts()
{
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$filter_order = $app->getUserStateFromRequest('com_jem.selectcontact.filter_order', 'filter_order', 'con.ordering', 'cmd');
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.selectcontact.filter_order_Dir', 'filter_order_Dir', '', 'word');
$filter_order = InputFilter::getinstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getinstance()->clean($filter_order_Dir, 'word');
$filter_type = $app->getUserStateFromRequest('com_jem.selectcontact.filter_type', 'filter_type', 0, 'int');
$search = $app->getUserStateFromRequest('com_jem.selectcontact.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('con.*'));
$query->from('#__contact_details As con');
// where
$where = array();
$where[] = 'con.published = 1';
/* something to search for? (we like to search for "0" too) */
if ($search || ($search === "0")) {
switch ($filter_type) {
case 1: /* Search name */
$where[] = ' LOWER(con.name) LIKE \'%' . $search . '%\' ';
break;
case 2: /* Search address (not supported yet, privacy) */
//$where[] = ' LOWER(con.address) LIKE \'%' . $search . '%\' ';
break;
case 3: // Search city
$where[] = ' LOWER(con.suburb) LIKE \'%' . $search . '%\' ';
break;
case 4: // Search state
$where[] = ' LOWER(con.state) LIKE \'%' . $search . '%\' ';
break;
}
}
$query->where($where);
// ordering
// ensure it's a valid order direction (asc, desc or empty)
if (!empty($filter_order_Dir) && strtoupper($filter_order_Dir) !== 'DESC') {
$filter_order_Dir = 'ASC';
}
if ($filter_order != '') {
$orderby = $filter_order . ' ' . $filter_order_Dir;
if ($filter_order != 'con.name') {
$orderby = array($orderby, 'con.name'); // in case of city or state we should have a useful second ordering
}
} else {
$orderby = 'con.name';
}
$query->order($orderby);
return $query;
}
###########
## USERS ##
###########
/**
* Get users data
*/
public function getUsers()
{
$query = $this->buildQueryUsers();
$pagination = $this->getUsersPagination();
$rows = $this->_getList($query, $pagination->limitstart, $pagination->limit);
// Add registration status if available
$itemId = (int)$this->getState('event.id');
$db = Factory::getContainer()->get('DatabaseDriver');
$qry = $db->getQuery(true);
// #__jem_register (id, event, uid, waiting, status, comment)
$qry->select(array('reg.uid, reg.status, reg.waiting, reg.places'));
$qry->from('#__jem_register As reg');
$qry->where('reg.event = ' . $itemId);
$db->setQuery($qry);
$regs = $db->loadObjectList('uid');
// JemHelper::addLogEntry((string)$qry . "\n" . print_r($regs, true), __METHOD__);
foreach ($rows AS &$row) {
if (array_key_exists($row->id, $regs)) {
$row->status = $regs[$row->id]->status;
$row->places = $regs[$row->id]->places;
if ($row->status == 1 && $regs[$row->id]->waiting) {
++$row->status;
}
} else {
$row->status = -99;
$row->places = 0;
}
}
return $rows;
}
/**
* users-Pagination
**/
public function getUsersPagination()
{
$jemsettings = JemHelper::config();
$app = Factory::getApplication();
$limit = 0;//$app->getUserStateFromRequest('com_jem.selectusers.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = 0;//$app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$query = $this->buildQueryUsers();
$total = $this->_getListCount($query);
// Create the pagination object
$pagination = new Pagination($total, $limitstart, $limit);
return $pagination;
}
/**
* users-query
*/
protected function buildQueryUsers()
{
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
// no filters, hard-coded
$filter_order = 'usr.name';
$filter_order_Dir = '';
$filter_type = '';
$search = '';
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('usr.id, usr.name'));
$query->from('#__users As usr');
// where
$where = array();
$where[] = 'usr.block = 0';
$where[] = 'NOT usr.activation > 0';
/* something to search for? (we like to search for "0" too) */
if ($search || ($search === "0")) {
switch ($filter_type) {
case 1: /* Search name */
$where[] = ' LOWER(usr.name) LIKE \'%' . $search . '%\' ';
break;
}
}
$query->where($where);
// ordering
// ensure it's a valid order direction (asc, desc or empty)
if (!empty($filter_order_Dir) && strtoupper($filter_order_Dir) !== 'DESC') {
$filter_order_Dir = 'ASC';
}
if ($filter_order != '') {
$orderby = $filter_order . ' ' . $filter_order_Dir;
if ($filter_order != 'usr.name') {
$orderby = array($orderby, 'usr.name'); // in case of (???) we should have a useful second ordering
}
} else {
$orderby = 'usr.name ' . $filter_order_Dir;
}
$query->order($orderby);
return $query;
}
/**
* Get list of invited users.
*/
public function getInvitedUsers()
{
$itemId = (int)$this->getState('event.id');
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
// #__jem_register (id, event, uid, waiting, status, comment)
$query->select(array('reg.uid'));
$query->from('#__jem_register As reg');
$query->where('reg.event = ' . $itemId);
$query->where('reg.status = 0');
$db->setQuery($query);
$regs = $db->loadColumn();
// JemHelper::addLogEntry((string)$query . "\n" . implode(',', $regs), __METHOD__);
return $regs;
}
}

View File

@ -0,0 +1,146 @@
<?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\Utilities\ArrayHelper;
// Base this model on the backend version.
require_once JPATH_ADMINISTRATOR . '/components/com_jem/models/venue.php';
/**
* Editvenue Model
*/
class JemModelEditvenue extends JemModelVenue
{
/**
* Model typeAlias string. Used for version history.
* @var string
*/
public $typeAlias = 'com_jem.venue';
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*/
protected function populateState()
{
$app = Factory::getApplication();
// Load state from the request.
$pk = $app->input->getInt('a_id', 0);
$this->setState('venue.id', $pk);
$fromId = $app->input->getInt('from_id', 0);
$this->setState('venue.from_id', $fromId);
$return = $app->input->get('return', '', 'base64');
$this->setState('return_page', base64_decode($return));
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
$this->setState('layout', $app->input->getCmd('layout', ''));
}
/**
* Method to get venue data.
*
* @param integer The id of the venue.
* @return mixed item data object on success, false on failure.
*/
public function getItem($itemId = null)
{
$jemsettings = JemHelper::config();
$user = JemFactory::getUser();
// Initialise variables.
$itemId = (int) (!empty($itemId)) ? $itemId : $this->getState('venue.id');
$doCopy = false;
if (!$itemId && $this->getState('venue.from_id')) {
$itemId = $this->getState('venue.from_id');
$doCopy = true;
}
// Get a row instance.
$table = $this->getTable();
// Attempt to load the row.
$return = $table->load($itemId);
// Check for a table object error.
if ($return === false && $table->getError()) {
$this->setError($table->getError());
return false;
}
$properties = $table->getProperties(1);
$value = ArrayHelper::toObject($properties, 'stdClass');
if ($doCopy) {
$value->id = 0;
$value->author_ip = '';
$value->created = '';
$value->created_by = '';
$value->modified = '';
$value->modified_by = '';
$value->version = '';
}
// Convert attrib field to Registry.
//$registry = new Registry();
//$registry->loadString($value->attribs);
$globalregistry = JemHelper::globalattribs();
$value->params = clone $globalregistry;
//$value->params->merge($registry);
// Compute selected asset permissions.
// Check edit permission.
$value->params->set('access-edit', $user->can('edit', 'venue', $value->id, $value->created_by));
// Check edit state permission.
$value->params->set('access-change', $user->can('publish', 'venue', $value->id, $value->created_by));
$value->author_ip = $jemsettings->storeip ? JemHelper::retrieveIP() : false;
// Get attachments - but not on copied venues
$files = JemAttachment::getAttachments('venue' . $value->id);
$value->attachments = $files;
// Preset values on new venues
if (isset($jemsettings->defaultCountry) && empty($itemId)) {
$value->country = $jemsettings->defaultCountry;
}
return $value;
}
protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false)
{
// JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
return parent::loadForm($name, $source, $options, $clear, $xpath);
}
/**
* Get the return URL.
*
* @return string return URL.
*/
public function getReturnPage()
{
return base64_encode($this->getState('return_page'));
}
}

View File

@ -0,0 +1,977 @@
<?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\Filter\OutputFilter;
use Joomla\CMS\MVC\Model\ItemModel;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\Registry\Registry;
/**
* Event-Model
*/
class JemModelEvent extends ItemModel
{
/**
* Model context string.
*
* @var string
*/
protected $_context = 'com_jem.event';
protected $_registers = null;
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*/
protected function populateState()
{
$app = Factory::getApplication('site');
// Load state from the request.
$pk = $app->input->getInt('id', 0);
$this->setState('event.id', $pk);
$offset = $app->input->getInt('limitstart', 0);
$this->setState('list.offset', $offset);
// Load the parameters.
$params = $app->getParams('com_jem');
$this->setState('params', $params);
$this->setState('filter.language', Multilanguage::isEnabled());
}
/**
* Method to get event data.
*
* @param int The id of the event.
* @return mixed item data object on success, false on failure.
*/
public function getItem($pk = null)
{
// Initialise variables.
$pk = (!empty($pk)) ? $pk : (int) $this->getState('event.id');
if ($this->_item === null) {
$this->_item = array();
}
if (!isset($this->_item[$pk]))
{
try
{
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
# Event
$query->select(
$this->getState('item.select',
'a.id, a.id AS did, a.title, a.alias, a.dates, a.enddates, a.times, a.endtimes, a.access, a.attribs, a.metadata, ' .
'a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10, ' .
'a.created, a.created_by, a.published, a.registra, a.registra_from, a.registra_until, a.unregistra, a.unregistra_until, a.reginvitedonly, ' .
'CASE WHEN a.modified = 0 THEN a.created ELSE a.modified END as modified, a.modified_by, ' .
'a.checked_out, a.checked_out_time, a.datimage, a.version, a.featured, ' .
'a.seriesbooking, a.singlebooking, a.meta_keywords, a.meta_description, a.created_by_alias, a.introtext, a.fulltext, a.maxplaces, a.reservedplaces, a.minbookeduser, a.maxbookeduser, a.waitinglist, a.requestanswer, ' .
'a.hits, a.language, a.recurrence_type, a.recurrence_first_id'));
$query->from('#__jem_events AS a');
# Author
$name = $settings->get('global_regname','1') ? 'u.name' : 'u.username';
$query->select($name.' AS author');
$query->join('LEFT', '#__users AS u on u.id = a.created_by');
# Contact
$query->select('con.id AS conid, con.name AS conname, con.catid AS concatid, con.telephone AS contelephone, con.email_to AS conemail');
$query->join('LEFT', '#__contact_details AS con ON con.id = a.contactid');
# Venue
$query->select('l.custom1 AS venue1, l.custom2 AS venue2, l.custom3 AS venue3, l.custom4 AS venue4, l.custom5 AS venue5, ' .
'l.custom6 AS venue6, l.custom7 AS venue7, l.custom8 AS venue8, l.custom9 AS venue9, l.custom10 AS venue10, ' .
'l.id AS locid, l.alias AS localias, l.venue, l.city, l.state, l.url, l.locdescription, l.locimage, ' .
'l.postalCode, l.street, l.country, l.map, l.created_by AS venueowner, l.latitude, l.longitude, ' .
'l.checked_out AS vChecked_out, l.checked_out_time AS vChecked_out_time, l.published as locpublished');
$query->join('LEFT', '#__jem_venues AS l ON a.locid = l.id');
# Join over the category tables
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.itemid = a.id');
$query->join('LEFT', '#__jem_categories AS c ON c.id = rel.catid');
# Get contact id
$subQuery = $db->getQuery(true);
$subQuery->select('MAX(contact.id) AS id');
$subQuery->from('#__contact_details AS contact');
$subQuery->where('contact.published = 1');
$subQuery->where('contact.user_id = a.created_by');
# Filter contact by language
if ($this->getState('filter.language')) {
$subQuery->where('(contact.language in (' . $db->quote(Factory::getApplication()->getLanguage()->getTag()) . ',' . $db->quote('*') . ') OR contact.language IS NULL)');
}
$query->select('(' . $subQuery . ') as contactid2');
# Filter event by language
/* commented out yet because it's incomplete
if ($this->getState('filter.language')) {
$query->where('a.language in (' . $db->quote(Factory::getApplication()->getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
}
*/
$query->where('a.id = ' . (int) $pk);
# Filter by published state ==> later.
// It would result in too complicated query.
// It's easier to get data and check then e.g. for event owner etc.
# Filter by categories
$cats = $this->getCategories('all');
if (!empty($cats)) {
$query->where('c.id IN (' . implode(',', $cats) . ')');
}
# Get the item
//$query->group('a.id');
// if ($error = $db->getErrorMsg()) {
// throw new Exception($error);
// }
try
{
$db->setQuery($query);
$data = $db->loadObject();
}
catch (RuntimeException $e)
{
Factory::getApplication()->enqueueMessage($e->getMessage(), 'notice');
}
if (empty($data)) {
throw new Exception(Text::_('COM_JEM_EVENT_ERROR_EVENT_NOT_FOUND'), 404);
}
# Convert parameter fields to objects.
$registry = new Registry;
$registry->loadString($data->attribs);
$data->params = JemHelper::globalattribs(); // returns Registry object
$data->params->merge($registry);
$registry = new Registry;
$registry->loadString($data->metadata);
$data->metadata = $registry;
$data->categories = $this->getCategories($pk);
# Compute selected asset permissions.
$access_edit = $user->can('edit', 'event', $data->id, $data->created_by);
$access_view = (($data->published == 1) || ($data->published == 2) || // published and archived event
(($data->published == 0) && $access_edit) || // unpublished for editors,
$user->can('publish', 'event', $data->id, $data->created_by)); // all for publishers
$data->params->set('access-edit', $access_edit);
# Compute view access permissions.
# event can be shown if
# - user has matching view access level and
# - there is at least one category attached user can see and
# - publishing state and user permissions allow that (e.g. unpublished event but user is editor, owner, or publisher)
$data->params->set('access-view', $access_view && !empty($data->categories) && in_array($data->access, $levels));
$this->_item[$pk] = $data;
}
catch (Exception $e)
{
if ($e->getCode() == 404) {
// Need to go thru the error handler to allow Redirect to
// work.
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return false;
}
else {
$this->setError($e);
$this->_item[$pk] = false;
return false;
}
}
}
# Get event attachments
$this->_item[$pk]->attachments = JemAttachment::getAttachments('event' . $this->_item[$pk]->did);
# Get venue attachments
$this->_item[$pk]->vattachments = JemAttachment::getAttachments('venue' . $this->_item[$pk]->locid);
// Define Booked
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('SUM(places)');
$query->from('#__jem_register');
$query->where(array('event = ' . $db->quote($this->_item[$pk]->did), 'waiting = 0', 'status = 1'));
$db->setQuery($query);
try {
$res = $db->loadResult();
}
catch (Exception $e) {
$res = 0;
}
$this->_item[$pk]->booked = $res;
return $this->_item[$pk];
}
/**
* Method to get list recurrence events data.
*
* @param int The id of the event.
* @param int The id of the parent event.
* @return mixed item data object on success, false on failure.
*/
public function getListRecurrenceEventsbyId ($id, $pk, $datetimeFrom, $iduser=null, $status=null)
{
// Initialise variables.
$pk = (!empty($pk)) ? $pk : (int) $this->getState('event.id');
if ($this->_item === null) {
$this->_item = array();
}
try
{
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
# Event
$query->select(
$this->getState('item.select',
'a.id, a.id AS did, a.title, a.alias, a.dates, a.enddates, a.times, a.endtimes, a.access, a.attribs, a.metadata, ' .
'a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10, ' .
'a.created, a.created_by, a.published, a.registra, a.registra_from, a.registra_until, a.unregistra, a.unregistra_until, ' .
'CASE WHEN a.modified = 0 THEN a.created ELSE a.modified END as modified, a.modified_by, ' .
'a.checked_out, a.checked_out_time, a.datimage, a.version, a.featured, ' .
'a.seriesbooking, a.singlebooking, a.meta_keywords, a.meta_description, a.created_by_alias, a.introtext, a.fulltext, a.maxplaces, a.reservedplaces, a.minbookeduser, a.maxbookeduser, a.waitinglist, a.requestanswer, ' .
'a.hits, a.language, a.recurrence_type, a.recurrence_first_id' . ($iduser? ', r.waiting, r.places, r.status':''))) ;
$query->from('#__jem_events AS a');
# Author
$name = $settings->get('global_regname','1') ? 'u.name' : 'u.username';
$query->select($name.' AS author');
$query->join('LEFT', '#__users AS u on u.id = a.created_by');
# Contact
$query->select('con.id AS conid, con.name AS conname, con.telephone AS contelephone, con.email_to AS conemail');
$query->join('LEFT', '#__contact_details AS con ON con.id = a.contactid');
# Venue
$query->select('l.custom1 AS venue1, l.custom2 AS venue2, l.custom3 AS venue3, l.custom4 AS venue4, l.custom5 AS venue5, ' .
'l.custom6 AS venue6, l.custom7 AS venue7, l.custom8 AS venue8, l.custom9 AS venue9, l.custom10 AS venue10, ' .
'l.id AS locid, l.alias AS localias, l.venue, l.city, l.state, l.url, l.locdescription, l.locimage, ' .
'l.postalCode, l.street, l.country, l.map, l.created_by AS venueowner, l.latitude, l.longitude, ' .
'l.checked_out AS vChecked_out, l.checked_out_time AS vChecked_out_time, l.published as locpublished');
$query->join('LEFT', '#__jem_venues AS l ON a.locid = l.id');
# Join over the category tables
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.itemid = a.id');
$query->join('LEFT', '#__jem_categories AS c ON c.id = rel.catid');
# Get contact id
$subQuery = $db->getQuery(true);
$subQuery->select('MAX(contact.id) AS id');
$subQuery->from('#__contact_details AS contact');
$subQuery->where('contact.published = 1');
$subQuery->where('contact.user_id = a.created_by');
# Filter contact by language
if ($this->getState('filter.language')) {
$subQuery->where('(contact.language in (' . $db->quote(Factory::getApplication()->getLanguage()->getTag()) . ',' . $db->quote('*') . ') OR contact.language IS NULL)');
}
# If $iduser is defined, then the events list is filtered by registration of this user
if($iduser) {
$query->join('LEFT', '#__jem_register AS r ON r.event = a.id');
$query->where("r.uid = " . $iduser );
}
// Not include the delete event
$query->where("a.published != -2");
$query->select('(' . $subQuery . ') as contactid2');
$dateFrom = date('Y-m-d', $datetimeFrom);
$timeFrom = date('H:i:s', $datetimeFrom);
$query->where('((a.recurrence_first_id = 0 AND a.id = ' . (int)($pk?$pk:$id) . ') OR a.recurrence_first_id = ' . (int)($pk?$pk:$id) . ')');
$query->where("(a.dates > '" . $dateFrom . "' OR a.dates = '" . $dateFrom . "' AND dates >= '" . $timeFrom . "')");
$query->order('a.dates ASC');
try
{
$db->setQuery($query);
$data = $db->loadObjectList();
}
catch (RuntimeException $e)
{
Factory::getApplication()->enqueueMessage($e->getMessage(), 'notice');
}
if (empty($data)) {
if(!$iduser) {
throw new Exception(Text::_('COM_JEM_EVENT_ERROR_EVENT_NOT_FOUND'), 404);
}else{
return false;
}
}
# Convert parameter fields to objects.
$registry = new Registry;
$registry->loadString($data[0]->attribs);
$data[0]->params = JemHelper::globalattribs(); // returns Registry object
$data[0]->params->merge($registry);
$registry = new Registry;
$registry->loadString($data[0]->metadata);
$data[0]->metadata = $registry;
$data[0]->categories = $this->getCategories($pk);
# Compute selected asset permissions.
$access_edit = $user->can('edit', 'event', $data[0]->id, $data[0]->created_by);
$access_view = (($data[0]->published == 1) || ($data[0]->published == 2) || // published and archived event
(($data[0]->published == 0) && $access_edit) || // unpublished for editors,
$user->can('publish', 'event', $data[0]->id, $data[0]->created_by)); // all for publishers
$data[0]->params->set('access-edit', $access_edit);
# Compute view access permissions.
# event can be shown if
# - user has matching view access level and
# - there is at least one category attached user can see and
# - publishing state and user permissions allow that (e.g. unpublished event but user is editor, owner, or publisher)
$data[0]->params->set('access-view', $access_view && !empty($data[0]->categories) && in_array($data[0]->access, $levels));
$this->_item[$pk] = $data[0];
}
catch (Exception $e)
{
if ($e->getCode() == 404) {
// Need to go thru the error handler to allow Redirect to
// work.
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return false;
}
else {
$this->setError($e);
$this->_item[$pk] = false;
return false;
}
}
# Get event attachments
$this->_item[$pk]->attachments = JemAttachment::getAttachments('event' . $this->_item[$pk]->did);
# Get venue attachments
$this->_item[$pk]->vattachments = JemAttachment::getAttachments('venue' . $this->_item[$pk]->locid);
// Define Booked
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('SUM(places)');
$query->from('#__jem_register');
$query->where(array('event = ' . $db->quote($this->_item[$id]->did), 'waiting = 0', 'status = 1'));
$db->setQuery($query);
try {
$res = $db->loadObject();
}
catch (Exception $e) {
$res = 0;
}
$this->_item[$id]->booked = $res;
return $data;
}
/**
* Increment the hit counter for the event.
*
* @param int Optional primary key of the event to increment.
* @return boolean if successful; false otherwise and internal error set.
*/
public function hit($pk = 0)
{
$hitcount = Factory::getApplication()->input->getInt('hitcount', 1);
if ($hitcount) {
// Initialise variables.
$pk = (!empty($pk)) ? $pk : (int) $this->getState('event.id');
$db = Factory::getContainer()->get('DatabaseDriver');
$db->setQuery('UPDATE #__jem_events' . ' SET hits = hits + 1' . ' WHERE id = ' . (int) $pk);
try {
if ($db->execute() === false) {
$this->setError($db->getErrorMsg());
return false;
}
}
catch (Exception $e) {
$this->setError($e);
return false;
}
}
return true;
}
/**
* Retrieve Categories
*
* Due to multi-cat this function is needed
* filter-index (4) is pointing to the cats
*/
public function getCategories($id = 0)
{
$id = (!empty($id)) ? $id : (int) $this->getState('event.id');
$user = JemFactory::getUser();
// $userid = (int)$user->get('id');
$levels = $user->getAuthorisedViewLevels();
// $app = Factory::getApplication();
// $params = $app->getParams();
// $catswitch = $params->get('categoryswitch', '0');
$settings = JemHelper::globalattribs();
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$case_when_c = ' CASE WHEN ';
$case_when_c .= $query->charLength('c.alias');
$case_when_c .= ' THEN ';
$id_c = $query->castAsChar('c.id');
$case_when_c .= $query->concatenate(array($id_c, 'c.alias'), ':');
$case_when_c .= ' ELSE ';
$case_when_c .= $id_c.' END as catslug';
$query->select(array('DISTINCT c.id','c.catname','c.access','c.checked_out AS cchecked_out','c.color',$case_when_c,'c.groupid'));
$query->from('#__jem_categories as c');
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.catid = c.id');
$query->select(array('a.id AS multi'));
$query->join('LEFT','#__jem_events AS a ON a.id = rel.itemid');
if ($id != 'all'){
$query->where('rel.itemid ='.(int)$id);
}
$query->where('c.published = 1');
###################################
## FILTER - MAINTAINER/JEM GROUP ##
###################################
# as maintainter someone who is registered can see a category that has special rights
# let's see if the user has access to this category.
// $query3 = $db->getQuery(true);
// $query3 = 'SELECT gr.id'
// . ' FROM #__jem_groups AS gr'
// . ' LEFT JOIN #__jem_groupmembers AS g ON g.group_id = gr.id'
// . ' WHERE g.member = ' . (int) $user->get('id')
// //. ' AND ' .$db->quoteName('gr.addevent') . ' = 1 '
// . ' AND g.member NOT LIKE 0';
// $db->setQuery($query3);
// $groupnumber = $db->loadColumn();
$groups = implode(',', $levels);
// $jemgroups = implode(',',$groupnumber);
// if ($jemgroups) {
// $query->where('(c.access IN ('.$groups.') OR c.groupid IN ('.$jemgroups.'))');
// } else {
$query->where('(c.access IN ('.$groups.'))');
// }
#######################
## FILTER - CATEGORY ##
#######################
# set filter for top_category
$top_cat = $this->getState('filter.category_top');
if ($top_cat) {
$query->where($top_cat);
}
# filter set by day-view
$requestCategoryId = (int)$this->getState('filter.req_catid');
if ($requestCategoryId) {
$query->where('c.id = '.$requestCategoryId);
}
# Filter by a single or group of categories.
$categoryId = $this->getState('filter.category_id');
if (is_numeric($categoryId)) {
$type = $this->getState('filter.category_id.include', true) ? '= ' : '<> ';
$query->where('c.id '.$type.(int) $categoryId);
}
elseif (is_array($categoryId) && count($categoryId)) {
\Joomla\Utilities\ArrayHelper::toInteger($categoryId);
$categoryId = implode(',', $categoryId);
$type = $this->getState('filter.category_id.include', true) ? 'IN' : 'NOT IN';
$query->where('c.id '.$type.' ('.$categoryId.')');
}
###################
## FILTER-SEARCH ##
###################
# define variables
$filter = $this->getState('filter.filter_type');
$search = $this->getState('filter.filter_search'); // not escaped
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('c.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%', false); // escape once
if($search && $settings->get('global_show_filter')) {
if ($filter == 4) {
$query->where('c.catname LIKE '.$search);
}
}
}
}
$db->setQuery($query);
try {
if ($id == 'all'){
$cats = $db->loadColumn(0);
$cats = array_unique($cats);
} else {
$cats = $db->loadObjectList();
}
}
catch (Exception $e) {
$cats = false;
}
return $cats;
}
/**
* Method to get user registration data if available.
*
* @access public
* @return mixed false if not registered, object with id, status, comment else
* status -1 if not attending, 0 if invited,
* 1 if attending, 2 if on waiting list
*/
public function getUserRegistration($eventId = null, $userid = 0)
{
// Initialize variables
$userid = (int)$userid;
if (empty($userid)) {
$user = JemFactory::getUser();
$userid = (int) $user->get('id', 0);
}
$eventId = (int)$eventId;
if (empty($eventId)) {
$eventId = $this->getState('event.id');
}
// usercheck
// -1 if user will not attend, 0 if invened/unknown, 1 if registeredm 2 if on waiting list
$query = 'SELECT IF (status > 0, waiting + 1, status) AS status, id, comment, places'
. ' FROM #__jem_register'
. ' WHERE uid = ' . $this->_db->quote($userid)
. ' AND event = ' . $this->_db->quote($eventId);
$this->_db->setQuery($query);
try {
$result = $this->_db->loadObject();
}
catch (Exception $e) {
$result = false;
}
return $result;
}
/**
* Method to check if the user is already registered
*
* @access public
* @return mixed false if not registered, -1 if not attending,
* 0 if invited, 1 if attending, 2 if on waiting list
*/
public function getUserIsRegistered($eventId = null)
{
$obj = $this->getUserRegistration($eventId);
if (is_object($obj) && isset($obj->status)) {
return $obj->status;
} else {
return false;
}
}
/**
* Method to get the registered users
*
* @access public
* @return object
*/
public function getRegisters($event = false, $status = 1)
{
if (empty($event)) {
return false;
}
// avatars should be displayed
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
$db = Factory::getContainer()->get('DatabaseDriver');
$avatar = '';
$join = '';
if ($settings->get('event_comunoption','0') == 1 && $settings->get('event_comunsolution','0') == 1) {
$avatar = ', c.avatar';
$join = ' LEFT JOIN #__comprofiler as c ON c.user_id = r.uid';
}
$name = ', ' . ($settings->get('global_regname','1') ? 'u.name' : 'u.username') . ' as name';
$where[] = 'event = '. $db->quote($event);
if (is_numeric($status)) {
if ($status == 2) {
$where[] = 'waiting = 1';
$where[] = 'status = 1';
} else {
$where[] = 'waiting = 0';
$where[] = 'status = ' . (int)$status;
}
} elseif ($status !== 'all') {
$where[] = 'waiting = 0';
$where[] = 'status = 1';
}
// Get registered users
$query = $db->getQuery(true);
$query = 'SELECT IF(r.status = 1 AND r.waiting = 1, 2, r.status) as status, r.uid, r.comment, r.places'
. $name . $avatar
. ' FROM #__jem_register AS r'
. ' LEFT JOIN #__users AS u ON u.id = r.uid'
. $join
. ' WHERE ' . implode(' AND ', $where);
$db->setQuery($query);
try {
$registered = $db->loadObjectList();
}
catch (Exception $e) {
$registered = false;
}
return $registered;
}
public function setId($id)
{
// Set new event ID and wipe data
$this->_registerid = $id;
}
/**
* Internal helper to store registration on database
*
* @param int $eventId id of event
* @param int $uid id of user to register
* @param mixed $uip ip address or false
* @param int $status registration status
* @param int $places number to add/cancel places of registration
* @param string $comment optional comment
* @param string &$errMsg gets a message in error cases
* @param int $regid id of registration record to change or 0 if new (default)
* @param bool $respectPlaces if true adapt status/waiting depending on event's free places,
* may return error if no free places and no waiting list
*
* @access protected
* @return int register id on success, else false
*/
protected function _doRegister($eventId, $uid, $uip, $status, $places, $comment, &$errMsg, $regid = 0, $respectPlaces = true)
{
// $app = Factory::getApplication('site');
// $user = JemFactory::getUser();
// $jemsettings = JemHelper::config();
$registration = (empty($uid) || empty($eventId)) ? false : $this->getUserRegistration($eventId, $uid);
$onwaiting = 0;
try {
$event = $this->getItem($eventId);
}
// some gently error handling
catch (Exception $e) {
$event = false;
}
if (empty($event)) {
$errMsg = Text::_('COM_JEM_EVENT_ERROR_EVENT_NOT_FOUND');
return false;
}
$oldstat = is_object($registration) ? $registration->status : 0;
if ($status == 1 && $status != $oldstat) {
if ($respectPlaces && ($event->maxplaces > 0)) { // there is a max
// check if the user should go on waiting list
if ($event->booked >= $event->maxplaces) {
if (!$event->waitinglist) {
$this->setError(Text::_('COM_JEM_EVENT_FULL_NOTICE'));
return false;
}
$onwaiting = 1;
}
}
}
elseif ($status == 2) {
if ($respectPlaces && !$event->waitinglist) {
$errMsg = Text::_('COM_JEM_NO_WAITINGLIST');
return false;
}
$onwaiting = 1;
$status = 1;
}
elseif ($respectPlaces && ($oldstat == 1) && ($status == -1) && !$event->unregistra) {
$errMsg = Text::_('COM_JEM_ERROR_ANNULATION_NOT_ALLOWED');
return false;
}
$obj = new stdClass();
$obj->event = (int)$eventId;
$obj->status = (int)$status;
$obj->places = (int)$places;
$obj->waiting = $onwaiting;
$obj->uid = (int)$uid;
$obj->uregdate = gmdate('Y-m-d H:i:s');
$obj->uip = $uip;
$obj->comment = $comment;
$result = false;
try {
if ($regid) {
$obj->id = $regid;
$this->_db->updateObject('#__jem_register', $obj, 'id');
$result = $regid;
} else {
$this->_db->insertObject('#__jem_register', $obj);
$result = $this->_db->insertid();
}
}
catch (Exception $e) {
// we have a unique user-event key so registering twice will fail
$errMsg = Text::_(($e->getCode() == 1062) ? 'COM_JEM_ALREADY_REGISTERED' : 'COM_JEM_ERROR_REGISTRATION');
return false;
}
return $result;
}
/**
* Saves the registration to the database
*
* @access public
* @return int register id on success, else false
*/
public function userregister()
{
$app = Factory::getApplication('site');
$user = JemFactory::getUser();
$jemsettings = JemHelper::config();
$status = $app->input->getInt('reg_check', 0);
// $noreg = ($status == -1) ? 'on' : 'off';//$app->input->getString('noreg_check', 'off');
$comment = $app->input->getString('reg_comment', '');
$comment = OutputFilter::cleanText($comment);
$regid = $app->input->getInt('regid', 0);
$addplaces = $app->input->getInt('addplaces', 0);
$cancelplaces = $app->input->getInt('cancelplaces', 0);
$checkseries = $app->input->getString('reg_check_series', '0');
$checkseries = ($checkseries === 'true' || $checkseries === 'on' || $checkseries === '1');
$uid = (int) $user->get('id');
$eventId = (int) $this->_registerid;
$events = array();
try {
$event = $this->getItem($eventId);
}
catch (Exception $e) {
$event = false;
}
// If event has 'seriesbooking' active and $checkseries is true then get all recurrence events of series from now (register or unregister)
if($event->recurrence_type){
if(($event->seriesbooking && !$event->singlebooking) || ($event->singlebooking && $checkseries)) {
$events = $this->getListRecurrenceEventsbyId($event->id, $event->recurrence_first_id, time());
}
}
if (!isset($events) || !count ($events)){
$events [] = clone $event;
}
foreach ($events as $e) {
$reg = $this->getUserRegistration($e->id);
$errMsg = '';
if ($status > 0) {
if ($addplaces > 0) {
if ($reg) {
if ($reg->status > 0) {
$places = $addplaces + $reg->places;
} else {
$places = $addplaces;
}
} else {
$places = $addplaces;
}
//Detect if the reserve go to waiting list
$placesavailableevent = $e->maxplaces - $e->reservedplaces - $e->booked;
if ($reg->status != 0 || $reg == null) {
if ($e->maxplaces) {
$placesavailableevent = $e->maxplaces - $e->reservedplaces - $e->booked;
if ($e->waitinglist && $placesavailableevent <= 0) {
$status = 2;
}
} else {
$status = 1;
}
}
} else {
$places = 0;
}
} else {
if ($reg) {
$places = $reg->places - $cancelplaces;
if ($reg->status >= 0 && $places > 0) {
$status = $reg->status;
}
} else {
$places = 0;
}
}
//Review max places per user
if ($e->maxbookeduser) {
if ($places > $e->maxbookeduser) {
$places = $e->maxbookeduser;
}
}
// Must be logged in
if ($uid < 1) {
Factory::getApplication()->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error');
return;
}
// IP
$uip = $jemsettings->storeip ? JemHelper::retrieveIP() : false;
$result = $this->_doRegister($e->id, $uid, $uip, $status, $places, $comment, $errMsg, $reg->id);
if (!$result) {
$this->setError(Text::_('COM_JEM_ERROR_REGISTRATION') . ' [id: ' . $e->id . ']');
} else {
Factory::getApplication()->enqueueMessage(($status==1? Text::_('COM_JEM_REGISTERED_USER_IN_EVENT') : Text::_('COM_JEM_UNREGISTERED_USER_IN_EVENT')), 'info');
}
}
return $result;
}
/**
* Saves the registration to the database
*
* @param int $eventId id of event
* @param int $uid id of user to register
* @param int $status registration status
* @param string $comment optional comment
* @param string &$errMsg gets a message in error cases
* @param int $regid id of registration record to change or 0 if new (default)
* @param bool $respectPlaces if true adapt status/waiting depending on event's free places,
* may return error if no free places and no waiting list
*
* @access public
* @return int register id on success, else false
*/
public function adduser($eventId, $uid, $status, $places, $comment, &$errMsg, $regid = 0, $respectPlaces = true)
{
// $app = Factory::getApplication('site');
$user = JemFactory::getUser();
$jemsettings = JemHelper::config();
// Acting user must be logged in
if ($user->get('id') < 1) {
\Joomla\CMS\Factory::getApplication()->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error');
return false;
}
// IP
$uip = $jemsettings->storeip ? JemHelper::retrieveIP() : false;
$result = $this->_doRegister($eventId, $uid, $uip, $status, $places, $comment, $errMsg, $regid, $respectPlaces);
return $result;
}
/**
* Deletes a registered user
*
* @access public
* @return true on success
*/
public function delreguser()
{
$user = JemFactory::getUser();
$userid = (int)$user->get('id');
$event = (int)$this->_registerid;
// Must be logged in
if ($userid < 1) {
Factory::getApplication()->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error');
return;
}
$query = 'DELETE FROM #__jem_register WHERE event = ' . $event . ' AND uid= ' . $userid;
$this->_db->SetQuery($query);
if ($this->_db->execute() === false) {
throw new Exception($this->_db->getErrorMsg(), 500);
}
return true;
}
}
?>

View File

@ -0,0 +1,967 @@
<?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\Filter\InputFilter;
use Joomla\Registry\Registry;
use Joomla\CMS\MVC\Model\ListModel;
// ensure JemFactory is loaded (because model is used by modules too)
require_once(JPATH_SITE.'/components/com_jem/factory.php');
/**
* Model-Eventslist
**/
class JemModelEventslist extends ListModel
{
/**
* Constructor.
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id', 'a.id',
'title', 'a.title',
'dates', 'a.dates',
'times', 'a.times',
'alias', 'a.alias',
'venue', 'l.venue','venue_title',
'city', 'l.city', 'venue_city',
'checked_out', 'a.checked_out',
'checked_out_time', 'a.checked_out_time',
'c.catname', 'category_title',
'state', 'a.state',
'access', 'a.access', 'access_level',
'created', 'a.created',
'created_by', 'a.created_by',
'ordering', 'a.ordering',
'featured', 'a.featured',
'language', 'a.language',
'hits', 'a.hits',
'publish_up', 'a.publish_up',
'publish_down', 'a.publish_down',
);
}
parent::__construct($config);
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$task = $app->input->getCmd('task','');
$format = $app->input->getCmd('format',false);
$itemid = $app->input->getInt('id', 0) . ':' . $app->input->getInt('Itemid', 0);
$params = $app->getParams();
# limit/start
if (empty($format) || ($format == 'html')) {
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->get('limitstart', null, 'int') === null) {
$app->setUserState('com_jem.eventslist.'.$itemid.'.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.limit', 'limit', $jemsettings->display_num, 'int');
$this->setState('list.limit', $limit);
$limitstart = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('list.start', $limitstart);
}
# Search - variables
$search = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.filter_search', 'filter_search', '', 'string');
$this->setState('filter.filter_search', $search); // must be escaped later
$filtertype = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.filter_type', 'filter_type', 0, 'int');
$this->setState('filter.filter_type', $filtertype);
$filtermonth = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.filter_month', 'filter_month', 0, 'string');
$this->setState('filter.filter_month', $filtermonth);
# Search - Filter by setting menu
$today = new DateTime();
$filterDaysBefore = $params->get('tablefiltereventfrom','');
if ($filterDaysBefore){
$dateFrom = (clone $today)->modify('-' . $filterDaysBefore . ' days')->format('Y-m-d');
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), "'. $dateFrom .'") >= 0';
$this->setState('filter.calendar_from',$where);
}
$filterDaysAfter = $params->get('tablefiltereventuntil','');
if ($filterDaysAfter){
$dateTo = (clone $today)->modify( $filterDaysAfter . ' days')->format('Y-m-d');
$where = ' DATEDIFF(a.dates, "'. $dateTo . '") <= 0';
$this->setState('filter.calendar_to',$where);
}
# publish state
$this->_populatePublishState($task);
$params = $app->getParams();
$this->setState('params', $params);
###############
## opendates ##
###############
$this->setState('filter.opendates', $params->get('showopendates', 0));
###########
## ORDER ##
###########
$filter_order = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.filter_order', 'filter_order', 'a.dates', 'cmd');
$filter_order_DirDefault = 'ASC';
// Reverse default order for dates in archive mode
if ($task == 'archive' && $filter_order == 'a.dates') {
$filter_order_DirDefault = 'DESC';
}
$filter_reset = $app->input->getInt('filter_reset', 0);
if ($filter_reset && $filter_order == 'a.dates') {
$app->setUserState('com_jem.eventslist.'.$itemid.'.filter_order_Dir', $filter_order_DirDefault);
}
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.eventslist.'.$itemid.'.filter_order_Dir', 'filter_order_Dir', $filter_order_DirDefault, 'word');
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
$default_order_Dir = ($task == 'archive') ? 'DESC' : 'ASC';
if(!isset($_REQUEST["filter_type"])) {
$tableInitialorderby = $params->get('tableorderby', '0');
if ($tableInitialorderby) {
switch ($tableInitialorderby) {
case 0:
$tableInitialorderby = 'a.dates';
break;
case 1:
$tableInitialorderby = 'a.title';
break;
case 2:
$tableInitialorderby = 'l.venue';
break;
case 3:
$tableInitialorderby = 'l.city';
break;
case 4:
$tableInitialorderby = 'l.state';
break;
case 5:
$tableInitialorderby = 'c.catname';
break;
}
$filter_order = $app->getUserStateFromRequest('com_jem.eventslist.' . $itemid . '.filter_order', 'filter_order', $tableInitialorderby, 'cmd');
}
$tableInitialDirectionOrder = $params->get('tabledirectionorder', 'ASC');
if ($tableInitialDirectionOrder) {
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.eventslist.' . $itemid . '.filter_order_Dir', 'filter_order_Dir', $tableInitialDirectionOrder, 'word');
}
}
$orderby = array($filter_order . ' ' . $filter_order_Dir, 'a.dates ' . $default_order_Dir, 'a.times ' . $default_order_Dir, 'a.created ' . $default_order_Dir);
$this->setState('filter.orderby',$orderby);
################################
## EXCLUDE/INCLUDE CATEGORIES ##
################################
$catswitch = $params->get('categoryswitch', '');
$cats = trim($params->get('categoryswitchcats', ''));
$list_cats=[];
if ($cats){
$ids_cats = explode(",", $cats);
if ($params->get('includesubcategories', 0))
{
//get subcategories
foreach($ids_cats as $idcat)
{
if (!in_array($idcat, $list_cats))
{
$list_cats[] = $idcat;
$child_cat = $this->getListChildCat($idcat, 1);
if ($child_cat !== false) {
if(count($child_cat) > 0) {
foreach ($child_cat as $child)
{
if (!in_array($child, $list_cats))
{
$list_cats[] = (string) $child;
}
}
}
}
}
}
}else{
$list_cats=$ids_cats;
}
if ($catswitch)
{
# set included categories
$this->setState('filter.category_id', $list_cats);
$this->setState('filter.category_id.include', true);
}else{
# set excluded categories
$this->setState('filter.category_id', $list_cats);
$this->setState('filter.category_id.include', false);
}
}
$this->setState('filter.groupby',array('a.id'));
}
/**
* Method to get a all list of children categories (subtree) by $id category.
*/
public function getListChildCat($id, $reset){
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$settings = JemHelper::globalattribs();
static $catchildlist=[];
if($reset){
foreach ($catchildlist as $k => $c){
unset($catchildlist[$k]);
}
}
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('DISTINCT c.id'));
$query->from('#__jem_categories as c');
$query->where('c.published = 1');
$query->where('(c.access IN ('.implode(',', $levels).'))');
$query->where('c.parent_id =' . (int) $id);
$db->setQuery($query);
$cats = $db->loadObjectList();
if ($cats != null) {
foreach ($cats as $cat){
$catchildlist[] = $cat->id;
$this->getListChildCat($cat->id,0);
}
return $catchildlist;
}
return false;
}
/**
* set limit
*/
public function setLimit($value)
{
$this->setState('list.limit', (int) $value);
}
/**
* set limitstart
*/
public function setLimitStart($value)
{
$this->setState('list.start', (int) $value);
}
/**
* Method to get a store id based on model configuration state.
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . serialize($this->getState('filter.published'));
$id .= ':' . $this->getState('filter.opendates');
$id .= ':' . $this->getState('filter.featured');
$id .= ':' . serialize($this->getState('filter.event_id'));
$id .= ':' . $this->getState('filter.event_id.include');
$id .= ':' . serialize($this->getState('filter.category_id'));
$id .= ':' . $this->getState('filter.category_id.include');
$id .= ':' . serialize($this->getState('filter.venue_id'));
$id .= ':' . $this->getState('filter.venue_id.include');
$id .= ':' . $this->getState('filter.venue_state');
$id .= ':' . $this->getState('filter.venue_state.mode');
$id .= ':' . $this->getState('filter.filter_search');
$id .= ':' . $this->getState('filter.filter_type');
$id .= ':' . $this->getState('list.start');
$id .= ':' . $this->getState('list.limit');
$id .= ':' . serialize($this->getState('filter.groupby'));
$id .= ':' . serialize($this->getState('filter.orderby'));
$id .= ':' . $this->getState('filter.category_top');
$id .= ':' . $this->getState('filter.calendar_multiday');
$id .= ':' . $this->getState('filter.calendar_startdayonly');
$id .= ':' . $this->getState('filter.show_archived_events');
$id .= ':' . $this->getState('filter.req_venid');
$id .= ':' . $this->getState('filter.req_catid');
$id .= ':' . $this->getState('filter.unpublished');
$id .= ':' . serialize($this->getState('filter.unpublished.events.on_groups'));
$id .= ':' . $this->getState('filter.unpublished.venues');
$id .= ':' . $this->getState('filter.unpublished.on_user');
return parent::getStoreId($id);
}
/**
* Build the query
*/
protected function getListQuery()
{
$app = Factory::getApplication();
$task = $app->input->getCmd('task', '');
$itemid = $app->input->getInt('id', 0) . ':' . $app->input->getInt('Itemid', 0);
$params = $app->getParams();
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
# Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
# Event
$query->select(
$this->getState('list.select',
'a.access,a.alias,a.attribs,a.checked_out,a.checked_out_time,a.contactid,a.created,a.created_by,a.created_by_alias,a.custom1,a.custom2,a.custom3,a.custom4,a.custom5,a.custom6,a.custom7,a.custom8,a.custom9,a.custom10,a.dates,a.datimage,a.enddates,a.endtimes,a.featured,' .
'a.fulltext,a.hits,a.id,a.introtext,a.language,a.locid,a.maxplaces,a.reservedplaces,a.minbookeduser,a.maxbookeduser,a.metadata,a.meta_keywords,a.meta_description,a.modified,a.modified_by,a.published,a.registra,a.times,a.title,a.unregistra,a.waitinglist,a.requestanswer,a.seriesbooking,a.singlebooking, DAYOFMONTH(a.dates) AS created_day, YEAR(a.dates) AS created_year, MONTH(a.dates) AS created_month,' .
'a.recurrence_byday,a.recurrence_counter,a.recurrence_first_id,a.recurrence_limit,a.recurrence_limit_date,a.recurrence_number, a.recurrence_type,a.version'
)
);
$query->from('#__jem_events as a');
# Author
$name = $settings->get('global_regname','1') ? 'u.name' : 'u.username';
$query->select($name.' AS author');
$query->join('LEFT', '#__users AS u on u.id = a.created_by');
# Venue
$query->select(array('l.alias AS l_alias','l.checked_out AS l_checked_out','l.checked_out_time AS l_checked_out_time','l.city','l.country','l.created AS l_created','l.created_by AS l_createdby'));
$query->select(array('l.custom1 AS l_custom1','l.custom2 AS l_custom2','l.custom3 AS l_custom3','l.custom4 AS l_custom4','l.custom5 AS l_custom5','l.custom6 AS l_custom6','l.custom7 AS l_custom7','l.custom8 AS l_custom8','l.custom9 AS l_custom9','l.custom10 AS l_custom10'));
$query->select(array('l.id AS l_id','l.latitude','l.locdescription','l.locimage','l.longitude','l.map','l.meta_description AS l_meta_description','l.meta_keywords AS l_meta_keywords','l.modified AS l_modified','l.modified_by AS l_modified_by','l.postalCode'));
$query->select(array('l.publish_up AS l_publish_up','l.publish_down AS l_publish_down','l.published AS l_published','l.state','l.street','l.url','l.venue','l.version AS l_version'));
$query->join('LEFT', '#__jem_venues AS l ON l.id = a.locid');
# Country
$query->select(array('ct.name AS countryname'));
$query->join('LEFT', '#__jem_countries AS ct ON ct.iso2 = l.country');
# the rest
$case_when_e = ' CASE WHEN ';
$case_when_e .= $query->charLength('a.alias','!=', '0');
$case_when_e .= ' THEN ';
$id_e = $query->castAsChar('a.id');
$case_when_e .= $query->concatenate(array($id_e, 'a.alias'), ':');
$case_when_e .= ' ELSE ';
$case_when_e .= $id_e.' END as slug';
$case_when_l = ' CASE WHEN ';
$case_when_l .= $query->charLength('l.alias', '!=', '0');
$case_when_l .= ' THEN ';
$id_l = $query->castAsChar('a.locid');
$case_when_l .= $query->concatenate(array($id_l, 'l.alias'), ':');
$case_when_l .= ' ELSE ';
$case_when_l .= $id_l.' END as venueslug';
$query->select(array($case_when_e, $case_when_l));
# join over the category-tables
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.itemid = a.id');
$query->join('LEFT', '#__jem_categories AS c ON c.id = rel.catid');
#############
## FILTERS ##
#############
#####################
## FILTER - EVENTS ##
#####################
# Filter by a single or group of events.
$eventId = $this->getState('filter.event_id');
if (is_numeric($eventId)) {
$type = $this->getState('filter.event_id.include', true) ? '= ' : '<> ';
$query->where('a.id '.$type.(int) $eventId);
}
elseif (is_array($eventId) && !empty($eventId)) {
\Joomla\Utilities\ArrayHelper::toInteger($eventId);
$eventId = implode(',', $eventId);
$type = $this->getState('filter.event_id.include', true) ? 'IN' : 'NOT IN';
$query->where('a.id '.$type.' ('.$eventId.')');
}
###################
## FILTER-ACCESS ##
###################
# Filter by access level - always.
$query->where('a.access IN ('.implode(',', $levels).')');
####################
## FILTER-PUBLISH ##
####################
# Filter by published state.
$where_pub = $this->_getPublishWhere();
if (!empty($where_pub)) {
$query->where('(' . implode(' OR ', $where_pub) . ')');
} else {
// something wrong - fallback to published events
$query->where('a.published = 1');
}
#####################
## FILTER-FEATURED ##
#####################
# Filter by featured flag.
$featured = $this->getState('filter.featured');
if (is_numeric($featured)) {
$query->where('a.featured = ' . (int) $featured);
}
elseif (is_array($featured) && !empty($featured)) {
\Joomla\Utilities\ArrayHelper::toInteger($featured);
$featured = implode(',', $featured);
$query->where('a.featured IN ('.$featured.')');
}
#############################
## FILTER - CALENDAR_DATES ##
#############################
$cal_from = $this->getState('filter.calendar_from');
$cal_to = $this->getState('filter.calendar_to');
$cal_month = $this->getState('filter.filter_month');
if ($cal_month) {
$cal_month = DateTime::createFromFormat('Y-m', $cal_month);
$filter_date_from = $cal_month->format('Y-m-01');
$filter_date_to = $cal_month->modify('last day of this month')->format('Y-m-d');
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), "'. $filter_date_from .'") >= 0';
$this->setState('filter.calendar_from',$where);
$where = ' DATEDIFF(a.dates, "'. $filter_date_to . '") <= 0';
$this->setState('filter.calendar_to',$where);
$cal_from = $this->getState('filter.calendar_from');
$cal_to = $this->getState('filter.calendar_to');
}
if ($cal_from) {
$query->where($cal_from);
}
if ($cal_to) {
$query->where($cal_to);
}
#############################
## FILTER - OPEN_DATES ##
#############################
$opendates = $this->getState('filter.opendates');
switch ($opendates) {
case 0: // don't show events without start date
default:
$query->where('a.dates IS NOT NULL');
break;
case 1: // show all events, with or without start date
break;
case 2: // show only events without startdate
$query->where('a.dates IS NULL');
break;
}
#####################
### FILTER - BYCAT ##
#####################
$filter_catid = $this->getState('filter.filter_catid');
if ($filter_catid) { // categorycal
$query->where('c.id = '.(int)$filter_catid);
} else {
$cats = $this->getCategories('all');
if (!empty($cats)) {
$query->where('c.id IN (' . implode(',', $cats) . ')');
}
}
####################
## FILTER - BYLOC ##
####################
$filter_locid = $this->getState('filter.filter_locid');
if ($filter_locid) {
$query->where('a.locid = '.(int)$filter_locid);
}
####################
## FILTER - VENUE ##
####################
$venueId = $this->getState('filter.venue_id');
if (is_numeric($venueId)) {
$type = $this->getState('filter.venue_id.include', true) ? '= ' : '<> ';
$query->where('l.id '.$type.(int) $venueId);
}
elseif (is_array($venueId) && !empty($venueId)) {
\Joomla\Utilities\ArrayHelper::toInteger($venueId);
$venueId = implode(',', $venueId);
$type = $this->getState('filter.venue_id.include', true) ? 'IN' : 'NOT IN';
$query->where('l.id '.$type.' ('.$venueId.')');
}
##########################
## FILTER - VENUE STATE ##
##########################
$venueState = $this->getState('filter.venue_state');
if (!empty($venueState)) {
$venueState = explode(',', $venueState);
$venueStateMode = $this->getState('filter.venue_state.mode', 0);
switch ($venueStateMode) {
case 0: # complete match: venue's state must be equal (ignoring upper/lower case) one of the strings given by filter
default:
array_walk($venueState, function(&$v,$k,$db) { $v = $db->quote(trim($v)); }, $db);
$query->where('l.state IN ('.implode(',', $venueState).')');
break;
case 1: # contain: venue's state must contain one of the strings given by filter
array_walk($venueState, function(&$v,$k,$db) { $v = quotemeta($db->escape(trim($v), true)); }, $db);
$query->where('l.state REGEXP '.$db->quote(implode('|', $venueState)));
break;
}
}
###################
## FILTER-SEARCH ##
###################
# define variables
$filter = $this->getState('filter.filter_type');
$search = $this->getState('filter.filter_search'); // not escaped
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('a.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%', false); // escape once
if ($search && $settings->get('global_show_filter')) {
switch ($filter) {
# case 4 is category, so it is omitted
case 1:
$query->where('a.title LIKE '.$search);
break;
case 2:
$query->where('l.venue LIKE '.$search);
break;
case 3:
$query->where('l.city LIKE '.$search);
break;
case 5:
$query->where('l.state LIKE '.$search);
break;
}
}
}
}
# Group
$group = $this->getState('filter.groupby');
if ($group) {
$query->group($group);
}
# ordering
$orderby = $this->getState('filter.orderby');
if ($orderby) {
$query->order($orderby);
}
return $query;
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
if (empty($items)) {
return array();
}
$user = JemFactory::getUser();
$calendarMultiday = $this->getState('filter.calendar_multiday');
$stateParams = $this->getState('params');
# Convert the parameter fields into objects.
foreach ($items as $index => $item)
{
$eventParams = new Registry;
$eventParams->loadString($item->attribs);
if (empty($stateParams)) {
$item->params = new Registry;
$item->params->merge($eventParams);
} else {
$item->params = clone $stateParams;
$item->params->merge($eventParams);
}
# adding categories
$item->categories = $this->getCategories($item->id);
# check if the item-categories is empty, if so the user has no access to that event at all.
if (empty($item->categories)) {
unset ($items[$index]);
continue;
} else {
# write access permissions.
$item->params->set('access-edit', $user->can('edit', 'event', $item->id, $item->created_by));
}
} // foreach
if ($items) {
/*$items =*/ JemHelper::getAttendeesNumbers($items);
if ($calendarMultiday) {
$items = self::calendarMultiday($items);
}
}
return $items;
}
/**
* Retrieve Categories
*
* Due to multi-cat this function is needed
* filter-index (4) is pointing to the cats
*/
public function getCategories($id)
{
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$settings = JemHelper::globalattribs();
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$case_when_c = ' CASE WHEN ';
$case_when_c .= $query->charLength('c.alias');
$case_when_c .= ' THEN ';
$id_c = $query->castAsChar('c.id');
$case_when_c .= $query->concatenate(array($id_c, 'c.alias'), ':');
$case_when_c .= ' ELSE ';
$case_when_c .= $id_c.' END as catslug';
$query->select(array('DISTINCT c.id','c.catname','c.access','c.checked_out AS cchecked_out','c.color',$case_when_c));
$query->from('#__jem_categories as c');
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.catid = c.id');
$query->select(array('a.id AS multi'));
$query->join('LEFT','#__jem_events AS a ON a.id = rel.itemid');
if ($id != 'all'){
$query->where('rel.itemid ='.(int)$id);
}
$query->where('c.published = 1');
###################
## FILTER-ACCESS ##
###################
# Filter by access level.
###################################
## FILTER - MAINTAINER/JEM GROUP ##
###################################
# -as maintainter someone who is registered can see a category that has special rights-
# -let's see if the user has access to this category.-
# ==> No. On frontend everybody needs proper access levels to see things. No exceptions.
// $query3 = $db->getQuery(true);
// $query3 = 'SELECT gr.id'
// . ' FROM #__jem_groups AS gr'
// . ' LEFT JOIN #__jem_groupmembers AS g ON g.group_id = gr.id'
// . ' WHERE g.member = ' . (int) $user->get('id')
// //. ' AND ' .$db->quoteName('gr.addevent') . ' = 1 '
// . ' AND g.member NOT LIKE 0';
// $db->setQuery($query3);
// $groupnumber = $db->loadColumn();
// $jemgroups = implode(',',$groupnumber);
// JEM groups doesn't overrule view access levels!
// if ($jemgroups) {
// $query->where('(c.access IN ('.$groups.') OR c.groupid IN ('.$jemgroups.'))');
// } else {
$query->where('(c.access IN ('.implode(',', $levels).'))');
// }
#######################
## FILTER - CATEGORY ##
#######################
# set filter for top_category
$top_cat = $this->getState('filter.category_top');
if ($top_cat) {
$query->where($top_cat);
}
# Filter by a single or group of categories.
$categoryId = $this->getState('filter.category_id');
if (is_numeric($categoryId)) {
$type = $this->getState('filter.category_id.include', true) ? '= ' : '<> ';
$query->where('c.id '.$type.(int) $categoryId);
}
elseif (is_array($categoryId) && !empty($categoryId)) {
\Joomla\Utilities\ArrayHelper::toInteger($categoryId);
$categoryId = implode(',', $categoryId);
$type = $this->getState('filter.category_id.include', true) ? 'IN' : 'NOT IN';
$query->where('c.id '.$type.' ('.$categoryId.')');
}
# filter set by day-view
$requestCategoryId = $this->getState('filter.req_catid');
if ($requestCategoryId) {
$query->where('c.id = '.(int)$requestCategoryId);
}
###################
## FILTER-SEARCH ##
###################
# define variables
$filter = $this->getState('filter.filter_type');
$search = $this->getState('filter.filter_search'); // not escaped
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('c.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%', false); // escape once
if ($search && $settings->get('global_show_filter')) {
if ($filter == 4) {
$query->where('c.catname LIKE '.$search);
}
}
}
}
$db->setQuery($query);
if ($id == 'all') {
$cats = $db->loadColumn(0);
$cats = array_unique($cats);
return ($cats);
} else {
$cats = $db->loadObjectList();
}
return $cats;
}
/**
* create multi-day events
*/
protected function calendarMultiday($items)
{
if (empty($items)) {
return array();
}
$startdayonly = $this->getState('filter.calendar_startdayonly');
if (!$startdayonly) {
foreach ($items as $item)
{
if (!is_null($item->enddates) && ($item->enddates != $item->dates)) {
$day = $item->start_day;
$multi = array();
# it's multiday regardless if other days are on next month
$item->multi = 'first';
$item->multitimes = $item->times;
$item->multiname = $item->title;
$item->sort = 'zlast';
for ($counter = 0; $counter <= $item->datesdiff-1; $counter++)
{
# next day:
$day++;
$nextday = mktime(0, 0, 0, $item->start_month, $day, $item->start_year);
# ensure we only generate days of current month in this loop
if (date('m', $this->_date) == date('m', $nextday)) {
$multi[$counter] = clone $item;
$multi[$counter]->dates = date('Y-m-d', $nextday);
if ($multi[$counter]->dates < $item->enddates) {
$multi[$counter]->multi = 'middle';
$multi[$counter]->multistartdate = $item->dates;
$multi[$counter]->multienddate = $item->enddates;
$multi[$counter]->multitimes = $item->times;
$multi[$counter]->multiname = $item->title;
$multi[$counter]->times = $item->times;
$multi[$counter]->endtimes = $item->endtimes;
$multi[$counter]->sort = 'middle';
} elseif ($multi[$counter]->dates == $item->enddates) {
$multi[$counter]->multi = 'zlast';
$multi[$counter]->multistartdate = $item->dates;
$multi[$counter]->multienddate = $item->enddates;
$multi[$counter]->multitimes = $item->times;
$multi[$counter]->multiname = $item->title;
$multi[$counter]->sort = 'first';
$multi[$counter]->times = $item->times;
$multi[$counter]->endtimes = $item->endtimes;
}
}
} // for
# add generated days to data
$items = array_merge($items, $multi);
# unset temp array holding generated days before working on the next multiday event
unset($multi);
}
} // foreach
}
# Sort the items
foreach ($items as $item) {
$time[] = $item->times;
$title[] = $item->title;
}
array_multisort($time, SORT_ASC, $title, SORT_ASC, $items);
return $items;
}
/**
* Helper method to auto-populate publishing related model state.
* Can be called in populateState()
*/
protected function _populatePublishState($task)
{
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$user = JemFactory::getUser();
$userId = $user->id ?? null;
# publish state
$format = $app->input->getCmd('format', '');
if ($task == 'archive') {
$this->setState('filter.published', 2);
} elseif (($format == 'raw') || ($format == 'feed')) {
$this->setState('filter.published', 1);
} else {
$show_unpublished = $user->can(array('edit', 'publish'), 'event', false, false, 1);
if ($show_unpublished) {
// global editor or publisher permission
$publishedStates = $this->show_archived_events ? array(0, 1, 2) : array(0, 1);
$this->setState('filter.published', $publishedStates);
} else {
// no global permission but maybe on event level
$this->setState('filter.published', 1);
$this->setState('filter.unpublished', 0);
$jemgroups = $user->getJemGroups(array('editevent', 'publishevent'));
if (($userId !== 0) && ($jemsettings->eventedit == -1)) {
$jemgroups[0] = true; // we need key 0 to get unpublished events not attached to any jem group
}
// user permitted on that jem groups
if (is_array($jemgroups) && count($jemgroups)) {
$this->setState('filter.unpublished.events.on_groups', array_keys($jemgroups));
}
// user permitted on own events
if (($userId !== 0) && ($user->authorise('core.edit.own', 'com_jem') || $jemsettings->eventowner)) {
$this->setState('filter.unpublished.on_user', $userId);
}
}
}
}
/**
* Helper method to create publishing related where clauses.
* Can be called in getListQuery()
*
* @param $tbl table alias to use
*
* @return array where clauses related to publishing state and user permissons
* to combine with OR
*/
protected function _getPublishWhere($tbl = 'a')
{
$tbl = empty($tbl) ? '' : $this->_db->quoteName($tbl) . '.';
$where_pub = array();
# Filter by published state.
$published = $this->getState('filter.published');
$show_archived_events = $this->getState('filter.show_archived_events');
if (is_numeric($published)) {
$where_pub[] = '(' . $tbl . 'published ' . ($show_archived_events? '>=':'=') . (int)$published . ')';
}
elseif (is_array($published) && !empty($published)) {
\Joomla\Utilities\ArrayHelper::toInteger($published);
$published = implode(',', $published);
$where_pub[] = '(' . $tbl . 'published IN (' . $published . '))';
}
# Filter by specific conditions
$unpublished = $this->getState('filter.unpublished');
if (is_numeric($unpublished))
{
// Is user member of jem groups allowing to see unpublished events?
$unpublished_on_groups = $this->getState('filter.unpublished.events.on_groups');
if (is_array($unpublished_on_groups) && !empty($unpublished_on_groups)) {
// to allow only events with categories attached to allowed jemgroups use this line:
//$where_pub[] = '(' . $tbl . '.published = ' . $unpublished . ' AND c.groupid IN (' . implode(',', $unpublished_on_groups) . '))';
// to allow also events with categories not attached to disallowed jemgroups use this crazy block:
$where_pub[] = '(' . $tbl . 'published = ' . $unpublished . ' AND '
. $tbl . 'id NOT IN (SELECT rel3.itemid FROM #__jem_categories as c3 '
. ' INNER JOIN #__jem_cats_event_relations as rel3 '
. ' WHERE c3.id = rel3.catid AND c3.groupid NOT IN (0,' . implode(',', $unpublished_on_groups) . ')'
. ' GROUP BY rel3.itemid)'
. ')';
// hint: above it's a not not ;-)
// meaning: Show unpublished events not connected to a category which is not one of the allowed categories.
}
// Is user allowed to see own unpublished events?
$unpublished_on_user = (int)$this->getState('filter.unpublished.on_user');
if ($unpublished_on_user > 0) {
$where_pub[] = '(' . $tbl . 'published = ' . $unpublished . ' AND ' . $tbl . 'created_by = ' . $unpublished_on_user . ')';
}
}
return $where_pub;
}
}
?>

View File

@ -0,0 +1,56 @@
<?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('JPATH_PLATFORM') or die;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Form\Field\CalendarField;
/**
* Form Field class for JEM needs.
*
* Advances CalendarField for better country-specific date format support.
*
* @since 2.2.3
*/
class JFormFieldCalendarJem extends CalendarField
{
/**
* The form field type.
*
* @var string
*/
protected $type = 'CalendarJem';
/**
* Method to get the data to be passed to the layout for rendering.
*
* @return array
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
if (!empty($this->hint)) {
return $data;
}
// add hint regarding date/time format accepted in edit field
$exampleTimestamp = strtotime("12/31/2017 23:59");
$date_format = str_replace("%","",$this->format);
$hint = Text::sprintf('COM_JEM_DATEFIELD_HINT', date($date_format, $exampleTimestamp));
$extraData = array(
'hint' => $hint,
);
return array_merge($data, $extraData);
}
}

View File

@ -0,0 +1,195 @@
<?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('JPATH_BASE') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Field\ListField;
use Joomla\CMS\Form\FormHelper;
use Joomla\CMS\HTML\HTMLHelper;
FormHelper::loadFieldClass('list');
require_once __DIR__ . '/../../helpers/helper.php';
/**
* CatOptions Field class.
*/
class JFormFieldCatOptions extends ListField
{
/**
* The category options field type.
*/
protected $type = 'CatOptions';
/**
* Create Input
* @see JFormField::getInput()
*/
public function getInput()
{
$attr = '';
// Initialize field attributes.
$attr .= !empty($this->class) ? ' class="' . $this->class . '"' : '';
$attr .= !empty($this->size) ? ' size="' . $this->size . '"' : '';
$attr .= $this->multiple ? ' multiple' : '';
$attr .= $this->required ? ' required aria-required="true"' : '';
// To avoid user's confusion, readonly="true" should imply disabled="true".
if ((string) $this->readonly == '1' || (string) $this->readonly == 'true' || (string) $this->disabled == '1'|| (string) $this->disabled == 'true')
{
$attr .= ' disabled="disabled"';
}
// Initialize JavaScript field attributes.
$attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : '';
// Output
$currentid = Factory::getApplication()->input->getInt('a_id');
if (!$currentid) { // special case: new event as copy of another one
$currentid = Factory::getApplication()->input->getInt('from_id');
}
// Get the field options.
$options = (array) $this->getOptions();
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('DISTINCT catid');
$query->from('#__jem_cats_event_relations');
$query->where('itemid = '. $db->quote($currentid));
$db->setQuery($query);
$selectedcats = $db->loadColumn();
// On new event we may have a category preferred to select.
if (empty($selectedcats) && !empty($this->element['prefer'])) {
$selectedcats = (array)$this->element['prefer'];
}
// Create a read-only list (no name) with a hidden input to store the value.
if ((string) $this->readonly == '1' || (string) $this->readonly == 'true')
{
$html[] = HTMLHelper::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $selectedcats,$this->id);
$html[] = '<input type="hidden" name="' . $this->name . '" value="' . htmlspecialchars($selectedcats, ENT_COMPAT, 'UTF-8') . '"/>';
}
else
// Create a regular list.
{
$html[] = HTMLHelper::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $selectedcats,$this->id);
}
return implode($html);
}
/**
* Retrieve Options
* @see ListField::getOptions()
*/
protected function getOptions()
{
$currentid = Factory::getApplication()->input->getInt('a_id');
$options = self::getCategories($currentid);
$options = array_values($options);
// Pad the option text with spaces using depth level as a multiplier
# the level has to be decreased as we are having a (invisible) root
# treename is generated by the function so let's use that one instead of the Joomla way
for ($i = 0, $n = count($options); $i < $n; $i++)
{
/*
if ($options[$i]->published == 1)
{
$options[$i]->text = str_repeat('- ', ($options[$i]->level - 1)) . $options[$i]->text;
}
else
{
$options[$i]->text = str_repeat('- ', ($options[$i]->level - 1)) . '[' . $options[$i]->text . ']';
}
*/
$options[$i]->text = $options[$i]->treename;
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $options);
return $options;
}
/**
* logic to get the categories
*
* @access public
* @return void
*/
public function getCategories($id)
{
$db = Factory::getContainer()->get('DatabaseDriver');
$user = JemFactory::getUser();
$userid = (int) $user->get('id');
if (empty($id)) {
// for new events also show all categories user is allowed to see, disable non-useable categories
// (to show same list in both cases, and allow "unusable" parents for structuring)
$mitems = $user->getJemCategories('add', 'event', array('use_disable' => true));
} else {
$query = $db->getQuery(true);
$query = 'SELECT COUNT(*)'
. ' FROM #__jem_events AS e'
. ' WHERE e.id = ' . $db->quote($id)
. ' AND e.created_by = ' . $db->quote($userid);
$db->setQuery($query);
$owner = $db->loadResult();
// on edit show all categories user is allowed to see, disable non-useable categories
$mitems = $user->getJemCategories(array('add', 'edit'), 'event', array('use_disable' => true, 'owner' => $owner));
}
if (!$mitems)
{
$mitems = array();
$children = array();
$parentid = 0;
}
else
{
$children = array();
// First pass - collect children
foreach ($mitems as $v)
{
$v->value = $v->id;
$v->text = $v->catname;
$pt = $v->parent_id;
$list = @$children[$pt] ? $children[$pt] : array();
array_push($list, $v);
$children[$pt] = $list;
}
// list childs of "root" which has no parent and normally id 1
$parentid = intval(@isset($children[0][0]->id) ? $children[0][0]->id : 1);
}
//get list of the items
$list = JemCategories::treerecurse($parentid, '', array(), $children, 9999, 0, 0);
// append orphaned categories
if (count($mitems) > count($list)) {
foreach ($children as $k => $v) {
if (($k > 1) && !array_key_exists($k, $list)) {
$list = JemCategories::treerecurse($k, '?&nbsp;', $list, $children, 999, 0, 0);
}
}
}
return $list;
}
}

View File

@ -0,0 +1,34 @@
<?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('JPATH_BASE') or die;
use Joomla\CMS\Form\Field\ListField;
use Joomla\CMS\Form\FormHelper;
FormHelper::loadFieldClass('list');
/**
* CountryOptions Field class
*/
class JFormFieldCountryOptions extends ListField
{
/**
* The form field type.
*/
protected $type = 'CountryOptions';
/**
* Method to get the Country options.
*/
public function getOptions()
{
return JemHelper::getCountryOptions();
}
}

View File

@ -0,0 +1,40 @@
<?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('JPATH_BASE') or die;
use Joomla\CMS\Form\FormField;
/**
* Endtime Field class.
*
*
*/
class JFormFieldEndtime extends FormField
{
/**
* The form field type.
*
*/
protected $type = 'Endtime';
public function getInput()
{
$endhours = JEMHelper::buildtimeselect(23, 'endhours', substr( $this->value, 0, 2 ));
$endminutes = JEMHelper::buildtimeselect(59, 'endminutes', substr($this->value, 3, 2 ));
$var2 = $endhours.$endminutes;
return $var2;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,110 @@
<?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\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Form\FormField;
/**
* Contact select
*/
class JFormFieldModal_Contact extends FormField
{
/**
* field type
* @var string
*/
protected $type = 'Modal_Contact';
/**
* Method to get the field input markup
*/
protected function getInput()
{
$app = Factory::getApplication();
$document = $app->getDocument();
$wa = $document->getWebAssetManager();
// Build the script
$script = array();
$script[] = ' function jSelectContact_'.$this->id.'(id, name, object) {';
$script[] = ' document.getElementById("'.$this->id.'_id").value = id;';
$script[] = ' document.getElementById("'.$this->id.'_name").value = name;';
// $script[] = ' SqueezeBox.close();';
$script[] = ' $("#contact-modal").modal("hide");';
$script[] = ' }';
// Add to document head
$wa->addInlineScript(implode("\n", $script));
// Setup variables for display
$html = array();
$link = 'index.php?option=com_jem&amp;view=editevent&amp;layout=choosecontact&amp;tmpl=component&amp;function=jSelectContact_'.$this->id;
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('name');
$query->from('#__contact_details');
$query->where(array('id='.(int)$this->value));
$db->setQuery($query);
try
{
$contact = $db->loadResult();
}
catch (RuntimeException $e)
{
$app->enqueueMessage($e->getMessage(), 'warning');
}
if (empty($contact)) {
$contact = Text::_('COM_JEM_SELECT_CONTACT');
}
$contact = htmlspecialchars($contact, ENT_QUOTES, 'UTF-8');
// The current contact input field
$html[] = ' <input type="text" id="'.$this->id.'_name" class="form-control readonly inputbox valid form-control-success" value="'.$contact.'" style="display:inline-block;" disabled="disabled" size="35" />';
// The contact select button
$html[] = HTMLHelper::_(
'bootstrap.renderModal',
'contact-modal',
array(
'url' => $link.'&amp;'.Session::getFormToken().'=1',
'title' => Text::_('COM_JEM_SELECT'),
'width' => '800px',
'height' => '450px',
'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">' . Text::_('COM_JEM_CLOSE') . '</button>'
)
);
$html[] ='<button type="button" class="btn btn-success button-select" data-bs-toggle="modal" data-bs-target="#contact-modal">'.Text::_('COM_JEM_SELECT').'</button>';
// The active contact id field
if (0 == (int)$this->value) {
$value = '';
} else {
$value = (int)$this->value;
}
// class='required' for client side validation
$class = '';
if ($this->required) {
$class = ' class="required modal-value"';
}
$html[] = '<input type="hidden" id="'.$this->id.'_id"'.$class.' name="'.$this->name.'" value="'.$value.'" />';
return implode("\n", $html);
}
}
?>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,124 @@
<?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\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\Session\Session;
/**
* Contact select
*/
class JFormFieldModal_Users extends FormField
{
/**
* field type
* @var string
*/
protected $type = 'Modal_Users';
/**
* Method to get the field input markup
*/
protected function getInput()
{
$app = Factory::getApplication();
$document = $app->getDocument();
$wa = $document->getWebAssetManager();
// Build the script
$script = array();
$script[] = ' function jSelectUsers_'.$this->id.'(ids, count, object) {';
$script[] = ' document.getElementById("'.$this->id.'_ids").value = ids;';
$script[] = ' document.getElementById("'.$this->id.'_count").value = count;';
// $script[] = ' SqueezeBox.close();';
$script[] = ' $("#user-modal").modal("hide");';
$script[] = ' }';
// Add to document head
$wa->addInlineScript(implode("\n", $script));
// Setup variables for display
$html = array();
$eventid = isset($this->element['eventid']) ? (int)$this->element['eventid'] : 0;
$link = 'index.php?option=com_jem&amp;view=editevent&amp;layout=chooseusers&amp;tmpl=component&amp;function=jSelectUsers_'.$this->id.'&amp;a_id='.$eventid;
// we expect a list of unique, non-zero numbers
$ids = explode(',', $this->value);
array_walk($ids, function(&$v, $k){$v = (int)$v;});
$ids = array_filter($ids);
$ids = array_unique($ids);
$idlist = implode(',', $ids);
if (!empty($idlist)) {
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('COUNT(id)');
$query->from('#__users');
$query->where('id IN ('.$idlist.')');
$db->setQuery($query);
// if ($error = $db->getErrorMsg()) {
// \Joomla\CMS\Factory::getApplication()->enqueueMessage($error, 'warning');
// }
try
{
$count = (int)$db->loadResult();
}
catch (RuntimeException $e)
{
\Joomla\CMS\Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
}
} else {
$count = 0;
}
// if (empty($count)) {
// $count = Text::_('COM_JEM_SELECT_USERS');
// }
// $count = htmlspecialchars($count, ENT_QUOTES, 'UTF-8');
// The current contact input field
$html[] = ' <input type="text" id="'.$this->id.'_count" value="'.$count.'" disabled="disabled" size="4" />';
// The contact select button
// $html[] = ' <a class="flyermodal" title="'.Text::_('COM_JEM_SELECT').'" href="'.$link.'&amp;'.Session::getFormToken().'=1" rel="{handler: \'iframe\', size: {x:800, y:450}}">'.
// Text::_('COM_JEM_SELECT').'</a>';
$html[] = HTMLHelper::_(
'bootstrap.renderModal',
'user-modal',
array(
'url' => $link.'&amp;'.Session::getFormToken().'=1',
'title' => Text::_('COM_JEM_SELECT'),
'width' => '800px',
'height' => '450px',
'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">' . Text::_('COM_JEM_CLOSE') . '</button>'
)
);
$html[] ='<button type="button" class="btn btn-link" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#user-modal">'.Text::_('COM_JEM_SELECT').'
</button>';
// class='required' for client side validation
$class = '';
if ($this->required) {
$class = ' class="required modal-value"';
}
$html[] = '<input type="hidden" id="'.$this->id.'_ids"'.$class.' name="'.$this->name.'" value="'.$idlist.'" />';
$html[] = '<input type="hidden" id="'.$this->id.'_evid"'.$class.' value="'.$eventid.'" />';
return implode("\n", $html);
}
}
?>

View File

@ -0,0 +1,120 @@
<?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\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Factory;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\Uri\Uri;
/**
* Venue Select
*/
class JFormFieldModal_Venue extends FormField
{
/**
* field type
* @var string
*/
protected $type = 'Modal_Venue';
/**
* Method to get the field input markup
*/
protected function getInput()
{
$app = Factory::getApplication();
$document = $app->getDocument();
$wa = $document->getWebAssetManager();
// Build the script
$script = array();
$script[] = ' function jSelectVenue_'.$this->id.'(id, venue, object) {';
$script[] = ' document.getElementById("'.$this->id.'_id").value = id;';
$script[] = ' document.getElementById("'.$this->id.'_name").value = venue;';
// $script[] = ' SqueezeBox.close();';
$script[] = ' $("#venue-modal").modal("hide");';
$script[] = ' }';
// Add to document head
$wa->addInlineScript(implode("\n", $script));
// Setup variables for display
$html = array();
$link = Uri::base() . 'index.php?option=com_jem&amp;view=editevent&amp;layout=choosevenue&amp;tmpl=component&amp;function=jSelectVenue_'.$this->id;
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('venue');
$query->from('#__jem_venues');
$query->where(array('id='.(int)$this->value));
$db->setQuery($query);
// if ($error = $db->getErrorMsg()) {
// \Joomla\CMS\Factory::getApplication()->enqueueMessage($error, 'warning');
// }
try
{
$venue = $db->loadResult();
}
catch (RuntimeException $e)
{
\Joomla\CMS\Factory::getApplication()->enqueueMessage($e->getMessage(), 'warning');
}
if (empty($venue)) {
$venue = Text::_('COM_JEM_SELECT_VENUE');
}
$venue = htmlspecialchars($venue, ENT_QUOTES, 'UTF-8');
// The current venue input field
$html[] = ' <input type="text" id="'.$this->id.'_name" value="'.$venue.'" disabled="disabled" size="35" />';
// The venue select button
// $html[] = ' <a class="flyermodal" title="'.Text::_('COM_JEM_SELECT').'" href="'.$link.'&amp;'.Session::getFormToken().'=1" rel="{handler: \'iframe\', size: {x:800, y:450}}">'.
// Text::_('COM_JEM_SELECT').'</a>';
$html[] = HTMLHelper::_(
'bootstrap.renderModal',
'venue-modal',
array(
'url' => $link.'&amp;'.Session::getFormToken().'=1',
'title' => Text::_('COM_JEM_SELECT'),
'width' => '800px',
'height' => '450px',
'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">' . Text::_('COM_JEM_CLOSE') . '</button>'
)
);
$html[] ='<button type="button" class="btn btn-link" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#venue-modal">'.Text::_('COM_JEM_SELECT').'
</button>';
// The active venue id field
if (0 == (int)$this->value) {
$value = '';
} else {
$value = (int)$this->value;
}
// class='required' for client side validation
$class = '';
if ($this->required) {
$class = ' class="required modal-value"';
}
$html[] = '<input type="hidden" id="'.$this->id.'_id"'.$class.' name="'.$this->name.'" value="'.$value.'" />';
return implode("\n", $html);
}
}
?>

View File

@ -0,0 +1,41 @@
<?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('JPATH_BASE') or die;
use Joomla\CMS\Form\FormField;
/**
* CountryOptions Field class.
*
*
*/
class JFormFieldStarttime extends FormField
{
/**
* The form field type.
*
*/
protected $type = 'Starttime';
public function getInput()
{
$starthours = JEMHelper::buildtimeselect(23, 'starthours', substr( $this->value, 0, 2 ));
$startminutes = JEMHelper::buildtimeselect(59, 'startminutes', substr($this->value, 3, 2 ));
$var2 = $starthours.$startminutes;
return $var2;
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset name="details">
<field name="status" type="list"
label="COM_JEM_STATUS"
description="COM_JEM_STATUS_DESC"
class="inputbox"
filter="intval"
size="1"
default="1"
>
<option value="0">COM_JEM_ATTENDEES_INVITED</option>
<option value="-1">COM_JEM_ATTENDEES_NOT_ATTENDING</option>
<option value="1">COM_JEM_ATTENDEES_ATTENDING</option>
<option value="2">COM_JEM_ATTENDEES_ON_WAITINGLIST</option>
</field>
</fieldset>
</form>

View File

@ -0,0 +1,428 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset name="details">
<field name="articletext" type="editor"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_DESCRIPTION"
description="COM_JEM_EDITEVENT_FIELD_DESCRIPTION_DESC"
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
hide="pagebreak"
/>
<field name="featured" class="inputbox" type="list"
label="JFEATURED"
description="COM_JEM_EDITEVENT_FIELD_FEATURED_DESC"
default="0"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field name="title" type="text"
class="inputbox"
size="40"
label="COM_JEM_EDITEVENT_FIELD_EVENT_TITLE"
description="COM_JEM_EDITEVENT_FIELD_EVENT_TITLE_DESC"
required="true"
/>
<field name="alias" type="text"
class="inputbox"
size="40"
label="COM_JEM_EDITEVENT_FIELD_ALIAS"
description="COM_JEM_EDITEVENT_FIELD_ALIAS"
hint="JFIELD_ALIAS_PLACEHOLDER"
required="false"
/>
<field name="dates" type="calendarjem"
label="COM_JEM_EDITEVENT_FIELD_DATE"
description="COM_JEM_EDITEVENT_FIELD_DATE_DESC"
class="inputbox"
size="22"
format="%Y-%m-%d"
translateformat="true"
filter="string"
showtime="false"
/>
<field name="enddates" type="calendarjem"
label="COM_JEM_EDITEVENT_FIELD_ENDDATE"
description="COM_JEM_EDITEVENT_FIELD_ENDDATE_DESC"
class="inputbox"
size="22"
format="%Y-%m-%d"
translateformat="true"
filter="string"
showtime="false"
/>
<field name="times" type="starttime"
class="inputbox"
size="10"
label="COM_JEM_EDITEVENT_FIELD_EVENT_TIME"
description="COM_JEM_EDITEVENT_FIELD_EVENT_TIME_DESC"
required="false"
/>
<field name="endtimes" type="endtime"
class="inputbox"
size="10"
label="COM_JEM_EDITEVENT_FIELD_END_TIME"
description="COM_JEM_EDITEVENT_FIELD_END_TIME_DESC"
required="false"
/>
<field name="cats" type="catoptions"
multiple="true"
class="inputbox required form-control"
size="4"
label="COM_JEM_EDITEVENT_FIELD_CATEGORIES"
labelclass=""
description="COM_JEM_EDITEVENT_FIELD_CATEGORIES_DESC"
required="true"
/>
</fieldset>
<fieldset name="publish">
<field name="id" type="text"
default="0"
readonly="true"
class="readonly"
label="JGLOBAL_FIELD_ID_LABEL"
description="JGLOBAL_FIELD_ID_DESC"
/>
<field name="created" type="calendar"
class="readonly"
label="JGLOBAL_FIELD_CREATED_LABEL"
description="JGLOBAL_FIELD_CREATED_DESC"
size="22"
default="now"
readonly="true"
format="Y-m-d H:i:s"
translateformat="true"
filter="user_utc"
/>
<field name="modified" type="calendar"
class="readonly"
label="JGLOBAL_FIELD_MODIFIED_LABEL"
description="COM_JEM_EDITEVENT_FIELD_EDITED_AT"
size="22"
readonly="true"
format="Y-m-d H:i:s"
translateformat="true"
filter="user_utc"
/>
<field name="version" type="text"
default="0"
readonly="true"
class="readonly"
label="COM_JEM_EDITEVENT_FIELD_REVISED"
description="COM_JEM_EDITEVENT_FIELD_REVISED"
/>
<field name="created_by" type="user"
label="JGLOBAL_FIELD_CREATED_BY_LABEL"
description="JGLOBAL_FIELD_CREATED_BY_Desc"
/>
<field name="published" type="list"
label="JSTATUS"
description="COM_JEM_EDITEVENT_FIELD_PUBLISHED_DESC"
class="inputbox"
size="1"
default="1"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
<option value="2">JARCHIVED</option>
<option value="-2">JTRASHED</option>
</field>
<field name="access" type="list"
label="JFIELD_ACCESS_LABEL"
description="JFIELD_ACCESS_DESC"
class="inputbox"
size="1"
/>
</fieldset>
<fieldset name="request">
<field name="locid" type="modal_venue"
label="COM_JEM_EDITEVENT_FIELD_VENUE"
description="COM_JEM_EDITEVENT_FIELD_VENUE_DESC"
size="40"
required="false"
default="0"
/>
<field name="contactid" type="modal_contact"
label="COM_JEM_EDITEVENT_FIELD_CONTACT"
description="COM_JEM_EDITEVENT_FIELD_CONTACT_DESC"
size="40"
required="false"
/>
</fieldset>
<fieldset name="image"
label="COM_JEM_IMAGE"
>
<field name="datimage" type="imageselectevent"
class="inputbox"
size="40"
label="COM_JEM_EDITEVENT_FIELD_IMAGESELECT"
description="COM_JEM_EDITEVENT_FIELD_IMAGESELECT_DESC"
/>
<field name="userfile" type="file"
class="inputbox"
size="40"
label="COM_JEM_IMAGE"
description="COM_JEM_UPLOAD_IMAGE"
/>
</fieldset>
<fieldset name="custom">
<field name="custom1" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD1"
description="COM_JEM_EVENT_CUSTOM_FIELD1_DESC"
/>
<field name="custom2" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD2"
description="COM_JEM_EVENT_CUSTOM_FIELD2_DESC"
/>
<field name="custom3" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD3"
description="COM_JEM_EVENT_CUSTOM_FIELD3_DESC"
/>
<field name="custom4" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD4"
description="COM_JEM_EVENT_CUSTOM_FIELD4_DESC"
/>
<field name="custom5" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD5"
description="COM_JEM_EVENT_CUSTOM_FIELD5_DESC"
/>
<field name="custom6" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD6"
description="COM_JEM_EVENT_CUSTOM_FIELD6_DESC"
/>
<field name="custom7" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD7"
description="COM_JEM_EVENT_CUSTOM_FIELD7_DESC"
/>
<field name="custom8" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD8"
description="COM_JEM_EVENT_CUSTOM_FIELD8_DESC"
/>
<field name="custom9" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD9"
description="COM_JEM_EVENT_CUSTOM_FIELD9_DESC"
/>
<field name="custom10" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_EVENT_CUSTOM_FIELD10"
description="COM_JEM_EVENT_CUSTOM_FIELD10_DESC"
/>
</fieldset>
<fieldset name="registration">
<field name="registra" type="list"
label="COM_JEM_EVENT_FIELD_ENABLE_REGISTRATION"
description="COM_JEM_EVENT_FIELD_ENABLE_REGISTRATION_DESC"
class="inputbox"
default="0"
required="false"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2">COM_JEM_EVENT_FIELD_FROM</option>
</field>
<field name="registra_from" type="calendar"
label="COM_JEM_EVENT_FIELD_REGISTRATION_FROM"
description="COM_JEM_EVENT_FIELD_REGISTRATION_FROM_DESC"
class="input-medium"
default="now"
filter="user_utc"
format="%Y-%m-%d %H:%M:%S"
filterformat="Y-m-d H:i:s"
singleheader="true"
showtime="true"
timeformat="24"
todaybutton="true"
weeknumbers="true"
filltable="true"
showon="registra:2"
/>
<field name="registra_until" type="calendar"
label="COM_JEM_EVENT_FIELD_REGISTRATION_UNTIL"
description="COM_JEM_EVENT_FIELD_REGISTRATION_UNTIL_DESC"
class="input-medium"
filter="user_utc"
format="%Y-%m-%d %H:%M:%S"
filterformat="Y-m-d H:i:s"
singleheader="true"
showtime="true"
timeformat="24"
todaybutton="true"
weeknumbers="true"
filltable="true"
showon="registra:2"
/>
<field name="reginvitedonly" type="checkbox"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_REG_INVITED_ONLY"
description="COM_JEM_EDITEVENT_FIELD_REG_INVITED_ONLY_DESC"
checked="0"
/>
<field name="unregistra" type="list"
label="COM_JEM_EVENT_FIELD_ENABLE_ANNULATION"
description="COM_JEM_EVENT_FIELD_ENABLE_ANNULATION_DESC"
class="inputbox"
default="0"
required="false"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
<option value="2">COM_JEM_EVENT_FIELD_UNTIL</option>
</field>
<field name="unregistra_until" type="calendar"
label="COM_JEM_EVENT_FIELD_ANNULATION_UNTIL"
description="COM_JEM_EVENT_FIELD_ANNULATION_UNTIL_DESC"
class="input-medium"
filter="user_utc"
format="%Y-%m-%d %H:%M:%S"
filterformat="Y-m-d H:i:s"
singleheader="true"
showtime="true"
timeformat="24"
todaybutton="true"
weeknumbers="true"
filltable="true"
showon="unregistra:2"
/>
<field name="maxplaces" type="number"
size="4"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_MAX_PLACES"
description="COM_JEM_EDITEVENT_FIELD_MAX_PLACES_DESC"
filter="integer"
default="0"
min="0"
/>
<field name="minbookeduser" type="number"
size="4"
class="inputbox"
label="COM_JEM_MINIMUM_BOOKED_PLACES_PER_USER"
description="COM_JEM_MINIMUM_BOOKED_PLACES_PER_USER_DESC"
filter="integer"
default="1"
min="1"
/>
<field name="maxbookeduser" type="number"
size="4"
class="inputbox"
label="COM_JEM_MAXIMUM_BOOKED_PLACES_PER_USER"
description="COM_JEM_MAXIMUM_BOOKED_PLACES_PER_USER_DESC"
filter="integer"
default="1"
min="1"
/>
<field name="reservedplaces" type="number"
size="4"
class="inputbox"
label="COM_JEM_RESERVED_PLACES"
description="COM_JEM_RESERVED_PLACES_DESC"
filter="integer"
default="0"
min="0"
/>
<field name="invited" type="modal_users"
label="COM_JEM_EDITEVENT_FIELD_INVITED_USERS"
description="COM_JEM_EDITEVENT_FIELD_INVITED_USERS_DESC"
size="4"
required="false"
/>
<field name="avplaces" type="text"
size="4"
class="readonly"
readonly="true"
disabled="true"
label="COM_JEM_AVAILABLE_PLACES"
description="COM_JEM_AVAILABLE_PLACES_DESC"
/>
<field name="waitinglist" type="checkbox"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_ENABLE_WAITINGLIST"
description="COM_JEM_EDITEVENT_FIELD_ENABLE_WAITINGLIST_DESC"
checked="0"
/>
<field name="requestanswer" type="checkbox"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_REQUEST_ANSWER_ASSISTENCE"
description="COM_JEM_EDITEVENT_FIELD_REQUEST_ANSWER_ASSISTENCE_DESC"
checked="0"
/>
<field name="seriesbooking" type="checkbox"
size="1"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_SERIES_EVENT_BOOKING"
description="COM_JEM_EDITEVENT_FIELD_SERIES_EVENT_BOOKING_DESC"
checked="0"
/>
<field name="singlebooking" type="checkbox"
size="1"
class="inputbox"
label="COM_JEM_EDITEVENT_FIELD_SINGLE_EVENT_BOOKING"
description="COM_JEM_EDITEVENT_FIELD_SINGLE_EVENT_BOOKING_DESC"
checked="0"
/>
</fieldset>
<fieldset name="recurrence"
label="COM_JEM_EDITEVENT_FIELD_RECURRING_EVENTS"
>
<field name="recurrence_type" type="list"
default="0"
label="COM_JEM_EDITEVENT_FIELD_RECURRENCE"
description="COM_JEM_EDITEVENT_FIELD_RECURRENCE"
>
<option value="0">COM_JEM_NOTHING</option>
<option value="1">COM_JEM_DAILY</option>
<option value="2">COM_JEM_WEEKLY</option>
<option value="3">COM_JEM_MONTHLY</option>
<option value="4">COM_JEM_WEEKDAY</option>
<option value="5">COM_JEM_YEARLY</option>
</field>
<field name="recurrence_limit_date" type="calendarjem"
default="now"
label="COM_JEM_EDITEVENT_FIELD_RECURRENCE_COUNTER"
description="COM_JEM_EDITEVENT_FIELD_RECURRENCE_COUNTER"
class="inputbox"
size="22"
format="%Y-%m-%d"
translateformat="true"
filter="string"
showtime="false"
/>
</fieldset>
</form>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8" ?>
<form>
<fieldset name="details">
<field
name="emailto"
type="email"
label="COM_JEM_MAILTO_EMAIL_TO"
filter="string"
required="true"
size="30"
validate="email"
autocomplete="email"
/>
<field
name="sender"
type="text"
label="COM_JEM_MAILTO_SENDER"
filter="string"
required="true"
size="30"
/>
<field
name="emailfrom"
type="email"
label="COM_JEM_MAILTO_YOUR_EMAIL"
filter="string"
required="true"
size="30"
validate="email"
autocomplete="email"
/>
<field
name="subject"
type="text"
label="COM_JEM_MAILTO_SUBJECT"
filter="string"
required="true"
size="30"
/>
<field
name="captcha"
type="captcha"
label="COM_JEM_MAILTO_CAPTCHA"
validate="captcha"
/>
</fieldset>
</form>

View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset name="details">
<field name="id" type="text"
default="0"
readonly="true"
class="readonly"
label="JGLOBAL_FIELD_ID_LABEL"
description="JGLOBAL_FIELD_ID_DESC"
/>
<field name="venue" type="text"
class="inputbox"
size="40"
label="COM_JEM_VENUE"
description="COM_JEM_VENUE"
required="true"
/>
<field name="alias" type="text"
class="inputbox"
size="40"
label="COM_JEM_EDITVENUE_FIELD_ALIAS"
hint="JFIELD_ALIAS_PLACEHOLDER"
description="COM_JEM_EDITVENUE_FIELD_ALIAS_DESC"
/>
<field name="url" type="text"
class="inputbox"
size="40"
label="COM_JEM_WEBSITE"
description="COM_JEM_WEBSITE_DESC"
/>
<field name="street" type="text"
id="street"
class="inputbox"
size="40"
label="COM_JEM_STREET"
description="COM_JEM_STREET"
/>
<field name="locdescription" type="editor"
filter="\Joomla\CMS\Component\ComponentHelper::filterText"
hide="pagebreak"
class="inputbox"
rows="3" cols="20"
width="100%"
label="COM_JEM_VENUE_DESCRIPTION"
description="COM_JEM_VENUE_DESCRIPTION_DESC"
/>
<field name="latitude" type="text"
class="inputbox"
size="40"
label="COM_JEM_LATITUDE"
description="COM_JEM_LATITUDE"
/>
<field name="longitude" type="text"
class="inputbox"
size="40"
label="COM_JEM_LONGITUDE"
description="COM_JEM_LONGITUDE_DESC"
/>
<field name="postalCode" type="text"
class="inputbox"
size="40"
label="COM_JEM_ZIP"
description="COM_JEM_ZIP"
/>
<field name="city" type="text"
class="inputbox"
size="40"
label="COM_JEM_CITY"
description="COM_JEM_CITY"
/>
<field name="state" type="text"
class="inputbox"
size="40"
label="COM_JEM_STATE"
description="COM_JEM_STATE"
/>
<field name="map" type="checkbox"
class="inputbox"
size="40"
label="COM_JEM_ENABLE_MAP"
description="COM_JEM_ENABLE_MAP"
value="1"
default="0"
/>
<field name="published" type="list"
label="JSTATUS"
description="COM_JEM_PUBLISHED"
class="inputbox"
filter="intval"
size="1"
default="1"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
</field>
<field name="country" type="countryoptions"
label="COM_JEM_COUNTRY"
description="COM_JEM_COUNTRY_DESC"
class="select_country"
/>
</fieldset>
<fieldset name="custom">
<field name="custom1" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD1"
description="COM_JEM_VENUE_CUSTOM_FIELD1_DESC"
/>
<field name="custom2" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD2"
description="COM_JEM_VENUE_CUSTOM_FIELD2_DESC"
/>
<field name="custom3" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD3"
description="COM_JEM_VENUE_CUSTOM_FIELD3_DESC"
/>
<field name="custom4" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD4"
description="COM_JEM_VENUE_CUSTOM_FIELD4_DESC"
/>
<field name="custom5" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD5"
description="COM_JEM_VENUE_CUSTOM_FIELD5_DESC"
/>
<field name="custom6" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD6"
description="COM_JEM_VENUE_CUSTOM_FIELD6_DESC"
/>
<field name="custom7" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD7"
description="COM_JEM_VENUE_CUSTOM_FIELD7_DESC"
/>
<field name="custom8" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD8"
description="COM_JEM_VENUE_CUSTOM_FIELD8_DESC"
/>
<field name="custom9" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD9"
description="COM_JEM_VENUE_CUSTOM_FIELD9_DESC"
/>
<field name="custom10" type="text"
size="20"
readonly="false"
class="inputbox"
label="COM_JEM_VENUE_CUSTOM_FIELD10"
description="COM_JEM_VENUE_CUSTOM_FIELD10_DESC"
/>
</fieldset>
<fieldset name="image" label="COM_JEM_IMAGE">
<field name="locimage" type="imageselectevent"
class="inputbox"
size="40"
label="COM_JEM_EDITVENUE_FIELD_IMAGESELECT"
description="COM_JEM_EDITVENUE_FIELD_IMAGESELECT_DESC"
/>
<field name="userfile" type="file"
class="inputbox"
size="40"
label="COM_JEM_IMAGE"
description="COM_JEM_UPLOAD_IMAGE"
/>
</fieldset>
<fieldset name="publish"
label="COM_JEM_FIELDSET_PUBLISHING"
>
<field name="created_by" type="user"
label="COM_JEM_FIELD_CREATED_BY_LABEL"
description="COM_JEM_FIELD_CREATED_BY_DESC"
/>
<field name="created" type="calendar"
class="readonly"
label="JGLOBAL_FIELD_CREATED_LABEL"
description="JGLOBAL_FIELD_CREATED_DESC"
size="22"
default="now"
readonly="true"
format="Y-m-d H:i:s"
translateformat="true"
filter="user_utc"
/>
<field name="version" type="text"
class="readonly"
label="COM_JEM_FIELD_VERSION_LABEL"
description="COM_JEM_FIELD_VERSION_DESC"
size="6"
readonly="true"
filter="unset"
/>
<field name="modified" type="calendar"
class="readonly"
label="JGLOBAL_FIELD_MODIFIED_LABEL"
description="COM_JEM_FIELD_MODIFIED_DESC"
size="22"
readonly="true"
format="Y-m-d H:i:s"
translateformat="true"
filter="user_utc"
/>
<field name="modified_by" type="user"
label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
description="JGLOBAL_FIELD_MODIFIED_BY_LABEL_DESC"
class="readonly"
readonly="true"
filter="unset"
/>
</fieldset>
<fieldset name="meta"
label="JGLOBAL_FIELDSET_METADATA_OPTIONS"
>
<field name="meta_keywords" type="textarea"
class="inputbox"
rows="3" cols="30"
label="JFIELD_META_KEYWORDS_LABEL"
description="COM_JEM_FIELD_METAKEYWORDS_DESC"
/>
<field name="meta_description" type="textarea"
class="inputbox"
rows="3" cols="30"
label="JFIELD_META_DESCRIPTION_LABEL"
description="COM_JEM_FIELD_METADESCRIPTION_DESC"
/>
</fieldset>
</form>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,124 @@
<?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\Language\Text;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\String\PunycodeHelper;
/**
* Mailto model class.
*
* @since 3.8.9
*/
class JemModelMailto extends FormModel
{
/**
* Method to get the mailto form.
*
* The base form is loaded from XML and then an event is fired
* for users plugins to extend the form with extra fields.
*
* @param array $data An optional array of data for the form to interrogate.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
*
* @return JForm A JForm object on success, false on failure
*
* @since 3.8.9
*/
protected function populateState()
{
$app = Factory::getApplication();
$params = $app->getParams();
$this->setState('params', $params);
$this->setState('layout', $app->input->getCmd('layout', ''));
}
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_jem.mailto', 'mailto', array('load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return array The default data is an empty array.
*
* @since 3.8.9
*/
protected function loadFormData()
{
$app = Factory::getApplication();
$user = $app->getIdentity();
$data = $app->getUserState('jem.mailto.form.data', array());
$data['link'] = urldecode($app->input->get('link', '', 'BASE64'));
if ($data['link'] == '')
{
// JError::raiseError(403, Text::_('COM_JEM_MAILTO_LINK_IS_MISSING'));
Factory::getApplication()->enqueueMessage(Text::_('COM_JEM_MAILTO_LINK_IS_MISSING'), 'error');
return false;
}
// Load with previous data, if it exists
$data['sender'] = $app->input->post->getString('sender', '');
$data['subject'] = $app->input->post->getString('subject', '');
$data['emailfrom'] = PunycodeHelper::emailToPunycode($app->input->post->getString('emailfrom', ''));
$data['emailto'] = PunycodeHelper::emailToPunycode($app->input->post->getString('emailto', ''));
if (!$user->guest)
{
$data['sender'] = $user->name;
$data['emailfrom'] = $user->email;
}
$app->setUserState('jem.mailto.form.data', $data);
$this->preprocessData('com_jem.mailto', $data);
return $data;
}
/**
* Get the request data
*
* @return array The requested data
*
* @since 3.8.9
*/
public function getData()
{
$input = Factory::getApplication()->input;
$data['emailto'] = $input->get('emailto', '', 'string');
$data['sender'] = $input->get('sender', '', 'string');
$data['emailfrom'] = $input->get('emailfrom', '', 'string');
$data['subject'] = $input->get('subject', '', 'string');
$data['consentbox'] = $input->get('consentbox', '', 'string');
return $data;
}
}

View File

@ -0,0 +1,291 @@
<?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\Pagination\Pagination;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Filter\InputFilter;
/**
* JEM Component JEM Model
*
* @package JEM
*
*/
class JemModelMyattendances extends BaseDatabaseModel
{
protected $_attending = null;
protected $_total_attending = null;
protected $_pagination_attending = null;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
//get the number of events
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.myattendances.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.myattendances.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->getUserStateFromRequest('com_jem.myattendances.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
}
/**
* Method to get the Events user is attending
*
* @access public
* @return array
*/
public function getAttending()
{
$pop = Factory::getApplication()->input->getBool('pop', false);
// Lets load the content if it doesn't already exist
if (empty($this->_attending)) {
$query = $this->_buildQueryAttending();
$pagination = $this->getAttendingPagination();
if ($pop) {
$this->_attending = $this->_getList($query);
} else {
$pagination = $this->getAttendingPagination();
$this->_attending = $this->_getList($query, $pagination->limitstart, $pagination->limit);
}
foreach ($this->_attending as $i => $item) {
$item->categories = $this->getCategories($item->eventid);
//remove events without categories (users have no access to them)
if (empty($item->categories)) {
unset($this->_attending[$i]);
}
}
}
return $this->_attending;
}
/**
* Total nr of events
*
* @access public
* @return integer
*/
public function getTotalAttending()
{
// Lets load the total nr if it doesn't already exist
if (empty($this->_total_attending))
{
$query = $this->_buildQueryAttending();
$this->_total_attending = $this->_getListCount($query);
}
return $this->_total_attending;
}
/**
* Method to get a pagination object for the attending events
*
* @access public
* @return integer
*/
public function getAttendingPagination()
{
// Lets load the content if it doesn't already exist
if (empty($this->_pagination_attending)) {
$this->_pagination_attending = new Pagination($this->getTotalAttending(), $this->getState('limitstart'), $this->getState('limit'));
}
return $this->_pagination_attending;
}
/**
* Build the query
*
* @access private
* @return string
*/
protected function _buildQueryAttending()
{
# Get the WHERE and ORDER BY clauses for the query
$where = $this->_buildAttendingWhere();
$orderby = $this->_buildOrderByAttending();
$groupby = ' GROUP BY a.id';
# Get Events from Database
$query = 'SELECT DISTINCT a.id AS eventid, a.dates, a.enddates, a.times, a.endtimes, a.title, a.created, a.locid, a.published, '
. ' a.recurrence_type, a.recurrence_first_id,'
. ' a.access, a.checked_out, a.checked_out_time, a.contactid, a.created, a.created_by, a.created_by_alias, a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10, a.datimage, a.featured,'
. ' a.fulltext, a.hits, a.introtext, a.language, a.maxplaces, a.maxbookeduser, a.minbookeduser, a.reservedplaces, r.places, a.metadata, a.meta_keywords, a.meta_description, a.modified, a.modified_by, a.registra, a.unregistra,'
. ' a.recurrence_byday, a.recurrence_counter, a.recurrence_limit, a.recurrence_limit_date, a.recurrence_number, a.version,'
. ' a.waitinglist, a.requestanswer, a.seriesbooking, a.singlebooking, r.status, r.waiting, r.comment,'
. ' l.id, l.venue, l.postalCode, l.city, l.state, l.country, l.url, l.published AS l_published,'
. ' l.alias AS l_alias, l.checked_out AS l_checked_out, l.checked_out_time AS l_checked_out_time, l.created AS l_created, l.created_by AS l_createdby,'
. ' l.custom1 AS l_custom1, l.custom2 AS l_custom2, l.custom3 AS l_custom3, l.custom4 AS l_custom4, l.custom5 AS l_custom5, l.custom6 AS l_custom6, l.custom7 AS l_custom7, l.custom8 AS l_custom8, l.custom9 AS l_custom9, l.custom10 AS l_custom10,'
. ' l.id AS l_id, l.latitude, l.locdescription, l.locimage, l.longitude, l.map, l.meta_description AS l_meta_description, l.meta_keywords AS l_meta_keywords, l.modified AS l_modified, l.modified_by AS l_modified_by,'
. ' l.publish_up AS l_publish_up, l.publish_down AS l_publish_down, l.street, l.version AS l_version,'
. ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'
. ' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', a.locid, l.alias) ELSE a.locid END as venueslug'
. ' FROM #__jem_events AS a'
. ' LEFT JOIN #__jem_register AS r ON r.event = a.id'
. ' LEFT JOIN #__jem_venues AS l ON l.id = a.locid'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.itemid = a.id'
. ' LEFT JOIN #__jem_categories AS c ON c.id = rel.catid'
. $where
. $groupby
. $orderby
;
return $query;
}
/**
* Build the order clause
*
* @access private
* @return string
*/
protected function _buildOrderByAttending()
{
$app = Factory::getApplication();
$task = $app->input->getCmd('task', '');
$filter_order = $app->getUserStateFromRequest('com_jem.myattendances.filter_order', 'filter_order', 'a.dates', 'cmd');
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
// Reverse default order for dates in archive mode
$filter_order_DirDefault = 'ASC';
if (($task == 'archive') && ($filter_order == 'a.dates')) {
$filter_order_DirDefault = 'DESC';
}
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.myattendances.filter_order_Dir', 'filter_order_Dir', $filter_order_DirDefault, 'word');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
$default_order_Dir = ($task == 'archive') ? 'DESC' : 'ASC';
if ($filter_order == 'r.status') {
$orderby = ' ORDER BY ' . $filter_order . ' ' . $filter_order_Dir . ', r.waiting ' . $filter_order_Dir . ', a.dates ' . $filter_order_Dir .', a.times ' . $filter_order_Dir;
// $orderby = ' ORDER BY CASE WHEN r.status < 0 THEN r.status * (-3) WHEN r.status = 1 AND r.waiting > 0 THEN r.status + 1 ELSE r.status END '.$filter_order_Dir.', a.dates ' . $filter_order_Dir .', a.times ' . $filter_order_Dir;
} elseif ($filter_order == 'a.dates') {
$orderby = ' ORDER BY a.dates ' . $filter_order_Dir .', a.times ' . $filter_order_Dir
. ', a.created ' . $filter_order_Dir;
} else {
$orderby = ' ORDER BY ' . $filter_order . ' ' . $filter_order_Dir
. ', a.dates ' . $default_order_Dir . ', a.times ' . $default_order_Dir
. ', a.created ' . $default_order_Dir;
}
return $orderby;
}
/**
* Build the where clause
*
* @access private
* @return string
*/
protected function _buildAttendingWhere()
{
$app = Factory::getApplication();
// Get the paramaters of the active menu item
$params = $app->getParams();
$task = $app->input->getCmd('task', '');
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$filter = $app->getUserStateFromRequest('com_jem.myattendances.filter', 'filter', 0, 'int');
$search = $app->getUserStateFromRequest('com_jem.myattendances.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
$where = array();
// First thing we need to do is to select only needed events
if ($task == 'archive') {
$where[] = ' a.published = 2';
} else {
$where[] = ' a.published IN (0,1)';
}
$where[] = ' c.published = 1';
$where[] = ' a.access IN (' . implode(',', $levels) . ')';
$where[] = ' c.access IN (' . implode(',', $levels) . ')';
//limit output so only future events the user attends will be shown
// but also allow events without start date because they will be normally in the future too
if ($params->get('filtermyregs')) {
$where[] = ' (a.dates IS NULL OR DATE_SUB(NOW(), INTERVAL '.(int)$params->get('myregspast').' DAY) < (IF (a.enddates IS NOT NULL, a.enddates, a.dates)))';
}
// then if the user is attending the event
$where[] = ' r.uid = '.$this->_db->Quote($user->id);
if ($settings->get('global_show_filter') && $search) {
switch($filter) {
case 1:
$where[] = ' LOWER(a.title) LIKE \'%'.$search.'%\' ';
break;
case 2:
$where[] = ' LOWER(l.venue) LIKE \'%'.$search.'%\' ';
break;
case 3:
$where[] = ' LOWER(l.city) LIKE \'%'.$search.'%\' ';
break;
case 4:
$where[] = ' LOWER(c.catname) LIKE \'%'.$search.'%\' ';
break;
case 5:
default:
$where[] = ' LOWER(l.state) LIKE \'%'.$search.'%\' ';
}
}
$where2 = (count($where) ? ' WHERE ' . implode(' AND ', $where) : '');
return $where2;
}
public function getCategories($id)
{
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$query = 'SELECT DISTINCT c.id, c.catname, c.access, c.checked_out AS cchecked_out,'
. ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END as catslug'
. ' FROM #__jem_categories AS c'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.catid = c.id'
. ' WHERE rel.itemid = '.(int)$id
. ' AND c.published = 1'
. ' AND c.access IN (' . implode(',', $levels) . ')'
;
$this->_db->setQuery($query);
$this->_cats = $this->_db->loadObjectList();
return $this->_cats;
}
}
?>

View File

@ -0,0 +1,359 @@
<?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\Pagination\Pagination;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\Registry\Registry;
jimport('joomla.application.component.model');
/**
* JEM Component JEM Model
*
* @package JEM
*
*/
class JemModelMyevents extends BaseDatabaseModel
{
/**
* Events data array
*
* @var array
*/
protected $_events = null;
/**
* Events total
*
* @var integer
*/
protected $_total_events = null;
/**
* Pagination object
*
* @var object
*/
protected $_pagination_events = null;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
//get the number of events from database
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.myevents.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.myevents.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->getUserStateFromRequest('com_jem.myevents.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
}
/**
* Method to get the Events
*
* @access public
* @return array
*/
public function getEvents()
{
$pop = Factory::getApplication()->input->getBool('pop', false);
$user = JemFactory::getUser();
$userId = $user->get('id');
if (empty($userId)) {
$this->_events = array();
return array();
}
// Lets load the content if it doesn't already exist
if (empty($this->_events)) {
$query = $this->_buildQueryEvents();
$pagination = $this->getEventsPagination();
if ($pop) {
$this->_events = $this->_getList($query);
} else {
$pagination = $this->getEventsPagination();
$this->_events = $this->_getList($query, $pagination->limitstart, $pagination->limit);
}
}
if ($this->_events) {
$now = time();
foreach ($this->_events as $i => $item) {
$item->categories = $this->getCategories($item->eventid);
//remove events without categories (users have no access to them)
if (empty($item->categories)) {
unset($this->_events[$i]);
} else {
if (empty($item->params)) {
// Set event params.
$registry = new Registry();
$registry->loadString($item->attribs ??'{}');
$item->params = clone JemHelper::globalattribs();
$item->params->merge($registry);
}
# edit state access permissions.
$item->params->set('access-change', $user->can('publish', 'event', $item->id, $item->created_by));
# calculate if event has finished (which e.g. makes adding attendees useless)
$date = $item->enddates ? $item->enddates : $item->dates;
$time = $item->endtimes ? $item->endtimes : $item->times;
$ts = strtotime($date . ' ' . $time);
$item->finished = $ts && ($ts < $now); // we have a timestamp and it's in the past
}
}
JemHelper::getAttendeesNumbers($this->_events); // does directly edit events
}
return $this->_events;
}
/**
* Method to (un)publish a event
*
* @access public
* @return boolean True on success
*/
public function publish($cid = array(), $publish = 1)
{
$result = false;
$user = JemFactory::getUser();
$userid = (int) $user->get('id');
if (is_array($cid) && count($cid)) {
\Joomla\Utilities\ArrayHelper::toInteger($cid);
$cids = implode(',', $cid);
$query = 'UPDATE #__jem_events'
. ' SET published = '. (int) $publish
. ' WHERE id IN ('. $cids .')'
. ' AND (checked_out = 0 OR checked_out Is null OR (checked_out = ' .$userid. '))'
;
$this->_db->setQuery($query);
$result = true;
if ($this->_db->execute() === false) {
$this->setError($this->_db->getErrorMsg());
$result = false;
}
}
return $result;
}
/**
* Total nr of events
*
* @access public
* @return integer
*/
public function getTotalEvents()
{
// Lets load the total nr if it doesn't already exist
if ( empty($this->_total_events)) {
$query = $this->_buildQueryEvents();
$this->_total_events = $this->_getListCount($query);
}
return $this->_total_events;
}
/**
* Method to get a pagination object for the events
*
* @access public
* @return integer
*/
public function getEventsPagination()
{
// Lets load the content if it doesn't already exist
if ( empty($this->_pagination_events)) {
$this->_pagination_events = new Pagination($this->getTotalEvents(), $this->getState('limitstart'), $this->getState('limit'));
}
return $this->_pagination_events;
}
/**
* Build the query
*
* @access private
* @return string
*/
protected function _buildQueryEvents()
{
# Get the WHERE and ORDER BY clauses for the query
$where = $this->_buildWhere();
$orderby = $this->_buildOrderBy();
# Get Events from Database
$query = 'SELECT DISTINCT a.id as eventid, a.id, a.dates, a.enddates, a.published, a.times, a.endtimes, a.title, a.created, a.created_by, a.locid, a.registra, a.unregistra, a.maxplaces, a.waitinglist, a.requestanswer, a.seriesbooking, a.singlebooking,'
. ' a.recurrence_type, a.recurrence_first_id, a.recurrence_byday, a.recurrence_counter, a.recurrence_limit, a.recurrence_limit_date, a.recurrence_number, a.attribs,'
. ' a.access, a.checked_out, a.checked_out_time, a.maxplaces, a.maxbookeduser, a.minbookeduser, a.reservedplaces, a.contactid, a.created_by_alias, a.datimage, a.featured,'
. ' a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10,'
. ' a.fulltext, a.hits, a.introtext, a.language, a.metadata, a.meta_keywords, a.meta_description, a.modified, a.modified_by, a.version,'
. ' l.id AS l_id, l.venue, l.street, l.postalCode, l.city, l.state, l.country, l.url, l.published AS l_published,'
. ' l.alias AS l_alias, l.checked_out AS l_checked_out, l.checked_out_time AS l_checked_out_time, l.created AS l_created, l.created_by AS l_createdby,'
. ' l.custom1 AS l_custom1, l.custom2 AS l_custom2, l.custom3 AS l_custom3, l.custom4 AS l_custom4, l.custom5 AS l_custom5, l.custom6 AS l_custom6, l.custom7 AS l_custom7, l.custom8 AS l_custom8, l.custom9 AS l_custom9, l.custom10 AS l_custom10,'
. ' l.latitude, l.locdescription, l.locimage, l.longitude, l.map, l.meta_description AS l_meta_description, l.meta_keywords AS l_meta_keywords, l.modified AS l_modified, l.modified_by AS l_modified_by,'
. ' l.publish_up AS l_publish_up, l.publish_down AS l_publish_down, l.version AS l_version,'
. ' c.catname, c.id AS catid,'
. ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'
. ' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', a.locid, l.alias) ELSE a.locid END as venueslug'
. ' FROM #__jem_events AS a'
. ' LEFT JOIN #__jem_venues AS l ON l.id = a.locid'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.itemid = a.id'
. ' LEFT JOIN #__jem_categories AS c ON c.id = rel.catid'
. $where
. ' GROUP BY a.id'
. $orderby
;
return $query;
}
/**
* Build the order clause
*
* @access private
* @return string
*/
protected function _buildOrderBy()
{
$app = Factory::getApplication();
$task = $app->input->getCmd('task', '');
$filter_order = $app->getUserStateFromRequest('com_jem.myevents.filter_order', 'filter_order', 'a.dates', 'cmd');
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.myevents.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word');
$default_order_Dir = ($task == 'archive') ? 'DESC' : 'ASC';
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
if ($filter_order == 'a.dates') {
$orderby = ' ORDER BY a.dates ' . $filter_order_Dir .', a.times ' . $filter_order_Dir
. ', a.created ' . $filter_order_Dir;
} else {
$orderby = ' ORDER BY ' . $filter_order . ' ' . $filter_order_Dir
. ', a.dates ' . $default_order_Dir . ', a.times ' . $default_order_Dir
. ', a.created ' . $default_order_Dir;
}
return $orderby;
}
/**
* Build the where clause
*
* @access private
* @return string
*/
protected function _buildWhere()
{
$app = Factory::getApplication();
$task = $app->input->getCmd('task', '');
$params = $app->getParams();
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$filter = $app->getUserStateFromRequest('com_jem.myevents.filter', 'filter', 0, 'int');
$search = $app->getUserStateFromRequest('com_jem.myevents.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
$where = array();
// First thing we need to do is to select only needed events
if ($task == 'archive') {
$where[] = ' a.published = 2';
} else {
$where[] = ' (a.published = 1 OR a.published = 0)';
}
$where[] = ' c.published = 1';
$where[] = ' a.access IN (' . implode(',', $levels) . ')';
$where[] = ' c.access IN (' . implode(',', $levels) . ')';
// then if the user is the owner of the event
$where[] = ' a.created_by = '.$this->_db->Quote($user->id);
// get excluded categories
$excluded_cats = trim($params->get('excluded_cats', ''));
if ($excluded_cats != '') {
$cats_excluded = explode(',', $excluded_cats);
\Joomla\Utilities\ArrayHelper::toInteger($cats_excluded);
$where[] = ' c.id NOT IN (' . implode(',', $cats_excluded) . ')';
}
// === END Excluded categories add === //
if ($settings->get('global_show_filter') && $search) {
switch($filter) {
case 1:
$where[] = ' LOWER(a.title) LIKE \'%'.$search.'%\' ';
break;
case 2:
$where[] = ' LOWER(l.venue) LIKE \'%'.$search.'%\' ';
break;
case 3:
$where[] = ' LOWER(l.city) LIKE \'%'.$search.'%\' ';
break;
case 4:
$where[] = ' LOWER(c.catname) LIKE \'%'.$search.'%\' ';
break;
case 5:
default:
$where[] = ' LOWER(l.state) LIKE \'%'.$search.'%\' ';
}
}
$where2 = (count($where) ? ' WHERE ' . implode(' AND ', $where) : '');
return $where2;
}
public function getCategories($id)
{
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$query = 'SELECT DISTINCT c.id, c.catname, c.access, c.checked_out AS cchecked_out, c.groupid,'
. ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END as catslug'
. ' FROM #__jem_categories AS c'
. ' LEFT JOIN #__jem_cats_event_relations AS rel ON rel.catid = c.id'
. ' WHERE rel.itemid = '.(int)$id
. ' AND c.published = 1'
. ' AND c.access IN (' . implode(',', $levels) . ')'
;
$this->_db->setQuery($query);
return $this->_db->loadObjectList();
}
}
?>

View File

@ -0,0 +1,450 @@
<?php
/**
* @version 2.2.2
* @package JEM
* @copyright (C) 2013-2017 joomlaeventmanager.net
* @copyright (C) 2005-2009 Christoph Lukes
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
*/
defined('_JEXEC') or die ;
require_once dirname(__FILE__) . '/eventslist.php';
/**
* Model-Calendar
*/
class JemModelMyplanning extends JemModelEventslist
{
protected $_date = 0;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->setdate(time());
}
public function setdate($date)
{
$this->_date = $date;
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
# parent::populateState($ordering, $direction);
$app = JFactory::getApplication();
$params = $app->getParams();
$task = $app->input->get('task','','cmd');
$top_category = $params->get('top_category', 0);
$startdayonly = $params->get('show_only_start', false);
# params
$this->setState('params', $params);
# publish state
$this->_populatePublishState($task);
###########
## DATES ##
###########
#only select events within specified dates. (chosen month)
$monthstart = mktime(0, 0, 1, strftime('%m', $this->_date), 1, strftime('%Y', $this->_date));
$monthend = mktime(0, 0, -1, strftime('%m', $this->_date)+1, 1, strftime('%Y', $this->_date));
$filter_date_from = $this->_db->Quote(strftime('%Y-%m-%d', $monthstart));
$filter_date_to = $this->_db->Quote(strftime('%Y-%m-%d', $monthend));
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), '. $filter_date_from .') >= 0';
$this->setState('filter.calendar_from',$where);
$where = ' DATEDIFF(a.dates, '. $filter_date_to .') <= 0';
$this->setState('filter.calendar_to',$where);
##################
## TOP-CATEGORY ##
##################
if ($top_category) {
$children = JemCategories::getChilds($top_category);
if (count($children)) {
$where = 'rel.catid IN ('. implode(',', $children) .')';
$this->setState('filter.category_top', $where);
}
}
# set filter
$this->setState('filter.calendar_multiday',true);
$this->setState('filter.calendar_startdayonly',(bool)$startdayonly);
$this->setState('filter.groupby',array('a.id'));
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
if ($items) {
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Create a new query object.
$app = JFactory::getApplication();
$task = $app->input->getCmd('task', '');
$itemid = $app->input->getInt('id', 0) . ':' . $app->input->getInt('Itemid', 0);
$params = $app->getParams();
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
# Query
$db = JFactory::getDBO();
$query = $db->getQuery(true);
# Event
$query->select(
$this->getState('list.select',
'a.access,a.alias,a.attribs,a.checked_out,a.checked_out_time,a.contactid,a.created,a.created_by,a.created_by_alias,a.custom1,a.custom2,a.custom3,a.custom4,a.custom5,a.custom6,a.custom7,a.custom8,a.custom9,a.custom10,a.dates,a.datimage,a.enddates,a.endtimes,a.featured,' .
'a.fulltext,a.hits,a.id,a.introtext,a.language,a.locid,a.maxplaces,a.metadata,a.meta_keywords,a.meta_description,a.modified,a.modified_by,a.published,a.registra,a.times,a.title,a.unregistra,a.waitinglist,DAYOFMONTH(a.dates) AS created_day, YEAR(a.dates) AS created_year, MONTH(a.dates) AS created_month,' .
'a.recurrence_byday,a.recurrence_counter,a.recurrence_first_id,a.recurrence_limit,a.recurrence_limit_date,a.recurrence_number, a.recurrence_type,a.version'
)
);
$query->from('#__jem_events as a');
# Venue
$query->select(array('l.alias AS l_alias','l.checked_out AS l_checked_out','l.checked_out_time AS l_checked_out_time','l.city','l.country','l.created AS l_created','l.created_by AS l_createdby'));
$query->select(array('l.custom1 AS l_custom1','l.custom2 AS l_custom2','l.custom3 AS l_custom3','l.custom4 AS l_custom4','l.custom5 AS l_custom5','l.custom6 AS l_custom6','l.custom7 AS l_custom7','l.custom8 AS l_custom8','l.custom9 AS l_custom9','l.custom10 AS l_custom10'));
$query->select(array('l.id AS l_id','l.latitude','l.locdescription','l.locimage','l.longitude','l.map','l.meta_description AS l_meta_description','l.meta_keywords AS l_meta_keywords','l.modified AS l_modified','l.modified_by AS l_modified_by','l.postalCode'));
$query->select(array('l.publish_up AS l_publish_up','l.publish_down AS l_publish_down','l.published AS l_published','l.state','l.street','l.url','l.venue','l.version AS l_version'));
$query->join('LEFT', '#__jem_venues AS l ON l.id = a.locid');
# the rest
$case_when_e = ' CASE WHEN ';
$case_when_e .= $query->charLength('a.alias','!=', '0');
$case_when_e .= ' THEN ';
$id_e = $query->castAsChar('a.id');
$case_when_e .= $query->concatenate(array($id_e, 'a.alias'), ':');
$case_when_e .= ' ELSE ';
$case_when_e .= $id_e.' END as slug';
$case_when_l = ' CASE WHEN ';
$case_when_l .= $query->charLength('l.alias', '!=', '0');
$case_when_l .= ' THEN ';
$id_l = $query->castAsChar('a.locid');
$case_when_l .= $query->concatenate(array($id_l, 'l.alias'), ':');
$case_when_l .= ' ELSE ';
$case_when_l .= $id_l.' END as venueslug';
$query->select(array($case_when_e, $case_when_l));
# join over the category-tables
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.itemid = a.id');
$query->join('LEFT', '#__jem_categories AS c ON c.id = rel.catid');
#############
## FILTERS ##
#############
#####################
## FILTER - EVENTS ##
#####################
# Filter by a single or group of events.
$eventId = $this->getState('filter.event_id');
if (is_numeric($eventId)) {
$type = $this->getState('filter.event_id.include', true) ? '= ' : '<> ';
$query->where('a.id '.$type.(int) $eventId);
}
elseif (is_array($eventId) && !empty($eventId)) {
JArrayHelper::toInteger($eventId);
$eventId = implode(',', $eventId);
$type = $this->getState('filter.event_id.include', true) ? 'IN' : 'NOT IN';
$query->where('a.id '.$type.' ('.$eventId.')');
}
###################
## FILTER-ACCESS ##
###################
# Filter by access level - always.
$query->where('a.access IN ('.implode(',', $levels).')');
####################
## FILTER-PUBLISH ##
####################
# Filter by published state.
$where_pub = $this->_getPublishWhere();
if (!empty($where_pub)) {
$query->where('(' . implode(' OR ', $where_pub) . ')');
} else {
// something wrong - fallback to published events
$query->where('a.published = 1');
}
#####################
## FILTER-FEATURED ##
#####################
# Filter by featured flag.
$featured = $this->getState('filter.featured');
if (is_numeric($featured)) {
$query->where('a.featured = ' . (int) $featured);
}
elseif (is_array($featured) && !empty($featured)) {
JArrayHelper::toInteger($featured);
$featured = implode(',', $featured);
$query->where('a.featured IN ('.$featured.')');
}
#############################
## FILTER - CALENDAR_DATES ##
#############################
$cal_from = $this->getState('filter.calendar_from');
$cal_to = $this->getState('filter.calendar_to');
if ($cal_from) {
$query->where($cal_from);
}
if ($cal_to) {
$query->where($cal_to);
}
#############################
## FILTER - OPEN_DATES ##
#############################
$opendates = $this->getState('filter.opendates');
switch ($opendates) {
case 0: // don't show events without start date
default:
$query->where('a.dates IS NOT NULL');
break;
case 1: // show all events, with or without start date
break;
case 2: // show only events without startdate
$query->where('a.dates IS NULL');
break;
}
#####################
### FILTER - BYCAT ##
#####################
$filter_catid = $this->getState('filter.filter_catid');
if ($filter_catid) { // categorycal
$query->where('c.id = '.(int)$filter_catid);
}else {
$cats = $this->getCategories('all');
if (!empty($cats)) {
$query->where('c.id IN (' . implode(',', $cats) . ')');
}
}
####################
## FILTER - BYLOC ##
####################
$filter_locid = $this->getState('filter.filter_locid');
if ($filter_locid) {
$query->where('a.locid = '.(int)$filter_locid);
}
####################
## FILTER - VENUE ##
####################
$venueId = $this->getState('filter.venue_id');
if (is_numeric($venueId)) {
$type = $this->getState('filter.venue_id.include', true) ? '= ' : '<> ';
$query->where('l.id '.$type.(int) $venueId);
}
elseif (is_array($venueId) && !empty($venueId)) {
JArrayHelper::toInteger($venueId);
$venueId = implode(',', $venueId);
$type = $this->getState('filter.venue_id.include', true) ? 'IN' : 'NOT IN';
$query->where('l.id '.$type.' ('.$venueId.')');
}
##########################
## FILTER - VENUE STATE ##
##########################
$venueState = $this->getState('filter.venue_state');
if (!empty($venueState)) {
$venueState = explode(',', $venueState);
$venueStateMode = $this->getState('filter.venue_state.mode', 0);
switch ($venueStateMode) {
case 0: # complete match: venue's state must be equal (ignoring upper/lower case) one of the strings given by filter
default:
array_walk($venueState, create_function('&$v,$k,$db','$v = $db->quote(trim($v));'), $db);
$query->where('l.state IN ('.implode(',', $venueState).')');
break;
case 1: # contain: venue's state must contain one of the strings given by filter
array_walk($venueState, create_function('&$v,$k,$db','$v = quotemeta($db->escape(trim($v), true));'), $db);
$query->where('l.state REGEXP '.$db->quote(implode('|', $venueState)));
break;
}
}
###################
## FILTER-SEARCH ##
###################
# define variables
$filter = $this->getState('filter.filter_type');
$search = $this->getState('filter.filter_search'); // not escaped
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('a.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%', false); // escape once
if ($search && $settings->get('global_show_filter')) {
switch ($filter) {
# case 4 is category, so it is omitted
case 1:
$query->where('a.title LIKE '.$search);
break;
case 2:
$query->where('l.venue LIKE '.$search);
break;
case 3:
$query->where('l.city LIKE '.$search);
break;
case 5:
$query->where('l.state LIKE '.$search);
break;
}
}
}
}
# Group
$group = $this->getState('filter.groupby');
if ($group) {
$query->group($group);
}
# ordering
$orderby = $this->getState('filter.orderby');
if ($orderby) {
$query->order($orderby);
}
// suite
# Get the WHERE clause for the query
$where = $this->_buildWhere();
// here we can extend the query of the Eventslist model
//$query->select('DATEDIFF(a.enddates, a.dates) AS datesdiff, DAYOFMONTH(a.dates) AS start_day, YEAR(a.dates) AS start_year, MONTH(a.dates) AS start_month');
$query->where( $where);
return $query;
}
/**
* Build the where clause
*
* @access private
* @return string
*/
protected function _buildWhere()
{
$app = JFactory::getApplication();
$task = $app->input->getCmd('task', '');
$params = $app->getParams();
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$filter = $app->getUserStateFromRequest('com_jem.myevents.filter', 'filter', 0, 'int');
$search = $app->getUserStateFromRequest('com_jem.myevents.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(JString::strtolower($search)));
$where = array();
// a.published traité auparavant
$where[] = ' c.published = 1';
// a.access traité auparavant
$where[] = ' c.access IN (' . implode(',', $levels) . ')';
// then if the user is the owner of the event
$where[] = ' a.created_by = '.$this->_db->Quote($user->id);
// get excluded categories
$excluded_cats = trim($params->get('excluded_cats', ''));
if ($excluded_cats != '') {
$cats_excluded = explode(',', $excluded_cats);
JArrayHelper::toInteger($cats_excluded);
$where[] = ' c.id NOT IN (' . implode(',', $cats_excluded) . ')';
}
// === END Excluded categories add === //
if ($settings->get('global_show_filter') && $search) {
switch($filter) {
case 1:
$where[] = ' LOWER(a.title) LIKE \'%'.$search.'%\' ';
break;
case 2:
$where[] = ' LOWER(l.venue) LIKE \'%'.$search.'%\' ';
break;
case 3:
$where[] = ' LOWER(l.city) LIKE \'%'.$search.'%\' ';
break;
case 4:
$where[] = ' LOWER(c.catname) LIKE \'%'.$search.'%\' ';
break;
case 5:
default:
$where[] = ' LOWER(l.state) LIKE \'%'.$search.'%\' ';
}
}
$where2 = (count($where) ? ' ' . implode(' AND ', $where) : '');
return $where2;
}
}
?>

View File

@ -0,0 +1,278 @@
<?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\Pagination\Pagination;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Filter\InputFilter;
/**
* JEM Component JEM Model
*
* @package JEM
*
*/
class JemModelMyvenues extends BaseDatabaseModel
{
/**
* Venues data array
*
* @var array
*/
protected $_venues = null;
/**
* Venues total count
*
* @var integer
*/
protected $_total_venues = null;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
//get the number of events
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.myvenues.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.myvenues.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->getUserStateFromRequest('com_jem.myvenues.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
}
/**
* Method to get the Events user is attending
*
* @access public
* @return array
*/
public function getVenues()
{
$pop = Factory::getApplication()->input->getBool('pop', false);
$user = JemFactory::getUser();
$userId = $user->get('id');
if (empty($userId)) {
$this->_venues = array();
return array();
}
// Lets load the content if it doesn't already exist
if ( empty($this->_venues)) {
$query = $this->_buildQueryVenues();
$pagination = $this->getVenuesPagination();
if ($pop) {
$this->_venues = $this->_getList($query);
} else {
$pagination = $this->getVenuesPagination();
$this->_venues = $this->_getList($query, $pagination->limitstart, $pagination->limit);
}
}
if ($this->_venues) {
foreach ($this->_venues as $item) {
if (empty($item->params)) {
// Set venue params.
$item->params = clone JemHelper::globalattribs();
}
# edit state access permissions.
$item->params->set('access-change', $user->can('publish', 'venue', $item->id, $item->created_by));
}
}
return $this->_venues;
}
/**
* Total nr of events
*
* @access public
* @return integer
*/
public function getTotalVenues()
{
// Lets load the total nr if it doesn't already exist
if ( empty($this->_total_venues)) {
$query = $this->_buildQueryVenues();
$this->_total_venues = $this->_getListCount($query);
}
return $this->_total_venues;
}
/**
* Method to get a pagination object for the attending events
*
* @access public
* @return integer
*/
public function getVenuesPagination()
{
// Lets load the content if it doesn't already exist
if ( empty($this->_pagination_venues))
{
$this->_pagination_venues = new Pagination($this->getTotalVenues(), $this->getState('limitstart'), $this->getState('limit'));
}
return $this->_pagination_venues;
}
/**
* Method to (un)publish one or more venue(s)
*
* @access public
* @return boolean True on success
*/
public function publish($cid = array(), $publish = 1)
{
$result = false;
$user = JemFactory::getUser();
$userid = (int) $user->get('id');
if (is_numeric($cid)) {
$cid = array($cid);
}
// simple checks, good enough here
if (is_array($cid) && count($cid) && ($publish >= -2) && ($publish <= 2)) {
\Joomla\Utilities\ArrayHelper::toInteger($cid);
$cids = implode(',', $cid);
$query = 'UPDATE #__jem_venues'
. ' SET published = ' . (int)$publish
. ' WHERE id IN (' . $cids . ')'
. ' AND (checked_out = 0 OR checked_out IS null OR (checked_out = ' . $userid . '))'
;
$this->_db->setQuery($query);
$result = true;
if ($this->_db->execute() === false) {
$this->setError($this->_db->getErrorMsg());
$result = false;
}
}
return $result;
}
/**
* Build the query
*
* @access private
* @return string
*/
protected function _buildQueryVenues()
{
# Get the WHERE and ORDER BY clauses for the query
$where = $this->_buildVenuesWhere();
$orderby = $this->_buildOrderByVenues();
# Get Venues from Database
$query = 'SELECT l.id, l.venue, l.street, l.postalCode, l.city, l.state, l.country, l.url, l.created, l.created_by, l.published,'
. ' l.custom1, l.custom2, l.custom3, l.custom4, l.custom5, l.custom6, l.custom7, l.custom8, l.custom9, l.custom10,'
. ' l.locdescription, l.locimage, l.latitude, l.longitude, l.map, l.meta_keywords, l.meta_description, l.checked_out, l.checked_out_time,'
. ' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', l.id, l.alias) ELSE l.id END as venueslug'
. ' FROM #__jem_venues AS l '
. $where
. $orderby
;
return $query;
}
/**
* Build the order clause
*
* @access private
* @return string
*/
protected function _buildOrderByVenues()
{
$app = Factory::getApplication();
$filter_order = $app->getUserStateFromRequest('com_jem.myvenues.filter_order', 'filter_order', 'l.venue', 'cmd');
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.myvenues.filter_order_Dir', 'filter_order_Dir', '', 'word');
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
if ($filter_order != '') {
$orderby = ' ORDER BY ' . $filter_order . ' ' . $filter_order_Dir . ', l.venue ASC';
} else {
$orderby = ' ORDER BY l.venue ASC';
}
return $orderby;
}
/**
* Build the where clause
*
* @access private
* @return string
*/
protected function _buildVenuesWhere()
{
$app = Factory::getApplication();
$user = JemFactory::getUser();
$settings = JemHelper::globalattribs();
$filter = $app->getUserStateFromRequest('com_jem.myvenues.filter', 'filter', 0, 'int');
$search = $app->getUserStateFromRequest('com_jem.myvenues.filter_search', 'filter_search', '', 'string');
$search = $this->_db->escape(trim(\Joomla\String\StringHelper::strtolower($search)));
$where = array();
// $where[] = ' l.published = 1';
// then if the user is creator of the event
$where [] = ' l.created_by = '.$this->_db->Quote($user->id);
if ($settings->get('global_show_filter') && $search) {
switch($filter) {
case 1:
// $where[] = ' LOWER(a.title) LIKE \'%'.$search.'%\' ';
break;
case 2:
$where[] = ' LOWER(l.venue) LIKE \'%'.$search.'%\' ';
break;
case 3:
$where[] = ' LOWER(l.city) LIKE \'%'.$search.'%\' ';
break;
case 4:
// $where[] = ' LOWER(c.catname) LIKE \'%'.$search.'%\' ';
break;
case 5:
default:
$where[] = ' LOWER(l.state) LIKE \'%'.$search.'%\' ';
}
}
$where2 = (count($where) ? ' WHERE ' . implode(' AND ', $where) : '');
return $where2;
}
}
?>

View File

@ -0,0 +1,458 @@
<?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\Pagination\Pagination;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
/**
* JEM Component search Model
*
* @package JEM
*
*/
class JemModelSearch extends BaseDatabaseModel
{
/**
* Events data array
*
* @var array
*/
protected $_data = null;
/**
* Events total count
*
* @var integer
*/
protected $_total = null;
/**
* Pagination object
*
* @var object
*/
protected $_pagination = null;
/**
* the query
*
* @var string
*/
protected $_query = null;
/**
* Constructor
*
*/
public function __construct()
{
parent::__construct();
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
//get the number of events from database
$limit = $app->getUserStateFromRequest('com_jem.search.limit', 'limit', $jemsettings->display_num, 'int');
$limitstart = $app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
// Get the filter request variables
$filter_order = $app->input->getCmd('filter_order', 'a.dates');
$this->setState('filter_order', $filter_order);
$filter_order_DirDefault = 'ASC';
// Reverse default order for dates in archive mode
$task = $app->input->getCmd('task', '');
if (($task == 'archive') && ($filter_order == 'a.dates')) {
$filter_order_DirDefault = 'DESC';
}
$this->setState('filter_order_Dir', $app->input->getCmd('filter_order_Dir', $filter_order_DirDefault));
}
/**
* Method to get the Events
*
* @access public
* @return array
*/
public function getData()
{
$pop = Factory::getApplication()->input->getBool('pop', false);
// Lets load the content if it doesn't already exist
if (empty($this->_data)) {
$query = $this->_buildQuery();
if ($pop) {
$this->_data = $this->_getList($query);
} else {
$pagination = $this->getPagination();
$this->_data = $this->_getList($query, $pagination->limitstart, $pagination->limit);
}
foreach ($this->_data as $i => $item) {
$item->categories = $this->getCategories($item->id);
//remove events without categories (users have no access to them)
if (empty($item->categories)) {
unset($this->_data[$i]);
}
}
}
return $this->_data;
}
/**
* Method to get a pagination object for the events
*
* @access public
* @return integer
*/
public function getPagination()
{
// Lets load the content if it doesn't already exist
if (empty($this->_pagination)) {
$this->_pagination = new Pagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit'));
}
return $this->_pagination;
}
/**
* Build the query
*
* @access private
* @return string
*/
protected function _buildQuery()
{
if (empty($this->_query)) {
# Get the WHERE and ORDER BY clauses for the query
$where = $this->_buildWhere();
$orderby = $this->_buildOrderBy();
# Get Events from Database
$this->_query = 'SELECT a.id, a.dates, a.enddates, a.times, a.endtimes, a.title, a.created, a.created_by, a.created_by_alias, a.locid, a.published, a.access,'
. ' a.recurrence_type, a.recurrence_first_id, a.recurrence_byday, a.recurrence_counter, a.recurrence_limit, a.recurrence_limit_date, a.recurrence_number,'
. ' a.alias, a.attribs, a.checked_out ,a.checked_out_time, a.contactid, a.datimage, a.featured, a.hits, a.language, a.version,'
. ' a.custom1, a.custom2, a.custom3, a.custom4, a.custom5, a.custom6, a.custom7, a.custom8, a.custom9, a.custom10,'
. ' a.introtext, a.fulltext, a.registra, a.unregistra, a.maxplaces, a.waitinglist, a.metadata, a.meta_keywords, a.meta_description, a.modified, a.modified_by,'
. ' l.id AS l_id, l.venue, l.street, l.postalCode, l.city, l.state, l.country, l.url, l.published AS l_published,'
. ' l.alias AS l_alias, l.checked_out AS l_checked_out, l.checked_out_time AS l_checked_out_time, l.created AS l_created, l.created_by AS l_createdby,'
. ' l.custom1 AS l_custom1, l.custom2 AS l_custom2, l.custom3 AS l_custom3, l.custom4 AS l_custom4, l.custom5 AS l_custom5, l.custom6 AS l_custom6, l.custom7 AS l_custom7, l.custom8 AS l_custom8, l.custom9 AS l_custom9, l.custom10 AS l_custom10,'
. ' l.locdescription, l.locimage, l.latitude, l.longitude, l.map, l.meta_description AS l_meta_description, l.meta_keywords AS l_meta_keywords, l.modified AS l_modified, l.modified_by AS l_modified_by,'
. ' l.publish_up AS l_publish_up, l.publish_down AS l_publish_down, l.version AS l_version,'
. ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'
. ' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', a.locid, l.alias) ELSE a.locid END as venueslug'
. ' FROM #__jem_events AS a'
. ' INNER JOIN #__jem_cats_event_relations AS rel ON rel.itemid = a.id '
. ' LEFT JOIN #__jem_venues AS l ON l.id = a.locid'
. ' LEFT JOIN #__jem_countries AS c ON c.iso2 = l.country'
. $where
. ' GROUP BY a.id '
. $orderby
;
}
return $this->_query;
}
/**
* Build the order clause
*
* @access private
* @return string
*/
protected function _buildOrderBy()
{
$app = Factory::getApplication();
$task = $app->input->getCmd('task', '');
$filter_order = $this->getState('filter_order');
$filter_order_Dir = $this->getState('filter_order_Dir');
$default_order_Dir = ($task == 'archive') ? 'DESC' : 'ASC';
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
if ($filter_order == 'a.dates') {
$orderby = ' ORDER BY a.dates ' . $filter_order_Dir .', a.times ' . $filter_order_Dir
. ', a.created ' . $filter_order_Dir;
} else {
$orderby = ' ORDER BY ' . $filter_order . ' ' . $filter_order_Dir
. ', a.dates ' . $default_order_Dir . ', a.times ' . $default_order_Dir
. ', a.created ' . $default_order_Dir;
}
return $orderby;
}
/**
* Build the where clause
*
* @access private
* @return string
*/
protected function _buildWhere()
{
$app = Factory::getApplication();
// Get the paramaters of the active menu item
$params = $app->getParams();
$task = $app->input->getCmd('task', '');
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$top_category = $params->get('top_category', 1);
// First thing we need to do is to select only needed events
if ($task == 'archive') {
$where = ' WHERE a.published = 2';
} else {
$where = ' WHERE a.published = 1';
}
// filter by user's access levels
$where .= ' AND a.access IN (' . implode(', ', $levels) .')';
//$filter = $app->input->getString('filter', '');
$filter = $app->getUserStateFromRequest('com_jem.search.filter_search', 'filter_search', '', 'string');
$filter_type = $app->input->get('filter_type', '');
$filter_continent = $app->getUserStateFromRequest('com_jem.search.filter_continent', 'filter_continent', '', 'string');
$filter_country = $app->getUserStateFromRequest('com_jem.search.filter_country', 'filter_country', '', 'string');
$filter_city = $app->getUserStateFromRequest('com_jem.search.filter_city', 'filter_city', '', 'string');
$filter_date_from = $app->getUserStateFromRequest('com_jem.search.filter_date_from', 'filter_date_from', '', 'string');
$filter_date_to = $app->getUserStateFromRequest('com_jem.search.filter_date_to', 'filter_date_to', '', 'string');
$filter_category = $app->getUserStateFromRequest('com_jem.search.filter_category', 'filter_category', 0, 'int');
// "Please select..." entry has number 1 which must be interpreted as "not set" and replaced by top category (which maybe 1 ;-)
$filter_category = (($filter_category > 1) ? $filter_category : $top_category);
// no result if no filter:
if (!($filter || $filter_continent || $filter_country || $filter_city || $filter_date_from || $filter_date_to || $filter_category != $top_category)) {
return ' WHERE 0 ';
}
if ($filter) {
// clean filter variables
$filter = \Joomla\String\StringHelper::strtolower($filter);
$filter = $this->_db->Quote('%'.$this->_db->escape($filter, true).'%', false);
$filter_type = \Joomla\String\StringHelper::strtolower($filter_type);
switch ($filter_type) {
case 'title' :
$where .= ' AND LOWER(a.title) LIKE '.$filter;
break;
case 'venue' :
$where .= ' AND LOWER(l.venue) LIKE '.$filter;
break;
case 'city' :
$where .= ' AND LOWER(l.city) LIKE '.$filter;
break;
}
}
// filter date
if ($params->get('date_filter_type', 0) == 1) // match on all events dates (between start and end)
{
if ($filter_date_from && strtotime($filter_date_from))
{
$filter_date_from = $this->_db->Quote(date('Y-m-d', strtotime($filter_date_from)));
$where .= ' AND DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), '. $filter_date_from .') >= 0';
}
if ($filter_date_to && strtotime($filter_date_to))
{
$filter_date_to = $this->_db->Quote(date('Y-m-d', strtotime($filter_date_to)));
$where .= ' AND DATEDIFF(a.dates, '. $filter_date_to .') <= 0';
}
} else {
// match only on start date
if ($filter_date_from && strtotime($filter_date_from)) {
$filter_date_from = $this->_db->Quote(date('Y-m-d', strtotime($filter_date_from)));
$where .= ' AND DATEDIFF(a.dates, '. $filter_date_from .') >= 0';
}
if ($filter_date_to && strtotime($filter_date_to)) {
$filter_date_to = $this->_db->Quote(date('Y-m-d', strtotime($filter_date_to)));
$where .= ' AND DATEDIFF(a.dates, '. $filter_date_to .') <= 0';
}
}
// filter continent
if ($filter_continent) {
$where .= ' AND c.continent = ' . $this->_db->Quote($filter_continent);
}
// filter country
if ($filter_country) {
$where .= ' AND l.country = ' . $this->_db->Quote($filter_country);
}
// filter city
if ($filter_country && $filter_city) {
$where .= ' AND l.city = ' . $this->_db->Quote($filter_city);
}
// filter category
if ($filter_category) {
$cats = JemCategories::getChilds((int) $filter_category);
$where .= ' AND rel.catid IN (' . implode(', ', $cats) .')';
}
return $where;
}
public function getTotal()
{
// Lets load the total nr if it doesn't already exist
if (empty($this->_total))
{
$query = $this->_buildQuery();
$this->_total = $this->_getListCount($query);
}
return $this->_total;
}
public function getCategories($id)
{
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$query = 'SELECT c.id, c.catname, c.access, c.lft, c.checked_out AS cchecked_out,'
. ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END as catslug'
. ' FROM #__jem_categories AS c'
. ' INNER JOIN #__jem_cats_event_relations AS rel ON rel.catid = c.id'
. ' WHERE rel.itemid = '.(int)$id
. ' AND c.published = 1'
. ' AND c.access IN (' . implode(',', $levels) . ')'
;
$this->_db->setQuery($query);
return $this->_db->loadObjectList();
}
public function getCountryOptions()
{
$app = Factory::getApplication();
$filter_continent = $app->getUserStateFromRequest('com_jem.search.filter_continent', 'filter_continent', '', 'string');
$query = ' SELECT c.iso2 as value, c.name as text '
. ' FROM #__jem_events AS a'
. ' INNER JOIN #__jem_venues AS l ON l.id = a.locid'
. ' INNER JOIN #__jem_countries as c ON c.iso2 = l.country '
;
if ($filter_continent) {
$query .= ' WHERE c.continent = ' . $this->_db->Quote($filter_continent);
}
$query .= ' GROUP BY c.iso2 ';
$query .= ' ORDER BY c.name ';
$this->_db->setQuery($query);
return $this->_db->loadObjectList();
}
public function getContinentFromCountry($country)
{
$app = Factory::getApplication();
$query = ' SELECT c.continent as value FROM #__jem_countries as c WHERE c.iso2 = ' . $this->_db->Quote($country);
$this->_db->setQuery($query);
return $this->_db->loadResult();
}
public function getCityOptions()
{
if (!$country = Factory::getApplication()->input->getString('filter_country', '')) {
return array();
}
$query = ' SELECT DISTINCT l.city as value, l.city as text '
. ' FROM #__jem_events AS a'
. ' INNER JOIN #__jem_venues AS l ON l.id = a.locid'
. ' INNER JOIN #__jem_countries as c ON c.iso2 = l.country '
. ' WHERE l.country = ' . $this->_db->Quote($country)
. ' ORDER BY l.city ';
$this->_db->setQuery($query);
return $this->_db->loadObjectList();
}
/**
* logic to get the categories
*
* @access public
* @return void
*/
public function getCategoryTree()
{
$app = Factory::getApplication();
$db = Factory::getContainer()->get('DatabaseDriver');
// Get the paramaters of the active menu item
$params = $app->getParams('com_jem');
$top_id = max(1, $params->get('top_category', 1)); // not below 'root'
$user = JemFactory::getUser();
// Support Joomla access levels instead of single group id
$levels = $user->getAuthorisedViewLevels();
$where = ' WHERE c.published = 1 AND c.access IN (' . implode(',', $levels) . ')';
//get the maintained categories and the categories whithout any group
//or just get all if somebody have edit rights
$query = 'SELECT c.*'
. ' FROM #__jem_categories AS c'
. $where
. ' ORDER BY c.lft'
;
try
{
$db->setQuery($query);
$mitems = $db->loadObjectList();
}
catch (RuntimeException $e)
{
\Joomla\CMS\Factory::getApplication()->enqueueMessage($e->getMessage(), 'notice');
}
// Check for a database error.
// if ($db->getErrorNum())
// {
// \Joomla\CMS\Factory::getApplication()->enqueueMessage($db->getErrorMsg(), 'notice');
// }
if (!$mitems) {
$mitems = array();
$children = array();
} else {
$children = array();
// First pass - collect children
foreach ($mitems as $v)
{
$pt = $v->parent_id;
$list = isset($children[$pt]) ? $children[$pt] : array();
array_push($list, $v);
$children[$pt] = $list;
}
}
//get list of the items
$list = JemCategories::treerecurse($top_id, '', array(), $children, 9999, 0, 0);
return $list;
}
}
?>

View File

@ -0,0 +1,219 @@
<?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\Language\Text;
require_once __DIR__ . '/eventslist.php';
/**
* Model: venue
*/
class JemModelVenue extends JemModelEventslist
{
/**
* Venue id
*
* @var int
*/
protected $_id = null;
public function __construct()
{
$app = Factory::getApplication();
$jinput = $app->input;
$params = $app->getParams();
# determing the id to load
if ($jinput->get('id',null,'int')) {
$id = $jinput->get('id',null,'int');
} else {
$id = $params->get('id');
}
$this->setId((int)$id);
parent::__construct();
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$params = $app->getParams();
$jinput = $app->input;
$task = $jinput->getCmd('task','');
$itemid = $jinput->getInt('id', 0) . ':' . $jinput->getInt('Itemid', 0);
$user = JemFactory::getUser();
$format = $jinput->getCmd('format',false);
// List state information
if (empty($format) || ($format == 'html')) {
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.venue.'.$itemid.'.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.venue.'.$itemid.'.limit', 'limit', $jemsettings->display_num, 'int');
$this->setState('list.limit', $limit);
$limitstart = $app->getUserStateFromRequest('com_jem.venue.'.$itemid.'.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('list.start', $limitstart);
}
# Search
$search = $app->getUserStateFromRequest('com_jem.venue.'.$itemid.'.filter_search', 'filter_search', '', 'string');
$this->setState('filter.filter_search', $search);
# FilterType
$filtertype = $app->getUserStateFromRequest('com_jem.venue.'.$itemid.'.filter_type', 'filter_type', 0, 'int');
$this->setState('filter.filter_type', $filtertype);
# filter_order
$orderCol = $app->getUserStateFromRequest('com_jem.venue.'.$itemid.'.filter_order', 'filter_order', 'a.dates', 'cmd');
$this->setState('filter.filter_ordering', $orderCol);
# filter_direction
$listOrder = $app->getUserStateFromRequest('com_jem.venue.'.$itemid.'.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word');
$this->setState('filter.filter_direction', $listOrder);
# show open date events
# (there is no menu item option yet so show all events)
$this->setState('filter.opendates', 1);
$defaultOrder = ($task == 'archive') ? 'DESC' : 'ASC';
if ($orderCol == 'a.dates') {
$orderby = array('a.dates ' . $listOrder, 'a.times ' . $listOrder, 'a.created ' . $listOrder);
} else {
$orderby = array($orderCol . ' ' . $listOrder,
'a.dates ' . $defaultOrder, 'a.times ' . $defaultOrder, 'a.created ' . $defaultOrder);
}
$this->setState('filter.orderby', $orderby);
# params
$this->setState('params', $params);
# publish state
$this->_populatePublishState($task);
$this->setState('filter.groupby',array('a.id'));
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
/* no additional things to do yet - place holder */
if ($items) {
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Create a new query object.
$query = parent::getListQuery();
// here we can extend the query of the Eventslist model
$query->where('a.locid = '.(int)$this->_id);
return $query;
}
/**
* Method to set the venue id
*
* The venue-id can be set by a menu-parameter
*/
public function setId($id)
{
// Set new venue ID and wipe data
$this->_id = $id;
//$this->_data = null;
}
/**
* set limit
* @param int value
*/
public function setLimit($value)
{
$this->setState('limit', (int) $value);
}
/**
* set limitstart
* @param int value
*/
public function setLimitStart($value)
{
$this->setState('limitstart', (int) $value);
}
/**
* Method to get a specific Venue
*
* @access public
* @return array
*/
public function getVenue()
{
$user = JemFactory::getUser();
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select('id, venue, published, city, state, url, street, custom1, custom2, custom3, custom4, custom5, '.
' custom6, custom7, custom8, custom9, custom10, locimage, meta_keywords, meta_description, '.
' created, created_by, locdescription, country, map, latitude, longitude, postalCode, checked_out AS vChecked_out, checked_out_time AS vChecked_out_time, '.
' CASE WHEN CHAR_LENGTH(alias) THEN CONCAT_WS(\':\', id, alias) ELSE id END as slug');
$query->from($db->quoteName('#__jem_venues'));
$query->where('id = '.(int)$this->_id);
// all together: if published or the user is creator of the venue or allowed to edit or publish venues
if (empty($user->id)) {
$query->where('published = 1');
}
// no limit if user can publish or edit foreign venues
elseif ($user->can(array('edit', 'publish'), 'venue')) {
$query->where('published IN (0,1)');
}
// user maybe creator
else {
$query->where('(published = 1 OR (published = 0 AND created_by = ' . $this->_db->Quote($user->id) . '))');
}
$db->setQuery($query);
$_venue = $db->loadObject();
if (empty($_venue)) {
$this->setError(Text::_('COM_JEM_VENUE_ERROR_VENUE_NOT_FOUND'));
return false;
}
$_venue->attachments = JemAttachment::getAttachments('venue'.$_venue->id);
return $_venue;
}
}
?>

View File

@ -0,0 +1,146 @@
<?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;
require_once __DIR__ . '/eventslist.php';
/**
* Model-Venuecal
**/
class JemModelVenueCal extends JemModelEventslist
{
/**
* Venue id
*
* @var int
*/
protected $_venue = null;
/**
* Date as timestamp useable for strftime()
*
* @var int
*/
protected $_date = null;
/**
* Constructor
*/
public function __construct()
{
$app = Factory::getApplication();
// $jemsettings = JemHelper::config();
$jinput = $app->input;
$params = $app->getParams();
$id = $jinput->getInt('id', 0);
if (empty($id)) {
$id = $params->get('id', 0);
}
$this->setdate(time());
$this->setId((int)$id);
parent::__construct();
}
public function setdate($date)
{
$this->_date = $date;
}
/**
* Method to set the venue id
*/
public function setId($id)
{
// Set new venue ID and wipe data
$this->_id = $id;
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
$app = Factory::getApplication();
$params = $app->getParams();
$itemid = $app->input->getInt('Itemid', 0);
$task = $app->input->getCmd('task', '');
$startdayonly = $params->get('show_only_start', false);
$show_archived_events = $params->get('show_archived_events', 0);
# params
$this->setState('params', $params);
# publish state
$this->_populatePublishState($task);
###########
## DATES ##
###########
#only select events within specified dates. (chosen month)
$monthstart = mktime(0, 0, 1, date('m', $this->_date), 1, date('Y', $this->_date));
$monthend = mktime(0, 0, -1, date('m', $this->_date)+1, 1, date('Y', $this->_date));
$filter_date_from = date('Y-m-d', $monthstart);
$filter_date_to = date('Y-m-d', $monthend);
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), '. $this->_db->Quote($filter_date_from) .') >= 0';
$this->setState('filter.calendar_from', $where);
$where = ' DATEDIFF(a.dates, '. $this->_db->Quote($filter_date_to) .') <= 0';
$this->setState('filter.calendar_to', $where);
# set filter
$this->setState('filter.calendar_multiday', true);
$this->setState('filter.calendar_startdayonly', (bool)$startdayonly);
$this->setState('filter.filter_locid', $this->_id);
$this->setState('filter.show_archived_events',(bool)$show_archived_events);
$app->setUserState('com_jem.venuecal.locid'.$itemid, $this->_id);
# groupby
$this->setState('filter.groupby', array('a.id'));
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
if ($items) {
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Let parent create a new query object.
$query = parent::getListQuery();
// here we can extend the query of the Eventslist model
$query->select('DATEDIFF(a.enddates, a.dates) AS datesdiff,DAYOFMONTH(a.dates) AS start_day, YEAR(a.dates) AS start_year, MONTH(a.dates) AS start_month');
//$query->where('a.locid = '.$this->_id);
return $query;
}
}
?>

View File

@ -0,0 +1,331 @@
<?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;
require_once __DIR__ . '/eventslist.php';
/**
* Model: Venues
*/
class JemModelVenues extends JemModelEventslist
{
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
// parent::populateState($ordering, $direction);
$app = Factory::getApplication();
$params = $app->getParams();
$task = $app->input->getCmd('task','');
// List state information
$limit = $app->input->getInt('limit', $params->get('display_venues_num'));
$this->setState('list.limit', $limit);
$limitstart = $app->input->getInt('limitstart', 0);
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('list.start', $limitstart);
# params
$this->setState('params', $params);
// $this->setState('filter.published', 1);
$this->setState('filter.groupby', array('l.id'));
# publish state
$this->_populatePublishState($task);
}
/**
* Build the query
*
* @access private
* @return string
*/
protected function getListQuery()
{
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$case_when_l = ' CASE WHEN ';
$case_when_l .= $query->charLength('l.alias');
$case_when_l .= ' THEN ';
$id_l = $query->castAsChar('l.id');
$case_when_l .= $query->concatenate(array($id_l, 'l.alias'), ':');
$case_when_l .= ' ELSE ';
$case_when_l .= $id_l.' END as venueslug';
$query->select(array('l.id AS locid', 'l.locimage', 'l.locdescription', 'l.url', 'l.venue', 'l.created', 'l.created_by',
'l.street', 'l.postalCode', 'l.city', 'l.state', 'l.country',
'l.map', 'l.latitude', 'l.longitude', 'l.published',
'l.custom1', 'l.custom2', 'l.custom3', 'l.custom4', 'l.custom5', 'l.custom6', 'l.custom7', 'l.custom8', 'l.custom9', 'l.custom10',
'l.meta_keywords', 'l.meta_description', 'l.checked_out', 'l.checked_out_time'));
$query->select(array($case_when_l));
$query->from('#__jem_venues as l');
$query->join('LEFT', '#__jem_events AS a ON l.id = a.locid');
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.itemid = a.id');
$query->join('LEFT', '#__jem_categories AS c ON c.id = rel.catid');
// where
$where = array();
// all together: if published or the user is creator of the venue or allowed to edit or publish venues
if (empty($user->id)) {
$where[] = ' l.published = 1';
}
// no limit if user can publish or edit foreign venues
elseif ($user->can(array('edit', 'publish'), 'venue')) {
$where[] = ' l.published IN (0,1)';
}
// user maybe creator
else {
$where[] = ' (l.published = 1 OR (l.published = 0 AND l.created_by = ' . $this->_db->Quote($user->id) . '))';
}
$query->where($where);
$query->group(array('l.id'));
$query->order(array('l.ordering', 'l.venue'));
return $query;
}
/**
* Method to get a list of venues
* We are defining it as we don't want to fire up the getItems function of the eventslist-model
*/
public function getItems()
{
// Get a storage key.
$store = $this->getStoreId();
// Try to load the data from internal storage.
if (!isset($this->cache[$store]))
{
// Load the list items.
$query = $this->_getListQuery();
try
{
$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));
}
catch (RuntimeException $e)
{
$this->setError($e->getMessage());
return false;
}
// Add the items to the internal cache.
$this->cache[$store] = $items;
}
return $this->cache[$store];
}
public function AssignedEvents($id, $state = 1)
{
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$query->select(array('a.id'));
$query->from('#__jem_events as a');
$query->join('LEFT', '#__jem_venues AS l ON l.id = a.locid');
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.itemid = a.id');
$query->join('LEFT', '#__jem_categories AS c ON c.id = rel.catid');
# venue-id
$query->where('l.id= '. $db->quote($id));
# view access level
$query->where('a.access IN (' . implode(',', $levels) . ')');
// Note: categories are filtered in getCategories() called below
// so we don't need to check c.access here
####################
## FILTER-PUBLISH ##
####################
# Filter by published state.
if ((int)$state === 1) {
$where_pub = $this->_getPublishWhere();
if (!empty($where_pub)) {
$query->where('(' . implode(' OR ', $where_pub) . ')');
} else {
// something wrong - fallback to published events
$query->where('a.published = 1');
}
} else {
$query->where('a.published = '.$db->quote($state));
}
#####################
### FILTER - BYCAT ##
#####################
$cats = $this->getCategories('all');
if (!empty($cats)) {
$query->where('c.id IN (' . implode(',', $cats) . ')');
}
$db->setQuery($query);
$ids = $db->loadColumn(0);
$ids = array_unique($ids);
$nr = is_array($ids) ? count($ids) : 0;
if (empty($nr)) {
$nr = 0;
}
return ($nr);
}
/**
* Retrieve Categories
*
* Due to multi-cat this function is needed
* filter-index (4) is pointing to the cats
*/
public function getCategories($id)
{
$user = JemFactory::getUser();
$levels = $user->getAuthorisedViewLevels();
$settings = JemHelper::globalattribs();
// Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$case_when_c = ' CASE WHEN ';
$case_when_c .= $query->charLength('c.alias');
$case_when_c .= ' THEN ';
$id_c = $query->castAsChar('c.id');
$case_when_c .= $query->concatenate(array($id_c, 'c.alias'), ':');
$case_when_c .= ' ELSE ';
$case_when_c .= $id_c.' END as catslug';
$query->select(array('DISTINCT c.id','c.catname','c.access','c.checked_out AS cchecked_out','c.color',$case_when_c));
$query->from('#__jem_categories as c');
$query->join('LEFT', '#__jem_cats_event_relations AS rel ON rel.catid = c.id');
$query->select(array('a.id AS multi'));
$query->join('LEFT','#__jem_events AS a ON a.id = rel.itemid');
if ($id != 'all'){
$query->where('rel.itemid ='.(int)$id);
}
$query->where('c.published = 1');
###################
## FILTER-ACCESS ##
###################
# Filter by access level.
###################################
## FILTER - MAINTAINER/JEM GROUP ##
###################################
# as maintainter someone who is registered can see a category that has special rights
# let's see if the user has access to this category.
// $query3 = $db->getQuery(true);
// $query3 = 'SELECT gr.id'
// . ' FROM #__jem_groups AS gr'
// . ' LEFT JOIN #__jem_groupmembers AS g ON g.group_id = gr.id'
// . ' WHERE g.member = ' . (int) $user->get('id')
// // . ' AND ' .$db->quoteName('gr.addevent') . ' = 1 '
// . ' AND g.member NOT LIKE 0';
// $db->setQuery($query3);
// $groupnumber = $db->loadColumn();
// $jemgroups = implode(',',$groupnumber);
// JEM groups doesn't overrule view access levels!
// if ($jemgroups) {
// $query->where('(c.access IN ('.$groups.') OR c.groupid IN ('.$jemgroups.'))');
// } else {
$query->where('(c.access IN ('.implode(',', $levels).'))');
// }
#######################
## FILTER - CATEGORY ##
#######################
# set filter for top_category
$top_cat = $this->getState('filter.category_top');
if ($top_cat) {
$query->where($top_cat);
}
# Filter by a single or group of categories.
$categoryId = $this->getState('filter.category_id');
if (is_numeric($categoryId)) {
$type = $this->getState('filter.category_id.include', true) ? '= ' : '<> ';
$query->where('c.id '.$type.(int) $categoryId);
}
elseif (is_array($categoryId) && count($categoryId)) {
\Joomla\Utilities\ArrayHelper::toInteger($categoryId);
$categoryId = implode(',', $categoryId);
$type = $this->getState('filter.category_id.include', true) ? 'IN' : 'NOT IN';
$query->where('c.id '.$type.' ('.$categoryId.')');
}
# filter set by day-view
$requestCategoryId = $this->getState('filter.req_catid');
if ($requestCategoryId) {
$query->where('c.id = '.$db->quote($requestCategoryId));
}
###################
## FILTER-SEARCH ##
###################
# define variables
$filter = $this->getState('filter.filter_type');
$search = $this->getState('filter.filter_search');
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('c.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%', false);
if ($search && $settings->get('global_show_filter')) {
if ($filter == 4) {
$query->where('c.catname LIKE '.$search);
}
}
}
}
$db->setQuery($query);
if ($id == 'all') {
$cats = $db->loadColumn(0);
$cats = array_unique($cats);
} else {
$cats = $db->loadObjectList();
}
return $cats;
}
}
?>

View File

@ -0,0 +1,181 @@
<?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\Filter\InputFilter;
use Joomla\CMS\MVC\Model\ListModel;
/**
* Model-Venueslist
*/
class JemModelVenueslist extends ListModel
{
var $_venues = null;
var $_total_venues = null;
/**
* Constructor
*/
public function __construct($config = array())
{
parent::__construct();
$app = Factory::getApplication();
$jemsettings = JEMHelper::config();
parent::__construct($config);
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
$app = Factory::getApplication();
$jemsettings = JemHelper::config();
$jinput = $app->input;
$task = $jinput->getCmd('task');
$itemid = $jinput->getInt('id', 0) . ':' . $jinput->getInt('Itemid', 0);
/* in J! 3.3.6 limitstart is removed from request - but we need it! */
if ($app->input->getInt('limitstart', null) === null) {
$app->setUserState('com_jem.venueslist.limitstart', 0);
}
$limit = $app->getUserStateFromRequest('com_jem.venueslist.'.$itemid.'.limit', 'limit', $jemsettings->display_num, 'int');
$this->setState('list.limit', $limit);
$limitstart = $app->getUserStateFromRequest('com_jem.venueslist.'.$itemid.'.limitstart', 'limitstart', 0, 'int');
// correct start value if required
$limitstart = $limit ? (int)(floor($limitstart / $limit) * $limit) : 0;
$this->setState('list.start', $limitstart);
# Search - variables
$search = $app->getUserStateFromRequest('com_jem.venueslist.'.$itemid.'.filter_search', 'filter_search', '', 'string');
$this->setState('filter.filter_search', $search); // must be escaped later
$filtertype = $app->getUserStateFromRequest('com_jem.venueslist.'.$itemid.'.filter_type', 'filter_type', '', 'int');
$this->setState('filter.filter_type', $filtertype);
###########
## ORDER ##
###########
$filter_order = $app->getUserStateFromRequest('com_jem.venueslist.'.$itemid.'.filter_order', 'filter_order', 'a.city', 'cmd');
$filter_order_Dir = $app->getUserStateFromRequest('com_jem.venueslist.'.$itemid.'.filter_order_Dir', 'filter_order_Dir', 'ASC', 'word');
$filter_order = InputFilter::getInstance()->clean($filter_order, 'cmd');
$filter_order_Dir = InputFilter::getInstance()->clean($filter_order_Dir, 'word');
$orderby = $filter_order . ' ' . $filter_order_Dir;
$this->setState('filter.orderby',$orderby);
parent::populateState('a.venue', 'ASC');
}
/**
* Method to get a store id based on model configuration state.
*/
protected function getStoreId($id = '')
{
$id .= ':' . $this->getState('list.start');
$id .= ':' . $this->getState('list.limit');
$id .= ':' . $this->getState('filter.filter_search');
$id .= ':' . $this->getState('filter.filter_type');
$id .= ':' . serialize($this->getState('filter.orderby'));
return parent::getStoreId($id);
}
/**
* Build the query
*/
protected function getListQuery()
{
$app = Factory::getApplication();
$jinput = Factory::getApplication()->input;
$task = $jinput->getCmd('task', '');
$itemid = $jinput->getInt('id', 0) . ':' . $jinput->getInt('Itemid', 0);
$params = $app->getParams();
$settings = JemHelper::globalattribs();
$user = JemFactory::getUser();
# Query
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true);
$case_when_l = ' CASE WHEN ';
$case_when_l .= $query->charLength('a.alias','!=', '0');
$case_when_l .= ' THEN ';
$id_l = $query->castAsChar('a.id');
$case_when_l .= $query->concatenate(array($id_l, 'a.alias'), ':');
$case_when_l .= ' ELSE ';
$case_when_l .= $id_l.' END as venueslug';
# venue
$query->select(
$this->getState(
'list.select',
'a.*'
)
);
$query->from('#__jem_venues as a');
$query->select(array($case_when_l));
###################
## FILTER-SEARCH ##
###################
# define variables
$filter = $this->getState('filter.filter_type');
$search = $this->getState('filter.filter_search'); // not escaped
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('a.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%', false); // escape once
if ($search && $settings->get('global_show_filter')) {
switch ($filter) {
# case 4 is category, so it is omitted
# there is no title so omit case 1
#case 1:
# $query->where('a.title LIKE '.$search);
# break;
case 2:
$query->where('a.venue LIKE '.$search);
break;
case 3:
$query->where('a.city LIKE '.$search);
break;
case 5:
$query->where('a.state LIKE '.$search);
break;
}
}
}
}
# ordering
$orderby = $this->getState('filter.orderby');
if ($orderby) {
$query->order($orderby);
}
return $query;
}
}

View File

@ -0,0 +1,269 @@
<?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;
require_once __DIR__ . '/eventslist.php';
/**
* Model-Calendar
*/
class JemModelWeekcal extends JemModelEventslist
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
}
/**
* Method to auto-populate the model state.
*/
protected function populateState($ordering = null, $direction = null)
{
$app = Factory::getApplication();
$task = $app->input->getCmd('task', '');
$params = $app->getParams();
$top_category = $params->get('top_category', 0);
$show_archived_events = $params->get('show_archived_events', 0);
$startdayonly = $params->get('show_only_start', false);
$numberOfWeeks = $params->get('nrweeks', '1');
$firstweekday = $params->get('firstweekday', 1);
# params
$this->setState('params', $params);
# publish state
$this->_populatePublishState($task);
###########
## DATES ##
###########
#only select events within specified dates. (chosen weeknrs)
$config = Factory::getConfig();
$offset = $config->get('offset');
date_default_timezone_set($offset);
$datetime = new DateTime();
// If week starts Monday we use dayoffset 1, on Sunday we use 0 but 7 if today is Sunday.
$dayoffset = ($firstweekday == 1) ? 1 : ((($firstweekday == 0) && ($datetime->format('N') == 7)) ? 7 : 0);
$datetime->setISODate($datetime->format('Y'), $datetime->format('W'), $dayoffset);
$filter_date_from = $datetime->format('Y-m-d');
$datetime->modify('+'.$numberOfWeeks.' weeks'.' -1 day'); // just to be compatible to php < 5.3 ;-)
$filter_date_to = $datetime->format('Y-m-d');
$where = ' DATEDIFF(IF (a.enddates IS NOT NULL, a.enddates, a.dates), ' . $this->_db->quote($filter_date_from) . ') >= 0';
$this->setState('filter.calendar_from', $where);
$this->setState('filter.date.from', $filter_date_from);
$where = ' DATEDIFF(a.dates, ' . $this->_db->quote($filter_date_to) . ') <= 0';
$this->setState('filter.calendar_to', $where);
$this->setState('filter.date.to', $filter_date_to);
##################
## TOP-CATEGORY ##
##################
if ($top_category) {
$children = JemCategories::getChilds($top_category);
if (count($children)) {
$where = 'rel.catid IN ('. implode(',', $children) .')';
$this->setState('filter.category_top', $where);
}
}
# set filter
$this->setState('filter.calendar_startdayonly', (bool)$startdayonly);
$this->setState('filter.groupby', 'a.id');
$this->setState('filter.show_archived_events',(bool)$show_archived_events);
}
/**
* Method to get a list of events.
*/
public function getItems()
{
$items = parent::getItems();
if ($items) {
$items = $this->calendarMultiday($items);
return $items;
}
return array();
}
/**
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Let parent create a new query object.
$query = parent::getListQuery();
$query->select('DATEDIFF(a.enddates, a.dates) AS datesdiff, DAYOFWEEK(a.dates) AS weekday, DAYOFMONTH(a.dates) AS start_day, YEAR(a.dates) AS start_year, MONTH(a.dates) AS start_month, WEEK(a.dates) AS weeknumber');
return $query;
}
/**
* create multi-day events
*/
protected function calendarMultiday($items)
{
if (empty($items)) {
return array();
}
$app = Factory::getApplication();
$params = $app->getParams();
$startdayonly = $this->getState('filter.calendar_startdayonly');
if (!$startdayonly) {
foreach ($items as $i => $item)
{
if (!is_null($item->enddates) && ($item->enddates != $item->dates)) {
$day = $item->start_day;
$multi = array();
$item->multi = 'first';
$item->multitimes = $item->times;
$item->multiname = $item->title;
$item->sort = 'zlast';
for ($counter = 0; $counter <= $item->datesdiff-1; $counter++)
{
# next day:
$day++;
$nextday = mktime(0, 0, 0, $item->start_month, $day, $item->start_year);
# generate days of current multi-day selection
$multi[$counter] = clone $item;
$multi[$counter]->dates = date('Y-m-d', $nextday);
if ($multi[$counter]->dates < $item->enddates) {
$multi[$counter]->multi = 'middle';
$multi[$counter]->multistartdate = $item->dates;
$multi[$counter]->multienddate = $item->enddates;
$multi[$counter]->multitimes = $item->times;
$multi[$counter]->multiname = $item->title;
$multi[$counter]->times = $item->times;
$multi[$counter]->endtimes = $item->endtimes;
$multi[$counter]->sort = 'middle';
} elseif ($multi[$counter]->dates == $item->enddates) {
$multi[$counter]->multi = 'zlast';
$multi[$counter]->multistartdate = $item->dates;
$multi[$counter]->multienddate = $item->enddates;
$multi[$counter]->multitimes = $item->times;
$multi[$counter]->multiname = $item->title;
$multi[$counter]->sort = 'first';
$multi[$counter]->times = $item->times;
$multi[$counter]->endtimes = $item->endtimes;
}
} // for
# add generated days to data
$items = array_merge($items, $multi);
# unset temp array holding generated days before working on the next multiday event
unset($multi);
}
} // foreach
}
# Remove items out of date range
$startdate = $this->getState('filter.date.from');
$enddate = $this->getState('filter.date.to');
if (empty($startdate) || empty($enddate)) {
$config = Factory::getConfig();
$offset = $config->get('offset');
$firstweekday = $params->get('firstweekday', 1); // 1 = Monday, 0 = Sunday
$numberOfWeeks = $params->get('nrweeks', '1');
date_default_timezone_set($offset);
$datetime = new DateTime();
# If week starts Monday we use dayoffset 1, on Sunday we use 0 but 7 if today is Sunday.
$dayoffset = ($firstweekday == 1) ? 1 : ((($firstweekday == 0) && ($datetime->format('N') == 7)) ? 7 : 0);
$datetime->setISODate($datetime->format('Y'), $datetime->format('W'), $dayoffset);
$startdate = $datetime->format('Y-m-d');
$datetime->modify('+'.$numberOfWeeks.' weeks'.' -1 day'); // just to be compatible to php < 5.3 ;-)
$enddate = $datetime->format('Y-m-d');
}
$check_startdate = strtotime($startdate);
$check_enddate = strtotime($enddate);
foreach ($items as $index => $item) {
$date = $item->dates;
$date_timestamp = strtotime($date);
if ($date_timestamp > $check_enddate) {
unset ($items[$index]);
} elseif ($date_timestamp < $check_startdate) {
unset ($items[$index]);
}
}
# Do we still have events? Return if not.
if (empty($items)) {
return array();
}
# Sort the items
foreach ($items as $item) {
$time[] = $item->times;
$title[] = $item->title;
// $id[] = $item->id;
// $dates[] = $item->dates;
$multi[] = (isset($item->multi) ? $item->multi : false);
$multitime[] = (isset($item->multitime) ? $item->multitime : false);
$multititle[] = (isset($item->multititle) ? $item->multititle : false);
$sort[] = (isset($item->sort) ? $item->sort : 'zlast');
}
array_multisort($sort, SORT_ASC, $multitime, $multititle, $time, SORT_ASC, $title, $items);
return $items;
}
/**
* Method to get the Currentweek
*
* Info MYSQL WEEK
* @link https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week
*/
public function getCurrentweek()
{
if (!isset($this->_currentweek)) {
$app = Factory::getApplication();
$params = $app->getParams('com_jem');
$weekday = $params->get('firstweekday', 1); // 1 = Monday, 0 = Sunday
if ($weekday == 1) {
$number = 3; // Monday, with more than 3 days this year
} else {
$number = 6; // Sunday, with more than 3 days this year
}
$today = Date("Y-m-d");
$query = 'SELECT WEEK(\''.$today.'\','.$number.')' ;
$this->_db->setQuery($query);
$this->_currentweek = $this->_db->loadResult();
}
return $this->_currentweek;
}
}
?>