<?php

namespace {
/*
 * This file is part of Contao.
 *
 * (c) Leo Feyer
 *
 * @license LGPL-3.0-or-later
 */
\Contao\System::loadLanguageFile('tl_content');
$GLOBALS['TL_DCA']['tl_calendar_events'] = array(
    // Config
    'config' => array('dataContainer' => \Contao\DC_Table::class, 'ptable' => 'tl_calendar', 'ctable' => array('tl_content'), 'switchToEdit' => \true, 'enableVersioning' => \true, 'markAsCopy' => 'title', 'onload_callback' => array(array('tl_calendar_events', 'checkPermission'), array('tl_calendar_events', 'generateFeed')), 'oncut_callback' => array(array('tl_calendar_events', 'scheduleUpdate')), 'ondelete_callback' => array(array('tl_calendar_events', 'scheduleUpdate')), 'onsubmit_callback' => array(array('tl_calendar_events', 'adjustTime'), array('tl_calendar_events', 'scheduleUpdate')), 'sql' => array('keys' => array('id' => 'primary', 'alias' => 'index', 'pid,start,stop,published' => 'index'))),
    // List
    'list' => array('sorting' => array('mode' => 4, 'fields' => array('startTime'), 'headerFields' => array('title', 'jumpTo', 'tstamp', 'protected', 'allowComments'), 'panelLayout' => 'filter;sort,search,limit', 'child_record_callback' => array('tl_calendar_events', 'listEvents')), 'global_operations' => array('all' => array('href' => 'act=select', 'class' => 'header_edit_all', 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"')), 'operations' => array('edit' => array('href' => 'table=tl_content', 'icon' => 'edit.svg'), 'editheader' => array('href' => 'act=edit', 'icon' => 'header.svg'), 'copy' => array('href' => 'act=paste&amp;mode=copy', 'icon' => 'copy.svg'), 'cut' => array('href' => 'act=paste&amp;mode=cut', 'icon' => 'cut.svg'), 'delete' => array('href' => 'act=delete', 'icon' => 'delete.svg', 'attributes' => 'onclick="if(!confirm(\'' . $GLOBALS['TL_LANG']['MSC']['deleteConfirm'] . '\'))return false;Backend.getScrollOffset()"'), 'toggle' => array('icon' => 'visible.svg', 'attributes' => 'onclick="Backend.getScrollOffset();return AjaxRequest.toggleVisibility(this,%s)"', 'button_callback' => array('tl_calendar_events', 'toggleIcon'), 'showInHeader' => \true), 'show' => array('href' => 'act=show', 'icon' => 'show.svg'))),
    // Palettes
    'palettes' => array('__selector__' => array('source', 'addTime', 'addImage', 'recurring', 'addEnclosure', 'overwriteMeta'), 'default' => '{title_legend},title,alias,author;{date_legend},addTime,startDate,endDate;{source_legend:hide},source;{meta_legend},pageTitle,description,serpPreview;{details_legend},location,address,teaser;{image_legend},addImage;{recurring_legend},recurring;{enclosure_legend:hide},addEnclosure;{expert_legend:hide},cssClass,noComments;{publish_legend},published,start,stop', 'internal' => '{title_legend},title,alias,author;{date_legend},addTime,startDate,endDate;{source_legend},source,jumpTo;{details_legend},location,address,teaser;{image_legend},addImage;{recurring_legend},recurring;{enclosure_legend:hide},addEnclosure;{expert_legend:hide},cssClass,noComments;{publish_legend},published,start,stop', 'article' => '{title_legend},title,alias,author;{date_legend},addTime,startDate,endDate;{source_legend},source,articleId;{details_legend},location,address,teaser;{image_legend},addImage;{recurring_legend},recurring;{enclosure_legend:hide},addEnclosure;{expert_legend:hide},cssClass,noComments;{publish_legend},published,start,stop', 'external' => '{title_legend},title,alias,author;{date_legend},addTime,startDate,endDate;{source_legend},source,url,target;{details_legend},location,address,teaser;{image_legend},addImage;{recurring_legend},recurring;{enclosure_legend:hide},addEnclosure;{expert_legend:hide},cssClass,noComments;{publish_legend},published,start,stop'),
    // Subpalettes
    'subpalettes' => array('addTime' => 'startTime,endTime', 'addImage' => 'singleSRC,size,floating,imagemargin,fullsize,overwriteMeta', 'recurring' => 'repeatEach,recurrences', 'addEnclosure' => 'enclosure', 'overwriteMeta' => 'alt,imageTitle,imageUrl,caption'),
    // Fields
    'fields' => array('id' => array('sql' => "int(10) unsigned NOT NULL auto_increment"), 'pid' => array('foreignKey' => 'tl_calendar.title', 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'belongsTo', 'load' => 'lazy')), 'tstamp' => array('sql' => "int(10) unsigned NOT NULL default 0"), 'title' => array('exclude' => \true, 'search' => \true, 'sorting' => \true, 'flag' => 1, 'inputType' => 'text', 'eval' => array('mandatory' => \true, 'maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'alias' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'alias', 'doNotCopy' => \true, 'unique' => \true, 'maxlength' => 255, 'tl_class' => 'w50 clr'), 'save_callback' => array(array('tl_calendar_events', 'generateAlias')), 'sql' => "varchar(255) BINARY NOT NULL default ''"), 'author' => array('default' => \Contao\BackendUser::getInstance()->id, 'exclude' => \true, 'search' => \true, 'filter' => \true, 'sorting' => \true, 'flag' => 11, 'inputType' => 'select', 'foreignKey' => 'tl_user.name', 'eval' => array('doNotCopy' => \true, 'chosen' => \true, 'mandatory' => \true, 'includeBlankOption' => \true, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'addTime' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true, 'doNotCopy' => \true), 'sql' => "char(1) NOT NULL default ''"), 'startTime' => array('default' => \time(), 'exclude' => \true, 'filter' => \true, 'sorting' => \true, 'flag' => 8, 'inputType' => 'text', 'eval' => array('rgxp' => 'time', 'mandatory' => \true, 'doNotCopy' => \true, 'tl_class' => 'w50'), 'load_callback' => array(array('tl_calendar_events', 'loadTime')), 'sql' => "int(10) NULL"), 'endTime' => array('default' => \time(), 'exclude' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'time', 'doNotCopy' => \true, 'tl_class' => 'w50'), 'load_callback' => array(array('tl_calendar_events', 'loadEndTime')), 'save_callback' => array(array('tl_calendar_events', 'setEmptyEndTime')), 'sql' => "int(10) NULL"), 'startDate' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'date', 'mandatory' => \true, 'doNotCopy' => \true, 'datepicker' => \true, 'tl_class' => 'w50 wizard'), 'sql' => "int(10) unsigned NULL"), 'endDate' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'date', 'doNotCopy' => \true, 'datepicker' => \true, 'tl_class' => 'w50 wizard'), 'sql' => "int(10) unsigned NULL"), 'pageTitle' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'decodeEntities' => \true, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'description' => array('exclude' => \true, 'search' => \true, 'inputType' => 'textarea', 'eval' => array('style' => 'height:60px', 'decodeEntities' => \true, 'tl_class' => 'clr'), 'sql' => "text NULL"), 'serpPreview' => array('label' => &$GLOBALS['TL_LANG']['MSC']['serpPreview'], 'exclude' => \true, 'inputType' => 'serpPreview', 'eval' => array('url_callback' => array('tl_calendar_events', 'getSerpUrl'), 'title_tag_callback' => array('tl_calendar_events', 'getTitleTag'), 'titleFields' => array('pageTitle', 'title'), 'descriptionFields' => array('description', 'teaser')), 'sql' => \null), 'location' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'address' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'teaser' => array('exclude' => \true, 'search' => \true, 'inputType' => 'textarea', 'eval' => array('rte' => 'tinyMCE', 'tl_class' => 'clr'), 'sql' => "text NULL"), 'addImage' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'overwriteMeta' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['overwriteMeta'], 'exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true, 'tl_class' => 'w50 clr'), 'sql' => "char(1) NOT NULL default ''"), 'singleSRC' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['singleSRC'], 'exclude' => \true, 'inputType' => 'fileTree', 'eval' => array('filesOnly' => \true, 'fieldType' => 'radio', 'extensions' => \Contao\Config::get('validImageTypes'), 'mandatory' => \true), 'sql' => "binary(16) NULL"), 'alt' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['alt'], 'exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'imageTitle' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['imageTitle'], 'exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'size' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['size'], 'exclude' => \true, 'inputType' => 'imageSize', 'reference' => &$GLOBALS['TL_LANG']['MSC'], 'eval' => array('rgxp' => 'natural', 'includeBlankOption' => \true, 'nospace' => \true, 'helpwizard' => \true, 'tl_class' => 'w50'), 'options_callback' => static function () {
        return \Contao\System::getContainer()->get('contao.image.image_sizes')->getOptionsForUser(\Contao\BackendUser::getInstance());
    }, 'sql' => "varchar(64) NOT NULL default ''"), 'imagemargin' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['imagemargin'], 'exclude' => \true, 'inputType' => 'trbl', 'options' => $GLOBALS['TL_CSS_UNITS'], 'eval' => array('includeBlankOption' => \true, 'tl_class' => 'w50'), 'sql' => "varchar(128) NOT NULL default ''"), 'imageUrl' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['imageUrl'], 'exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'url', 'decodeEntities' => \true, 'maxlength' => 255, 'dcaPicker' => \true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(255) NOT NULL default ''"), 'fullsize' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['fullsize'], 'exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'caption' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['caption'], 'exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'allowHtml' => \true, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'floating' => array('label' => &$GLOBALS['TL_LANG']['tl_content']['floating'], 'exclude' => \true, 'inputType' => 'radioTable', 'options' => array('above', 'left', 'right', 'below'), 'eval' => array('cols' => 4, 'tl_class' => 'w50'), 'reference' => &$GLOBALS['TL_LANG']['MSC'], 'sql' => "varchar(32) NOT NULL default 'above'"), 'recurring' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'repeatEach' => array('exclude' => \true, 'inputType' => 'timePeriod', 'options' => array('days', 'weeks', 'months', 'years'), 'reference' => &$GLOBALS['TL_LANG']['tl_calendar_events'], 'eval' => array('mandatory' => \true, 'rgxp' => 'natural', 'minval' => 1, 'tl_class' => 'w50'), 'sql' => "varchar(64) NOT NULL default ''"), 'repeatEnd' => array('sql' => "int(10) unsigned NOT NULL default 0"), 'recurrences' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('mandatory' => \true, 'rgxp' => 'natural', 'tl_class' => 'w50'), 'sql' => "smallint(5) unsigned NOT NULL default 0"), 'addEnclosure' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'enclosure' => array('exclude' => \true, 'inputType' => 'fileTree', 'eval' => array('multiple' => \true, 'fieldType' => 'checkbox', 'filesOnly' => \true, 'isDownloads' => \true, 'extensions' => \Contao\Config::get('allowedDownload'), 'mandatory' => \true, 'orderField' => 'orderEnclosure'), 'sql' => "blob NULL"), 'orderEnclosure' => array('label' => &$GLOBALS['TL_LANG']['MSC']['sortOrder'], 'sql' => "blob NULL"), 'source' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'radio', 'options_callback' => array('tl_calendar_events', 'getSourceOptions'), 'reference' => &$GLOBALS['TL_LANG']['tl_calendar_events'], 'eval' => array('submitOnChange' => \true, 'helpwizard' => \true), 'sql' => "varchar(32) NOT NULL default 'default'"), 'jumpTo' => array('exclude' => \true, 'inputType' => 'pageTree', 'foreignKey' => 'tl_page.title', 'eval' => array('mandatory' => \true, 'fieldType' => 'radio'), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'belongsTo', 'load' => 'lazy')), 'articleId' => array('exclude' => \true, 'inputType' => 'select', 'options_callback' => array('tl_calendar_events', 'getArticleAlias'), 'eval' => array('chosen' => \true, 'mandatory' => \true, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('table' => 'tl_article', 'type' => 'hasOne', 'load' => 'lazy')), 'url' => array('label' => &$GLOBALS['TL_LANG']['MSC']['url'], 'exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('mandatory' => \true, 'rgxp' => 'url', 'decodeEntities' => \true, 'maxlength' => 255, 'dcaPicker' => \true, 'addWizardClass' => \false, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'target' => array('label' => &$GLOBALS['TL_LANG']['MSC']['target'], 'exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'cssClass' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'noComments' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'published' => array('exclude' => \true, 'filter' => \true, 'flag' => 2, 'inputType' => 'checkbox', 'eval' => array('doNotCopy' => \true), 'sql' => "char(1) NOT NULL default ''"), 'start' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'datim', 'datepicker' => \true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(10) NOT NULL default ''"), 'stop' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'datim', 'datepicker' => \true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(10) NOT NULL default ''")),
);
/**
 * Provide miscellaneous methods that are used by the data configuration array.
 *
 * @property Contao\Calendar $Calendar
 *
 * @author Leo Feyer <https://github.com/leofeyer>
 */
class tl_calendar_events extends \Contao\Backend
{
    /**
     * Import the back end user object
     */
    public function __construct()
    {
        parent::__construct();
        $this->import('Contao\\BackendUser', 'User');
    }
    /**
     * Check permissions to edit table tl_calendar_events
     *
     * @throws Contao\CoreBundle\Exception\AccessDeniedException
     */
    public function checkPermission()
    {
        $bundles = \Contao\System::getContainer()->getParameter('kernel.bundles');
        // HOOK: comments extension required
        if (!isset($bundles['ContaoCommentsBundle'])) {
            $key = \array_search('allowComments', $GLOBALS['TL_DCA']['tl_calendar_events']['list']['sorting']['headerFields']);
            unset($GLOBALS['TL_DCA']['tl_calendar_events']['list']['sorting']['headerFields'][$key], $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['noComments']);
        }
        if ($this->User->isAdmin) {
            return;
        }
        // Set root IDs
        if (empty($this->User->calendars) || !\is_array($this->User->calendars)) {
            $root = array(0);
        } else {
            $root = $this->User->calendars;
        }
        $id = \strlen(\Contao\Input::get('id')) ? \Contao\Input::get('id') : \CURRENT_ID;
        // Check current action
        switch (\Contao\Input::get('act')) {
            case 'paste':
            case 'select':
                // Check CURRENT_ID here (see #247)
                if (!\in_array(\CURRENT_ID, $root)) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access calendar ID ' . $id . '.');
                }
                break;
            case 'create':
                if (!\Contao\Input::get('pid') || !\in_array(\Contao\Input::get('pid'), $root)) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to create events in calendar ID ' . \Contao\Input::get('pid') . '.');
                }
                break;
            case 'cut':
            case 'copy':
                if (!\in_array(\Contao\Input::get('pid'), $root)) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . \Contao\Input::get('act') . ' event ID ' . $id . ' to calendar ID ' . \Contao\Input::get('pid') . '.');
                }
            // no break
            case 'edit':
            case 'show':
            case 'delete':
            case 'toggle':
                $objCalendar = $this->Database->prepare("SELECT pid FROM tl_calendar_events WHERE id=?")->limit(1)->execute($id);
                if ($objCalendar->numRows < 1) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Invalid event ID ' . $id . '.');
                }
                if (!\in_array($objCalendar->pid, $root)) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . \Contao\Input::get('act') . ' event ID ' . $id . ' of calendar ID ' . $objCalendar->pid . '.');
                }
                break;
            case 'editAll':
            case 'deleteAll':
            case 'overrideAll':
            case 'cutAll':
            case 'copyAll':
                if (!\in_array($id, $root)) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access calendar ID ' . $id . '.');
                }
                $objCalendar = $this->Database->prepare("SELECT id FROM tl_calendar_events WHERE pid=?")->execute($id);
                /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
                $objSession = \Contao\System::getContainer()->get('session');
                $session = $objSession->all();
                $session['CURRENT']['IDS'] = \array_intersect((array) $session['CURRENT']['IDS'], $objCalendar->fetchEach('id'));
                $objSession->replace($session);
                break;
            default:
                if (\Contao\Input::get('act')) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Invalid command "' . \Contao\Input::get('act') . '".');
                }
                if (!\in_array($id, $root)) {
                    throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access calendar ID ' . $id . '.');
                }
                break;
        }
    }
    /**
     * Auto-generate the event alias if it has not been set yet
     *
     * @param mixed                $varValue
     * @param Contao\DataContainer $dc
     *
     * @return mixed
     *
     * @throws Exception
     */
    public function generateAlias($varValue, \Contao\DataContainer $dc)
    {
        $aliasExists = function (string $alias) use($dc) : bool {
            return $this->Database->prepare("SELECT id FROM tl_calendar_events WHERE alias=? AND id!=?")->execute($alias, $dc->id)->numRows > 0;
        };
        // Generate the alias if there is none
        if (!$varValue) {
            $varValue = \Contao\System::getContainer()->get('contao.slug')->generate($dc->activeRecord->title, \Contao\CalendarModel::findByPk($dc->activeRecord->pid)->jumpTo, $aliasExists);
        } elseif (\preg_match('/^[1-9]\\d*$/', $varValue)) {
            throw new \Exception(\sprintf($GLOBALS['TL_LANG']['ERR']['aliasNumeric'], $varValue));
        } elseif ($aliasExists($varValue)) {
            throw new \Exception(\sprintf($GLOBALS['TL_LANG']['ERR']['aliasExists'], $varValue));
        }
        return $varValue;
    }
    /**
     * Set the timestamp to 1970-01-01 (see #26)
     *
     * @param integer $value
     *
     * @return integer
     */
    public function loadTime($value)
    {
        return \strtotime('1970-01-01 ' . \date('H:i:s', $value));
    }
    /**
     * Set the end time to an empty string (see #23)
     *
     * @param integer              $value
     * @param Contao\DataContainer $dc
     *
     * @return integer
     */
    public function loadEndTime($value, \Contao\DataContainer $dc)
    {
        $return = \strtotime('1970-01-01 ' . \date('H:i:s', $value));
        // Return an empty string if the start time is the same as the end time (see #23)
        if ($dc->activeRecord && $return == $dc->activeRecord->startTime) {
            return '';
        }
        // Return an empty string if no time has been set yet
        if ($dc->activeRecord && $return - $dc->activeRecord->startTime == 86399) {
            return '';
        }
        return \strtotime('1970-01-01 ' . \date('H:i:s', $value));
    }
    /**
     * Automatically set the end time if not set
     *
     * @param mixed                $varValue
     * @param Contao\DataContainer $dc
     *
     * @return string
     */
    public function setEmptyEndTime($varValue, \Contao\DataContainer $dc)
    {
        if ($varValue === \null) {
            $varValue = $dc->activeRecord->startTime;
        }
        return $varValue;
    }
    /**
     * Return the SERP URL
     *
     * @param Contao\CalendarEventsModel $model
     *
     * @return string
     */
    public function getSerpUrl(\Contao\CalendarEventsModel $model)
    {
        return \Contao\Events::generateEventUrl($model, \true);
    }
    /**
     * Return the title tag from the associated page layout
     *
     * @param Contao\NewsModel $model
     *
     * @return string
     */
    public function getTitleTag(\Contao\CalendarEventsModel $model)
    {
        /** @var Contao\CalendarModel $calendar */
        if (!($calendar = $model->getRelated('pid'))) {
            return '';
        }
        /** @var Contao\PageModel $page */
        if (!($page = $calendar->getRelated('jumpTo'))) {
            return '';
        }
        $page->loadDetails();
        /** @var Contao\LayoutModel $layout */
        if (!($layout = $page->getRelated('layout'))) {
            return '';
        }
        $origObjPage = $GLOBALS['objPage'] ?? \null;
        // Override the global page object, so we can replace the insert tags
        $GLOBALS['objPage'] = $page;
        $title = \implode('%s', \array_map(static function ($strVal) {
            return \str_replace('%', '%%', self::replaceInsertTags($strVal));
        }, \explode('{{page::pageTitle}}', $layout->titleTag ?: '{{page::pageTitle}} - {{page::rootPageTitle}}', 2)));
        $GLOBALS['objPage'] = $origObjPage;
        return $title;
    }
    /**
     * Add the type of input field
     *
     * @param array $arrRow
     *
     * @return string
     */
    public function listEvents($arrRow)
    {
        $span = \Contao\Calendar::calculateSpan($arrRow['startTime'], $arrRow['endTime']);
        if ($span > 0) {
            $date = \Contao\Date::parse(\Contao\Config::get($arrRow['addTime'] ? 'datimFormat' : 'dateFormat'), $arrRow['startTime']) . $GLOBALS['TL_LANG']['MSC']['cal_timeSeparator'] . \Contao\Date::parse(\Contao\Config::get($arrRow['addTime'] ? 'datimFormat' : 'dateFormat'), $arrRow['endTime']);
        } elseif ($arrRow['startTime'] == $arrRow['endTime']) {
            $date = \Contao\Date::parse(\Contao\Config::get('dateFormat'), $arrRow['startTime']) . ($arrRow['addTime'] ? ' ' . \Contao\Date::parse(\Contao\Config::get('timeFormat'), $arrRow['startTime']) : '');
        } else {
            $date = \Contao\Date::parse(\Contao\Config::get('dateFormat'), $arrRow['startTime']) . ($arrRow['addTime'] ? ' ' . \Contao\Date::parse(\Contao\Config::get('timeFormat'), $arrRow['startTime']) . $GLOBALS['TL_LANG']['MSC']['cal_timeSeparator'] . \Contao\Date::parse(\Contao\Config::get('timeFormat'), $arrRow['endTime']) : '');
        }
        return '<div class="tl_content_left">' . $arrRow['title'] . ' <span style="color:#999;padding-left:3px">[' . $date . ']</span></div>';
    }
    /**
     * Get all articles and return them as array
     *
     * @param Contao\DataContainer $dc
     *
     * @return array
     */
    public function getArticleAlias(\Contao\DataContainer $dc)
    {
        $arrPids = array();
        $arrAlias = array();
        if (!$this->User->isAdmin) {
            foreach ($this->User->pagemounts as $id) {
                $arrPids[] = array($id);
                $arrPids[] = $this->Database->getChildRecords($id, 'tl_page');
            }
            if (!empty($arrPids)) {
                $arrPids = \array_merge(...$arrPids);
            } else {
                return $arrAlias;
            }
            $objAlias = $this->Database->prepare("SELECT a.id, a.title, a.inColumn, p.title AS parent FROM tl_article a LEFT JOIN tl_page p ON p.id=a.pid WHERE a.pid IN(" . \implode(',', \array_map('\\intval', \array_unique($arrPids))) . ") ORDER BY parent, a.sorting")->execute($dc->id);
        } else {
            $objAlias = $this->Database->prepare("SELECT a.id, a.title, a.inColumn, p.title AS parent FROM tl_article a LEFT JOIN tl_page p ON p.id=a.pid ORDER BY parent, a.sorting")->execute($dc->id);
        }
        if ($objAlias->numRows) {
            \Contao\System::loadLanguageFile('tl_article');
            while ($objAlias->next()) {
                $arrAlias[$objAlias->parent][$objAlias->id] = $objAlias->title . ' (' . ($GLOBALS['TL_LANG']['COLS'][$objAlias->inColumn] ?: $objAlias->inColumn) . ', ID ' . $objAlias->id . ')';
            }
        }
        return $arrAlias;
    }
    /**
     * Add the source options depending on the allowed fields (see #5498)
     *
     * @param Contao\DataContainer $dc
     *
     * @return array
     */
    public function getSourceOptions(\Contao\DataContainer $dc)
    {
        if ($this->User->isAdmin) {
            return array('default', 'internal', 'article', 'external');
        }
        $arrOptions = array('default');
        // Add the "internal" option
        if ($this->User->hasAccess('tl_calendar_events::jumpTo', 'alexf')) {
            $arrOptions[] = 'internal';
        }
        // Add the "article" option
        if ($this->User->hasAccess('tl_calendar_events::articleId', 'alexf')) {
            $arrOptions[] = 'article';
        }
        // Add the "external" option
        if ($this->User->hasAccess('tl_calendar_events::url', 'alexf')) {
            $arrOptions[] = 'external';
        }
        // Add the option currently set
        if ($dc->activeRecord && $dc->activeRecord->source) {
            $arrOptions[] = $dc->activeRecord->source;
            $arrOptions = \array_unique($arrOptions);
        }
        return $arrOptions;
    }
    /**
     * Adjust start end end time of the event based on date, span, startTime and endTime
     *
     * @param Contao\DataContainer $dc
     */
    public function adjustTime(\Contao\DataContainer $dc)
    {
        // Return if there is no active record (override all) or no start date has been set yet
        if (!$dc->activeRecord || !$dc->activeRecord->startDate) {
            return;
        }
        $arrSet['startTime'] = $dc->activeRecord->startDate;
        $arrSet['endTime'] = $dc->activeRecord->startDate;
        // Set end date
        if ($dc->activeRecord->endDate) {
            if ($dc->activeRecord->endDate > $dc->activeRecord->startDate) {
                $arrSet['endDate'] = $dc->activeRecord->endDate;
                $arrSet['endTime'] = $dc->activeRecord->endDate;
            } else {
                $arrSet['endDate'] = $dc->activeRecord->startDate;
                $arrSet['endTime'] = $dc->activeRecord->startDate;
            }
        }
        // Add time
        if ($dc->activeRecord->addTime) {
            $arrSet['startTime'] = \strtotime(\date('Y-m-d', $arrSet['startTime']) . ' ' . \date('H:i:s', $dc->activeRecord->startTime));
            $arrSet['endTime'] = \strtotime(\date('Y-m-d', $arrSet['endTime']) . ' ' . \date('H:i:s', '' !== (string) $dc->activeRecord->endTime ? $dc->activeRecord->endTime : $dc->activeRecord->startTime));
        } elseif ($dc->activeRecord->endDate && $arrSet['endDate'] == $arrSet['endTime'] || $arrSet['startTime'] == $arrSet['endTime']) {
            $arrSet['endTime'] = \strtotime('+ 1 day', $arrSet['endTime']) - 1;
        }
        $arrSet['repeatEnd'] = 0;
        // Recurring events
        if ($dc->activeRecord->recurring) {
            // Unlimited recurrences end on 2106-02-07 07:28:15 (see #4862 and #510)
            if ($dc->activeRecord->recurrences == 0) {
                $arrSet['repeatEnd'] = \min(4294967295, \PHP_INT_MAX);
            } else {
                $arrRange = \Contao\StringUtil::deserialize($dc->activeRecord->repeatEach);
                if (isset($arrRange['unit'], $arrRange['value'])) {
                    $arg = $arrRange['value'] * $dc->activeRecord->recurrences;
                    $unit = $arrRange['unit'];
                    $strtotime = '+ ' . $arg . ' ' . $unit;
                    $arrSet['repeatEnd'] = \strtotime($strtotime, $arrSet['endTime']);
                }
            }
        }
        $this->Database->prepare("UPDATE tl_calendar_events %s WHERE id=?")->set($arrSet)->execute($dc->id);
    }
    /**
     * Check for modified calendar feeds and update the XML files if necessary
     */
    public function generateFeed()
    {
        /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
        $objSession = \Contao\System::getContainer()->get('session');
        $session = $objSession->get('calendar_feed_updater');
        if (empty($session) || !\is_array($session)) {
            return;
        }
        $request = \Contao\System::getContainer()->get('request_stack')->getCurrentRequest();
        if ($request) {
            $origScope = $request->attributes->get('_scope');
            $request->attributes->set('_scope', 'frontend');
        }
        $this->import('Contao\\Calendar', 'Calendar');
        foreach ($session as $id) {
            $this->Calendar->generateFeedsByCalendar($id);
        }
        $this->import('Contao\\Automator', 'Automator');
        $this->Automator->generateSitemap();
        if ($request) {
            $request->attributes->set('_scope', $origScope);
        }
        $objSession->set('calendar_feed_updater', \null);
    }
    /**
     * Schedule a calendar feed update
     *
     * This method is triggered when a single event or multiple events are
     * modified (edit/editAll), moved (cut/cutAll) or deleted (delete/deleteAll).
     * Since duplicated events are unpublished by default, it is not necessary
     * to schedule updates on copyAll as well.
     *
     * @param Contao\DataContainer $dc
     */
    public function scheduleUpdate(\Contao\DataContainer $dc)
    {
        // Return if there is no ID
        if (!$dc->activeRecord || !$dc->activeRecord->pid || \Contao\Input::get('act') == 'copy') {
            return;
        }
        /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
        $objSession = \Contao\System::getContainer()->get('session');
        // Store the ID in the session
        $session = $objSession->get('calendar_feed_updater');
        $session[] = $dc->activeRecord->pid;
        $objSession->set('calendar_feed_updater', \array_unique($session));
    }
    /**
     * Return the "toggle visibility" button
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     * @param string $attributes
     *
     * @return string
     */
    public function toggleIcon($row, $href, $label, $title, $icon, $attributes)
    {
        if (\Contao\Input::get('tid')) {
            $this->toggleVisibility(\Contao\Input::get('tid'), \Contao\Input::get('state') == 1, \func_num_args() <= 12 ? \null : \func_get_arg(12));
            $this->redirect($this->getReferer());
        }
        // Check permissions AFTER checking the tid, so hacking attempts are logged
        if (!$this->User->hasAccess('tl_calendar_events::published', 'alexf')) {
            return '';
        }
        $href .= '&amp;tid=' . $row['id'] . '&amp;state=' . ($row['published'] ? '' : 1);
        if (!$row['published']) {
            $icon = 'invisible.svg';
        }
        return '<a href="' . $this->addToUrl($href) . '" title="' . \Contao\StringUtil::specialchars($title) . '"' . $attributes . '>' . \Contao\Image::getHtml($icon, $label, 'data-state="' . ($row['published'] ? 1 : 0) . '"') . '</a> ';
    }
    /**
     * Disable/enable a user group
     *
     * @param integer              $intId
     * @param boolean              $blnVisible
     * @param Contao\DataContainer $dc
     *
     * @throws Contao\CoreBundle\Exception\AccessDeniedException
     */
    public function toggleVisibility($intId, $blnVisible, \Contao\DataContainer $dc = \null)
    {
        // Set the ID and action
        \Contao\Input::setGet('id', $intId);
        \Contao\Input::setGet('act', 'toggle');
        if ($dc) {
            $dc->id = $intId;
            // see #8043
        }
        // Trigger the onload_callback
        if (\is_array($GLOBALS['TL_DCA']['tl_calendar_events']['config']['onload_callback'])) {
            foreach ($GLOBALS['TL_DCA']['tl_calendar_events']['config']['onload_callback'] as $callback) {
                if (\is_array($callback)) {
                    $this->import($callback[0]);
                    $this->{$callback[0]}->{$callback[1]}($dc);
                } elseif (\is_callable($callback)) {
                    $callback($dc);
                }
            }
        }
        // Check the field access
        if (!$this->User->hasAccess('tl_calendar_events::published', 'alexf')) {
            throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to publish/unpublish event ID ' . $intId . '.');
        }
        $objRow = $this->Database->prepare("SELECT * FROM tl_calendar_events WHERE id=?")->limit(1)->execute($intId);
        if ($objRow->numRows < 1) {
            throw new \Contao\CoreBundle\Exception\AccessDeniedException('Invalid event ID ' . $intId . '.');
        }
        // Set the current record
        if ($dc) {
            $dc->activeRecord = $objRow;
        }
        $objVersions = new \Contao\Versions('tl_calendar_events', $intId);
        $objVersions->initialize();
        // Trigger the save_callback
        if (\is_array($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['published']['save_callback'])) {
            foreach ($GLOBALS['TL_DCA']['tl_calendar_events']['fields']['published']['save_callback'] as $callback) {
                if (\is_array($callback)) {
                    $this->import($callback[0]);
                    $blnVisible = $this->{$callback[0]}->{$callback[1]}($blnVisible, $dc);
                } elseif (\is_callable($callback)) {
                    $blnVisible = $callback($blnVisible, $dc);
                }
            }
        }
        $time = \time();
        // Update the database
        $this->Database->prepare("UPDATE tl_calendar_events SET tstamp={$time}, published='" . ($blnVisible ? '1' : '') . "' WHERE id=?")->execute($intId);
        if ($dc) {
            $dc->activeRecord->tstamp = $time;
            $dc->activeRecord->published = $blnVisible ? '1' : '';
        }
        // Trigger the onsubmit_callback
        if (\is_array($GLOBALS['TL_DCA']['tl_calendar_events']['config']['onsubmit_callback'])) {
            foreach ($GLOBALS['TL_DCA']['tl_calendar_events']['config']['onsubmit_callback'] as $callback) {
                if (\is_array($callback)) {
                    $this->import($callback[0]);
                    $this->{$callback[0]}->{$callback[1]}($dc);
                } elseif (\is_callable($callback)) {
                    $callback($dc);
                }
            }
        }
        $objVersions->create();
        // The onsubmit_callback has triggered scheduleUpdate(), so run generateFeed() now
        $this->generateFeed();
        if ($dc) {
            $dc->invalidateCacheTags();
        }
    }
}
}

