mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-12-31 03:52:01 +08:00
Merge branch 'the-djmaze:master' into master
This commit is contained in:
commit
c2b7ddc76b
25 changed files with 135 additions and 66 deletions
|
@ -316,5 +316,5 @@ dev_email = ""
|
|||
dev_password = ""
|
||||
|
||||
[version]
|
||||
current = "2.26.4"
|
||||
current = "2.27.0"
|
||||
saved = "Sun, 18 Dec 2022 22:10:48 +0000"
|
||||
|
|
55
CHANGELOG.md
55
CHANGELOG.md
|
@ -1,3 +1,57 @@
|
|||
## 2.27.0 – 2023-03-14
|
||||
|
||||
## Added
|
||||
- Unique attachments.zip filename
|
||||
[#992](https://github.com/the-djmaze/snappymail/pull/992)
|
||||
- Select next email after (re)move current
|
||||
[#968](https://github.com/the-djmaze/snappymail/pull/968)
|
||||
|
||||
## Changed
|
||||
- Improved FolderCollection handling
|
||||
- MODSEQ requires 64-bit int
|
||||
- Update russian language by @Akrobs
|
||||
[#994](https://github.com/the-djmaze/snappymail/pull/994)
|
||||
- Don't make font bigger when screen > 1400px
|
||||
- Put top menu "accountPlace" inside top-system-dropdown-id
|
||||
- Put attachment controls inside attachmentsPlace
|
||||
- Show message toolbar on screens > 1400px
|
||||
[#970](https://github.com/the-djmaze/snappymail/pull/970)
|
||||
- Chinese updated by @mayswind
|
||||
[#1011](https://github.com/the-djmaze/snappymail/pull/1011)
|
||||
- Prevent folder/messages flags conflict by using the right name `attributes` for Folders
|
||||
- FolderInformation() use jsonSerialize()
|
||||
- Squire space handling on paste use `\u00A0` instead of ` ` for
|
||||
[#1004](https://github.com/the-djmaze/snappymail/pull/1004)
|
||||
- Better line-height for QR code
|
||||
|
||||
## Fixed
|
||||
- Composer src is null
|
||||
- Image in Signature disappears in Sent/Draft
|
||||
[#932](https://github.com/the-djmaze/snappymail/pull/932)
|
||||
- Mail list is empty
|
||||
[#998](https://github.com/the-djmaze/snappymail/pull/998)
|
||||
- Cache handling issues
|
||||
[#1003](https://github.com/the-djmaze/snappymail/pull/1003)
|
||||
- No message notification popup when installed in sub-directory
|
||||
[#1007](https://github.com/the-djmaze/snappymail/pull/1007)
|
||||
- ERROR: Undefined constant "MailSo\Log\Drivers\STDERR"
|
||||
[#965](https://github.com/the-djmaze/snappymail/pull/965)
|
||||
- 'Location:' headers using proper '302 Found' header
|
||||
- Can't send email
|
||||
[#1006](https://github.com/the-djmaze/snappymail/pull/1006)
|
||||
- Attachment preview
|
||||
[#1005](https://github.com/the-djmaze/snappymail/pull/1005)
|
||||
- When decrypt message, subject was replaced empty
|
||||
|
||||
### Removed
|
||||
- \MailSo\Imap\ImapClient::GetConnectedPort()
|
||||
|
||||
### Nextcloud
|
||||
- CSS `--panel-bg-clr` was missing
|
||||
- SnappyMail Menu under Nextcloud top bar
|
||||
[#1017](https://github.com/the-djmaze/snappymail/pull/1017)
|
||||
|
||||
|
||||
## 2.26.4 – 2023-02-24
|
||||
|
||||
## Added
|
||||
|
@ -62,7 +116,6 @@
|
|||
- Unused Squire code
|
||||
|
||||
|
||||
|
||||
## 2.26.2 – 2023-02-17
|
||||
|
||||
## Added
|
||||
|
|
24
README.md
24
README.md
|
@ -141,26 +141,26 @@ RainLoop 1.17 vs SnappyMail
|
|||
|
||||
|js/* |RainLoop |Snappy |
|
||||
|--------------- |--------: |--------: |
|
||||
|admin.js |2.170.153 | 78.971 |
|
||||
|app.js |4.207.787 | 409.340 |
|
||||
|admin.js |2.170.153 | 78.985 |
|
||||
|app.js |4.207.787 | 407.112 |
|
||||
|boot.js | 868.735 | 4.142 |
|
||||
|libs.js | 658.812 | 185.881 |
|
||||
|libs.js | 658.812 | 185.826 |
|
||||
|sieve.js | 0 | 85.599 |
|
||||
|polyfills.js | 334.608 | 0 |
|
||||
|serviceworker.js | 0 | 285 |
|
||||
|TOTAL |8.240.095 | 764.218 |
|
||||
|TOTAL |8.240.095 | 761.949 |
|
||||
|
||||
|js/min/* |RainLoop |Snappy |RL gzip |SM gzip |RL brotli |SM brotli |
|
||||
|--------------- |--------: |--------: |------: |------: |--------: |--------: |
|
||||
|admin.min.js | 256.831 | 38.936 | 73.606 | 13.036 | 60.877 | 11.694 |
|
||||
|app.min.js | 515.367 | 186.883 |139.456 | 63.102 |110.485 | 54.200 |
|
||||
|admin.min.js | 256.831 | 38.922 | 73.606 | 13.044 | 60.877 | 11.689 |
|
||||
|app.min.js | 515.367 | 185.851 |139.456 | 62.793 |110.485 | 54.006 |
|
||||
|boot.min.js | 84.659 | 2.084 | 26.998 | 1.202 | 23.643 | 1.003 |
|
||||
|libs.min.js | 584.772 | 90.445 |180.901 | 33.592 |155.182 | 30.108 |
|
||||
|libs.min.js | 584.772 | 90.419 |180.901 | 33.579 |155.182 | 30.112 |
|
||||
|sieve.min.js | 0 | 41.525 | 0 | 10.435 | 0 | 9.401 |
|
||||
|polyfills.min.js | 32.837 | 0 | 11.406 | 0 | 10.175 | 0 |
|
||||
|TOTAL user |1.217.635 | 279.412 |358.761 | 97.896 |299.485 | 85.311 |
|
||||
|TOTAL user+sieve |1.217.635 | 320.937 |358.761 |108.331 |299.485 | 94.712 |
|
||||
|TOTAL admin | 959.099 | 131.465 |292.911 | 47.830 |249.877 | 42.805 |
|
||||
|TOTAL user |1.217.635 | 278.354 |358.761 | 97.574 |299.485 | 85.121 |
|
||||
|TOTAL user+sieve |1.217.635 | 319.879 |358.761 |108.009 |299.485 | 94.522 |
|
||||
|TOTAL admin | 959.099 | 131.425 |292.911 | 47.825 |249.877 | 42.804 |
|
||||
|
||||
For a user it is around 72% smaller and faster than traditional RainLoop.
|
||||
|
||||
|
@ -189,8 +189,8 @@ For a user it is around 72% smaller and faster than traditional RainLoop.
|
|||
|
||||
|css/* |RainLoop |Snappy |RL gzip |SM gzip |SM brotli |
|
||||
|------------ |-------: |------: |------: |------: |--------: |
|
||||
|app.css | 340.331 | 81.526 | 46.946 | 16.960 | 14.620 |
|
||||
|app.min.css | 274.947 | 65.398 | 39.647 | 15.032 | 13.119 |
|
||||
|app.css | 340.331 | 81.459 | 46.946 | 16.976 | 14.618 |
|
||||
|app.min.css | 274.947 | 65.368 | 39.647 | 15.033 | 13.117 |
|
||||
|boot.css | | 1.326 | | 664 | 545 |
|
||||
|boot.min.css | | 1.071 | | 590 | 474 |
|
||||
|admin.css | | 30.296 | | 6.939 | 6.066 |
|
||||
|
|
|
@ -4,7 +4,7 @@ import { logoutLink } from 'Common/Links';
|
|||
import { i18nToNodes, initOnStartOrLangChange } from 'Common/Translator';
|
||||
|
||||
import { LanguageStore } from 'Stores/Language';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
import { initThemes } from 'Stores/Theme';
|
||||
|
||||
import { SelectComponent } from 'Component/Select';
|
||||
import { CheckboxComponent } from 'Component/Checkbox';
|
||||
|
@ -46,7 +46,7 @@ export class AbstractApp {
|
|||
initOnStartOrLangChange();
|
||||
|
||||
LanguageStore.populate();
|
||||
ThemeStore.populate();
|
||||
initThemes();
|
||||
|
||||
this.start();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'External/ko';
|
||||
|
||||
import { Settings, SettingsGet } from 'Common/Globals';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
import { initThemes } from 'Stores/Theme';
|
||||
|
||||
import Remote from 'Remote/Admin/Fetch';
|
||||
|
||||
|
@ -18,7 +18,7 @@ export class AdminApp extends AbstractApp {
|
|||
}
|
||||
|
||||
refresh() {
|
||||
ThemeStore.populate();
|
||||
initThemes();
|
||||
this.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ import { IdentityUserStore } from 'Stores/User/Identity';
|
|||
import { FolderUserStore } from 'Stores/User/Folder';
|
||||
import { PgpUserStore } from 'Stores/User/Pgp';
|
||||
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
||||
import { ThemeStore, changeTheme } from 'Stores/Theme';
|
||||
import { ThemeStore, initThemes } from 'Stores/Theme';
|
||||
import { LanguageStore } from 'Stores/Language';
|
||||
import { MessageUserStore } from 'Stores/User/Message';
|
||||
|
||||
|
@ -183,7 +183,7 @@ export class AppUser extends AbstractApp {
|
|||
super.bootstart();
|
||||
|
||||
addEventListener('beforeunload', event => {
|
||||
if (arePopupsVisible() || (!SettingsUserStore.layout() && MessageUserStore.message())) {
|
||||
if (arePopupsVisible() || (!SettingsUserStore.usePreviewPane() && MessageUserStore.message())) {
|
||||
event.preventDefault();
|
||||
return event.returnValue = i18n('POPUPS_ASK/EXIT_ARE_YOU_SURE');
|
||||
}
|
||||
|
@ -191,9 +191,8 @@ export class AppUser extends AbstractApp {
|
|||
}
|
||||
|
||||
refresh() {
|
||||
ThemeStore.populate();
|
||||
initThemes();
|
||||
LanguageStore.language(SettingsGet('language'));
|
||||
changeTheme(SettingsGet('Theme'));
|
||||
this.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@ export function MimeToMessage(data, message)
|
|||
let signed;
|
||||
const struct = ParseMime(data);
|
||||
if (struct.headers) {
|
||||
let html = struct.getByContentType('text/html');
|
||||
let html = struct.getByContentType('text/html'),
|
||||
subject = struct.headerValue('subject');
|
||||
html = html ? html.body : '';
|
||||
|
||||
message.subject(struct.headerValue('subject') || '');
|
||||
subject && message.subject(subject);
|
||||
|
||||
// EmailCollectionModel
|
||||
['from','to'].forEach(name => message[name].fromString(struct.headerValue(name)));
|
||||
|
|
|
@ -19,23 +19,25 @@ export const
|
|||
fontSansSerif: ko.observable(''),
|
||||
fontSerif: ko.observable(''),
|
||||
fontMono: ko.observable(''),
|
||||
isMobile: ko.observable(false),
|
||||
isMobile: ko.observable(false)
|
||||
},
|
||||
|
||||
populate: () => {
|
||||
const themes = Settings.app('themes');
|
||||
initThemes = () => {
|
||||
const theme = SettingsGet('Theme'),
|
||||
themes = Settings.app('themes');
|
||||
|
||||
ThemeStore.themes(isArray(themes) ? themes : []);
|
||||
ThemeStore.theme(SettingsGet('Theme'));
|
||||
if (!ThemeStore.isMobile()) {
|
||||
ThemeStore.userBackgroundName(SettingsGet('userBackgroundName'));
|
||||
ThemeStore.userBackgroundHash(SettingsGet('userBackgroundHash'));
|
||||
}
|
||||
ThemeStore.fontSansSerif(SettingsGet('fontSansSerif'));
|
||||
ThemeStore.fontSerif(SettingsGet('fontSerif'));
|
||||
ThemeStore.fontMono(SettingsGet('fontMono'));
|
||||
|
||||
leftPanelDisabled(ThemeStore.isMobile());
|
||||
ThemeStore.themes(isArray(themes) ? themes : []);
|
||||
ThemeStore.theme(theme);
|
||||
changeTheme(theme);
|
||||
if (!ThemeStore.isMobile()) {
|
||||
ThemeStore.userBackgroundName(SettingsGet('userBackgroundName'));
|
||||
ThemeStore.userBackgroundHash(SettingsGet('userBackgroundHash'));
|
||||
}
|
||||
ThemeStore.fontSansSerif(SettingsGet('fontSansSerif'));
|
||||
ThemeStore.fontSerif(SettingsGet('fontSerif'));
|
||||
ThemeStore.fontMono(SettingsGet('fontMono'));
|
||||
|
||||
leftPanelDisabled(ThemeStore.isMobile());
|
||||
},
|
||||
|
||||
changeTheme = (value, themeTrigger = ()=>0) => {
|
||||
|
|
|
@ -50,10 +50,10 @@ export const SettingsUserStore = new class {
|
|||
|
||||
self.init();
|
||||
|
||||
self.usePreviewPane = koComputable(() => self.layout() && !ThemeStore.isMobile());
|
||||
self.usePreviewPane = koComputable(() => ThemeStore.isMobile() ? 0 : self.layout());
|
||||
|
||||
const toggleLayout = () => {
|
||||
const value = ThemeStore.isMobile() ? 0 : self.layout();
|
||||
const value = self.usePreviewPane();
|
||||
$htmlCL.toggle('sm-msgView-side', Layout.SidePreview === value);
|
||||
$htmlCL.toggle('sm-msgView-bottom', Layout.BottomPreview === value);
|
||||
fireEvent('rl-layout', value);
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
.accountPlace {
|
||||
border-right: 1px solid var(--btn-border-clr, rgba(0, 0, 0, 0.2));
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
margin: 0 6px -3px 0;
|
||||
|
|
|
@ -801,7 +801,7 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
if (msgComposeType && message) {
|
||||
sDate = timestampToString(message.dateTimeStampInUTC(), 'FULL');
|
||||
sDate = timestampToString(message.dateTimestamp(), 'FULL');
|
||||
sSubject = message.subject();
|
||||
aDraftInfo = message.draftInfo;
|
||||
|
||||
|
|
|
@ -566,11 +566,9 @@ export class MailMessageList extends AbstractViewRight {
|
|||
// initMailboxLayoutResizer
|
||||
const top = dom.querySelector('.messageList'),
|
||||
fToggle = () => {
|
||||
let layout = SettingsUserStore.layout();
|
||||
let layout = SettingsUserStore.usePreviewPane();
|
||||
setLayoutResizer(top, ClientSideKeyNameMessageListSize,
|
||||
(ThemeStore.isMobile() || !layout)
|
||||
? 0
|
||||
: (Layout.SidePreview === layout ? 'Width' : 'Height')
|
||||
layout ? (Layout.SidePreview === layout ? 'Width' : 'Height') : 0
|
||||
);
|
||||
};
|
||||
if (top) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
This app packages SnappyMail <upstream>2.26.4</upstream>.
|
||||
This app packages SnappyMail <upstream>2.27.0</upstream>.
|
||||
|
||||
SnappyMail is a simple, modern, lightweight & fast web-based email client.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ RUN mkdir -p /app/code
|
|||
WORKDIR /app/code
|
||||
|
||||
# If you change the extraction below, be sure to test on scaleway
|
||||
VERSION=2.26.4
|
||||
VERSION=2.27.0
|
||||
RUN wget https://github.com/the-djmaze/snappymail/releases/download/v${VERSION}/snappymail-${VERSION}.zip -O /tmp/snappymail.zip && \
|
||||
unzip /tmp/snappymail.zip -d /app/code && \
|
||||
rm /tmp/snappymail.zip && \
|
||||
|
|
|
@ -87,6 +87,8 @@
|
|||
--border-radius: var(--border-radius);
|
||||
--hr-color: var(--color-border);
|
||||
|
||||
--panel-bg-clr: var(--color-main-background);
|
||||
|
||||
--warning-clr: var(--color-warning);
|
||||
--warning-bg-clr: #fcf8e3;
|
||||
--warning-border-clr: #fbeed5;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<id>snappymail</id>
|
||||
<name>SnappyMail</name>
|
||||
<summary>SnappyMail Webmail</summary>
|
||||
<version>2.26.4</version>
|
||||
<version>2.27.0</version>
|
||||
<licence>agpl</licence>
|
||||
<author>SnappyMail, RainLoop Team, Nextgen-Networks, Tab Fitts, Nathan Kinkade, Pierre-Alain Bandinelli</author>
|
||||
<description><![CDATA[**Simple, modern, lightweight & fast web-based email client.**
|
||||
|
|
|
@ -120,3 +120,9 @@ a.selectable::after {
|
|||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 799px) {
|
||||
#body-user #rl-left {
|
||||
top: 50px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ return "SnappyMail Webmail is a browser-based multilingual IMAP client with an a
|
|||
# script_snappymail_versions()
|
||||
sub script_snappymail_versions
|
||||
{
|
||||
return ( "2.26.4" );
|
||||
return ( "2.27.0" );
|
||||
}
|
||||
|
||||
sub script_snappymail_version_desc
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"title": "SnappyMail",
|
||||
"description": "Simple, modern & fast web-based email client",
|
||||
"private": true,
|
||||
"version": "2.26.4",
|
||||
"version": "2.27.0",
|
||||
"homepage": "https://snappymail.eu",
|
||||
"author": {
|
||||
"name": "DJ Maze",
|
||||
|
|
|
@ -4,8 +4,8 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
{
|
||||
const
|
||||
NAME = 'Nextcloud',
|
||||
VERSION = '2.20',
|
||||
RELEASE = '2023-02-22',
|
||||
VERSION = '2.21',
|
||||
RELEASE = '2023-03-18',
|
||||
CATEGORY = 'Integrations',
|
||||
DESCRIPTION = 'Integrate with Nextcloud v20+',
|
||||
REQUIRED = '2.25.1';
|
||||
|
|
|
@ -6,3 +6,6 @@ SELECT_FOLDER = "Select folder"
|
|||
SELECT_FILES = "Select file(s)"
|
||||
ATTACH_FILES = "Attach Nextcloud files"
|
||||
SELECT_CALENDAR = "Select calendar"
|
||||
FILE_ATTACH = "attach"
|
||||
FILE_INTERNAL = "internal"
|
||||
FILE_PUBLIC = "public"
|
||||
|
|
|
@ -6,3 +6,6 @@ SELECT_FOLDER = "选择文件夹"
|
|||
SELECT_FILES = "选择文件"
|
||||
ATTACH_FILES = "添加 Nextcloud 文件"
|
||||
SELECT_CALENDAR = "选择日历"
|
||||
FILE_ATTACH = "attach"
|
||||
FILE_INTERNAL = "internal"
|
||||
FILE_PUBLIC = "public"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<ul id="sm-nc-files-tree"></ul>
|
||||
</div>
|
||||
<footer data-bind="visible:files">
|
||||
<button data-bind="click:attach" name="select" data-icon="📎" class="button-vue">attach</button>
|
||||
<button data-bind="click:shareInternal" name="share-internal" data-icon="🔗" class="button-vue">internal</button>
|
||||
<button data-bind="click:sharePublic" name="share-public" data-icon="🔗" class="button-vue">public</button>
|
||||
<button data-bind="click:attach" name="select" data-icon="📎" class="button-vue" data-i18n="NEXTCLOUD/FILE_ATTACH">attach</button>
|
||||
<button data-bind="click:shareInternal" name="share-internal" data-icon="🔗" class="button-vue" data-i18n="NEXTCLOUD/FILE_INTERNAL">internal</button>
|
||||
<button data-bind="click:sharePublic" name="share-public" data-icon="🔗" class="button-vue" data-i18n="NEXTCLOUD/FILE_PUBLIC">public</button>
|
||||
</footer>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<blockquote>
|
||||
<p class="muted width100-on-mobile" style="width: 550px" data-i18n="PLUGIN_2FA/TWO_FACTOR_SECRET_DESC"></p>
|
||||
</blockquote>
|
||||
<pre data-bind="text: viewQRCode" style="line-height:1;letter-spacing:-1px;font-family:monospace"></pre>
|
||||
<pre data-bind="text: viewQRCode" style="line-height:1.1;letter-spacing:-1px;font-family:monospace"></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="visible: '' !== viewBackupCodes()">
|
||||
|
|
|
@ -61,6 +61,8 @@ abstract class Service
|
|||
} else {
|
||||
\ob_start('ob_gzhandler');
|
||||
}
|
||||
} else {
|
||||
\ob_start();
|
||||
}
|
||||
|
||||
$sQuery = \trim($_SERVER['QUERY_STRING'] ?? '');
|
||||
|
@ -110,7 +112,6 @@ abstract class Service
|
|||
}
|
||||
|
||||
$bIndex = true;
|
||||
$sResult = '';
|
||||
if (\count($aPaths) && !empty($aPaths[0]) && 'index' !== \strtolower($aPaths[0])) {
|
||||
if ('mailto' !== \strtolower($aPaths[0]) && !\SnappyMail\HTTP\SecFetch::matchAnyRule($oConfig->Get('security', 'secfetch_allow', ''))) {
|
||||
\MailSo\Base\Http::StatusHeader(403);
|
||||
|
@ -123,15 +124,15 @@ abstract class Service
|
|||
return false;
|
||||
}
|
||||
|
||||
$bIndex = false;
|
||||
$sMethodName = 'Service'.\preg_replace('/@.+$/', '', $aPaths[0]);
|
||||
$sMethodExtra = \strpos($aPaths[0], '@') ? \preg_replace('/^[^@]+@/', '', $aPaths[0]) : '';
|
||||
|
||||
if (\method_exists($oServiceActions, $sMethodName) && \is_callable(array($oServiceActions, $sMethodName))) {
|
||||
$bIndex = false;
|
||||
$oServiceActions->SetQuery($sQuery)->SetPaths($aPaths);
|
||||
$sResult = $oServiceActions->{$sMethodName}($sMethodExtra);
|
||||
} else if (!$oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths)) {
|
||||
$bIndex = true;
|
||||
echo $oServiceActions->{$sMethodName}($sMethodExtra);
|
||||
} else if ($oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths)) {
|
||||
$bIndex = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,6 +197,8 @@ abstract class Service
|
|||
$oActions->verifyCacheByKey($sCacheFileName);
|
||||
if ($oConfig->Get('cache', 'system_data', true)) {
|
||||
$sResult = $oActions->Cacher()->Get($sCacheFileName);
|
||||
} else {
|
||||
$sResult = '';
|
||||
}
|
||||
|
||||
if ($sResult) {
|
||||
|
@ -232,14 +235,13 @@ abstract class Service
|
|||
static::setCSP(null, $sScriptHash);
|
||||
*/
|
||||
$oActions->cacheByKey($sCacheFileName);
|
||||
|
||||
echo $sResult;
|
||||
unset($sResult);
|
||||
} else if (!\headers_sent()) {
|
||||
\header('X-XSS-Protection: 1; mode=block');
|
||||
}
|
||||
|
||||
// Output result
|
||||
echo $sResult;
|
||||
unset($sResult);
|
||||
|
||||
$oActions->BootEnd();
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue