├── .github ├── javascript-syntax.json ├── php-syntax.json └── workflows │ ├── codestyle.yml │ ├── javascript.yml │ ├── php.yml │ └── templates.yml ├── .phpcs.xml ├── LICENSE ├── README.md ├── acptemplates ├── __cmsVersion.tpl ├── __menuItemAddJavascript.tpl ├── __pageMenuInfo.tpl ├── boxContentType.tpl ├── categoryFileListDialog.tpl ├── columnsContentType.tpl ├── contentAdd.tpl ├── contentContentType.tpl ├── contentItemsList.tpl ├── contentList.tpl ├── contentTypeList.tpl ├── databaseObjectListContentType.tpl ├── fileContentType.tpl ├── fileDetails.tpl ├── fileList.tpl ├── fileListDialog.tpl ├── filePreview.tpl ├── fileUploadDialog.tpl ├── galleryContentType.tpl ├── googleMapsContentType.tpl ├── groupContentType.tpl ├── headlineContentType.tpl ├── imageContentType.tpl ├── imageList.tpl ├── import.tpl ├── linkContentType.tpl ├── linkPageType.tpl ├── menuContentType.tpl ├── pageAdd.tpl ├── pageList.tpl ├── pageMultiSelectOptionType.tpl ├── pagePageType.tpl ├── pageRevisionList.tpl ├── pageSelectOptionType.tpl ├── phpContentType.tpl ├── pieChartContentType.tpl ├── pollContentType.tpl ├── rssContentType.tpl ├── slideshowContentType.tpl ├── stats.tpl ├── stylesheetAdd.tpl ├── stylesheetList.tpl ├── tabMenuContentType.tpl ├── templateContentType.tpl ├── textContentType.tpl ├── userContentType.tpl ├── wsipImportContentType.tpl └── youtubeContentType.tpl ├── constants.php ├── files ├── acp │ ├── global.php │ ├── index.php │ ├── install_de.codequake.cms.php │ └── js │ │ ├── Fireball.ACP.js │ │ └── Fireball.ACP.min.js ├── files │ ├── .htaccess │ └── thumbnails │ │ └── .gitignore ├── global.php ├── index.php ├── js │ ├── Fireball.js │ ├── Fireball.min.js │ └── codeQuake │ │ └── Acp │ │ └── FileInlineEditor.js ├── lib │ ├── acp │ │ ├── action │ │ │ └── CMSExportAction.class.php │ │ ├── form │ │ │ ├── CMSImportForm.class.php │ │ │ ├── ContentAddForm.class.php │ │ │ ├── ContentEditForm.class.php │ │ │ ├── FileCategoryAddForm.class.php │ │ │ ├── FileCategoryEditForm.class.php │ │ │ ├── PageAddForm.class.php │ │ │ ├── PageEditForm.class.php │ │ │ ├── StylesheetAddForm.class.php │ │ │ └── StylesheetEditForm.class.php │ │ └── page │ │ │ ├── ContentListPage.class.php │ │ │ ├── FileCategoryListPage.class.php │ │ │ ├── FileListPage.class.php │ │ │ ├── PageListPage.class.php │ │ │ ├── StatsPage.class.php │ │ │ └── StylesheetListPage.class.php │ ├── data │ │ ├── content │ │ │ ├── BoxContentNodeTree.class.php │ │ │ ├── Content.class.php │ │ │ ├── ContentAction.class.php │ │ │ ├── ContentCache.class.php │ │ │ ├── ContentEditor.class.php │ │ │ ├── ContentList.class.php │ │ │ ├── ContentNode.class.php │ │ │ ├── ContentNodeTree.class.php │ │ │ ├── DrainedContentNodeTree.class.php │ │ │ ├── DrainedPositionContentNodeTree.class.php │ │ │ ├── ViewableContent.class.php │ │ │ └── ViewableContentList.class.php │ │ ├── file │ │ │ ├── CategoryFileList.class.php │ │ │ ├── File.class.php │ │ │ ├── FileAction.class.php │ │ │ ├── FileCache.class.php │ │ │ ├── FileEditor.class.php │ │ │ └── FileList.class.php │ │ ├── page │ │ │ ├── AccessiblePageNodeTree.class.php │ │ │ ├── DrainedPageNodeTree.class.php │ │ │ ├── Page.class.php │ │ │ ├── PageAction.class.php │ │ │ ├── PageCache.class.php │ │ │ ├── PageEditor.class.php │ │ │ ├── PageList.class.php │ │ │ ├── PageNode.class.php │ │ │ ├── PageNodeTree.class.php │ │ │ ├── SearchResultPage.class.php │ │ │ ├── SearchResultPageList.class.php │ │ │ ├── ViewablePage.class.php │ │ │ ├── ViewablePageNodeTree.class.php │ │ │ └── revision │ │ │ │ ├── PageRevision.class.php │ │ │ │ ├── PageRevisionAction.class.php │ │ │ │ ├── PageRevisionEditor.class.php │ │ │ │ └── PageRevisionList.class.php │ │ └── stylesheet │ │ │ ├── Stylesheet.class.php │ │ │ ├── StylesheetAction.class.php │ │ │ ├── StylesheetCache.class.php │ │ │ ├── StylesheetEditor.class.php │ │ │ └── StylesheetList.class.php │ ├── page │ │ ├── AbstractCMSPage.class.php │ │ ├── FileDownloadPage.class.php │ │ ├── ICMSPage.class.php │ │ ├── LinkPage.class.php │ │ ├── PagePage.class.php │ │ └── SitemapPage.class.php │ ├── system │ │ ├── CMSCore.class.php │ │ ├── backup │ │ │ └── BackupHandler.class.php │ │ ├── bbcode │ │ │ ├── CMSFileBBCode.class.php │ │ │ ├── CMSFileUrlBBCode.class.php │ │ │ └── PageBBCode.class.php │ │ ├── cache │ │ │ └── builder │ │ │ │ ├── ContentCacheBuilder.class.php │ │ │ │ ├── ContentPermissionCacheBuilder.class.php │ │ │ │ ├── FileCacheBuilder.class.php │ │ │ │ ├── FilePermissionCacheBuilder.class.php │ │ │ │ ├── PageCacheBuilder.class.php │ │ │ │ ├── PagePermissionCacheBuilder.class.php │ │ │ │ └── StylesheetCacheBuilder.class.php │ │ ├── category │ │ │ └── FileCategoryType.class.php │ │ ├── clipboard │ │ │ └── action │ │ │ │ ├── ContentClipboardAction.class.php │ │ │ │ ├── FileClipboardAction.class.php │ │ │ │ ├── PageClipboardAction.class.php │ │ │ │ └── StylesheetClipboardAction.class.php │ │ ├── comment │ │ │ └── manager │ │ │ │ └── PageCommentManager.class.php │ │ ├── condition │ │ │ └── PagePageCondition.class.php │ │ ├── content │ │ │ ├── ContentPermissionHandler.class.php │ │ │ └── type │ │ │ │ ├── AbstractContentType.class.php │ │ │ │ ├── AbstractDatabaseObjectListContentType.class.php │ │ │ │ ├── AbstractSearchableContentType.class.php │ │ │ │ ├── AbstractStructureContentType.class.php │ │ │ │ ├── BoxContentType.class.php │ │ │ │ ├── ColumnsContentType.class.php │ │ │ │ ├── ContentContentType.class.php │ │ │ │ ├── FileContentType.class.php │ │ │ │ ├── GalleryContentType.class.php │ │ │ │ ├── GoogleMapsContentType.class.php │ │ │ │ ├── GroupContentType.class.php │ │ │ │ ├── HeadlineContentType.class.php │ │ │ │ ├── IContentType.class.php │ │ │ │ ├── ISearchableContentType.class.php │ │ │ │ ├── ImageContentType.class.php │ │ │ │ ├── LinkContentType.class.php │ │ │ │ ├── MenuContentType.class.php │ │ │ │ ├── PHPContentType.class.php │ │ │ │ ├── PollContentType.class.php │ │ │ │ ├── RssContentType.class.php │ │ │ │ ├── SlideshowContentType.class.php │ │ │ │ ├── TabMenuContentType.class.php │ │ │ │ ├── TemplateContentType.class.php │ │ │ │ ├── TextContentType.class.php │ │ │ │ ├── UserContentType.class.php │ │ │ │ ├── WSIPImportContentType.class.php │ │ │ │ ├── YoutubeContentType.class.php │ │ │ │ └── graph │ │ │ │ └── PieChartContentType.class.php │ │ ├── counter │ │ │ └── VisitCountHandler.class.php │ │ ├── cronjob │ │ │ └── PublicationCronjob.class.php │ │ ├── event │ │ │ └── listener │ │ │ │ ├── CommentActionListener.class.php │ │ │ │ ├── DailyCleanUpListener.class.php │ │ │ │ ├── UserRenameListener.class.php │ │ │ │ └── WSIPImportContentTypeListener.class.php │ │ ├── exporter │ │ │ ├── Fireball2Exporter.class.php │ │ │ └── InfinitePortalExporter.class.php │ │ ├── file │ │ │ └── FilePermissionHandler.class.php │ │ ├── importer │ │ │ ├── ContentImporter.class.php │ │ │ ├── FileCategoryImporter.class.php │ │ │ ├── FileImporter.class.php │ │ │ ├── PageACLImporter.class.php │ │ │ ├── PageCommentImporter.class.php │ │ │ ├── PageCommentResponseImporter.class.php │ │ │ ├── PageImporter.class.php │ │ │ └── StylesheetImporter.class.php │ │ ├── option │ │ │ ├── CMSPageMultiSelectOptionType.class.php │ │ │ └── CMSPageSelectOptionType.class.php │ │ ├── page │ │ │ ├── PagePermissionHandler.class.php │ │ │ ├── handler │ │ │ │ ├── PagePageHandler.class.php │ │ │ │ └── TPageOnlineLocationPageHandler.class.php │ │ │ └── type │ │ │ │ ├── AbstractPageType.class.php │ │ │ │ ├── IPageType.class.php │ │ │ │ ├── LinkPageType.class.php │ │ │ │ └── PagePageType.class.php │ │ ├── poll │ │ │ └── ContentPollHandler.class.php │ │ ├── search │ │ │ ├── PageSearch.class.php │ │ │ └── acp │ │ │ │ └── PageACPSearchResultProvider.class.php │ │ ├── sitemap │ │ │ └── object │ │ │ │ └── PageSitemapObject.class.php │ │ ├── stat │ │ │ ├── PageCommentStatDailyHandler.class.php │ │ │ └── PageStatDailyHandler.class.php │ │ ├── style │ │ │ └── StylesheetCompiler.class.php │ │ ├── template │ │ │ └── EnvironmentTemplateEngine.class.php │ │ ├── user │ │ │ ├── activity │ │ │ │ └── event │ │ │ │ │ ├── PageCommentResponseUserActivityEvent.class.php │ │ │ │ │ └── PageCommentUserActivityEvent.class.php │ │ │ ├── notification │ │ │ │ ├── event │ │ │ │ │ ├── PageCommentResponseUserNotificationEvent.class.php │ │ │ │ │ └── PageCommentUserNotificationEvent.class.php │ │ │ │ └── object │ │ │ │ │ └── type │ │ │ │ │ ├── PageCommentResponseUserNotificationObjectType.class.php │ │ │ │ │ └── PageCommentUserNotificationObjectType.class.php │ │ │ └── object │ │ │ │ └── watch │ │ │ │ └── PageUserObjectWatch.class.php │ │ └── worker │ │ │ ├── ContentRebuildDataWorker.class.php │ │ │ ├── FileRebuildDataWorker.class.php │ │ │ └── PageRebuildDataWorker.class.php │ └── util │ │ ├── Browser.php │ │ ├── BrowserUtil.class.php │ │ └── PageUtil.class.php └── style │ ├── cms.scss │ ├── grid.scss │ └── presetClasses.scss ├── files_wcf ├── lib │ └── system │ │ ├── event │ │ └── listener │ │ │ └── FireballRouteListener.class.php │ │ └── request │ │ └── route │ │ └── FireballRequestRoute.class.php └── style │ └── ui │ └── fireball.scss ├── install.sql ├── language ├── de-informal.xml ├── de.xml └── en.xml ├── package.xml ├── templates ├── __copyright.tpl ├── __pageAddButton.tpl ├── cmsFileBBCodeTag.tpl ├── contentAddDialog.tpl ├── contentNodeList.tpl ├── contentTypeList.tpl ├── fileContentType.tpl ├── galleryContentType.tpl ├── googleMapsContentType.tpl ├── headlineContentType.tpl ├── imageContentType.tpl ├── inlineEditor_boxContentType.tpl ├── inlineEditor_columnsContentType.tpl ├── inlineEditor_contentContentType.tpl ├── inlineEditor_databaseObjectListContentType.tpl ├── inlineEditor_fileContentType.tpl ├── inlineEditor_galleryContentType.tpl ├── inlineEditor_googleMapsContentType.tpl ├── inlineEditor_groupContentType.tpl ├── inlineEditor_headlineContentType.tpl ├── inlineEditor_imageContentType.tpl ├── inlineEditor_linkContentType.tpl ├── inlineEditor_menuContentType.tpl ├── inlineEditor_phpContentType.tpl ├── inlineEditor_pieChartContentType.tpl ├── inlineEditor_pollContentType.tpl ├── inlineEditor_rssContentType.tpl ├── inlineEditor_slideshowContentType.tpl ├── inlineEditor_tabMenuContentType.tpl ├── inlineEditor_templateContentType.tpl ├── inlineEditor_textContentType.tpl ├── inlineEditor_userContentType.tpl ├── inlineEditor_youtubeContentType.tpl ├── linkContentType.tpl ├── menuContentType.tpl ├── page.tpl ├── pageAddDialog.tpl ├── pageEditor.tpl ├── pieChartContentType.tpl ├── rssContentType.tpl ├── sitemap.tpl ├── slideshowContentType.tpl ├── sortableContentList.tpl ├── tabMenuContentType.tpl └── userContentType.tpl └── xml ├── aclOption.xml ├── acpMenu.xml ├── acpSearchProvider.xml ├── bbcode.xml ├── clipboardAction.xml ├── cronjob.xml ├── eventlistener.xml ├── menuItem.xml ├── objectType.xml ├── objectTypeDefinition.xml ├── option.xml ├── page.xml ├── templateListener.xml ├── userGroupOption.xml └── userNotificationEvent.xml /.github/javascript-syntax.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "node -c", 5 | "pattern": [ 6 | { 7 | "regexp": "^(./\\S+):(\\d+) - (.*)$", 8 | "file": 1, 9 | "line": 2, 10 | "message": 3 11 | } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.github/php-syntax.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "php -l", 5 | "pattern": [ 6 | { 7 | "regexp": "^\\s*(PHP\\s+)?([a-zA-Z\\s]+):\\s+(.*)\\s+in\\s+(\\S+)\\s+on\\s+line\\s+(\\d+)$", 8 | "file": 4, 9 | "line": 5, 10 | "message": 3 11 | } 12 | ] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/codestyle.yml: -------------------------------------------------------------------------------- 1 | name: Code Style 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | php: 9 | name: PHP CodeSniffer 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - run: git clone --branch=master --depth=1 --quiet git://github.com/WoltLab/WCF.git WCF 14 | - uses: chekalsky/phpcs-action@e269c2f264f400adcda7c6b24c8550302350d495 15 | -------------------------------------------------------------------------------- /.github/workflows/javascript.yml: -------------------------------------------------------------------------------- 1 | name: JavaScript 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | syntax: 9 | name: "Check Syntax" 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | steps: 14 | - name: Set up node.js 15 | uses: actions/setup-node@v1 16 | with: 17 | node-version: "12" 18 | - uses: actions/checkout@v2 19 | - run: echo "::add-matcher::.github/javascript-syntax.json" 20 | - name: Remove files to be ignored 21 | run: | 22 | true 23 | - run: | 24 | ! find . -type f -name '*.js' -exec node -c '{}' \; 2>&1 \ 25 | |awk 'BEGIN {m=0} /(.js):[0-9]+$/ {m=1; printf "%s - ",$0} m==1 && /^SyntaxError/ { m=0; print }' \ 26 | |sed "s@$(pwd)@.@" \ 27 | |grep '^' 28 | -------------------------------------------------------------------------------- /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: PHP 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | syntax: 9 | name: "Check Syntax (${{ matrix.php }})" 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | php: 15 | - '7.2' 16 | - '7.3' 17 | - '7.4' 18 | - '8.0' 19 | steps: 20 | - name: Set up PHP 21 | uses: shivammathur/setup-php@v2 22 | with: 23 | php-version: ${{ matrix.php }} 24 | - uses: actions/checkout@v2 25 | - run: echo "::add-matcher::.github/php-syntax.json" 26 | - name: Remove files to be ignored 27 | run: | 28 | true 29 | - run: | 30 | ! find . -type f -name '*.php' -exec php -l '{}' \; 2>&1 |grep -v '^No syntax errors detected' 31 | -------------------------------------------------------------------------------- /.github/workflows/templates.yml: -------------------------------------------------------------------------------- 1 | name: Templates 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | sync: 9 | name: Check for differing synced templates. 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - run: sudo apt-get install -y jq diffutils 14 | - name: Check for differences in frontend 15 | run: | 16 | for template in $(jq -r '.templates[] + ".tpl"' < syncTemplates.json); do 17 | defaultDirectory="$(jq -r '.directories[0]' < syncTemplates.json)" 18 | for directory in $(jq -r '.directories[]' < syncTemplates.json); do 19 | diff -u $defaultDirectory/$template $directory/$template 20 | done 21 | done 22 | - name: Check for differences in acp 23 | run: | 24 | for template in $(jq -r '.acptemplates[] + ".tpl"' < syncTemplates.json); do 25 | defaultDirectory="$(jq -r '.directories[0]' < syncTemplates.json)" 26 | for directory in $(jq -r '.directories[]' < syncTemplates.json); do 27 | diff -u $defaultDirectory/$template $directory/$template 28 | done 29 | done 30 | -------------------------------------------------------------------------------- /.phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | files/ 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Fireball CMS 2 | ======== 3 | The Fireball CMS is a very powerful CMS solution, based on WoltLab Suite Core 3.0. It's full responsive, so you can use the CMS on any device you want (PC, Smartphones or Tablet-PCs). With Fireball CMS you can easily build up your own professional website with all features you like. You can use the latest technologies of CSS3, HTML5, SCSS & PHP. 4 | 5 | [![Build Status](https://travis-ci.org/codeQuake/Fireball.svg?branch=v3.2)](https://travis-ci.org/codeQuake/Fireball) 6 | 7 | DANGER 8 | --------------------------------------------------------------------------------------- 9 | This is an experimental branch, working on a frontend editing feature. The Frontend-Editor can look similar like shown in the image below. Please do not install or use this branch as a public system due to a lot of issues. (Release not guaranteed - experiments are just for fun) 10 | 11 | Plugins 12 | ------------------- 13 | Fireball CMS is easily extendable due to the WCF's plugin system. There are a lot of optional features packed in the following plugins: 14 | - [Fireball CMS - News System](https://github.com/codeQuake/Fireball_News) 15 | - [Fireball CMS - News System - RSS Reader](https://github.com/codeQuake/Fireball-News-RSS-Reader) 16 | - [Fireball CMS - News System - Burning Board Integration](https://github.com/codeQuake/Fireball_News_WBB) 17 | - [Fireball CMS - Burning Board Integration](https://github.com/codeQuake/Fireball_WBB) 18 | 19 | The following plugins are required to install Fireball CMS: 20 | - [ACP WYSIWYG](https://github.com/codeQuake/WYSIWYG-ACP) 21 | 22 | System Requirements 23 | ------------------- 24 | - PHP Version: 7.0.22 or greater 25 | - MySQL Version: 5.5.35 or greater with InnoDB-Support 26 | - OR MariaDB Version: 10.0.22 or greater with InnoDB-Support 27 | - WoltLab Suite Core Version: 3.1.9 pl 2 or greater 28 | - WYSIWYG-ACP Plugin (included) Version: 1.2.0 or greater 29 | 30 | ###PHP Extensions 31 | mbstring, libxml, dom, zlib, pdo, pdo_mysql, json, pcre 32 | 33 | Contributions 34 | ---------------- 35 | If you want to support the development, you are allowed to use pull requests or submit issues. 36 | 37 | License 38 | ---------------- 39 | All files are LGPL licensed: GNU Lesser General Public License http://opensource.org/licenses/lgpl-license.php 40 | -------------------------------------------------------------------------------- /acptemplates/__cmsVersion.tpl: -------------------------------------------------------------------------------- 1 |
2 |
{lang}wcf.acp.index.system.software.cmsVersion{/lang}
3 |
{$__cms->getPackage()->packageVersion}
4 |
5 | -------------------------------------------------------------------------------- /acptemplates/__menuItemAddJavascript.tpl: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /acptemplates/__pageMenuInfo.tpl: -------------------------------------------------------------------------------- 1 | {js application='cms' file='Fireball.ACP' acp='true'} 2 | 3 | 12 | -------------------------------------------------------------------------------- /acptemplates/boxContentType.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /acptemplates/categoryFileListDialog.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{$category->getTitle()}

4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {event name='columnHeads'} 15 | 16 | 17 | 18 | {foreach from=$fileList item=file} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {event name='columnRows'} 28 | 29 | {/foreach} 30 | 31 |
{lang}wcf.global.objectID{/lang}{lang}wcf.global.title{/lang}{lang}cms.acp.file.fileType{/lang}{lang}cms.acp.file.downloads{/lang}
{@$file->fileID}{@$file->getIconTag()}{$file->getTitle()}{$file->fileType}{#$file->downloads}
32 |
33 | -------------------------------------------------------------------------------- /acptemplates/columnsContentType.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 8 |
9 | 10 | 15 | -------------------------------------------------------------------------------- /acptemplates/contentContentType.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /acptemplates/contentTypeList.tpl: -------------------------------------------------------------------------------- 1 | {foreach from=$contentTypes key=category item=types} 2 |
3 |

{lang}cms.acp.content.type.{$category}{/lang}

4 | 5 | 12 |
13 | {/foreach} 14 | -------------------------------------------------------------------------------- /acptemplates/databaseObjectListContentType.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | {if $errorField == 'objectListClassname'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {else} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.databaseobjectlist.objectListClassname.error.{@$errorType}{/lang} 11 | {/if} 12 | 13 | {/if} 14 |
15 |
16 | 17 |
18 |
19 |
20 | 21 | {if $errorField == 'maxItems'} 22 | 23 | {if $errorType == 'empty'} 24 | {lang}wcf.global.form.error.empty{/lang} 25 | {else} 26 | {lang}cms.acp.content.type.de.codequake.cms.content.type.databaseobjectlist.maxItems.error.{@$errorType}{/lang} 27 | {/if} 28 | 29 | {/if} 30 |
31 |
32 | 33 | {if !$additionalTemplate|empty} 34 | {include file=$additionalTemplate application='cms'} 35 | {/if} 36 | -------------------------------------------------------------------------------- /acptemplates/fileContentType.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
    6 | {lang}cms.acp.file.picker{/lang} 7 |
    8 |
    9 |
    10 | 11 | 30 | -------------------------------------------------------------------------------- /acptemplates/fileListDialog.tpl: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 20 |
    21 | 22 | {include file='categoryFileListDialog' application='cms'} 23 |
    24 | -------------------------------------------------------------------------------- /acptemplates/filePreview.tpl: -------------------------------------------------------------------------------- 1 | 
    2 |
    3 | {if $file->isImage()} 4 |

    5 | {else} 6 |

    {@$file->getIconTag(96)}

    7 | {/if} 8 |
    9 |
    10 |

    {$file->getTitle()}

    11 | {$file->filesize|filesize} - {$file->fileType} - {@$file->uploadTime|time} 12 |
    13 |
    14 | -------------------------------------------------------------------------------- /acptemplates/fileUploadDialog.tpl: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    {lang}cms.acp.file.files{/lang}
    4 |
    5 |
      6 |
      7 | {lang}cms.acp.file.files.description{/lang} 8 |
      9 |
      10 | 11 |
      12 |
      13 |
      14 | 19 |
      20 |
      21 | 22 |
      23 | 24 |
      25 |
      26 | -------------------------------------------------------------------------------- /acptemplates/galleryContentType.tpl: -------------------------------------------------------------------------------- 1 |
      2 |
      3 |
      4 |
      5 |
        6 | {lang}cms.acp.file.picker{/lang} 7 |
        8 |
        9 |
        10 | 11 | 40 | -------------------------------------------------------------------------------- /acptemplates/googleMapsContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | N 5 | {if $errorField == 'latitude'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {else} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.googlemaps.latitude.error.{@$errorType}{/lang} 11 | {/if} 12 | 13 | {/if} 14 |
        15 |
        16 | 17 |
        18 |
        19 |
        20 | E 21 | {if $errorField == 'longitude'} 22 | 23 | {if $errorType == 'empty'} 24 | {lang}wcf.global.form.error.empty{/lang} 25 | {else} 26 | {lang}cms.acp.content.type.de.codequake.cms.content.type.googlemaps.longitude.error.{@$errorType}{/lang} 27 | {/if} 28 | 29 | {/if} 30 |
        31 |
        32 | -------------------------------------------------------------------------------- /acptemplates/groupContentType.tpl: -------------------------------------------------------------------------------- 1 |

        {lang}cms.acp.content.type.de.codequake.cms.content.type.group.description{/lang}

        2 | -------------------------------------------------------------------------------- /acptemplates/headlineContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 11 |
        12 |
        13 | 14 |
        15 |
        16 |
        17 | 18 | 19 | {include file='multipleLanguageInputJavascript' elementIdentifier='text' forceSelection=false} 20 |
        21 |
        22 | 23 |
        24 |
        25 |
        26 | 27 |
        28 |
        29 | -------------------------------------------------------------------------------- /acptemplates/import.tpl: -------------------------------------------------------------------------------- 1 | {include file='header' pageTitle='cms.acp.page.import'} 2 | 3 |
        4 |

        {lang}cms.acp.page.import{/lang}

        5 |
        6 | 7 | {include file='formError'} 8 | 9 | {if $success|isset} 10 |

        {lang}wcf.global.success{/lang}

        11 | {/if} 12 | 13 |

        {lang}cms.acp.page.import.info{/lang}

        14 | 15 |
        16 |
        17 |

        {lang}cms.acp.page.import{/lang}

        18 | 19 | 20 |
        21 |
        22 | 23 | {if $errorField == 'file'} 24 | 25 | {lang}cms.acp.page.import.{$errorType}{/lang} 26 | 27 | {/if} 28 | {lang}cms.acp.page.import.upload.description{/lang} 29 |
        30 | 31 | 32 |
        33 |
        34 | 35 | {if $errorField == 'fileLink'} 36 | 37 | {lang}cms.acp.page.import.{$errorType}{/lang} 38 | 39 | {/if} 40 | {lang}cms.acp.page.import.link.description{/lang} 41 |
        42 | 43 |
        44 | 45 |
        46 | 47 | {@SECURITY_TOKEN_INPUT_TAG} 48 |
        49 |
        50 | 51 |
        52 |

        {lang}cms.acp.page.export{/lang}

        53 | 54 |
        55 |
        56 |
        57 |

        {lang}cms.acp.page.export{/lang}

        58 | {lang}cms.acp.page.export.download.description{/lang} 59 |
        60 |
        61 | 62 | {event name='exportFields'} 63 |
        64 | 65 | {include file='footer'} 66 | -------------------------------------------------------------------------------- /acptemplates/linkContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 9 |
        10 |
        11 | 12 |
        13 |
        14 |
        15 | 16 | 17 | {include file='multipleLanguageInputJavascript' elementIdentifier='text' forceSelection=false} 18 |
        19 |
        20 | 21 |
        22 |
        23 |
        24 | 25 | 26 | {include file='multipleLanguageInputJavascript' elementIdentifier='link' forceSelection=false} 27 |
        28 |
        29 | -------------------------------------------------------------------------------- /acptemplates/menuContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 8 |
        9 |
        10 | 11 |
        12 |
        13 |
        14 | 20 |
        21 |
        22 | 23 |
        24 |
        25 |
        26 | 27 | {lang}cms.acp.content.type.de.codequake.cms.content.type.menu.depth.description{/lang} 28 |
        29 |
        30 | -------------------------------------------------------------------------------- /acptemplates/pageMultiSelectOptionType.tpl: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /acptemplates/pagePageType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |

        {lang}cms.acp.page.type.page.comments{/lang}

        3 | 4 | 5 |
        6 |
        7 | 8 | {lang}cms.acp.page.settings.isCommentable.description{/lang} 9 |
        10 | 11 |
        12 | -------------------------------------------------------------------------------- /acptemplates/pageRevisionList.tpl: -------------------------------------------------------------------------------- 1 | {if $revisions|count} 2 | 7 | 8 |
        9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {event name='columnHeads'} 18 | 19 | 20 | 21 | {foreach from=$revisions item=revision} 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | {event name='columns'} 35 | 36 | {/foreach} 37 | 38 |
        {lang}wcf.global.objectID{/lang}{lang}cms.acp.page.revision.action{/lang}{lang}wcf.user.username{/lang}{lang}cms.acp.page.revision.time{/lang}
        24 | 25 | 26 | 27 | {event name='rowButtons'} 28 | {@$revision->revisionID}{lang}cms.acp.page.revision.action.{$revision->action}{/lang}{@$revision->username}{@$revision->time|time}
        39 |
        40 | {else} 41 |

        {lang}wcf.global.noItems{/lang}

        42 | {/if} 43 | -------------------------------------------------------------------------------- /acptemplates/pageSelectOptionType.tpl: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /acptemplates/phpContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 5 | 6 | {if !'ACE_THEME'|defined} 7 | {include file='codemirror' codemirrorMode='php' codemirrorSelector='#text' sandbox=true} 8 | {else} 9 | {include file='ace' aceMode='php' aceSelector='text' sandbox=true} 10 | {/if} 11 |
        12 |
        13 | -------------------------------------------------------------------------------- /acptemplates/rssContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 5 | {lang}cms.acp.content.type.de.codequake.cms.content.type.rss.url.description{/lang} 6 |
        7 |
        8 | 9 |
        10 |
        11 | 12 |
        13 |
        14 | 15 |
        16 |
        17 | -------------------------------------------------------------------------------- /acptemplates/slideshowContentType.tpl: -------------------------------------------------------------------------------- 1 |

        {lang}cms.acp.content.type.de.codequake.cms.content.type.slideshow.description{/lang}

        2 | -------------------------------------------------------------------------------- /acptemplates/tabMenuContentType.tpl: -------------------------------------------------------------------------------- 1 |

        {lang}cms.acp.content.type.de.codequake.cms.content.type.tabmenu.description{/lang}

        2 | -------------------------------------------------------------------------------- /acptemplates/templateContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 5 | {if $errorField == 'text'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {else} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.template.text.error.{@$errorType}{/lang} 11 | {/if} 12 | 13 | {/if} 14 | {lang}cms.acp.content.type.de.codequake.cms.content.type.template.text.description{/lang} 15 | 16 | {if !'ACE_THEME'|defined} 17 | {include file='codemirror' codemirrorMode='smartymixed' codemirrorSelector='#text' sandbox=true} 18 | {else} 19 | {include file='ace' aceMode='smarty' aceSelector='text' sandbox=true} 20 | {/if} 21 |
        22 |
        23 | -------------------------------------------------------------------------------- /acptemplates/textContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 5 | {if !$errorField|empty && $errorField == 'text'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {elseif $errorType == 'tooLong'} 10 | {lang}wcf.message.error.tooLong{/lang} 11 | {elseif $errorType == 'censoredWordsFound'} 12 | {lang}wcf.message.error.censoredWordsFound{/lang} 13 | {elseif $errorType == 'disallowedBBCodes'} 14 | {lang}wcf.message.error.disallowedBBCodes{/lang} 15 | {else} 16 | {lang}cms.content.text.text.error.{@$errorType}{/lang} 17 | {/if} 18 | 19 | {/if} 20 | 21 | {include file='wysiwyg'} 22 | {include file='wysiwygI18n' elementIdentifier='text' forceSelection=false} 23 | 24 | 25 |
        26 |
        27 | -------------------------------------------------------------------------------- /acptemplates/userContentType.tpl: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
        9 |
        10 | 11 | {if $errorField == 'data[name]'} 12 | 13 | {if $errorType == 'empty'} 14 | {lang}wcf.global.form.error.empty{/lang} 15 | {elseif $errorType == 'notValid'} 16 | {lang}wcf.user.username.error.notValid{/lang} 17 | {/if} 18 | 19 | {/if} 20 |
        21 | 22 | -------------------------------------------------------------------------------- /acptemplates/wsipImportContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 5 | 6 | {if $errorField == 'text'} 7 | 8 | {if $errorType == 'empty'} 9 | {lang}wcf.global.form.error.empty{/lang} 10 | {else} 11 | {lang}cms.acp.content.type.de.codequake.cms.content.type.wsipimport.text.error.{@$errorType}{/lang} 12 | {/if} 13 | 14 | {/if} 15 |
        16 |
        17 | 18 | {include file='wysiwyg'} 19 | 20 | 29 | -------------------------------------------------------------------------------- /acptemplates/youtubeContentType.tpl: -------------------------------------------------------------------------------- 1 | 2 |
        3 |
        4 | 5 | {if $errorField == 'data[video]'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {elseif $errorType == 'notValid'} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.youtube.video.error.notValid{/lang} 11 | {/if} 12 | 13 | {/if} 14 |
        15 | 16 | -------------------------------------------------------------------------------- /constants.php: -------------------------------------------------------------------------------- 1 | 6 | * @package de.codequake.cms 7 | */ 8 | // define paths 9 | define('RELATIVE_CMS_DIR', '../'); 10 | 11 | // include config 12 | require_once (dirname(__DIR__) . '/app.config.inc.php'); 13 | 14 | // include WCF 15 | require_once (RELATIVE_WCF_DIR . 'acp/global.php'); 16 | -------------------------------------------------------------------------------- /files/acp/index.php: -------------------------------------------------------------------------------- 1 | 6 | * @package de.codequake.cms 7 | */ 8 | require_once ('./global.php'); 9 | wcf\system\request\RequestHandler::getInstance()->handle('cms', true); 10 | -------------------------------------------------------------------------------- /files/acp/install_de.codequake.cms.php: -------------------------------------------------------------------------------- 1 | 10 | * @package de.codequake.cms 11 | */ 12 | $sql = "UPDATE wcf" . WCF_N . "_option 13 | SET optionValue = ? 14 | WHERE optionName = ?"; 15 | $optionUpdate = WCF::getDB()->prepareStatement($sql); 16 | 17 | // set default page title 18 | if (!defined('PAGE_TITLE') || !PAGE_TITLE) { 19 | $optionUpdate->execute(['Fireball CMS 3.1', 'page_title']); 20 | } 21 | 22 | $sql = "SELECT objectTypeID 23 | FROM wcf" . WCF_N . "_object_type 24 | WHERE objectType = ? 25 | AND definitionID = ( 26 | SELECT definitionID 27 | FROM wcf" . WCF_N . "_object_type_definition 28 | WHERE definitionName = ? 29 | )"; 30 | $statement = WCF::getDB()->prepareStatement($sql); 31 | $statement->execute([ 32 | 'de.codequake.cms.file', 33 | 'com.woltlab.wcf.category' 34 | ]); 35 | $row = $statement->fetchArray(); 36 | $categoryObjectTypeID = $row['objectTypeID']; 37 | 38 | // create default file category 39 | CategoryEditor::create([ 40 | 'objectTypeID' => $categoryObjectTypeID, 41 | 'title' => 'Default Category', 42 | 'time' => TIME_NOW 43 | ]); 44 | 45 | // add MysteryCode update server 46 | if (isset($this->instruction['attributes']['installupdateserver']) && $this->instruction['attributes']['installupdateserver'] == 1) { 47 | $serverURL = 'https://update.mysterycode.de/tornado/'; 48 | 49 | // check if update server already exists 50 | $sql = "SELECT packageUpdateServerID 51 | FROM wcf" . WCF_N . "_package_update_server 52 | WHERE serverURL = ?"; 53 | $statement = WCF::getDB()->prepareStatement($sql); 54 | $statement->execute([$serverURL]); 55 | $row = $statement->fetchArray(); 56 | if ($row === false) { 57 | $objectAction = new PackageUpdateServerAction([], 'create', [ 58 | 'data' => [ 59 | 'serverURL' => $serverURL 60 | ] 61 | ]); 62 | $objectAction->executeAction(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /files/files/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /files/files/thumbnails/.gitignore: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /files/global.php: -------------------------------------------------------------------------------- 1 | 6 | * @package de.codequake.cms 7 | */ 8 | // include config 9 | require_once (__DIR__ . '/app.config.inc.php'); 10 | 11 | // include wcf 12 | require_once (RELATIVE_WCF_DIR . 'global.php'); 13 | -------------------------------------------------------------------------------- /files/index.php: -------------------------------------------------------------------------------- 1 | 6 | * @package de.codequake.cms 7 | */ 8 | require_once ('./global.php'); 9 | wcf\system\request\RequestHandler::getInstance()->handle('cms'); 10 | -------------------------------------------------------------------------------- /files/lib/acp/action/CMSExportAction.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class CMSExportAction extends AbstractAction { 16 | /** 17 | * @inheritDoc 18 | */ 19 | public function execute() { 20 | parent::execute(); 21 | 22 | $filename = BackupHandler::getInstance()->getExportArchive(); 23 | $this->executed(); 24 | 25 | header('Content-Type: application/x-gzip; charset=utf8'); 26 | header('Content-Disposition: attachment; filename="CMS-Export.tar.gz"'); 27 | readfile($filename); 28 | @unlink($filename); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /files/lib/acp/form/FileCategoryAddForm.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class FileCategoryAddForm extends AbstractCategoryAddForm { 15 | /** 16 | * @inheritDoc 17 | */ 18 | public $activeMenuItem = 'fireball.acp.menu.link.fireball.file.category.add'; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | public $neededPermissions = ['admin.fireball.file.canAddFile']; 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public $objectTypeName = 'de.codequake.cms.file'; 29 | } 30 | -------------------------------------------------------------------------------- /files/lib/acp/form/FileCategoryEditForm.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class FileCategoryEditForm extends AbstractCategoryEditForm { 15 | /** 16 | * @inheritDoc 17 | */ 18 | public $activeMenuItem = 'fireball.acp.menu.link.fireball.file'; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | public $neededPermissions = ['admin.fireball.file.canAddFile']; 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public $objectTypeName = 'de.codequake.cms.file'; 29 | } 30 | -------------------------------------------------------------------------------- /files/lib/acp/page/FileCategoryListPage.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class FileCategoryListPage extends AbstractCategoryListPage { 15 | /** 16 | * @inheritDoc 17 | */ 18 | public $activeMenuItem = 'fireball.acp.menu.link.fireball.file.category.list'; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | public $objectTypeName = 'de.codequake.cms.file'; 24 | } 25 | -------------------------------------------------------------------------------- /files/lib/acp/page/PageListPage.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class PageListPage extends AbstractPage { 19 | /** 20 | * @inheritDoc 21 | */ 22 | public $activeMenuItem = 'fireball.acp.menu.link.fireball.page.list'; 23 | 24 | /** 25 | * @inheritDoc 26 | */ 27 | public $neededPermissions = ['admin.fireball.page.canListPage']; 28 | 29 | /** 30 | * list of content types 31 | * @var array<\wcf\data\object\type\ObjectType> 32 | */ 33 | public $objectTypeList = null; 34 | 35 | /** 36 | * list of pages 37 | * @var \RecursiveIteratorIterator 38 | */ 39 | public $pageList = null; 40 | 41 | /** 42 | * @inheritDoc 43 | */ 44 | public function readData() { 45 | parent::readData(); 46 | 47 | $this->objectTypeList = ObjectTypeCache::getInstance()->getObjectTypes('de.codequake.cms.content.type'); 48 | 49 | // read pages 50 | $pageNodeTree = new PageNodeTree(); 51 | $this->pageList = $pageNodeTree->getIterator(); 52 | } 53 | 54 | /** 55 | * @inheritDoc 56 | */ 57 | public function assignVariables() { 58 | parent::assignVariables(); 59 | 60 | WCF::getTPL()->assign([ 61 | 'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(ClipboardHandler::getInstance()->getObjectTypeID('de.codequake.cms.page')), 62 | 'objectTypeList' => $this->objectTypeList, 63 | 'pageList' => $this->pageList 64 | ]); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /files/lib/acp/page/StylesheetListPage.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class StylesheetListPage extends SortablePage { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public $activeMenuItem = 'fireball.acp.menu.link.fireball.stylesheet.list'; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | public $defaultSortField = 'title'; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | public $neededPermissions = ['admin.fireball.style.canListStylesheet']; 32 | 33 | /** 34 | * @inheritDoc 35 | */ 36 | public $objectListClassName = StylesheetList::class; 37 | 38 | /** 39 | * @inheritDoc 40 | */ 41 | public $validSortFields = ['stylesheetID', 'title']; 42 | 43 | /** 44 | * @inheritDoc 45 | */ 46 | public function assignVariables() { 47 | parent::assignVariables(); 48 | 49 | WCF::getTPL()->assign([ 50 | 'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(ClipboardHandler::getInstance()->getObjectTypeID('de.codequake.cms.stylesheet')) 51 | ]); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /files/lib/data/content/BoxContentNodeTree.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | */ 13 | class BoxContentNodeTree extends ContentNodeTree { 14 | public function buildTree() { 15 | $this->parentNode = new ContentNode(new Content(null, ['contentID' => 0])); 16 | $parentContent = $this->getNode($this->parentID); 17 | $this->parentNode->addChild($parentContent); 18 | $this->buildTreeLevel($parentContent); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /files/lib/data/content/ContentCache.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class ContentCache extends SingletonFactory { 16 | 17 | protected $contents = []; 18 | 19 | protected $tree = []; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | protected function init() { 25 | $this->tree = ContentCacheBuilder::getInstance()->getData([], 'tree'); 26 | $this->contents = ContentCacheBuilder::getInstance()->getData([], 'contents'); 27 | } 28 | 29 | public function getContent($id) { 30 | if (isset($this->contents[$id])) return $this->contents[$id]; 31 | return null; 32 | } 33 | 34 | public function getChildIDs($parentID = null) { 35 | if ($parentID === null) $parentID = ''; 36 | 37 | if (!isset($this->tree[$parentID])) return []; 38 | 39 | return $this->tree[$parentID]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /files/lib/data/content/ContentEditor.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | * 17 | * @mixin Content 18 | * @method Content getDecoratedObject() 19 | */ 20 | class ContentEditor extends DatabaseObjectEditor implements IEditableCachedObject { 21 | /** 22 | * @inheritDoc 23 | */ 24 | protected static $baseClass = Content::class; 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | public static function resetCache() { 30 | ContentCacheBuilder::getInstance()->reset(); 31 | ContentPermissionCacheBuilder::getInstance()->reset(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /files/lib/data/content/ContentList.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @property Content[] $objects 15 | * @method Content[] getObjects() 16 | */ 17 | class ContentList extends DatabaseObjectList { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public $className = Content::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/data/content/DrainedContentNodeTree.class.php: -------------------------------------------------------------------------------- 1 | drainedID = $drainedID; 12 | } 13 | 14 | public function isIncluded(ContentNode $contentNode) { 15 | if ($this->drainedID != null && $contentNode->contentID == $this->drainedID) return false; 16 | return parent::isIncluded($contentNode); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /files/lib/data/content/DrainedPositionContentNodeTree.class.php: -------------------------------------------------------------------------------- 1 | drainedID = $drainedID; 12 | $this->position = $position; 13 | $this->isACP = $isACP; 14 | } 15 | 16 | public function isIncluded(ContentNode $contentNode) { 17 | if ($contentNode->position != $this->position) return false; 18 | return parent::isIncluded($contentNode); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /files/lib/data/content/ViewableContent.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class ViewableContent extends DatabaseObjectDecorator { 15 | 16 | protected static $baseClass = Content::class; 17 | } 18 | -------------------------------------------------------------------------------- /files/lib/data/content/ViewableContentList.class.php: -------------------------------------------------------------------------------- 1 | 10 | * @package de.codequake.cms 11 | */ 12 | class ViewableContentList extends ContentList { 13 | 14 | public $decoratorClassName = ViewableContent::class; 15 | } 16 | -------------------------------------------------------------------------------- /files/lib/data/file/CategoryFileList.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class CategoryFileList extends FileList { 16 | /** 17 | * Creates a new CategoryFileList object. 18 | * 19 | * @param array $categoryIDs 20 | * @inheritDoc 21 | */ 22 | public function __construct(array $categoryIDs) { 23 | parent::__construct(); 24 | 25 | $this->sqlJoins .= " LEFT JOIN cms".WCF_N."_file_to_category file_to_category ON (file.fileID = file_to_category.fileID)"; 26 | 27 | if (!empty($categoryIDs)) { 28 | $this->getConditionBuilder()->add('file_to_category.categoryID IN (?)', [$categoryIDs]); 29 | $this->getConditionBuilder()->add('file.fileID = file_to_category.fileID'); 30 | } else { 31 | $this->getConditionBuilder()->add('1=0'); 32 | } 33 | } 34 | 35 | /** 36 | * @inheritDoc 37 | */ 38 | public function countObjects() { 39 | $sql = "SELECT COUNT(*) AS count 40 | FROM cms".WCF_N."_file_to_category file_to_category, 41 | cms".WCF_N."_file file 42 | ".$this->sqlConditionJoins." 43 | ".$this->getConditionBuilder(); 44 | $statement = WCF::getDB()->prepareStatement($sql); 45 | $statement->execute($this->getConditionBuilder()->getParameters()); 46 | return $statement->fetchColumn(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /files/lib/data/file/FileCache.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class FileCache extends SingletonFactory { 17 | 18 | protected $files = []; 19 | 20 | protected $filesToCategory = []; 21 | 22 | protected $categoryIDs = []; 23 | 24 | protected $categories = null; 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | protected function init() { 30 | $this->filesToCategory = FileCacheBuilder::getInstance()->getData([], 'filesToCategory'); 31 | $this->files = FileCacheBuilder::getInstance()->getData([], 'files'); 32 | } 33 | 34 | public function getFile($id) { 35 | if (isset($this->files[$id])) return $this->files[$id]; 36 | return null; 37 | } 38 | 39 | public function getCategoryIDs($id) { 40 | if (!empty($this->categoryIDs)) { 41 | foreach ($this->filesToCategory as $fileID => $categoryID) { 42 | if ($fileID == $id) $this->categoryIDs[] = $categoryID; 43 | } 44 | } 45 | return $this->categoryIDs; 46 | } 47 | 48 | public function getCategories($id) { 49 | if ($this->categories === null) { 50 | $this->categories = []; 51 | 52 | foreach ($this->getCategoryIDs($id) as $categoryID) { 53 | $this->categories[$categoryID] = CategoryHandler::getInstance()->getCategory($categoryID); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /files/lib/data/file/FileList.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @property File[] $objects 15 | * @method File[] getObjects() 16 | */ 17 | class FileList extends DatabaseObjectList { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public $className = File::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/data/page/AccessiblePageNodeTree.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class AccessiblePageNodeTree extends ViewablePageNodeTree { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected function isIncluded(PageNode $pageNode) { 19 | if (!$pageNode->canRead()) { 20 | return false; 21 | } 22 | 23 | return parent::isIncluded($pageNode); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /files/lib/data/page/DrainedPageNodeTree.class.php: -------------------------------------------------------------------------------- 1 | 10 | * @package de.codequake.cms 11 | */ 12 | class DrainedPageNodeTree extends PageNodeTree { 13 | 14 | public $drainedID = null; 15 | 16 | public function __construct($parentID = null, $drainedID = null) { 17 | parent::__construct($parentID); 18 | 19 | $this->drainedID = $drainedID; 20 | } 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | public function isIncluded(PageNode $pageNode) { 26 | if ($pageNode->pageID == $this->drainedID) { 27 | return false; 28 | } 29 | 30 | return parent::isIncluded($pageNode); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /files/lib/data/page/PageList.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @property Page[] $objects 15 | * @method Page[] getObjects() 16 | */ 17 | class PageList extends DatabaseObjectList { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public $className = Page::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/data/page/SearchResultPage.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class SearchResultPage extends ViewablePage implements ISearchResultObject { 18 | /** 19 | * @var UserProfile 20 | */ 21 | protected $userProfile = null; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | public function getFormattedMessage() { 27 | return SearchResultTextParser::getInstance()->parse(WCF::getLanguage()->get($this->description)); 28 | } 29 | 30 | /** 31 | * @inheritDoc 32 | */ 33 | public function getLink($query = '') { 34 | if ($query) { 35 | return LinkHandler::getInstance()->getLink('Page', [ 36 | 'alias' => $this->getDecoratedObject()->getAlias(), 37 | 'application' => 'cms', 38 | 'highlight' => urlencode($query) 39 | ]); 40 | } 41 | 42 | return $this->getDecoratedObject()->getLink(); 43 | } 44 | 45 | /** 46 | * @inheritDoc 47 | */ 48 | public function getSubject() { 49 | return WCF::getLanguage()->get($this->title); 50 | } 51 | 52 | /** 53 | * @inheritDoc 54 | */ 55 | public function getUserProfile() { 56 | if ($this->userProfile === null) { 57 | $this->userProfile = new UserProfile(new User($this->authorID)); 58 | } 59 | 60 | return $this->userProfile; 61 | } 62 | 63 | /** 64 | * @inheritDoc 65 | */ 66 | public function getTime() { 67 | return $this->creationTime; 68 | } 69 | 70 | /** 71 | * @inheritDoc 72 | */ 73 | public function getObjectTypeName() { 74 | return 'de.codequake.cms.page'; 75 | } 76 | 77 | /** 78 | * @inheritDoc 79 | */ 80 | public function getContainerLink() { 81 | return ''; 82 | } 83 | 84 | /** 85 | * @inheritDoc 86 | */ 87 | public function getContainerTitle() { 88 | return ''; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /files/lib/data/page/SearchResultPageList.class.php: -------------------------------------------------------------------------------- 1 | 8 | * @package de.codequake.cms 9 | */ 10 | class SearchResultPageList extends PageList { 11 | 12 | public $decoratorClassName = SearchResultPage::class; 13 | } 14 | -------------------------------------------------------------------------------- /files/lib/data/page/ViewablePage.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @mixin Page 15 | * @method Page getDecoratedObject() 16 | */ 17 | class ViewablePage extends DatabaseObjectDecorator { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected static $baseClass = Page::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/data/page/ViewablePageNodeTree.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class ViewablePageNodeTree extends PageNodeTree { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected function isIncluded(PageNode $pageNode) { 19 | if ($pageNode->invisible) { 20 | return false; 21 | } 22 | 23 | return parent::isIncluded($pageNode); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /files/lib/data/page/revision/PageRevision.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | * 13 | * @property-read integer $revisionID id of the revision 14 | * @property-read integer $pageID id of the page 15 | * @property-read integer $action action which has been performed 16 | * @property-read integer $userID id of the user 17 | * @property-read string $username username of the user 18 | * @property-read integer $time timestamp 19 | * @property-read string $data data of the revision 20 | * @property-read array $contentData content data of the revision 21 | */ 22 | class PageRevision extends DatabaseObject { 23 | /** 24 | * @inheritDoc 25 | */ 26 | protected static $databaseTableName = 'page_revision'; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | protected static $databaseTableIndexName = 'revisionID'; 32 | } 33 | -------------------------------------------------------------------------------- /files/lib/data/page/revision/PageRevisionEditor.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @mixin PageRevision 15 | * @method PageRevision getDecoratedObject() 16 | */ 17 | class PageRevisionEditor extends DatabaseObjectEditor { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected static $baseClass = PageRevision::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/data/page/revision/PageRevisionList.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @property PageRevision[] $objects 15 | * @method PageRevision[] getObjects() 16 | */ 17 | class PageRevisionList extends DatabaseObjectList { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public $className = PageRevision::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/data/stylesheet/StylesheetAction.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @property StylesheetEditor[] $objects 15 | * @method StylesheetEditor[] getObjects() 16 | * @method StylesheetEditor getSingleObject() 17 | */ 18 | class StylesheetAction extends AbstractDatabaseObjectAction { 19 | /** 20 | * @inheritDoc 21 | */ 22 | protected $className = StylesheetEditor::class; 23 | 24 | /** 25 | * @inheritDoc 26 | */ 27 | protected $permissionsDelete = ['admin.fireball.style.canAddStylesheet']; 28 | 29 | /** 30 | * @inheritDoc 31 | */ 32 | protected $requireACP = ['delete', 'update']; 33 | } 34 | -------------------------------------------------------------------------------- /files/lib/data/stylesheet/StylesheetCache.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class StylesheetCache extends SingletonFactory { 15 | /** 16 | * cached stylesheets 17 | * @var array<\cms\data\stylesheet\Stylesheet> 18 | */ 19 | protected $stylesheets = []; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | protected function init() { 25 | $this->stylesheets = StylesheetCacheBuilder::getInstance()->getData(); 26 | } 27 | 28 | /** 29 | * Returns the stylesheet with the given id. 30 | * 31 | * @param integer $stylesheetID 32 | * @return \cms\data\stylesheet\Stylesheet 33 | */ 34 | public function getStylesheet($stylesheetID) { 35 | if (isset($this->stylesheets[$stylesheetID])) { 36 | return $this->stylesheets[$stylesheetID]; 37 | } 38 | 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /files/lib/data/stylesheet/StylesheetEditor.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | * 16 | * @mixin Stylesheet 17 | * @method Stylesheet getDecoratedObject() 18 | */ 19 | class StylesheetEditor extends DatabaseObjectEditor implements IEditableCachedObject { 20 | /** 21 | * @inheritDoc 22 | */ 23 | protected static $baseClass = Stylesheet::class; 24 | 25 | /** 26 | * Delete the compiled stylesheet files. The files will get recompiled 27 | * when user visit one of the associated pages. 28 | * 29 | * @inheritDoc 30 | */ 31 | public static function resetCache() { 32 | $stylesheets = glob(CMS_DIR.'style/style-*.css'); 33 | if ($stylesheets !== false) { 34 | foreach ($stylesheets as $stylesheet) { 35 | @unlink($stylesheet); 36 | } 37 | } 38 | 39 | StylesheetCacheBuilder::getInstance()->reset(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /files/lib/data/stylesheet/StylesheetList.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | * 14 | * @property Stylesheet[] $objects 15 | * @method Stylesheet[] getObjects() 16 | */ 17 | class StylesheetList extends DatabaseObjectList { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public $className = Stylesheet::class; 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/page/ICMSPage.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | */ 13 | interface ICMSPage { 14 | /** 15 | * Returns the page that belongs to the displayed page. 16 | * 17 | * @return \cms\data\page\Page 18 | */ 19 | public function getPage(); 20 | } 21 | -------------------------------------------------------------------------------- /files/lib/page/LinkPage.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class LinkPage extends AbstractCMSPage { 18 | /** 19 | * enables template usage 20 | * @var string 21 | */ 22 | public $useTemplate = false; 23 | 24 | /** 25 | * @inheritDoc 26 | */ 27 | public function show() { 28 | // register visit 29 | VisitCountHandler::getInstance()->count(); 30 | 31 | // count click 32 | $pageEditor = new PageEditor($this->page); 33 | $pageEditor->updateCounters([ 34 | 'clicks' => 1 35 | ]); 36 | 37 | if ($this->page->delayedRedirect) { 38 | if ($this->page->redirectMessage) 39 | HeaderUtil::delayedRedirect($this->page->url, WCF::getLanguage()->get($this->page->redirectMessage), $this->page->delay); 40 | else 41 | HeaderUtil::delayedRedirect($this->page->url, WCF::getLanguage()->get('cms.page.link.redirect'), $this->page->delay); 42 | } else { 43 | HeaderUtil::redirect($this->page->url); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /files/lib/page/PagePage.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class PagePage extends AbstractCMSPage { 17 | /** 18 | * structured list of page comments 19 | * @var \wcf\data\comment\StructuredCommentList 20 | */ 21 | public $commentList = null; 22 | 23 | /** 24 | * comment manager object 25 | * @var \wcf\system\comment\manager\ICommentManager 26 | */ 27 | public $commentManager = null; 28 | 29 | /** 30 | * object type id for comments 31 | * @var integer 32 | */ 33 | public $commentObjectTypeID = 0; 34 | 35 | /** 36 | * @inheritDoc 37 | */ 38 | public function readData() { 39 | parent::readData(); 40 | 41 | // change style 42 | if ($this->page->styleID && StyleHandler::getInstance()->getStyle()->styleID != $this->page->styleID) { 43 | StyleHandler::getInstance()->changeStyle($this->page->styleID, true); 44 | } 45 | 46 | // comments 47 | if ($this->page->isCommentable) { 48 | $this->commentObjectTypeID = CommentHandler::getInstance()->getObjectTypeID('de.codequake.cms.page.comment'); 49 | $this->commentManager = CommentHandler::getInstance()->getObjectType($this->commentObjectTypeID)->getProcessor(); 50 | $this->commentList = CommentHandler::getInstance()->getCommentList($this->commentManager, $this->commentObjectTypeID, $this->page->pageID); 51 | } 52 | } 53 | 54 | /** 55 | * @inheritDoc 56 | */ 57 | public function assignVariables() { 58 | parent::assignVariables(); 59 | 60 | WCF::getTPL()->assign([ 61 | 'likeData' => ((MODULE_LIKE && $this->commentList) ? $this->commentList->getLikeData() : []), 62 | 'commentCanAdd' => $this->page->getPermission('user.canAddComment'), 63 | 'commentList' => $this->commentList, 64 | 'commentObjectTypeID' => $this->commentObjectTypeID, 65 | 'lastCommentTime' => ($this->commentList ? $this->commentList->getMinCommentTime() : 0) 66 | ]); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /files/lib/page/SitemapPage.class.php: -------------------------------------------------------------------------------- 1 | pageNodeTree = new AccessiblePageNodeTree(); 32 | } 33 | 34 | /** 35 | * @inheritDoc 36 | */ 37 | public function assignVariables () { 38 | parent::assignVariables(); 39 | 40 | WCF::getTPL()->assign([ 41 | 'pageNodeTree' => $this->pageNodeTree->getIterator() 42 | ]); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /files/lib/system/CMSCore.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class CMSCore extends AbstractApplication { 16 | /** 17 | * @inheritDoc 18 | */ 19 | protected $primaryController = PagePage::class; 20 | } 21 | -------------------------------------------------------------------------------- /files/lib/system/bbcode/CMSFileBBCode.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class CMSFileBBCode extends AbstractBBCode { 19 | 20 | public $isImage = false; 21 | public $align = ''; 22 | public $width = 0; 23 | public $caption = ''; 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public function getParsedTag(array $openingTag, $content, array $closingTag, BBCodeParser $parser) { 29 | $this->isImage = false; 30 | $this->align = $this->caption = ''; 31 | $this->width = 0; 32 | 33 | //get id attribute 34 | $fileID = 0; 35 | if (isset($openingTag['attributes'][0])) { 36 | $fileID = $openingTag['attributes'][0]; 37 | } 38 | $file = FileCache::getInstance()->getFile($fileID); 39 | if ($file === null) 40 | $file = new File($fileID); 41 | 42 | if ($file === null) return ''; 43 | 44 | if (preg_match('~(image/*)+~', $file->fileType)) $this->isImage = true; 45 | 46 | if ($this->isImage && isset($openingTag['attributes'][1])) { 47 | $this->align = $openingTag['attributes'][1]; 48 | } 49 | 50 | if ($this->isImage && isset($openingTag['attributes'][2])) { 51 | $this->width = $openingTag['attributes'][2]; 52 | } 53 | 54 | if ($this->isImage && isset($openingTag['attributes'][3])) { 55 | $this->caption = $openingTag['attributes'][3]; 56 | } 57 | 58 | WCF::getTPL()->assign([ 59 | '_file' => $file, 60 | '_align' => $this->align, 61 | '_width' => $this->width, 62 | '_isImage' => $this->isImage, 63 | '_caption' => $this->caption 64 | 65 | ]); 66 | 67 | return WCF::getTPL()->fetch('cmsFileBBCodeTag', 'cms'); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /files/lib/system/bbcode/CMSFileUrlBBCode.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class CMSFileUrlBBCode extends AbstractBBCode { 18 | public $fileID = 0; 19 | public $file = null; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | public function getParsedTag(array $openingTag, $content, array $closingTag, BBCodeParser $parser) { 25 | $this->fileID = $content; 26 | $this->file = FileCache::getInstance()->getFile($this->fileID); 27 | if ($this->file === null) 28 | $this->file = new File($this->fileID); 29 | 30 | if ($this->file == null) 31 | return ''; 32 | 33 | return $this->file->getLink(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /files/lib/system/bbcode/PageBBCode.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class PageBBCode extends AbstractBBCode { 19 | public $pageID = 0; 20 | public $page = null; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | public function getParsedTag(array $openingTag, $content, array $closingTag, BBCodeParser $parser) { 26 | if (isset($openingTag['attributes'][0])) { 27 | $this->pageID = $openingTag['attributes'][0]; 28 | } 29 | $this->page = PageCache::getInstance()->getPage($this->pageID); 30 | if ($this->page === null) 31 | $this->page = new Page($this->pageID); 32 | 33 | if ($this->page == null && empty($content)) 34 | return WCF::getLanguage()->get('cms.page.bbcode.notFound'); 35 | else if ($this->page == null && !empty($content)) 36 | return $content . WCF::getLanguage()->get('cms.page.bbcode.notFound.inline'); 37 | 38 | return '' . (!empty($content) ? $content : $this->page->getTitle()) . ''; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/ContentCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class ContentCacheBuilder extends AbstractCacheBuilder { 16 | /** 17 | * @inheritDoc 18 | */ 19 | public function rebuild(array $parameters) { 20 | $data = [ 21 | 'contents' => [], 22 | 'tree' => [] 23 | ]; 24 | 25 | $list = new ContentList(); 26 | $list->sqlOrderBy = 'parentID ASC, showOrder ASC'; 27 | $list->readObjects(); 28 | $data['contents'] = $list->getObjects(); 29 | 30 | foreach ($data['contents'] as $content) { 31 | $data['tree'][$content->parentID][] = $content->contentID; 32 | } 33 | 34 | return $data; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/ContentPermissionCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class ContentPermissionCacheBuilder extends AbstractCacheBuilder { 17 | /** 18 | * @inheritDoc 19 | */ 20 | public function rebuild(array $parameters) { 21 | $data = []; 22 | $objectTypeName = 'de.codequake.cms.content'; 23 | $contentList = new ContentList(); 24 | $contentList->readObjects(); 25 | $contentList = $contentList->getObjects(); 26 | 27 | $aclOptions = ACLHandler::getInstance()->getPermissions(ACLHandler::getInstance()->getObjectTypeID($objectTypeName), array_keys($contentList)); 28 | $options = $aclOptions['options']->getObjects(); 29 | foreach ([ 30 | 'group', 31 | 'user' 32 | ] as $type) { 33 | foreach ($aclOptions[$type] as $contentID => $optionData) { 34 | if (!isset($data[$contentID])) { 35 | $data[$contentID] = [ 36 | 'group' => [], 37 | 'user' => [] 38 | ]; 39 | } 40 | foreach ($optionData as $typeID => $optionValues) { 41 | $data[$contentID][$type][$typeID] = []; 42 | 43 | foreach ($optionValues as $optionID => $optionValue) { 44 | $data[$contentID][$type][$typeID][$options[$optionID]->optionName] = $optionValue; 45 | } 46 | } 47 | } 48 | } 49 | return $data; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/FileCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class FileCacheBuilder extends AbstractCacheBuilder { 16 | /** 17 | * @inheritDoc 18 | */ 19 | public function rebuild(array $parameters) { 20 | $data = [ 21 | 'files' => [], 22 | 'filesToCategory' => [] 23 | ]; 24 | 25 | $list = new FileList(); 26 | $list->readObjects(); 27 | foreach ($data['files'] = $list->getObjects() as $file) { 28 | foreach ($file->getCategoryIDs() as $categoryID) { 29 | $data['filesToCategory'][$file->fileID] = $categoryID; 30 | } 31 | } 32 | 33 | return $data; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/FilePermissionCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class FilePermissionCacheBuilder extends AbstractCacheBuilder { 17 | /** 18 | * @inheritDoc 19 | */ 20 | public function rebuild(array $parameters) { 21 | $data = []; 22 | $objectTypeName = 'de.codequake.cms.file'; 23 | $fileList = new FileList(); 24 | $fileList->readObjects(); 25 | $fileList = $fileList->getObjects(); 26 | 27 | $aclOptions = ACLHandler::getInstance()->getPermissions(ACLHandler::getInstance()->getObjectTypeID($objectTypeName), array_keys($fileList)); 28 | $options = $aclOptions['options']->getObjects(); 29 | foreach ([ 30 | 'group', 31 | 'user' 32 | ] as $type) { 33 | foreach ($aclOptions[$type] as $fileID => $optionData) { 34 | if (!isset($data[$fileID])) { 35 | $data[$fileID] = [ 36 | 'group' => [], 37 | 'user' => [] 38 | ]; 39 | } 40 | foreach ($optionData as $typeID => $optionValues) { 41 | $data[$fileID][$type][$typeID] = []; 42 | 43 | foreach ($optionValues as $optionID => $optionValue) { 44 | $data[$fileID][$type][$typeID][$options[$optionID]->optionName] = $optionValue; 45 | } 46 | } 47 | } 48 | } 49 | return $data; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/PageCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class PageCacheBuilder extends AbstractCacheBuilder { 17 | /** 18 | * @inheritDoc 19 | */ 20 | public function rebuild(array $parameters) { 21 | $data = [ 22 | 'aliasToPage' => [], 23 | 'pages' => [], 24 | 'stylesheetsToPage' => [], 25 | 'structure' => [], 26 | 'wcfPageIDs' => [], 27 | ]; 28 | 29 | // fetch pages 30 | $pageList = new PageList(); 31 | $pageList->sqlOrderBy = 'page.parentID ASC, page.showOrder ASC'; 32 | $pageList->readObjects(); 33 | 34 | $data['pages'] = $pageList->getObjects(); 35 | 36 | foreach ($pageList as $page) { 37 | // Handle aliase to page assignment. Notice that we 38 | // can't simply use '$page->getAlias()' here since the 39 | // function would require a builded cache! 40 | $alias = $page->alias; 41 | $tmp = $page; 42 | while ($tmp->parentID && $tmp = $data['pages'][$tmp->parentID]) { 43 | $alias = $tmp->alias . '/' . $alias; 44 | } 45 | $data['aliasToPage'][$alias] = $page->pageID; 46 | 47 | // page structure 48 | $data['structure'][$page->parentID][] = $page->pageID; 49 | $data['wcfPageIDs'][$page->pageID] = $page->wcfPageID; 50 | } 51 | 52 | // stylesheets 53 | $sql = "SELECT * 54 | FROM cms".WCF_N."_stylesheet_to_page"; 55 | $statement = WCF::getDB()->prepareStatement($sql); 56 | $statement->execute(); 57 | while ($row = $statement->fetchArray()) { 58 | $data['stylesheetsToPage'][$row['pageID']][] = $row['stylesheetID']; 59 | } 60 | 61 | return $data; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/PagePermissionCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class PagePermissionCacheBuilder extends AbstractCacheBuilder { 17 | /** 18 | * @inheritDoc 19 | */ 20 | public function rebuild(array $parameters) { 21 | $data = []; 22 | $objectTypeName = 'de.codequake.cms.page'; 23 | $pageList = new PageList(); 24 | $pageList->readObjects(); 25 | $pageList = $pageList->getObjects(); 26 | 27 | $aclOptions = ACLHandler::getInstance()->getPermissions(ACLHandler::getInstance()->getObjectTypeID($objectTypeName), array_keys($pageList)); 28 | $options = $aclOptions['options']->getObjects(); 29 | foreach ([ 30 | 'group', 31 | 'user' 32 | ] as $type) { 33 | foreach ($aclOptions[$type] as $pageID => $optionData) { 34 | if (!isset($data[$pageID])) { 35 | $data[$pageID] = [ 36 | 'group' => [], 37 | 'user' => [] 38 | ]; 39 | } 40 | foreach ($optionData as $typeID => $optionValues) { 41 | $data[$pageID][$type][$typeID] = []; 42 | 43 | foreach ($optionValues as $optionID => $optionValue) { 44 | $data[$pageID][$type][$typeID][$options[$optionID]->optionName] = $optionValue; 45 | } 46 | } 47 | } 48 | } 49 | return $data; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /files/lib/system/cache/builder/StylesheetCacheBuilder.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class StylesheetCacheBuilder extends AbstractCacheBuilder { 16 | /** 17 | * @inheritDoc 18 | */ 19 | public function rebuild(array $parameters) { 20 | $stylesheetList = new StylesheetList(); 21 | $stylesheetList->readObjects(); 22 | 23 | return $stylesheetList->getObjects(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /files/lib/system/category/FileCategoryType.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class FileCategoryType extends AbstractCategoryType { 16 | /** 17 | * @inheritDoc 18 | */ 19 | protected $hasDescription = false; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | public function canAddCategory() { 25 | return $this->canEditCategory(); 26 | } 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | public function canDeleteCategory() { 32 | return $this->canEditCategory(); 33 | } 34 | 35 | /** 36 | * @inheritDoc 37 | */ 38 | public function canEditCategory() { 39 | return WCF::getSession()->getPermission('admin.fireball.file.canAddFile'); 40 | } 41 | 42 | /** 43 | * @inheritDoc 44 | */ 45 | public function getApplication() { 46 | return 'cms'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /files/lib/system/clipboard/action/FileClipboardAction.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class FileClipboardAction extends AbstractClipboardAction { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected $actionClassActions = ['delete']; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | protected $supportedActions = ['delete']; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | public function execute(array $objects, ClipboardAction $action) { 32 | $item = parent::execute($objects, $action); 33 | 34 | if ($item === null) { 35 | return null; 36 | } 37 | 38 | // handle actions 39 | switch ($action->actionName) { 40 | case 'delete': 41 | $item->addInternalData('confirmMessage', WCF::getLanguage()->getDynamicVariable('wcf.clipboard.item.de.codequake.cms.file.delete.confirmMessage', [ 42 | 'count' => $item->getCount() 43 | ])); 44 | break; 45 | } 46 | 47 | return $item; 48 | } 49 | 50 | /** 51 | * @inheritDoc 52 | */ 53 | public function getClassName() { 54 | return FileAction::class; 55 | } 56 | 57 | /** 58 | * @inheritDoc 59 | */ 60 | public function getTypeName() { 61 | return 'de.codequake.cms.file'; 62 | } 63 | 64 | /** 65 | * Returns the ids of the files which can be deleted. 66 | * 67 | * @return array 68 | */ 69 | protected function validateDelete() { 70 | if (WCF::getSession()->getPermission('admin.fireball.file.canAddFile')) { 71 | return array_keys($this->objects); 72 | } 73 | 74 | return []; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /files/lib/system/clipboard/action/StylesheetClipboardAction.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class StylesheetClipboardAction extends AbstractClipboardAction { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected $actionClassActions = ['delete']; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | protected $supportedActions = ['delete']; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | public function execute(array $objects, ClipboardAction $action) { 32 | $item = parent::execute($objects, $action); 33 | 34 | if ($item === null) { 35 | return null; 36 | } 37 | 38 | // handle actions 39 | switch ($action->actionName) { 40 | case 'delete': 41 | $item->addInternalData('confirmMessage', WCF::getLanguage()->getDynamicVariable('wcf.clipboard.item.de.codequake.cms.stylesheet.delete.confirmMessage', [ 42 | 'count' => $item->getCount() 43 | ])); 44 | break; 45 | } 46 | 47 | return $item; 48 | } 49 | 50 | /** 51 | * @inheritDoc 52 | */ 53 | public function getClassName() { 54 | return StylesheetAction::class; 55 | } 56 | 57 | /** 58 | * @inheritDoc 59 | */ 60 | public function getTypeName() { 61 | return 'de.codequake.cms.stylesheet'; 62 | } 63 | 64 | /** 65 | * Returns the ids of the stylesheets which can be deleted. 66 | * 67 | * @return array 68 | */ 69 | protected function validateDelete() { 70 | if (WCF::getSession()->getPermission('admin.fireball.style.canAddStylesheet')) { 71 | return array_keys($this->objects); 72 | } 73 | 74 | return []; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /files/lib/system/content/type/AbstractDatabaseObjectListContentType.class.php: -------------------------------------------------------------------------------- 1 | assign([ 50 | 'additionalTemplate' => $this->additionalFormTemplate 51 | ]); 52 | } 53 | 54 | /** 55 | * @inheritDoc 56 | */ 57 | public function getOutput(Content $content) { 58 | $this->objectList = new $this->objectListClassName(); 59 | $this->objectList->sqlLimit = $content->maxItems; 60 | $this->initObjectList($content); 61 | $this->objectList->readObjects(); 62 | 63 | return WCF::getTPL()->fetch($this->templateName, $this->templateNameApplication, array_merge([ 64 | 'items' => iterator_count($this->objectList), 65 | 'objects' => $this->objectList, 66 | 'content' => $content 67 | ], $this->additionalFields)); 68 | } 69 | 70 | /** 71 | * special operations to avoid overriding getOutput 72 | * directly before readObjects() 73 | * @param Content $content 74 | */ 75 | public function initObjectList(Content $content) { 76 | // does nothing 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /files/lib/system/content/type/AbstractSearchableContentType.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | abstract class AbstractSearchableContentType extends AbstractContentType implements ISearchableContentType { 17 | /** 18 | * list of searchable fields 19 | * @var array 20 | */ 21 | protected $searchableFields = []; 22 | 23 | /** 24 | * search index data 25 | * @var array 26 | */ 27 | public $searchIndexData = []; 28 | 29 | /** 30 | * @inheritDoc 31 | * use searchableFields instead of previewFields 32 | */ 33 | public function getPreview(Content $content) { 34 | if (!empty($this->searchableFields)) { 35 | $preview = ''; 36 | foreach ($this->searchableFields as $field) { 37 | if ((string) $content->{$field} != '') { 38 | $preview .= ' - '; 39 | $preview .= $content->{$field}; 40 | } 41 | } 42 | return StringUtil::truncate(substr($preview, 3), 70); 43 | } 44 | else { 45 | return parent::getPreview($content); 46 | } 47 | } 48 | 49 | /** 50 | * @inheritDoc 51 | */ 52 | public function getSearchableData(Content $content) { 53 | foreach (LanguageFactory::getInstance()->getLanguages() as $language) { 54 | $this->searchIndexData[$language->languageID] = []; 55 | 56 | foreach ($this->searchableFields as $field) { 57 | $this->searchIndexData[$language->languageID][] = $language->get($content->{$field}); 58 | } 59 | 60 | $this->searchIndexData[$language->languageID] = implode("\n", $this->searchIndexData[$language->languageID]); 61 | } 62 | 63 | return $this->searchIndexData; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /files/lib/system/content/type/AbstractStructureContentType.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | abstract class AbstractStructureContentType extends AbstractContentType { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected $icon = 'fa-columns'; 19 | 20 | /** 21 | * Returns the css classes for structuring the output 22 | * 23 | * @return string 24 | */ 25 | public function getCSSClasses() { 26 | return ''; 27 | } 28 | 29 | /** 30 | * Returns the css classes for child elements 31 | * 32 | * @param \cms\data\content\Content $content 33 | * @return string 34 | */ 35 | public function getChildCSSClasses(Content $content) { 36 | return ''; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /files/lib/system/content/type/ColumnsContentType.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class ColumnsContentType extends AbstractStructureContentType { 16 | /** 17 | * @inheritDoc 18 | */ 19 | public function getCSSClasses() { 20 | return 'gridContainer'; 21 | } 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | public function getChildCSSClasses(Content $content) { 27 | $parent = $content->getParentContent(); 28 | 29 | $columnData = $parent->columnData; 30 | $columnCount = count($columnData); 31 | 32 | $siblingIDs = ContentCache::getInstance()->getChildIDs($parent->contentID); 33 | $siblingNumber = array_search($content->contentID, $siblingIDs); 34 | 35 | if ($columnCount > 0) 36 | $width = $columnData[$siblingNumber % $columnCount]; 37 | else 38 | $width = $columnData[$siblingNumber]; 39 | return 'grid grid'.$width; 40 | } 41 | 42 | /** 43 | * @inheritDoc 44 | */ 45 | public function validate(&$data) { 46 | $accumulatedColumnWidth = 0; 47 | 48 | if (!isset($data['columnData']) || !is_array($data['columnData'])) { 49 | throw new UserInputException('columnData'); 50 | } 51 | 52 | $data['columnData'] = ArrayUtil::toIntegerArray($data['columnData']); 53 | $columnCount = count($data['columnData']); 54 | 55 | $minColumnCount = 2; 56 | $maxColumnCount = 5; 57 | $minColumnWidth = 20; 58 | 59 | if ($columnCount < $minColumnCount || $columnCount > $maxColumnCount) { 60 | throw new UserInputException('columnData'); 61 | } 62 | 63 | foreach ($data['columnData'] as $column => $width) { 64 | if ($width < $minColumnWidth) { 65 | throw new UserInputException('columnData'); 66 | } 67 | 68 | $accumulatedColumnWidth += $width; 69 | } 70 | 71 | if ($accumulatedColumnWidth !== 100) { 72 | throw new UserInputException('columnData'); 73 | } 74 | } 75 | 76 | /** 77 | * @inheritDoc 78 | */ 79 | public function getOutput(Content $content) { 80 | return ''; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /files/lib/system/content/type/ContentContentType.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class ContentContentType extends AbstractContentType { 17 | /** 18 | * @inheritDoc 19 | */ 20 | protected $icon = 'fa-files-o'; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | public $templateName = 'contentContentType'; 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public function getFormTemplate() { 31 | WCF::getTPL()->assign([ 32 | 'contentNodeTree' => new DrainedContentNodeTree() 33 | ]); 34 | 35 | return parent::getFormTemplate(); 36 | } 37 | 38 | /** 39 | * @inheritDoc 40 | */ 41 | public function getOutput(Content $content) { 42 | /** @var Content $outputContent */ 43 | $outputContent = ContentCache::getInstance()->getContent($content->contentData['contentID']); 44 | if ($outputContent === null) 45 | return ''; 46 | 47 | return $outputContent->getOutput(); 48 | } 49 | 50 | /** 51 | * @inheritDoc 52 | */ 53 | public function getSortableOutput(Content $content) { 54 | return 'Content #' . $content->contentID; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /files/lib/system/content/type/FileContentType.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class FileContentType extends AbstractContentType { 17 | /** 18 | * @inheritDoc 19 | */ 20 | protected $icon = 'fa-file'; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | protected $previewFields = ['fileID']; 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public function getOutput(Content $content) { 31 | $file = FileCache::getInstance()->getFile($content->fileID); 32 | 33 | WCF::getTPL()->assign([ 34 | 'file' => $file 35 | ]); 36 | 37 | return parent::getOutput($content); 38 | } 39 | 40 | /** 41 | * @inheritDoc 42 | */ 43 | public function getPreview(Content $content) { 44 | $file = FileCache::getInstance()->getFile($content->{$this->previewFields[0]}); 45 | if ($file !== null) return $file->getTitle(); 46 | else return parent::getPreview($content); 47 | } 48 | 49 | /** 50 | * @inheritDoc 51 | */ 52 | public function validate(&$data) { 53 | if (!isset($data['fileID'])) { 54 | throw new UserInputException('fileID'); 55 | } 56 | 57 | $file = new File($data['fileID']); 58 | if (!$file->fileID) { 59 | throw new UserInputException('fileID'); 60 | } 61 | } 62 | 63 | /** 64 | * @param integer $fileID image id 65 | * @return File 66 | */ 67 | public function getFile($fileID) { 68 | return new File($fileID); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /files/lib/system/content/type/GoogleMapsContentType.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | */ 13 | class GoogleMapsContentType extends AbstractContentType { 14 | /** 15 | * @inheritDoc 16 | */ 17 | protected $icon = 'fa-map-o'; 18 | 19 | /** 20 | * @inheritDoc 21 | */ 22 | public function getOutput(Content $content) { 23 | return WCF::getTPL()->fetch('googleMapsContentType', 'cms', [ 24 | 'latitude' => $content->latitude, 25 | 'longitude' => $content->longitude, 26 | 'title' => $content->getTitle(), 27 | 'contentID' => $content->contentID 28 | ]); 29 | } 30 | 31 | /** 32 | * @inheritDoc 33 | */ 34 | public function isAvailableToAdd($position) { 35 | return defined('GOOGLE_MAPS_API_KEY') && GOOGLE_MAPS_API_KEY; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /files/lib/system/content/type/GroupContentType.class.php: -------------------------------------------------------------------------------- 1 | 10 | * @package de.codequake.cms 11 | */ 12 | class GroupContentType extends AbstractStructureContentType { 13 | /** 14 | * @inheritDoc 15 | */ 16 | public function getCSSClasses() { 17 | return 'contentCollection'; 18 | } 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | public function getOutput(Content $content) { 24 | return ''; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /files/lib/system/content/type/HeadlineContentType.class.php: -------------------------------------------------------------------------------- 1 | 8 | * @package de.codequake.cms 9 | */ 10 | class HeadlineContentType extends AbstractSearchableContentType { 11 | /** 12 | * @inheritDoc 13 | */ 14 | protected $icon = 'fa-underline'; 15 | 16 | /** 17 | * @inheritDoc 18 | */ 19 | public $multilingualFields = ['text']; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | protected $searchableFields = ['text']; 25 | } 26 | -------------------------------------------------------------------------------- /files/lib/system/content/type/IContentType.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | interface IContentType { 15 | /** 16 | * Returns the formatted output for the given content. 17 | * 18 | * @param \cms\data\content\Content $content 19 | * @return string 20 | */ 21 | public function getOutput(Content $content); 22 | /** 23 | * Returns the formatted output for the given content used by sortable lists. 24 | * 25 | * @param \cms\data\content\Content $content 26 | * @return string 27 | */ 28 | public function getSortableOutput(Content $content); 29 | 30 | /** 31 | * Returns the icon name (with icon prefix) for this content type. 32 | * 33 | * @return string 34 | */ 35 | public function getIcon(); 36 | 37 | /** 38 | * Returns a short preview for this content type. 39 | * 40 | * @param Content $content 41 | * @return string 42 | */ 43 | public function getPreview(Content $content); 44 | 45 | /** 46 | * Returns whether it's currently possible to create a content of this 47 | * type. 48 | * 49 | * @param string $position 50 | * @return bool 51 | */ 52 | public function isAvailableToAdd($position); 53 | 54 | /** 55 | * Reads content type specific parameters. 56 | */ 57 | public function readParameters(); 58 | 59 | /** 60 | * Reads content type specific form parameters. 61 | */ 62 | public function readFormParameters(); 63 | 64 | /** 65 | * Validates the submitted form data. In case of invalid inputs, throw 66 | * an instance of '\wcf\system\exception\UserInputException' 67 | * @param mixed[] $data 68 | */ 69 | public function validate(&$data); 70 | 71 | /** 72 | * Returns the template name for the acp forms 73 | * 74 | * @return string 75 | */ 76 | public function getFormTemplate(); 77 | 78 | /** 79 | * Returns the template name for the frontend inline editing forms 80 | * 81 | * @return string 82 | */ 83 | public function getInlineFormTemplate(); 84 | } 85 | -------------------------------------------------------------------------------- /files/lib/system/content/type/ISearchableContentType.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | interface ISearchableContentType { 15 | /** 16 | * Return data for the search index 17 | * 18 | * @param Content $content 19 | * @return array 20 | */ 21 | public function getSearchableData(Content $content); 22 | } 23 | -------------------------------------------------------------------------------- /files/lib/system/content/type/ImageContentType.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class ImageContentType extends FileContentType { 17 | /** 18 | * @inheritDoc 19 | */ 20 | protected $icon = 'fa-picture-o'; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | protected $previewFields = ['imageID']; 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public $multilingualFields = ['text']; 31 | 32 | /** 33 | * @inheritDoc 34 | */ 35 | public function getOutput(Content $content) { 36 | $image = FileCache::getInstance()->getFile($content->imageID); 37 | 38 | WCF::getTPL()->assign([ 39 | 'image' => $image, 40 | 'width' => $content->width 41 | ]); 42 | 43 | return AbstractContentType::getOutput($content); 44 | } 45 | 46 | /** 47 | * @inheritDoc 48 | */ 49 | public function validate(&$data) { 50 | if (!isset($data['imageID'])) { 51 | throw new UserInputException('imageID'); 52 | } 53 | 54 | $file = new File($data['imageID']); 55 | if (!$file->fileID) { 56 | throw new UserInputException('imageID'); 57 | } 58 | } 59 | 60 | /** 61 | * @param integer $imageID image id 62 | * @return File 63 | */ 64 | public function getImage($imageID) { 65 | return new File($imageID); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /files/lib/system/content/type/LinkContentType.class.php: -------------------------------------------------------------------------------- 1 | 8 | * @package de.codequake.cms 9 | */ 10 | class LinkContentType extends AbstractSearchableContentType { 11 | /** 12 | * @inheritDoc 13 | */ 14 | protected $icon = 'fa-link'; 15 | 16 | /** 17 | * @inheritDoc 18 | */ 19 | public $multilingualFields = ['text', 'link']; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | protected $searchableFields = ['text']; 25 | } 26 | -------------------------------------------------------------------------------- /files/lib/system/content/type/MenuContentType.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class MenuContentType extends AbstractStructureContentType { 16 | /** 17 | * @inheritDoc 18 | */ 19 | protected $icon = 'fa-sitemap'; 20 | 21 | /** 22 | * @inheritDoc 23 | */ 24 | public function getOutput(Content $content) { 25 | $menuItems = []; 26 | 27 | switch ($content->type) { 28 | case "children": 29 | if (!empty($content->pageID)) 30 | $menuItems = PageCache::getInstance()->getPage($content->pageID)->getChildrenTree(($content->depth) ? intval($content->depth) - 1 : null); 31 | else 32 | $menuItems = $content->getPage()->getChildrenTree(($content->depth) ? intval($content->depth) - 1 : null); 33 | break; 34 | 35 | case "all": 36 | $nodeTree = new AccessiblePageNodeTree(); 37 | $menuItems = $nodeTree->getIterator(); 38 | if ($content->depth) $menuItems->setMaxDepth(intval($content->depth) - 1); 39 | break; 40 | } 41 | 42 | WCF::getTPL()->assign([ 43 | 'menuItems' => $menuItems 44 | ]); 45 | 46 | return parent::getOutput($content); 47 | } 48 | 49 | /** 50 | * @inheritDoc 51 | */ 52 | public function getCSSClasses() { 53 | return 'menuContainer'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /files/lib/system/content/type/PHPContentType.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | */ 13 | class PHPContentType extends AbstractContentType { 14 | /** 15 | * @inheritDoc 16 | */ 17 | protected $icon = 'fa-code'; 18 | 19 | /** 20 | * @inheritDoc 21 | */ 22 | protected $previewFields = ['text']; 23 | 24 | /** 25 | * @inheritDoc 26 | */ 27 | public $templateName = 'phpContentType'; 28 | 29 | /** 30 | * @inheritDoc 31 | */ 32 | public function getOutput(Content $content) { 33 | try { 34 | $output = eval($content->text); 35 | } 36 | catch (\ParseError $e) { 37 | if ($content->getPermission('mod.canViewErroredContent')) { 38 | $url = LinkHandler::getInstance()->getLink('ContentEdit', ['application' => 'cms', 'object' => $content, 'isACP' => true]); 39 | $output = '
        '; 40 | $output .= 'Please check content #' . $content->contentID . '. The following error occurred parsing this content at line ' . $e->getLine() . ':

        '; 41 | $output .= $e->getMessage(); 42 | $output .= '
        '; 43 | } 44 | else { 45 | $output = ''; 46 | } 47 | } 48 | 49 | return $output; 50 | } 51 | 52 | /** 53 | * @inheritDoc 54 | */ 55 | public function getSortableOutput(Content $content) { 56 | return ''; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /files/lib/system/content/type/PollContentType.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class PollContentType extends AbstractContentType { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected $icon = 'fa-bar-chart'; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | public function getOutput(Content $content) { 24 | WCF::getTPL()->assign('poll', $content->getPoll()); 25 | 26 | return WCF::getTPL()->fetch('poll', 'wcf'); 27 | } 28 | 29 | /** 30 | * @inheritDoc 31 | */ 32 | public function readParameters() { 33 | parent::readParameters(); 34 | 35 | PollManager::getInstance()->setObject('de.codequake.cms.content', 0); 36 | } 37 | 38 | /** 39 | * @inheritDoc 40 | */ 41 | public function readFormParameters() { 42 | PollManager::getInstance()->readFormParameters(); 43 | } 44 | 45 | /** 46 | * @inheritDoc 47 | */ 48 | public function validate(&$data) { 49 | PollManager::getInstance()->validate(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /files/lib/system/content/type/SlideshowContentType.class.php: -------------------------------------------------------------------------------- 1 | 10 | * @package de.codequake.cms 11 | */ 12 | class SlideshowContentType extends AbstractStructureContentType { 13 | /** 14 | * @inheritDoc 15 | */ 16 | protected $icon = 'fa-play'; 17 | 18 | /** 19 | * @inheritDoc 20 | */ 21 | public function getCSSClasses() { 22 | return 'fireballSlideContainer'; 23 | } 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public function getChildCSSClasses(Content $content) { 29 | return 'fireballSlide'; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /files/lib/system/content/type/TabMenuContentType.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class TabMenuContentType extends AbstractStructureContentType { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected $icon = 'fa-list-alt'; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | public function getCSSClasses() { 24 | return 'section tabMenuContainer'; 25 | } 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public function getChildCSSClasses(Content $content) { 31 | return 'tabMenuContent'; 32 | } 33 | 34 | /** 35 | * @inheritDoc 36 | */ 37 | public function getOutput(Content $content) { 38 | $childIDs = ContentCache::getInstance()->getChildIDs($content->contentID); 39 | $children = []; 40 | 41 | foreach ($childIDs as $childID) { 42 | $children[] = ContentCache::getInstance()->getContent($childID); 43 | } 44 | 45 | WCF::getTPL()->assign([ 46 | 'children' => $children 47 | ]); 48 | 49 | return parent::getOutput($content); 50 | } 51 | 52 | /** 53 | * @inheritDoc 54 | */ 55 | public function getSortableOutput(Content $content) { 56 | return ''; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /files/lib/system/content/type/YoutubeContentType.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class YoutubeContentType extends AbstractContentType { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected $icon = 'fa-youtube'; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | protected $previewFields = ['video']; 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public function validate(&$data) { 29 | if (!isset($data['video'])) { 30 | throw new UserInputException('data[video]'); 31 | } 32 | 33 | if (!FileUtil::isURL($data['video'])) { 34 | throw new UserInputException('data[video]', 'notValid'); 35 | } 36 | } 37 | 38 | /** 39 | * @inheritDoc 40 | */ 41 | public function getOutput(Content $content) { 42 | parse_str(parse_url($content->video, PHP_URL_QUERY), $var); 43 | 44 | if (isset($var['v'])) { 45 | $videoID = $var['v']; 46 | return '
        '; 47 | } 48 | return ''; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /files/lib/system/content/type/graph/PieChartContentType.class.php: -------------------------------------------------------------------------------- 1 | $value) { 36 | if (!is_numeric($value)) { 37 | throw new UserInputException('contentData[graphOptions][value][' . $key . ']', 'notNumberic'); 38 | } 39 | 40 | $total += $value; 41 | } 42 | 43 | $data['total'] = $total; 44 | } 45 | 46 | /** 47 | * @inheritDoc 48 | */ 49 | public function getOutput(Content $content) { 50 | $options = []; 51 | foreach ($content->contentData['graphOptions']['title'] as $key => $title) { 52 | $options[$title] = $content->contentData['graphOptions']['value'][$key]; 53 | } 54 | 55 | WCF::getTPL()->assign([ 56 | 'graphOptions' => $options 57 | ]); 58 | 59 | return parent::getOutput($content); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /files/lib/system/cronjob/PublicationCronjob.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class PublicationCronjob extends AbstractCronjob { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public function execute(Cronjob $cronjob) { 22 | // publish pages 23 | $sql = "SELECT pageID 24 | FROM cms".WCF_N."_page 25 | WHERE isPublished = 0 26 | AND publicationDate <= ?"; 27 | $statement = WCF::getDB()->prepareStatement($sql); 28 | $statement->execute([TIME_NOW]); 29 | 30 | $pageIDs = []; 31 | while ($row = $statement->fetchArray()) { 32 | $pageIDs[] = $row['pageID']; 33 | } 34 | 35 | $action = new PageAction($pageIDs, 'publish'); 36 | $action->executeAction(); 37 | 38 | // disable pages 39 | $sql = "SELECT pageID 40 | FROM cms".WCF_N."_page 41 | WHERE isDisabled = 0 42 | AND deactivationDate BETWEEN 1 AND ?"; 43 | $statement = WCF::getDB()->prepareStatement($sql); 44 | $statement->execute([TIME_NOW]); 45 | 46 | $pageIDs = []; 47 | while ($row = $statement->fetchArray()) { 48 | $pageIDs[] = $row['pageID']; 49 | } 50 | 51 | $action = new PageAction($pageIDs, 'disable'); 52 | $action->executeAction(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /files/lib/system/event/listener/CommentActionListener.class.php: -------------------------------------------------------------------------------- 1 | 18 | * @package de.codequake.cms 19 | */ 20 | class CommentActionListener implements IParameterizedEventListener { 21 | const OBJECT_TYPE = 'de.codequake.cms.page.comment'; 22 | 23 | /** 24 | * event object 25 | * @var \wcf\data\comment\CommentAction 26 | */ 27 | protected $eventObj; 28 | 29 | /** 30 | * @inheritDoc 31 | */ 32 | public function execute($eventObj, $className, $eventName, array &$parameters) { 33 | $this->eventObj = $eventObj; 34 | 35 | if (method_exists($this, $this->eventObj->getActionName())) { 36 | call_user_func([$this, $this->eventObj->getActionName()]); 37 | } 38 | } 39 | 40 | /** 41 | * Fires notification event to notify all subscribers when added a commit. 42 | */ 43 | protected function addComment() { 44 | $params = $this->eventObj->getParameters(); 45 | $objectType = ObjectTypeCache::getInstance()->getObjectType($params['data']['objectTypeID']); 46 | $comment = $this->eventObj->createdComment; 47 | 48 | if ($comment !== null && $objectType->objectType == self::OBJECT_TYPE) { 49 | $notificationObject = new CommentUserNotificationObject($comment); 50 | 51 | UserObjectWatchHandler::getInstance()->updateObject('de.codequake.cms.page', $comment->objectID, 'comment', self::OBJECT_TYPE, $notificationObject); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /files/lib/system/event/listener/DailyCleanUpListener.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class DailyCleanUpListener implements IParameterizedEventListener { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public function execute($eventObj, $className, $eventName, array &$parameters) { 22 | // delete obsolete file uploads 23 | // files are considered obsolete when they are not assigned to 24 | // at least one category and are older than one day 25 | $sql = "SELECT file.fileID 26 | FROM cms".WCF_N."_file file 27 | LEFT JOIN cms".WCF_N."_file_to_category file_to_category ON (file.fileID = file_to_category.fileID) 28 | WHERE file_to_category.categoryID IS NULL 29 | AND file.uploadTime < ?"; 30 | $statement = WCF::getDB()->prepareStatement($sql); 31 | $statement->execute([TIME_NOW - 86400]); 32 | 33 | $fileIDs = []; 34 | while ($row = $statement->fetchArray()) { 35 | $fileIDs[] = $row['fileID']; 36 | } 37 | 38 | $fileAction = new FileAction($fileIDs, 'delete'); 39 | $fileAction->executeAction(); 40 | 41 | // delete outdated revisions 42 | if (FIREBALL_REVISION_DELETE) { 43 | $sql = "DELETE FROM cms".WCF_N."_page_revision 44 | WHERE time < ?"; 45 | $statement = WCF::getDB()->prepareStatement($sql); 46 | $statement->execute([TIME_NOW - (FIREBALL_REVISION_DELETE * 86400)]); 47 | } 48 | 49 | // delete old statistics 50 | if (FIREBALL_PAGES_STATISTICS_DELETE) { 51 | $sql = "DELETE FROM cms".WCF_N."_counter 52 | WHERE UNIX_TIMESTAMP(DATE_ADD(DATE_ADD(MAKEDATE(year, 1), INTERVAL (month)-1 MONTH), INTERVAL (day)-1 DAY)) < ?"; 53 | $statement = WCF::getDB()->prepareStatement($sql); 54 | $statement->execute([TIME_NOW - (FIREBALL_PAGES_STATISTICS_DELETE * 86400)]); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /files/lib/system/event/listener/UserRenameListener.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU Lesser General Public License 14 | * @package de.codequake.cms 15 | */ 16 | class UserRenameListener implements IParameterizedEventListener { 17 | /** 18 | * @inheritDoc 19 | */ 20 | public function execute($eventObj, $className, $eventName, array &$parameters) { 21 | $objects = $eventObj->getObjects(); 22 | $userID = $objects[0]->userID; 23 | $parameters = $eventObj->getParameters(); 24 | $username = $parameters['data']['username']; 25 | 26 | $sql = []; 27 | // pages 28 | $sql[] = "UPDATE cms" . WCF_N . "_page 29 | SET authorName = ? 30 | WHERE authorID = ?"; 31 | // page revisions 32 | $sql[] = "UPDATE cms" . WCF_N . "_page_revision 33 | SET username = ? 34 | WHERE userID = ?"; 35 | 36 | foreach ($sql as $query) { 37 | $statement = WCF::getDB()->prepareStatement($query); 38 | $statement->execute([$username, $userID]); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /files/lib/system/event/listener/WSIPImportContentTypeListener.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU Lesser General Public License 14 | * @package de.codequake.cms 15 | */ 16 | class WSIPImportContentTypeListener implements IParameterizedEventListener { 17 | /** 18 | * @inheritDoc 19 | */ 20 | public function execute($eventObj, $className, $eventName, array &$parameters) { 21 | $checkObjectTypeID = ObjectTypeCache::getInstance()->getObjectTypeByName('de.codequake.cms.content.type', 'de.codequake.cms.content.type.wsipimport')->objectTypeID; 22 | 23 | if (!empty($eventObj->content) && $eventObj->content->contentTypeID == $checkObjectTypeID) { 24 | $contentTypeID = ObjectTypeCache::getInstance()->getObjectTypeByName('de.codequake.cms.content.type', 'de.codequake.cms.content.type.text')->objectTypeID; 25 | $contentAction = new ContentAction([$eventObj->content], 'update', ['data' => ['contentTypeID' => $contentTypeID]]); 26 | $contentAction->executeAction(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /files/lib/system/importer/ContentImporter.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class ContentImporter extends AbstractImporter { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected $className = Content::class; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | public function import($oldID, array $data, array $additionalData = []) { 27 | unset($data['contentID']); 28 | 29 | if (empty($data['dontUpdateParentID'])) { 30 | if (!empty($data['parentID'])) 31 | $data['parentID'] = ImportHandler::getInstance()->getNewID('de.codequake.cms.content', $data['parentID']); 32 | if (isset($data['parentID']) && $data['parentID'] == 0) 33 | unset($data['parentID']); 34 | } else { 35 | unset($data['dontUpdateParentID']); 36 | } 37 | 38 | $data['pageID'] = ImportHandler::getInstance()->getNewID('de.codequake.cms.page', $data['pageID']); 39 | 40 | if (is_numeric($oldID)) { 41 | $content = new Content($oldID); 42 | if (!$content->contentID) 43 | $data['contentID'] = $oldID; 44 | } 45 | 46 | if (!empty($data['contentData']['pageID'])) { 47 | $data['contentData']['pageID'] = ImportHandler::getInstance()->getNewID('de.codequake.cms.page', $data['pageID']); 48 | } 49 | 50 | if (isset($data['contentData']) && is_array($data['contentData'])) { 51 | $data['contentData'] = serialize($data['contentData']); 52 | } 53 | 54 | if (isset($data['additionalData']) && is_array($data['additionalData'])) { 55 | $data['additionalData'] = serialize($data['additionalData']); 56 | } 57 | 58 | $action = new ContentAction([], 'create', [ 59 | 'data' => $data 60 | ]); 61 | $returnValues = $action->executeAction(); 62 | $newID = $returnValues['returnValues']->contentID; 63 | $content = new Content($newID); 64 | 65 | ImportHandler::getInstance()->saveNewID('de.codequake.cms.content', $oldID, $content->contentID); 66 | 67 | return $content->contentID; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /files/lib/system/importer/FileCategoryImporter.class.php: -------------------------------------------------------------------------------- 1 | getNewID('de.codequake.cms.file.category', $data['parentCategoryID']); 21 | 22 | $objectTypeID = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.category', 'de.codequake.cms.file')->objectTypeID; 23 | $category = CategoryEditor::create(array_merge($data, ['objectTypeID' => $objectTypeID])); 24 | 25 | ImportHandler::getInstance()->saveNewID('de.codequake.cms.file.category', $oldID, $category->categoryID); 26 | 27 | return $category->categoryID; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /files/lib/system/importer/FileImporter.class.php: -------------------------------------------------------------------------------- 1 | 17 | * @package de.codequake.cms 18 | */ 19 | class FileImporter extends AbstractImporter { 20 | /** 21 | * @inheritDoc 22 | */ 23 | protected $className = File::class; 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public function import($oldID, array $data, array $additionalData = []) { 29 | unset($data['fileID']); 30 | 31 | if (is_numeric($oldID)) { 32 | $file = new File($oldID); 33 | if (!$file->fileID) 34 | $data['fileID'] = $oldID; 35 | } 36 | 37 | $categoryIDs = []; 38 | if (!empty($additionalData['categoryIDs'])) { 39 | foreach ($additionalData['categoryIDs'] as $categoryID) { 40 | $categoryIDs[] = ImportHandler::getInstance()->getNewID('de.codequake.cms.file.category', $categoryID); 41 | } 42 | } 43 | 44 | $action = new FileAction([], 'create', [ 45 | 'data' => $data 46 | ]); 47 | $returnValues = $action->executeAction(); 48 | $newID = $returnValues['returnValues']->fileID; 49 | $file = new File($newID); 50 | 51 | if (!empty($categoryIDs)) { 52 | $updateAction = new FileAction([$file], 'update', ['categoryIDs' => $categoryIDs]); 53 | $updateAction->executeAction(); 54 | } 55 | 56 | $dir = dirname($file->getLocation()); 57 | if (!@file_exists($dir)) { 58 | FileUtil::makePath($dir); 59 | } 60 | 61 | // copy file 62 | try { 63 | if (!copy($additionalData['fileLocation'], $file->getLocation())) throw new SystemException(); 64 | } 65 | catch (SystemException $e) { 66 | $deleteAction = new FileAction([$file], 'delete'); 67 | $deleteAction->executeAction(); 68 | return 0; 69 | } 70 | 71 | ImportHandler::getInstance()->saveNewID('de.codequake.cms.file', $oldID, $file->fileID); 72 | 73 | return $file->fileID; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /files/lib/system/importer/PageCommentImporter.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class PageCommentImporter extends AbstractCommentImporter { 17 | /** 18 | * @inheritDoc 19 | */ 20 | protected $objectTypeName = 'de.codequake.cms.page.comment'; 21 | 22 | public function __construct() { 23 | $objectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.comment.commentableContent', $this->objectTypeName); 24 | $this->objectTypeID = $objectType->objectTypeID; 25 | } 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public function import($oldID, array $data, array $additionalData = []) { 31 | $data['objectID'] = ImportHandler::getInstance()->getNewID('de.codequake.cms.page', $data['objectID']); 32 | if (!$data['objectID']) 33 | return 0; 34 | 35 | $data['userID'] = ImportHandler::getInstance()->getNewID('com.woltlab.wcf.user', $data['userID']); 36 | 37 | return parent::import($oldID, $data); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /files/lib/system/importer/PageCommentResponseImporter.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class PageCommentResponseImporter extends AbstractCommentResponseImporter { 15 | /** 16 | * @inheritDoc 17 | */ 18 | protected $objectTypeName = 'de.codequake.cms.page.comment'; 19 | } 20 | -------------------------------------------------------------------------------- /files/lib/system/importer/StylesheetImporter.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class StylesheetImporter extends AbstractImporter { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected $className = Stylesheet::class; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | public function import($oldID, array $data, array $additionalData = []) { 27 | unset($data['stylesheetID']); 28 | 29 | if (is_numeric($oldID)) { 30 | $stylesheet = new Stylesheet($oldID); 31 | if (!$stylesheet->stylesheetID) 32 | $data['stylesheetID'] = $oldID; 33 | } 34 | 35 | $action = new StylesheetAction([], 'create', [ 36 | 'data' => $data 37 | ]); 38 | $returnValues = $action->executeAction(); 39 | $newID = $returnValues['returnValues']->stylesheetID; 40 | $stylesheet = new Stylesheet($newID); 41 | 42 | ImportHandler::getInstance()->saveNewID('de.codequake.cms.stylesheet', $oldID, $stylesheet->stylesheetID); 43 | 44 | return $stylesheet->stylesheetID; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /files/lib/system/option/CMSPageMultiSelectOptionType.class.php: -------------------------------------------------------------------------------- 1 | 18 | * @package de.codequake.cms 19 | */ 20 | class CMSPageMultiSelectOptionType extends AbstractOptionType { 21 | /** 22 | * @inheritDoc 23 | */ 24 | public function getData(Option $option, $newValue) { 25 | if (!is_array($newValue)) { 26 | $newValue = []; 27 | } 28 | 29 | return implode("\n", ArrayUtil::toIntegerArray($newValue)); 30 | } 31 | 32 | /** 33 | * @inheritDoc 34 | */ 35 | public function getFormElement(Option $option, $value) { 36 | $nodeTree = new PageNodeTree(); 37 | $nodeList = $nodeTree->getIterator(); 38 | 39 | WCF::getTPL()->assign([ 40 | 'nodeList' => $nodeList, 41 | 'option' => $option, 42 | 'value' => (!is_array($value) ? explode("\n", $value) : $value) 43 | ]); 44 | 45 | return WCF::getTPL()->fetch('pageMultiSelectOptionType', 'cms'); 46 | } 47 | 48 | /** 49 | * @inheritDoc 50 | */ 51 | public function validate(Option $option, $newValue) { 52 | if (!is_array($newValue)) $newValue = []; 53 | $newValue = ArrayUtil::toIntegerArray($newValue); 54 | 55 | foreach ($newValue as $pageID) { 56 | if (PageCache::getInstance()->getPage($pageID) === null) { 57 | throw new UserInputException($option->optionName, 'validationFailed'); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /files/lib/system/option/CMSPageSelectOptionType.class.php: -------------------------------------------------------------------------------- 1 | 17 | * @package de.codequake.cms 18 | */ 19 | class CMSPageSelectOptionType extends AbstractOptionType { 20 | /** 21 | * @inheritDoc 22 | */ 23 | public function getData(Option $option, $newValue) { 24 | return intval($newValue); 25 | } 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public function getFormElement(Option $option, $value) { 31 | $nodeTree = new PageNodeTree(); 32 | $nodeList = $nodeTree->getIterator(); 33 | 34 | WCF::getTPL()->assign([ 35 | 'nodeList' => $nodeList, 36 | 'option' => $option, 37 | 'value' => $value 38 | ]); 39 | 40 | return WCF::getTPL()->fetch('pageSelectOptionType', 'cms'); 41 | } 42 | 43 | /** 44 | * @inheritDoc 45 | */ 46 | public function validate(Option $option, $newValue) { 47 | if (!empty($newValue)) { 48 | if (PageCache::getInstance()->getPage($newValue) === null) { 49 | throw new UserInputException($option->optionName, 'validationFailed'); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /files/lib/system/page/PagePermissionHandler.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class PagePermissionHandler extends SingletonFactory { 19 | /** 20 | * cached permissions 21 | * @var array 22 | */ 23 | protected $permissions = []; 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | protected function init() { 29 | $this->permissions = PagePermissionCacheBuilder::getInstance()->getData(); 30 | } 31 | 32 | public function resetCache() { 33 | PagePermissionCacheBuilder::getInstance()->reset(); 34 | } 35 | 36 | /** 37 | * Returns the acl options for the given page and for the given user. 38 | * If no user is given, the active user is used. 39 | * 40 | * @param \cms\data\page\Page $page 41 | * @param \wcf\data\user\User $user 42 | * @return array 43 | */ 44 | public function getPermissions(Page $page, User $user = null) { 45 | if ($user === null) { 46 | $user = WCF::getUser(); 47 | } 48 | 49 | $permissions = []; 50 | if (isset($this->permissions[$page->pageID])) { 51 | if (isset($this->permissions[$page->pageID]['group'])) { 52 | foreach ($user->getGroupIDs() as $groupID) { 53 | if (isset($this->permissions[$page->pageID]['group'][$groupID])) { 54 | foreach ($this->permissions[$page->pageID]['group'][$groupID] as $optionName => $optionValue) { 55 | if (isset($permissions[$optionName])) { 56 | $permissions[$optionName] = $permissions[$optionName] || $optionValue; 57 | } 58 | else { 59 | $permissions[$optionName] = $optionValue; 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | if (isset($this->permissions[$page->pageID]['user']) && isset($this->permissions[$page->pageID]['user'][$user->userID])) { 67 | foreach ($this->permissions[$page->pageID]['user'][$user->userID] as $optionName => $optionValue) { 68 | $permissions[$optionName] = $optionValue; 69 | } 70 | } 71 | } 72 | 73 | return $permissions; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /files/lib/system/page/handler/TPageOnlineLocationPageHandler.class.php: -------------------------------------------------------------------------------- 1 | pageID; 19 | $objectID = $user->pageObjectID; 20 | $fPage = null; 21 | 22 | if ($objectID) { 23 | $fPage = PageCache::getInstance()->getPage($user->pageObjectID); 24 | } 25 | else { 26 | if ($pageID) { 27 | $pages = PageCache::getInstance()->getPages(); 28 | foreach ($pages as $item) { 29 | if ($item->wcfPageID == $pageID) { 30 | $fPage = $item; 31 | break; 32 | } 33 | } 34 | } 35 | } 36 | 37 | if ($fPage === null || !$fPage->canRead()) { 38 | return ''; 39 | } 40 | 41 | return WCF::getLanguage()->getDynamicVariable('wcf.page.onlineLocation.de.codequake.cms.Page', ['page' => $fPage]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /files/lib/system/page/type/PagePageType.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | */ 13 | class PagePageType extends AbstractPageType { 14 | /** 15 | * @inheritdoc 16 | */ 17 | public $frontendController = PagePage::class; 18 | 19 | /** 20 | * @inheritDoc 21 | */ 22 | public $assignValues = [ 23 | 'isCommentable' => FIREBALL_PAGES_DEFAULT_COMMENTS 24 | ]; 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | public function readFormParameters(AbstractForm $form) { 30 | $formParameters = parent::readFormParameters($form); 31 | 32 | $this->assignValues['isCommentable'] = isset($_POST['isCommentable']) ? 1 : 0; 33 | 34 | return array_merge($formParameters, $this->assignValues); 35 | } 36 | 37 | /** 38 | * @inheritDoc 39 | */ 40 | public function readData(AbstractForm $form) { 41 | $return = parent::readData($form); 42 | 43 | if (empty($_POST)) { 44 | if (!empty($form->page->isCommentable)) $return['isCommentable'] = $form->page->isCommentable; 45 | } 46 | 47 | return $return; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /files/lib/system/poll/ContentPollHandler.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class ContentPollHandler extends AbstractPollHandler { 18 | /** 19 | * @inheritDoc 20 | * @todo only admins with the right to create contents are 21 | * allowed to start a public poll. 22 | */ 23 | public function canStartPublicPoll() { 24 | return true; 25 | } 26 | 27 | /** 28 | * @inheritDoc 29 | * @todo only users that can view the content are allowed to 30 | * vote. 31 | */ 32 | public function canVote() { 33 | return (WCF::getSession()->getPermission('user.fireball.content.canVotePoll') ? true : false); 34 | } 35 | 36 | /** 37 | * @inheritDoc 38 | */ 39 | public function getRelatedObject(Poll $poll) { 40 | $content = new Content($poll->objectID); 41 | 42 | if ($content->contentID && $content->pollID == $poll->pollID) { 43 | return $content; 44 | } 45 | 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /files/lib/system/search/PageSearch.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class PageSearch extends AbstractSearchableObjectType { 16 | /** 17 | * page cache 18 | * @var array<\cms\data\page\SearchResultPage> 19 | */ 20 | public $cache = []; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | public function cacheObjects(array $objectIDs, array $additionalData = null) { 26 | $pageList = new SearchResultPageList(); 27 | $pageList->getConditionBuilder()->add('page.pageID IN (?)', [$objectIDs]); 28 | $pageList->readObjects(); 29 | 30 | foreach ($pageList->getObjects() as $page) { 31 | $this->cache[$page->pageID] = $page; 32 | } 33 | } 34 | 35 | /** 36 | * @inheritDoc 37 | */ 38 | public function getIDFieldName() { 39 | return $this->getTableName().'.pageID'; 40 | } 41 | 42 | /** 43 | * @inheritDoc 44 | */ 45 | public function getObject($objectID) { 46 | if (isset($this->cache[$objectID])) { 47 | return $this->cache[$objectID]; 48 | } 49 | 50 | return null; 51 | } 52 | 53 | /** 54 | * @inheritDoc 55 | */ 56 | public function getSubjectFieldName() { 57 | return $this->getTableName().'.title'; 58 | } 59 | 60 | /** 61 | * @inheritDoc 62 | */ 63 | public function getTableName() { 64 | return 'cms'.WCF_N.'_page'; 65 | } 66 | 67 | /** 68 | * @inheritDoc 69 | */ 70 | public function getTimeFieldName() { 71 | return $this->getTableName().'.creationTime'; 72 | } 73 | 74 | /** 75 | * @inheritDoc 76 | */ 77 | public function getUsernameFieldName() { 78 | return $this->getTableName().'.authorName'; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /files/lib/system/search/acp/PageACPSearchResultProvider.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class PageACPSearchResultProvider implements IACPSearchResultProvider { 19 | /** 20 | * @inheritDoc 21 | */ 22 | public function search($query) { 23 | // check permissions 24 | if (!WCF::getSession()->getPermission('admin.fireball.page.canAddPage')) { 25 | return []; 26 | } 27 | 28 | $results = []; 29 | 30 | /** @var \cms\data\page\Page[] $pages */ 31 | $pages = PageCacheBuilder::getInstance()->getData([], 'pages'); 32 | foreach ($pages as $page) { 33 | if (mb_stripos($page->getTitle(), $query) !== false || mb_stripos($page->alias, $query) !== false) { 34 | $link = LinkHandler::getInstance()->getLink('PageEdit', [ 35 | 'application' => 'cms', 36 | 'id' => $page->pageID 37 | ]); 38 | 39 | $subtitle = WCF::getLanguage()->getDynamicVariable('cms.page.parents', [ 40 | 'page' => $page 41 | ]); 42 | 43 | $results[] = new ACPSearchResult($page->getTitle(), $link, $subtitle); 44 | } 45 | } 46 | 47 | return $results; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /files/lib/system/sitemap/object/PageSitemapObject.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class PageSitemapObject extends AbstractSitemapObjectObjectType { 18 | /** 19 | * @inheritDoc 20 | */ 21 | public function getObjectClass() { 22 | return Page::class; 23 | } 24 | 25 | /** 26 | * @inheritDoc 27 | */ 28 | public function getLastModifiedColumn() { 29 | return 'lastEditTime'; 30 | } 31 | 32 | /** 33 | * @inheritDoc 34 | */ 35 | public function canView(DatabaseObject $object) { 36 | /** @var Page $object */ 37 | return $object->canRead(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /files/lib/system/stat/PageCommentStatDailyHandler.class.php: -------------------------------------------------------------------------------- 1 | 11 | * @package de.codequake.cms 12 | */ 13 | class PageCommentStatDailyHandler extends AbstractCommentStatDailyHandler { 14 | /** 15 | * @inheritDoc 16 | */ 17 | protected $objectType = 'de.codequake.cms.page.comment'; 18 | } 19 | -------------------------------------------------------------------------------- /files/lib/system/stat/PageStatDailyHandler.class.php: -------------------------------------------------------------------------------- 1 | 12 | * @package de.codequake.cms 13 | */ 14 | class PageStatDailyHandler extends AbstractStatDailyHandler { 15 | /** 16 | * @inheritDoc 17 | */ 18 | public function getData($date) { 19 | return [ 20 | 'counter' => $this->getCounter($date, 'cms'.WCF_N.'_page', 'creationTime'), 21 | 'total' => $this->getTotal($date, 'cms'.WCF_N.'_page', 'creationTime') 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /files/lib/system/template/EnvironmentTemplateEngine.class.php: -------------------------------------------------------------------------------- 1 | environment = $environment; 15 | } 16 | 17 | /** 18 | * @inheritDoc 19 | */ 20 | protected function init() { 21 | $this->registerPrefilter(['event', 'hascontent', 'lang']); 22 | $this->assign([ 23 | '__wcf' => null, 24 | '__wcfVersion' => LAST_UPDATE_TIME 25 | ]); 26 | 27 | parent::init(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /files/lib/system/user/activity/event/PageCommentUserActivityEvent.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class PageCommentUserActivityEvent extends SingletonFactory implements IUserActivityEvent { 19 | /** 20 | * @inheritDoc 21 | */ 22 | public function prepare(array $events) { 23 | $commentIDs = []; 24 | foreach ($events as $event) { 25 | $commentIDs[] = $event->objectID; 26 | } 27 | 28 | $commentList = new CommentList(); 29 | $commentList->getConditionBuilder()->add('comment.commentID IN (?)', [$commentIDs]); 30 | $commentList->readObjects(); 31 | $comments = $commentList->getObjects(); 32 | 33 | foreach ($events as $event) { 34 | if (isset($comments[$event->objectID])) { 35 | $comment = $comments[$event->objectID]; 36 | $page = PageCache::getInstance()->getPage($comment->objectID); 37 | 38 | if ($page !== null) { 39 | if (!$page->canRead()) { 40 | continue; 41 | } 42 | 43 | $event->setIsAccessible(); 44 | 45 | $text = WCF::getLanguage()->getDynamicVariable('wcf.user.profile.recentActivity.pageComment', [ 46 | 'page' => $page 47 | ]); 48 | $event->setTitle($text); 49 | $event->setDescription($comment->getFormattedMessage()); 50 | 51 | continue; 52 | } 53 | } 54 | 55 | $event->setIsOrphaned(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /files/lib/system/user/notification/object/type/PageCommentResponseUserNotificationObjectType.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class PageCommentResponseUserNotificationObjectType extends AbstractUserNotificationObjectType { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected static $decoratorClassName = CommentResponseUserNotificationObject::class; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | protected static $objectClassName = CommentResponse::class; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | protected static $objectListClassName = CommentResponseList::class; 32 | } 33 | -------------------------------------------------------------------------------- /files/lib/system/user/notification/object/type/PageCommentUserNotificationObjectType.class.php: -------------------------------------------------------------------------------- 1 | 15 | * @package de.codequake.cms 16 | */ 17 | class PageCommentUserNotificationObjectType extends AbstractUserNotificationObjectType { 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected static $decoratorClassName = CommentUserNotificationObject::class; 22 | 23 | /** 24 | * @inheritDoc 25 | */ 26 | protected static $objectClassName = Comment::class; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | protected static $objectListClassName = CommentList::class; 32 | } 33 | -------------------------------------------------------------------------------- /files/lib/system/user/object/watch/PageUserObjectWatch.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @package de.codequake.cms 17 | */ 18 | class PageUserObjectWatch implements IUserObjectWatch { 19 | /** 20 | * @inheritDoc 21 | */ 22 | public function validateObjectID($objectID) { 23 | $page = PageCache::getInstance()->getPage($objectID); 24 | if ($page === null) { 25 | throw new IllegalLinkException(); 26 | } 27 | 28 | // check permission 29 | if (!$page->canRead()) { 30 | throw new PermissionDeniedException(); 31 | } 32 | } 33 | 34 | /** 35 | * @inheritDoc 36 | */ 37 | public function resetUserStorage(array $userIDs) { 38 | UserStorageHandler::getInstance()->reset($userIDs, 'cmsUnreadWatchedPages'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /files/lib/system/worker/FileRebuildDataWorker.class.php: -------------------------------------------------------------------------------- 1 | 14 | * @package de.codequake.cms 15 | */ 16 | class FileRebuildDataWorker extends AbstractRebuildDataWorker { 17 | /** 18 | * @inheritDoc 19 | */ 20 | protected $limit = 100; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | protected $objectListClassName = FileList::class; 26 | 27 | /** 28 | * @inheritDoc 29 | */ 30 | public function execute() { 31 | parent::execute(); 32 | 33 | /** @var \cms\data\file\File $file */ 34 | foreach ($this->objectList->getObjects() as $file) { 35 | if ($file->isImage() && !$file->hasThumbnail()) { 36 | $fileAction = new FileAction([$file], 'generateThumbnail'); 37 | $fileAction->executeAction(); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /files/lib/util/BrowserUtil.class.php: -------------------------------------------------------------------------------- 1 | 10 | * @package de.codequake.cms 11 | */ 12 | final class BrowserUtil { 13 | /** 14 | * Returns the name of the browser with the given user agent. 15 | * 16 | * @param string $userAgent 17 | * @return string 18 | */ 19 | public static function getBrowser($userAgent = '') { 20 | require_once(CMS_DIR.'lib/util/Browser.php'); 21 | $browser = new \Browser($userAgent); 22 | if (!$browser->isRobot()) return $browser->getBrowser(); 23 | return 'unknown'; 24 | } 25 | 26 | /** 27 | * Returns the used platform. 28 | * 29 | * @param string $userAgent 30 | * @return string 31 | */ 32 | public static function getPlatform($userAgent = '') { 33 | require_once(CMS_DIR.'lib/util/Browser.php'); 34 | $browser = new \Browser($userAgent); 35 | return $browser->getPlatform(); 36 | } 37 | 38 | /** 39 | * Returns whether the given user agent is of a mobile browser. 40 | * 41 | * @param string $userAgent 42 | * @return boolean 43 | */ 44 | public static function isMobile($userAgent = '') { 45 | require_once(CMS_DIR.'lib/util/Browser.php'); 46 | $browser = new \Browser($userAgent); 47 | return $browser->isMobile(); 48 | } 49 | 50 | /** 51 | * Returns whether the given user agent is of a tablet device. 52 | * 53 | * @param string $userAgent 54 | * @return boolean 55 | */ 56 | public static function isTablet($userAgent = '') { 57 | require_once(CMS_DIR.'lib/util/Browser.php'); 58 | $browser = new \Browser($userAgent); 59 | return $browser->isTablet(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /files/style/grid.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Fireball Grid System for WCF 3 | */ 4 | .gridContainer { 5 | display: flex; 6 | flex-flow: row wrap; 7 | 8 | &::before, &::after { 9 | //display: table; 10 | //content: ''; 11 | } 12 | 13 | &::after { 14 | //clear: both; 15 | } 16 | } 17 | 18 | @media all and (min-width: 801px) { 19 | .grid { 20 | //float: left; 21 | //box-sizing: border-box; 22 | //-moz-box-sizing: border-box; 23 | } 24 | 25 | @for $i from 1 through 100 { 26 | .grid#{$i} { 27 | //width: percentage($i/100); 28 | flex: 0 0 percentage($i/100); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /files/style/presetClasses.scss: -------------------------------------------------------------------------------- 1 | .sectionBorder:not(.sortableNode) { 2 | border: 1px solid $wcfContentBorder; 3 | } 4 | 5 | .sectionPadding { 6 | padding: 6px; 7 | } 8 | 9 | .sectionCenter { 10 | text-align: center; 11 | } 12 | -------------------------------------------------------------------------------- /files_wcf/lib/system/event/listener/FireballRouteListener.class.php: -------------------------------------------------------------------------------- 1 | 13 | * @package de.codequake.cms 14 | */ 15 | class FireballRouteListener implements IParameterizedEventListener { 16 | /** 17 | * @inheritDoc 18 | */ 19 | public function execute($eventObj, $className, $eventName, array &$parameters) { 20 | /** @var $eventObj \wcf\system\request\RouteHandler */ 21 | 22 | $route = new FireballRequestRoute(); 23 | $eventObj->addRoute($route); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /files_wcf/style/ui/fireball.scss: -------------------------------------------------------------------------------- 1 | #filePicker { 2 | .filePickerItem { 3 | .sortableNodeLabel { 4 | display: flex; 5 | padding: 2px 0; 6 | margin-top: -20px; 7 | 8 | > img { 9 | height: 64px; 10 | width: auto; 11 | max-width: 80px; 12 | } 13 | 14 | > div { 15 | padding-left: 10px; 16 | } 17 | } 18 | } 19 | 20 | span.button.small { 21 | margin-top: 14px; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /templates/__copyright.tpl: -------------------------------------------------------------------------------- 1 | {if $__cms->isActiveApplication()}{/if} 2 | -------------------------------------------------------------------------------- /templates/__pageAddButton.tpl: -------------------------------------------------------------------------------- 1 | {if $__wcf->getSession()->getPermission('admin.fireball.page.canAddPage')} 2 |
      1. 3 | 4 | 5 | {lang}cms.acp.page.add{/lang} 6 | 7 | 8 | {js application='cms' file='Fireball'} 9 | 14 |
      2. 15 | {/if} 16 | -------------------------------------------------------------------------------- /templates/cmsFileBBCodeTag.tpl: -------------------------------------------------------------------------------- 1 | {if $_file|isset} 2 | {if $_isImage} 3 | 4 | 5 | {if $_caption != ''}{$_caption}{/if} 6 | 7 | {else} 8 | {$_file->getTitle()} 9 | {/if} 10 | {/if} 11 | -------------------------------------------------------------------------------- /templates/contentAddDialog.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 |
        5 |

        {lang}cms.acp.content.type.{$objectType->objectType}{/lang}

        6 | 7 | {@$typeTemplate} 8 |
        9 | 10 |
        11 |

        {lang}cms.acp.content.css{/lang}

        12 | 13 |
        14 |
        15 |
        16 | 17 | {lang}cms.acp.content.css.cssClasses.description{/lang} 18 |
        19 |
        20 | 21 | {event name='cssFields'} 22 |
        23 |
        24 | 25 |
        26 | 27 | {@SECURITY_TOKEN_INPUT_TAG} 28 | 29 | 30 | 31 | 32 |
        33 |
        34 |
        35 | -------------------------------------------------------------------------------- /templates/contentNodeList.tpl: -------------------------------------------------------------------------------- 1 | {if $position|empty}{assign var=position value='body'}{/if} 2 | 3 | {assign var=oldDepth value=0} 4 | {foreach from=$contentNodeTree item=content} 5 | {section name=i loop=$oldDepth-$contentNodeTree->getDepth()}{if $position == 'sidebar'}{else}{/if}{/section} 6 | {if $content->getTypeName() != 'de.codequake.cms.content.type.box'} 7 | {if $position == 'sidebar'} 8 |
        9 | {else} 10 | getCSSClasses()} class="{$content->getCSSClasses()}"{/if} id="cmsContent{@$content->contentID}" data-content-type="{$content->getTypeName()}"> 11 | {/if} 12 | {if $content->showHeadline}

        {$content->getTitle()}

        {/if} 13 | 14 | {if $position == 'sidebar'}
        {/if} 15 | {@$content->getOutput()|language} 16 | {if !$contentNodeTree->current()->hasChildren()} 17 | {if $position == 'sidebar'}
        {else}{/if} 18 | {/if} 19 | 20 | {assign var=oldDepth value=$contentNodeTree->getDepth()} 21 | {else} 22 | {@$content->getOutput()|language} 23 | {/if} 24 | {/foreach} 25 | {section name=i loop=$oldDepth}{if $position == 'sidebar'}{else}{/if}{/section} 26 | -------------------------------------------------------------------------------- /templates/contentTypeList.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 | 4 | 5 | 6 |

        {lang}cms.acp.content.add{/lang}

        7 | 8 | {foreach from=$contentTypes key=category item=types} 9 |
        10 |

        {lang}cms.acp.content.type.{$category}{/lang}

        11 | 12 | 20 |
        21 | {/foreach} 22 | 23 |
        24 | 27 |
        28 |
        29 |
        30 | 31 | 44 | -------------------------------------------------------------------------------- /templates/fileContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 | {@$file->getIconTag(32)} 3 |
        4 | {$file->getTitle()} 5 |

        6 | {$file->filesize|filesize} 7 |

        8 |
        9 |
        10 | -------------------------------------------------------------------------------- /templates/galleryContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 | {foreach from=$images item=image} 3 | 6 | {/foreach} 7 |
        8 | -------------------------------------------------------------------------------- /templates/googleMapsContentType.tpl: -------------------------------------------------------------------------------- 1 | {include file='googleMapsJavaScript'} 2 | 10 | 11 |
        12 | -------------------------------------------------------------------------------- /templates/headlineContentType.tpl: -------------------------------------------------------------------------------- 1 |
        type == 'h1'} class="boxHeadline"{elseif $content->type == h2} class="boxSubHeadline"{elseif $content->type == h3} class="containerHeadline"{/if}> 2 | {if $content->link}{/if}<{$content->type}>{$content->text|language}type}>{if $content->link}{/if} 3 |
        4 | -------------------------------------------------------------------------------- /templates/imageContentType.tpl: -------------------------------------------------------------------------------- 1 | 2 | {$content->title}text} title="{$content->text|language}"{/if}{if $content->width} style="width: {$content->width}px"{/if} /> 3 | {if $content->text}
        {$content->text|language}{/if} 4 |
        5 | -------------------------------------------------------------------------------- /templates/inlineEditor_boxContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 9 |
        10 |
        11 | -------------------------------------------------------------------------------- /templates/inlineEditor_columnsContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 | 8 |
        9 | 10 | 15 | -------------------------------------------------------------------------------- /templates/inlineEditor_contentContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 9 |
        10 |
        11 | -------------------------------------------------------------------------------- /templates/inlineEditor_databaseObjectListContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 | 5 | {if $errorField == 'objectListClassname'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {else} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.databaseobjectlist.objectListClassname.error.{@$errorType}{/lang} 11 | {/if} 12 | 13 | {/if} 14 |
        15 |
        16 | 17 |
        18 |
        19 |
        20 | 21 | {if $errorField == 'maxItems'} 22 | 23 | {if $errorType == 'empty'} 24 | {lang}wcf.global.form.error.empty{/lang} 25 | {else} 26 | {lang}cms.acp.content.type.de.codequake.cms.content.type.databaseobjectlist.maxItems.error.{@$errorType}{/lang} 27 | {/if} 28 | 29 | {/if} 30 |
        31 |
        32 | 33 | {if !$additionalTemplate|empty} 34 | {include file=$additionalTemplate application='cms'} 35 | {/if} 36 | -------------------------------------------------------------------------------- /templates/inlineEditor_fileContentType.tpl: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |
        4 |
        5 |
          6 | {lang}cms.acp.file.picker{/lang} 7 |
          8 |
          9 |
          10 | 11 | 30 | -------------------------------------------------------------------------------- /templates/inlineEditor_galleryContentType.tpl: -------------------------------------------------------------------------------- 1 |
          2 |
          3 |
          4 |
          5 |
            6 | {lang}cms.acp.file.picker{/lang} 7 |
            8 |
            9 |
            10 | 11 | 32 | -------------------------------------------------------------------------------- /templates/inlineEditor_googleMapsContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | N 5 | {if $errorField == 'latitude'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {else} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.googlemaps.latitude.error.{@$errorType}{/lang} 11 | {/if} 12 | 13 | {/if} 14 |
            15 |
            16 | 17 |
            18 |
            19 |
            20 | E 21 | {if $errorField == 'longitude'} 22 | 23 | {if $errorType == 'empty'} 24 | {lang}wcf.global.form.error.empty{/lang} 25 | {else} 26 | {lang}cms.acp.content.type.de.codequake.cms.content.type.googlemaps.longitude.error.{@$errorType}{/lang} 27 | {/if} 28 | 29 | {/if} 30 |
            31 |
            32 | -------------------------------------------------------------------------------- /templates/inlineEditor_groupContentType.tpl: -------------------------------------------------------------------------------- 1 |

            {lang}cms.acp.content.type.de.codequake.cms.content.type.group.description{/lang}

            2 | -------------------------------------------------------------------------------- /templates/inlineEditor_headlineContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 11 |
            12 |
            13 | 14 |
            15 |
            16 |
            17 | 18 | 19 | {include file='multipleLanguageInputJavascript' elementIdentifier='text' forceSelection=false} 20 |
            21 |
            22 | 23 |
            24 |
            25 |
            26 | 27 |
            28 |
            29 | -------------------------------------------------------------------------------- /templates/inlineEditor_linkContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 9 |
            10 |
            11 | 12 |
            13 |
            14 |
            15 | 16 | 17 | {include file='multipleLanguageInputJavascript' elementIdentifier='text' forceSelection=false} 18 |
            19 |
            20 | 21 |
            22 |
            23 |
            24 | 25 | 26 | {include file='multipleLanguageInputJavascript' elementIdentifier='link' forceSelection=false} 27 |
            28 |
            29 | -------------------------------------------------------------------------------- /templates/inlineEditor_menuContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 8 |
            9 |
            10 | 11 |
            12 |
            13 |
            14 | 20 |
            21 |
            22 | 23 |
            24 |
            25 |
            26 | 27 | {lang}cms.acp.content.type.de.codequake.cms.content.type.menu.depth.description{/lang} 28 |
            29 |
            30 | -------------------------------------------------------------------------------- /templates/inlineEditor_phpContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 5 | 6 | {if !'ACE_THEME'|defined} 7 | {include file='codemirror' codemirrorMode='php' codemirrorSelector='#text' sandbox=true} 8 | {else} 9 | {include file='ace' aceMode='php' aceSelector='text' sandbox=true} 10 | {/if} 11 |
            12 |
            13 | -------------------------------------------------------------------------------- /templates/inlineEditor_rssContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 5 | {lang}cms.acp.content.type.de.codequake.cms.content.type.rss.url.description{/lang} 6 |
            7 |
            8 | 9 |
            10 |
            11 | 12 |
            13 |
            14 | 15 |
            16 |
            17 | -------------------------------------------------------------------------------- /templates/inlineEditor_slideshowContentType.tpl: -------------------------------------------------------------------------------- 1 |

            {lang}cms.acp.content.type.de.codequake.cms.content.type.slideshow.description{/lang}

            2 | -------------------------------------------------------------------------------- /templates/inlineEditor_tabMenuContentType.tpl: -------------------------------------------------------------------------------- 1 |

            {lang}cms.acp.content.type.de.codequake.cms.content.type.tabmenu.description{/lang}

            2 | -------------------------------------------------------------------------------- /templates/inlineEditor_templateContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 5 | {if $errorField == 'text'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {else} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.template.text.error.{@$errorType}{/lang} 11 | {/if} 12 | 13 | {/if} 14 | {lang}cms.acp.content.type.de.codequake.cms.content.type.template.text.description{/lang} 15 | 16 | {if !'ACE_THEME'|defined} 17 | {include file='codemirror' codemirrorMode='smartymixed' codemirrorSelector='#text' sandbox=true} 18 | {else} 19 | {include file='ace' aceMode='smarty' aceSelector='text' sandbox=true} 20 | {/if} 21 |
            22 |
            23 | -------------------------------------------------------------------------------- /templates/inlineEditor_textContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 |
            3 |
            4 | 5 | {if !$errorField|empty && $errorField == 'text'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {elseif $errorType == 'tooLong'} 10 | {lang}wcf.message.error.tooLong{/lang} 11 | {elseif $errorType == 'censoredWordsFound'} 12 | {lang}wcf.message.error.censoredWordsFound{/lang} 13 | {elseif $errorType == 'disallowedBBCodes'} 14 | {lang}wcf.message.error.disallowedBBCodes{/lang} 15 | {else} 16 | {lang}cms.content.text.text.error.{@$errorType}{/lang} 17 | {/if} 18 | 19 | {/if} 20 | 21 | {include file='wysiwyg'} 22 | {include file='wysiwygI18n' elementIdentifier='text' forceSelection=false} 23 | 24 | 25 |
            26 |
            27 | -------------------------------------------------------------------------------- /templates/inlineEditor_userContentType.tpl: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
            9 |
            10 | 11 | {if $errorField == 'data[name]'} 12 | 13 | {if $errorType == 'empty'} 14 | {lang}wcf.global.form.error.empty{/lang} 15 | {elseif $errorType == 'notValid'} 16 | {lang}wcf.user.username.error.notValid{/lang} 17 | {/if} 18 | 19 | {/if} 20 |
            21 | 22 | -------------------------------------------------------------------------------- /templates/inlineEditor_youtubeContentType.tpl: -------------------------------------------------------------------------------- 1 | 2 |
            3 |
            4 | 5 | {if $errorField == 'data[video]'} 6 | 7 | {if $errorType == 'empty'} 8 | {lang}wcf.global.form.error.empty{/lang} 9 | {elseif $errorType == 'notValid'} 10 | {lang}cms.acp.content.type.de.codequake.cms.content.type.youtube.video.error.notValid{/lang} 11 | {/if} 12 | 13 | {/if} 14 |
            15 | 16 | -------------------------------------------------------------------------------- /templates/linkContentType.tpl: -------------------------------------------------------------------------------- 1 | 2 | {$content->text|language} 3 | 4 | -------------------------------------------------------------------------------- /templates/menuContentType.tpl: -------------------------------------------------------------------------------- 1 |
              2 | {assign var=oldDepth value=0} 3 | {foreach from=$menuItems item=item} 4 | {section name=i loop=$oldDepth-$menuItems->getDepth()}
            {/section} 5 |
          • 6 | {$item->getTitle()} 7 |
              8 | 9 | {if !$menuItems->current()->hasChildren()}
          • {/if} 10 | {assign var=oldDepth value=$menuItems->getDepth()} 11 | {/foreach} 12 | {section name=i loop=$oldDepth}{/section} 13 | 14 | -------------------------------------------------------------------------------- /templates/pieChartContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 | {if !$__pieChartJavascriptLoaded|isset} 3 | 4 | 5 | {assign var=__pieChartJavascriptLoaded value=true} 6 | {/if} 7 | -------------------------------------------------------------------------------- /templates/rssContentType.tpl: -------------------------------------------------------------------------------- 1 | {hascontent} 2 |
            3 | 36 |
            37 | {/hascontent} 38 | -------------------------------------------------------------------------------- /templates/sitemap.tpl: -------------------------------------------------------------------------------- 1 | {include file='header'} 2 | 3 |
            4 | {assign var=oldDepth value=0} 5 |
              6 | {foreach from=$pageNodeTree item=node} 7 | {section name=i loop=$oldDepth-$pageNodeTree->getDepth()}
            {/section} 8 |
          • 9 | 10 | {$node->getTitle()} 11 | {if !$node->lastEditTime|empty}{@$node->lastEditTime|date}{else}{@$node->creationTime|date}{/if} 12 | 13 |
              14 | {if !$pageNodeTree->current()->hasChildren()} 15 |
          • 16 | {/if} 17 | {assign var=oldDepth value=$pageNodeTree->getDepth()} 18 | {/foreach} 19 | {section name=i loop=$oldDepth}{/section} 20 | 21 |
            22 | 23 | {include file='footer'} 24 | -------------------------------------------------------------------------------- /templates/slideshowContentType.tpl: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /templates/tabMenuContentType.tpl: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /templates/userContentType.tpl: -------------------------------------------------------------------------------- 1 |
            2 | {@$user->getAvatar()->getImageTag(128)} 3 |
            4 | 32 |

            {@$user->username}

            33 |

            {$user->getUserTitle()}

            34 |
            35 | 36 |
            37 | {@$user->getFormattedUserOption('aboutMe')} 38 |
            39 |
            40 | -------------------------------------------------------------------------------- /xml/acpSearchProvider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cms\system\search\acp\PageACPSearchResultProvider 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /xml/bbcode.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 1 11 | 12 | 13 | ^(left|right|none)$ 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 1 28 | 29 | 30 | 1 31 | fa-file-text-o 32 | cms.bbcode.button.page 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /xml/cronjob.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cms\system\cronjob\PublicationCronjob 6 | 7 | 8 | */15 9 | * 10 | * 11 | * 12 | * 13 | 1 14 | 1 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /xml/menuItem.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.woltlab.wcf.FooterMenu 6 | de.codequake.cms.Sitemap 7 | Seitenübersicht 8 | Sitemap 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /xml/objectTypeDefinition.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | de.codequake.cms.content.type 6 | 7 | 8 | 9 | de.codequake.cms.page.type 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /xml/page.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cms\page\SitemapPage 6 | system 7 | fireball_sitemap_enable 8 | 9 | CMS: Seitenübersicht 10 | CMS: Sitemap 11 | 12 | 13 | Seitenübersicht 14 | 15 | 16 | Sitemap 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /xml/userNotificationEvent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | comment 7 | de.codequake.cms.page.comment 8 | cms\system\user\notification\event\PageCommentUserNotificationEvent 9 | 1 10 | 11 | 12 | commentResponse 13 | de.codequake.cms.page.comment.response.notification 14 | cms\system\user\notification\event\PageCommentResponseUserNotificationEvent 15 | 1 16 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------