namespace {
if (@\class_exists("tl_calendar_events")) {
    /**
     * Change palettes
     */
    $disabledObjects = \deserialize($GLOBALS['TL_CONFIG']['disabledC4gMapObjects'], \true);
    if (!\in_array('tl_calendar_events', $disabledObjects)) {
        // Palettes
        try {
            \Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addLegend('c4g_maps_legend', 'expert_legend', \Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_BEFORE)->addField(array('c4g_loc_geox', 'c4g_loc_geoy', 'c4g_loc_label', 'c4g_locstyle'), 'c4g_maps_legend', \Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)->applyToPalette('default', 'tl_calendar_events');
        } catch (\Exception $e) {
            //test after error report
            //error >= Contao 4.4.14
            //do nothing
        }
        $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['c4g_loc_geox'] = ['label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['c4g_loc_geox'], 'exclude' => \true, 'inputType' => 'c4g_text', 'eval' => ['mandatory' => \false, 'maxlength' => 20, 'tl_class' => 'w50 wizard'], 'save_callback' => [['tl_calendar_events_c4g_maps', 'setLocLon']], 'wizard' => [['\\con4gis\\MapsBundle\\Resources\\contao\\classes\\GeoPicker', 'getPickerLink']], 'sql' => "varchar(20) NOT NULL default ''"];
        $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['c4g_loc_geoy'] = ['label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['c4g_loc_geoy'], 'exclude' => \true, 'inputType' => 'c4g_text', 'eval' => ['mandatory' => \false, 'maxlength' => 20, 'tl_class' => 'w50 wizard'], 'save_callback' => [['tl_calendar_events_c4g_maps', 'setLocLat']], 'wizard' => [['\\con4gis\\MapsBundle\\Resources\\contao\\classes\\GeoPicker', 'getPickerLink']], 'sql' => "varchar(20) NOT NULL default ''"];
        $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['c4g_loc_label'] = ['label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['c4g_loc_label'], 'exclude' => \true, 'inputType' => 'text', 'eval' => ['tl_class' => 'clr'], 'sql' => "varchar(100) NOT NULL default ''"];
        $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['c4g_locstyle'] = ['label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['c4g_locstyle'], 'exclude' => \true, 'inputType' => 'select', 'options_callback' => ['tl_calendar_events_c4g_maps', 'getLocStyles'], 'eval' => array('chosen' => \true, 'includeBlankOption' => \true), 'sql' => "int(10) unsigned NOT NULL default '0'"];
    }
}
/**
 * Class tl_calendar_events_c4g_maps
 */
class tl_calendar_events_c4g_maps extends \Backend
{
    /**
     * Return all Location Styles as array
     * @param object
     * @return array
     */
    public function getLocStyles(\DataContainer $dc)
    {
        $locStyles = $this->Database->prepare("SELECT id,name FROM tl_c4g_map_locstyles ORDER BY name")->execute();
        $return[''] = '-';
        while ($locStyles->next()) {
            $return[$locStyles->id] = $locStyles->name;
        }
        return $return;
    }
    /**
     * Validate Longitude
     */
    public function setLocLon($varValue, \DataContainer $dc)
    {
        if ($varValue != 0) {
            if (!\con4gis\MapsBundle\Resources\contao\classes\Utils::validateLon($varValue)) {
                throw new \Exception($GLOBALS['TL_LANG']['c4g_maps']['geox_invalid']);
            }
        }
        return $varValue;
    }
    /**
     * Validate Latitude
     */
    public function setLocLat($varValue, \DataContainer $dc)
    {
        if ($varValue != 0) {
            if (!\con4gis\MapsBundle\Resources\contao\classes\Utils::validateLat($varValue)) {
                throw new \Exception($GLOBALS['TL_LANG']['c4g_maps']['geoy_invalid']);
            }
        }
        return $varValue;
    }
}
}
