<?php

namespace {
$GLOBALS['TL_DCA']['tl_page'] = array(
    // Config
    'config' => array('dataContainer' => \Contao\DC_Table::class, 'ctable' => array('tl_article'), 'enableVersioning' => \true, 'markAsCopy' => 'title', 'onload_callback' => array(array('tl_page', 'checkPermission'), array('tl_page', 'addBreadcrumb'), array('tl_page', 'setRootType'), array('tl_page', 'showFallbackWarning'), array('tl_page', 'makeRedirectPageMandatory')), 'oncut_callback' => array(array('tl_page', 'scheduleUpdate')), 'ondelete_callback' => array(array('tl_page', 'scheduleUpdate')), 'onsubmit_callback' => array(array('tl_page', 'scheduleUpdate')), 'oninvalidate_cache_tags_callback' => array(array('tl_page', 'addSitemapCacheInvalidationTag')), 'sql' => array('keys' => array('id' => 'primary', 'alias' => 'index', 'type,dns' => 'index', 'pid,published,type,start,stop' => 'index'))),
    // List
    'list' => array('sorting' => array('mode' => \Contao\DataContainer::MODE_TREE, 'rootPaste' => \true, 'showRootTrails' => \true, 'icon' => 'pagemounts.svg', 'paste_button_callback' => array('tl_page', 'pastePage'), 'panelLayout' => 'filter;search'), 'label' => array('fields' => array('title'), 'format' => '%s', 'label_callback' => array('tl_page', 'addIcon')), 'global_operations' => array('toggleNodes' => array('href' => 'ptg=all', 'class' => 'header_toggle', 'showOnSelect' => \true), 'all' => array('href' => 'act=select', 'class' => 'header_edit_all', 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"')), 'operations' => array('edit' => array('href' => 'act=edit', 'icon' => 'edit.svg', 'button_callback' => array('tl_page', 'editPage')), 'copy' => array('href' => 'act=paste&amp;mode=copy', 'icon' => 'copy.svg', 'attributes' => 'onclick="Backend.getScrollOffset()"', 'button_callback' => array('tl_page', 'copyPage')), 'copyChilds' => array('href' => 'act=paste&amp;mode=copy&amp;childs=1', 'icon' => 'copychilds.svg', 'attributes' => 'onclick="Backend.getScrollOffset()"', 'button_callback' => array('tl_page', 'copyPageWithSubpages')), 'cut' => array('href' => 'act=paste&amp;mode=cut', 'icon' => 'cut.svg', 'attributes' => 'onclick="Backend.getScrollOffset()"', 'button_callback' => array('tl_page', 'cutPage')), 'delete' => array('href' => 'act=delete', 'icon' => 'delete.svg', 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? \null) . '\'))return false;Backend.getScrollOffset()"', 'button_callback' => array('tl_page', 'deletePage')), 'toggle' => array('href' => 'act=toggle&amp;field=published', 'icon' => 'visible.svg', 'button_callback' => array('tl_page', 'toggleIcon')), 'show' => array('href' => 'act=show', 'icon' => 'show.svg'), 'articles' => array('href' => 'do=article', 'icon' => 'article.svg'))),
    // Select
    'select' => array('buttons_callback' => array(array('tl_page', 'addAliasButton'))),
    // Palettes
    'palettes' => array('__selector__' => array('type', 'fallback', 'autoforward', 'protected', 'includeLayout', 'includeCache', 'includeChmod', 'enforceTwoFactor'), 'default' => '{title_legend},title,type', 'regular' => '{title_legend},title,type;{routing_legend},alias,requireItem,routePath,routePriority,routeConflicts;{meta_legend},pageTitle,robots,description,serpPreview;{canonical_legend:hide},canonicalLink,canonicalKeepParams;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,noSearch,guests;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'forward' => '{title_legend},title,type;{routing_legend},alias,routePath,routePriority,routeConflicts;{meta_legend},pageTitle,robots;{redirect_legend},jumpTo,redirect,alwaysForward;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,guests;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'redirect' => '{title_legend},title,type;{routing_legend},alias,routePath,routePriority,routeConflicts;{meta_legend},pageTitle,robots;{redirect_legend},redirect,url,target;{protected_legend:hide},protected;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide,guests;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'root' => '{title_legend},title,type;{routing_legend},alias;{meta_legend},pageTitle;{url_legend},dns,useSSL,urlPrefix,urlSuffix,validAliasCharacters,useFolderUrl;{language_legend},language,fallback,disableLanguageRedirect;{website_legend:hide},maintenanceMode;{global_legend:hide},mailerTransport,enableCanonical,adminEmail,dateFormat,timeFormat,datimFormat,staticFiles,staticPlugins;{protected_legend:hide},protected;{layout_legend},includeLayout;{twoFactor_legend:hide},enforceTwoFactor;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{publish_legend},published,start,stop', 'rootfallback' => '{title_legend},title,type;{routing_legend},alias;{meta_legend},pageTitle;{url_legend},dns,useSSL,urlPrefix,urlSuffix,validAliasCharacters,useFolderUrl;{language_legend},language,fallback,disableLanguageRedirect;{website_legend:hide},favicon,robotsTxt,maintenanceMode;{global_legend:hide},mailerTransport,enableCanonical,adminEmail,dateFormat,timeFormat,datimFormat,staticFiles,staticPlugins;{protected_legend:hide},protected;{layout_legend},includeLayout;{twoFactor_legend:hide},enforceTwoFactor;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{publish_legend},published,start,stop', 'logout' => '{title_legend},title,type;{routing_legend},alias,routePath,routePriority,routeConflicts;{forward_legend},jumpTo,redirectBack;{protected_legend:hide},protected;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass,sitemap,hide;{tabnav_legend:hide},tabindex,accesskey;{publish_legend},published,start,stop', 'error_401' => '{title_legend},title,type;{meta_legend},pageTitle,robots,description;{forward_legend},autoforward;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass;{publish_legend},published,start,stop', 'error_403' => '{title_legend},title,type;{meta_legend},pageTitle,robots,description;{forward_legend},autoforward;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass;{publish_legend},published,start,stop', 'error_404' => '{title_legend},title,type;{meta_legend},pageTitle,robots,description;{forward_legend},autoforward;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass;{publish_legend},published,start,stop', 'error_503' => '{title_legend},title,type;{meta_legend},pageTitle,robots,description;{forward_legend},autoforward;{layout_legend:hide},includeLayout;{cache_legend:hide},includeCache;{chmod_legend:hide},includeChmod;{expert_legend:hide},cssClass;{publish_legend},published,start,stop'),
    // Subpalettes
    'subpalettes' => array('autoforward' => 'jumpTo', 'protected' => 'groups', 'includeLayout' => 'layout,subpageLayout', 'includeCache' => 'clientCache,cache,alwaysLoadFromCache', 'includeChmod' => 'cuser,cgroup,chmod', 'enforceTwoFactor' => 'twoFactorJumpTo'),
    // Fields
    'fields' => array('id' => array('sql' => "int(10) unsigned NOT NULL auto_increment"), 'pid' => array('sql' => "int(10) unsigned NOT NULL default 0"), 'sorting' => array('sql' => "int(10) unsigned NOT NULL default 0"), 'tstamp' => array('sql' => "int(10) unsigned NOT NULL default 0"), 'title' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('mandatory' => \true, 'maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'type' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'select', 'eval' => array('helpwizard' => \true, 'submitOnChange' => \true, 'tl_class' => 'w50'), 'reference' => &$GLOBALS['TL_LANG']['PTY'], 'sql' => "varchar(64) NOT NULL default 'regular'"), 'alias' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'folderalias', 'doNotCopy' => \true, 'maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) BINARY NOT NULL default ''"), 'requireItem' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'routePath' => array('exclude' => \true), 'routePriority' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('tl_class' => 'w50'), 'sql' => "int(10) NOT NULL default 0"), 'routeConflicts' => array('exclude' => \true), 'pageTitle' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'language' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('mandatory' => \true, 'maxlength' => 64, 'nospace' => \true, 'decodeEntities' => \true, 'doNotCopy' => \true, 'tl_class' => 'w50'), 'sql' => "varchar(64) NOT NULL default ''", 'save_callback' => array(static function ($value) {
        // Make sure there is at least a basic language
        if (!\preg_match('/^[a-z]{2,}/i', $value)) {
            throw new \RuntimeException($GLOBALS['TL_LANG']['ERR']['language']);
        }
        return \Contao\CoreBundle\Util\LocaleUtil::canonicalize($value);
    })), 'robots' => array('exclude' => \true, 'search' => \true, 'inputType' => 'select', 'options' => array('index,follow', 'index,nofollow', 'noindex,follow', 'noindex,nofollow'), 'eval' => array('tl_class' => 'w50'), 'sql' => "varchar(32) 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_page', 'getSerpUrl'), 'title_tag_callback' => array('tl_page', 'getTitleTag'), 'titleFields' => array('pageTitle', 'title'), 'tl_class' => 'clr'), 'sql' => \null), 'redirect' => array('exclude' => \true, 'inputType' => 'select', 'options' => array('permanent', 'temporary'), 'eval' => array('tl_class' => 'w50'), 'reference' => &$GLOBALS['TL_LANG']['tl_page'], 'sql' => "varchar(32) NOT NULL default 'permanent'"), 'alwaysForward' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'jumpTo' => array(
        'exclude' => \true,
        'inputType' => 'pageTree',
        'foreignKey' => 'tl_page.title',
        'eval' => array('fieldType' => 'radio'),
        // do not set mandatory (see #5453)
        'save_callback' => array(array('tl_page', 'checkJumpTo')),
        'sql' => "int(10) unsigned NOT NULL default 0",
        'relation' => array('type' => 'hasOne', 'load' => 'lazy'),
    ), 'redirectBack' => array('exclude' => \true, 'inputType' => 'checkbox', 'sql' => "char(1) NOT NULL default ''"), 'url' => array('label' => &$GLOBALS['TL_LANG']['MSC']['url'], 'exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('mandatory' => \true, 'rgxp' => 'url', 'decodeEntities' => \true, 'maxlength' => 2048, 'dcaPicker' => \true, 'tl_class' => 'w50 clr'), 'sql' => "varchar(2048) 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 ''"), 'dns' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'url', 'decodeEntities' => \true, 'maxlength' => 255, 'tl_class' => 'w50'), 'load_callback' => array(array('tl_page', 'loadDns')), 'save_callback' => array(array('tl_page', 'checkDns')), 'sql' => "varchar(255) NOT NULL default ''"), 'staticFiles' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'url', 'trailingSlash' => \false, 'tl_class' => 'w50'), 'save_callback' => array(array('tl_page', 'checkStaticUrl')), 'sql' => "varchar(255) NOT NULL default ''"), 'staticPlugins' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'url', 'trailingSlash' => \false, 'tl_class' => 'w50'), 'save_callback' => array(array('tl_page', 'checkStaticUrl')), 'sql' => "varchar(255) NOT NULL default ''"), 'fallback' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('doNotCopy' => \true, 'submitOnChange' => \true, 'tl_class' => 'w50 clr'), 'save_callback' => array(array('tl_page', 'checkFallback')), 'sql' => "char(1) NOT NULL default ''"), 'disableLanguageRedirect' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('doNotCopy' => \true, 'tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"), 'favicon' => array('exclude' => \true, 'inputType' => 'fileTree', 'eval' => array('filesOnly' => \true, 'fieldType' => 'radio', 'extensions' => 'ico,svg,png'), 'sql' => "binary(16) NULL"), 'robotsTxt' => array('exclude' => \true, 'inputType' => 'textarea', 'eval' => array('doNotCopy' => \true, 'decodeEntities' => \true), 'sql' => "text NULL"), 'maintenanceMode' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"), 'mailerTransport' => array('exclude' => \true, 'inputType' => 'select', 'eval' => array('tl_class' => 'w50', 'includeBlankOption' => \true), 'sql' => "varchar(255) NOT NULL default ''"), 'enableCanonical' => array('exclude' => \true, 'inputType' => 'checkbox', 'default' => \true, 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'canonicalLink' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'url', 'decodeEntities' => \true, 'maxlength' => 2048, 'dcaPicker' => \true, 'tl_class' => 'w50'), 'sql' => "varchar(2048) NOT NULL default ''"), 'canonicalKeepParams' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('decodeEntities' => \true, 'maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'adminEmail' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'rgxp' => 'friendly', 'decodeEntities' => \true, 'placeholder' => \Contao\Config::get('adminEmail'), 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'dateFormat' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('helpwizard' => \true, 'decodeEntities' => \true, 'placeholder' => \Contao\Config::get('dateFormat'), 'tl_class' => 'w50'), 'explanation' => 'dateFormat', 'sql' => "varchar(32) NOT NULL default ''"), 'timeFormat' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('decodeEntities' => \true, 'placeholder' => \Contao\Config::get('timeFormat'), 'tl_class' => 'w50'), 'sql' => "varchar(32) NOT NULL default ''"), 'datimFormat' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('decodeEntities' => \true, 'placeholder' => \Contao\Config::get('datimFormat'), 'tl_class' => 'w50'), 'sql' => "varchar(32) NOT NULL default ''"), 'validAliasCharacters' => array('exclude' => \true, 'inputType' => 'select', 'options_callback' => static function () {
        return \Contao\System::getContainer()->get('contao.slug.valid_characters')->getOptions();
    }, 'eval' => array('includeBlankOption' => \true, 'decodeEntities' => \true, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'useFolderUrl' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'urlPrefix' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'folderalias', 'doNotCopy' => \true, 'maxlength' => 128, 'tl_class' => 'w50'), 'sql' => "varchar(128) BINARY NOT NULL default ''"), 'urlSuffix' => array('exclude' => \true, 'inputType' => 'text', 'eval' => array('nospace' => 'true', 'maxlength' => 16, 'tl_class' => 'w50'), 'sql' => "varchar(16) NOT NULL default ''"), 'useSSL' => array('exclude' => \true, 'inputType' => 'select', 'options' => array('' => 'http://', '1' => 'https://'), 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default '1'"), 'autoforward' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'protected' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'groups' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'checkbox', 'foreignKey' => 'tl_member_group.name', 'eval' => array('mandatory' => \true, 'multiple' => \true), 'sql' => "blob NULL", 'relation' => array('type' => 'hasMany', 'load' => 'lazy')), 'includeLayout' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'layout' => array('exclude' => \true, 'search' => \true, 'inputType' => 'select', 'foreignKey' => 'tl_layout.name', 'eval' => array('chosen' => \true, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'subpageLayout' => array('exclude' => \true, 'search' => \true, 'inputType' => 'select', 'foreignKey' => 'tl_layout.name', 'eval' => array('chosen' => \true, 'tl_class' => 'w50', 'includeBlankOption' => \true, 'blankOptionLabel' => &$GLOBALS['TL_LANG']['tl_page']['layout_inherit']), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'includeCache' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'cache' => array('exclude' => \true, 'search' => \true, 'inputType' => 'select', 'options' => array(0, 5, 15, 30, 60, 300, 900, 1800, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000, 7776000, 15552000, 31536000), 'reference' => &$GLOBALS['TL_LANG']['CACHE'], 'eval' => array('tl_class' => 'w50 clr'), 'sql' => "int(10) unsigned NOT NULL default 0"), 'alwaysLoadFromCache' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50 m12'), 'sql' => "char(1) NOT NULL default ''"), 'clientCache' => array('exclude' => \true, 'search' => \true, 'inputType' => 'select', 'options' => array(0, 5, 15, 30, 60, 300, 900, 1800, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000), 'reference' => &$GLOBALS['TL_LANG']['CACHE'], 'eval' => array('tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default 0"), 'includeChmod' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'cuser' => array('default' => (int) \Contao\Config::get('defaultUser'), 'search' => \true, 'exclude' => \true, 'inputType' => 'select', 'foreignKey' => 'tl_user.name', 'eval' => array('mandatory' => \true, 'chosen' => \true, 'includeBlankOption' => \true, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'cgroup' => array('default' => (int) \Contao\Config::get('defaultGroup'), 'search' => \true, 'exclude' => \true, 'inputType' => 'select', 'foreignKey' => 'tl_user_group.name', 'eval' => array('mandatory' => \true, 'chosen' => \true, 'includeBlankOption' => \true, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'chmod' => array('default' => \Contao\Config::get('defaultChmod'), 'exclude' => \true, 'inputType' => 'chmod', 'eval' => array('tl_class' => 'clr'), 'sql' => "varchar(255) NOT NULL default ''"), 'noSearch' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"), 'cssClass' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('maxlength' => 64, 'tl_class' => 'w50'), 'sql' => "varchar(64) NOT NULL default ''"), 'sitemap' => array('exclude' => \true, 'inputType' => 'select', 'options' => array('map_default', 'map_always', 'map_never'), 'eval' => array('maxlength' => 32, 'tl_class' => 'w50'), 'reference' => &$GLOBALS['TL_LANG']['tl_page'], 'sql' => "varchar(32) NOT NULL default ''"), 'hide' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"), 'guests' => array('exclude' => \true, 'filter' => \true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"), 'tabindex' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'natural', 'nospace' => \true, 'tl_class' => 'w50'), 'sql' => "smallint(5) unsigned NOT NULL default 0"), 'accesskey' => array('exclude' => \true, 'search' => \true, 'inputType' => 'text', 'eval' => array('rgxp' => 'alnum', 'maxlength' => 1, 'tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"), 'published' => array('exclude' => \true, 'toggle' => \true, 'filter' => \true, '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 ''"), 'enforceTwoFactor' => array('exclude' => \true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => \true), 'sql' => "char(1) NOT NULL default ''"), 'twoFactorJumpTo' => array('exclude' => \true, 'inputType' => 'pageTree', 'foreignKey' => 'tl_page.title', 'eval' => array('fieldType' => 'radio', 'mandatory' => \true), 'save_callback' => array(array('tl_page', 'checkJumpTo')), 'sql' => "int(10) unsigned NOT NULL default 0", 'relation' => array('type' => 'hasOne', 'load' => 'lazy'))),
);
// Disable the articles link in the modal window
if (\Contao\Input::get('popup')) {
    unset($GLOBALS['TL_DCA']['tl_page']['list']['operations']['articles']);
}
/**
 * Provide miscellaneous methods that are used by the data configuration array.
 */
class tl_page extends \Contao\Backend
{
    /**
     * Import the back end user object
     */
    public function __construct()
    {
        parent::__construct();
        $this->import(\Contao\BackendUser::class, 'User');
    }
    /**
     * Check permissions to edit table tl_page
     *
     * @throws AccessDeniedException
     */
    public function checkPermission()
    {
        if ($this->User->isAdmin) {
            return;
        }
        $objSession = \Contao\System::getContainer()->get('session');
        $session = $objSession->all();
        // Set the default page user and group
        $GLOBALS['TL_DCA']['tl_page']['fields']['cuser']['default'] = (int) \Contao\Config::get('defaultUser') ?: $this->User->id;
        $GLOBALS['TL_DCA']['tl_page']['fields']['cgroup']['default'] = (int) \Contao\Config::get('defaultGroup') ?: (int) ($this->User->groups[0] ?? 0);
        // Restrict the page tree
        if (empty($this->User->pagemounts) || !\is_array($this->User->pagemounts)) {
            $root = array(0);
        } else {
            $root = $this->User->pagemounts;
        }
        $GLOBALS['TL_DCA']['tl_page']['list']['sorting']['rootPaste'] = \false;
        $GLOBALS['TL_DCA']['tl_page']['list']['sorting']['root'] = $root;
        $security = \Contao\System::getContainer()->get('security.helper');
        // Set allowed page IDs (edit multiple)
        if (\is_array($session['CURRENT']['IDS'] ?? \null)) {
            $edit_all = array();
            $delete_all = array();
            foreach ($session['CURRENT']['IDS'] as $id) {
                $objPage = $this->Database->prepare("SELECT id, pid, type, includeChmod, chmod, cuser, cgroup FROM tl_page WHERE id=?")->limit(1)->execute($id);
                if ($objPage->numRows < 1 || !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $objPage->type)) {
                    continue;
                }
                $row = $objPage->row();
                if ($security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE, $row)) {
                    $edit_all[] = $id;
                }
                // Mounted pages cannot be deleted
                if ($security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_DELETE_PAGE, $row) && !$this->User->hasAccess($id, 'pagemounts')) {
                    $delete_all[] = $id;
                }
            }
            $session['CURRENT']['IDS'] = \Contao\Input::get('act') == 'deleteAll' ? $delete_all : $edit_all;
        }
        // Set allowed clipboard IDs
        if (\is_array($session['CLIPBOARD']['tl_page']['id'] ?? \null)) {
            $clipboard = array();
            foreach ($session['CLIPBOARD']['tl_page']['id'] as $id) {
                $objPage = $this->Database->prepare("SELECT id, pid, type, includeChmod, chmod, cuser, cgroup FROM tl_page WHERE id=?")->limit(1)->execute($id);
                if ($objPage->numRows < 1 || !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $objPage->type)) {
                    continue;
                }
                if ($security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $objPage->row())) {
                    $clipboard[] = $id;
                }
            }
            $session['CLIPBOARD']['tl_page']['id'] = $clipboard;
        }
        // Overwrite session
        $objSession->replace($session);
        // Check permissions to save and create new
        if (\Contao\Input::get('act') == 'edit') {
            $objPage = $this->Database->prepare("SELECT * FROM tl_page WHERE id=(SELECT pid FROM tl_page WHERE id=?)")->limit(1)->execute(\Contao\Input::get('id'));
            if ($objPage->numRows && !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $objPage->row())) {
                $GLOBALS['TL_DCA']['tl_page']['config']['closed'] = \true;
            }
        }
        // Check current action
        if (\Contao\Input::get('act') && \Contao\Input::get('act') != 'paste') {
            $permission = \null;
            $cid = \CURRENT_ID ?: \Contao\Input::get('id');
            $ids = $cid ? array($cid) : array();
            // Set permission
            switch (\Contao\Input::get('act')) {
                case 'edit':
                case 'toggle':
                    $permission = \Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE;
                    break;
                case 'move':
                    $permission = \Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY;
                    $ids[] = \Contao\Input::get('sid');
                    break;
                case 'create':
                case 'copy':
                case 'copyAll':
                case 'cut':
                case 'cutAll':
                    $permission = \Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY;
                    // Check the parent page in "paste into" mode
                    if (\Contao\Input::get('mode') == 2) {
                        $ids[] = \Contao\Input::get('pid');
                    } else {
                        $objPage = $this->Database->prepare("SELECT pid FROM tl_page WHERE id=?")->limit(1)->execute(\Contao\Input::get('pid'));
                        $ids[] = $objPage->pid;
                    }
                    break;
                case 'delete':
                    $permission = \Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_DELETE_PAGE;
                    break;
            }
            // Check user permissions
            $pagemounts = array();
            // Get all allowed pages for the current user
            foreach ($this->User->pagemounts as $root) {
                if (\Contao\Input::get('act') != 'delete') {
                    $pagemounts[] = array($root);
                }
                $pagemounts[] = $this->Database->getChildRecords($root, 'tl_page');
            }
            if (!empty($pagemounts)) {
                $pagemounts = \array_merge(...$pagemounts);
            }
            $pagemounts = \array_unique($pagemounts);
            // Do not allow pasting after pages on the root level (pagemounts)
            if (\Contao\Input::get('mode') == 1 && (\Contao\Input::get('act') == 'cut' || \Contao\Input::get('act') == 'cutAll') && \in_array(\Contao\Input::get('pid'), $this->eliminateNestedPages($this->User->pagemounts))) {
                throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to paste page ID ' . \Contao\Input::get('id') . ' after mounted page ID ' . \Contao\Input::get('pid') . ' (root level).');
            }
            $error = \false;
            // Check each page
            foreach ($ids as $i => $id) {
                if (!\in_array($id, $pagemounts)) {
                    \Contao\System::getContainer()->get('monolog.logger.contao.error')->error('Page ID ' . $id . ' was not mounted');
                    $error = \true;
                    break;
                }
                // Get the page object
                $objPage = \Contao\PageModel::findById($id);
                if ($objPage === \null) {
                    continue;
                }
                // Check whether the current user is allowed to access the current page
                if (\Contao\Input::get('act') != 'show' && ($permission === \null || !$security->isGranted($permission, $objPage->row()))) {
                    $error = \true;
                    break;
                }
                // Check the type of the first page (not the following parent pages)
                // In "edit multiple" mode, $ids contains only the parent ID, therefore check $id != $_GET['pid'] (see #5620)
                if ($i == 0 && $id != \Contao\Input::get('pid') && \Contao\Input::get('act') != 'create' && \Contao\Input::get('act') != 'show' && !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $objPage->type)) {
                    \Contao\System::getContainer()->get('monolog.logger.contao.error')->error('Not enough permissions to  ' . \Contao\Input::get('act') . ' ' . $objPage->type . ' pages');
                    $error = \true;
                    break;
                }
            }
            // Redirect if there is an error
            if ($error) {
                throw new \Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . \Contao\Input::get('act') . ' page ID ' . $cid . ' or paste after/into page ID ' . \Contao\Input::get('pid') . '.');
            }
        }
    }
    /**
     * Add the breadcrumb menu
     */
    public function addBreadcrumb()
    {
        \Contao\Backend::addPagesBreadcrumb();
    }
    /**
     * Make new top-level pages root pages
     *
     * @param DataContainer $dc
     */
    public function setRootType(\Contao\DataContainer $dc)
    {
        if (\Contao\Input::get('act') != 'create') {
            return;
        }
        // Insert into
        if (\Contao\Input::get('pid') == 0) {
            $GLOBALS['TL_DCA']['tl_page']['fields']['type']['default'] = 'root';
        } elseif (\Contao\Input::get('mode') == 1) {
            $objPage = $this->Database->prepare("SELECT * FROM " . $dc->table . " WHERE id=?")->limit(1)->execute(\Contao\Input::get('pid'));
            if ($objPage->pid == 0) {
                $GLOBALS['TL_DCA']['tl_page']['fields']['type']['default'] = 'root';
            }
        }
    }
    /**
     * Make sure that top-level pages are root pages
     *
     * @param mixed         $varValue
     * @param DataContainer $dc
     *
     * @return mixed
     *
     * @throws Exception
     *
     * @deprecated
     */
    public function checkRootType($varValue, \Contao\DataContainer $dc)
    {
        \trigger_deprecation('contao/core-bundle', '4.10', 'Using "tl_page::checkRootType()" has been deprecated and will no longer work in Contao 5.0.');
        if ($varValue != 'root' && $dc->activeRecord->pid == 0) {
            throw new \Exception($GLOBALS['TL_LANG']['ERR']['topLevelRoot']);
        }
        return $varValue;
    }
    /**
     * Return the SERP URL
     *
     * @param PageModel $page
     *
     * @return string
     */
    public function getSerpUrl(\Contao\PageModel $page)
    {
        return $page->getAbsoluteUrl();
    }
    /**
     * Return the title tag from the associated page layout
     *
     * @param PageModel $page
     *
     * @return string
     */
    public function getTitleTag(\Contao\PageModel $page)
    {
        $page->loadDetails();
        /** @var 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('%', '%%', \Contao\System::getContainer()->get('contao.insert_tag.parser')->replaceInline($strVal));
        }, \explode('{{page::pageTitle}}', $layout->titleTag ?: '{{page::pageTitle}} - {{page::rootPageTitle}}', 2)));
        $GLOBALS['objPage'] = $origObjPage;
        return $title;
    }
    /**
     * Show a warning if there is no language fallback page
     */
    public function showFallbackWarning()
    {
        if (\Contao\Input::get('act')) {
            return;
        }
        $messages = new \Contao\Messages();
        \Contao\Message::addRaw($messages->languageFallback());
    }
    /**
     * Make the redirect page mandatory if the page is a logout page
     *
     * @param DataContainer $dc
     *
     * @throws Exception
     */
    public function makeRedirectPageMandatory(\Contao\DataContainer $dc)
    {
        $objPage = $this->Database->prepare("SELECT * FROM " . $dc->table . " WHERE id=?")->limit(1)->execute($dc->id);
        if ($objPage->numRows && $objPage->type == 'logout') {
            $GLOBALS['TL_DCA']['tl_page']['fields']['jumpTo']['eval']['mandatory'] = \true;
        }
    }
    /**
     * Schedule a sitemap update
     *
     * This method is triggered when a single page or multiple pages are
     * modified (edit/editAll), moved (cut/cutAll) or deleted
     * (delete/deleteAll). Since duplicated pages are unpublished by default,
     * it is not necessary to schedule updates on copyAll as well.
     *
     * @param DataContainer $dc
     */
    public function scheduleUpdate(\Contao\DataContainer $dc)
    {
        // Return if there is no ID
        if (!$dc->activeRecord || !$dc->activeRecord->id || \Contao\Input::get('act') == 'copy') {
            return;
        }
        $objSession = \Contao\System::getContainer()->get('session');
        // Store the ID in the session
        $session = $objSession->get('sitemap_updater');
        $session[] = \Contao\PageModel::findWithDetails($dc->activeRecord->id)->rootId;
        $objSession->set('sitemap_updater', \array_unique($session));
    }
    /**
     * Auto-generate a page alias if it has not been set yet
     *
     * @param mixed         $varValue
     * @param DataContainer $dc
     *
     * @return string
     *
     * @throws Exception
     */
    public function generateAlias($varValue, \Contao\DataContainer $dc)
    {
        \trigger_deprecation('contao/core-bundle', '4.10', 'Using "tl_page::generateAlias()" has been deprecated and will no longer work in Contao 5.0.');
        return \Contao\System::getContainer()->get('contao.listener.data_container.page_url')->generateAlias($varValue, $dc);
    }
    /**
     * Automatically create an article in the main column of a new page
     *
     * @param DataContainer $dc
     *
     * @deprecated
     */
    public function generateArticle(\Contao\DataContainer $dc)
    {
        \trigger_deprecation('contao/core-bundle', '4.10', 'Using "tl_page::generateArticle()" has been deprecated and will no longer work in Contao 5.0.');
        \Contao\System::getContainer()->get('contao.listener.data_container.content_composition')->generateArticleForPage($dc);
    }
    /**
     * Purge the search index if a page is being deleted
     *
     * @param DataContainer $dc
     *
     * @deprecated
     */
    public function purgeSearchIndex(\Contao\DataContainer $dc)
    {
        \trigger_deprecation('contao/core-bundle', '4.10', 'Using "tl_page::purgeSearchIndex()" has been deprecated and will no longer work in Contao 5.0.');
        \Contao\System::getContainer()->get('contao.listener.data_container.page_search')->onDelete($dc);
    }
    /**
     * Check the sitemap alias
     *
     * @param mixed         $varValue
     * @param DataContainer $dc
     *
     * @return mixed
     *
     * @throws Exception
     */
    public function checkFeedAlias($varValue, \Contao\DataContainer $dc)
    {
        // No change or empty value
        if (!$varValue || $varValue == $dc->value) {
            return $varValue;
        }
        $varValue = \Contao\StringUtil::standardize($varValue);
        // see #5096
        $this->import(\Contao\Automator::class, 'Automator');
        $arrFeeds = $this->Automator->purgeXmlFiles(\true);
        // Alias exists
        if (\in_array($varValue, $arrFeeds)) {
            throw new \Exception(\sprintf($GLOBALS['TL_LANG']['ERR']['aliasExists'], $varValue));
        }
        return $varValue;
    }
    /**
     * Prevent circular references
     *
     * @param mixed         $varValue
     * @param DataContainer $dc
     *
     * @return mixed
     *
     * @throws Exception
     */
    public function checkJumpTo($varValue, \Contao\DataContainer $dc)
    {
        if ($varValue == $dc->id) {
            throw new \Exception($GLOBALS['TL_LANG']['ERR']['circularReference']);
        }
        return $varValue;
    }
    /**
     * Load the DNS settings
     *
     * @param string $varValue
     *
     * @return string
     */
    public function loadDns($varValue)
    {
        return \Contao\Idna::decode($varValue);
    }
    /**
     * Check the DNS settings
     *
     * @param string $varValue
     *
     * @return string
     */
    public function checkDns($varValue)
    {
        if (!$varValue) {
            return '';
        }
        // The first part will match IPv6 addresses in square brackets. The
        // second part will match domain names and IPv4 addresses.
        \preg_match('#^(?:[a-z]+://)?(\\[[0-9a-f:]+]|[\\pN\\pL._-]*)#ui', $varValue, $matches);
        return \Contao\Idna::encode($matches[1]);
    }
    /**
     * Make sure there is only one fallback per domain (thanks to Andreas Schempp)
     *
     * @param mixed         $varValue
     * @param DataContainer $dc
     *
     * @return mixed
     *
     * @throws Exception
     */
    public function checkFallback($varValue, \Contao\DataContainer $dc)
    {
        if (!$varValue) {
            return '';
        }
        $objPage = $this->Database->prepare("SELECT id FROM tl_page WHERE type='root' AND fallback=1 AND dns=? AND id!=?")->execute($dc->activeRecord->dns, $dc->activeRecord->id);
        if ($objPage->numRows) {
            throw new \Exception($GLOBALS['TL_LANG']['ERR']['multipleFallback']);
        }
        return $varValue;
    }
    /**
     * Check a static URL
     *
     * @param mixed $varValue
     *
     * @return mixed
     */
    public function checkStaticUrl($varValue)
    {
        if ($varValue) {
            $varValue = \preg_replace('@https?://@', '', $varValue);
        }
        return $varValue;
    }
    /**
     * Returns all allowed page types as array
     *
     * @param DataContainer $dc
     *
     * @return array
     *
     * @deprecated
     */
    public function getPageTypes(\Contao\DataContainer $dc)
    {
        \trigger_deprecation('contao/core-bundle', '4.10', 'Using "tl_page::getPageTypes()" has been deprecated and will no longer work in Contao 5.0.');
        return \Contao\System::getContainer()->get('contao.listener.data_container.page_type_options')($dc);
    }
    /**
     * Add an image to each page in the tree
     *
     * @param array         $row
     * @param string        $label
     * @param DataContainer $dc
     * @param string        $imageAttribute
     * @param boolean       $blnReturnImage
     * @param boolean       $blnProtected
     * @param boolean       $isVisibleRootTrailPage
     *
     * @return string
     */
    public function addIcon($row, $label, ?\Contao\DataContainer $dc = \null, $imageAttribute = '', $blnReturnImage = \false, $blnProtected = \false, $isVisibleRootTrailPage = \false)
    {
        return \Contao\Backend::addPageIcon($row, $label, $dc, $imageAttribute, $blnReturnImage, $blnProtected, $isVisibleRootTrailPage);
    }
    /**
     * Return the edit page button
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     * @param string $attributes
     *
     * @return string
     */
    public function editPage($row, $href, $label, $title, $icon, $attributes)
    {
        $security = \Contao\System::getContainer()->get('security.helper');
        return $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $row['type']) && $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE, $row) ? '<a href="' . $this->addToUrl($href . '&amp;id=' . $row['id']) . '" title="' . \Contao\StringUtil::specialchars($title) . '"' . $attributes . '>' . \Contao\Image::getHtml($icon, $label) . '</a> ' : \Contao\Image::getHtml(\preg_replace('/\\.svg$/i', '_.svg', $icon)) . ' ';
    }
    /**
     * Return the copy page button
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     * @param string $attributes
     * @param string $table
     *
     * @return string
     */
    public function copyPage($row, $href, $label, $title, $icon, $attributes, $table)
    {
        if ($GLOBALS['TL_DCA'][$table]['config']['closed'] ?? \null) {
            return '';
        }
        $security = \Contao\System::getContainer()->get('security.helper');
        return $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $row['type']) && $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $row) ? '<a href="' . $this->addToUrl($href . '&amp;id=' . $row['id']) . '" title="' . \Contao\StringUtil::specialchars($title) . '"' . $attributes . '>' . \Contao\Image::getHtml($icon, $label) . '</a> ' : \Contao\Image::getHtml(\preg_replace('/\\.svg$/i', '_.svg', $icon)) . ' ';
    }
    /**
     * Return the copy page with subpages button
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     * @param string $attributes
     * @param string $table
     *
     * @return string
     */
    public function copyPageWithSubpages($row, $href, $label, $title, $icon, $attributes, $table)
    {
        if ($GLOBALS['TL_DCA'][$table]['config']['closed'] ?? \null) {
            return '';
        }
        $security = \Contao\System::getContainer()->get('security.helper');
        $objSubpages = \Contao\PageModel::findByPid($row['id']);
        return $objSubpages !== \null && $objSubpages->count() > 0 && $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $row['type']) && $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $row) ? '<a href="' . $this->addToUrl($href . '&amp;id=' . $row['id']) . '" title="' . \Contao\StringUtil::specialchars($title) . '"' . $attributes . '>' . \Contao\Image::getHtml($icon, $label) . '</a> ' : \Contao\Image::getHtml(\preg_replace('/\\.svg$/i', '_.svg', $icon)) . ' ';
    }
    /**
     * Return the cut page button
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     * @param string $attributes
     *
     * @return string
     */
    public function cutPage($row, $href, $label, $title, $icon, $attributes)
    {
        $security = \Contao\System::getContainer()->get('security.helper');
        return $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $row['type']) && $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $row) ? '<a href="' . $this->addToUrl($href . '&amp;id=' . $row['id']) . '" title="' . \Contao\StringUtil::specialchars($title) . '"' . $attributes . '>' . \Contao\Image::getHtml($icon, $label) . '</a> ' : \Contao\Image::getHtml(\preg_replace('/\\.svg$/i', '_.svg', $icon)) . ' ';
    }
    /**
     * Return the paste page button
     *
     * @param DataContainer $dc
     * @param array         $row
     * @param string        $table
     * @param boolean       $cr
     * @param array         $arrClipboard
     *
     * @return string
     */
    public function pastePage(\Contao\DataContainer $dc, $row, $table, $cr, $arrClipboard = \null)
    {
        $security = \Contao\System::getContainer()->get('security.helper');
        $disablePA = \false;
        $disablePI = \false;
        // Disable all buttons if there is a circular reference
        if ($arrClipboard !== \false && ($arrClipboard['mode'] == 'cut' && ($cr == 1 || $arrClipboard['id'] == $row['id']) || $arrClipboard['mode'] == 'cutAll' && ($cr == 1 || \in_array($row['id'], $arrClipboard['id'])))) {
            $disablePA = \true;
            $disablePI = \true;
        }
        // Prevent adding non-root pages on top-level
        if (empty($row['pid']) && \Contao\Input::get('mode') != 'create') {
            $objPage = $this->Database->prepare("SELECT * FROM " . $table . " WHERE id=?")->limit(1)->execute(\Contao\Input::get('id'));
            if ($objPage->type != 'root') {
                $disablePA = \true;
                if ($row['id'] == 0) {
                    $disablePI = \true;
                }
            }
        }
        // Check permissions if the user is not an administrator
        if (!$this->User->isAdmin) {
            // Disable "paste into" button if there is no permission 2 (move) or 1 (create) for the current page
            if (!$disablePI) {
                if (!$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $row) || \Contao\Input::get('mode') == 'create' && !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE, $row)) {
                    $disablePI = \true;
                }
            }
            // Disable "paste after" button if there is no permission 2 (move) or 1 (create) for the parent page
            if (!$disablePA) {
                /** @var PageModel $objModel */
                $objModel = \Contao\Model::getClassFromTable($table);
                if (($objPage = $objModel::findById($row['pid'])) !== \null && (!$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE_HIERARCHY, $objPage->row()) || \Contao\Input::get('mode') == 'create' && !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE, $objPage->row()))) {
                    $disablePA = \true;
                }
            }
            // Disable "paste after" button if the parent page is a root page and the user is not an administrator
            if (!$disablePA && ($row['pid'] < 1 || \in_array($row['id'], $dc->rootIds))) {
                $disablePA = \true;
            }
        }
        $return = '';
        // Return the buttons
        $imagePasteAfter = \Contao\Image::getHtml('pasteafter.svg', \sprintf($GLOBALS['TL_LANG'][$table]['pasteafter'][1], $row['id']));
        $imagePasteInto = \Contao\Image::getHtml('pasteinto.svg', \sprintf($GLOBALS['TL_LANG'][$table]['pasteinto'][1], $row['id']));
        if ($row['id'] > 0) {
            $return = $disablePA ? \Contao\Image::getHtml('pasteafter_.svg') . ' ' : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=1&amp;pid=' . $row['id'] . (!\is_array($arrClipboard['id']) ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . \Contao\StringUtil::specialchars(\sprintf($GLOBALS['TL_LANG'][$table]['pasteafter'][1], $row['id'])) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a> ';
        }
        return $return . ($disablePI ? \Contao\Image::getHtml('pasteinto_.svg') . ' ' : '<a href="' . $this->addToUrl('act=' . $arrClipboard['mode'] . '&amp;mode=2&amp;pid=' . $row['id'] . (!\is_array($arrClipboard['id']) ? '&amp;id=' . $arrClipboard['id'] : '')) . '" title="' . \Contao\StringUtil::specialchars(\sprintf($GLOBALS['TL_LANG'][$table]['pasteinto'][$row['id'] > 0 ? 1 : 0], $row['id'])) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a> ');
    }
    /**
     * Return the delete page button
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     * @param string $attributes
     *
     * @return string
     */
    public function deletePage($row, $href, $label, $title, $icon, $attributes)
    {
        $root = \func_get_arg(7);
        $security = \Contao\System::getContainer()->get('security.helper');
        return $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $row['type']) && $security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_DELETE_PAGE, $row) && ($this->User->isAdmin || !\in_array($row['id'], $root)) ? '<a href="' . $this->addToUrl($href . '&amp;id=' . $row['id']) . '" title="' . \Contao\StringUtil::specialchars($title) . '"' . $attributes . '>' . \Contao\Image::getHtml($icon, $label) . '</a> ' : \Contao\Image::getHtml(\preg_replace('/\\.svg$/i', '_.svg', $icon)) . ' ';
    }
    /**
     * Generate an "edit articles" button and return it as string
     *
     * @param array  $row
     * @param string $href
     * @param string $label
     * @param string $title
     * @param string $icon
     *
     * @return string
     *
     * @deprecated
     */
    public function editArticles($row, $href, $label, $title, $icon)
    {
        \trigger_deprecation('contao/core-bundle', '4.10', 'Using "tl_page::editArticles()" has been deprecated and will no longer work in Contao 5.0.');
        return \Contao\System::getContainer()->get('contao.listener.data_container.content_composition')->renderPageArticlesOperation($row, $href, $label, $title, $icon);
    }
    /**
     * Automatically generate the folder URL aliases
     *
     * @param array         $arrButtons
     * @param DataContainer $dc
     *
     * @return array
     */
    public function addAliasButton($arrButtons, \Contao\DataContainer $dc)
    {
        if (!\Contao\System::getContainer()->get('security.helper')->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_FIELD_OF_TABLE, 'tl_page::alias')) {
            return $arrButtons;
        }
        // Generate the aliases
        if (isset($_POST['alias']) && \Contao\Input::post('FORM_SUBMIT') == 'tl_select') {
            $router = \Contao\System::getContainer()->get('router');
            $objSession = \Contao\System::getContainer()->get('session');
            $session = $objSession->all();
            $ids = $session['CURRENT']['IDS'] ?? array();
            foreach ($ids as $id) {
                $objPage = \Contao\PageModel::findWithDetails($id);
                if ($objPage === \null) {
                    continue;
                }
                $dc->id = $id;
                $dc->activeRecord = $objPage;
                $strAlias = '';
                // Generate new alias through save callbacks
                if (\is_array($GLOBALS['TL_DCA'][$dc->table]['fields']['alias']['save_callback'] ?? \null)) {
                    foreach ($GLOBALS['TL_DCA'][$dc->table]['fields']['alias']['save_callback'] as $callback) {
                        if (\is_array($callback)) {
                            $this->import($callback[0]);
                            $strAlias = $this->{$callback[0]}->{$callback[1]}($strAlias, $dc);
                        } elseif (\is_callable($callback)) {
                            $strAlias = $callback($strAlias, $dc);
                        }
                    }
                }
                // The alias has not changed
                if ($strAlias == $objPage->alias) {
                    continue;
                }
                // Initialize the version manager
                $objVersions = new \Contao\Versions('tl_page', $id);
                $objVersions->setEditUrl($router->generate('contao_backend', array('do' => 'page', 'act' => 'edit', 'id' => $id, 'rt' => '1')));
                $objVersions->initialize();
                // Store the new alias
                $this->Database->prepare("UPDATE tl_page SET alias=? WHERE id=?")->execute($strAlias, $id);
                // Create a new version
                $objVersions->create();
                // Update the record stored in the page registry (see #6542)
                \Contao\PageModel::findByPk($id)->alias = $strAlias;
            }
            $this->redirect($this->getReferer());
        }
        // Add the button
        $arrButtons['alias'] = '<button type="submit" name="alias" id="alias" class="tl_submit" accesskey="a">' . $GLOBALS['TL_LANG']['MSC']['aliasSelected'] . '</button> ';
        return $arrButtons;
    }
    /**
     * 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)
    {
        $security = \Contao\System::getContainer()->get('security.helper');
        // Check permissions AFTER checking the tid, so hacking attempts are logged
        if (!$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_FIELD_OF_TABLE, 'tl_page::published')) {
            return '';
        }
        $href .= '&amp;id=' . $row['id'];
        if (!$row['published']) {
            $icon = 'invisible.svg';
        }
        if (!$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_ACCESS_PAGE_TYPE, $row['type']) || ($objPage = \Contao\PageModel::findById($row['id'])) === \null || !$security->isGranted(\Contao\CoreBundle\Security\ContaoCorePermissions::USER_CAN_EDIT_PAGE, $objPage->row())) {
            return \Contao\Image::getHtml($icon) . ' ';
        }
        return '<a href="' . $this->addToUrl($href) . '" title="' . \Contao\StringUtil::specialchars($title) . '" onclick="Backend.getScrollOffset();return AjaxRequest.toggleField(this,true)">' . \Contao\Image::getHtml($icon, $label, 'data-icon="' . \Contao\Image::getPath('visible.svg') . '" data-icon-disabled="' . \Contao\Image::getPath('invisible.svg') . '" data-state="' . ($row['published'] ? 1 : 0) . '"') . '</a> ';
    }
    /**
     * @param DataContainer $dc
     *
     * @return array
     */
    public function addSitemapCacheInvalidationTag($dc, array $tags)
    {
        $pageModel = \Contao\PageModel::findWithDetails($dc->id);
        if ($pageModel === \null) {
            return $tags;
        }
        return \array_merge($tags, array('contao.sitemap.' . $pageModel->rootId));
    }
}
}

