Apply assignment all roles.
@param array $config
@return void
169722
protected function assignRoles(array $config) : void
    {
        $this->stdout("Assign roles: " . count($config) . "\n", Console::FG_YELLOW);
        foreach ($config as $item) {
            if (!$role = $this->assignRole($item)) {
                $this->stdout("\t- error assigned role: " . Json::encode($item) . "\n", Console::FG_RED);
            }
        }
    }
1216216
public function initiate(array $config): void
    {
        $this->fieldsets = new Collection();

        foreach ($config as $key => $value) {
            if (\property_exists($this, $key)) {
                $this->{$key} = $value;
            }
        }

        $this->data = new Fluent();
    }
918499
static public function setConfig(array $config)
    {
        foreach ($config as $k => $v) {
            self::$_config[$k] = $v;
        }
    }
671960
public function initialize(array $config = []) {
		if (empty($this->_config['fields'])) {
			$schema = $this->getTable()->getSchema();

			$fields = [];
			foreach ($schema->columns() as $field) {
				$v = $schema->getColumn($field);
				if (!in_array($v['type'], ['string', 'text'])) {
					continue;
				}
				if (!empty($v['key'])) {
					continue;
				}
				if (isset($v['length']) && $v['length'] === 1) { // TODO: also skip UUID (lenght 36)?
					continue;
				}
				$fields[] = $field;
			}
			$this->_config['fields'] = $fields;
		}
		if ($this->_config['mergeQuotes'] === true) {
			$this->_config['mergeQuotes'] = '"';
		}
	}
551588
public function setConfig($config = [])
    {
        $this->config = $config;
        $this->debug->debug(__FUNCTION__, 'setConfig: ', $this->config);
    }
1228151
public function initialize(array $config = [])
    {
        $this->setConfig($config);
        $this->_registry->getController()->viewBuilder()->setHelpers(['Recaptcha.Recaptcha' => $this->_config]);
    }
1053531
public function assignTo($parent, array $config = []) {
		foreach ($config as $key => $val) {
			$this->{'_' . $key} = $val;
		}
		$this->_parent =& $parent;
	}
212565
public function manipulate(Config $config)
    {
        if ($this->isArrayAppend) {
            $this->appendToArraySetting($config);
        } else {
            $this->setSingleConfigValue($config);
        }
    }
12541
public function setPageTitle(array $config): void
    {
        foreach ($config as $item) {
            if (isset($item['active']) && $item['active']) {
                $this->_View->assign('title', $item['title']);
                break;
            }
        }
    }
483182
protected function applyRoles(array $config) : void
    {
        $this->stdout("Init roles: " . count($config) . "\n", Console::FG_YELLOW);
        foreach ($config as $item) {
            if ($role = $this->applyRole($item)) {
                $this->stdout("\t- success: " . $role->name . "\n", Console::FG_GREEN);
            } else {
                $this->stdout("\t- error config role: " . Json::encode($item) . "\n", Console::FG_RED);
            }
        }
    }
14565
public function initialize(array $config) {
		// Shims
		if (isset($this->useTable)) {
			$this->setTable($this->useTable);
		}
		if (isset($this->primaryKey)) {
			$this->setPrimaryKey($this->primaryKey);
		}
		if (isset($this->displayField)) {
			$this->setDisplayField($this->displayField);
		}
		$this->_shimRelations();

		$this->_prefixOrderProperty();

		if (isset($this->actsAs)) {
			foreach ($this->actsAs as $name => $options) {
				if (is_numeric($name)) {
					$name = $options;
					$options = [];
				}
				$this->addBehavior($name, $options);
			}
		}

		if ($this->createdField || $this->modifiedField && !$this->hasBehavior('Timestamp')) {
			$this->addBehavior('Timestamp');
		}
	}
432678
public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('banners_positions');
        $this->setDisplayField('title');
        $this->setPrimaryKey('id');

        $this->hasMany('Banners', ['className' => 'MeCms.Banners'])
            ->setForeignKey('position_id');

        $this->addBehavior('Timestamp');

        $this->_validatorClass = BannersPositionValidator::class;
    }
