├── .editorconfig
├── LICENSE
├── src
├── Sources
│ └── LightPortal
│ │ ├── .editorconfig
│ │ ├── .meta-storm.xml
│ │ ├── Actions
│ │ ├── AbstractPageList.php
│ │ ├── ActionInterface.php
│ │ ├── Block.php
│ │ ├── BoardIndex.php
│ │ ├── CardList.php
│ │ ├── CardListInterface.php
│ │ ├── Category.php
│ │ ├── Comment.php
│ │ ├── FrontPage.php
│ │ ├── Page.php
│ │ ├── PageListInterface.php
│ │ ├── Tag.php
│ │ └── index.php
│ │ ├── Areas
│ │ ├── BlockArea.php
│ │ ├── CategoryArea.php
│ │ ├── ConfigArea.php
│ │ ├── Configs
│ │ │ ├── AbstractConfig.php
│ │ │ ├── BasicConfig.php
│ │ │ ├── ExtraConfig.php
│ │ │ ├── FeedbackConfig.php
│ │ │ ├── MiscConfig.php
│ │ │ ├── PanelConfig.php
│ │ │ ├── VarFactory.php
│ │ │ └── index.php
│ │ ├── CreditArea.php
│ │ ├── Exports
│ │ │ ├── AbstractExport.php
│ │ │ ├── BlockExport.php
│ │ │ ├── CategoryExport.php
│ │ │ ├── ExportInterface.php
│ │ │ ├── PageExport.php
│ │ │ ├── PluginExport.php
│ │ │ ├── TagExport.php
│ │ │ └── index.php
│ │ ├── Imports
│ │ │ ├── AbstractCustomBlockImport.php
│ │ │ ├── AbstractCustomCategoryImport.php
│ │ │ ├── AbstractCustomImport.php
│ │ │ ├── AbstractCustomPageImport.php
│ │ │ ├── AbstractImport.php
│ │ │ ├── BlockImport.php
│ │ │ ├── CategoryImport.php
│ │ │ ├── CustomImportInterface.php
│ │ │ ├── ImportInterface.php
│ │ │ ├── PageImport.php
│ │ │ ├── PluginImport.php
│ │ │ ├── TagImport.php
│ │ │ ├── Traits
│ │ │ │ ├── CanInsertDataTrait.php
│ │ │ │ ├── HasComments.php
│ │ │ │ ├── HasParams.php
│ │ │ │ ├── HasTitles.php
│ │ │ │ ├── HasTransactions.php
│ │ │ │ └── index.php
│ │ │ └── index.php
│ │ ├── PageArea.php
│ │ ├── PluginArea.php
│ │ ├── TagArea.php
│ │ ├── Traits
│ │ │ ├── HasArea.php
│ │ │ ├── HasQuery.php
│ │ │ └── index.php
│ │ └── index.php
│ │ ├── Articles
│ │ ├── AbstractArticle.php
│ │ ├── ArticleInterface.php
│ │ ├── BoardArticle.php
│ │ ├── ChosenPageArticle.php
│ │ ├── ChosenTopicArticle.php
│ │ ├── PageArticle.php
│ │ ├── TopicArticle.php
│ │ └── index.php
│ │ ├── Container.php
│ │ ├── Enums
│ │ ├── Action.php
│ │ ├── AlertAction.php
│ │ ├── ContentClass.php
│ │ ├── ContentType.php
│ │ ├── EntryType.php
│ │ ├── Hook.php
│ │ ├── Permission.php
│ │ ├── Placement.php
│ │ ├── PluginType.php
│ │ ├── PortalHook.php
│ │ ├── PortalSubAction.php
│ │ ├── Status.php
│ │ ├── Tab.php
│ │ ├── TitleClass.php
│ │ ├── Traits
│ │ │ ├── HasHtml.php
│ │ │ ├── HasNames.php
│ │ │ ├── HasValues.php
│ │ │ └── index.php
│ │ ├── VarType.php
│ │ └── index.php
│ │ ├── Events
│ │ ├── EventManager.php
│ │ ├── EventManagerFactory.php
│ │ ├── HasEvents.php
│ │ └── index.php
│ │ ├── Hooks
│ │ ├── Actions.php
│ │ ├── AlertTypes.php
│ │ ├── BuildRoute.php
│ │ ├── CurrentAction.php
│ │ ├── DefaultAction.php
│ │ ├── DeleteMembers.php
│ │ ├── DisplayButtons.php
│ │ ├── DownloadRequest.php
│ │ ├── FetchAlerts.php
│ │ ├── HasCommonChecks.php
│ │ ├── Init.php
│ │ ├── LoadIllegalGuestPermissions.php
│ │ ├── LoadPermissions.php
│ │ ├── LoadTheme.php
│ │ ├── MenuButtons.php
│ │ ├── PermissionsList.php
│ │ ├── PreCssOutput.php
│ │ ├── ProfileAreas.php
│ │ ├── ProfilePopup.php
│ │ ├── Redirect.php
│ │ ├── RouteParsers.php
│ │ ├── WhosOnline.php
│ │ └── index.php
│ │ ├── Integration.php
│ │ ├── Lists
│ │ ├── CategoryList.php
│ │ ├── IconList.php
│ │ ├── ListInterface.php
│ │ ├── PageList.php
│ │ ├── PluginList.php
│ │ ├── TagList.php
│ │ └── index.php
│ │ ├── Models
│ │ ├── AbstractFactory.php
│ │ ├── AbstractModel.php
│ │ ├── BlockFactory.php
│ │ ├── BlockModel.php
│ │ ├── CategoryFactory.php
│ │ ├── CategoryModel.php
│ │ ├── FactoryInterface.php
│ │ ├── ModelInterface.php
│ │ ├── PageFactory.php
│ │ ├── PageModel.php
│ │ ├── TagFactory.php
│ │ ├── TagModel.php
│ │ └── index.php
│ │ ├── Plugins
│ │ ├── AdsBlock
│ │ │ ├── AdsBlock.php
│ │ │ ├── Hooks
│ │ │ │ ├── DisplayButtons.php
│ │ │ │ ├── MenuButtons.php
│ │ │ │ ├── MessageindexButtons.php
│ │ │ │ ├── PrepareDisplayContext.php
│ │ │ │ └── index.php
│ │ │ ├── Placement.php
│ │ │ ├── PlacementSelect.php
│ │ │ ├── RepliesComparisonTrait.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── template.php
│ │ ├── ApexCharts
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── ArticleList
│ │ │ ├── ArticleList.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── AssetHandler.php
│ │ ├── Block.php
│ │ ├── BlogMode
│ │ │ ├── BlogArticle.php
│ │ │ ├── BlogIndex.php
│ │ │ ├── BlogMode.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── BoardList
│ │ │ ├── BoardList.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── BoardNews
│ │ │ ├── BoardNews.php
│ │ │ ├── CustomSelectField.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── BoardStats
│ │ │ ├── BoardStats.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── BootstrapIcons
│ │ │ ├── BootstrapIcons.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── Calculator
│ │ │ ├── Calculator.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── script.js
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── CategoryList
│ │ │ ├── CategoryList.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Chart
│ │ │ ├── Chart.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── template.php
│ │ ├── ChessBoard
│ │ │ ├── ChessBoard.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── script.js
│ │ ├── CodeMirror
│ │ │ ├── CodeMirror.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── ConfigHandler.php
│ │ ├── CurrentMonth
│ │ │ ├── CurrentMonth.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── CustomTranslate
│ │ │ ├── CustomTranslate.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── script.js
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── DiceBear
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Disqus
│ │ │ ├── Disqus.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Dragula
│ │ │ ├── Dragula.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── script.js
│ │ │ └── style.css
│ │ ├── DummyArticleCards
│ │ │ ├── DummyArticle.php
│ │ │ ├── DummyArticleCards.php
│ │ │ ├── Lorem.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── EasyMarkdownEditor
│ │ │ ├── EasyMarkdownEditor.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── EhPortalMigration
│ │ │ ├── BlockImport.php
│ │ │ ├── CategoryImport.php
│ │ │ ├── EhPortalMigration.php
│ │ │ ├── PageImport.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Event.php
│ │ ├── Events
│ │ │ ├── Events.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── ExtendedMetaTags
│ │ │ ├── ExtendedMetaTags.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── EzPortalMigration
│ │ │ ├── BlockImport.php
│ │ │ ├── EzPortalMigration.php
│ │ │ ├── PageImport.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── FaBoardIcons
│ │ │ ├── FaBoardIcons.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── FacebookComments
│ │ │ ├── FacebookComments.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── GalleryBlock
│ │ │ ├── CategorySelect.php
│ │ │ ├── GalleryBlock.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── Giscus
│ │ │ ├── Giscus.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── HelloPortal
│ │ │ ├── HelloPortal.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── steps.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── HidingBlocks
│ │ │ ├── BreakpointSelect.php
│ │ │ ├── HidingBlocks.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── ImageUpload
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── IndexNow
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Jodit
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── LangHandler.php
│ │ ├── LanguageAccess
│ │ │ ├── LanguageAccess.php
│ │ │ ├── LanguageSelect.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── LatteLayouts
│ │ │ ├── LatteLayouts.php
│ │ │ ├── LatteRenderer.php
│ │ │ ├── composer.json
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── layouts
│ │ │ │ ├── alt.latte
│ │ │ │ ├── alt2.latte
│ │ │ │ ├── default.latte
│ │ │ │ ├── example.latte
│ │ │ │ ├── flarum.latte
│ │ │ │ ├── index.php
│ │ │ │ ├── simple.latte
│ │ │ │ ├── simple2.latte
│ │ │ │ ├── simple3.latte
│ │ │ │ └── spectre.latte
│ │ ├── Likely
│ │ │ ├── ButtonSelect.php
│ │ │ ├── Likely.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── LineAwesomeIcons
│ │ │ ├── LineAwesomeIcons.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── MainIcons
│ │ │ ├── MainIcons.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── MainMenu
│ │ │ ├── MainMenu.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── template.php
│ │ ├── Markdown
│ │ │ ├── Markdown.php
│ │ │ ├── SMF
│ │ │ │ ├── BlockQuoteRenderer.php
│ │ │ │ ├── FencedCodeRenderer.php
│ │ │ │ ├── HeadingRenderer.php
│ │ │ │ ├── ImageRenderer.php
│ │ │ │ ├── LinkRenderer.php
│ │ │ │ ├── ListBlockRenderer.php
│ │ │ │ ├── ListItemRenderer.php
│ │ │ │ ├── TableRenderer.php
│ │ │ │ ├── TableRowRenderer.php
│ │ │ │ └── index.php
│ │ │ ├── composer.json
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── MaterialDesignIcons
│ │ │ ├── MaterialDesignIcons.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── MediaBlock
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── News
│ │ │ ├── News.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Optimus
│ │ │ ├── Optimus.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── PageList
│ │ │ ├── PageList.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── PageScroll
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Plugin.php
│ │ ├── PluginHandler.php
│ │ ├── PluginInterface.php
│ │ ├── PluginMaker
│ │ │ ├── Builder.php
│ │ │ ├── Generator.php
│ │ │ ├── Handler.php
│ │ │ ├── License.php
│ │ │ ├── PluginMaker.php
│ │ │ ├── Validator.php
│ │ │ ├── composer.json
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── template.php
│ │ ├── Polls
│ │ │ ├── Polls.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── PrettyUrls
│ │ │ ├── PrettyUrls.php
│ │ │ ├── functions.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── RandomPages
│ │ │ ├── RandomPages.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── RandomTopics
│ │ │ ├── RandomTopics.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── Reactions
│ │ │ ├── Reactions.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── RecentAttachments
│ │ │ ├── RecentAttachments.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── RecentComments
│ │ │ ├── RecentComments.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── RecentPosts
│ │ │ ├── RecentPosts.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── RecentTopics
│ │ │ ├── RecentTopics.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── Search
│ │ │ ├── Search.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── SimpleChat
│ │ │ ├── Chat.php
│ │ │ ├── SimpleChat.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── script.js
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── SimpleFeeder
│ │ │ ├── SimpleFeeder.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── SimpleMenu
│ │ │ ├── SimpleMenu.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── template.php
│ │ ├── SiteList
│ │ │ ├── SiteArticle.php
│ │ │ ├── SiteList.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── template.php
│ │ ├── Snowflakes
│ │ │ ├── Snowflakes.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Swiper
│ │ │ ├── Swiper.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── TagList
│ │ │ ├── DecoratorPluginManager.php
│ │ │ ├── TagCloud.php
│ │ │ ├── TagList.php
│ │ │ ├── composer.json
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── ThemeSwitcher
│ │ │ ├── ThemeSwitcher.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── TinyMCE
│ │ │ ├── TinyMCE.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── TinyPortalMigration
│ │ │ ├── BlockImport.php
│ │ │ ├── CategoryImport.php
│ │ │ ├── PageImport.php
│ │ │ ├── TinyPortalMigration.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── TinySlider
│ │ │ ├── TinySlider.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── TopBoards
│ │ │ ├── TopBoards.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── TopPages
│ │ │ ├── TopPages.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── TopPosters
│ │ │ ├── TopPosters.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── TopTopics
│ │ │ ├── TopTopics.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── TopicRatingBar
│ │ │ ├── TopicRatingBar.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── Translator
│ │ │ ├── Translator.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ ├── TrendingTopics
│ │ │ ├── TrendingTopics.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── TwentyFortyEight
│ │ │ ├── TwentyFortyEight.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── script.js
│ │ │ └── style.css
│ │ ├── TwigLayouts
│ │ │ ├── TwigLayouts.php
│ │ │ ├── TwigRenderer.php
│ │ │ ├── composer.json
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── layouts
│ │ │ │ ├── default.twig
│ │ │ │ ├── example.twig
│ │ │ │ └── index.php
│ │ ├── Uicons
│ │ │ ├── Uicons.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── UserInfo
│ │ │ ├── UserInfo.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ ├── style.css
│ │ │ └── template.php
│ │ ├── VkComments
│ │ │ ├── VkComments.php
│ │ │ ├── index.php
│ │ │ ├── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ │ └── style.css
│ │ ├── WhosOnline
│ │ │ ├── WhosOnline.php
│ │ │ ├── index.php
│ │ │ └── langs
│ │ │ │ ├── english.php
│ │ │ │ └── index.php
│ │ └── index.php
│ │ ├── PortalApp.php
│ │ ├── Renderers
│ │ ├── AbstractRenderer.php
│ │ ├── Blade.php
│ │ ├── PurePHP.php
│ │ ├── RendererInterface.php
│ │ └── index.php
│ │ ├── Repositories
│ │ ├── AbstractRepository.php
│ │ ├── BlockRepository.php
│ │ ├── CategoryRepository.php
│ │ ├── CommentRepository.php
│ │ ├── PageRepository.php
│ │ ├── PluginRepository.php
│ │ ├── TagRepository.php
│ │ └── index.php
│ │ ├── Routes
│ │ ├── Forum.php
│ │ ├── Page.php
│ │ ├── Portal.php
│ │ └── index.php
│ │ ├── ServiceProvider.php
│ │ ├── Tasks
│ │ ├── Maintainer.php
│ │ ├── Notifier.php
│ │ └── index.php
│ │ ├── UI
│ │ ├── Fields
│ │ │ ├── AbstractField.php
│ │ │ ├── CheckboxField.php
│ │ │ ├── ColorField.php
│ │ │ ├── CustomField.php
│ │ │ ├── InputField.php
│ │ │ ├── NumberField.php
│ │ │ ├── RadioField.php
│ │ │ ├── RangeField.php
│ │ │ ├── SelectField.php
│ │ │ ├── TextField.php
│ │ │ ├── TextareaField.php
│ │ │ ├── UrlField.php
│ │ │ ├── VirtualSelectField.php
│ │ │ └── index.php
│ │ ├── Partials
│ │ │ ├── AbstractPartial.php
│ │ │ ├── ActionSelect.php
│ │ │ ├── AreaSelect.php
│ │ │ ├── BoardSelect.php
│ │ │ ├── CategorySelect.php
│ │ │ ├── ContentClassSelect.php
│ │ │ ├── EntryTypeSelect.php
│ │ │ ├── IconSelect.php
│ │ │ ├── PageIconSelect.php
│ │ │ ├── PageSelect.php
│ │ │ ├── PageSlugSelect.php
│ │ │ ├── PermissionSelect.php
│ │ │ ├── PlacementSelect.php
│ │ │ ├── StatusSelect.php
│ │ │ ├── TagSelect.php
│ │ │ ├── TitleClassSelect.php
│ │ │ ├── TopicSelect.php
│ │ │ └── index.php
│ │ ├── Tables
│ │ │ ├── Button.php
│ │ │ ├── CheckboxColumn.php
│ │ │ ├── ContextMenuColumn.php
│ │ │ ├── ExportButtonsRow.php
│ │ │ ├── HiddenInput.php
│ │ │ ├── IconButton.php
│ │ │ ├── IconColumn.php
│ │ │ ├── ImportButtonsRow.php
│ │ │ ├── Link.php
│ │ │ ├── NumViewsColumn.php
│ │ │ ├── PageButtonsRow.php
│ │ │ ├── PageContextMenuColumn.php
│ │ │ ├── PageSearchRow.php
│ │ │ ├── PageSlugColumn.php
│ │ │ ├── PageStatusColumn.php
│ │ │ ├── PageTypeSelectRow.php
│ │ │ ├── PortalTableBuilder.php
│ │ │ ├── PortalTableBuilderInterface.php
│ │ │ ├── StatusColumn.php
│ │ │ ├── TableRenderer.php
│ │ │ ├── TitleColumn.php
│ │ │ └── index.php
│ │ └── index.php
│ │ ├── Utils
│ │ ├── Avatar.php
│ │ ├── Breadcrumbs.php
│ │ ├── Cache.php
│ │ ├── CacheInterface.php
│ │ ├── Content.php
│ │ ├── DateTime.php
│ │ ├── Editor.php
│ │ ├── File.php
│ │ ├── GlobalArray.php
│ │ ├── Icon.php
│ │ ├── Language.php
│ │ ├── MessageIndex.php
│ │ ├── Notify.php
│ │ ├── ParamWrapper.php
│ │ ├── Post.php
│ │ ├── Request.php
│ │ ├── Response.php
│ │ ├── Session.php
│ │ ├── SessionManager.php
│ │ ├── Setting.php
│ │ ├── Str.php
│ │ ├── Traits
│ │ │ ├── HasBreadcrumbs.php
│ │ │ ├── HasCache.php
│ │ │ ├── HasForumHooks.php
│ │ │ ├── HasReflection.php
│ │ │ ├── HasRequest.php
│ │ │ ├── HasResponse.php
│ │ │ ├── HasSession.php
│ │ │ ├── HasTemplate.php
│ │ │ ├── HasThemes.php
│ │ │ └── index.php
│ │ ├── Weaver.php
│ │ └── index.php
│ │ ├── Validators
│ │ ├── AbstractValidator.php
│ │ ├── BlockValidator.php
│ │ ├── CategoryValidator.php
│ │ ├── PageValidator.php
│ │ ├── TagValidator.php
│ │ ├── ValidatorInterface.php
│ │ └── index.php
│ │ ├── app.php
│ │ ├── composer.json
│ │ ├── create_index.php
│ │ ├── index.php
│ │ └── update_plugins.php
├── Themes
│ └── default
│ │ ├── LightPortal
│ │ ├── .editorconfig
│ │ ├── ManageBlocks.template.php
│ │ ├── ManageCategories.template.php
│ │ ├── ManageFeedback.template.php
│ │ ├── ManageImpex.template.php
│ │ ├── ManagePages.template.php
│ │ ├── ManagePanels.template.php
│ │ ├── ManagePlugins.template.php
│ │ ├── ManageSettings.template.php
│ │ ├── ManageTags.template.php
│ │ ├── ViewBlocks.template.php
│ │ ├── ViewCredits.template.php
│ │ ├── ViewDebug.template.php
│ │ ├── ViewFrontPage.template.php
│ │ ├── ViewPage.template.php
│ │ ├── index.php
│ │ └── layouts
│ │ │ ├── alt.blade.php
│ │ │ ├── alt2.blade.php
│ │ │ ├── alt3.blade.php
│ │ │ ├── debug.blade.php
│ │ │ ├── default.blade.php
│ │ │ ├── featured_grid.blade.php
│ │ │ ├── flarum.blade.php
│ │ │ ├── index.php
│ │ │ ├── partials
│ │ │ ├── base.blade.php
│ │ │ ├── card-footer.blade.php
│ │ │ ├── card-header.blade.php
│ │ │ ├── card.blade.php
│ │ │ ├── image.blade.php
│ │ │ ├── index.php
│ │ │ └── pagination.blade.php
│ │ │ ├── simple.blade.php
│ │ │ ├── simple2.blade.php
│ │ │ ├── simple3.blade.php
│ │ │ ├── simple_grid.blade.php
│ │ │ └── spectre.blade.php
│ │ ├── css
│ │ └── light_portal
│ │ │ ├── flexboxgrid.css
│ │ │ └── index.php
│ │ ├── languages
│ │ └── LightPortal
│ │ │ ├── LightPortal.english.php
│ │ │ └── index.php
│ │ └── scripts
│ │ └── light_portal
│ │ ├── index.php
│ │ └── portal.js
├── database.php
├── package-info.xml
├── portal.php
├── uninstall-optional.php
└── uninstall.php
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | indent_style = tab
7 | indent_size = tab
8 | tab_width = 4
9 | trim_trailing_whitespace = true
10 | charset = utf-8
11 |
12 | [*.{js,css,json}]
13 | indent_style = space
14 | indent_size = 2
--------------------------------------------------------------------------------
/src/Sources/LightPortal/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | indent_style = tab
7 | indent_size = tab
8 | tab_width = 4
9 | trim_trailing_whitespace = true
10 | charset = utf-8
11 |
12 | [*.{js,css,json}]
13 | indent_style = space
14 | indent_size = 2
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Actions/ActionInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Actions;
14 |
15 | interface ActionInterface
16 | {
17 | public function show(): void;
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Actions/BoardIndex.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Actions;
14 |
15 | use Bugo\Compat\Actions\BoardIndex as Index;
16 |
17 | if (! defined('SMF'))
18 | die('No direct access...');
19 |
20 | final class BoardIndex implements ActionInterface
21 | {
22 | public function show(): void
23 | {
24 | Index::call();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Actions/CardListInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Actions;
14 |
15 | use Bugo\Bricks\Tables\Interfaces\TableBuilderInterface;
16 |
17 | interface CardListInterface
18 | {
19 | public function show(PageListInterface $entity): void;
20 |
21 | public function getOrderBy(): string;
22 |
23 | public function getBuilder(string $id): TableBuilderInterface;
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Actions/PageListInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Actions;
14 |
15 | interface PageListInterface extends ActionInterface
16 | {
17 | public function showAll();
18 |
19 | public function getPages(int $start, int $limit, string $sort): array;
20 |
21 | public function getTotalPages(): int;
22 | }
23 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Actions/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Areas\Exports;
14 |
15 | interface ExportInterface
16 | {
17 | public function main();
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Areas/Exports/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Areas\Imports;
14 |
15 | interface CustomImportInterface
16 | {
17 | public function getAll(int $start, int $limit, string $sort): array;
18 |
19 | public function getTotalCount(): int;
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Areas/Imports/ImportInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Areas\Imports;
14 |
15 | interface ImportInterface
16 | {
17 | public function main();
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Areas/Imports/Traits/HasComments.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Areas\Imports\Traits;
14 |
15 | trait HasComments
16 | {
17 | protected function replaceComments(array $comments, array &$results): void
18 | {
19 | if ($comments === [] || $results === [])
20 | return;
21 |
22 | $results = $this->insertData(
23 | 'lp_comments',
24 | 'replace',
25 | $comments,
26 | [
27 | 'id' => 'int',
28 | 'parent_id' => 'int',
29 | 'page_id' => 'int',
30 | 'author_id' => 'int',
31 | 'message' => 'string',
32 | 'created_at' => 'int',
33 | ],
34 | ['id', 'page_id'],
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Areas/Imports/Traits/HasParams.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Areas\Imports\Traits;
14 |
15 | trait HasParams
16 | {
17 | protected function replaceParams(array $params, array &$results): void
18 | {
19 | if ($params === [] || $results === [])
20 | return;
21 |
22 | $results = $this->insertData(
23 | 'lp_params',
24 | 'replace',
25 | $params,
26 | [
27 | 'item_id' => 'int',
28 | 'type' => 'string',
29 | 'name' => 'string',
30 | 'value' => 'string',
31 | ],
32 | ['item_id', 'type', 'name'],
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Areas/Imports/Traits/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Articles;
14 |
15 | use Bugo\LightPortal\Events\HasEvents;
16 |
17 | if (! defined('SMF'))
18 | die('No direct access...');
19 |
20 | abstract class AbstractArticle implements ArticleInterface
21 | {
22 | use HasEvents;
23 |
24 | protected array $columns = [];
25 |
26 | protected array $tables = [];
27 |
28 | protected array $wheres = [];
29 |
30 | protected array $params = [];
31 |
32 | protected array $orders = [];
33 |
34 | abstract public function init(): void;
35 |
36 | abstract public function getData(int $start, int $limit): array;
37 |
38 | abstract public function getTotalCount(): int;
39 | }
40 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Articles/ArticleInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Articles;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | interface ArticleInterface
19 | {
20 | public function init(): void;
21 |
22 | public function getData(int $start, int $limit): array;
23 |
24 | public function getTotalCount(): int;
25 | }
26 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Articles/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | enum Action: string
16 | {
17 | case FORUM = 'forum';
18 | case HOME = 'home';
19 | case PAGES = 'pages';
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/AlertAction.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\LightPortal\Enums\Traits\HasNames;
16 |
17 | enum AlertAction
18 | {
19 | use HasNames;
20 |
21 | case PAGE_COMMENT;
22 | case PAGE_COMMENT_REPLY;
23 | case PAGE_UNAPPROVED;
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/EntryType.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\Compat\Lang;
16 | use Bugo\LightPortal\Enums\Traits\HasNames;
17 |
18 | use function array_combine;
19 | use function array_filter;
20 |
21 | enum EntryType
22 | {
23 | use HasNames;
24 |
25 | case DEFAULT;
26 | case INTERNAL;
27 | case DRAFT;
28 |
29 | public static function all(): array
30 | {
31 | return array_combine(self::names(), Lang::$txt['lp_page_type_set']);
32 | }
33 |
34 | public static function withoutDrafts(): array
35 | {
36 | return array_filter(self::names(), fn($item) => $item !== self::DRAFT->name());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Placement.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\Compat\Lang;
16 | use Bugo\LightPortal\Enums\Traits\HasNames;
17 |
18 | use function array_combine;
19 |
20 | enum Placement
21 | {
22 | use HasNames;
23 |
24 | case HEADER;
25 | case TOP;
26 | case LEFT;
27 | case RIGHT;
28 | case BOTTOM;
29 | case FOOTER;
30 |
31 | public static function all(): array
32 | {
33 | return array_combine(self::names(), Lang::$txt['lp_block_placement_set']);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/PluginType.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\Compat\Lang;
16 | use Bugo\LightPortal\Enums\Traits\HasNames;
17 |
18 | use function array_combine;
19 |
20 | enum PluginType
21 | {
22 | use HasNames;
23 |
24 | case BLOCK;
25 | case SSI;
26 | case EDITOR;
27 | case COMMENT;
28 | case PARSER;
29 | case ARTICLE;
30 | case FRONTPAGE;
31 | case IMPEX;
32 | case BLOCK_OPTIONS;
33 | case PAGE_OPTIONS;
34 | case ICONS;
35 | case SEO;
36 | case OTHER;
37 |
38 | public static function all(): array
39 | {
40 | return array_combine(self::names(), Lang::$txt['lp_plugins_types']);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/PortalSubAction.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\LightPortal\Enums\Traits\HasNames;
16 |
17 | use const LP_BASE_URL;
18 |
19 | enum PortalSubAction
20 | {
21 | use HasNames;
22 |
23 | case CATEGORIES;
24 | case TAGS;
25 | case PROMOTE;
26 |
27 | public function url(): string
28 | {
29 | return LP_BASE_URL . ';sa=' . $this->name();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Status.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\LightPortal\Enums\Traits\HasValues;
16 |
17 | enum Status: int
18 | {
19 | use HasValues;
20 |
21 | case INACTIVE = 0;
22 | case ACTIVE = 1;
23 | case UNAPPROVED = 2;
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Tab.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums;
14 |
15 | use Bugo\LightPortal\Enums\Traits\HasNames;
16 |
17 | enum Tab
18 | {
19 | use HasNames;
20 |
21 | case CONTENT;
22 | case ACCESS_PLACEMENT;
23 | case APPEARANCE;
24 | case SEO;
25 | case TUNING;
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Traits/HasHtml.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums\Traits;
14 |
15 | use function array_combine;
16 | use function array_key_first;
17 | use function array_map;
18 | use function sprintf;
19 |
20 | trait HasHtml
21 | {
22 | public static function values(): array
23 | {
24 | return array_combine(
25 | array_map(fn($class) => $class->value, self::cases()),
26 | array_map(fn($class) => $class->getList(), self::cases())
27 | );
28 | }
29 |
30 | public static function first(): string
31 | {
32 | return array_key_first(self::values());
33 | }
34 |
35 | public static function html(string $content, string $class = ''): string
36 | {
37 | return sprintf(self::values()[$class] ?? self::values()[''], $content);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Traits/HasNames.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums\Traits;
14 |
15 | use function array_map;
16 | use function strtolower;
17 |
18 | trait HasNames
19 | {
20 | public function name(): string
21 | {
22 | return strtolower($this->name);
23 | }
24 |
25 | public static function names(): array
26 | {
27 | return array_map(fn($item) => $item->name(), self::cases());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Traits/HasValues.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Enums\Traits;
14 |
15 | use function array_map;
16 |
17 | trait HasValues
18 | {
19 | public static function values(): array
20 | {
21 | return array_map(fn($item) => $item->value, self::cases());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Enums/Traits/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Events;
14 |
15 | use Bugo\LightPortal\Plugins\PluginHandler;
16 |
17 | final class EventManagerFactory
18 | {
19 | private static array $plugins = [];
20 |
21 | private static PluginHandler $handler;
22 |
23 | private static EventManager $manager;
24 |
25 | public function __invoke(array $plugins = []): EventManager
26 | {
27 | if ($plugins !== self::$plugins) {
28 | self::$plugins = $plugins;
29 | self::$handler = app(PluginHandler::class)($plugins);
30 | }
31 |
32 | self::$handler ??= app(PluginHandler::class)();
33 | self::$manager = self::$handler->getManager();
34 |
35 | return self::$manager;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Events/HasEvents.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Hooks;
14 |
15 | use Bugo\Compat\Lang;
16 | use Bugo\LightPortal\Enums\PortalHook;
17 | use Bugo\LightPortal\Events\HasEvents;
18 |
19 | if (! defined('SMF'))
20 | die('No direct access...');
21 |
22 | class DownloadRequest
23 | {
24 | use HasEvents;
25 |
26 | public function __invoke(mixed &$attachRequest): void
27 | {
28 | Lang::load('LightPortal/LightPortal');
29 |
30 | $this->events()->dispatch(PortalHook::downloadRequest, ['attachRequest' => &$attachRequest]);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Hooks/LoadIllegalGuestPermissions.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Hooks;
14 |
15 | use Bugo\Compat\Utils;
16 |
17 | use function array_merge;
18 |
19 | if (! defined('SMF'))
20 | die('No direct access...');
21 |
22 | class LoadIllegalGuestPermissions
23 | {
24 | public function __invoke(): void
25 | {
26 | Utils::$context['non_guest_permissions'] = array_merge(
27 | Utils::$context['non_guest_permissions'],
28 | [
29 | 'light_portal_manage_pages_own',
30 | 'light_portal_manage_pages_any',
31 | 'light_portal_manage_pages',
32 | 'light_portal_approve_pages',
33 | ]
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Hooks/Redirect.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Hooks;
14 |
15 | use Bugo\Compat\Config;
16 | use Bugo\LightPortal\Utils\Setting;
17 | use Bugo\LightPortal\Utils\Traits\HasRequest;
18 |
19 | if (! defined('SMF'))
20 | die('No direct access...');
21 |
22 | class Redirect
23 | {
24 | use HasRequest;
25 |
26 | public function __invoke(string &$setLocation): void
27 | {
28 | if (empty(Config::$modSettings['lp_frontpage_mode']) || Setting::isStandaloneMode())
29 | return;
30 |
31 | if ($this->request()->is('markasread')) {
32 | $setLocation = Config::$scripturl . '?action=forum';
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Hooks/RouteParsers.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Hooks;
14 |
15 | use Bugo\Compat\QueryString;
16 | use Bugo\LightPortal\Enums\Action;
17 | use Bugo\LightPortal\Routes\Forum;
18 | use Bugo\LightPortal\Routes\Page;
19 | use Bugo\LightPortal\Routes\Portal;
20 |
21 | use const LP_ACTION;
22 |
23 | class RouteParsers
24 | {
25 | public function __invoke(): void
26 | {
27 | QueryString::$route_parsers[Action::FORUM->value] = Forum::class;
28 | QueryString::$route_parsers[Action::PAGES->value] = Page::class;
29 | QueryString::$route_parsers[LP_ACTION] = Portal::class;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Hooks/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Lists;
14 |
15 | interface ListInterface
16 | {
17 | public function __invoke(): array;
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Lists/PluginList.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright 2019-2025 Bugo
10 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
11 | *
12 | * @version 2.9
13 | */
14 |
15 | namespace Bugo\LightPortal\Lists;
16 |
17 | use function array_map;
18 | use function basename;
19 | use function glob;
20 |
21 | use const GLOB_ONLYDIR;
22 | use const LP_ADDON_DIR;
23 |
24 | if (! defined('SMF'))
25 | die('No direct access...');
26 |
27 | class PluginList implements ListInterface
28 | {
29 | public function __invoke(): array
30 | {
31 | if (empty($dirs = glob(LP_ADDON_DIR . '/*', GLOB_ONLYDIR)))
32 | return [];
33 |
34 | return array_map(static fn($item): string => basename($item), $dirs);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Lists/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | use Bugo\LightPortal\Utils\Str;
16 |
17 | abstract class AbstractFactory implements FactoryInterface
18 | {
19 | protected string $modelClass;
20 |
21 | public function create(array $data): ModelInterface
22 | {
23 | if (! empty($data['titles'])) {
24 | Str::cleanBbcode($data['titles']);
25 | }
26 |
27 | $data = $this->modifyData($data);
28 |
29 | return new $this->modelClass($data);
30 | }
31 |
32 | protected function modifyData(array $data): array
33 | {
34 | return $data;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/BlockFactory.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | use Bugo\LightPortal\Utils\Str;
16 |
17 | class BlockFactory extends AbstractFactory
18 | {
19 | protected string $modelClass = BlockModel::class;
20 |
21 | protected function modifyData(array $data): array
22 | {
23 | if (! empty($data['note'])) {
24 | Str::cleanBbcode($data['note']);
25 | }
26 |
27 | return $data;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/CategoryFactory.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | use Bugo\LightPortal\Utils\Str;
16 |
17 | class CategoryFactory extends AbstractFactory
18 | {
19 | protected string $modelClass = CategoryModel::class;
20 |
21 | protected function modifyData(array $data): array
22 | {
23 | if (! empty($data['description'])) {
24 | Str::cleanBbcode($data['description']);
25 | }
26 |
27 | return $data;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/CategoryModel.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | use Bugo\LightPortal\Enums\Status;
16 |
17 | class CategoryModel extends AbstractModel
18 | {
19 | public int $id;
20 |
21 | public string $icon;
22 |
23 | public string $description;
24 |
25 | public int $priority;
26 |
27 | public int $status;
28 |
29 | public array $titles = [];
30 |
31 | public function __construct(array $data)
32 | {
33 | $this->id = $data['category_id'] ?? $data['id'] ?? 0;
34 | $this->icon = $data['icon'] ?? '';
35 | $this->description = $data['description'] ?? '';
36 | $this->priority = $data['priority'] ?? 0;
37 | $this->status = $data['status'] ?? Status::ACTIVE->value;
38 | $this->titles = $data['titles'] ?? [];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/FactoryInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | interface FactoryInterface
16 | {
17 | public function create(array $data): ModelInterface;
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/ModelInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | interface ModelInterface
16 | {
17 | public function toArray(): array;
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/PageFactory.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | use Bugo\LightPortal\Utils\Str;
16 |
17 | use function explode;
18 | use function is_array;
19 |
20 | class PageFactory extends AbstractFactory
21 | {
22 | protected string $modelClass = PageModel::class;
23 |
24 | protected function modifyData(array $data): array
25 | {
26 | if (! empty($data['description'])) {
27 | Str::cleanBbcode($data['description']);
28 | }
29 |
30 | $data['tags'] = empty($data['tags']) ? [] : $data['tags'];
31 | $data['tags'] = is_array($data['tags']) ? $data['tags'] : explode(',', (string) $data['tags']);
32 |
33 | return $data;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/TagFactory.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | class TagFactory extends AbstractFactory
16 | {
17 | protected string $modelClass = TagModel::class;
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/TagModel.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Models;
14 |
15 | use Bugo\LightPortal\Enums\Status;
16 |
17 | class TagModel extends AbstractModel
18 | {
19 | public int $id;
20 |
21 | public string $icon;
22 |
23 | public int $status;
24 |
25 | public array $titles = [];
26 |
27 | public function __construct(array $data)
28 | {
29 | $this->id = $data['tag_id'] ?? $data['id'] ?? 0;
30 | $this->icon = $data['icon'] ?? '';
31 | $this->status = $data['status'] ?? Status::ACTIVE->value;
32 | $this->titles = $data['titles'] ?? [];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Models/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2020-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @category plugin
11 | * @version 28.11.24
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\AdsBlock\Hooks;
15 |
16 | use Bugo\Compat\Utils;
17 | use Bugo\LightPortal\Plugins\AdsBlock\RepliesComparisonTrait;
18 |
19 | use function dirname;
20 |
21 | class DisplayButtons
22 | {
23 | use RepliesComparisonTrait;
24 |
25 | public function __invoke(): void
26 | {
27 | if ($this->isRepliesBelowMinimum())
28 | return;
29 |
30 | require_once dirname(__DIR__) . '/template.php';
31 |
32 | Utils::$context['template_layers'][] = 'ads_placement_topic';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/AdsBlock/Hooks/MessageindexButtons.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2020-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @category plugin
11 | * @version 06.11.24
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\AdsBlock\Hooks;
15 |
16 | use Bugo\Compat\Utils;
17 |
18 | use function dirname;
19 |
20 | class MessageindexButtons
21 | {
22 | public function __invoke(): void
23 | {
24 | require_once dirname(__DIR__) . '/template.php';
25 |
26 | Utils::$context['template_layers'][] = 'ads_placement_board';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/AdsBlock/Hooks/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2020-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @category plugin
11 | * @version 06.11.24
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\AdsBlock;
15 |
16 | use Bugo\Compat\Utils;
17 |
18 | trait RepliesComparisonTrait
19 | {
20 | protected function isRepliesBelowMinimum(): bool
21 | {
22 | return isset(Utils::$context['lp_ads_block_plugin']['min_replies'])
23 | && Utils::$context['topicinfo']['num_replies'] < (int) Utils::$context['lp_ads_block_plugin']['min_replies'];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/AdsBlock/index.php:
--------------------------------------------------------------------------------
1 | 'Article List',
5 | 'description' => 'Displays a list of selected articles of the portal (with images if exist).',
6 | 'body_class' => 'CSS class of article blocks',
7 | 'display_type' => 'What should be displayed',
8 | 'display_type_set' => ['Forum topics', 'Portal pages'],
9 | 'include_topics' => 'Topics',
10 | 'include_topics_select' => 'Select the topics to be displayed inside the block.',
11 | 'include_pages' => 'Pages',
12 | 'include_pages_select' => 'Select the portal pages to display inside the block.',
13 | 'seek_images' => 'Search for images in the text of articles',
14 | 'no_items' => 'There are no available articles.'
15 | ];
16 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/ArticleList/langs/index.php:
--------------------------------------------------------------------------------
1 | div {
7 | display: flex;
8 | flex-direction: column;
9 | justify-content: space-between;
10 | text-align: center;
11 | margin: 0 !important;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Block.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Plugins;
14 |
15 | use Bugo\Compat\Utils;
16 |
17 | if (! defined('LP_NAME'))
18 | die('No direct access...');
19 |
20 | abstract class Block extends Plugin
21 | {
22 | public string $type = 'block';
23 |
24 | public function isInPlacements(int $id, array $placements): bool
25 | {
26 | $block = Utils::$context['lp_active_blocks'][$id] ?? Utils::$context['lp_block'];
27 |
28 | return in_array($block['placement'], $placements);
29 | }
30 |
31 | public function isInSidebar(int $id): bool
32 | {
33 | return $this->isInPlacements($id, ['left', 'right']);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BlogMode/BlogArticle.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2024-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @category plugin
11 | * @version 13.11.24
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\BlogMode;
15 |
16 | use Bugo\LightPortal\Articles\PageArticle;
17 |
18 | if (! defined('LP_NAME'))
19 | die('No direct access...');
20 |
21 | class BlogArticle extends PageArticle
22 | {
23 | public const TYPE = 'blog';
24 |
25 | public function init(): void
26 | {
27 | parent::init();
28 |
29 | $this->selectedCategories = [];
30 |
31 | $this->params['entry_type'] = self::TYPE;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BlogMode/index.php:
--------------------------------------------------------------------------------
1 | 'Adds the ability to create personal blogs for portal users. Do not forget to assign appropriate permissions to member groups.',
5 | 'show_blogs_in_profiles' => 'Display users\' blogs in their profiles',
6 | 'permission' => 'Post blog entries',
7 | 'group_permission' => 'Who can post blog entries — Blogger',
8 | 'menu_item_title' => 'Blog',
9 | 'profile_title' => 'Blog %s',
10 | 'entries' => 'Blog entries',
11 | 'blog_action' => 'Blog action',
12 | 'blogged_status' => 'Blog entry',
13 | 'simple_status' => 'Simple page',
14 | ];
15 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BlogMode/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Board List',
5 | 'description' => 'Displays a list of boards that are available to the current user.',
6 | 'category_class' => 'CSS class of category titles',
7 | 'board_class' => 'CSS class of blocks with board lists',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BoardList/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Board News',
5 | 'description' => 'Displays the latest posts from selected board.',
6 | 'board_id' => 'Board as source of news',
7 | 'num_posts' => 'Number of posts to display',
8 | 'teaser_length' => 'News teaser length',
9 | 'no_posts' => 'You cannot specify an empty board or board that doesn\'t allow guests',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BoardNews/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Forum stats',
5 | 'description' => 'Displays basic forum statistics, as well as the number of online users.',
6 | 'show_latest_member' => 'Display the name of the last member',
7 | 'show_basic_info' => 'Display basic statistics',
8 | 'show_whos_online' => 'Display the "Now online" list',
9 | 'use_fa_icons' => 'Use Font Awesome icons',
10 | 'update_interval' => 'Data refresh interval, in seconds',
11 | 'newbie' => 'Newbie',
12 | 'online_today' => 'Online today',
13 | 'max_online' => 'Most max online',
14 | 'guests' => 'Guests',
15 | 'spiders' => 'Spiders',
16 | ];
17 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BoardStats/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Using Bootstrap Icons in the portal blocks\' titles.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/BootstrapIcons/langs/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2023-2025 Bugo
8 | * @license https://opensource.org/licenses/MIT MIT
9 | *
10 | * @category plugin
11 | * @version 22.12.24
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\Calculator;
15 |
16 | use Bugo\LightPortal\Plugins\Block;
17 | use Bugo\LightPortal\Plugins\Event;
18 |
19 | if (! defined('LP_NAME'))
20 | die('No direct access...');
21 |
22 | /**
23 | * Generated by PluginMaker
24 | */
25 | class Calculator extends Block
26 | {
27 | public string $icon = 'fas fa-calculator';
28 |
29 | public function prepareBlockParams(Event $e): void
30 | {
31 | $e->args->params['no_content_class'] = true;
32 | }
33 |
34 | public function prepareContent(Event $e): void
35 | {
36 | echo $this->getFromTemplate('show_calculator_block', $e->args->id);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Calculator/index.php:
--------------------------------------------------------------------------------
1 | 'Calculator',
5 | 'description' => 'Adds a widget with a simple calculator in HTML, CSS, and JavaScript.',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Calculator/langs/index.php:
--------------------------------------------------------------------------------
1 | * {
22 | position: relative;
23 | text-align: center;
24 | }
25 |
26 | > *:active::before,
27 | > .is-depressed::before {
28 | background-color: rgba(0, 0, 0, 0.2);
29 | bottom: 0;
30 | box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.5) inset;
31 | content: "";
32 | left: 0;
33 | opacity: 0.3;
34 | position: absolute;
35 | right: 0;
36 | top: 0;
37 | z-index: 1;
38 | }
39 | }
40 |
41 | .key--equal {
42 | background-image: linear-gradient(to bottom, #fe886a, #ff7033);
43 | grid-column: -2;
44 | grid-row: 2 / span 4;
45 | }
46 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/CategoryList/index.php:
--------------------------------------------------------------------------------
1 | 'Portal categories',
5 | 'description' => 'Displays a category list of the portal.',
6 | 'no_items' => 'No category has been created yet',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/CategoryList/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Chart',
5 | 'description' => 'Chart.js provides a set of frequently used chart types.',
6 | 'chart_title' => 'Title of chart',
7 | 'chart_title_placeholder' => 'Text to display as a title of chart',
8 | 'datasets' => 'Datasets',
9 | 'datasets_placeholder' => 'Example: 1, 2, 3 (or as objects: {x: 1, y: 2}, {x: 3, y: 4})',
10 | 'set_label' => 'Label',
11 | 'background_color' => 'Background color',
12 | 'border_color' => 'Border color',
13 | 'border_width' => 'Border width',
14 | 'set_add' => 'Add set',
15 | 'labels' => 'Labels',
16 | 'labels_placeholder' => 'Example: Red, Orange, Green',
17 | 'default_palette' => 'Use default color palette',
18 | 'type' => 'Chart type',
19 | 'type_set' => ['Line chart', 'Bar chart', 'Pie chart', 'Doughnut chart', 'Polar area chart', 'Radar chart'],
20 | 'stacked' => 'Enable stacked bar charts',
21 | 'stacked_after' => 'Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.',
22 | 'horizontal' => 'Enable horizontal bar charts',
23 | ];
24 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Chart/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Chessboard',
5 | 'description' => 'Provides an opportunity to play chess with the computer.',
6 | 'search_depth' => 'Search depth',
7 | 'game_over' => 'Game over',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/ChessBoard/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Provides syntax highlighting when editing pages and blocks with various content.',
5 | 'modes' => 'Syntax Highlighting',
6 | 'small_hint' => 'Disable other editor plugins so that content blocks are not duplicated.',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/CodeMirror/langs/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Plugins;
14 |
15 | use Bugo\Compat\Utils;
16 | use Bugo\LightPortal\Repositories\PluginRepository;
17 |
18 | class ConfigHandler
19 | {
20 | private static array $settings;
21 |
22 | public function handle(string $snakeName): void
23 | {
24 | self::$settings ??= app(PluginRepository::class)->getSettings();
25 |
26 | // @TODO These variables are still needed in some templates
27 | Utils::$context['lp_' . $snakeName . '_plugin'] = self::$settings[$snakeName] ?? [];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/CurrentMonth/index.php:
--------------------------------------------------------------------------------
1 | 'Current month',
5 | 'description' => 'Displays a widget with the current month.',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/CurrentMonth/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Widget for quick translation of forum pages',
5 | 'description' => 'Displays a modified version of the standard Yandex.Translate widget to translate forum pages into the selected language.',
6 | 'languages' => 'Supported languages',
7 | 'languages_select' => 'Select desired languages that will be available via this widget',
8 | 'languages_set' => ['Arabic', 'German', 'Greek', 'English', 'Esperanto', 'Spanish', 'French', 'Hindi', 'Italian', 'Dutch', 'Portuguese', 'Russian', 'Swedish', 'Turkish', 'Ukrainian', 'Chinese'],
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/CustomTranslate/langs/index.php:
--------------------------------------------------------------------------------
1 |
12 |
13 |
16 | ';
17 |
18 | foreach (Utils::$context['ctw_languages'] as $lang) {
19 | echo '
20 |
21 |
22 | ';
23 | }
24 |
25 | echo '
26 |
27 | ';
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/DiceBear/index.php:
--------------------------------------------------------------------------------
1 | 'With DiceBear you can provide your users with stunning random avatars in no time.',
5 | 'replace_missing_avatars' => 'Replace only missing avatars',
6 | 'source' => 'Data source for generation',
7 | 'source_set' => ['User name', 'User ID', 'User email'],
8 | 'style' => 'Style',
9 | 'size' => 'Default size',
10 | 'flip' => 'Flip right',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/DiceBear/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Adds the ability to display Disqus comments on portal pages.',
5 | 'shortname' => 'Website shortname',
6 | 'shortname_subtext' => 'This is used to uniquely identify your website on Disqus.
Copy your site shortname from the Disqus settings and paste here.',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Disqus/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Allows you to quickly drag and drop blocks between panels without going into the admin area.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Dragula/langs/index.php:
--------------------------------------------------------------------------------
1 | 'The plugin generates fake cards on the frontpage, for testing templates.',
5 | 'use_lorem_ipsum' => 'Use Lorem Ipsum for cards',
6 | 'keywords' => 'Image keywords',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/DummyArticleCards/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Enables the EasyMDE editor to work with Markdown.',
5 | 'tasks' => 'Task list',
6 | 'lines' => 'lines: ',
7 | 'words' => 'words: ',
8 | 'toggle' => 'Toggle Side by Side',
9 | 'guide' => 'Markdown Guide',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/EasyMarkdownEditor/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Support for importing EhPortal/SimplePortal pages, categories, and custom blocks (if they exist in the database).',
5 | 'label_name' => 'Import from EhPortal',
6 | 'block_import_desc' => 'Import custom EhPortal/SimplePortal blocks (BBCode, HTML, PHP).',
7 | 'page_import_desc' => 'Import EhPortal/SimplePortal pages (if they exist in the database).',
8 | 'category_import_desc' => 'Import EhPortal/SimplePortal categories (if they exist in the database).',
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/EhPortalMigration/langs/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Plugins;
14 |
15 | use Doctrine\Common\EventArgs;
16 |
17 | class Event extends EventArgs
18 | {
19 | public function __construct(public object $args) {}
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Events/index.php:
--------------------------------------------------------------------------------
1 | 'Events',
5 | 'description' => 'Displays calendar summary such as birthdays, holidays and events.',
6 | 'days_in_future' => 'Number of days in future to show events',
7 | 'update_interval' => 'Data refresh interval, in seconds',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Events/langs/index.php:
--------------------------------------------------------------------------------
1 | div:last-child {
3 | display: grid;
4 | grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
5 | grid-gap: 0 10px;
6 |
7 | @media screen and (max-width: 768px) {
8 | & {
9 | display: block;
10 | }
11 | }
12 | }
13 |
14 | .fa-calendar {
15 | color: forestgreen;
16 | }
17 |
18 | .fa-cake-candles {
19 | color: salmon;
20 | }
21 |
22 | .fa-calendar-days {
23 | color: rgb(59, 91, 152);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/ExtendedMetaTags/index.php:
--------------------------------------------------------------------------------
1 | 'Adds additional meta tags for portal pages.',
5 | 'meta_robots' => 'Robots (bot behavior management)',
6 | 'meta_robots_set' => ['No', 'index, follow', 'index, nofollow', 'noindex, follow', 'noindex, nofollow'],
7 | 'meta_rating' => 'Age rating',
8 | 'meta_rating_set' => ['No', '14-year-old audience', 'adults (18+)', 'general category', 'mature (17+)', 'restricted', 'safe for kids'],
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/ExtendedMetaTags/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Support for importing ezPortal pages and custom blocks (if they exist in the database).',
5 | 'label_name' => 'Import from ezPortal',
6 | 'block_import_desc' => 'Import custom ezPortal blocks (HTML, PHP).',
7 | 'page_import_desc' => 'Import ezPortal pages (if they exist in the database).',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/EzPortalMigration/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Displays FA Board Icons for boards in the article mode on the frontpage.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/FaBoardIcons/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Adds the ability to display Facebook comments on portal pages.',
5 | 'app_id' => 'Facebook Application ID',
6 | 'app_id_subtext' => 'Get Application ID',
7 | 'comments_per_page' => 'Number of comments per page',
8 | 'comment_order_by' => 'Comments sorting',
9 | 'comment_order_by_set' => ['The newest at the top', 'The oldest at the top'],
10 | 'dark_themes' => 'Select themes for which the color scheme of the widget should be dark',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/FacebookComments/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Images from SMF Gallery',
5 | 'description' => 'Displays images from selected SMF Gallery categories.',
6 | 'categories' => 'Image categories',
7 | 'categories_select' => 'If you do not need all the images, but only from certain categories',
8 | 'num_images' => 'Number of images to display',
9 | 'num_images_subtext' => 'Set to 0 to disable the limit',
10 | 'no_items' => 'There are no images in the selected categories.',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/GalleryBlock/langs/index.php:
--------------------------------------------------------------------------------
1 | 'A comments system powered by GitHub Discussions. Let visitors leave comments and reactions on your website via GitHub!',
5 | 'repo' => 'GitHub Repository',
6 | 'repo_subtext' => 'Take from the data-repo field of the proposed config',
7 | 'repo_id' => 'Repository ID',
8 | 'repo_id_subtext' => 'Take from the data-repo-id field of the proposed config',
9 | 'category' => 'Discussion Category',
10 | 'category_subtext' => 'Take from the data-category field of the proposed config',
11 | 'category_id' => 'Category ID',
12 | 'category_id_subtext' => 'Take from the data-category-id field of the proposed config',
13 | 'theme' => 'Theme',
14 | ];
15 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Giscus/langs/index.php:
--------------------------------------------------------------------------------
1 |
9 |
12 | ';
13 | }
14 |
15 | function template_tour_info_below()
16 | {
17 | }
18 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/HidingBlocks/index.php:
--------------------------------------------------------------------------------
1 | 'Allows to hide any block depending on the screen width.',
5 | 'hidden_breakpoints' => 'Hide the block on screens with the specified width',
6 | 'hidden_breakpoints_set' => ['less than 576px', 'from 576 to 768px', 'from 768 to 992px', 'from 992 to 1200px', 'more than 1200px'],
7 | 'hidden_breakpoints_subtext' => 'If no element is selected, there are no restrictions'
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/HidingBlocks/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Notify supported search engines about changes of the portal pages.',
5 | 'user_key' => 'User Verification Key',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/IndexNow/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Enables the Jodit visual editor for working with HTML content.',
5 | 'dark_themes' => 'Select themes for which the editor appearance should be dark',
6 | 'icon_size' => 'Size of icons in the toolbar',
7 | 'icon_size_set' => ['small' => 'Small', 'middle' => 'Middle', 'large' => 'Large'],
8 | 'enter_element' => 'Element that will be created when you press Enter',
9 | 'enter_element_set' => ['p' => 'Paragraph (P)', 'div' => 'Block (DIV)', 'br' => 'Break (BR)'],
10 | 'default_mode' => 'Default mode',
11 | 'default_mode_set' => [1 => 'WYSIWYG', 'Source code', 'Split code'],
12 | 'autofocus' => 'Autofocus on page loading',
13 | 'insert_image_base64' => 'Insert image as Base64 URI',
14 | ];
15 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Jodit/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Allows you to display a specific block depending on the user\'s language.',
5 | 'allowed_languages' => 'Display a block if the user\'s current language is',
6 | 'allowed_languages_subtext' => 'If no language is selected, there are no restrictions'
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/LanguageAccess/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Provides the ability to use Latte markup in your own frontpage layouts.',
5 | 'note' => 'To add your template, create a file with the extension %s in the %s directory',
6 | 'example' => 'Example markup',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/LatteLayouts/langs/index.php:
--------------------------------------------------------------------------------
1 |
8 | {/if}
9 |
10 |
11 | {do show_pagination()}
12 |
13 |
17 |
18 | {php echo parse_bbc('[code]' . print_r($article, true) . '[/code]')}
19 |
20 |
21 |
22 | {do show_pagination(bottom)}
23 |
24 |
25 | {if $no_blocks}
26 |
27 | {/if}
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/LatteLayouts/layouts/index.php:
--------------------------------------------------------------------------------
1 |
8 | {/if}
9 |
10 |
11 | {do show_pagination()}
12 |
13 |
23 |
24 | {do show_pagination(bottom)}
25 |
26 |
27 | {if $no_blocks}
28 |
29 | {/if}
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/LatteLayouts/layouts/simple3.latte:
--------------------------------------------------------------------------------
1 | {varType array $context}
2 |
3 | {if empty($context[lp_active_blocks])}
4 |
5 | {/if}
6 |
7 | {do show_pagination()}
8 |
9 |
10 |
11 |
![{$article[title]}]()
12 |
13 |
14 |
{teaser($article[teaser])}
15 |
16 |
19 |
20 |
21 |
22 | {do show_pagination(bottom)}
23 |
24 | {if empty($context[lp_active_blocks])}
25 |
26 | {/if}
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Likely/index.php:
--------------------------------------------------------------------------------
1 | 'Likely',
5 | 'description' => 'Displays selected social sharing buttons.',
6 | 'size' => 'Button size',
7 | 'size_set' => [
8 | 'small' => 'Small',
9 | 'big' => 'Big'
10 | ],
11 | 'dark_mode' => 'Use buttons for dark mode',
12 | 'buttons' => 'Displayed buttons',
13 | 'select_buttons' => 'Select social buttons to display',
14 | 'buttons_set' => [
15 | 'facebook' => 'Share',
16 | 'twitter' => 'Tweet',
17 | 'vkontakte' => 'Share',
18 | 'pinterest' => 'Pin',
19 | 'odnoklassniki' => 'Like',
20 | 'telegram' => 'Send',
21 | 'linkedin' => 'Share',
22 | 'whatsapp' => 'Send',
23 | 'viber' => 'Send',
24 | 'reddit' => 'Share',
25 | ],
26 | ];
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Likely/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Using Line Awesome icons by Icons8 in the portal blocks\' titles.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/LineAwesomeIcons/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Using standard SMF icons in the portal blocks\' titles.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/MainIcons/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Provides the ability to override the labels of the "Portal" and "Forum" items.',
5 | 'menu_item' => 'Name of item',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/MainMenu/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Custom Markdown',
5 | 'description' => 'Adds the ability to use Markdown content in articles and portal blocks.',
6 | 'block_desc' => 'Here you can use basic Markdown syntax as content.',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Markdown/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Using Material Design Icons in the portal blocks\' titles.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/MaterialDesignIcons/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Block with media links',
5 | 'description' => 'Converts links from popular media sites to auto-embed videos.',
6 | 'urls' => 'URLs',
7 | 'title_placeholder' => 'Title (will be displayed below the video)',
8 | 'link_placeholder' => 'Link to video',
9 | 'url_add' => 'Add URL',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/MediaBlock/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Forum News',
5 | 'description' => 'Displays one of the forum\'s news items.',
6 | 'selected_item' => 'What to display',
7 | 'random_news' => 'The random news',
8 | 'no_items' => 'No news yet.'
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/News/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Displays the descriptions and keywords of the Optimus for topics in the articles mode on the frontpage.',
5 | 'use_topic_descriptions' => 'Use topic descriptions as article teasers on the portal frontpage',
6 | 'show_topic_keywords' => 'Show topic keywords on the portal frontpage',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Optimus/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Page List',
5 | 'description' => 'Displays a list of active portal pages.',
6 | 'categories_select' => 'If you do not need all the pages, but only from certain categories',
7 | 'sort' => 'Page sorting',
8 | 'sort_set' => ['By ID', 'By author', 'By title', 'By slug', 'By type', 'By number views', 'By date of creation', 'By date of updating'],
9 | 'num_pages' => 'Number of pages to display',
10 | 'num_pages_subtext' => 'Set 0 to show all pages',
11 | 'no_items' => 'There are no available pages.'
12 | ];
13 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/PageList/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Adds buttons to move up/down the page.',
5 | 'button_up' => 'The "Up" Button (Unicode)',
6 | 'button_down' => 'The "Down" Button (Unicode)',
7 | 'button_color' => 'Button color',
8 | 'arrow_color' => 'Arrow color',
9 | 'placement' => 'Button layout',
10 | 'placement_set' => ['Lower left corner', 'Lower right corner'],
11 | 'hide_on_mobile' => 'Hide on mobile screens',
12 | ];
13 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/PageScroll/langs/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Plugins;
14 |
15 | interface PluginInterface
16 | {
17 | public function getCamelName(): string;
18 |
19 | public function getSnakeName(): string;
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/PluginMaker/License.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2021-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @category plugin
11 | * @version 09.01.25
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\PluginMaker;
15 |
16 | enum License: string
17 | {
18 | case MIT = 'mit';
19 | case BSD = 'bsd';
20 | case GPL = 'gpl';
21 |
22 | public function getName(): string
23 | {
24 | return match ($this) {
25 | self::MIT => 'MIT',
26 | self::BSD => 'BSD-3-Clause',
27 | self::GPL => 'GPL-3.0-or-later',
28 | };
29 | }
30 |
31 | public function getLink(): string
32 | {
33 | return match ($this) {
34 | self::MIT => 'https://opensource.org/licenses/MIT',
35 | self::BSD => 'https://opensource.org/licenses/BSD-3-Clause',
36 | self::GPL => 'https://spdx.org/licenses/GPL-3.0-or-later.html',
37 | };
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/PluginMaker/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "nette/php-generator": "^4.1"
4 | },
5 | "config": {
6 | "optimize-autoloader": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/PluginMaker/index.php:
--------------------------------------------------------------------------------
1 | 'Forum polls',
5 | 'description' => 'Displays a selected poll.',
6 | 'selected_item' => 'Select a poll',
7 | 'no_items' => 'No polls yet.',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Polls/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Provides support for the portal action and pages urls like your_forum/page/slug with the PrettyUrls mod.'
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/PrettyUrls/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Random Pages',
5 | 'description' => 'Displays a list of random pages of the portal.',
6 | 'exclude_categories' => 'Exclude categories',
7 | 'exclude_categories_select' => 'Select the categories from which pages will NOT be displayed.',
8 | 'include_categories' => 'Include categories',
9 | 'include_categories_select' => 'Pages will be displayed ONLY from the selected categories.',
10 | 'num_pages' => 'Number of pages to display',
11 | 'show_num_views' => 'Show number of views',
12 | 'none' => 'There are no random pages',
13 | ];
14 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/RandomPages/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Random Topics',
5 | 'description' => 'Displays a list of random topics of the forum.',
6 | 'exclude_boards' => 'Exclude boards',
7 | 'exclude_boards_select' => 'Select the boards from which topics will NOT be displayed.',
8 | 'include_boards' => 'Include boards',
9 | 'include_boards_select' => 'Topics will be displayed ONLY from the selected boards.',
10 | 'num_topics' => 'Number of topics to display',
11 | 'show_num_views' => 'Show number of views',
12 | 'none' => 'There are no random topics',
13 | ];
14 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/RandomTopics/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Adds reactions for pages and comments.',
5 | 'allow_reactions' => 'Allow reactions',
6 | 'titles' => ['Like', 'Dislike', 'Love', 'Laugh', 'Sad', 'Angry'],
7 | 'react' => 'React',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Reactions/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Recent Attachments',
5 | 'description' => 'Displays the recent attachments that the user can see.',
6 | 'num_attachments' => 'Number of attachments to display',
7 | 'extensions' => 'The extensions of attachments that you want to display',
8 | 'extensions_subtext' => 'Enter the required extensions, separated by commas. For example: jpg,png',
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/RecentAttachments/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Recent Comments',
5 | 'description' => 'Displays a list of recent comments of the portal pages.',
6 | 'num_comments' => 'Number of comments to display',
7 | 'length' => 'Teaser length',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/RecentComments/langs/index.php:
--------------------------------------------------------------------------------
1 | div {
26 | display: flex;
27 | flex-direction: column;
28 | justify-content: space-between;
29 | text-align: center;
30 | margin: 0 !important;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/RecentTopics/index.php:
--------------------------------------------------------------------------------
1 | 'Recent Topics',
5 | 'description' => 'Displays a list of recent forum topics.',
6 | 'exclude_boards' => 'Exclude boards',
7 | 'exclude_boards_select' => 'Select the boards from which topics will NOT be displayed.',
8 | 'include_boards' => 'Include boards',
9 | 'include_boards_select' => 'Topics will be displayed ONLY from the selected boards.',
10 | 'use_simple_style' => 'Use a simple design style',
11 | 'use_simple_style_subtext' => 'Disables avatars and icons.',
12 | 'show_avatars' => 'Show user avatars',
13 | 'show_icons' => 'Show topic icons',
14 | 'num_topics' => 'Number of topics to display',
15 | 'type' => 'What to display as a link to a post',
16 | 'type_set' => ['Message subject', 'Message preview'],
17 | 'update_interval' => 'List refresh interval, in seconds',
18 | ];
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/RecentTopics/langs/index.php:
--------------------------------------------------------------------------------
1 | div {
26 | display: flex;
27 | flex-direction: column;
28 | justify-content: space-between;
29 | text-align: center;
30 | margin: 0 !important;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Search/index.php:
--------------------------------------------------------------------------------
1 | 'Search in pages',
5 | 'description' => 'Displays the search field for the content of portal pages.',
6 | 'min_chars' => 'Minimum number of characters (>= 1) a user must type before a search is performed',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Search/langs/index.php:
--------------------------------------------------------------------------------
1 |
10 | ', Lang::$txt['search_results'], '
11 | ';
12 |
13 | if (empty(Utils::$context['search_results'])) {
14 | echo '
15 | ', Lang::$txt['search_no_results'], '
';
16 | }
17 |
18 | foreach (Utils::$context['search_results'] as $i => $result) {
19 | echo '
20 |
21 |
22 |
23 | ', ++$i, '
24 |
27 | ', Lang::$txt['by'], ' ', $result['author'], ' ', $result['date'], '
28 |
29 |
30 |
', $result['content'], '
31 |
';
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/SimpleChat/index.php:
--------------------------------------------------------------------------------
1 | 'Simple Chat',
5 | 'description' => 'Displays a simple form to communicate with other users in real time.',
6 | 'show_avatars' => 'Show user avatars',
7 | 'form_position' => 'Position of the input form',
8 | 'form_position_set' => ['At the bottom', 'At the top'],
9 | 'window_height' => 'Chat window height (px)',
10 | 'login' => 'Log in to participate in the discussion',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/SimpleChat/langs/index.php:
--------------------------------------------------------------------------------
1 | 'RSS Feed',
5 | 'description' => 'Displays the RSS feed from the specified URL.',
6 | 'url' => 'RSS feed URL',
7 | 'show_text' => 'Show text',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/SimpleFeeder/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Simple menu',
5 | 'description' => 'Displays a simple menu of the specified items.',
6 | 'items' => 'Menu items',
7 | 'name_placeholder' => 'Item name',
8 | 'link_placeholder' => 'Item link or forum action',
9 | 'item_add' => 'Add new item',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/SimpleMenu/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Displays a custom site list on the frontpage.',
5 | 'caution' => 'the added sites will be displayed INSTEAD of portal articles on the frontpage!',
6 | 'image' => 'Link to screenshot',
7 | 'add' => 'Add site',
8 | ];
9 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/SiteList/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Adds a New Year mood to the site, more specifically snowfall, snowdrifts and a car that clears them regularly!',
5 | 'icon_color' => 'Snowflake color',
6 | 'icon_size' => 'Snowflake size',
7 | 'snowflakes_count' => 'Number of snowflakes',
8 | 'enable_snowdrifts' => 'Enable snowdrifts',
9 | 'snowdrifts_count' => 'Number of snowdrifts',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Snowflakes/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Swiper slider',
5 | 'block_desc' => 'Mobile touch slider to display added images.',
6 | 'description' => 'It provides a block with the free and most modern mobile touch slider with hardware accelerated transitions and amazing native behavior.',
7 | 'direction' => 'Direction of slide movement',
8 | 'effect' => 'Transition effect',
9 | 'slides_per_view' => 'Number of slides per view',
10 | 'loop' => 'Move throughout all the slides seamlessly',
11 | 'show_pagination' => 'Show pagination',
12 | 'show_navigation' => 'Show navigation buttons',
13 | 'show_scrollbar' => 'Show scrollbar',
14 | 'images' => 'Image list',
15 | 'title_placeholder' => 'Title (optional)',
16 | 'link_placeholder' => 'Image link',
17 | 'image_add' => 'Add new image',
18 | ];
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Swiper/langs/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2020-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @category plugin
11 | * @version 12.02.25
12 | */
13 |
14 | namespace Bugo\LightPortal\Plugins\TagList;
15 |
16 | use Laminas\ServiceManager\ServiceManager;
17 | use Laminas\Tag\Cloud;
18 |
19 | class TagCloud extends Cloud
20 | {
21 | public function __construct($options = null)
22 | {
23 | parent::__construct($options);
24 |
25 | $this->decorators = new DecoratorPluginManager(new ServiceManager());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TagList/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "laminas/laminas-tag": "^2.11",
4 | "laminas/laminas-servicemanager": "^4.4.0"
5 | },
6 | "config": {
7 | "optimize-autoloader": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TagList/index.php:
--------------------------------------------------------------------------------
1 | 'Tag List',
5 | 'description' => 'Displays a list of tags of the portal pages (or forum topics, if the Optimus is installed).',
6 | 'source' => 'Tag source',
7 | 'source_set' => ['Portal page tags', 'Topic keywords'],
8 | 'sorting' => 'Tag sorting',
9 | 'sorting_set' => ['By name', 'By frequency'],
10 | 'as_cloud' => 'Display tags as a cloud',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TagList/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Theme Switcher',
5 | 'description' => 'Displays a list of themes that are available to quick selecting.',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/ThemeSwitcher/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Enables a fully-featured, sleek and intuitive rich text editor to work with HTML content.',
5 | 'favorites' => 'Favorites',
6 | 'api_key' => 'API Key',
7 | 'api_key_subtext' => 'Get your API Key',
8 | 'dark_themes' => 'Select themes for which the editor appearance should be dark',
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TinyMCE/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Support for importing TinyPortal pages, categories, and custom blocks (if they exist in the database).',
5 | 'label_name' => 'Import from TinyPortal',
6 | 'block_import_desc' => 'Import custom TinyPortal blocks (BBCode, HTML, PHP).',
7 | 'page_import_desc' => 'Import TinyPortal pages (if they exist in the database).',
8 | 'category_import_desc' => 'Import TinyPortal categories (if they exist in the database).',
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TinyPortalMigration/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Top Boards',
5 | 'description' => 'Displays a list of popular boards.',
6 | 'num_boards' => 'Number of boards to display',
7 | 'entity_type' => 'What to display in bars',
8 | 'entity_type_set' => ['A number of topics', 'A number of posts'],
9 | 'show_numbers_only' => 'Only display numbers',
10 | 'topics' => '{topics, plural, one {# topic} other {# topics}}',
11 | 'posts' => '{posts, plural, one {# post} other {# posts}}'
12 | ];
13 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TopBoards/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Top Pages',
5 | 'description' => 'Displays a list of popular portal pages.',
6 | 'type' => 'Calculation of the popularity',
7 | 'type_set' => ['By comments', 'By views'],
8 | 'num_pages' => 'Number of pages to display',
9 | 'show_numbers_only' => 'Display numbers only',
10 | 'no_items' => 'There are no popular pages.',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TopPages/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Top Posters',
5 | 'description' => 'Displays a list of top posters.',
6 | 'show_avatars' => 'Display user avatars',
7 | 'num_posters' => 'Number of posters to display',
8 | 'show_numbers_only' => 'Display numbers only',
9 | 'posts' => '{posts, plural, one {# post} other {# posts}}',
10 | 'none' => 'No members with posts',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TopPosters/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Top Topics',
5 | 'description' => 'Displays a list of popular topics.',
6 | 'type' => 'Calculation of the popularity',
7 | 'type_set' => ['By replies', 'By views'],
8 | 'num_topics' => 'Number of topics to display',
9 | 'show_numbers_only' => 'Display numbers only',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TopTopics/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Enables support for Topic Rating Bar mod, displaying the rating for topics in the articles mode on the frontpage.',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TopicRatingBar/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Translator widget',
5 | 'description' => 'Displays the button for translating the current page to the selected language.',
6 | 'engine' => 'Used engine',
7 | 'engine_set' => ['Google.Translator', 'Yandex.Translator'],
8 | 'widget_theme' => 'Widget theme',
9 | 'widget_theme_set' => ['Light', 'Dark'],
10 | 'auto_mode' => 'Automatic translation',
11 | ];
12 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Translator/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Trending Topics',
5 | 'description' => 'Displays the most trending forum topics for a specified period of time.',
6 | 'show_avatars' => 'Show user avatars',
7 | 'time_period' => 'Time period (to determine the frequency of replies)',
8 | 'time_period_set' => ['Day', 'Week', '2 weeks', 'Month', '2 months', '4 months', '6 months', '8 months', 'Year'],
9 | 'min_replies' => 'Minimum number of replies for the specified period',
10 | 'num_topics' => 'Number of topics to display',
11 | 'none' => 'There are no trending topics',
12 | ];
13 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TrendingTopics/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Twenty Forty Eight',
5 | 'description' => 'A simple implementation of the popular game 2048.',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TwentyFortyEight/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Provides the ability to use Twig markup in your own frontpage layouts.',
5 | 'note' => 'To add your template, create a file with the extension %s in the %s directory',
6 | 'example' => 'Example markup',
7 | ];
8 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TwigLayouts/langs/index.php:
--------------------------------------------------------------------------------
1 |
3 | {% endif %}
4 | {# {{ debug(context.user) }} #}
5 |
6 |
7 | {{ show_pagination() }}
8 |
9 | {% for article in context.lp_frontpage_articles %}
10 |
11 | {{ debug(article) }}
12 |
13 | {% endfor %}
14 |
15 | {{ show_pagination('bottom') }}
16 |
17 |
18 | {% if not context.lp_active_blocks %}
19 |
20 | {% endif %}
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/TwigLayouts/layouts/index.php:
--------------------------------------------------------------------------------
1 | 'Using Uicons by Flaticon in the portal blocks\' titles.',
5 | 'weight' => 'Icon Style',
6 | 'weight_set' => ['Regular', 'Bold', 'Solid'],
7 | 'corner' => 'Corners',
8 | 'corner_set' => ['Rounded', 'Straight'],
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/Uicons/langs/index.php:
--------------------------------------------------------------------------------
1 | 'User Info',
5 | 'description' => 'Displays a info about the current user.',
6 | ];
7 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/UserInfo/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Adds the ability to display VK comments on portal pages.',
5 | 'api_id' => 'VK API ID',
6 | 'api_id_subtext' => 'Create application and copy its ID (apiId), to enter here.',
7 | 'comments_per_page' => 'Number of comments per page',
8 | 'allow_attachments' => 'Allow attachments',
9 | 'auto_publish' => 'Post comments on VK user\'s page',
10 | ];
11 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/VkComments/langs/index.php:
--------------------------------------------------------------------------------
1 | 'Who is online',
5 | 'description' => 'Displays a list of online users.',
6 | 'show_group_key' => 'Show user group titles',
7 | 'show_avatars' => 'Show user avatars',
8 | 'update_interval' => 'List refresh interval, in seconds',
9 | ];
10 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Plugins/WhosOnline/langs/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal;
14 |
15 | use Bugo\LightPortal\Areas\ConfigArea;
16 | use Bugo\LightPortal\Areas\CreditArea;
17 |
18 | if (! defined('SMF'))
19 | die('No direct access...');
20 |
21 | final class PortalApp
22 | {
23 | public function __construct()
24 | {
25 | if (SMF === 'BACKGROUND')
26 | return;
27 |
28 | app(Integration::class)();
29 | app(ConfigArea::class)();
30 | app(CreditArea::class)();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Renderers/RendererInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Renderers;
14 |
15 | interface RendererInterface
16 | {
17 | public function getLayouts(): array;
18 |
19 | public function render(string $layout, array $params = []): string;
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Renderers/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Routes;
14 |
15 | use Bugo\Compat\Routable;
16 |
17 | use function array_shift;
18 |
19 | class Forum implements Routable
20 | {
21 | public static function buildRoute(array $params): array
22 | {
23 | $route[] = $params['action'];
24 |
25 | unset($params['action']);
26 |
27 | return ['route' => $route, 'params' => $params];
28 | }
29 |
30 | public static function parseRoute(array $route, array $params = []): array
31 | {
32 | $params['action'] = array_shift($route);
33 |
34 | return $params;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Routes/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | class ColorField extends InputField
19 | {
20 | public function __construct(string $name, string $label)
21 | {
22 | parent::__construct($name, $label);
23 |
24 | $this->setType('color');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/InputField.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | class InputField extends AbstractField
19 | {
20 | public function __construct(string $name, string $label)
21 | {
22 | parent::__construct($name, $label);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/NumberField.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | class NumberField extends InputField
19 | {
20 | public function __construct(string $name, string $label)
21 | {
22 | parent::__construct($name, $label);
23 |
24 | $this
25 | ->setType('number')
26 | ->setAttribute('id', $name);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/TextField.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | class TextField extends InputField
19 | {
20 | public function __construct(string $name, string $label)
21 | {
22 | parent::__construct($name, $label);
23 |
24 | $this->setType('text');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/TextareaField.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | class TextareaField extends AbstractField
19 | {
20 | public function __construct(string $name, string $label)
21 | {
22 | parent::__construct($name, $label);
23 |
24 | $this->setType('textarea');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/UrlField.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | class UrlField extends TextField
19 | {
20 | public function __construct(string $name, string $label)
21 | {
22 | parent::__construct($name, $label);
23 |
24 | $this->setType('url');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/VirtualSelectField.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Fields;
14 |
15 | use Bugo\Compat\Theme;
16 | use Bugo\Compat\Utils;
17 |
18 | if (! defined('SMF'))
19 | die('No direct access...');
20 |
21 | class VirtualSelectField extends SelectField
22 | {
23 | public function __construct(string $name, string $label)
24 | {
25 | parent::__construct($name, $label);
26 |
27 | Theme::addInlineJavaScript('
28 | VirtualSelect.init({
29 | ele: "#' . $name . '",
30 | hideClearButton: true,' . (Utils::$context['right_to_left'] ? '
31 | textDirection: "rtl",' : '') . '
32 | dropboxWrapper: "body"
33 | });', true);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Fields/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Partials;
14 |
15 | use Stringable;
16 |
17 | if (! defined('SMF'))
18 | die('No direct access...');
19 |
20 | abstract class AbstractPartial implements Stringable
21 | {
22 | abstract public function __invoke(): string;
23 |
24 | public function __toString(): string
25 | {
26 | return static::__invoke();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Partials/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\LightPortal\Utils\Str;
16 |
17 | class Button
18 | {
19 | public function __construct(
20 | private readonly string $name,
21 | private readonly string $value,
22 | private readonly string $class = 'button'
23 | ) {}
24 |
25 | public static function make(string $name, string $value, string $class = 'button'): string
26 | {
27 | $button = new self($name, $value, $class);
28 |
29 | return $button->render();
30 | }
31 |
32 | public function render(): string
33 | {
34 | return Str::html('input', [
35 | 'type' => 'submit',
36 | 'name' => $this->name,
37 | 'value' => $this->value,
38 | 'class' => $this->class,
39 | ])->toHtml();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/CheckboxColumn.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Column;
16 | use Bugo\LightPortal\Utils\Str;
17 |
18 | class CheckboxColumn extends Column
19 | {
20 | public static function make(string $name = 'actions', string $title = '', ?string $entity = null): static
21 | {
22 | return parent::make($name, $title ?: Str::html('input', [
23 | 'type' => 'checkbox',
24 | 'onclick' => 'invertAll(this, this.form);',
25 | ])->toHtml())
26 | ->setStyle('width: 5%')
27 | ->setData(static fn($entry) => Str::html('input', [
28 | 'type' => 'checkbox',
29 | 'value' => $entry['id'],
30 | 'name' => $entity . '[]',
31 | ]), 'centertext');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/ExportButtonsRow.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Row;
16 | use Bugo\Compat\Lang;
17 |
18 | class ExportButtonsRow extends Row
19 | {
20 | public static function make(string $value = '', ?string $class = null): static
21 | {
22 | return parent::make($value ?: implode('', [
23 | HiddenInput::make(),
24 | Button::make('export_selection', Lang::$txt['lp_export_selection']),
25 | Button::make('export_all', Lang::$txt['lp_export_all']),
26 | ]), $class ?? '');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/HiddenInput.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\LightPortal\Utils\Str;
16 |
17 | class HiddenInput
18 | {
19 | public static function make(): string
20 | {
21 | $button = new self();
22 |
23 | return $button->render();
24 | }
25 |
26 | public function render(): string
27 | {
28 | return Str::html('input', [
29 | 'type' => 'hidden',
30 | ])->toHtml();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/IconColumn.php:
--------------------------------------------------------------------------------
1 | setData('icon', 'centertext');
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/ImportButtonsRow.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Row;
16 | use Bugo\Compat\Lang;
17 |
18 | class ImportButtonsRow extends Row
19 | {
20 | public static function make(string $value = '', ?string $class = null): static
21 | {
22 | return parent::make($value ?: implode('', [
23 | HiddenInput::make(),
24 | Button::make('import_selection', Lang::$txt['lp_import_selection']),
25 | Button::make('import_all', Lang::$txt['lp_import_all']),
26 | ]), $class ?? '');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/NumViewsColumn.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Column;
16 | use Bugo\Compat\Lang;
17 | use Bugo\LightPortal\Utils\Icon;
18 |
19 | class NumViewsColumn extends Column
20 | {
21 | public static function make(string $name = 'num_views', string $title = ''): static
22 | {
23 | return parent::make($name, $title ?: Icon::get('views', Lang::$txt['lp_views']))
24 | ->setData('num_views', 'centertext')
25 | ->setSort('p.num_views DESC', 'p.num_views');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/PageSlugColumn.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Column;
16 | use Bugo\Compat\Lang;
17 |
18 | class PageSlugColumn extends Column
19 | {
20 | public static function make(string $name = 'slug', string $title = ''): static
21 | {
22 | return parent::make($name, $title ?: Lang::$txt['lp_page_slug'])
23 | ->setData('slug', 'centertext')
24 | ->setSort('p.slug DESC', 'p.slug');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/PortalTableBuilderInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Interfaces\TableBuilderInterface;
16 |
17 | interface PortalTableBuilderInterface extends TableBuilderInterface
18 | {
19 | public function withCreateButton(string $entity, string $title = ''): self;
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/TableRenderer.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Renderers\RendererInterface;
16 | use Bugo\Compat\ItemList;
17 | use Bugo\Compat\Utils;
18 |
19 | class TableRenderer implements RendererInterface
20 | {
21 | public function render(array $data): void
22 | {
23 | new ItemList($data);
24 |
25 | Utils::$context['sub_template'] = 'show_list';
26 | Utils::$context['default_list'] = $data['id'];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/TitleColumn.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\UI\Tables;
14 |
15 | use Bugo\Bricks\Tables\Column;
16 | use Bugo\Compat\Lang;
17 | use Bugo\LightPortal\Utils\Str;
18 |
19 | class TitleColumn extends Column
20 | {
21 | public static function make(string $name = 'title', string $title = '', ?string $entity = null): static
22 | {
23 | return parent::make($name, $title ?: Lang::$txt['lp_title'])
24 | ->setData(static fn($entry) => $entry['status']
25 | ? Str::html('a', ['class' => 'bbc_link'])
26 | ->href(LP_BASE_URL . ";sa=$entity;id=" . $entry['id'])
27 | ->setText($entry['title'])
28 | : $entry['title'], 'word_break')
29 | ->setSort('t.value DESC', 't.value');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/UI/Tables/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | use const LP_CACHE_TIME;
16 |
17 | interface CacheInterface
18 | {
19 | public function withKey(?string $key): self;
20 |
21 | public function setLifeTime(int $lifeTime): self;
22 |
23 | public function remember(string $key, callable $callback, int $time = LP_CACHE_TIME ?? 0): mixed;
24 |
25 | public function setFallback(callable $callback): mixed;
26 |
27 | public function get(string $key, int $time): mixed;
28 |
29 | public function put(string $key, mixed $value, int $time): void;
30 |
31 | public function forget(string $key): void;
32 |
33 | public function flush(): void;
34 | }
35 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/File.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | final class File extends GlobalArray
19 | {
20 | public function __construct()
21 | {
22 | $this->storage = &$_FILES;
23 | }
24 |
25 | public function free(string $key): void
26 | {
27 | unset($this->storage[$key]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/ParamWrapper.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | use ArrayAccess;
16 |
17 | class ParamWrapper implements ArrayAccess
18 | {
19 | public function __construct(private array $storage = []) {}
20 |
21 | public function offsetExists(mixed $offset): bool
22 | {
23 | return isset($this->storage[$offset]);
24 | }
25 |
26 | public function offsetGet(mixed $offset): mixed
27 | {
28 | return $this->storage[$offset] ?? null;
29 | }
30 |
31 | public function offsetSet(mixed $offset, mixed $value): void
32 | {
33 | $this->storage[$offset] = $value;
34 | }
35 |
36 | public function offsetUnset(mixed $offset): void
37 | {
38 | unset($this->storage[$offset]);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Post.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | final class Post extends GlobalArray
19 | {
20 | public function __construct()
21 | {
22 | $this->storage = &$_POST;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Response.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | use Bugo\Compat\Utils;
16 |
17 | use function header;
18 | use function json_encode;
19 |
20 | class Response
21 | {
22 | public function json(mixed $data, int $flags = 0): false|string
23 | {
24 | header('Content-Type: application/json; charset=utf-8');
25 |
26 | return json_encode($data, $flags);
27 | }
28 |
29 | public function exit(mixed $data, int $flags = 0): never
30 | {
31 | exit($this->json($data, $flags));
32 | }
33 |
34 | public function redirect(string $url = ''): void
35 | {
36 | Utils::redirectexit($url);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Session.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | if (! defined('SMF'))
16 | die('No direct access...');
17 |
18 | final class Session extends GlobalArray
19 | {
20 | public function __construct(?string $key = null)
21 | {
22 | if ($key) {
23 | if (! isset($_SESSION[$key])) {
24 | $_SESSION[$key] = [];
25 | }
26 |
27 | $this->storage = &$_SESSION[$key];
28 | return;
29 | }
30 |
31 | $this->storage = &$_SESSION;
32 | }
33 |
34 | public function withKey(?string $key): self
35 | {
36 | return new self($key);
37 | }
38 |
39 | public function free(string $key): void
40 | {
41 | unset($this->storage[$key]);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/HasBreadcrumbs.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils\Traits;
14 |
15 | use Bugo\LightPortal\Utils\Breadcrumbs;
16 |
17 | trait HasBreadcrumbs
18 | {
19 | public function breadcrumbs(): Breadcrumbs
20 | {
21 | return app(Breadcrumbs::class);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/HasForumHooks.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils\Traits;
14 |
15 | use Bugo\Compat\IntegrationHook;
16 | use Bugo\LightPortal\Enums\Hook;
17 |
18 | use function method_exists;
19 |
20 | if (! defined('SMF'))
21 | die('No direct access...');
22 |
23 | trait HasForumHooks
24 | {
25 | protected function applyHook(Hook $hook, ?string $class = null): void
26 | {
27 | $class ??= static::class;
28 |
29 | $method = method_exists($class, $hook->name) ? $hook->name : '__invoke';
30 |
31 | IntegrationHook::add($hook->name(), "$class::$method#", false);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/HasReflection.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils\Traits;
14 |
15 | use ReflectionClass;
16 |
17 | if (! defined('SMF'))
18 | die('No direct access...');
19 |
20 | trait HasReflection
21 | {
22 | public function getCalledClass(): ReflectionClass
23 | {
24 | return new ReflectionClass(static::class);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/HasRequest.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils\Traits;
14 |
15 | use Bugo\LightPortal\Utils\File;
16 | use Bugo\LightPortal\Utils\Post;
17 | use Bugo\LightPortal\Utils\Request;
18 |
19 | trait HasRequest
20 | {
21 | public function request(): Request
22 | {
23 | return app(Request::class);
24 | }
25 |
26 | public function post(): Post
27 | {
28 | return app(Post::class);
29 | }
30 |
31 | public function files(): File
32 | {
33 | return app(File::class);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/HasResponse.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils\Traits;
14 |
15 | use Bugo\LightPortal\Utils\Response;
16 |
17 | trait HasResponse
18 | {
19 | public function response(): Response
20 | {
21 | return app(Response::class);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/HasSession.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils\Traits;
14 |
15 | use Bugo\LightPortal\Utils\Session;
16 |
17 | trait HasSession
18 | {
19 | public function session(?string $key = null): Session
20 | {
21 | return $key === null
22 | ? app(Session::class)
23 | : app(Session::class)->withKey($key);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/Traits/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Utils;
14 |
15 | use Bugo\Compat\ErrorHandler;
16 | use Fiber;
17 | use Throwable;
18 |
19 | class Weaver
20 | {
21 | public function __invoke(callable $callback): array
22 | {
23 | $fiber = new Fiber(function () use ($callback) {
24 | $data = $callback();
25 | Fiber::suspend($data);
26 | });
27 |
28 | try {
29 | return $fiber->start();
30 | } catch (Throwable $e) {
31 | ErrorHandler::fatal($e->getMessage(), false);
32 | }
33 |
34 | return [];
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Utils/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Validators;
14 |
15 | class CategoryValidator extends AbstractValidator
16 | {
17 | protected array $filters = [
18 | 'category_id' => FILTER_VALIDATE_INT,
19 | 'icon' => FILTER_DEFAULT,
20 | 'description' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
21 | ];
22 | }
23 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Validators/TagValidator.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Validators;
14 |
15 | class TagValidator extends AbstractValidator
16 | {
17 | protected array $filters = [
18 | 'tag_id' => FILTER_VALIDATE_INT,
19 | 'icon' => FILTER_DEFAULT,
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Validators/ValidatorInterface.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | namespace Bugo\LightPortal\Validators;
14 |
15 | interface ValidatorInterface
16 | {
17 | public function validate(): array;
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/Validators/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | if (! defined('SMF'))
14 | die('We gotta get out of here!');
15 |
16 | require_once __DIR__ . '/Libs/autoload.php';
17 |
18 | use Bugo\Compat\ErrorHandler;
19 | use Bugo\LightPortal\Container;
20 | use Bugo\LightPortal\PortalApp;
21 |
22 | /**
23 | * @template RequestedType
24 | * @param class-string|string $service
25 | * @return RequestedType|mixed
26 | */
27 | function app(string $service = ''): mixed
28 | {
29 | if (empty($service)) {
30 | return Container::getInstance();
31 | }
32 |
33 | try {
34 | return Container::get($service);
35 | } catch (Throwable $e) {
36 | ErrorHandler::fatal($e->getMessage(), 'critical');
37 | }
38 |
39 | return false;
40 | }
41 |
42 | // This is the way
43 | app(PortalApp::class);
44 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "php": "~8.1",
4 | "ext-dom": "*",
5 | "ext-intl": "*",
6 | "ext-simplexml": "*",
7 | "ext-zip": "*",
8 | "bugo/fa-php-helper": "^0.5",
9 | "bugo/smf-bricks": "^0.5",
10 | "bugo/smf-compat": "^0.3",
11 | "doctrine/event-manager": "^2.0",
12 | "eftec/bladeone": "^4.13",
13 | "league/container": "^5.0",
14 | "wplake/typed": "^1.1"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "Bugo\\LightPortal\\": ""
19 | },
20 | "exclude-from-classmap": [
21 | "Plugins"
22 | ]
23 | },
24 | "config": {
25 | "vendor-dir": "Libs",
26 | "optimize-autoloader": true,
27 | "preferred-install": "dist",
28 | "sort-packages": true,
29 | "platform": {
30 | "php": "8.1"
31 | }
32 | },
33 | "scripts": {
34 | "post-update-cmd": [
35 | "@php update_plugins.php",
36 | "@php create_index.php"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Sources/LightPortal/create_index.php:
--------------------------------------------------------------------------------
1 | getPathname(), 'Libs'))
12 | continue;
13 |
14 | if (str_contains((string) $directory->getPathname(), 'packages'))
15 | continue;
16 |
17 | if ($directory->isDir() && ! file_exists($directory . '/index.php')) {
18 | file_put_contents($directory . '/index.php', '';
10 | }
11 |
12 | echo /** @lang text */ '
13 |
14 | ';
17 | }
18 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/ViewDebug.template.php:
--------------------------------------------------------------------------------
1 |
14 |
15 | ' . Lang::$txt['admin_search_type_online'] . '
16 |
17 | ';
18 | }
19 |
20 | function template_docs_below()
21 | {
22 | }
23 |
24 | function template_debug_above()
25 | {
26 | }
27 |
28 | function template_debug_below(): void
29 | {
30 | echo '
31 |
32 | ', Utils::$context['lp_load_page_stats'], '
33 |
';
34 | }
35 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/index.php:
--------------------------------------------------------------------------------
1 | @dump($context['user']) -->
5 |
6 |
7 | @include('partials.pagination')
8 |
9 | @foreach ($context['lp_frontpage_articles'] as $article)
10 |
15 |
16 | {!! parse_bbc('[code]' . print_r($article, true) . '[/code]') !!}
17 |
18 |
19 | @endforeach
20 |
21 | @include('partials.pagination', ['position' => 'bottom'])
22 |
23 | @endsection
24 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/default.blade.php:
--------------------------------------------------------------------------------
1 | @extends('partials.base')
2 |
3 | @section('content')
4 |
5 | @include('partials.pagination')
6 |
7 | @foreach ($context['lp_frontpage_articles'] as $article)
8 |
9 |
10 | @include('partials.image', ['article' => $article])
11 |
12 | @include('partials.card', ['article' => $article])
13 |
14 |
15 | @endforeach
16 |
17 | @include('partials.pagination', ['position' => 'bottom'])
18 |
19 | @endsection
20 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/index.php:
--------------------------------------------------------------------------------
1 |
3 | @endempty
4 |
5 | @yield('content')
6 |
7 | @empty ($context['lp_active_blocks'])
8 |
9 | @endempty
10 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/partials/card-header.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @unless (empty($article['section']['name']))
3 |
4 | @empty ($article['section']['icon'])
5 | @icon('category')
6 | @else
7 | {!! $article['section']['icon'] !!}
8 | @endempty
9 |
10 | {{ $article['section']['name'] }}
11 |
12 | @endunless
13 |
14 | @if ($article['is_new'] && empty($article['image']))
15 |
16 | {{ $txt['new'] }}
17 |
18 | @endif
19 |
20 | @unless (empty($article['datetime']))
21 |
24 | @endunless
25 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/partials/card.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @include('partials.card-header', ['article' => $article])
3 |
4 |
7 |
8 | @unless (empty($article['teaser']))
9 |
{{ $article['teaser'] }}
10 | @endunless
11 |
12 | @include('partials.card-footer', ['article' => $article])
13 |
14 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/partials/image.blade.php:
--------------------------------------------------------------------------------
1 | @unless (empty($article['image']))
2 | @if ($article['is_new'])
3 |
4 |
5 | {{ $txt['new'] }}
6 |
7 |
8 | @endif
9 |
10 | @if ($article['can_edit'])
11 |
16 | @endif
17 |
18 |
19 |
20 |
21 |
22 | @endunless
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/partials/index.php:
--------------------------------------------------------------------------------
1 |
5 | @include('partials.pagination')
6 |
7 | @foreach ($context['lp_frontpage_articles'] as $article)
8 |
9 | @unless (empty($article['image']))
10 |
11 | @endunless
12 |
13 |
14 |
{{ $article['title'] }}
15 |
16 | @unless (empty($article['teaser']))
17 |
{{ $article['teaser'] }}
18 | @endunless
19 |
20 |
21 |
24 |
25 | @endforeach
26 |
27 | @include('partials.pagination', ['position' => 'bottom'])
28 |
29 | @endsection
30 |
--------------------------------------------------------------------------------
/src/Themes/default/LightPortal/layouts/simple_grid.blade.php:
--------------------------------------------------------------------------------
1 | @extends('partials.base')
2 |
3 | @section('content')
4 | @include('partials.pagination')
5 |
6 |
7 | @foreach ($context['lp_frontpage_articles'] as $article)
8 |
9 | @unless (empty($article['image']))
10 |
![{{ $article['title'] }}]()
11 | @endunless
12 |
13 |
16 |
17 | @endforeach
18 |
19 |
20 | @include('partials.pagination', ['position' => 'bottom'])
21 | @endsection
22 |
--------------------------------------------------------------------------------
/src/Themes/default/css/light_portal/index.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright 2019-2025 Bugo
8 | * @license https://spdx.org/licenses/GPL-3.0-or-later.html GPL-3.0-or-later
9 | *
10 | * @version 2.9
11 | */
12 |
13 | use Bugo\Compat\{Config, Lang, Utils};
14 | use Bugo\LightPortal\Actions\FrontPage;
15 |
16 | require_once __DIR__ . '/SSI.php';
17 |
18 | if (empty(Config::$sourcedir)) {
19 | die('' . Lang::$txt['error_occured'] . ' ' . Lang::$txt['lp_standalone_mode_error']);
20 | }
21 |
22 | if (empty(Config::$modSettings['lp_standalone_mode']) || empty(Config::$modSettings['lp_standalone_url'])) {
23 | Utils::redirectexit();
24 | }
25 |
26 | try {
27 | app(FrontPage::class)->show();
28 | } catch (Exception $e) {
29 | die($e->getMessage());
30 | }
31 |
32 | Utils::obExit();
33 |
--------------------------------------------------------------------------------
/src/uninstall.php:
--------------------------------------------------------------------------------
1 | Error: Cannot install - please verify that you put this file in the same place as SMF\'s index.php and SSI.php files.');
9 | }
10 |
11 | if ((SMF === 'SSI') && ! $user_info['is_admin']) {
12 | die('Admin privileges required.');
13 | }
14 |
15 | $smcFunc['db_query']('', '
16 | DELETE FROM {db_prefix}background_tasks
17 | WHERE task_file LIKE {string:task_file}',
18 | [
19 | 'task_file' => '%$sourcedir/LightPortal%'
20 | ]
21 | );
22 |
23 | if (SMF === 'SSI') {
24 | echo 'Database changes are complete! Please wait...';
25 | }
26 |
27 | echo 'I\'ll see you again. I promise ©️';
28 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowJs": true,
7 | "checkJs": true,
8 | "esModuleInterop": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "resolveJsonModule": true,
11 | "skipLibCheck": true,
12 | "noEmit": true,
13 | "allowImportingTsExtensions": true,
14 | "verbatimModuleSyntax": true,
15 | "isolatedModules": true
16 | },
17 | "include": ["resources"]
18 | }
19 |
--------------------------------------------------------------------------------