namespace {
\Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addLegend('klaro_legend', 'layout_legend', \Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_AFTER)->addField('includeKlaro', 'klaro_legend', \Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)->applyToPalette('root', 'tl_page')->applyToPalette('rootfallback', 'tl_page');
$GLOBALS['TL_DCA']['tl_page']['palettes']['__selector__'][] = 'includeKlaro';
$GLOBALS['TL_DCA']['tl_page']['subpalettes']['includeKlaro'] = 'klaroConfig,klaroExclude';
$GLOBALS['TL_DCA']['tl_page']['fields']['includeKlaro'] = ['exclude' => \true, 'inputType' => 'checkbox', 'eval' => ['submitOnChange' => \true], 'sql' => "char(1) NOT NULL default ''"];
$GLOBALS['TL_DCA']['tl_page']['fields']['klaroConfig'] = ['exclude' => \true, 'search' => \true, 'inputType' => 'select', 'foreignKey' => 'tl_klaro_config.title', 'eval' => ['chosen' => \true, 'tl_class' => 'w50', 'includeBlankOption' => \true], 'sql' => 'int(10) unsigned NOT NULL default 0', 'relation' => ['type' => 'hasOne', 'load' => 'lazy']];
$GLOBALS['TL_DCA']['tl_page']['fields']['klaroExclude'] = ['exclude' => \true, 'inputType' => 'pageTree', 'foreignKey' => 'tl_page.title', 'eval' => ['fieldType' => 'checkbox', 'tl_class' => 'clr', 'multiple' => \true], 'sql' => 'blob NULL'];
}
