Error
Class "SeminarCatalog\Core\TwigComponents\Base\TwigComponent" not found Error thrown with message "Class "SeminarCatalog\Core\TwigComponents\Base\TwigComponent" not found" Stacktrace: #11 Error in /srv/www/bgphoenics2.invorbereitung.de/ilias/Core/TwigComponents/Classes/Components/Favourites.php:10 #10 include in /srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/composer/ClassLoader.php:576 #9 Composer\Autoload\{closure} in /srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/composer/ClassLoader.php:427 #8 Composer\Autoload\ClassLoader:loadClass in [internal]:0 #7 class_exists in /srv/www/bgphoenics2.invorbereitung.de/ilias/Core/Object/Classes/Manager/ObjectManager.php:36 #6 SeminarCatalog\Core\Object\Manager\ObjectManager:has in /srv/www/bgphoenics2.invorbereitung.de/ilias/classes/Service/Wrapper/TwigTemplate.php:71 #5 SeminarCatalog\Service\Wrapper\TwigTemplate:parseSemiTags in /srv/www/bgphoenics2.invorbereitung.de/ilias/classes/Service/Wrapper/TwigTemplate.php:50 #4 SeminarCatalog\Service\Wrapper\TwigTemplate:render in /srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/twig/twig/src/TemplateWrapper.php:51 #3 Twig\TemplateWrapper:render in /srv/www/bgphoenics2.invorbereitung.de/ilias/Core/Cart/Classes/Controller/CartController.php:172 #2 SeminarCatalog\Core\Cart\Controller\CartController:showCartAction in /srv/www/bgphoenics2.invorbereitung.de/ilias/classes/Controller/BaseController.php:255 #1 SeminarCatalog\Controller\BaseController:handleCmd in /srv/www/bgphoenics2.invorbereitung.de/ilias/classes/SeminarCatalogKernel.php:91 #0 SeminarCatalogKernel:handleRequest in /srv/www/bgphoenics2.invorbereitung.de/ilias/index.php:23
Stack frames (12)
11
Error
/Core/TwigComponents/Classes/Components/Favourites.php:10
10
include
/vendor/composer/ClassLoader.php:576
9
Composer\Autoload\{closure}
/vendor/composer/ClassLoader.php:427
8
Composer\Autoload\ClassLoader loadClass
[internal]:0
7
class_exists
/Core/Object/Classes/Manager/ObjectManager.php:36
6
SeminarCatalog\Core\Object\Manager\ObjectManager has
/classes/Service/Wrapper/TwigTemplate.php:71
5
SeminarCatalog\Service\Wrapper\TwigTemplate parseSemiTags
/classes/Service/Wrapper/TwigTemplate.php:50
4
SeminarCatalog\Service\Wrapper\TwigTemplate render
/vendor/twig/twig/src/TemplateWrapper.php:51
3
Twig\TemplateWrapper render
/Core/Cart/Classes/Controller/CartController.php:172
2
SeminarCatalog\Core\Cart\Controller\CartController showCartAction
/classes/Controller/BaseController.php:255
1
SeminarCatalog\Controller\BaseController handleCmd
/classes/SeminarCatalogKernel.php:91
0
SeminarCatalogKernel handleRequest
/index.php:23
/srv/www/bgphoenics2.invorbereitung.de/ilias/Core/TwigComponents/Classes/Components/Favourites.php
<?php
 
namespace SeminarCatalog\Core\TwigComponents\Components;
 
use SeminarCatalog\Core\Object\Manager\ObjectManager;
use SeminarCatalog\Core\Seminar\Model\Seminar;
use SeminarCatalog\Core\TwigComponents\Base\TwigComponent;
use SeminarCatalog\Core\User\Model\CurrentUser;
 
class Favourites extends TwigComponent
{
    protected Seminar $seminar;
 
 
    public function getContext(): array
    {
        $favouriteList = ObjectManager::get(CurrentUser::class)->getFavouritesIdList();
        return [
            'id' => uniqid(),
            'seminar' => $this->seminar,
            'favouriteList' => $favouriteList,
        ];
    }
}
 
Arguments
  1. "Class "SeminarCatalog\Core\TwigComponents\Base\TwigComponent" not found"
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/composer/ClassLoader.php
 
    /**
     * @return void
     */
    private static function initializeIncludeClosure()
    {
        if (self::$includeFile !== null) {
            return;
        }
 
        /**
         * Scope isolated include.
         *
         * Prevents access to $this/self from included files.
         *
         * @param  string $file
         * @return void
         */
        self::$includeFile = \Closure::bind(static function($file) {
            include $file;
        }, null, null);
    }
}
 
/srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/composer/ClassLoader.php
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));
 
        if (null !== $this->vendorDir) {
            unset(self::$registeredLoaders[$this->vendorDir]);
        }
    }
 
    /**
     * Loads the given class or interface.
     *
     * @param  string    $class The name of the class
     * @return true|null True if loaded, null otherwise
     */
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            $includeFile = self::$includeFile;
            $includeFile($file);
 
            return true;
        }
 
        return null;
    }
 
    /**
     * Finds the path to the file where the class is defined.
     *
     * @param string $class The name of the class
     *
     * @return string|false The path if found, false otherwise
     */
    public function findFile($class)
    {
        // class map lookup
        if (isset($this->classMap[$class])) {
            return $this->classMap[$class];
        }
Arguments
  1. "/srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/composer/../../Core/TwigComponents/Classes/Components/Favourites.php"
    
[internal]
Arguments
  1. "SeminarCatalog\Core\TwigComponents\Components\Favourites"
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/Core/Object/Classes/Manager/ObjectManager.php
 */
class ObjectManager implements ObjectManagerInterface
{
 
 
    /**
     * @var array<class-string,Callable> $factories
     */
    protected static array $factories = [];
 
    /**
     * @var array<class-string,ObjectFactoryInterface> $factories
     */
    protected static array $factoriesInstance = [];
 
    protected static bool $testMode = false;
 
    public static function has(string $className) : bool {
        $className = self::mapClass($className);
        return class_exists($className) || interface_exists($className);
    }
 
    /**
     * @template Type
     * @param class-string<Type> $className
     * @param list<mixed> $constructorArguments
     * @return Type
     */
    public static function get(string $className, array $constructorArguments = []) {
        $className = self::mapClass($className);
 
        $instance = self::getInstanceVariable($className, $constructorArguments);
 
        if (method_exists($instance, '__inject')) {
            self::injectDependencies($instance);
        }
 
        return $instance;
    }
 
Arguments
  1. "SeminarCatalog\Core\TwigComponents\Components\Favourites"
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/classes/Service/Wrapper/TwigTemplate.php
 
    public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true): string
    {
        $template = $this->base->renderBlock($name, $context, $blocks, $useBlocks);
        return $this->parseSemiTags($template);
    }
 
    private function parseSemiTags(string $template): string
    {
        // modifier 's' makes, that the dot also matches newlines
        if (preg_match_all('/<xsem:(\S+)[^>]*>(.*?)<\/xsem:\1>/s', $template, $matches)) {
            for ($i = 0; $i < count($matches[0]); $i++) {
                $componentName = $matches[1][$i];
                $content = $matches[2][$i] ?? "";
                $completeTag = $matches[0][$i];
 
                $componentName = str_replace(':', '\\', $componentName);
 
                $class = '\SeminarCatalog\Core\TwigComponents\Components\\' . $componentName;
                if (!ObjectManager::has($class)) {
                    continue;
                }
 
                $component = ObjectManager::get($class, [ $this->twig->getGlobals()['controller'] ]);
                if (!$component instanceof TwigComponent) {
                    continue;
                }
 
                $arguments = $this->parseArguments($completeTag);
                $frontendArguments = [];
                foreach ($arguments as $argument) {
                    $key = $argument['key'];
                    $value = $argument['value'];
                    if (is_string($value) && str_starts_with($value, '_context_pass_')) {
                        $contextKey = substr($value, 14);
                        $value = $this->twig->getPassContext()[$contextKey];
                    }
                    $property = UtilityService::kebabToCamelCase($key);
                    if (property_exists($component, $property)) {
                        $setter = 'set' . ucfirst($property);
Arguments
  1. "SeminarCatalog\Core\TwigComponents\Components\Favourites"
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/classes/Service/Wrapper/TwigTemplate.php
 
    public function getDebugInfo(): array
    {
        return $this->base->getDebugInfo();
    }
 
    public function getSourceContext(): Source
    {
        return $this->base->getSourceContext();
    }
 
    protected function doDisplay(array $context, array $blocks = []): Traversable|array
    {
        return $this->base->doDisplay($context, $blocks);
    }
 
    public function render(array $context = []): string
    {
        $template = $this->base->render($context);
        return $this->parseSemiTags($template);
    }
 
    public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true): string
    {
        $template = $this->base->renderBlock($name, $context, $blocks, $useBlocks);
        return $this->parseSemiTags($template);
    }
 
    private function parseSemiTags(string $template): string
    {
        // modifier 's' makes, that the dot also matches newlines
        if (preg_match_all('/<xsem:(\S+)[^>]*>(.*?)<\/xsem:\1>/s', $template, $matches)) {
            for ($i = 0; $i < count($matches[0]); $i++) {
                $componentName = $matches[1][$i];
                $content = $matches[2][$i] ?? "";
                $completeTag = $matches[0][$i];
 
                $componentName = str_replace(':', '\\', $componentName);
 
                $class = '\SeminarCatalog\Core\TwigComponents\Components\\' . $componentName;
Arguments
  1. """
    <style>\n
        .tab-notice-danger {\n
            color: var(--il-danger-color);\n
        }\n
    \n
        .tab-notice-warning {\n
            color: var(--warning-color);\n
        }\n
        div.il_HeaderInner {\n
            /*Removes ilias header, since we render an semi header*/\n
            display: none !important;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler div.xsem-menu-dropdown-menu {\n
            padding: 10px;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler div.xsem-menu-dropdown-menu {\n
            display: none;\n
        }\n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler.show div.xsem-menu-dropdown-menu,\n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler.open div.xsem-menu-dropdown-menu {\n
            display: flex;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler.active a {\n
            background-color: #fff;\n
            color: var(--main-color) !important;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler.active a span.caret {\n
            color: var(--main-color) !important;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler div.xsem-menu-dropdown-menu .dropdown-item {\n
            color: var(--darkblue) !important;\n
            display: block;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler div.xsem-menu-dropdown-menu .dropdown-item:not(:first-child) {\n
            margin-top: 10px;\n
        }\n
    \n
        #xsem.backend #xsemTopArea #xsemTopWrapper #xsemTabs .nav.nav-tabs > li#xsemMenuDropdownToggler div.xsem-menu-dropdown-menu .dropdown-item.active {\n
            font-weight: bold;\n
        }\n
    </style>\n
        <svg width="20px" height="20px" viewBox="0 -0.5 33 33" display="none">\n
            <g id="Vivid.JS" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="scale(1)">\n
                <g id="Vivid-Icons" transform="translate(-903.000000, -411.000000)" fill="currentColor">\n
                    <g id="Icons" transform="translate(37.000000, 169.000000)">\n
                        <g id="star" transform="translate(858.000000, 234.000000)">\n
                            <g transform="translate(7.000000, 8.000000)" id="Shape">\n
                                <polygon\n
                                        points="27.865 31.83 17.615 26.209 7.462 32.009 9.553 20.362 0.99 12.335 12.532 10.758 17.394 0 22.436 10.672 34 12.047 25.574 20.22">\n
                                </polygon>\n
                            </g>\n
                        </g>\n
                    </g>\n
                </g>\n
            </g>\n
        </svg>\n
    <div id="xsemTopArea" class="">\n
                    <nav aria-label="Brotkrumen" class="breadcrumb_wrapper xsem-breadcrumbs" data-a="showCart"\n
             data-c="SeminarCatalog__Core__Cart__Controller__CartController">\n
          <div class="breadcrumb">\n
                                                            <span class="crumb">\n
                                                                    <a href="/warenkorb.html">Warenkorb</a>\n
                        </span>\n
                                  </div>\n
        </nav>\n
      \n
            <div id="xsemTopWrapper" class="xsemHeaderNoTabs">\n
              <div id="xsemHeadline">\n
            <div class="headline">\n
                          <h1>\n
                                                    Warenkorb\n
                                  \n
                                                                            </h1>\n
                                                                                                      \n
              \n
                                </div>\n
            <div class="headerContent">\n
                      </div>\n
          </div>\n
        \n
                                </div>\n
    \n
                  </div>\n
    \n
                <div id="xsemAlerts">\n
                \n
    \n
    \n
    \n
            </div>\n
        \n
    \n
    \n
    <div class="modal fade" id="xsem_header_object_modified_confirm_modal" tabindex="-1" role="dialog">\n
        <div class="modal-dialog modal-lg" role="document">\n
            <div class="modal-content">\n
                <div class="modal-header">\n
                    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>\n
                    <h4 class="modal-title">\n
                        Der Datensatz wurde geändert.\n
                    </h4>\n
                </div>\n
                <div class="modal-body">\n
                    <p>Dieser Datensatz wurde zwischenzeitlich zuletzt von <span id="xsem_header_object_modified_confirm_modal_user">N/A</span> vor <span id="xsem_header_object_modified_confirm_modal_time">N/A</span> geändert.</p>\n
                    <p>Es könnten wichtige Änderungen verloren gehen, möchten Sie trotzdem Ihre Änderungen übernehmen?</p>\n
                </div>\n
                <div class="modal-footer">\n
                    <button type="button" class="btn btn-default" data-dismiss="modal">Abbrechen</button>\n
                    <a type="button" class="btn btn-primary" id="xsem_header_object_modified_confirm_modal_btn">Bestätigen</a>\n
                </div>\n
            </div>\n
        </div>\n
    </div>\n
    \n
    <script type="text/javascript">\n
    \n
        const tabContainer = document.getElementById('xsemTabs');\n
        let realDropdownMenuBtnWidth = false;\n
        const dropdownMenuBtnWidthThreshold = 3;\n
        // Predicted width of dropdown btn, only for initialization, will be replaced later by automatic detection.\n
        let dropdownMenuBtnWidth = 99 + dropdownMenuBtnWidthThreshold;\n
        const dropdownMenuBtnLabel = "Mehr...";\n
        let previousWidth = 0;\n
        if (tabContainer) {\n
            previousWidth = tabContainer.getBoundingClientRect().width;\n
        }\n
    \n
        /**\n
         * Ensures that all tabs in the navigation bar are in one row only. Overflowing tabs are moved to a dropdown menu.\n
         *\n
         * Dynamically adjusts the contents of the dropdown based on the width of the navigation bar.\n
         * @author Justin Jansen <jjansen@databay.de>\n
         * @param init\n
         */\n
        function handleTabDropdown(init = false) {\n
            const availableWidth = tabContainer.getBoundingClientRect().width;\n
            // Important because ilias triggers several size changes due to the grid system\n
            if (!init && availableWidth === previousWidth) {\n
                return;\n
            }\n
            previousWidth = availableWidth;\n
    \n
            const tabList = tabContainer.querySelector('#xsemTabs .nav-tabs');\n
            const tabs = Array.from(tabList.children);\n
            let tabsToMove = [];\n
            tabsToMove = getTabsOverceedWidth(tabs, availableWidth, tabsToMove);\n
            const dropdownMenu = document.createElement('div');\n
            dropdownMenu.classList.add('xsem-menu-dropdown-menu', 'dropdown-menu');\n
    \n
            // Remove tabs from tab list and add them to dropdown menu\n
            let isDropTabActive = false;\n
            tabsToMove.forEach(tab => {\n
                const tabLink = tab.querySelector('a');\n
                if (tabLink) {\n
                    const dropdownTab = tabLink.cloneNode(true);\n
                    dropdownTab.classList.add('dropdown-item');\n
                    if (tab.classList.contains('active')) {\n
                        isDropTabActive = true;\n
                        dropdownTab.classList.add('active');\n
                    }\n
                    dropdownMenu.appendChild(dropdownTab);\n
                }\n
            });\n
    \n
            const dropdownBtn = document.getElementById('xsemMenuDropdownToggler');\n
            if (dropdownBtn) {\n
                dropdownBtn.remove()\n
            }\n
    \n
            if (tabsToMove.length > 0) {\n
                const dropdownBtn = document.createElement('li');\n
                dropdownBtn.classList.add('dropdown', 'pull-right');\n
                if (isDropTabActive) {\n
                    dropdownBtn.classList.add('active');\n
                }\n
                dropdownBtn.id = 'xsemMenuDropdownToggler';\n
                dropdownBtn.innerHTML = `\n
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">` + dropdownMenuBtnLabel + ` <span class="caret"></span></a>\n
            `;\n
                dropdownBtn.appendChild(dropdownMenu);\n
                tabList.appendChild(dropdownBtn);\n
                if (!realDropdownMenuBtnWidth) {\n
                    getWidthOfDropdownBtn()\n
                }\n
            }\n
        }\n
    \n
        /**\n
         * Returns all tabs that exceed the specified available width.\n
         *\n
         * Uses a recursive solution to add only tabs that actually go over the available width without a dropdown button.\n
         * @author Justin Jansen <jjansen@databay.de>\n
         * @param tabs\n
         * @param availableWidth\n
         * @param overflowingTabs\n
         * @param initMove\n
         * @returns {*}\n
         */\n
        function getTabsOverceedWidth(tabs, availableWidth, overflowingTabs, initMove = false) {\n
            let totalWidth = 0;\n
    \n
            for (const tab of tabs) {\n
                totalWidth += getFullWidthOfTab(tab);\n
    \n
                if (tab.classList.contains('dropdown') || tab.classList.contains('xsem-menu-back-btn')) {\n
                    continue; // Skip certain tabs\n
                }\n
    \n
                if (totalWidth >= availableWidth) {\n
                    if (!initMove) {\n
                        return getTabsOverceedWidth(tabs, availableWidth - dropdownMenuBtnWidth, overflowingTabs, true);\n
                    }\n
                    overflowingTabs.push(tab);\n
                    tab.style.display = 'none';\n
                } else {\n
                    tab.style.display = 'inherit';\n
                    const index = overflowingTabs.indexOf(tab);\n
                    if (index > -1) {\n
                        overflowingTabs.splice(index, 1);\n
                    }\n
                }\n
            }\n
    \n
            return overflowingTabs;\n
        }\n
    \n
        /**\n
         * Fetches the complete width of the dropdown menu button, if any, and uses it for further calculations.\n
         *\n
         * An accurate solution if the button has a different size than originally intended (e.g. 90px) due to overriding styling.\n
         * The size is needed to give the dropdown menu button always enough space in the same row of the navigation bar and when the tabs have to disappear.\n
         * @author Justin Jansen <jjansen@databay.de>\n
         * @returns {number}\n
         */\n
        function getWidthOfDropdownBtn() {\n
            const dropdownBtn = document.getElementById('xsemMenuDropdownToggler');\n
    \n
            if (dropdownBtn) {\n
                realDropdownMenuBtnWidth = true;\n
                dropdownMenuBtnWidth = getFullWidthOfTab(dropdownBtn) + dropdownMenuBtnWidthThreshold;\n
            }\n
        }\n
    \n
        /**\n
         * Returns the complete width of the given element with margin, padding, border and offsetWidth included.\n
         * @author Justin Jansen <jjansen@databay.de>\n
         * @param element\n
         * @returns {number}\n
         */\n
        function getFullWidthOfTab(element) {\n
            const styles = getComputedStyle(element);\n
    \n
            const isHidden = styles.display === 'none';\n
    \n
            if (isHidden) {\n
                element.style.display = 'block';\n
            }\n
    \n
            // Get values of padding, border, and margin\n
            const paddingLeft = parseFloat(styles.paddingLeft);\n
            const paddingRight = parseFloat(styles.paddingRight);\n
            const borderLeft = parseFloat(styles.borderLeftWidth);\n
            const borderRight = parseFloat(styles.borderRightWidth);\n
            const marginLeft = parseFloat(styles.marginLeft);\n
            const marginRight = parseFloat(styles.marginRight);\n
    \n
            const fullWidth =\n
                element.offsetWidth +\n
                marginLeft + marginRight +\n
                paddingLeft + paddingRight +\n
                borderLeft + borderRight;\n
    \n
            if (isHidden) {\n
                element.style.display = 'none';\n
            }\n
    \n
            return fullWidth;\n
        }\n
    \n
        if (tabContainer) {\n
            $(function() {\n
                // Important because ilias triggers several size changes due to the grid system\n
                handleTabDropdown(true);\n
                // change debounce delay higher, it gets triggered to often\n
                const resizeObserver = new ResizeObserver(debounce(handleTabDropdown, 1));\n
                resizeObserver.observe(tabContainer);\n
            });\n
        }\n
    \n
            const fetchLastModifiedUrl = document.querySelector('[name="xsem-header-object-url"]')?.value;\n
    \n
    \n
    \n
    \n
    \n
        // add an event listener on every form submit and call fetchLastModified, then check with the data if the lastModifiedTime is bigger then modifiedTimestamp\n
        function submitForm(event) {\n
            setFormValidation(event.target, true);\n
            event.submitter.click();\n
        }\n
    \n
        function getCurrentLastModifiedTime() {\n
            let modifiedTimestamp = 0;\n
            const changeDate = document.querySelector('input[name="xsem-header-object-change-date"]');\n
            if (changeDate) {\n
                modifiedTimestamp = Number(changeDate.value);\n
            }\n
            return modifiedTimestamp;\n
        }\n
    \n
        let modifiedTimestamp = getCurrentLastModifiedTime();\n
        // if yes then show a confirm dialog if the user wants to leave the page\n
        if (modifiedTimestamp > 0) {\n
            document.addEventListener('submit', function (event) {\n
    \n
                const isValidated = isFormValidated(event.target);\n
                if (isValidated) {\n
                    return;\n
                }\n
    \n
                event.preventDefault();\n
                fetchLastObjectModified(fetchLastModifiedUrl)\n
                    .then(data => {\n
    \n
                        // if the fetch failed, just submit the form\n
                        if (!data.success) {\n
                            submitForm(event);\n
                            return;\n
                        }\n
                        let modifiedTimestamp = getCurrentLastModifiedTime();\n
                        const lastModifiedTime = Number(data.lastModifiedTime);\n
    \n
                        if (lastModifiedTime > modifiedTimestamp) {\n
                            initModal(event, data.lastModifiedBy, data.formattedLastModified);\n
                        } else {\n
                            submitForm(event);\n
                        }\n
                    });\n
            });\n
        }\n
    \n
        const initModal = (event, lastModifiedBy, formattedLastModified) => {\n
            const modal = document.getElementById('xsem_header_object_modified_confirm_modal');\n
            modal.querySelector('#xsem_header_object_modified_confirm_modal_user').innerText = lastModifiedBy;\n
            modal.querySelector('#xsem_header_object_modified_confirm_modal_time').innerText = formattedLastModified;\n
            const submitModalBtn = document.getElementById('xsem_header_object_modified_confirm_modal_btn');\n
            submitModalBtn.addEventListener('click', function () {\n
                submitForm(event);\n
            })\n
            $('#xsem_header_object_modified_confirm_modal').modal('show');\n
        }\n
    \n
        const setFormValidation = (form, isValidated) => {\n
            form.setAttribute('data-xsem-header-object-form-is-validate', isValidated ? '1' : '0');\n
        }\n
    \n
        const isFormValidated = (form) => {\n
            const value = form.getAttribute('data-xsem-header-object-form-is-validate',)\n
    \n
            return value === '1';\n
        }\n
    </script>\n
    \n
    \n
        \n
    \n
    \n
        <div class="cart">\n
            \n
            <form id="cartForm" action="/kasse.html" method="post" class="submitOnChange">\n
    \n
                \n
                            \n
                                                                                                            \n
    <div class="cart-row-item  mb-l " data-seminar-id="5" data-seminar-type="seminar">\n
        <div class="cart-col-item cart-event-block">\n
                    <style>\n
    \t.xsem-related-bundles-event-btn {\n
    \t\tpadding: 3px 10px !important;\n
    \t\ttext-transform: uppercase !important;\n
    \t\tfont-weight: 500 !important;\n
    \t}\n
    </style>\n
        \n
    \t<div class="card card-event card-sections card-bordered favourite-wrapper ">\n
    \t\t<xsem:Favourites seminar="_context_pass_0" favouriteList="_context_pass_1"></xsem:Favourites>\n
    \t\t<section class="card-header">\n
    \t\t\t\t\t\t<div class="row">\n
    \t\t\t\t<div class="col-xs-12 col-sm-6">\n
    \t\t\t\t\t<h5 class="card-column-headline">Kurstermin</h5>\n
    \t\t\t\t\t                10. - 14.09.2025\n
                \t\t\t\t\t\t\t\t\t\t\t<xsem:EditPencil\n
    \t\t\t\t\t\t\t\tobject="_context_pass_2"\n
    \t\t\t\t\t\t\t\tlink="/seminarverwaltung/kurse/grundseminar-fuer-sicherheitsbeauftragte-5/termine/grundseminar-fuer-sicherheitsbeauftragte-10.--14.09.2025-5/bearbeiten.html?parentObject=Seminar"\n
    \t\t\t\t\t\t\t\ttarget="editEvent"\n
    \t\t\t\t\t\t>\n
    \t\t\t\t\t\t</xsem:EditPencil>\n
    \t\t\t\t\t\t\t\t\t</div>\n
    \t\t\t\t<div class="col-xs-6 col-sm-3">\n
    \t\t\t\t\t<h5 class="card-column-headline">Kurssprache</h5>\n
    \t\t\t\t\t    <span class="nowrap">Deutsch <img src="./Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/SeminarCatalog/Resources//img/flags/de.png" alt="Kurssprache: Deutsch"></span>\t\t\t\t</div>\n
    \t\t\t\t<div class="col-xs-6 col-sm-3">\n
    \t\t\t\t\t\t\t\t\t\t\t<h5 class="card-column-headline">Kurs-Nr.</h5>\n
    \t\t\t\t\t\t1201 / SB-G\n
    \t\t\t\t\t\t\t\t\t</div>\n
    \t\t\t</div>\n
    \t\t</section>\n
    \t\t<section class="card-body">\n
    \t\t\t<div class="row">\n
    \t\t\t\t<div class="col-xs-12 col-sm-6">\n
    \t\t\t\t\t\t\t\t\t\t\t<h5 class="card-column-headline">Kurs</h5>\n
    \t\t\t\t\t\n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class="card-title">\n
    \t\t\t\t\t\t\t\n
        \t\t<a href="/kursangebot/kurs/grundseminar-fuer-sicherheitsbeauftragte-5.html"\n
    \t\t   \t\t   title="Kursdetails anzeigen"\n
    \t\t   class=""\t\t>\n
                Grundseminar für Sicherheitsbeauftragte\n
    \t\t\t\t\t</a>\n
        <xsem:EditPencil\n
    \t\tobject="_context_pass_3"\n
    \t\tlink="/seminarverwaltung/kurse/grundseminar-fuer-sicherheitsbeauftragte-5/termine/grundseminar-fuer-sicherheitsbeauftragte-10.--14.09.2025-5/bearbeiten.html?parentObject=Seminar"\n
    \t\ttarget="editEvent"\n
    >\n
    </xsem:EditPencil>\n
    \t\t\t\t\t</div>\n
    \n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n
    \n
    \t\t\t\t<div class="col-xs-6 col-sm-3">\n
    \t\t\t\t\t\t\t\t\t\t\t<h5 class="card-column-headline">Kursort</h5>\n
    \t\t\t\t\t\t<xsem:FormatEventLocation event="_context_pass_4" cityOnly></xsem:FormatEventLocation>\n
    \t\t\t\t\t\t\t\t\t</div>\n
    \n
    \t\t\t\t <div class="col-xs-6 col-sm-3 online-event-pricecontainer">\n
    \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t\t \t\t\t\t\t\t\t\t <h5 class="card-column-headline">Kursgebühr</h5>\n
    \t\t\t\t\t\t\t\t \t<div class="price-block">\n
    \t\t\t\t\t\t<p class="pb-best-price">\n
    \t\t\t\t\t\t\t<span class="pb-price">100,- EUR</span>\n
    \t\t\t\t<br><span class="pb-vat">\n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n
    \t\t\t\t            \t\t</p>\n
            \n
    \t\t\t\t\t\t\t</div>\n
    \t\t\t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t </div>\n
    \t\t\t</div>\n
    \n
    \t\t\t\t\t</section>\n
    \t\t\t\t\t\t\t\t\t<section class="card-footer ce-accordion closed">\n
    \t\t\t\t\t<div class="ce-info">\n
                <div id="event-detail-row-5" class="row">\n
                <div class="col-sm-12 col-md-6 mb-l">\n
                                <div class="info-table">\n
                        <div class="table-row wide">\n
                            <div class="label-column">Kursort:</div>\n
                            <div class="info-column">\n
                                <div class="location">\n
                                        \n
                <p>\n
                <b>Ausbildungszentrum für Arbeitssicherheit</b>\n
            </p>\n
        \n
        <div class="address-row info-table info-table-small">\n
                            <div class="table-row">\n
                <div class="icon-column">\n
                    <span class="glyphicon glyphicon-map-marker"\n
                          title="Anschrift"></span>\n
                </div>\n
                <div class="info-column">\n
                    Pirnaer Landstraße 40,\n
                    01237  Dresden,\n
                        Deutschland            </div>\n
            </div>\n
        </div>\n
                                    </div>\n
                            </div>\n
                        </div>\n
                    </div>\n
                \n
                 \n
                                            \n
                         </div>\n
        \n
            <div class="col-sm-12 col-md-6 mb-l">\n
    \n
            <div class="map">\n
                                            <div class="event-details-map mb-m">\n
                                            <!-- OPENSTREETMAPS START -->\n
                                        <div id="maploc4-68b861fb1ab77"\n
                             class="mapBlock mt-m mb-m"\n
                             style="height: 200px; width: 100%"\n
                             data-mapdata='{"id":"loc4-68b861fb1ab77","searchText":"Pirnaer Landstra\u00dfe 40 01237  Dresden Deutschland","description":"Ausbildungszentrum f\u00fcr Arbeitssicherheit<br>Pirnaer Landstra\u00dfe 40<br>01237  Dresden<br>Deutschland"}'\n
                             data-longitude="13.8135227"\n
                             data-latitude="51.0183231">\n
                        </div>\n
                                    <!-- OPENSTREETMAPS END -->\n
                        </div>\n
                                        <div id="navloc4-68b861fb1ab77" class="mapNavigation text-right mb-m">\n
                        <a class="btn btn-primary mapNavigationLink"\n
                           id="navLinkloc4-68b861fb1ab77"\n
                           target="_blank"\n
                           href="https://www.google.de/maps/dir//Pirnaer Landstraße 40 01237  Dresden Deutschland">\n
                            Routenplaner\n
                        </a>\n
                    </div>\n
                                    </div>\n
    \n
                        </div>\n
        </div>\n
        \n
                \n
                        \n
        \n
                        \n
                \n
                \n
        \n
        \n
        \n
        \n
        <div class="row">\n
            <div class="col-sm-12 col-md-6 mb-l">\n
                <div class="info-table">\n
                    \n
                    \n
                        \n
                    \n
                    \n
                    \n
                    \n
    \n
                    \n
                                </div>\n
    \n
                        </div>\n
                </div>\n
    \n
        </div>\n
    \n
    <div id="cancellation-info5">\n
        <div style="padding-top:30px;">\n
            \n
        </div>\n
    </div>\n
    <style>\n
        #xsem #cancellation-info5 {\n
            display: none;\n
        }\n
    </style>\n
    \t\t\t\t\t<div class="ce-accordion-header">\n
    \t\t\t\t\t\t<button id="btnOpenAccordion5">Weitere Informationen</button>\n
    \t\t\t\t\t</div>\n
    \t\t\t\t</section>\n
    \t\t\t\t\t\t</div>\n
    \n
        </div>\n
        <div class="cart-col-amount">\n
            <div class="cart-price price-block">\n
                <span class="cart-label">Preis je Teilnehmer</span>\n
                \t<div class="price-block">\n
    \t\t\t\t\t\t<p class="pb-best-price">\n
    \t\t\t\t\t\t\t<span class="pb-price">100,- EUR</span>\n
    \t\t\t\t<br><span class="pb-vat">\n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n
    \t\t\t\t            \t\t</p>\n
            \n
    \t\t\t\t\t\t\t</div>\n
            </div>\n
            <div class="cart-amount">\n
                                            <span class="cart-label">Anzahl Teilnehmer</span>\n
                    <div class="form-group">\n
                        <input type="number"\n
                               min="0"\n
                               max="250"\n
                               id="cartNumberParticipants54"\n
                               name="numberParticipants[54]"\n
                               class="form-control cartNumberParticipants"\n
                                                          value="1">\n
                    </div>\n
                    <button id="updateItem54"\n
                            type="submit"\n
                            name="cmd[change]"\n
                            class="btn btn-primary"\n
                            title="Aktualisieren"><span class="glyphicon glyphicon-refresh"></span>\n
                    </button>\n
                                <button id="removeItem54"\n
                            type="submit"\n
                            name="cmd[delete]"\n
                            class="btn btn-primary remove"\n
                            title="Entfernen"><span class="glyphicon glyphicon-trash"></span>\n
                    </button>\n
                    <script type="text/javascript">\n
                        $('#removeItem54').on('click', function () {\n
                            $('#cartNumberParticipants54').val(0);\n
                            $(this).closest('form').submit();\n
                            if (typeof GARemoveFromCart54 === "function") {\n
                                GARemoveFromCart54();\n
                            }\n
                        });\n
    \n
                        $('#updateItem54').on('click', function (e) {\n
                                                    if (typeof GAUpdateCart54 === "function") {\n
                                GAUpdateCart54();\n
                            }\n
                        });\n
                        //$('form.submitOnChange input').on('keyup', function() {\n
                        //    $.post($(this).closest('form').attr('action'), $(this).closest('form').serialize())\n
                        //});\n
                    </script>\n
                    \n
    \n
    \n
                    \n
    \n
    \n
                            \n
                        </div>\n
        </div>\n
    </div>\n
                                                                                                                                                \n
    <div class="cart-row-item  mb-l " data-seminar-id="51" data-seminar-type="seminar">\n
        <div class="cart-col-item cart-event-block">\n
                    <style>\n
    \t.xsem-related-bundles-event-btn {\n
    \t\tpadding: 3px 10px !important;\n
    \t\ttext-transform: uppercase !important;\n
    \t\tfont-weight: 500 !important;\n
    \t}\n
    </style>\n
        \n
    \t<div class="card card-event card-sections card-bordered favourite-wrapper ">\n
    \t\t<xsem:Favourites seminar="_context_pass_5" favouriteList="_context_pass_6"></xsem:Favourites>\n
    \t\t<section class="card-header">\n
    \t\t\t\t\t\t<div class="row">\n
    \t\t\t\t<div class="col-xs-12 col-sm-6">\n
    \t\t\t\t\t<h5 class="card-column-headline">Kurstermin</h5>\n
    \t\t\t\t\t                10. - 15.09.2025\n
                \t\t\t\t\t\t\t\t\t\t\t<xsem:EditPencil\n
    \t\t\t\t\t\t\t\tobject="_context_pass_7"\n
    \t\t\t\t\t\t\t\tlink="/seminarverwaltung/kurse/sicherheit-und-gesundheit-im-wasserbau-51/termine/sicherheit-und-gesundheit-im-wasserbau-10.--15.09.2025-51/bearbeiten.html?parentObject=Seminar"\n
    \t\t\t\t\t\t\t\ttarget="editEvent"\n
    \t\t\t\t\t\t>\n
    \t\t\t\t\t\t</xsem:EditPencil>\n
    \t\t\t\t\t\t\t\t\t</div>\n
    \t\t\t\t<div class="col-xs-6 col-sm-3">\n
    \t\t\t\t\t<h5 class="card-column-headline">Kurssprache</h5>\n
    \t\t\t\t\t    <span class="nowrap">Deutsch <img src="./Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/SeminarCatalog/Resources//img/flags/de.png" alt="Kurssprache: Deutsch"></span>\t\t\t\t</div>\n
    \t\t\t\t<div class="col-xs-6 col-sm-3">\n
    \t\t\t\t\t\t\t\t\t\t\t<h5 class="card-column-headline">Kurs-Nr.</h5>\n
    \t\t\t\t\t\t1921 / SG-WB\n
    \t\t\t\t\t\t\t\t\t</div>\n
    \t\t\t</div>\n
    \t\t</section>\n
    \t\t<section class="card-body">\n
    \t\t\t<div class="row">\n
    \t\t\t\t<div class="col-xs-12 col-sm-6">\n
    \t\t\t\t\t\t\t\t\t\t\t<h5 class="card-column-headline">Kurs</h5>\n
    \t\t\t\t\t\n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class="card-title">\n
    \t\t\t\t\t\t\t\n
        \t\t<a href="/kursangebot/kurs/sicherheit-und-gesundheit-im-wasserbau-51.html"\n
    \t\t   \t\t   title="Kursdetails anzeigen"\n
    \t\t   class=""\t\t>\n
                Sicherheit und Gesundheit im Wasserbau\n
    \t\t\t\t\t</a>\n
        <xsem:EditPencil\n
    \t\tobject="_context_pass_8"\n
    \t\tlink="/seminarverwaltung/kurse/sicherheit-und-gesundheit-im-wasserbau-51/termine/sicherheit-und-gesundheit-im-wasserbau-10.--15.09.2025-51/bearbeiten.html?parentObject=Seminar"\n
    \t\ttarget="editEvent"\n
    >\n
    </xsem:EditPencil>\n
    \t\t\t\t\t</div>\n
    \n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n
    \n
    \t\t\t\t<div class="col-xs-6 col-sm-3">\n
    \t\t\t\t\t\t\t\t\t\t\t<h5 class="card-column-headline">Kursort</h5>\n
    \t\t\t\t\t\t<xsem:FormatEventLocation event="_context_pass_9" cityOnly></xsem:FormatEventLocation>\n
    \t\t\t\t\t\t\t\t\t</div>\n
    \n
    \t\t\t\t <div class="col-xs-6 col-sm-3 online-event-pricecontainer">\n
    \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t\t \t\t\t\t\t\t\t\t <h5 class="card-column-headline">Kursgebühr</h5>\n
    \t\t\t\t\t\t\t\t \t<div class="price-block">\n
    \t\t\t\t\t\t<p class="pb-best-price">\n
    \t\t\t\t\t\t\t<span class="pb-price">100,- EUR</span>\n
    \t\t\t\t<br><span class="pb-vat">\n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n
    \t\t\t\t            \t\t</p>\n
            \n
    \t\t\t\t\t\t\t</div>\n
    \t\t\t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t </div>\n
    \t\t\t</div>\n
    \n
    \t\t\t\t\t</section>\n
    \t\t\t\t\t\t\t\t\t<section class="card-footer ce-accordion closed">\n
    \t\t\t\t\t<div class="ce-info">\n
                <div id="event-detail-row-51" class="row">\n
                <div class="col-sm-12 col-md-6 mb-l">\n
                                <div class="info-table">\n
                        <div class="table-row wide">\n
                            <div class="label-column">Kursort:</div>\n
                            <div class="info-column">\n
                                <div class="location">\n
                                        \n
                <p>\n
                <b>Schulungszentrum Ricklingen</b>\n
            </p>\n
        \n
        <div class="address-row info-table info-table-small">\n
                        <div class="table-row">\n
                    <div class="icon-column">\n
                    <span class="glyphicon glyphicon-record"\n
                          title="Raum"></span>\n
                    </div>\n
                    <div class="info-column">\n
                        1\n
                    </div>\n
                </div>\n
                                <div class="table-row">\n
                    <div class="icon-column">\n
                    <span class="glyphicon glyphicon-home"\n
                          title="Gebäude"></span>\n
                    </div>\n
                    <div class="info-column">\n
                        Nebengebäude,                    1                </div>\n
                </div>\n
                    <div class="table-row">\n
                <div class="icon-column">\n
                    <span class="glyphicon glyphicon-map-marker"\n
                          title="Anschrift"></span>\n
                </div>\n
                <div class="info-column">\n
                    Wettgerber Bach,\n
                    30453 Ricklingen,\n
                        Deutschland            </div>\n
            </div>\n
        </div>\n
                                    </div>\n
                            </div>\n
                        </div>\n
                    </div>\n
                \n
                 \n
                                            \n
                         </div>\n
        \n
            <div class="col-sm-12 col-md-6 mb-l">\n
    \n
            <div class="map">\n
                                            <div class="event-details-map mb-m">\n
                                            <!-- OPENSTREETMAPS START -->\n
                                        <div id="maploc1-68b861fb20b56"\n
                             class="mapBlock mt-m mb-m"\n
                             style="height: 200px; width: 100%"\n
                             data-mapdata='{"id":"loc1-68b861fb20b56","searchText":"Wettgerber Bach 30453 Ricklingen Deutschland","description":"Schulungszentrum Ricklingen<br>Wettgerber Bach<br>30453 Ricklingen<br>Deutschland"}'\n
                             data-longitude="9.681339116927258"\n
                             data-latitude="52.33289610883518">\n
                        </div>\n
                                    <!-- OPENSTREETMAPS END -->\n
                        </div>\n
                                        <div id="navloc1-68b861fb20b56" class="mapNavigation text-right mb-m">\n
                        <a class="btn btn-primary mapNavigationLink"\n
                           id="navLinkloc1-68b861fb20b56"\n
                           target="_blank"\n
                           href="https://www.google.de/maps/dir//Wettgerber Bach 30453 Ricklingen Deutschland">\n
                            Routenplaner\n
                        </a>\n
                    </div>\n
                                    </div>\n
    \n
                        </div>\n
        </div>\n
        \n
                \n
                        \n
        \n
                        \n
                \n
                \n
        \n
        \n
                <div class="row">\n
                                            <div class="col-sm-12 col-md-6 mb-l">\n
                                \n
                                                                        <div class="info-table">\n
                    <div class="table-row wide">\n
                        <div class="label-column">Hotelempfehlungen:</div>\n
                        <div class="info-column">\n
                                                        <div class="hotel">\n
                                    <p class="locationAddress">\n
                                                                                <a class="hotelWeblink" href="https://www.databay.de"\n
                                               target="_blank">\n
                                                <b>Hotel am See</b>\n
                                                <span class="glyphicon glyphicon-link"\n
                                                      title="Webseite"></span>\n
                                            </a>\n
                                            <br>\n
                                                                        </p>\n
    \n
                                    <div class="address-row info-table info-table-small">\n
                                        <div class="table-row">\n
                                            <div class="icon-column">\n
                                                <span class="glyphicon glyphicon-map-marker"\n
                                                      title="Anschrift"></span>\n
                                            </div>\n
                                            <div class="info-column">\n
                                                Seeufer 1, 12345 Seestadt\n
                                            </div>\n
                                        </div>\n
                                    </div>\n
                                                                        <div class="address-row info-table info-table-small">\n
                                            <div class="table-row">\n
                                                <div class="icon-column">\n
                                                    <span class="glyphicon glyphicon-earphone"\n
                                                          title="Fon"></span>\n
                                                </div>\n
                                                <div class="info-column">\n
                                                    <a class="hotelWeblink"\n
                                                       href="tel:123456789">123456789</a>\n
                                                </div>\n
                                            </div>\n
                                        </div>\n
                                                                                                                                        <div class="address-row info-table info-table-small">\n
                                            <div class="table-row">\n
                                                <div class="icon-column">\n
                                                    <span class="glyphicon glyphicon-envelope"\n
                                                          title="E-Mail"></span>\n
                                                </div>\n
                                                <div class="info-column">\n
                                                    <a class="hotelWeblink"\n
                                                       href="mailto:jc@databay.de">jc@databay.de</a>\n
                                                </div>\n
                                            </div>\n
                                        </div>\n
                                                                                                                                                                    </div>\n
                                                </div>\n
                    </div>\n
                </div>\n
                                            \n
                                \n
                                        </div>\n
                        </div>\n
        \n
        \n
        <div class="row">\n
            <div class="col-sm-12 col-md-6 mb-l">\n
                <div class="info-table">\n
                    \n
                    \n
                        \n
                    \n
                    \n
                    \n
                    \n
    \n
                    \n
                                </div>\n
    \n
                        </div>\n
                </div>\n
    \n
        </div>\n
    \n
    <div id="cancellation-info51">\n
        <div style="padding-top:30px;">\n
            \n
        </div>\n
    </div>\n
    <style>\n
        #xsem #cancellation-info51 {\n
            display: none;\n
        }\n
    </style>\n
    \t\t\t\t\t<div class="ce-accordion-header">\n
    \t\t\t\t\t\t<button id="btnOpenAccordion51">Weitere Informationen</button>\n
    \t\t\t\t\t</div>\n
    \t\t\t\t</section>\n
    \t\t\t\t\t\t</div>\n
    \n
        </div>\n
        <div class="cart-col-amount">\n
            <div class="cart-price price-block">\n
                <span class="cart-label">Preis je Teilnehmer</span>\n
                \t<div class="price-block">\n
    \t\t\t\t\t\t<p class="pb-best-price">\n
    \t\t\t\t\t\t\t<span class="pb-price">100,- EUR</span>\n
    \t\t\t\t<br><span class="pb-vat">\n
    \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n
    \t\t\t\t            \t\t</p>\n
            \n
    \t\t\t\t\t\t\t</div>\n
            </div>\n
            <div class="cart-amount">\n
                                            <span class="cart-label">Anzahl Teilnehmer</span>\n
                    <div class="form-group">\n
                        <input type="number"\n
                               min="0"\n
                               max="250"\n
                               id="cartNumberParticipants55"\n
                               name="numberParticipants[55]"\n
                               class="form-control cartNumberParticipants"\n
                                                          value="1">\n
                    </div>\n
                    <button id="updateItem55"\n
                            type="submit"\n
                            name="cmd[change]"\n
                            class="btn btn-primary"\n
                            title="Aktualisieren"><span class="glyphicon glyphicon-refresh"></span>\n
                    </button>\n
                                <button id="removeItem55"\n
                            type="submit"\n
                            name="cmd[delete]"\n
                            class="btn btn-primary remove"\n
                            title="Entfernen"><span class="glyphicon glyphicon-trash"></span>\n
                    </button>\n
                    <script type="text/javascript">\n
                        $('#removeItem55').on('click', function () {\n
                            $('#cartNumberParticipants55').val(0);\n
                            $(this).closest('form').submit();\n
                            if (typeof GARemoveFromCart55 === "function") {\n
                                GARemoveFromCart55();\n
                            }\n
                        });\n
    \n
                        $('#updateItem55').on('click', function (e) {\n
                                                    if (typeof GAUpdateCart55 === "function") {\n
                                GAUpdateCart55();\n
                            }\n
                        });\n
                        //$('form.submitOnChange input').on('keyup', function() {\n
                        //    $.post($(this).closest('form').attr('action'), $(this).closest('form').serialize())\n
                        //});\n
                    </script>\n
                    \n
    \n
    \n
                    \n
    \n
    \n
                            \n
                        </div>\n
        </div>\n
    </div>\n
                                                    \n
                <div class="cart-row-total">\n
                    <div class="cart-col-coupon">\n
                                        </div>\n
                    <div class="cart-col-total price-block">\n
                                                                    \n
                            <div class="pb-total">\n
                                <span class="cart-label">Gesamtsumme</span>\n
                                200,- EUR<br>\n
                                                                <span class="pb-vat">\n
                                        mehrwertsteuerfrei<br>\n
    \n
                                    </span>\n
                                                        </div>\n
    \n
                                                                </div>\n
                </div>\n
    \n
                <div class="row cart-submit">\n
                    <div class="col-sm-6">\n
                                        <a class="btn btn-primary" href="/kursangebot.html">\n
            Weitere Kurse buchen\n
        </a>\n
                    </div>\n
                    <div class="col-sm-6 text-right">\n
                                                                            <button id="bookingButton" name="cmd[book]" class="btn btn-primary" type="submit">\n
                                    Zur Kasse\n
                                </button>\n
                                                                </div>\n
                </div>\n
            </form>\n
    \n
            <div class="clear"></div>\n
        </div>\n
    \n
    \n
    <style>\n
        #xsem {\n
            [data-seminar-type="conference"] .cart-event-block .card {\n
                margin-bottom: 0 !important;\n
                border: 0 !important;\n
                min-height: 0 !important\n
            }\n
    \n
            [data-seminar-type="conference"] .cart-amount{\n
                padding-bottom: 0 !important;\n
            }\n
        }\n
    </style>\n
    <style>\n
        .booking-blocked {\n
            border-color:red;\n
        }\n
    </style>\n
    \n
    \n
    <script type="text/javascript">\n
        $(document).ready(function () {\n
            $(".cartNumberParticipants").each(function () {\n
                if ($(this).val() > $(this).data("max-participants") || $(this).val() < 0) {\n
                    $(this).popover("show");\n
                    $(this).data("has-popover", 1);\n
                }\n
            });\n
        });\n
    \n
    \n
        $(".cartNumberParticipants").on("click", function () {\n
            if ($(this).data("max-participants")) {\n
                if ($(this).val() > $(this).data("max-participants") || $(this).val() < 0) {\n
                    $(this).popover("show");\n
                    $(this).data("has-popover", 1);\n
                } else {\n
                    $(this).popover("hide");\n
                    $(this).data("has-popover", 0);\n
                }\n
            }\n
        });\n
        $(".cartNumberParticipants").on("keyup", function () {\n
            if ($(this).data("max-participants")) {\n
                if ($(this).val() > $(this).data("max-participants") || $(this).val() < 0) {\n
                    $(this).popover("show");\n
                    $(this).data("has-popover", 1);\n
                } else {\n
                    $(this).popover("hide");\n
                    $(this).data("has-popover", 0);\n
                }\n
            }\n
        });\n
    \n
        $("#bookingButton").on("click", function () {\n
            var saveFlag = true;\n
            $(".cartNumberParticipants").each(function () {\n
                if ($(this).data("has-popover") == 1) {\n
                    saveFlag = false;\n
                }\n
            });\n
    \n
            if (saveFlag) {\n
                //$("#cartForm").submit();\n
                return true;\n
            }\n
    \n
            return false;\n
        });\n
    </script>\n
    \n
    <style>\n
        #xsem .cart-row-item,\n
        #xsem .cart-row-total {\n
            display: flex;\n
            flex-direction: row;\n
            flex-wrap: nowrap;\n
            justify-content: space-between;\n
            align-items: stretch;\n
            align-content: stretch;\n
            gap: 0;\n
        }\n
        #xsem .cart-col-item {\n
            flex-grow: 3;\n
            flex-basis: 75%;\n
            padding-right: 20px;\n
        }\n
        #xsem .cart-col-amount {\n
            flex-grow: 1;\n
            flex-basis: 25%;\n
            padding: 0 20px;\n
        }\n
        #xsem .cart-col-coupon {\n
            flex-grow: 3;\n
            flex-basis: 75%;\n
            padding: 0 20px;\n
        }\n
        #xsem .cart-col-total {\n
            flex-grow: 1;\n
            flex-basis: 25%;\n
            padding: 0 20px;\n
        }\n
    \n
        #xsem .cart-col-total .cart-price {\n
            display: inline-block;\n
            text-align: left;\n
        }\n
    </style>\n
    """
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/vendor/twig/twig/src/TemplateWrapper.php
 
    /**
     * @return iterable<scalar|\Stringable|null>
     */
    public function stream(array $context = []): iterable
    {
        yield from $this->template->yield($context);
    }
 
    /**
     * @return iterable<scalar|\Stringable|null>
     */
    public function streamBlock(string $name, array $context = []): iterable
    {
        yield from $this->template->yieldBlock($name, $context);
    }
 
    public function render(array $context = []): string
    {
        return $this->template->render($context);
    }
 
    /**
     * @return void
     */
    public function display(array $context = [])
    {
        // using func_get_args() allows to not expose the blocks argument
        // as it should only be used by internal code
        $this->template->display($context, \func_get_args()[1] ?? []);
    }
 
    public function hasBlock(string $name, array $context = []): bool
    {
        return $this->template->hasBlock($name, $context);
    }
 
    /**
     * @return string[] An array of defined template block names
     */
Arguments
  1. array:6 [
      "newItem" => SeminarCatalog\Core\Order\Model\Item {#3860}
      "isEmptyCart" => false
      "currentOrder" => SeminarCatalog\Core\Order\Model\Order {#2461}
      "validationResult" => SeminarCatalog\Validator\ValidationResult {#3257}
      "couponDiscounts" => []
      "orderItemsReserved" => null
    ]
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/Core/Cart/Classes/Controller/CartController.php
 
                if (isset($_GET['newItemId'])) {
                    if ($item->getId() === (int)StringUtility::fromMixed($_GET['newItemId'])) {
                        $newItem = $item;
                    }
                }
            }
 
            $couponDiscounts = $this->couponService->getDiscountsList($this->currentOrder);
        }
 
        if ($this->configurationService->get('maintenance_mode') == 1) {
            NoticeService::send(
                "error",
                LanguageService::translate("booking_info_bookings_temporarily_not_possible")
            );
 
        }
 
        return $template->render(
            [
                'newItem'            => $newItem,
                'isEmptyCart'        => $isEmptyCart,
                'currentOrder'       => $this->currentOrder,
                'validationResult'   => $this->validationResult,
                'couponDiscounts'    => $couponDiscounts,
                "orderItemsReserved" => isset($_GET['orderItemsReserved']) ? explode(",",
                    urldecode($_GET['orderItemsReserved'])) : null,
            ]
        );
    }
 
    /**
     * @access isAnybody
     * @return RedirectControllerResult|string
     * @throws \Exception
     */
    public function submitCartAction()
    {
        if (!($this->currentOrder instanceof Order)) {
Arguments
  1. array:6 [
      "newItem" => SeminarCatalog\Core\Order\Model\Item {#3860}
      "isEmptyCart" => false
      "currentOrder" => SeminarCatalog\Core\Order\Model\Order {#2461}
      "validationResult" => SeminarCatalog\Validator\ValidationResult {#3257}
      "couponDiscounts" => []
      "orderItemsReserved" => null
    ]
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/classes/Controller/BaseController.php
                    $this,
                    'handleParameters',
                    $_GET
                );
 
                $this->handleParameters(...$params);
            }
 
            if (method_exists($this, 'initializeAction')) {
                $params = ClassService::convertGetValuesToMethodParameterValues(
                    $this,
                    'initializeAction',
                    $_GET
                );
                $this->initializeAction(...$params);
            }
 
            $cmd = $cmd . 'Action';
            $params = ClassService::convertGetValuesToMethodParameterValues($this, $cmd, $_GET);
            $html = $this->$cmd(...$params);
 
            global $tpl;
 
            if ($tpl) {
                if ($this->getPageTitle() != '') {
                    $tpl->setTitle($this->getPageTitle());
                } else {
                    // This is a bad idea because it will break the page title in the repository
                    $tpl->setTitle(LanguageService::translate('default_page_header'));
                }
 
                if ($this->getPageIcon() != '') {
                    $tpl->setTitleIcon($this->getPageIcon());
                }
            }
 
            return $html;
        }
 
        throw new AuthenticationException(get_class($this), $cmd);
/srv/www/bgphoenics2.invorbereitung.de/ilias/classes/SeminarCatalogKernel.php
 
            $router = ObjectManager::get(\SeminarCatalog\Core\Routing\Service\CoreRouter::class);
 
            try {
                if ($request->getRequestUri()) {
                    if (strpos($request->getRequestUri(), '/index.php?') === 0) {
                        throw new ResourceNotFoundException('URLs starting with /index.php? are not allowed');
                    }
                }
                $match  = $router->match($request);
                $router->resolveMatch($match);
                $controller = $match[$configurationService->getControllerGetParameterName()];
                $request->query->add($match);
 
                $controller = UtilityService::prepareClassNameFromUrl($controller);
                $controller = self::checkAccessAndGetControllerInstance(
                    $controller,
                    $configurationService
                );
                $response = $controller->handleCmd($request);
 
            } catch(NoConfigurationException|ResourceNotFoundException $e) {
                // Fallback to legacy Routing
                $controller = $request->get($configurationService->getControllerGetParameterName());
                if ($controller == "") {
                    throw new \Exception("No route found");
                }
 
 
                $controller = UtilityService::prepareClassNameFromUrl($controller);
                $controller = self::checkAccessAndGetControllerInstance(
                    $controller,
                    $configurationService
                );
                $response = $controller->handleCmd();
            }
 
            return $this->handleControllerResponse($response, $request, $controller);
        } catch(\Throwable $e) {
 
Arguments
  1. Symfony\Component\HttpFoundation\Request {#543
      +attributes: Symfony\Component\HttpFoundation\ParameterBag {#533}
      +request: Symfony\Component\HttpFoundation\InputBag {#531}
      +query: Symfony\Component\HttpFoundation\InputBag {#532}
      +server: Symfony\Component\HttpFoundation\ServerBag {#536}
      +files: Symfony\Component\HttpFoundation\FileBag {#535}
      +cookies: Symfony\Component\HttpFoundation\InputBag {#534}
      +headers: Symfony\Component\HttpFoundation\HeaderBag {#537}
      #content: null
      #languages: null
      #charsets: null
      #encodings: null
      #acceptableContentTypes: null
      #pathInfo: "/warenkorb.html"
      #requestUri: "/warenkorb.html?newItemId=55"
      #baseUrl: ""
      #basePath: null
      #method: "GET"
      #format: null
      #session: null
      #locale: null
      #defaultLocale: "en"
      -preferredFormat: null
      -isHostValid: true
      -isForwardedValid: true
      -isSafeContentPreferred: null
      -isIisRewrite: false
      basePath: ""
      format: "html"
    }
    
/srv/www/bgphoenics2.invorbereitung.de/ilias/index.php
use SeminarCatalog\Rest\Utility\ControllerResultInterface;
use Symfony\Component\HttpFoundation\Request;
 
 
require_once __DIR__ . '/classes/SeminarCatalogKernel.php';
 
error_reporting(error_reporting() & ~E_NOTICE);
ini_set('display_errors', 1);
apcu_clear_cache();
 
$whoops = new \Whoops\Run;
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
$whoops->register();
 
define("standalone2",true);
define("DEVMODE",true);
 
$kernel = new \SeminarCatalogKernel();
$kernel->boot();
$response = $kernel->handleRequest(ObjectManager::get(Request::class));
 
if ($response instanceof \Symfony\Component\HttpFoundation\Response || $response instanceof ControllerResultInterface) {
    $response->send();
} else {
    if (is_string($response)) {
        echo $response;
    } else {
        throw new \Exception('Invalid response type given. Only Response|String is valid.');
    }
}
 
// http://localhost:32768/?scontroller=SeminarCatalog__Core__Catalog__Controller__CatalogController&saction=catalog
 
Arguments
  1. Symfony\Component\HttpFoundation\Request {#543
      +attributes: Symfony\Component\HttpFoundation\ParameterBag {#533}
      +request: Symfony\Component\HttpFoundation\InputBag {#531}
      +query: Symfony\Component\HttpFoundation\InputBag {#532}
      +server: Symfony\Component\HttpFoundation\ServerBag {#536}
      +files: Symfony\Component\HttpFoundation\FileBag {#535}
      +cookies: Symfony\Component\HttpFoundation\InputBag {#534}
      +headers: Symfony\Component\HttpFoundation\HeaderBag {#537}
      #content: null
      #languages: null
      #charsets: null
      #encodings: null
      #acceptableContentTypes: null
      #pathInfo: "/warenkorb.html"
      #requestUri: "/warenkorb.html?newItemId=55"
      #baseUrl: ""
      #basePath: null
      #method: "GET"
      #format: null
      #session: null
      #locale: null
      #defaultLocale: "en"
      -preferredFormat: null
      -isHostValid: true
      -isForwardedValid: true
      -isSafeContentPreferred: null
      -isIisRewrite: false
      basePath: ""
      format: "html"
    }
    

Environment & details:

Key Value
args
"/warenkorb.html"
newItemId
"55"
_route
"view_cart"
saction
"showCart"
scontroller
"SeminarCatalog__Core__Cart__Controller__CartController"
lang
"de"
request
Symfony\Component\HttpFoundation\Request {#543
  +attributes: Symfony\Component\HttpFoundation\ParameterBag {#533}
  +request: Symfony\Component\HttpFoundation\InputBag {#531}
  +query: Symfony\Component\HttpFoundation\InputBag {#532}
  +server: Symfony\Component\HttpFoundation\ServerBag {#536}
  +files: Symfony\Component\HttpFoundation\FileBag {#535}
  +cookies: Symfony\Component\HttpFoundation\InputBag {#534}
  +headers: Symfony\Component\HttpFoundation\HeaderBag {#537}
  #content: null
  #languages: null
  #charsets: null
  #encodings: null
  #acceptableContentTypes: null
  #pathInfo: "/warenkorb.html"
  #requestUri: "/warenkorb.html?newItemId=55"
  #baseUrl: ""
  #basePath: null
  #method: "GET"
  #format: null
  #session: null
  #locale: null
  #defaultLocale: "en"
  -preferredFormat: null
  -isHostValid: true
  -isForwardedValid: true
  -isSafeContentPreferred: null
  -isIisRewrite: false
  basePath: ""
  format: "html"
}
empty
empty
Key Value
PHPSESSID
"m19u3t67qmnkt4rt3k0mr2s9nd"
orderId
"51"
Key Value
order_session
array:1 [
  51 => array:5 [
    "billingAddressStep" => false
    "participantDataStep" => false
    "shippingAddressStep" => false
    "paymentStep" => false
    "overviewStep" => false
  ]
]
orderId
51
Key Value
PHP_MAX_INPUT_TIME
"600"
PHP_UPLOAD_MAX_FILESIZE
"512M"
PHP_START_SERVERS
"10"
LANGUAGE
"en_US:en"
HOSTNAME
"php8.2-fpm"
PHP_POOL_NAME
"www_8.2"
PHP_MAX_FILE_UPLOADS
"20"
PHP_INI_DIR
"/usr/local/etc/php"
PHP_OPCACHE_MEMORY_CONSUMPTION
"256M"
PHP_SESSION_GC_MAX_LIFETIME
"3600"
HOME
"/var/www"
PHP_LDFLAGS
"-Wl,-O1 -pie"
PHP_OPCACHE_INTERNED_STRINGS_BUFFER
"32"
PHP_CFLAGS
"-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
PHP_VERSION
"8.2.28"
PHP_MAX_INPUT_VARS
"4000"
GPG_KEYS
"39B641343D8C104B2B146DC3F9C39DC0B9698544 E60913E4DF209907D8E30D96659A97C9CF2A795A 1198C0117593497A5EC5C199286AF1F9897469DC"
PHP_OPCACHE_JIT
"1255"
PHP_USER
"www-data"
PHP_GROUP
"www-data"
PHP_CPPFLAGS
"-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
PHP_ASC_URL
"https://www.php.net/distributions/php-8.2.28.tar.xz.asc"
PHP_POST_MAX_SIZE
"512M"
OPENSSL_CONF
"/etc/ssl/openssl.cnf"
PHP_URL
"https://www.php.net/distributions/php-8.2.28.tar.xz"
PHP_MAX_EXECUTION_TIME
"600"
PATH
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
PHP_MAX_CHILDREN
"20"
PHP_MEMORY_LIMIT
"512M"
PHP_SESSION_SAVE_PATH
"/tmp"
LANG
"en_US.UTF-8"
PHP_OPCACHE_HUGE_CODE_PAGES
"0"
PHP_SESSION_CACHE_EXPIRE
"180"
PHP_OPCACHE_MAX_ACCELERATED_FILES
"32000"
PHP_OPCACE_JIT_BUFFER_SIZE
"32M"
PHP_APP_NAME
"www_8.2"
PHP_LISTEN_PORT
"9000"
PHP_MIN_SPARE_SERVERS
"10"
PHP_MAX_REQUESTS
"5000"
PHPIZE_DEPS
"autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c"
LC_ALL
"en_US.UTF-8"
PWD
"/var/www/html"
PHP_SOAP_WSDL_CACHE_DIR
"/tmp/"
PHP_SHA256
"af8c9153153a7f489153b7a74f2f29a5ee36f5cb2c6c6929c98411a577e89c91"
PHP_MAX_SPARE_SERVERS
"10"
TZ
"Europe/Berlin"
LDAPTLS_REQCERT
"hard"
PHP_PROCESS_MODELL
"ondemand"
USER
"www-data"
HTTP_COOKIE
"PHPSESSID=m19u3t67qmnkt4rt3k0mr2s9nd; orderId=51"
HTTP_REFERER
"https://bgphoenics2.invorbereitung.de/buchen/51.html?disabled=0"
HTTP_ACCEPT_ENCODING
"gzip, br, zstd, deflate"
HTTP_USER_AGENT
"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)"
HTTP_ACCEPT
"*/*"
HTTP_CONNECTION
"close"
HTTP_HTTPS
"on"
HTTP_X_SSL
"on"
HTTP_X_FORWARDED_PORT
"443"
HTTP_X_FORWARDED_PROTO
"https"
HTTP_X_FORWARDED_HOST
"bgphoenics2.invorbereitung.de"
HTTP_X_FORWARDED_FOR
"216.73.216.114"
HTTP_X_REAL_IP
"216.73.216.114"
HTTP_X_HOST
"bgphoenics2.invorbereitung.de"
HTTP_HOST
"bgphoenics2.invorbereitung.de"
REDIRECT_STATUS
"200"
SERVER_NAME
"bgphoenics2.invorbereitung.de"
SERVER_PORT
"80"
SERVER_ADDR
"172.25.64.37"
REMOTE_PORT
""
REMOTE_ADDR
"216.73.216.114"
SERVER_SOFTWARE
"nginx/1.26.0"
GATEWAY_INTERFACE
"CGI/1.1"
REQUEST_SCHEME
"http"
SERVER_PROTOCOL
"HTTP/1.1"
DOCUMENT_ROOT
"/srv/www/bgphoenics2.invorbereitung.de/ilias"
DOCUMENT_URI
"/index.php"
REQUEST_URI
"/warenkorb.html?newItemId=55"
SCRIPT_NAME
"/index.php"
CONTENT_LENGTH
""
CONTENT_TYPE
""
REQUEST_METHOD
"GET"
QUERY_STRING
"args=/warenkorb.html&newItemId=55"
SCRIPT_FILENAME
"/srv/www/bgphoenics2.invorbereitung.de/ilias/index.php"
PATH_INFO
""
FCGI_ROLE
"RESPONDER"
PHP_SELF
"/index.php"
REQUEST_TIME_FLOAT
1756914170.6228
REQUEST_TIME
1756914170
empty
0. Whoops\Handler\PrettyPageHandler