506874
public function initialize(array $config): void
    {
        Config::set($config);

        $hasServer = Config::hasServer();

        // Automatically log in the user
        if ($hasServer && (Config::hasFeature('USERS') || Config::hasFeature('USERS_LOGIN_DEFAULT'))) {
            $cookies = Internal\Cookies::getList(Internal\Cookies::TYPE_SERVER);
            if (isset($cookies['_a']) && !$this->currentUser->exists()) {
                $data = Internal\Server::call('autologin', [], true);
                if (isset($data['error'])) {
                    $this->currentUser->logout(); // kill the autologin cookie
                }
            }
        }

        $hasElements = Config::hasFeature('ELEMENTS');
        $hasThemes = Config::hasFeature('THEMES');

        // Enable elements
        if ($hasElements || Config::hasFeature('ELEMENTS_*')) {
            $this->app->components
                    ->addAlias('bearcms-elements', 'file:' . $this->context->dir . '/components/bearcmsElements.php')
                    ->addTag('bearcms-elements', 'file:' . $this->context->dir . '/components/bearcmsElements.php')
                    ->addAlias('bearcms-missing-element', 'file:' . $this->context->dir . '/components/bearcmsElement.php')
                    ->addEventListener('makeComponent', function($details) {
                        // Updates the BearCMS components when created
                        $component = $details->component;
                        $name = strlen($component->src) > 0 ? $component->src : ($component->tagName !== 'component' ? $component->tagName : null);
                        if ($name !== null) {
                            if ($name === 'bearcms-elements') {
                                Internal\ElementsHelper::updateContainerComponent($component);
                            } elseif (isset(Internal\ElementsHelper::$elementsTypesFilenames[$name])) {
                                $component->setAttribute('bearcms-internal-attribute-type', Internal\ElementsHelper::$elementsTypesCodes[$name]);
                                $component->setAttribute('bearcms-internal-attribute-filename', Internal\ElementsHelper::$elementsTypesFilenames[$name]);
                                Internal\ElementsHelper::updateElementComponent($component);
                            } else if ($name === 'bearcms-missing-element') {
                                $component->setAttribute('bearcms-internal-attribute-type', 'missing');
                                Internal\ElementsHelper::updateElementComponent($component);
                            }
                        }
                    });

            $this->app->serverRequests
                    ->add('bearcms-elements-load-more', function($data) {
                        if (isset($data['serverData'])) {
                            $serverData = Internal\TempClientData::get($data['serverData']);
                            if (is_array($serverData) && isset($serverData['componentHTML'])) {
                                $content = $this->app->components->process($serverData['componentHTML']);
                                $editorContent = Internal\ElementsHelper::getEditableElementsHtml();
                                return json_encode([
                                    'content' => $content,
                                    'editorContent' => (isset($editorContent[0]) ? $editorContent : ''),
                                    'nextLazyLoadData' => (string) Internal\ElementsHelper::$lastLoadMoreServerData
                                ]);
                            }
                        }
                    });

            if ($hasElements || Config::hasFeature('ELEMENTS_HEADING')) {
                Internal\ElementsTypes::add('heading', [
                    'componentSrc' => 'bearcms-heading-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsHeadingElement.php',
                    'fields' => [
                        [
                            'id' => 'size',
                            'type' => 'list',
                            'defaultValue' => 'large',
                            'options' => [
                                [
                                    'value' => 'large'
                                ],
                                [
                                    'value' => 'medium'
                                ],
                                [
                                    'value' => 'small'
                                ]
                            ]
                        ],
                        [
                            'id' => 'text',
                            'type' => 'textbox'
                        ]
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['heading'] = function($context, $idPrefix, $parentSelector) {
                        $group = $context->addGroup(__("bearcms.themes.options.Heading"));

                        $groupLarge = $group->addGroup(__("bearcms.themes.options.Large"));
                        $groupLarge->addOption($idPrefix . "HeadingLargeCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-heading-element-large", "box-sizing:border-box;font-weight:normal;padding:0;margin:0;"],
                                ["selector", $parentSelector . " .bearcms-heading-element-large"]
                            ]
                        ]);

                        $groupMedium = $group->addGroup(__("bearcms.themes.options.Medium"));
                        $groupMedium->addOption($idPrefix . "HeadingMediumCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-heading-element-medium", "box-sizing:border-box;box-sizing:border-box;font-weight:normal;padding:0;margin:0;"],
                                ["selector", $parentSelector . " .bearcms-heading-element-medium"]
                            ]
                        ]);

                        $groupSmall = $group->addGroup(__("bearcms.themes.options.Small"));
                        $groupSmall->addOption($idPrefix . "HeadingSmallCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-heading-element-small", "box-sizing:border-box;box-sizing:border-box;font-weight:normal;padding:0;margin:0;"],
                                ["selector", $parentSelector . " .bearcms-heading-element-small"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_TEXT')) {
                Internal\ElementsTypes::add('text', [
                    'componentSrc' => 'bearcms-text-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsTextElement.php',
                    'fields' => [
                        [
                            'id' => 'text',
                            'type' => 'textbox'
                        ]
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['text'] = function($context, $idPrefix, $parentSelector) {
                        $groupText = $context->addGroup(__("bearcms.themes.options.Text"));
                        $groupText->addOption($idPrefix . "TextCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-text-element", "box-sizing:border-box;"],
                                ["rule", $parentSelector . " .bearcms-text-element ul,ol,li", "list-style-position:inside;"],
                                ["rule", $parentSelector . " .bearcms-text-element ul,ol,li,p,input", "margin:0;padding:0;"],
                                ["selector", $parentSelector . " .bearcms-text-element"]
                            ]
                        ]);

                        $groupLinks = $groupText->addGroup(__("bearcms.themes.options.Links"));
                        $groupLinks->addOption($idPrefix . "TextLinkCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-text-element a", "text-decoration:none;"],
                                ["selector", $parentSelector . " .bearcms-text-element a"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_LINK')) {
                Internal\ElementsTypes::add('link', [
                    'componentSrc' => 'bearcms-link-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsLinkElement.php',
                    'fields' => [
                        [
                            'id' => 'url',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'text',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'title',
                            'type' => 'textbox'
                        ]
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['link'] = function($context, $idPrefix, $parentSelector) {
                        $group = $context->addGroup(__("bearcms.themes.options.Link"));
                        $group->addOption($idPrefix . "LinkCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-link-element a", "text-decoration:none;"],
                                ["selector", $parentSelector . " .bearcms-link-element a"]
                            ]
                        ]);

                        $groupContainer = $group->addGroup(__("bearcms.themes.options.Container"));
                        $groupContainer->addOption($idPrefix . "LinkContainerCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-link-element", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-link-element"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_IMAGE')) {
                Internal\ElementsTypes::add('image', [
                    'componentSrc' => 'bearcms-image-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsImageElement.php',
                    'fields' => [
                        [
                            'id' => 'filename',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'title',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'onClick',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'url',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'width',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'align',
                            'type' => 'list',
                            'defaultValue' => 'left',
                            'options' => [
                                [
                                    'value' => 'left'
                                ],
                                [
                                    'value' => 'center'
                                ],
                                [
                                    'value' => 'right'
                                ]
                            ]
                        ],
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['image'] = function($context, $idPrefix, $parentSelector) {
                        $group = $context->addGroup(__("bearcms.themes.options.Image"));
                        $group->addOption($idPrefix . "ImageCSS", "css", '', [
                            "cssTypes" => ["cssBorder", "cssRadius", "cssShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-image-element", "overflow:hidden;"],
                                ["rule", $parentSelector . " .bearcms-image-element img", "border:0;"],
                                ["selector", $parentSelector . " .bearcms-image-element"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_IMAGE_GALLERY')) {
                Internal\ElementsTypes::add('imageGallery', [
                    'componentSrc' => 'bearcms-image-gallery-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsImageGalleryElement.php',
                    'fields' => [
                        [
                            'id' => 'type',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'columnsCount',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'imageSize',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'imageAspectRatio',
                            'type' => 'textbox'
                        ]
                    ],
                    'updateComponentFromData' => function($component, $data) {
                        if (isset($data['files']) && is_array($data['files'])) {
                            $innerHTML = '';
                            foreach ($data['files'] as $file) {
                                if (isset($file['filename'])) {
                                    $innerHTML .= '<file filename="' . htmlentities($file['filename']) . '"/>';
                                }
                            }
                            $component->innerHTML = $innerHTML;
                        }
                        return $component;
                    },
                    'updateDataFromComponent' => function($component, $data) {
                        $domDocument = new HTML5DOMDocument();
                        $domDocument->loadHTML($component->innerHTML, HTML5DOMDocument::ALLOW_DUPLICATE_IDS);
                        $files = [];
                        $filesElements = $domDocument->querySelectorAll('file');
                        foreach ($filesElements as $fileElement) {
                            $files[] = ['filename' => $fileElement->getAttribute('filename')];
                        }
                        $data['files'] = $files;
                        return $data;
                    }
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['imageGallery'] = function($context, $idPrefix, $parentSelector) {
                        $groupImageGallery = $context->addGroup(__("bearcms.themes.options.Image gallery"));
                        $groupImageGallery->addOption($idPrefix . "ImageGalleryCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssBorder", "cssRadius", "cssShadow", "cssBackground"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-image-gallery-element"]
                            ]
                        ]);

                        $groupImage = $groupImageGallery->addGroup(__("bearcms.themes.options.Image"));
                        $groupImage->addOption($idPrefix . "ImageGalleryImageCSS", "css", '', [
                            "cssTypes" => ["cssBorder", "cssRadius", "cssShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-image-gallery-element-image", "overflow:hidden;"],
                                ["rule", $parentSelector . " .bearcms-image-gallery-element-image img", "border:0;"],
                                ["selector", $parentSelector . " .bearcms-image-gallery-element-image"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_VIDEO')) {
                Internal\ElementsTypes::add('video', [
                    'componentSrc' => 'bearcms-video-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsVideoElement.php',
                    'fields' => [
                        [
                            'id' => 'url',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'filename',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'width',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'align',
                            'type' => 'list',
                            'defaultValue' => 'left',
                            'options' => [
                                [
                                    'value' => 'left'
                                ],
                                [
                                    'value' => 'center'
                                ],
                                [
                                    'value' => 'right'
                                ]
                            ]
                        ],
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['video'] = function($context, $idPrefix, $parentSelector) {
                        $group = $context->addGroup(__("bearcms.themes.options.Video"));
                        $group->addOption($idPrefix . "VideoCSS", "css", '', [
                            "cssTypes" => ["cssBorder", "cssRadius", "cssShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-video-element", "overflow:hidden;"],
                                ["selector", $parentSelector . " .bearcms-video-element"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_NAVIGATION')) {
                Internal\ElementsTypes::add('navigation', [
                    'componentSrc' => 'bearcms-navigation-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsNavigationElement.php',
                    'fields' => [
                        [
                            'id' => 'source',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'sourceParentPageID',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'showHomeLink',
                            'type' => 'checkbox'
                        ],
                        [
                            'id' => 'homeLinkText',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'itemsType',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'items',
                            'type' => 'textbox'
                        ]
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['navigation'] = function($context, $idPrefix, $parentSelector) {
                        $groupNavigation = $context->addGroup(__("bearcms.themes.options.Navigation"));
                        $groupNavigation->addOption($idPrefix . "NavigationCSS", "css", '', [
                            "cssTypes" => ["cssBorder", "cssBackground"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-navigation-element"]
                            ]
                        ]);

                        $groupElements = $groupNavigation->addGroup(__("bearcms.themes.options.Elements"));
                        $groupElements->addOption($idPrefix . "NavigationItemLinkCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-navigation-element-item a", "text-decoration:none;"],
                                ["selector", $parentSelector . " .bearcms-navigation-element-item a"]
                            ]
                        ]);

                        $groupElementsContainer = $groupElements->addGroup(__("bearcms.themes.options.Container"));
                        $groupElementsContainer->addOption($idPrefix . "NavigationItemLinkContainerCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-navigation-element-item", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-navigation-element-item"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_HTML')) {
                Internal\ElementsTypes::add('html', [
                    'componentSrc' => 'bearcms-html-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsHtmlElement.php',
                    'fields' => [
                        [
                            'id' => 'code',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'originalCode',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'renderMode',
                            'type' => 'textbox'
                        ]
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['html'] = function($context, $idPrefix, $parentSelector) {
                        $groupHTMLCode = $context->addGroup(__("bearcms.themes.options.HTML code"));
                        $groupHTMLCode->addOption($idPrefix . "HtmlCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-html-element ul,ol,li", "list-style-position:inside;"],
                                ["rule", $parentSelector . " .bearcms-html-element ul,ol,li,p,input", "margin:0;padding:0;"],
                                ["selector", $parentSelector . " .bearcms-html-element"]
                            ]
                        ]);

                        $groupLinks = $groupHTMLCode->addGroup(__("bearcms.themes.options.Links"));
                        $groupLinks->addOption($idPrefix . "HtmlLinkCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-html-element a", "text-decoration:none;"],
                                ["selector", $parentSelector . " .bearcms-html-element a"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_BLOG_POSTS')) {
                Internal\ElementsTypes::add('blogPosts', [
                    'componentSrc' => 'bearcms-blog-posts-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsBlogPostsElement.php',
                    'fields' => [
                        [
                            'id' => 'source',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'sourceCategoriesIDs',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'type',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'showDate',
                            'type' => 'checkbox'
                        ],
                        [
                            'id' => 'limit',
                            'type' => 'number'
                        ]
                    ]
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['blogPosts'] = function($context, $idPrefix, $parentSelector) {
                        $groupBlogPosts = $context->addGroup(__("bearcms.themes.options.Blog posts"));
                        $groupBlogPosts->addOption($idPrefix . "BlogPostsCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssBorder", "cssRadius", "cssShadow", "cssBackground"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-blog-posts-element"]
                            ]
                        ]);

                        $groupPost = $groupBlogPosts->addGroup(__("bearcms.themes.options.Post"));
                        $groupPost->addOption($idPrefix . "BlogPostsPostCSS", "css", '', [
                            "cssTypes" => ["cssBorder", "cssBackground", "cssShadow"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-post"]
                            ]
                        ]);

                        $groupPostTitle = $groupPost->addGroup(__("bearcms.themes.options.Title"));
                        $groupPostTitle->addOption($idPrefix . "BlogPostsPostTitleCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-blog-posts-element-post-title a", "text-decoration:none;"],
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-post-title"]
                            ]
                        ]);

                        $groupPostTitleContainer = $groupPostTitle->addGroup(__("bearcms.themes.options.Container"));
                        $groupPostTitleContainer->addOption($idPrefix . "BlogPostsPostTitleContainerCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-blog-posts-element-post-title-container", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-post-title-container"]
                            ]
                        ]);

                        $groupPostDate = $groupPost->addGroup(__("bearcms.themes.options.Date"));
                        $groupPostDate->addOption($idPrefix . "BlogPostsPostDateCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-post-date"]
                            ]
                        ]);

                        $groupPostDateContainer = $groupPostDate->addGroup(__("bearcms.themes.options.Container"));
                        $groupPostDateContainer->addOption($idPrefix . "BlogPostsPostDateContainerCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-blog-posts-element-post-date-container", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-post-date-container"]
                            ]
                        ]);

                        $groupPostContent = $groupPost->addGroup(__("bearcms.themes.options.Content"));
                        $groupPostContent->addOption($idPrefix . "BlogPostsPostContentCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-blog-posts-element-post-content", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-post-content"]
                            ]
                        ]);

                        $groupShowMoreButton = $groupBlogPosts->addGroup(__('bearcms.themes.options.blogPosts.Show more button'));
                        $groupShowMoreButton->addOption($idPrefix . "BlogPostsShowMoreButtonCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-blog-posts-element-show-more-button", "box-sizing:border-box;display:inline-block;text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;"],
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-show-more-button"]
                            ]
                        ]);

                        $groupShowMoreButtonContainer = $groupShowMoreButton->addGroup(__("bearcms.themes.options.Container"));
                        $groupShowMoreButtonContainer->addOption($idPrefix . "BlogPostsShowMoreButtonContainerCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-blog-posts-element-show-more-button-container", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-blog-posts-element-show-more-button-container"]
                            ]
                        ]);
                    };
                }
            }
            if ($hasElements || Config::hasFeature('ELEMENTS_COMMENTS')) {
                Internal\ElementsTypes::add('comments', [
                    'componentSrc' => 'bearcms-comments-element',
                    'componentFilename' => $this->context->dir . '/components/bearcmsCommentsElement.php',
                    'fields' => [
                        [
                            'id' => 'threadID',
                            'type' => 'textbox'
                        ],
                        [
                            'id' => 'count',
                            'type' => 'number'
                        ]
                    ],
                    'onDelete' => function($data) {
                        if (isset($data['threadID'])) {
                            $this->app->data->delete('bearcms/comments/thread/' . md5($data['threadID']) . '.json');
                        }
                    }
                ]);
                if ($hasThemes) {
                    Internal\Themes::$elementsOptions['comments'] = function($context, $idPrefix, $parentSelector) {
                        $groupComments = $context->addGroup(__("bearcms.themes.options.Comments"));

                        $groupComment = $groupComments->addGroup(__("bearcms.themes.options.comments.Comment"));
                        $groupComment->addOption($idPrefix . "CommentsCommentCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-comment", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-comments-comment"]
                            ]
                        ]);

                        $groupCommentAuthorName = $groupComment->addGroup(__("bearcms.themes.options.comments.Author name"));
                        $groupCommentAuthorName->addOption($idPrefix . "CommentsAuthorNameCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-comments-comment-author-name"]
                            ]
                        ]);

                        $groupCommentAuthorImage = $groupComment->addGroup(__("bearcms.themes.options.comments.Author image"));
                        $groupCommentAuthorImage->addOption($idPrefix . "CommentsAuthorImageCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-comment-author-image", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-comments-comment-author-image"]
                            ]
                        ]);

                        $groupCommentDate = $groupComment->addGroup(__("bearcms.themes.options.comments.Date"));
                        $groupCommentDate->addOption($idPrefix . "CommentsDateCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-comments-comment-date"]
                            ]
                        ]);

                        $groupCommentText = $groupComment->addGroup(__("bearcms.themes.options.comments.Text"));
                        $groupCommentText->addOption($idPrefix . "CommentsTextCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-comments-comment-text"]
                            ]
                        ]);

                        $groupCommentTextLinks = $groupComment->addGroup(__("bearcms.themes.options.comments.Text links"));
                        $groupCommentTextLinks->addOption($idPrefix . "CommentsTextLinksCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow"],
                            "cssOutput" => [
                                ["selector", $parentSelector . " .bearcms-comments-comment-text a"]
                            ]
                        ]);

                        $groupTextInput = $groupComments->addGroup(__("bearcms.themes.options.comments.Text input"));
                        $groupTextInput->addOption($idPrefix . "CommentsTextInputCSS", "css", '', [
                            "cssTypes" => ["cssText", "cssTextShadow", "cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-element-text-input", "box-sizing:border-box;border:0;margin:0;padding:0;"],
                                ["selector", $parentSelector . " .bearcms-comments-element-text-input"]
                            ]
                        ]);

                        $groupSendButton = $groupComments->addGroup(__("bearcms.themes.options.comments.Send button"));
                        $groupSendButton->addOption($idPrefix . "CommentsSendButtonCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-element-send-button", "box-sizing:border-box;display:inline-block;text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;"],
                                ["selector", $parentSelector . " .bearcms-comments-element-send-button"]
                            ]
                        ]);

                        $groupSendButtonWaiting = $groupSendButton->addGroup(__("bearcms.themes.options.comments.Send button waiting"));
                        $groupSendButtonWaiting->addOption($idPrefix . "CommentsSendButtonWaitingCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-element-send-button-waiting", "box-sizing:border-box;display:inline-block;text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;"],
                                ["selector", $parentSelector . " .bearcms-comments-element-send-button-waiting"]
                            ]
                        ]);

                        $groupShowMoreButton = $groupComments->addGroup(__("bearcms.themes.options.comments.Show more button"));
                        $groupShowMoreButton->addOption($idPrefix . "CommentsShowMoreButtonCSS", "css", '', [
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-show-more-button", "box-sizing:border-box;display:inline-block;text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;"],
                                ["selector", $parentSelector . " .bearcms-comments-show-more-button"]
                            ]
                        ]);

                        $groupShowMoreButtonContainer = $groupShowMoreButton->addGroup(__("bearcms.themes.options.comments.Container"));
                        $groupShowMoreButtonContainer->addOption($idPrefix . "CommentsShowMoreButtonContainerCSS", "css", '', [
                            "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                            "cssOutput" => [
                                ["rule", $parentSelector . " .bearcms-comments-show-more-button-container", "box-sizing:border-box;"],
                                ["selector", $parentSelector . " .bearcms-comments-show-more-button-container"]
                            ]
                        ]);
                    };
                }
            }

            $this->app->clientShortcuts
                    ->add('-bearcms-elements-lazy-load', function(IvoPetkov\BearFrameworkAddons\ClientShortcut $shortcut) {
                        $shortcut->requirements[] = [
                            'type' => 'file',
                            'url' => $this->context->assets->getURL('assets/elementsLazyLoad.min.js', ['cacheMaxAge' => 999999999, 'version' => 3]),
                            'mimeType' => 'text/javascript'
                        ];
                        $lazyLoadInitializeData = [];
                        $lazyLoadInitializeData[] = __('bearcms.elements.LoadingMore');
                        $shortcut->init = 'bearCMS.elementsLazyLoad.initialize(' . json_encode($lazyLoadInitializeData) . ');';
                    });
        }

        // Load the CMS managed addons
        if (Config::hasFeature('ADDONS')) {
            Internal\Data\Addons::addToApp();
        }

        // Register the system pages
        if ($hasServer) {
            if (Config::hasFeature('USERS') || Config::hasFeature('USERS_LOGIN_DEFAULT')) {
                $this->app->routes
                        ->add(Config::$adminPagesPathPrefix . 'loggedin/', function() {
                            return new App\Response\TemporaryRedirect($this->app->request->base . '/');
                        })
                        ->add([Config::$adminPagesPathPrefix, Config::$adminPagesPathPrefix . '*/'], function() {
                            return Internal\Controller::handleAdminPage();
                        })
                        ->add([rtrim(Config::$adminPagesPathPrefix, '/'), Config::$adminPagesPathPrefix . '*'], function() {
                            return new App\Response\PermanentRedirect($this->app->request->base . $this->app->request->path . '/');
                        });
            }
            if (Config::hasFeature('USERS') || Config::hasFeature('USERS_LOGIN_*')) {
                $this->app->routes
                        ->add('POST /-aj/', function() {
                            return Internal\Controller::handleAjax();
                        })
                        ->add('POST /-au/', function() {
                            return Internal\Controller::handleFileUpload();
                        });
            }
        }

        // Register the file handlers
        if (Config::hasFeature('FILES')) {
            $this->app->routes
                    ->add('/files/preview/*', function() {
                        return Internal\Controller::handleFilePreview();
                    })
                    ->add('/files/download/*', function() {
                        return Internal\Controller::handleFileDownload();
                    });
        }

        // Register some other pages
        $this->app->routes
                ->add('/rss.xml', [
                    [$this, 'disabledCheck'],
                    function() {
                        $settings = $this->app->bearCMS->data->settings->get();
                        if ($settings->enableRSS) {
                            return Internal\Controller::handleRSS();
                        }
                    }
                ])
                ->add('/sitemap.xml', [
                    [$this, 'disabledCheck'],
                    function() {
                        return Internal\Controller::handleSitemap();
                    }
                ])
                ->add('/robots.txt', [
                    [$this, 'disabledCheck'],
                    function() {
                        return Internal\Controller::handleRobots();
                    }
                ])
                ->add('/-link-rel-icon-*', [
                    [$this, 'disabledCheck'],
                    function() {
                        $size = str_replace('/-link-rel-icon-', '', (string) $this->app->request->path);
                        if (is_numeric($size)) {
                            $settings = $this->app->bearCMS->data->settings->get();
                            $icon = $settings->icon;
                            if (isset($icon{0})) {
                                $url = $this->app->assets->getURL($icon, ['cacheMaxAge' => 999999999, 'width' => (int) $size, 'height' => (int) $size]);
                                return new App\Response\TemporaryRedirect($url);
                            }
                        }
                    }
        ]);

        if (Config::hasFeature('COMMENTS')) {
            $this->app->serverRequests
                    ->add('bearcms-comments-load-more', function($data) {
                        if (isset($data['serverData'], $data['listElementID'], $data['listCommentsCount'])) {
                            $listElementID = (string) $data['listElementID'];
                            $listCommentsCount = (int) $data['listCommentsCount'];
                            $serverData = Internal\TempClientData::get($data['serverData']);
                            if (is_array($serverData) && isset($serverData['threadID'])) {
                                $threadID = $serverData['threadID'];
                                $listContent = $this->app->components->process('<component src="file:' . $this->context->dir . '/components/bearcmsCommentsElement/commentsList.php" count="' . htmlentities($listCommentsCount) . '" threadID="' . htmlentities($threadID) . '" />');
                                return json_encode([
                                    'listElementID' => $listElementID,
                                    'listContent' => $listContent
                                ]);
                            }
                        }
                    });
            $this->app->clientShortcuts
                    ->add('-bearcms-comments-element', function(IvoPetkov\BearFrameworkAddons\ClientShortcut $shortcut) {
                        $shortcut->requirements[] = [// taken from dev/commentsElement.js // file_get_contents(__DIR__ . '/../dev/commentsElement.js')
                            'type' => 'text',
                            'value' => 'var bearCMS=bearCMS||{};bearCMS.commentsElement=bearCMS.commentsElement||function(){var g=function(a){clientShortcuts.get("users").then(function(a){a.currentUser.exists()||a.openLogin()});return!1},f=function(a,d){clientShortcuts.get("-bearcms-html5domdocument").then(function(b){var c=document.getElementById(a.listElementID);b.insert(a.listContent,[c,"outerHTML"]);d()})},h=function(a){var d=a.target,b=a.result;"undefined"!==typeof b.noUser?(c(a),g()):"undefined"!==typeof b.success&&f(b,function(){c(a);d.reset()})},k=function(a){c(a)},l=function(a){a=a.target;a.querySelector(".bearcms-comments-element-send-button").style.display="none";a.querySelector(".bearcms-comments-element-send-button-waiting").style.removeProperty("display");a.querySelector(".bearcms-comments-element-text-input").setAttribute("readonly","readonly")},c=function(a){a=a.target;a.querySelector(".bearcms-comments-element-send-button").style.removeProperty("display");a.querySelector(".bearcms-comments-element-send-button-waiting").style.display="none";a.querySelector(".bearcms-comments-element-text-input").removeAttribute("readonly")};return{loadMore:function(a,d){a.target.innerHTML+=" ...";var b=a.target.parentNode.parentNode.id,c=parseInt(a.target.parentNode.parentNode.getAttribute("data-count"),10)+10,e=[];e.serverData=d.serverData;e.listElementID=b;e.listCommentsCount=c;clientShortcuts.get("serverRequests").then(function(a){a.send("bearcms-comments-load-more",e).then(function(a){a=JSON.parse(a);f(a,function(){})})})},onBeforeSubmitForm:function(a){var c=a.previousSibling.id,b=a.previousSibling.getAttribute("data-count");a.querySelector(\'input[type="hidden"]\').value=JSON.stringify({listElementID:c,listCommentsCount:b});"undefined"===typeof a.bearCMSCommentsEventsAttached&&(a.bearCMSCommentsEventsAttached=!0,a.addEventListener("submitstart",l),a.addEventListener("submitsuccess",h),a.addEventListener("submiterror",k))},onFocusTextarea:function(a){a=a.target.parentNode;"none"===a.querySelector(".bearcms-comments-element-send-button-waiting").style.display&&a.querySelector(".bearcms-comments-element-send-button").style.removeProperty("display")}}}();',
                            'mimeType' => 'text/javascript'
                        ];
                    });
        }

        if (Config::hasFeature('BLOG')) {
            $this->app->routes
                    ->add([Config::$blogPagesPathPrefix . '?', Config::$blogPagesPathPrefix . '?/'], [
                        [$this, 'disabledCheck'],
                        function() {
                            $slug = (string) $this->app->request->path->getSegment(1);
                            $slugsList = Internal\Data\BlogPosts::getSlugsList('published');
                            $blogPostID = array_search($slug, $slugsList);
                            if ($blogPostID === false && substr($slug, 0, 6) === 'draft-' && (Config::hasFeature('USERS') || Config::hasFeature('USERS_LOGIN_*')) && $this->currentUser->exists()) {
                                $blogPost = $this->app->bearCMS->data->blogPosts->get(substr($slug, 6));
                                if ($blogPost !== null) {
                                    if ($blogPost->status === 'published') {
                                        return new App\Response\PermanentRedirect($this->app->urls->get(Config::$blogPagesPathPrefix . $blogPost->slug . '/'));
                                    }
                                    $blogPostID = $blogPost->id;
                                }
                            }
                            if ($blogPostID !== false) {
                                $blogPost = $this->app->bearCMS->data->blogPosts->get($blogPostID);
                                if ($blogPost !== null) {
                                    $path = $this->app->request->path->get();
                                    $hasSlash = substr($path, -1) === '/';
                                    if (!$hasSlash) {
                                        return new App\Response\PermanentRedirect($this->app->request->base . $this->app->request->path . '/');
                                    }
                                    $content = '<html><head>';
                                    $title = isset($blogPost->titleTagContent) ? trim($blogPost->titleTagContent) : '';
                                    if (!isset($title{0})) {
                                        $title = isset($blogPost->title) ? trim($blogPost->title) : '';
                                    }
                                    $description = isset($blogPost->descriptionTagContent) ? trim($blogPost->descriptionTagContent) : '';
                                    $keywords = isset($blogPost->keywordsTagContent) ? trim($blogPost->keywordsTagContent) : '';
                                    if (isset($title{0})) {
                                        $content .= '<title>' . htmlspecialchars($title) . '</title>';
                                    }
                                    if (isset($description{0})) {
                                        $content .= '<meta name="description" content="' . htmlentities($description) . '"/>';
                                    }
                                    if (isset($keywords{0})) {
                                        $content .= '<meta name="keywords" content="' . htmlentities($keywords) . '"/>';
                                    }
                                    $content .= '<style>'
                                            . '.bearcms-blogpost-page-title-container{word-break:break-word;}'
                                            . '.bearcms-blogpost-page-content{word-break:break-word;}'
                                            . '</style>';
                                    $content .= '</head><body>';
                                    $content .= '<div class="bearcms-blogpost-page-title-container"><h1 class="bearcms-blogpost-page-title">' . htmlspecialchars($blogPost->title) . '</h1></div>';
                                    $content .= '<div class="bearcms-blogpost-page-date-container"><div class="bearcms-blogpost-page-date">' . ($blogPost->status === 'published' ? $this->app->localization->formatDate($blogPost->publishedTime, ['date']) : __('bearcms.blogPost.draft')) . '</div></div>';
                                    $content .= '<div class="bearcms-blogpost-page-content"><bearcms-elements id="bearcms-blogpost-' . $blogPostID . '"/></div>';
                                    $content .= '</body></html>';

                                    $response = new App\Response\HTML($content);
                                    if ($this->hasEventListeners('internalMakeBlogPostPageResponse')) {
                                        $eventDetails = new \BearCMS\Internal\MakeBlogPostPageResponseEventDetails($response, $blogPostID);
                                        $this->dispatchEvent('internalMakeBlogPostPageResponse', $eventDetails);
                                    }
                                    $this->apply($response);
                                    return $response;
                                }
                            }
                        }
            ]);
            $this->app->serverRequests
                    ->add('bearcms-blogposts-load-more', function($data) {
                        if (isset($data['serverData'], $data['serverData'])) {
                            $serverData = Internal\TempClientData::get($data['serverData']);
                            if (is_array($serverData) && isset($serverData['componentHTML'])) {
                                $content = $this->app->components->process($serverData['componentHTML']);
                                return json_encode([
                                    'content' => $content
                                ]);
                            }
                        }
                    });

            if (Config::hasFeature('THEMES')) {
                Internal\Themes::$pagesOptions['blog'] = function($context) {
                    $group = $context->addGroup(__("bearcms.themes.options.Blog post page"));

                    $groupTitle = $group->addGroup(__("bearcms.themes.options.Title"));
                    $groupTitle->addOption("blogPostPageTitleCSS", "css", '', [
                        "cssOutput" => [
                            ["rule", ".bearcms-blogpost-page-title", "box-sizing:border-box;font-weight:normal;padding:0;margin:0;"],
                            ["selector", ".bearcms-blogpost-page-title"]
                        ]
                    ]);

                    $groupTitleContainer = $groupTitle->addGroup(__("bearcms.themes.options.Container"));
                    $groupTitleContainer->addOption("blogPostPageTitleContainerCSS", "css", '', [
                        "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                        "cssOutput" => [
                            ["rule", ".bearcms-blogpost-page-title-container", "box-sizing:border-box;"],
                            ["selector", ".bearcms-blogpost-page-title-container"]
                        ]
                    ]);

                    $groupDate = $group->addGroup(__("bearcms.themes.options.Date"));
                    $groupDate->addOption("blogPostPageDateVisibility", "list", __('bearcms.themes.options.Visibility'), [
                        "values" => [
                            [
                                "value" => "1",
                                "name" => __('bearcms.themes.options.Visible')
                            ],
                            [
                                "value" => "0",
                                "name" => __('bearcms.themes.options.Hidden')
                            ]
                        ],
                        "value" => "1"
                    ]);
                    $groupDate->addOption("blogPostPageDateCSS", "css", '', [
                        "cssTypes" => ["cssText", "cssTextShadow"],
                        "cssOutput" => [
                            ["selector", ".bearcms-blogpost-page-date"]
                        ]
                    ]);


                    $groupDateContainer = $groupDate->addGroup(__("bearcms.themes.options.Container"));
                    $groupDateContainer->addOption("blogPostPageDateContainerCSS", "css", '', [
                        "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                        "cssOutput" => [
                            ["rule", ".bearcms-blogpost-page-date-container", "box-sizing:border-box;"],
                            ["selector", ".bearcms-blogpost-page-date-container"]
                        ]
                    ]);

                    $groupContent = $group->addGroup(__("bearcms.themes.options.Content"));
                    $groupContent->addOption("blogPostPageContentCSS", "css", '', [
                        "cssTypes" => ["cssPadding", "cssMargin", "cssBorder", "cssRadius", "cssShadow", "cssBackground", "cssSize"],
                        "cssOutput" => [
                            ["rule", ".bearcms-blogpost-page-content", "box-sizing:border-box;"],
                            ["selector", ".bearcms-blogpost-page-content"]
                        ]
                    ]);
                };
            }
            $this->app->clientShortcuts
                    ->add('-bearcms-blog-posts-element', function(IvoPetkov\BearFrameworkAddons\ClientShortcut $shortcut) {
                        $shortcut->requirements[] = [// taken from dev/blogPostsElement.js // file_get_contents(__DIR__ . '/../dev/blogPostsElement.js')
                            'type' => 'text',
                            'value' => 'var bearCMS=bearCMS||{};bearCMS.blogPostsElement=bearCMS.blogPostsElement||function(){var e=function(a,b){clientShortcuts.get("-bearcms-html5domdocument").then(function(c){c.insert(a,[b,"outerHTML"])})};return{loadMore:function(a,b){a.target.innerHTML+=" ...";var c=a.target.parentNode.parentNode.parentNode,d=[];d.serverData=b.serverData;clientShortcuts.get("serverRequests").then(function(a){a.send("bearcms-blogposts-load-more",d).then(function(a){a=JSON.parse(a);e(a.content,c)})})}}}();',
                            'mimeType' => 'text/javascript'
                        ];
                    });
        }

        // Register a home page and the dynamic pages handler
        if (Config::hasFeature('PAGES')) {
            $this->app->routes
                    ->add('*', [
                        [$this, 'disabledCheck'],
                        function() {
                            $path = $this->app->request->path->get();
                            if ($path === '/') {
                                if (Config::$autoCreateHomePage) {
                                    $pageID = 'home';
                                } else {
                                    $pageID = false;
                                }
                            } else {
                                $hasSlash = substr($path, -1) === '/';
                                $pathsList = Internal\Data\Pages::getPathsList((Config::hasFeature('USERS') || Config::hasFeature('USERS_LOGIN_*')) && $this->currentUser->exists() ? 'all' : 'published');
                                if ($hasSlash) {
                                    $pageID = array_search($path, $pathsList);
                                } else {
                                    $pageID = array_search($path . '/', $pathsList);
                                    if ($pageID !== false) {
                                        return new App\Response\PermanentRedirect($this->app->request->base . $this->app->request->path . '/');
                                    }
                                }
                            }
                            if ($pageID !== false) {
                                $response = $this->disabledCheck();
                                if ($response !== null) {
                                    return $response;
                                }
                                $found = false;
                                if ($pageID === 'home') {
                                    $settings = $this->app->bearCMS->data->settings->get();
                                    $title = trim($settings->title);
                                    $description = trim($settings->description);
                                    $keywords = trim($settings->keywords);
                                    $found = true;
                                } else {
                                    $page = $this->app->bearCMS->data->pages->get($pageID);
                                    if ($page !== null) {
                                        $title = isset($page->titleTagContent) ? trim($page->titleTagContent) : '';
                                        if (!isset($title{0})) {
                                            $title = isset($page->name) ? trim($page->name) : '';
                                        }
                                        $description = isset($page->descriptionTagContent) ? trim($page->descriptionTagContent) : '';
                                        $keywords = isset($page->keywordsTagContent) ? trim($page->keywordsTagContent) : '';
                                        $found = true;
                                    }
                                }
                                if ($found) {
                                    $content = '<html><head>';
                                    if (isset($title{0})) {
                                        $content .= '<title>' . htmlspecialchars($title) . '</title>';
                                    }
                                    if (isset($description{0})) {
                                        $content .= '<meta name="description" content="' . htmlentities($description) . '"/>';
                                    }
                                    if (isset($keywords{0})) {
                                        $content .= '<meta name="keywords" content="' . htmlentities($keywords) . '"/>';
                                    }
                                    $content .= '</head><body>';
                                    $content .= '<bearcms-elements id="bearcms-page-' . $pageID . '" editable="true"/>';
                                    $content .= '</body></html>';

                                    $response = new App\Response\HTML($content);
                                    if ($this->hasEventListeners('internalMakePageResponse')) {
                                        $eventDetails = new \BearCMS\Internal\MakePageResponseEventDetails($response, $pageID);
                                        $this->dispatchEvent('internalMakePageResponse', $eventDetails);
                                    }
                                    $this->apply($response);
                                    return $response;
                                }
                            }
                        }
            ]);
        }

        $this->app->assets
                ->addEventListener('prepare', function(\BearFramework\App\Assets\PrepareEventDetails $details) {
                    $filename = $details->filename;
                    $addonAssetsDir = $this->context->dir . '/assets/';
                    if (strpos($filename, $addonAssetsDir) === 0) {

                        $downloadUrl = function($url) {
                            $tempFileKey = '.temp/bearcms/urlassets/' . md5($url) . '.' . pathinfo($url, PATHINFO_EXTENSION);
                            $tempFilename = $this->app->data->getFilename($tempFileKey);
                            if ($this->app->data->exists($tempFileKey)) {
                                return $tempFilename;
                            } else {
                                $ch = curl_init();
                                curl_setopt($ch, CURLOPT_URL, $url);
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                                $response = curl_exec($ch);
                                $valid = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200 && strlen($response) > 0;
                                curl_close($ch);
                                if ($valid) {
                                    $this->app->data->set($this->app->data->make($tempFileKey, $response));
                                    return $tempFilename;
                                } else {
                                    throw new Exception('Cannot download file from URL (' . $url . ')');
                                }
                            }
                        };

                        // Proxy
                        $matchingDir = $addonAssetsDir . 'p/';
                        if (strpos($filename, $matchingDir) === 0) {
                            $details->returnValue = null;
                            $pathParts = explode('/', substr($filename, strlen($matchingDir)), 3);
                            if (isset($pathParts[0], $pathParts[1], $pathParts[2])) {
                                $url = $pathParts[0] . '://' . $pathParts[1] . '/' . str_replace('\\', '/', $pathParts[2]);
                                $details->returnValue = $downloadUrl($url);
                            }
                            return;
                        }

                        // Theme media file
                        $matchingDir = $addonAssetsDir . 'tm/';
                        if (strpos($filename, $matchingDir) === 0) {
                            $details->returnValue = null;
                            $pathParts = explode('/', substr($filename, strlen($matchingDir)), 2);
                            if (isset($pathParts[0], $pathParts[1])) {
                                $themeIDMD5 = $pathParts[0];
                                $mediaFilenameMD5 = $pathParts[1];
                                $themes = Internal\Themes::getIDs();
                                foreach ($themes as $id) {
                                    if ($themeIDMD5 === md5($id)) {
                                        $themeManifest = Internal\Themes::getManifest($id, false);
                                        if (isset($themeManifest['media'])) {
                                            foreach ($themeManifest['media'] as $i => $mediaItem) {
                                                if (isset($mediaItem['filename'])) {
                                                    if ($mediaFilenameMD5 === md5($mediaItem['filename']) . '.' . pathinfo($mediaItem['filename'], PATHINFO_EXTENSION)) {
                                                        $details->returnValue = $mediaItem['filename'];
                                                        return;
                                                    }
                                                }
                                            }
                                        }
                                        $themeStyles = Internal\Themes::getStyles($id, false);
                                        foreach ($themeStyles as $themeStyle) {
                                            if (isset($themeStyle['media'])) {
                                                foreach ($themeStyle['media'] as $i => $mediaItem) {
                                                    if (isset($mediaItem['filename'])) {
                                                        if ($mediaFilenameMD5 === md5($mediaItem['filename']) . '.' . pathinfo($mediaItem['filename'], PATHINFO_EXTENSION)) {
                                                            $details->returnValue = $mediaItem['filename'];
                                                            return;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            return;
                        }

                        // Download the server files
                        $matchingDir = $addonAssetsDir . 's/';
                        if (strpos($filename, $matchingDir) === 0) {
                            $details->returnValue = null;
                            $url = Config::$serverUrl . str_replace('\\', '/', substr($filename, strlen($matchingDir)));
                            $details->returnValue = $downloadUrl($url);
                        }
                    }
                });

        $this->app
                ->addEventListener('beforeSendResponse', function(\BearFramework\App\BeforeSendResponseEventDetails $details) {
                    if (strpos((string) $this->app->request->path, $this->app->assets->pathPrefix) !== 0) {
                        $response = $details->response;
                        if ($response instanceof App\Response\NotFound) {
                            $response->headers->set($response->headers->make('Content-Type', 'text/html'));
                            $this->apply($response);
                        } elseif ($response instanceof App\Response\TemporaryUnavailable) {
                            $response->headers->set($response->headers->make('Content-Type', 'text/html'));
                            $this->apply($response);
                        }
                    }
                });

        if (Config::hasFeature('THEMES') && Config::$addDefaultThemes) {
            $this->themes->addDefault();
        }

        if ($hasServer && (Config::hasFeature('USERS') || Config::hasFeature('USERS_LOGIN_*'))) {
            if (Config::$useDefaultUserProfile) {
                $this->app->users
                        ->addProvider('bearcms', Internal\UserProvider::class);

                if ($this->currentUser->exists()) {
                    if (!$this->app->currentUser->exists()) {
                        $this->app->currentUser->login('bearcms', $this->currentUser->getID());
                    }
                } else {
                    if ($this->app->currentUser->exists()) {
                        if ($this->app->currentUser->provider === 'bearcms') {
                            $this->app->currentUser->logout();
                        }
                    }
                }
            }
            $this->app
                    ->addEventListener('beforeSendResponse', function(\BearFramework\App\BeforeSendResponseEventDetails $details) {
                        Internal\Cookies::apply($details->response);
                    });
        }


        if (Config::hasFeature('NOTIFICATIONS')) {
            $this->app->tasks
                    ->define('bearcms-send-new-comment-notification', function($data) {
                        $threadID = $data['threadID'];
                        $commentID = $data['commentID'];
                        $comments = Internal2::$data2->comments->getList()
                                ->filterBy('threadID', $threadID)
                                ->filterBy('id', $commentID);
                        if (isset($comments[0])) {
                            $comment = $comments[0];
                            $comments = Internal2::$data2->comments->getList()
                                    ->filterBy('status', 'pendingApproval');
                            $pendingApprovalCount = $comments->count();
                            $profile = Internal\PublicProfile::getFromAuthor($comment->author);
                            Internal\Data::sendNotification('comments', $comment->status, $profile->name, $comment->text, $pendingApprovalCount);
                        }
                    });
        }

        // Initialize to add asset dirs
        $currentThemeID = Internal\CurrentTheme::getID();
        Internal\Themes::initialize($currentThemeID);

        Config::$initialized = true;
    }
842661
public function initialize(array $config)
    {
        $config += $this->_defaultConfig;
        $this->config('fields', $this->_resolveFields($config['fields']));
        $this->config('strategy', $this->_resolveStrategy($config['strategy']));
    }
742189
protected function configure(array $config)
    {
        $this->width = $config['width'] ?? null;
        $this->height = $config['height'] ?? null;
        $this->position = $config['position'] ?? 'center';
        $this->interlace = $config['interlace'] ?? true;
    }
510153
public function initialize(array $config)
    {
        $this->_controller = $this->_registry->getController();
        $this->_request    = $this->_controller->request;

        parent::initialize($config);
    }
1325038
public function put(array $config)
    {
        foreach ($config as $key => $value) {
            $this->set($key, $value);
        }

        return $this;
    }