first commit
No files matched your search
@@ -0,0 +1,387 @@
|
||||
#####
|
||||
#
|
||||
# Example .htaccess file for TYPO3 CMS - for use with Apache Webserver
|
||||
#
|
||||
# This file includes settings for the following configuration options:
|
||||
#
|
||||
# - Compression
|
||||
# - Caching
|
||||
# - MIME types
|
||||
# - Cross Origin requests
|
||||
# - Rewriting and Access
|
||||
# - Miscellaneous
|
||||
# - PHP optimisation
|
||||
#
|
||||
# If you want to use it, you have to copy it to the root folder of your TYPO3 installation (if its
|
||||
# not there already) and rename it to '.htaccess'. To make .htaccess files work, you might need to
|
||||
# adjust the 'AllowOverride' directive in your Apache configuration file.
|
||||
#
|
||||
# IMPORTANT: You may need to change this file depending on your TYPO3 installation!
|
||||
# Consider adding this file's content to your webserver's configuration directly for speed improvement
|
||||
#
|
||||
# Lots of the options are taken from https://github.com/h5bp/html5-boilerplate/blob/master/dist/.htaccess
|
||||
#
|
||||
####
|
||||
|
||||
#RewriteEngine On
|
||||
#RewriteCond % {HTTPS} off
|
||||
#RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
|
||||
|
||||
### Begin: Compression ###
|
||||
|
||||
# Compressing resource files will save bandwidth and so improve loading speed especially for users
|
||||
# with slower internet connections. TYPO3 can compress the .js and .css files for you.
|
||||
# *) Uncomment the following lines and
|
||||
# *) Set $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'] = 9 for the Backend
|
||||
# *) Set $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] = 9 together with the TypoScript properties
|
||||
# config.compressJs and config.compressCss for GZIP compression of Frontend JS and CSS files.
|
||||
|
||||
#<FilesMatch "\.js\.gzip$">
|
||||
# AddType "text/javascript" .gzip
|
||||
#</FilesMatch>
|
||||
#<FilesMatch "\.css\.gzip$">
|
||||
# AddType "text/css" .gzip
|
||||
#</FilesMatch>
|
||||
#AddEncoding gzip .gzip
|
||||
|
||||
<IfModule mod_deflate.c>
|
||||
# Force compression for mangled `Accept-Encoding` request headers
|
||||
<IfModule mod_setenvif.c>
|
||||
<IfModule mod_headers.c>
|
||||
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
|
||||
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
# Compress all output labeled with one of the following media types.
|
||||
#
|
||||
# (!) For Apache versions below version 2.3.7 you don't need to
|
||||
# enable `mod_filter` and can remove the `<IfModule mod_filter.c>`
|
||||
# and `</IfModule>` lines as `AddOutputFilterByType` is still in
|
||||
# the core directives.
|
||||
#
|
||||
# https://httpd.apache.org/docs/current/mod/mod_filter.html#addoutputfilterbytype
|
||||
|
||||
<IfModule mod_filter.c>
|
||||
AddOutputFilterByType DEFLATE application/atom+xml \
|
||||
application/javascript \
|
||||
application/json \
|
||||
application/ld+json \
|
||||
application/manifest+json \
|
||||
application/rdf+xml \
|
||||
application/rss+xml \
|
||||
application/schema+json \
|
||||
application/vnd.geo+json \
|
||||
application/vnd.ms-fontobject \
|
||||
application/x-font-ttf \
|
||||
application/x-javascript \
|
||||
application/x-web-app-manifest+json \
|
||||
application/xhtml+xml \
|
||||
application/xml \
|
||||
font/eot \
|
||||
font/opentype \
|
||||
image/bmp \
|
||||
image/svg+xml \
|
||||
image/vnd.microsoft.icon \
|
||||
image/x-icon \
|
||||
text/cache-manifest \
|
||||
text/css \
|
||||
text/html \
|
||||
text/javascript \
|
||||
text/plain \
|
||||
text/vcard \
|
||||
text/vnd.rim.location.xloc \
|
||||
text/vtt \
|
||||
text/x-component \
|
||||
text/x-cross-domain-policy \
|
||||
text/xml
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_mime.c>
|
||||
AddEncoding gzip svgz
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
### End: Compression ###
|
||||
|
||||
|
||||
|
||||
### Begin: Browser caching of resource files ###
|
||||
|
||||
# This affects Frontend and Backend and increases performance.
|
||||
<IfModule mod_expires.c>
|
||||
|
||||
ExpiresActive on
|
||||
ExpiresDefault "access plus 1 month"
|
||||
|
||||
ExpiresByType text/css "access plus 1 year"
|
||||
|
||||
ExpiresByType application/json "access plus 0 seconds"
|
||||
ExpiresByType application/ld+json "access plus 0 seconds"
|
||||
ExpiresByType application/schema+json "access plus 0 seconds"
|
||||
ExpiresByType application/vnd.geo+json "access plus 0 seconds"
|
||||
ExpiresByType application/xml "access plus 0 seconds"
|
||||
ExpiresByType text/xml "access plus 0 seconds"
|
||||
|
||||
ExpiresByType image/vnd.microsoft.icon "access plus 1 week"
|
||||
ExpiresByType image/x-icon "access plus 1 week"
|
||||
|
||||
ExpiresByType text/x-component "access plus 1 month"
|
||||
|
||||
ExpiresByType text/html "access plus 0 seconds"
|
||||
|
||||
ExpiresByType application/javascript "access plus 1 year"
|
||||
ExpiresByType application/x-javascript "access plus 1 year"
|
||||
ExpiresByType text/javascript "access plus 1 year"
|
||||
|
||||
ExpiresByType application/manifest+json "access plus 1 week"
|
||||
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
|
||||
ExpiresByType text/cache-manifest "access plus 0 seconds"
|
||||
|
||||
ExpiresByType audio/ogg "access plus 1 month"
|
||||
ExpiresByType image/bmp "access plus 1 month"
|
||||
ExpiresByType image/gif "access plus 1 month"
|
||||
ExpiresByType image/jpeg "access plus 1 month"
|
||||
ExpiresByType image/png "access plus 1 month"
|
||||
ExpiresByType image/svg+xml "access plus 1 month"
|
||||
ExpiresByType image/webp "access plus 1 month"
|
||||
ExpiresByType video/mp4 "access plus 1 month"
|
||||
ExpiresByType video/ogg "access plus 1 month"
|
||||
ExpiresByType video/webm "access plus 1 month"
|
||||
|
||||
ExpiresByType application/atom+xml "access plus 1 hour"
|
||||
ExpiresByType application/rdf+xml "access plus 1 hour"
|
||||
ExpiresByType application/rss+xml "access plus 1 hour"
|
||||
|
||||
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
|
||||
ExpiresByType font/eot "access plus 1 month"
|
||||
ExpiresByType font/opentype "access plus 1 month"
|
||||
ExpiresByType application/x-font-ttf "access plus 1 month"
|
||||
ExpiresByType application/font-woff "access plus 1 month"
|
||||
ExpiresByType application/x-font-woff "access plus 1 month"
|
||||
ExpiresByType font/woff "access plus 1 month"
|
||||
ExpiresByType application/font-woff2 "access plus 1 month"
|
||||
|
||||
ExpiresByType text/x-cross-domain-policy "access plus 1 week"
|
||||
|
||||
</IfModule>
|
||||
|
||||
### End: Browser caching of resource files ###
|
||||
|
||||
|
||||
### Begin: MIME types ###
|
||||
|
||||
# Proper MIME types for all files
|
||||
<IfModule mod_mime.c>
|
||||
|
||||
RemoveType .html .htm
|
||||
<FilesMatch ".+\.html?$">
|
||||
AddType text/html .html
|
||||
AddType text/html .htm
|
||||
</FilesMatch>
|
||||
|
||||
RemoveType .svg .svgz
|
||||
<FilesMatch ".+\.svgz?$">
|
||||
AddType image/svg+xml .svg
|
||||
AddType image/svg+xml .svgz
|
||||
</FilesMatch>
|
||||
|
||||
|
||||
|
||||
# Data interchange
|
||||
AddType application/atom+xml atom
|
||||
AddType application/json json map topojson
|
||||
AddType application/ld+json jsonld
|
||||
AddType application/rss+xml rss
|
||||
AddType application/vnd.geo+json geojson
|
||||
AddType application/xml rdf xml
|
||||
|
||||
# JavaScript
|
||||
AddType application/javascript js
|
||||
|
||||
# Manifest files
|
||||
AddType application/manifest+json webmanifest
|
||||
AddType application/x-web-app-manifest+json webapp
|
||||
AddType text/cache-manifest appcache
|
||||
|
||||
# Media files
|
||||
|
||||
AddType audio/mp4 f4a f4b m4a
|
||||
AddType audio/ogg oga ogg opus
|
||||
AddType image/bmp bmp
|
||||
AddType image/webp webp
|
||||
AddType video/mp4 f4v f4p m4v mp4
|
||||
AddType video/ogg ogv
|
||||
AddType video/webm webm
|
||||
AddType video/x-flv flv
|
||||
AddType image/x-icon cur ico
|
||||
|
||||
# Web fonts
|
||||
AddType application/font-woff woff
|
||||
AddType application/font-woff2 woff2
|
||||
AddType application/vnd.ms-fontobject eot
|
||||
AddType application/x-font-ttf ttc ttf
|
||||
AddType font/opentype otf
|
||||
|
||||
# Other
|
||||
AddType application/octet-stream safariextz
|
||||
AddType application/x-bb-appworld bbaw
|
||||
AddType application/x-chrome-extension crx
|
||||
AddType application/x-opera-extension oex
|
||||
AddType application/x-xpinstall xpi
|
||||
AddType text/vcard vcard vcf
|
||||
AddType text/vnd.rim.location.xloc xloc
|
||||
AddType text/vtt vtt
|
||||
AddType text/x-component htc
|
||||
|
||||
</IfModule>
|
||||
|
||||
# UTF-8 encoding
|
||||
AddDefaultCharset utf-8
|
||||
<IfModule mod_mime.c>
|
||||
AddCharset utf-8 .atom .css .js .json .manifest .rdf .rss .vtt .webapp .webmanifest .xml
|
||||
</IfModule>
|
||||
|
||||
### End: MIME types ###
|
||||
|
||||
|
||||
### Begin: Cross Origin ###
|
||||
|
||||
# Send the CORS header for images when browsers request it.
|
||||
<IfModule mod_setenvif.c>
|
||||
<IfModule mod_headers.c>
|
||||
<FilesMatch "\.(bmp|cur|gif|ico|jpe?g|png|svgz?|webp)$">
|
||||
SetEnvIf Origin ":" IS_CORS
|
||||
Header set Access-Control-Allow-Origin "*" env=IS_CORS
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
# Allow cross-origin access to web fonts.
|
||||
<IfModule mod_headers.c>
|
||||
<FilesMatch "\.(eot|otf|tt[cf]|woff2?)$">
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
### End: Cross Origin ###
|
||||
|
||||
|
||||
|
||||
### Begin: Rewriting and Access ###
|
||||
|
||||
# You need rewriting, if you use a URL-Rewriting extension (RealURL, CoolUri).
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
|
||||
# Enable URL rewriting
|
||||
RewriteEngine On
|
||||
|
||||
# Store the current location in an environment variable CWD to use
|
||||
# mod_rewrite in .htaccess files without knowing the RewriteBase
|
||||
RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
|
||||
RewriteRule ^.*$ - [E=CWD:%2]
|
||||
|
||||
# Rules to set ApplicationContext based on hostname
|
||||
#RewriteCond %{HTTP_HOST} ^dev\.example\.com$
|
||||
#RewriteRule .? - [E=TYPO3_CONTEXT:Development]
|
||||
#RewriteCond %{HTTP_HOST} ^staging\.example\.com$
|
||||
#RewriteRule .? - [E=TYPO3_CONTEXT:Production/Staging]
|
||||
#RewriteCond %{HTTP_HOST} ^www\.example\.com$
|
||||
#RewriteRule .? - [E=TYPO3_CONTEXT:Production]
|
||||
|
||||
# Rule for versioned static files, configured through:
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['BE']['versionNumberInFilename']
|
||||
# - $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename']
|
||||
# IMPORTANT: This rule has to be the very first RewriteCond in order to work!
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ %{ENV:CWD}$1.$3 [L]
|
||||
|
||||
# Access block for folders
|
||||
RewriteRule _(?:recycler|temp)_/ - [F]
|
||||
RewriteRule fileadmin/templates/.*\.(?:txt|ts)$ - [F]
|
||||
RewriteRule ^(?:vendor|typo3_src|typo3temp/var) - [F]
|
||||
RewriteRule (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/ - [F]
|
||||
|
||||
# Block access to all hidden files and directories with the exception of
|
||||
# the visible content from within the `/.well-known/` hidden directory (RFC 5785).
|
||||
RewriteCond %{REQUEST_URI} "!(^|/)\.well-known/([^./]+./?)+$" [NC]
|
||||
RewriteCond %{SCRIPT_FILENAME} -d [OR]
|
||||
RewriteCond %{SCRIPT_FILENAME} -f
|
||||
RewriteRule (?:^|/)\. - [F]
|
||||
|
||||
# Stop rewrite processing, if we are in the typo3/ directory or any other known directory
|
||||
# NOTE: Add your additional local storages here
|
||||
RewriteRule ^(?:typo3/|fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) - [L]
|
||||
|
||||
# If the file/symlink/directory does not exist => Redirect to index.php.
|
||||
# For httpd.conf, you need to prefix each '%{REQUEST_FILENAME}' with '%{DOCUMENT_ROOT}'.
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-l
|
||||
RewriteRule ^.*$ %{ENV:CWD}index.php [QSA,L]
|
||||
|
||||
</IfModule>
|
||||
|
||||
# Access block for files
|
||||
# Apache < 2.3
|
||||
<IfModule !mod_authz_core.c>
|
||||
<FilesMatch "(?i:^\.|^#.*#|^(?:ChangeLog|ToDo|Readme|License)(?:\.md|\.txt)?|^composer\.(?:json|lock)|^ext_conf_template\.txt|^ext_typoscript_constants\.txt|^ext_typoscript_setup\.txt|flexform[^.]*\.xml|locallang[^.]*\.(?:xml|xlf)|\.(?:bak|co?nf|cfg|ya?ml|ts|typoscript|tsconfig|dist|fla|in[ci]|log|sh|sql(?:\..*)?|sqlite(?:\..*)?|sw[op]|git.*|rc)|.*~)$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy All
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
# Apache ≥ 2.3
|
||||
<IfModule mod_authz_core.c>
|
||||
<If "%{REQUEST_URI} =~ m#(?i:/\.|/\x23.*\x23|/(?:ChangeLog|ToDo|Readme|License)(?:\.md|\.txt)?|/composer\.(?:json|lock)|/ext_conf_template\.txt|/ext_typoscript_constants\.txt|/ext_typoscript_setup\.txt|flexform[^.]*\.xml|locallang[^.]*\.(?:xml|xlf)|\.(?:bak|co?nf|cfg|ya?ml|ts|typoscript|tsconfig|dist|fla|in[ci]|log|sh|sql(?:\..*)?|sqlite(?:\..*)?|sw[op]|git.*|rc)|.*~)$#">
|
||||
Require all denied
|
||||
</If>
|
||||
</IfModule>
|
||||
|
||||
# Block access to vcs directories
|
||||
<IfModule mod_alias.c>
|
||||
RedirectMatch 404 /\.(?:git|svn|hg)/
|
||||
</IfModule>
|
||||
|
||||
### End: Rewriting and Access ###
|
||||
|
||||
|
||||
|
||||
### Begin: Miscellaneous ###
|
||||
|
||||
# 404 error prevention for non-existing redirected folders
|
||||
Options -MultiViews
|
||||
|
||||
# Make sure that directory listings are disabled.
|
||||
<IfModule mod_autoindex.c>
|
||||
Options -Indexes
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
# Force IE to render pages in the highest available mode
|
||||
Header set X-UA-Compatible "IE=edge"
|
||||
<FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svgz?|ttf|vcf|webapp|webm|webp|woff2?|xml|xpi)$">
|
||||
Header unset X-UA-Compatible
|
||||
</FilesMatch>
|
||||
|
||||
# Reducing MIME type security risks
|
||||
Header set X-Content-Type-Options "nosniff"
|
||||
</IfModule>
|
||||
|
||||
# ETag removal
|
||||
<IfModule mod_headers.c>
|
||||
Header unset ETag
|
||||
</IfModule>
|
||||
FileETag None
|
||||
|
||||
### End: Miscellaneous ###
|
||||
|
||||
|
||||
# Add your own rules here.
|
||||
|
||||
# Erzwinge PHP 7.4 aus dem Docker-Container für alle PHP-Dateien
|
||||
<FilesMatch \.php$>
|
||||
SetHandler "proxy:fcgi://127.0.0.1:9074"
|
||||
</FilesMatch>
|
||||
@@ -0,0 +1,33 @@
|
||||
# This file applies Content-Security-Policy (CSP) HTTP headers
|
||||
# to directories containing (user uploaded) resources like
|
||||
# /fileadmin/ or /uploads/
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
# matching requested *.pdf files only (strict rules block Safari showing PDF documents)
|
||||
<FilesMatch "\.pdf$">
|
||||
Header set Content-Security-Policy "default-src 'self' 'unsafe-inline'; script-src 'none'; object-src 'self'; plugin-types application/pdf;"
|
||||
</FilesMatch>
|
||||
# matching anything else, using negative lookbehind pattern
|
||||
<FilesMatch "(?<!\.pdf)$">
|
||||
Header set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'none'; object-src 'none';"
|
||||
</FilesMatch>
|
||||
|
||||
# =================================================================
|
||||
# Variations to send CSP header only when it has not be set before.
|
||||
# Adjust all `Header set` instructions above
|
||||
# Header set Content-Security-Policy "<directives>"
|
||||
# with substitutes shown below
|
||||
#
|
||||
# -----------------------------------------------------------------
|
||||
# a) for Apache 2.4 (having `setifempty`)
|
||||
# -----------------------------------------------------------------
|
||||
# Header setifempty Content-Security-Policy "<directives>"
|
||||
#
|
||||
# -----------------------------------------------------------------
|
||||
# b) for Apache 2.2 (using fallbacks)
|
||||
# -----------------------------------------------------------------
|
||||
# Header append Content-Security-Policy ""
|
||||
# Header edit Content-Security-Policy "^$" "<directives>"
|
||||
#
|
||||
# =================================================================
|
||||
</IfModule>
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 384 B |
|
After Width: | Height: | Size: 384 B |
@@ -0,0 +1,15 @@
|
||||
# This file restricts access to the fileadmin/_temp_ directory. It is
|
||||
# meant to protect temporary files which could contain sensible
|
||||
# information. Please do not touch.
|
||||
|
||||
# Apache < 2.3
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy All
|
||||
</IfModule>
|
||||
|
||||
# Apache ≥ 2.3
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
@@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv=Refresh Content="0; Url=/"/>
|
||||
</head>
|
||||
</html>
|
||||
@@ -0,0 +1,102 @@
|
||||
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
|
||||
<div class="pure-form">
|
||||
<f:flashMessages />
|
||||
<f:if condition="{cookieWarning}">
|
||||
<f:render partial="CookieWarning" />
|
||||
</f:if>
|
||||
|
||||
<f:if condition="{messageKey}">
|
||||
<h3>
|
||||
<f:render partial="RenderLabelOrMessage" arguments="{key: '{messageKey}_header'}" />
|
||||
</h3>
|
||||
<p>
|
||||
<f:render partial="RenderLabelOrMessage" arguments="{key: '{messageKey}_message'}" />
|
||||
</p>
|
||||
</f:if>
|
||||
<f:if condition="{onSubmit}">
|
||||
<f:then>
|
||||
<f:form target="_top" fieldNamePrefix="" action="login" onsubmit="{onSubmit}">
|
||||
<f:render section="content" arguments="{_all}" />
|
||||
</f:form>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:form target="_top" fieldNamePrefix="" action="login">
|
||||
<f:render section="content" arguments="{_all}" />
|
||||
</f:form>
|
||||
</f:else>
|
||||
</f:if>
|
||||
|
||||
<f:if condition="{settings.showForgotPassword}">
|
||||
<f:link.action action="recovery" controller="PasswordRecovery">
|
||||
<f:render partial="RenderLabelOrMessage" arguments="{key: 'forgot_header'}" />
|
||||
</f:link.action>
|
||||
</f:if>
|
||||
|
||||
<f:section name="content">
|
||||
|
||||
<fieldset>
|
||||
<legend>
|
||||
<f:translate key="login" />
|
||||
</legend>
|
||||
<table class="pure-table pure-table-striped" style="width: 60%"><tr>
|
||||
<label>
|
||||
|
||||
<td><f:translate key="username" /></td>
|
||||
<td><f:form.textfield name="user" /></td>
|
||||
|
||||
</label>
|
||||
</tr>
|
||||
<tr>
|
||||
<label>
|
||||
<td><f:translate key="password" /></td>
|
||||
<td><f:form.password name="pass" data="{rsa-encryption: ''}" /></td>
|
||||
</label>
|
||||
</tr>
|
||||
|
||||
|
||||
<f:if condition="{permaloginStatus} > -1">
|
||||
<div>
|
||||
<label>
|
||||
<f:translate id="permalogin" />
|
||||
<f:if condition="{permaloginStatus} == 1">
|
||||
<f:then>
|
||||
<f:form.hidden name="permalogin" value="0" additionalAttributes="{disabled: 'disabled'}" />
|
||||
<f:form.checkbox name="permalogin" id="permalogin" value="1" checked="checked" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:form.hidden name="permalogin" value="0" />
|
||||
<f:form.checkbox name="permalogin" id="permalogin" value="1" />
|
||||
</f:else>
|
||||
</f:if>
|
||||
</label>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
<tr>
|
||||
<td></td><td><f:form.submit value="{f:translate(key: 'login')}" name="submit" class="pure-button" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="felogin-hidden">
|
||||
<f:form.hidden name="logintype" value="login" />
|
||||
<f:form.hidden name="pid" value="{storagePid}" />
|
||||
<f:if condition="{redirectURL}!=''">
|
||||
<f:form.hidden name="redirect_url" value="{redirectURL}" />
|
||||
</f:if>
|
||||
<f:if condition="{referer}!=''">
|
||||
<f:form.hidden name="referer" value="{referer}" />
|
||||
</f:if>
|
||||
<f:if condition="{redirectReferrer}!=''">
|
||||
<f:form.hidden name="redirectReferrer" value="off" />
|
||||
</f:if>
|
||||
<f:if condition="{noRedirect}!=''">
|
||||
<f:form.hidden name="noredirect" value="1" />
|
||||
</f:if>
|
||||
|
||||
{extraHidden}
|
||||
</div>
|
||||
</fieldset>
|
||||
</f:section>
|
||||
</div>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,39 @@
|
||||
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
|
||||
<div class="pure-form">
|
||||
<h3>
|
||||
<f:translate key="forgot_header" />
|
||||
</h3>
|
||||
<p>
|
||||
<f:translate key="forgot_reset_message" />
|
||||
</p>
|
||||
|
||||
<f:render partial="ValidationErrors" />
|
||||
|
||||
<f:form action="recovery" method="post">
|
||||
<fieldset>
|
||||
<table class="pure-table pure-table-striped"><tr>
|
||||
<legend>
|
||||
<f:render partial="RenderLabelOrMessage" arguments="{key: 'reset_password'}" />
|
||||
</legend>
|
||||
<tr>
|
||||
<label>
|
||||
<td><f:translate key="enter_your_data" /></td>
|
||||
<td><f:form.textfield name="userIdentifier" /></td>
|
||||
</label>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><f:form.submit value="{f:translate(key: 'reset_password')}" class="pure-button" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
</f:form>
|
||||
|
||||
<p>
|
||||
<f:link.action action="login" controller="Login">
|
||||
<f:translate key="forgot_header_backToLogin" />
|
||||
</f:link.action>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,513 @@
|
||||
/*csslint important:false*/
|
||||
|
||||
/* ==========================================================================
|
||||
Pure Base Extras
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Extra rules that Pure adds on top of Normalize.css
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always hide an element when it has the `hidden` HTML attribute.
|
||||
*/
|
||||
|
||||
.hidden,
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add this class to an image to make it fit within it's fluid parent wrapper while maintaining
|
||||
* aspect ratio.
|
||||
*/
|
||||
.pure-img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pure-button {
|
||||
/* Structure */
|
||||
display: inline-block;
|
||||
line-height: normal;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Firefox: Get rid of the inner focus border */
|
||||
.pure-button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Inherit .pure-g styles */
|
||||
.pure-button-group {
|
||||
letter-spacing: -0.31em; /* Webkit: collapse white-space between units */
|
||||
text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */
|
||||
}
|
||||
|
||||
.opera-only :-o-prefocus,
|
||||
.pure-button-group {
|
||||
word-spacing: -0.43em;
|
||||
}
|
||||
|
||||
.pure-button-group .pure-button {
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
vertical-align: top;
|
||||
text-rendering: auto;
|
||||
}
|
||||
/*csslint box-model:false*/
|
||||
/*
|
||||
Box-model set to false because we're setting a height on select elements, which
|
||||
also have border and padding. This is done because some browsers don't render
|
||||
the padding. We explicitly set the box-model for select elements to border-box,
|
||||
so we can ignore the csslint warning.
|
||||
*/
|
||||
|
||||
.pure-form input[type="text"],
|
||||
.pure-form input[type="password"],
|
||||
.pure-form input[type="email"],
|
||||
.pure-form input[type="url"],
|
||||
.pure-form input[type="date"],
|
||||
.pure-form input[type="month"],
|
||||
.pure-form input[type="time"],
|
||||
.pure-form input[type="datetime"],
|
||||
.pure-form input[type="datetime-local"],
|
||||
.pure-form input[type="week"],
|
||||
.pure-form input[type="number"],
|
||||
.pure-form input[type="search"],
|
||||
.pure-form input[type="tel"],
|
||||
.pure-form input[type="color"],
|
||||
.pure-form select,
|
||||
.pure-form textarea {
|
||||
padding: 0.5em 0.6em;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: inset 0 1px 3px #ddd;
|
||||
border-radius: 4px;
|
||||
vertical-align: middle;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/*
|
||||
Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
|
||||
since IE8 won't execute CSS that contains a CSS3 selector.
|
||||
*/
|
||||
.pure-form input:not([type]) {
|
||||
padding: 0.5em 0.6em;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: inset 0 1px 3px #ddd;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
/* Chrome (as of v.32/34 on OS X) needs additional room for color to display. */
|
||||
/* May be able to remove this tweak as color inputs become more standardized across browsers. */
|
||||
.pure-form input[type="color"] {
|
||||
padding: 0.2em 0.5em;
|
||||
}
|
||||
|
||||
|
||||
.pure-form input[type="text"]:focus,
|
||||
.pure-form input[type="password"]:focus,
|
||||
.pure-form input[type="email"]:focus,
|
||||
.pure-form input[type="url"]:focus,
|
||||
.pure-form input[type="date"]:focus,
|
||||
.pure-form input[type="month"]:focus,
|
||||
.pure-form input[type="time"]:focus,
|
||||
.pure-form input[type="datetime"]:focus,
|
||||
.pure-form input[type="datetime-local"]:focus,
|
||||
.pure-form input[type="week"]:focus,
|
||||
.pure-form input[type="number"]:focus,
|
||||
.pure-form input[type="search"]:focus,
|
||||
.pure-form input[type="tel"]:focus,
|
||||
.pure-form input[type="color"]:focus,
|
||||
.pure-form select:focus,
|
||||
.pure-form textarea:focus {
|
||||
outline: 0;
|
||||
border-color: #129FEA;
|
||||
}
|
||||
|
||||
/*
|
||||
Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
|
||||
since IE8 won't execute CSS that contains a CSS3 selector.
|
||||
*/
|
||||
.pure-form input:not([type]):focus {
|
||||
outline: 0;
|
||||
border-color: #129FEA;
|
||||
}
|
||||
|
||||
.pure-form input[type="file"]:focus,
|
||||
.pure-form input[type="radio"]:focus,
|
||||
.pure-form input[type="checkbox"]:focus {
|
||||
outline: thin solid #129FEA;
|
||||
outline: 1px auto #129FEA;
|
||||
}
|
||||
.pure-form .pure-checkbox,
|
||||
.pure-form .pure-radio {
|
||||
margin: 0.5em 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pure-form input[type="text"][disabled],
|
||||
.pure-form input[type="password"][disabled],
|
||||
.pure-form input[type="email"][disabled],
|
||||
.pure-form input[type="url"][disabled],
|
||||
.pure-form input[type="date"][disabled],
|
||||
.pure-form input[type="month"][disabled],
|
||||
.pure-form input[type="time"][disabled],
|
||||
.pure-form input[type="datetime"][disabled],
|
||||
.pure-form input[type="datetime-local"][disabled],
|
||||
.pure-form input[type="week"][disabled],
|
||||
.pure-form input[type="number"][disabled],
|
||||
.pure-form input[type="search"][disabled],
|
||||
.pure-form input[type="tel"][disabled],
|
||||
.pure-form input[type="color"][disabled],
|
||||
.pure-form select[disabled],
|
||||
.pure-form textarea[disabled] {
|
||||
cursor: not-allowed;
|
||||
background-color: #eaeded;
|
||||
color: #cad2d3;
|
||||
}
|
||||
|
||||
/*
|
||||
Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
|
||||
since IE8 won't execute CSS that contains a CSS3 selector.
|
||||
*/
|
||||
.pure-form input:not([type])[disabled] {
|
||||
cursor: not-allowed;
|
||||
background-color: #eaeded;
|
||||
color: #cad2d3;
|
||||
}
|
||||
.pure-form input[readonly],
|
||||
.pure-form select[readonly],
|
||||
.pure-form textarea[readonly] {
|
||||
background-color: #eee; /* menu hover bg color */
|
||||
color: #777; /* menu text color */
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.pure-form input:focus:invalid,
|
||||
.pure-form textarea:focus:invalid,
|
||||
.pure-form select:focus:invalid {
|
||||
color: #b94a48;
|
||||
border-color: #e9322d;
|
||||
}
|
||||
.pure-form input[type="file"]:focus:invalid:focus,
|
||||
.pure-form input[type="radio"]:focus:invalid:focus,
|
||||
.pure-form input[type="checkbox"]:focus:invalid:focus {
|
||||
outline-color: #e9322d;
|
||||
}
|
||||
.pure-form select {
|
||||
/* Normalizes the height; padding is not sufficient. */
|
||||
height: 2.25em;
|
||||
border: 1px solid #ccc;
|
||||
background-color: white;
|
||||
}
|
||||
.pure-form select[multiple] {
|
||||
height: auto;
|
||||
}
|
||||
.pure-form label {
|
||||
margin: 0.5em 0 0.2em;
|
||||
}
|
||||
.pure-form fieldset {
|
||||
margin: 0;
|
||||
padding: 0.35em 0 0.75em;
|
||||
border: 0;
|
||||
}
|
||||
.pure-form legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.3em 0;
|
||||
margin-bottom: 0.3em;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.pure-form-stacked input[type="text"],
|
||||
.pure-form-stacked input[type="password"],
|
||||
.pure-form-stacked input[type="email"],
|
||||
.pure-form-stacked input[type="url"],
|
||||
.pure-form-stacked input[type="date"],
|
||||
.pure-form-stacked input[type="month"],
|
||||
.pure-form-stacked input[type="time"],
|
||||
.pure-form-stacked input[type="datetime"],
|
||||
.pure-form-stacked input[type="datetime-local"],
|
||||
.pure-form-stacked input[type="week"],
|
||||
.pure-form-stacked input[type="number"],
|
||||
.pure-form-stacked input[type="search"],
|
||||
.pure-form-stacked input[type="tel"],
|
||||
.pure-form-stacked input[type="color"],
|
||||
.pure-form-stacked input[type="file"],
|
||||
.pure-form-stacked select,
|
||||
.pure-form-stacked label,
|
||||
.pure-form-stacked textarea {
|
||||
display: block;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
|
||||
since IE8 won't execute CSS that contains a CSS3 selector.
|
||||
*/
|
||||
.pure-form-stacked input:not([type]) {
|
||||
display: block;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
.pure-form-aligned input,
|
||||
.pure-form-aligned textarea,
|
||||
.pure-form-aligned select,
|
||||
.pure-form-message-inline {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.pure-form-aligned textarea {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* Aligned Forms */
|
||||
.pure-form-aligned .pure-control-group {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.pure-form-aligned .pure-control-group label {
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 10em;
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
.pure-form-aligned .pure-controls {
|
||||
margin: 1.5em 0 0 11em;
|
||||
}
|
||||
|
||||
/* Rounded Inputs */
|
||||
.pure-form input.pure-input-rounded,
|
||||
.pure-form .pure-input-rounded {
|
||||
border-radius: 2em;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
/* Grouped Inputs */
|
||||
.pure-form .pure-group fieldset {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.pure-form .pure-group input,
|
||||
.pure-form .pure-group textarea {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
margin: 0 0 -1px;
|
||||
border-radius: 0;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
.pure-form .pure-group input:focus,
|
||||
.pure-form .pure-group textarea:focus {
|
||||
z-index: 3;
|
||||
}
|
||||
.pure-form .pure-group input:first-child,
|
||||
.pure-form .pure-group textarea:first-child {
|
||||
top: 1px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
margin: 0;
|
||||
}
|
||||
.pure-form .pure-group input:first-child:last-child,
|
||||
.pure-form .pure-group textarea:first-child:last-child {
|
||||
top: 1px;
|
||||
border-radius: 4px;
|
||||
margin: 0;
|
||||
}
|
||||
.pure-form .pure-group input:last-child,
|
||||
.pure-form .pure-group textarea:last-child {
|
||||
top: -2px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
margin: 0;
|
||||
}
|
||||
.pure-form .pure-group button {
|
||||
margin: 0.35em 0;
|
||||
}
|
||||
|
||||
.pure-form .pure-input-1 {
|
||||
width: 100%;
|
||||
}
|
||||
.pure-form .pure-input-3-4 {
|
||||
width: 75%;
|
||||
}
|
||||
.pure-form .pure-input-2-3 {
|
||||
width: 66%;
|
||||
}
|
||||
.pure-form .pure-input-1-2 {
|
||||
width: 50%;
|
||||
}
|
||||
.pure-form .pure-input-1-3 {
|
||||
width: 33%;
|
||||
}
|
||||
.pure-form .pure-input-1-4 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
/* Inline help for forms */
|
||||
.pure-form-message-inline {
|
||||
display: inline-block;
|
||||
padding-left: 0.3em;
|
||||
color: #666;
|
||||
vertical-align: middle;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* Block help for forms */
|
||||
.pure-form-message {
|
||||
display: block;
|
||||
color: #666;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
.pure-table {
|
||||
/* Remove spacing between table cells (from Normalize.css) */
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
empty-cells: show;
|
||||
border: 1px solid #cbcbcb;
|
||||
}
|
||||
|
||||
.pure-table caption {
|
||||
color: #000;
|
||||
font: italic 85%/1 arial, sans-serif;
|
||||
padding: 1em 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pure-table td,
|
||||
.pure-table th {
|
||||
border-left: 1px solid #cbcbcb;/* inner column border */
|
||||
border-width: 0 0 0 1px;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
overflow: visible; /*to make ths where the title is really long work*/
|
||||
padding: 0.5em 1em; /* cell padding */
|
||||
}
|
||||
|
||||
.pure-table thead {
|
||||
background-color: #e0e0e0;
|
||||
color: #000;
|
||||
text-align: left;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
striping:
|
||||
even - #fff (white)
|
||||
odd - #f2f2f2 (light gray)
|
||||
*/
|
||||
.pure-table td {
|
||||
background-color: transparent;
|
||||
}
|
||||
.pure-table-odd td {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
/* nth-child selector for modern browsers */
|
||||
.pure-table-striped tr:nth-child(2n-1) td {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
/* BORDERED TABLES */
|
||||
.pure-table-bordered td {
|
||||
border-bottom: 1px solid #cbcbcb;
|
||||
}
|
||||
.pure-table-bordered tbody > tr:last-child > td {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
|
||||
/* HORIZONTAL BORDERED TABLES */
|
||||
|
||||
.pure-table-horizontal td,
|
||||
.pure-table-horizontal th {
|
||||
border-width: 0 0 1px 0;
|
||||
border-bottom: 1px solid #cbcbcb;
|
||||
}
|
||||
.pure-table-horizontal tbody > tr:last-child > td {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
/*csslint outline-none:false*/
|
||||
|
||||
.pure-button {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
padding: 0.5em 1em;
|
||||
color: rgba(0, 0, 0, 0.80);
|
||||
border: none rgba(0, 0, 0, 0);
|
||||
background-color: #E6E6E6;
|
||||
text-decoration: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.pure-button-hover,
|
||||
.pure-button:hover,
|
||||
.pure-button:focus {
|
||||
background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
|
||||
}
|
||||
.pure-button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.pure-button-active,
|
||||
.pure-button:active {
|
||||
box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.pure-button[disabled],
|
||||
.pure-button-disabled,
|
||||
.pure-button-disabled:hover,
|
||||
.pure-button-disabled:focus,
|
||||
.pure-button-disabled:active {
|
||||
border: none;
|
||||
background-image: none;
|
||||
opacity: 0.40;
|
||||
cursor: not-allowed;
|
||||
box-shadow: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.pure-button-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pure-button-primary,
|
||||
.pure-button-selected,
|
||||
a.pure-button-primary,
|
||||
a.pure-button-selected {
|
||||
background-color: rgb(0, 120, 231);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Button Groups */
|
||||
.pure-button-group .pure-button {
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.2);
|
||||
|
||||
}
|
||||
|
||||
.pure-button-group .pure-button:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
}
|
||||
.pure-button-group .pure-button:last-child {
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
border-right: none;
|
||||
}
|
||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,20 @@
|
||||
#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translateY(-4px);transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#29d transparent transparent #29d;border-style:solid;border-width:2px;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}
|
||||
|
||||
|
||||
/*!
|
||||
Pure v2.0.3
|
||||
Copyright 2013 Yahoo!
|
||||
Licensed under the BSD License.
|
||||
https://github.com/pure-css/pure/blob/master/LICENSE
|
||||
*/
|
||||
/*!
|
||||
normalize.css v | MIT License | git.io/normalize
|
||||
Copyright (c) Nicolas Gallagher and Jonathan Neal
|
||||
*/
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}html{font-family:sans-serif}.hidden,[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,Droid Sans,Helvetica,Arial,sans-serif;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-line-pack:start;align-content:flex-start}@media (-ms-high-contrast:active),(-ms-high-contrast:none){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-1-12,.pure-u-1-24,.pure-u-2-3,.pure-u-2-5,.pure-u-2-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-3-24,.pure-u-4-5,.pure-u-4-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-5-12,.pure-u-5-24,.pure-u-6-24,.pure-u-7-8,.pure-u-7-12,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-5-12,.pure-u-10-24{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-7-12,.pure-u-14-24{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-5-8,.pure-u-15-24{width:62.5%}.pure-u-2-3,.pure-u-16-24{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-3-4,.pure-u-18-24{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-5-6,.pure-u-20-24{width:83.3333%}.pure-u-7-8,.pure-u-21-24{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:border-box;box-sizing:border-box}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-group{letter-spacing:-.31em;text-rendering:optimizespeed}.opera-only :-o-prefocus,.pure-button-group{word-spacing:-.43em}.pure-button-group .pure-button{letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-button{font-size:100%;padding:.5em 1em;color:rgba(0,0,0,.8);border:transparent;background-color:#e6e6e6;text-decoration:none;border-radius:2px}.pure-butLine truncated
|
||||
/*!
|
||||
Pure v2.0.3
|
||||
Copyright 2013 Yahoo!
|
||||
Licensed under the BSD License.
|
||||
https://github.com/pure-css/pure/blob/master/LICENSE
|
||||
*/@media screen and (min-width:35.5em){.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-1-2,.pure-u-sm-1-3,.pure-u-sm-1-4,.pure-u-sm-1-5,.pure-u-sm-1-6,.pure-u-sm-1-8,.pure-u-sm-1-12,.pure-u-sm-1-24,.pure-u-sm-2-3,.pure-u-sm-2-5,.pure-u-sm-2-24,.pure-u-sm-3-4,.pure-u-sm-3-5,.pure-u-sm-3-8,.pure-u-sm-3-24,.pure-u-sm-4-5,.pure-u-sm-4-24,.pure-u-sm-5-5,.pure-u-sm-5-6,.pure-u-sm-5-8,.pure-u-sm-5-12,.pure-u-sm-5-24,.pure-u-sm-6-24,.pure-u-sm-7-8,.pure-u-sm-7-12,.pure-u-sm-7-24,.pure-u-sm-8-24,.pure-u-sm-9-24,.pure-u-sm-10-24,.pure-u-sm-11-12,.pure-u-sm-11-24,.pure-u-sm-12-24,.pure-u-sm-13-24,.pure-u-sm-14-24,.pure-u-sm-15-24,.pure-u-sm-16-24,.pure-u-sm-17-24,.pure-u-sm-18-24,.pure-u-sm-19-24,.pure-u-sm-20-24,.pure-u-sm-21-24,.pure-u-sm-22-24,.pure-u-sm-23-24,.pure-u-sm-24-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-sm-1-24{width:4.1667%}.pure-u-sm-1-12,.pure-u-sm-2-24{width:8.3333%}.pure-u-sm-1-8,.pure-u-sm-3-24{width:12.5%}.pure-u-sm-1-6,.pure-u-sm-4-24{width:16.6667%}.pure-u-sm-1-5{width:20%}.pure-u-sm-5-24{width:20.8333%}.pure-u-sm-1-4,.pure-u-sm-6-24{width:25%}.pure-u-sm-7-24{width:29.1667%}.pure-u-sm-1-3,.pure-u-sm-8-24{width:33.3333%}.pure-u-sm-3-8,.pure-u-sm-9-24{width:37.5%}.pure-u-sm-2-5{width:40%}.pure-u-sm-5-12,.pure-u-sm-10-24{width:41.6667%}.pure-u-sm-11-24{width:45.8333%}.pure-u-sm-1-2,.pure-u-sm-12-24{width:50%}.pure-u-sm-13-24{width:54.1667%}.pure-u-sm-7-12,.pure-u-sm-14-24{width:58.3333%}.pure-u-sm-3-5{width:60%}.pure-u-sm-5-8,.pure-u-sm-15-24{width:62.5%}.pure-u-sm-2-3,.pure-u-sm-16-24{width:66.6667%}.pure-u-sm-17-24{width:70.8333%}.pure-u-sm-3-4,.pure-u-sm-18-24{width:75%}.pure-u-sm-19-24{width:79.1667%}.pure-u-sm-4-5{width:80%}.pure-u-sm-5-6,.pure-u-sm-20-24{width:83.3333%}.pure-u-sm-7-8,.pure-u-sm-21-24{width:87.5%}.pure-u-sm-11-12,.pure-u-sm-22-24{width:91.6667%}.pure-u-sm-23-24{width:95.8333%}.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-5-5,.pure-u-sm-24-24{width:100%}}@media screen and (min-width:48em){.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-1-2,.pure-u-md-1-3,.pure-u-md-1-4,.pure-u-md-1-5,.pure-u-md-1-6,.pure-u-md-1-8,.pure-u-md-1-12,.pure-u-md-1-24,.pure-u-md-2-3,.pure-u-md-2-5,.pure-u-md-2-24,.pure-u-md-3-4,.pure-u-md-3-5,.pure-u-md-3-8,.pure-u-md-3-24,.pure-u-md-4-5,.pure-u-md-4-24,.pure-u-md-5-5,.pure-u-md-5-6,.pure-u-md-5-8,.pure-u-md-5-12,.pure-u-md-5-24,.pure-u-md-6-24,.pure-u-md-7-8,.pure-u-md-7-12,.pure-u-md-7-24,.pure-u-md-8-24,.pure-u-md-9-24,.pure-u-md-10-24,.pure-u-md-11-12,.pure-u-md-11-24,.pure-u-md-12-24,.pure-u-md-13-24,.pure-u-md-14-24,.pure-u-md-15-24,.pure-u-md-16-24,.pure-u-md-17-24,.pure-u-md-18-24,.pure-u-md-19-24,.pure-u-md-20-24,.pure-u-md-21-24,.pure-u-md-22-24,.pure-u-md-23-24,.pure-u-md-24-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-md-1-24{width:4.1667%}.pure-u-md-1-12,.pure-u-md-2-24{width:8.3333%}.pure-u-md-1-8,.pure-u-md-3-24{width:12.5%}.pure-u-md-1-6,.pure-u-md-4-24{width:16.6667%}.pure-u-md-1-5{width:20%}.pure-u-md-5-24{width:20.8333%}.pure-u-md-1-4,.pure-u-md-6-24{width:25%}.pure-u-md-7-24{width:29.1667%}.pure-u-md-1-3,.pure-u-md-8-24{width:33.3333%}.pure-u-md-3-8,.pure-u-md-9-24{width:37.5%}.pure-u-md-2-5{width:40%}.pure-u-md-5-12,.pure-u-md-10-24{width:41.6667%}.pure-u-md-11-24{width:45.8333%}.pure-u-md-1-2,.pure-u-md-12-24{width:50%}.pure-u-md-13-24{width:54.1667%}.pure-u-md-7-12,.pure-u-md-14-24{width:58.3333%}.pure-u-md-3-5{width:60%}.pure-u-md-5-8,.pure-u-md-15-24{width:62.5%}.pure-u-md-2-3,.pure-u-md-16-24{width:66.6667%}.pure-u-md-17-24{width:70.8333%}.pure-u-md-3-4,.pure-u-md-18-24{width:75%}.pure-u-md-19-24{width:79.1667%}.pure-u-md-4-5{width:80%}.pure-u-md-5-6,.pure-u-md-20-24{width:83.3333%}.pure-u-md-7-8,.pure-u-md-21-24{width:87.5%}.pure-u-md-11-12,.pure-u-md-22-24{width:91.6667%}.pure-u-md-23-24{width:95.8333%}.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-5-5,.pure-u-md-24-24{width:100%}}@media screen and (min-width:64em){.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-1-2,.pure-u-lg-1-3,.pure-u-lg-1-4,.pure-u-lg-1-5,.pure-u-lg-1-6,.pure-u-lg-1-8,.pure-u-lg-1-12,.pure-u-lg-1-24,.pure-u-lg-2-3,.pure-u-lg-2-5,.pure-u-lg-2-24,.pure-u-lg-3-4,.pure-u-lg-3-5,.pure-u-lg-3-8,.pure-u-lg-3-24,.pure-u-lg-4-5,.pure-u-lg-4-24,.pure-u-lg-5-5,.pure-u-lg-5-6,.pure-u-lg-5-8,.pure-u-lg-5-12,.pure-u-lg-5-24,.pure-u-lg-6-24,.pure-u-lg-7-8,.pure-u-lg-7-12,.pure-u-lg-7-24,.pure-u-lg-8-24,.pure-u-lg-9-24,.pure-u-lg-10-24,.pure-u-lg-11-12,.pure-u-lg-11-24,.pure-u-lg-12-24,.pure-u-lg-13-24,.pure-u-lg-14-24,.pure-u-lg-15-24,.pure-u-lg-16-24,.pure-u-lg-17-24,.pure-u-lg-18-24,.pure-u-lg-19-24,.pure-u-lg-20-24,.pure-u-lg-21-24,.pure-u-lg-22-24,.pure-u-lg-23-24,.pure-u-lg-24-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-lg-1-24{width:4.1667%}.pure-u-lg-1-12,.pure-u-lg-2-24{width:8.3333%}.pure-u-lg-1-8,.pure-u-lg-3-24{width:12.5%}.pure-u-lg-1-6,.pure-u-lg-4-24{width:16.6667%}.pure-u-lg-1-5{width:20Line truncated
|
||||
|
After Width: | Height: | Size: 27 KiB |
@@ -0,0 +1,15 @@
|
||||
# This file restricts access to the fileadmin/user_upload/_import_export_ directory. It is
|
||||
# meant to protect temporary files which could contain sensible
|
||||
# information. Please do not touch.
|
||||
|
||||
# Apache < 2.3
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy All
|
||||
</IfModule>
|
||||
|
||||
# Apache ≥ 2.3
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
@@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv=Refresh Content="0; Url=/"/>
|
||||
</head>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
halo
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
// Exit early if php requirement is not satisfied.
|
||||
if (PHP_VERSION_ID < 70200) {
|
||||
die('This version of TYPO3 CMS requires PHP 7.2 or above');
|
||||
}
|
||||
|
||||
// Set up the application for the frontend
|
||||
call_user_func(function () {
|
||||
$classLoader = require dirname(__DIR__).'/vendor/autoload.php';
|
||||
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(0, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_FE);
|
||||
\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader)->get(\TYPO3\CMS\Frontend\Http\Application::class)->run();
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
// Exit early if php requirement is not satisfied.
|
||||
if (PHP_VERSION_ID < 70200) {
|
||||
die('This version of TYPO3 CMS requires PHP 7.2 or above');
|
||||
}
|
||||
|
||||
// Set up the application for the backend
|
||||
call_user_func(function () {
|
||||
$classLoader = require dirname(dirname(__DIR__)).'/vendor/autoload.php';
|
||||
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(1, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE);
|
||||
\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader)->get(\TYPO3\CMS\Backend\Http\Application::class)->run();
|
||||
});
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Entry point to the install tool and step installer.
|
||||
*
|
||||
* There are two main controllers: "step" and "tool".
|
||||
* The step controller is always called first, and redirects to the tool controller
|
||||
* if the basic core functionality is given (instance configuration exists, database
|
||||
* connection works, ...)
|
||||
* The tool controller is the main "install tool" with all the main functionality.
|
||||
*
|
||||
* The step controller handles the basic installation.
|
||||
* During first installation it creates the basic file and folder structure, the
|
||||
* configuration files, the database connection and a basic configuration. Those steps
|
||||
* are cycled through and if some step returns TRUE on "needsExecution", an input
|
||||
* form of this step is rendered.
|
||||
* After initial installation, the step installer is still called if the install
|
||||
* tool is accessed, so it will automatically come up if some basic configuration fails.
|
||||
* If everything is ok, the step installer will redirect to the main install tool.
|
||||
* The step installer also has some "silent" update scripts, for example it migrates
|
||||
* a localconf.php to LocalConfiguration if needed.
|
||||
*
|
||||
* This ensures as soon as the tool controller is called, the basic configuration is ok.
|
||||
*
|
||||
* Whenever the bootstrap or other core elements figure the installation
|
||||
* needs an update that is handled within the step controller, it should just
|
||||
* redirect to the entry script and let the step controller do necessary work.
|
||||
*
|
||||
* The step installer initiates browser redirects if steps were executed. This simplifies
|
||||
* internal logic by separating the different bootstrap states needed during installation
|
||||
* from each other.
|
||||
*
|
||||
* There is also a backend module controller, that basically only shows a screen
|
||||
* with the "enable install tool" button and then redirects to the entry script. Other
|
||||
* than that, it does not interfere with step or tool controller and just sets a
|
||||
* context GET parameter to indicate that the install tool is called within backend context.
|
||||
*
|
||||
* To coordinate different tasks within step and install controller and actions, several
|
||||
* GET or POST parameters are used, all prefixed with "install".
|
||||
* Parameters allowed as GET and POST are preserved during redirects, POST parameters are
|
||||
* thrown away between redirects (HTTP status code 303).
|
||||
*
|
||||
* The following main GET and POST parameters are used:
|
||||
* - GET/POST "install[context]" Preserved
|
||||
* Either empty, 'standalone' or 'backend', fallback to 'standalone'. Set to 'backend'
|
||||
* if install tool is called form the backend main module (BackendModuleController). This
|
||||
* changes the view a bit and shows the doc header in the install tool, changes background
|
||||
* color and such.
|
||||
*
|
||||
* - GET/POST "install[controller]" Preserved
|
||||
* Either empty, 'step' or 'tool', fallback to 'step'. This coordinates whether the step
|
||||
* or tool controller is called. This parameter is never set externally, so the step
|
||||
* controller is always called first. It itself sets the type to 'tool' and redirects to
|
||||
* the tool controller if needed.
|
||||
* This means you could (but shouldn't) directly call the tool controller, but it
|
||||
* will still require a login and session, then.
|
||||
*
|
||||
* - GET/POST "install[action]" Preserved
|
||||
* Determine step and tool controller main action sanitized by step / tool controller and
|
||||
* only executed if user is logged in. Form protection API relies on this.
|
||||
*
|
||||
* - GET/POST "install[redirectCount]"
|
||||
* The install tool initiates redirects to itself if configuration parameters were changed.
|
||||
* This may lead to infinite redirect loops under rare circumstances. This parameter is
|
||||
* incremented for each redirect to break a loop after some iterations.
|
||||
*
|
||||
* - POST "install[set]"
|
||||
* Contains keys to determine which sub-action of the action is requested,
|
||||
* eg. "change install tool password" in "important actions". Set to 'execute' if some
|
||||
* step should be executed.
|
||||
*
|
||||
* - POST "install[values]"
|
||||
* Data values for a specific "install[set]" action
|
||||
*
|
||||
* - POST "install[token]"
|
||||
* A session and instance specific token created from the instance specific
|
||||
* encryptionKey (taken care of in an early point in the step controller). This hash
|
||||
* is used as form protection against CSRF for all POST data. Both the step and tool
|
||||
* controller will logout a user if the token check fails. The only exception to this
|
||||
* handling is the very first installation step where no session and no encryption key
|
||||
* can exist yet.
|
||||
*/
|
||||
|
||||
// Exit early if php requirement is not satisfied.
|
||||
if (PHP_VERSION_ID < 70200) {
|
||||
die('This version of TYPO3 CMS requires PHP 7.2 or above');
|
||||
}
|
||||
|
||||
call_user_func(function () {
|
||||
$classLoader = require dirname(dirname(__DIR__)).'/vendor/autoload.php';
|
||||
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(1, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_INSTALL);
|
||||
\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader, true)->get(\TYPO3\CMS\Install\Http\Application::class)->run();
|
||||
});
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\About\Controller;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Backend\Module\ModuleLoader;
|
||||
use TYPO3\CMS\Backend\Template\ModuleTemplate;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Http\HtmlResponse;
|
||||
use TYPO3\CMS\Core\Package\PackageManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3Fluid\Fluid\View\ViewInterface;
|
||||
|
||||
/**
|
||||
* Module 'about' shows some standard information for TYPO3 CMS:
|
||||
* About-text, version number, available modules and so on.
|
||||
*
|
||||
* @internal This is a specific Backend Controller implementation and is not considered part of the Public TYPO3 API.
|
||||
*/
|
||||
class AboutController
|
||||
{
|
||||
/**
|
||||
* ModuleTemplate object
|
||||
*
|
||||
* @var ModuleTemplate
|
||||
*/
|
||||
protected $moduleTemplate;
|
||||
|
||||
/**
|
||||
* @var ViewInterface
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* Main action: Show standard information
|
||||
*
|
||||
* @return ResponseInterface the HTML output
|
||||
*/
|
||||
public function indexAction(): ResponseInterface
|
||||
{
|
||||
$this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
|
||||
$this->initializeView('index');
|
||||
$warnings = [];
|
||||
// Hook for additional warnings
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['displayWarningMessages'] ?? [] as $className) {
|
||||
$hookObj = GeneralUtility::makeInstance($className);
|
||||
if (method_exists($hookObj, 'displayWarningMessages_postProcess')) {
|
||||
$hookObj->displayWarningMessages_postProcess($warnings);
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->assignMultiple([
|
||||
'copyrightYear' => TYPO3_copyright_year,
|
||||
'donationUrl' => TYPO3_URL_DONATE,
|
||||
'currentVersion' => TYPO3_version,
|
||||
'loadedExtensions' => $this->getLoadedExtensions(),
|
||||
'copyRightNotice' => BackendUtility::TYPO3_copyRightNotice(),
|
||||
'warnings' => $warnings,
|
||||
'modules' => $this->getModulesData()
|
||||
]);
|
||||
|
||||
$this->moduleTemplate->setContent($this->view->render());
|
||||
return new HtmlResponse($this->moduleTemplate->renderContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create array with data of all main modules (Web, File, ...)
|
||||
* and its nested sub modules
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getModulesData(): array
|
||||
{
|
||||
$loadedModules = GeneralUtility::makeInstance(ModuleLoader::class);
|
||||
$loadedModules->observeWorkspaces = true;
|
||||
$loadedModules->load($GLOBALS['TBE_MODULES']);
|
||||
$mainModulesData = [];
|
||||
foreach ($loadedModules->modules as $moduleName => $moduleInfo) {
|
||||
$moduleLabels = $loadedModules->getLabelsForModule($moduleName);
|
||||
$mainModuleData = [
|
||||
'name' => $moduleName,
|
||||
'label' => $moduleLabels['title']
|
||||
];
|
||||
if (is_array($moduleInfo['sub']) && !empty($moduleInfo['sub'])) {
|
||||
$mainModuleData['subModules'] = $this->getSubModuleData($loadedModules, $moduleName);
|
||||
}
|
||||
$mainModulesData[] = $mainModuleData;
|
||||
}
|
||||
return $mainModulesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create array with data of all subModules of a specific main module
|
||||
*
|
||||
* @param ModuleLoader $loadedModules the module loader instance
|
||||
* @param string $moduleName Name of the main module
|
||||
* @return array
|
||||
*/
|
||||
protected function getSubModuleData(ModuleLoader $loadedModules, $moduleName): array
|
||||
{
|
||||
if (empty($loadedModules->modules[$moduleName]['sub'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$subModulesData = [];
|
||||
foreach ($loadedModules->modules[$moduleName]['sub'] as $subModuleName => $subModuleInfo) {
|
||||
$moduleLabels = $loadedModules->getLabelsForModule($moduleName . '_' . $subModuleName);
|
||||
$subModuleData = [];
|
||||
$subModuleData['name'] = $subModuleName;
|
||||
$subModuleData['icon'] = $subModuleInfo['icon'] ?? null;
|
||||
$subModuleData['iconIdentifier'] = $subModuleInfo['iconIdentifier'] ?? null;
|
||||
$subModuleData['label'] = $moduleLabels['title'] ?? null;
|
||||
$subModuleData['shortDescription'] = $moduleLabels['shortdescription'] ?? null;
|
||||
$subModuleData['longDescription'] = $moduleLabels['description'] ?? null;
|
||||
$subModulesData[] = $subModuleData;
|
||||
}
|
||||
return $subModulesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a list of all active (loaded) extensions in the current system
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getLoadedExtensions(): array
|
||||
{
|
||||
$extensions = [];
|
||||
$packageManager = GeneralUtility::makeInstance(PackageManager::class);
|
||||
foreach ($packageManager->getActivePackages() as $package) {
|
||||
// Skip system extensions (= type: typo3-cms-framework)
|
||||
if ($package->getValueFromComposerManifest('type') !== 'typo3-cms-extension') {
|
||||
continue;
|
||||
}
|
||||
$extensions[] = [
|
||||
'key' => $package->getPackageKey(),
|
||||
'title' => $package->getPackageMetaData()->getDescription(),
|
||||
'authors' => $package->getValueFromComposerManifest('authors')
|
||||
];
|
||||
}
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the view by setting the templateName
|
||||
*
|
||||
* @param string $templateName
|
||||
*/
|
||||
protected function initializeView(string $templateName)
|
||||
{
|
||||
$this->view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$this->view->setTemplate($templateName);
|
||||
$this->view->setTemplateRootPaths(['EXT:about/Resources/Private/Templates/About']);
|
||||
$this->view->setPartialRootPaths(['EXT:about/Resources/Private/Partials']);
|
||||
$this->view->setLayoutRootPaths(['EXT:about/Resources/Private/Layouts']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
Some icons used in the TYPO3 project are retrieved from the "Silk" icon set of
|
||||
Mark James, which can be found at http://famfamfam.com/lab/icons/silk/. This
|
||||
set is distributed under a Creative Commons Attribution 2.5 License. The
|
||||
license can be found at http://creativecommons.org/licenses/by/2.5/.
|
||||
---------------------------------
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415814871" source-language="en" datatype="plaintext" original="EXT:about/Resources/Private/Language/Modules/about.xlf" date="2011-10-17T20:22:34Z" product-name="typo3-cms-about">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="mlang_labels_tablabel" resname="mlang_labels_tablabel">
|
||||
<source>About TYPO3 CMS</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="mlang_labels_tabdescr" resname="mlang_labels_tabdescr">
|
||||
<source>Displays the basic facts about the TYPO3 application, version and licensing terms.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="mlang_tabs_tab" resname="mlang_tabs_tab">
|
||||
<source>About TYPO3 CMS</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="title" resname="title">
|
||||
<source>About TYPO3 CMS</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="typo3_logo" resname="typo3_logo">
|
||||
<source>TYPO3 CMS logo</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="information" resname="information">
|
||||
<source>TYPO3 Information</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="welcome" resname="welcome">
|
||||
<source>TYPO3 CMS - Professional Web Content Management System</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="minor" resname="minor">
|
||||
<source>TYPO3 CMS is an enterprise-class, Open Source Content Management System, used internationally to build and manage websites of all types, from small sites for non-profits to multilingual enterprise solutions for large corporations.<br /><br />For further information visit <a href="https://typo3.org/typo3-cms/" target="_blank" rel="noopener noreferrer">typo3.org</a>.<br /><br />TYPO3 CMS is <b>freely available</b> under the <a href="https://typo3.org/project/licenses/" target="_blank">TYPO3-license (GNU/GPL)</a>.<br /><br />You are using %s %s</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="cms_description" resname="cms_description">
|
||||
<source>TYPO3 CMS is an enterprise-class, Open Source Content Management System, used internationally to build and manage websites of all types, from small sites for non-profits to multilingual enterprise solutions for large corporations.<br /><br />For further information visit <a href="https://typo3.org/typo3-cms/" target="_blank" rel="noopener noreferrer">typo3.org</a>.<br /><br />TYPO3 CMS is <b>freely available</b> under the <a href="https://typo3.org/project/licenses/" target="_blank">TYPO3-license (GNU/GPL)</a>.<br /><br />You are using version %s - Copyright %s %s</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="community_credits" resname="community_credits">
|
||||
<source>Community Credits</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="information_detail" resname="information_detail">
|
||||
<source>Visit <a href="https://typo3.org/community/" target="_blank" rel="noopener noreferrer">typo3.org/community/</a> if you want to know why TYPO3 rocks.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="coredevs" resname="coredevs">
|
||||
<source>Core Team</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="coredevs_detail" resname="coredevs_detail">
|
||||
<source>Visit <a href="https://typo3.org/teams-committees/core-development/" target="_blank" rel="noopener noreferrer">typo3.org/teams-committees/core-development/</a> for the complete member list.<br /><br />The Git Repository and the ChangeLog can be found <a href="https://forge.typo3.org/projects/typo3cms-core/" target="_blank">here</a>.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="extension_authors" resname="extension_authors">
|
||||
<source>Extension Authors</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="extension_list_info" resname="extension_list_info">
|
||||
<source>This is a list of the people who contributed to the extensions you're using in your installation.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="extension" resname="extension">
|
||||
<source>Extension</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="extension_author" resname="extension_author">
|
||||
<source>Author</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="donation_header" resname="donation_header">
|
||||
<source>TYPO3 Donation</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="donation_message" resname="donation_message">
|
||||
<source>It would be great if you could donate. TYPO3 CMS is Open Source and relies heavily on donations from its users and supporters.<br/><br/><b>Thank you</b> for making this great Content Management System even better with your support!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="donation_button" resname="donation_button">
|
||||
<source>Donate now</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="external_libraries" resname="external_libraries">
|
||||
<source>External Libraries</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="external_thanks" resname="external_thanks">
|
||||
<source>TYPO3 CMS core uses and thanks these external Open Source projects:</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415814848" source-language="en" datatype="plaintext" original="EXT:about/Resources/Private/Language/Modules/locallang_alt_intro.xlf" date="2011-10-17T20:22:33Z" product-name="lang">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="introtext" resname="introtext">
|
||||
<source>Web Content Management System</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="introtext2" resname="introtext2">
|
||||
<source>This is a brief description of the available modules.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="endText" resname="endText">
|
||||
<source>Features may vary depending on your website and permissions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="userInfo" resname="userInfo">
|
||||
<source>You're logged in as user</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,8 @@
|
||||
<p>
|
||||
{f:translate(key: 'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:cms_description',
|
||||
arguments: '{
|
||||
0: currentVersion,
|
||||
1: "© {copyrightYear}",
|
||||
2: "Kasper Skårhøj"
|
||||
}') -> f:format.raw()}
|
||||
</p>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body panel-body-highlightlinks">
|
||||
<h2 class="h4">
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:coredevs" />
|
||||
</h2>
|
||||
<p>
|
||||
{f:translate(key: 'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:coredevs_detail') -> f:format.raw()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body panel-body-highlightlinks">
|
||||
<h2 class="h4">
|
||||
{f:translate(key: 'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:community_credits') -> f:format.raw()}
|
||||
</h2>
|
||||
<p>
|
||||
{f:translate(key: 'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:information_detail') -> f:format.raw()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body panel-body-highlightlinks">
|
||||
<h2 class="h4">
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:donation_header" />
|
||||
</h2>
|
||||
<p>
|
||||
{f:translate(key: 'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:donation_message') -> f:format.raw()}
|
||||
</p>
|
||||
<a href="{donationUrl}" class="btn btn-default" title="{f:translate(key:'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:donation_button')}" target="_blank" rel="noopener noreferrer">
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:donation_button" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
<f:if condition="{loadedExtensions}">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body panel-body-highlightlinks">
|
||||
<h2 class="h3">
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:extension_authors" />
|
||||
</h2>
|
||||
<p>
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:extension_list_info" />
|
||||
</p>
|
||||
</div>
|
||||
<table class="table panel-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="60%"><f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:extension" /></th>
|
||||
<th><f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:extension_author" /></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<f:for each="{loadedExtensions}" as="loadedExtension">
|
||||
<tr>
|
||||
<td>
|
||||
{loadedExtension.title} ({loadedExtension.key})
|
||||
</td>
|
||||
<td>
|
||||
<f:for each="{loadedExtension.authors}" as="extensionAuthor" iteration="i">
|
||||
<f:if condition="{extensionAuthor.email}">
|
||||
<f:then>
|
||||
<f:link.email
|
||||
email="{extensionAuthor.email}?subject={f:format.urlencode(value:'Thanks for your {loadedExtension.title} extension')}"
|
||||
>
|
||||
{extensionAuthor.name}
|
||||
</f:link.email>
|
||||
</f:then>
|
||||
<f:else>
|
||||
{extensionAuthor.name}
|
||||
</f:else>
|
||||
</f:if>
|
||||
<f:if condition="{i.isLast} == false">
|
||||
<br>
|
||||
</f:if>
|
||||
</f:for>
|
||||
</td>
|
||||
</tr>
|
||||
</f:for>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</f:if>
|
||||
@@ -0,0 +1,116 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body panel-body-highlightlinks">
|
||||
<h2 class="h3">
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:external_libraries" />
|
||||
</h2>
|
||||
<p>
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:external_thanks" />
|
||||
</p>
|
||||
</div>
|
||||
<table class="table panel-table">
|
||||
<tr>
|
||||
<td>Composer</td>
|
||||
<td><a href="https://getcomposer.org" target="_blank" rel="noopener noreferrer">getcomposer.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery</td>
|
||||
<td><a href="https://jquery.com" target="_blank" rel="noopener noreferrer">jquery.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Twitter Bootstrap</td>
|
||||
<td><a href="https://getbootstrap.com" target="_blank" rel="noopener noreferrer">getbootstrap.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Swift Mailer</td>
|
||||
<td><a href="https://swiftmailer.org" target="_blank" rel="noopener noreferrer">swiftmailer.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Doctrine Project (DBAL Component and Instantiator)</td>
|
||||
<td><a href="https://www.doctrine-project.org/projects/dbal.html" target="_blank" rel="noopener noreferrer">doctrine-project.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Symfony Framework (YAML, Console and Finder Component)</td>
|
||||
<td><a href="https://symfony.com" target="_blank" rel="noopener noreferrer">symfony.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Guzzle PHP</td>
|
||||
<td><a href="http://guzzlephp.org" target="_blank" rel="noopener noreferrer">guzzlephp.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d3 Data Driven Documents</td>
|
||||
<td><a href="https://d3js.org" target="_blank" rel="noopener noreferrer">d3js.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CKEditor</td>
|
||||
<td><a href="https://ckeditor.com" target="_blank" rel="noopener noreferrer">ckeditor.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RequireJS</td>
|
||||
<td><a href="https://requirejs.org" target="_blank" rel="noopener noreferrer">requirejs.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>moment.js</td>
|
||||
<td><a href="https://momentjs.com" target="_blank" rel="noopener noreferrer">momentjs.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NProgress</td>
|
||||
<td><a href="https://ricostacruz.com/nprogress/" target="_blank" rel="noopener noreferrer">ricostacruz.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery UI</td>
|
||||
<td><a href="https://jqueryui.com" target="_blank" rel="noopener noreferrer">jqueryui.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Twitter Bootstrap Plugin: DateTimePicker</td>
|
||||
<td><a href="https://eonasdan.github.io/bootstrap-datetimepicker/" target="_blank" rel="noopener noreferrer">eonasdan.github.io</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Twitter Bootstrap Plugin: Slider</td>
|
||||
<td><a href="https://seiyria.com/bootstrap-slider/" target="_blank" rel="noopener noreferrer">seiyria.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: Ajax AutoComplete</td>
|
||||
<td><a href="https://www.devbridge.com/sourcery/components/jquery-autocomplete/" target="_blank" rel="noopener noreferrer">devbridge.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: Autosize</td>
|
||||
<td><a href="https://www.jacklmoore.com/autosize/" target="_blank" rel="noopener noreferrer">jacklmoore.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: Cropper</td>
|
||||
<td><a href="https://fengyuanchen.github.io/cropper/" target="_blank" rel="noopener noreferrer">fengyuanchen.github.io</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: DataTables</td>
|
||||
<td><a href="https://datatables.net" target="_blank" rel="noopener noreferrer">datatables.net</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: ImagesLoaded</td>
|
||||
<td><a href="https://imagesloaded.desandro.com" target="_blank" rel="noopener noreferrer">imagesloaded.desandro.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: MiniColors</td>
|
||||
<td><a href="https://labs.abeautifulsite.net/jquery-minicolors/" target="_blank" rel="noopener noreferrer">labs.abeautifulsite.net</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jQuery Plugin: Tab Override</td>
|
||||
<td><a href="https://wjbryant.github.io/taboverride/" target="_blank" rel="noopener noreferrer">wjbryant.github.io</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Neos (Form component)</td>
|
||||
<td><a href="https://www.neos.io" target="_blank" rel="noopener noreferrer">neos.io</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FineDiff</td>
|
||||
<td><a href="https://github.com/cogpowered/FineDiff" target="_blank" rel="noopener noreferrer">github.com</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IDNA Convert</td>
|
||||
<td><a href="https://idnaconv.net" target="_blank" rel="noopener noreferrer">idnaconv.net</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CodeMirror</td>
|
||||
<td><a href="https://codemirror.net" target="_blank" rel="noopener noreferrer">codemirror.net</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
<img src="{f:uri.resource(path: 'Images/typo3_orange.svg', extensionName: 'backend')}" width="150"
|
||||
alt="{f:translate(key:'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf:typo3_logo')}" />
|
||||
<br>
|
||||
<br>
|
||||
<h1>
|
||||
TYPO3 CMS {currentVersion}<br>
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/locallang_alt_intro.xlf:introtext" />
|
||||
</h1>
|
||||
@@ -0,0 +1,43 @@
|
||||
<p>
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/locallang_alt_intro.xlf:introtext2" />
|
||||
</p>
|
||||
<f:for each="{modules}" as="mainModule">
|
||||
<f:if condition="{mainModule.subModules}">
|
||||
<f:if condition="{mainModule.label}">
|
||||
<h2>{f:translate(key: mainModule.label)}</h2>
|
||||
</f:if>
|
||||
<section class="card-container">
|
||||
<f:for each="{mainModule.subModules}" as="subModule" iteration="subModuleIterator">
|
||||
<a
|
||||
href="#"
|
||||
onclick="top.goToModule('{mainModule.name}_{subModule.name}'); return false;"
|
||||
title="{f:if(condition: subModule.shortDescription, then: '{f:translate(key: subModule.shortDescription)}')}"
|
||||
class="card card-size-medium"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div class="card-icon">
|
||||
<core:icon identifier="{subModule.iconIdentifier}" size="default" />
|
||||
</div>
|
||||
<f:if condition="{subModule.label}">
|
||||
<div class="card-header-body">
|
||||
<h3 class="card-title">
|
||||
{f:translate(key: subModule.label)}
|
||||
</h3>
|
||||
<f:if condition="{subModule.shortDescription}">
|
||||
<span class="card-subtitle">
|
||||
<f:translate key="{subModule.shortDescription}" />
|
||||
</span>
|
||||
</f:if>
|
||||
<f:if condition="{subModule.longDescription}">
|
||||
<div class="card-longdesc">
|
||||
{f:translate(key: subModule.longDescription) -> f:format.raw()}
|
||||
</div>
|
||||
</f:if>
|
||||
</div>
|
||||
</f:if>
|
||||
</div>
|
||||
</a>
|
||||
</f:for>
|
||||
</section>
|
||||
</f:if>
|
||||
</f:for>
|
||||
@@ -0,0 +1,39 @@
|
||||
<div class="container-small about-module">
|
||||
<f:render partial="Logo" arguments="{_all}" />
|
||||
|
||||
<f:if condition="{warnings}">
|
||||
<f:be.infobox title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.header')}" state="2">
|
||||
<f:if condition="{f:count(subject: warnings)} > 1">
|
||||
<f:then>
|
||||
<ul>
|
||||
<f:for each="{warnings}" as="warning">
|
||||
<li>{warning -> f:format.raw()}</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<p>
|
||||
<f:for each="{warnings}" as="warning">
|
||||
{warning -> f:format.raw()}
|
||||
</f:for>
|
||||
</p>
|
||||
</f:else>
|
||||
</f:if>
|
||||
</f:be.infobox>
|
||||
</f:if>
|
||||
|
||||
<f:render partial="About" arguments="{_all}" />
|
||||
<f:render partial="Modules" arguments="{_all}" />
|
||||
<f:render partial="Donation" arguments="{_all}" />
|
||||
<f:render partial="Credits" arguments="{_all}" />
|
||||
<f:render partial="CoreTeam" arguments="{_all}" />
|
||||
<f:render partial="ExternalLibraries" arguments="{_all}" />
|
||||
<f:render partial="Extensions" arguments="{_all}" />
|
||||
|
||||
<p>
|
||||
<em class="text-muted">
|
||||
<f:translate key="LLL:EXT:about/Resources/Private/Language/Modules/locallang_alt_intro.xlf:endText" />
|
||||
</em>
|
||||
</p>
|
||||
<p>{copyRightNotice -> f:format.raw()}</p>
|
||||
</div>
|
||||
|
After Width: | Height: | Size: 977 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path fill="#FF8700" d="M0 0h64v64H0z"/><path fill="#FFF" d="M42.8 32.8c-3.6 0-8.1-10.1-8.1-15.1 0-2.3.9-2.7 3.2-2.7 5.5 0 11 .9 11 4-.1 6.2-4 13.8-6.1 13.8zM28.5 18.5c0 5 6.4 20.2 10.7 20.2.5 0 .9-.1 1.4-.2-3.8 6.1-8.4 10.6-11.2 10.6-5.9 0-14.3-17.9-14.3-25.7 0-1.2.3-2.2.7-2.8 2-2.5 8.4-4.4 13.7-5-.6.4-1 1-1 2.9z"/></svg>
|
||||
|
After Width: | Height: | Size: 384 B |
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "typo3/cms-about",
|
||||
"type": "typo3-cms-framework",
|
||||
"description": "Shows info about TYPO3, installed extensions and a separate module for available modules.",
|
||||
"homepage": "https://typo3.org",
|
||||
"license": ["GPL-2.0-or-later"],
|
||||
"authors": [{
|
||||
"name": "TYPO3 Core Team",
|
||||
"email": "typo3cms@typo3.org",
|
||||
"role": "Developer"
|
||||
}],
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"require": {
|
||||
"typo3/cms-core": "9.5.31"
|
||||
},
|
||||
"conflict": {
|
||||
"typo3/cms": "*"
|
||||
},
|
||||
"extra": {
|
||||
"typo3/cms": {
|
||||
"Package": {
|
||||
"partOfFactoryDefault": true
|
||||
},
|
||||
"extension-key": "about"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"TYPO3\\CMS\\About\\": "Classes/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
$EM_CONF[$_EXTKEY] = [
|
||||
'title' => 'Help>About',
|
||||
'description' => 'Shows info about TYPO3, installed extensions and a separate module for available modules.',
|
||||
'category' => 'module',
|
||||
'state' => 'stable',
|
||||
'uploadfolder' => 0,
|
||||
'createDirs' => '',
|
||||
'clearCacheOnLoad' => 0,
|
||||
'author' => 'TYPO3 Core Team',
|
||||
'author_email' => 'typo3cms@typo3.org',
|
||||
'version' => '9.5.31',
|
||||
'constraints' => [
|
||||
'depends' => [
|
||||
'typo3' => '9.5.31',
|
||||
],
|
||||
'conflicts' => [],
|
||||
'suggests' => [],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or die();
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModule(
|
||||
'help',
|
||||
'AboutAbout',
|
||||
'top',
|
||||
null,
|
||||
[
|
||||
'routeTarget' => \TYPO3\CMS\About\Controller\AboutController::class . '::indexAction',
|
||||
'access' => 'user,group',
|
||||
'name' => 'help_AboutAbout',
|
||||
'icon' => 'EXT:about/Resources/Public/Icons/module-about.svg',
|
||||
'labels' => 'LLL:EXT:about/Resources/Private/Language/Modules/about.xlf'
|
||||
]
|
||||
);
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Controller;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
|
||||
use TYPO3\CMS\Adminpanel\Service\ModuleLoader;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Http\JsonResponse;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Admin Panel Ajax Controller - Route endpoint for ajax actions
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class AjaxController
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $adminPanelModuleConfiguration;
|
||||
|
||||
/**
|
||||
* @var ModuleLoader
|
||||
*/
|
||||
protected $moduleLoader;
|
||||
|
||||
/**
|
||||
* @var ConfigurationService
|
||||
*/
|
||||
private $configurationService;
|
||||
|
||||
/**
|
||||
* @param ConfigurationService $configurationService
|
||||
* @param ModuleLoader $moduleLoader
|
||||
*/
|
||||
public function __construct(ConfigurationService $configurationService = null, ModuleLoader $moduleLoader = null)
|
||||
{
|
||||
$this->configurationService = $configurationService
|
||||
??
|
||||
GeneralUtility::makeInstance(ConfigurationService::class);
|
||||
$this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? [];
|
||||
$this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save adminPanel data
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function saveDataAction(ServerRequestInterface $request): JsonResponse
|
||||
{
|
||||
$this->configurationService->saveConfiguration(
|
||||
$this->moduleLoader->validateSortAndInitializeModules($this->adminPanelModuleConfiguration),
|
||||
$request
|
||||
);
|
||||
return new JsonResponse(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle admin panel active state via UC
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function toggleActiveState(): JsonResponse
|
||||
{
|
||||
$backendUser = $this->getBackendUser();
|
||||
if ($backendUser->uc['AdminPanel']['display_top'] ?? false) {
|
||||
$backendUser->uc['AdminPanel']['display_top'] = false;
|
||||
} else {
|
||||
$backendUser->uc['AdminPanel']['display_top'] = true;
|
||||
}
|
||||
$backendUser->writeUC();
|
||||
return new JsonResponse(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current BE user.
|
||||
*
|
||||
* @return BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Controller;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleDataStorageCollection;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
|
||||
use TYPO3\CMS\Adminpanel\Service\ModuleLoader;
|
||||
use TYPO3\CMS\Adminpanel\Utility\ResourceUtility;
|
||||
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
|
||||
use TYPO3\CMS\Adminpanel\View\AdminPanelView;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
/**
|
||||
* Main controller for the admin panel
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class MainController implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[]
|
||||
*/
|
||||
protected $modules = [];
|
||||
|
||||
/**
|
||||
* @var ModuleLoader
|
||||
*/
|
||||
protected $moduleLoader;
|
||||
|
||||
/**
|
||||
* @var UriBuilder
|
||||
*/
|
||||
protected $uriBuilder;
|
||||
|
||||
/**
|
||||
* @var ConfigurationService
|
||||
*/
|
||||
protected $configurationService;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $adminPanelModuleConfiguration;
|
||||
|
||||
/**
|
||||
* @param ModuleLoader $moduleLoader
|
||||
* @param UriBuilder $uriBuilder
|
||||
* @param ConfigurationService $configurationService
|
||||
*/
|
||||
public function __construct(
|
||||
ModuleLoader $moduleLoader = null,
|
||||
UriBuilder $uriBuilder = null,
|
||||
ConfigurationService $configurationService = null
|
||||
) {
|
||||
$this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class);
|
||||
$this->uriBuilder = $uriBuilder ?? GeneralUtility::makeInstance(UriBuilder::class);
|
||||
$this->configurationService = $configurationService
|
||||
??
|
||||
GeneralUtility::makeInstance(ConfigurationService::class);
|
||||
$this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes settings for the admin panel.
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
*/
|
||||
public function initialize(ServerRequestInterface $request): void
|
||||
{
|
||||
$this->modules = $this->moduleLoader->validateSortAndInitializeModules(
|
||||
$this->adminPanelModuleConfiguration
|
||||
);
|
||||
|
||||
if (StateUtility::isActivatedForUser()) {
|
||||
$this->initializeModules($request, $this->modules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the admin panel - Called in PSR-15 Middleware
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\Middleware\AdminPanelRenderer
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @return string
|
||||
*/
|
||||
public function render(ServerRequestInterface $request): string
|
||||
{
|
||||
// legacy handling, deprecated, will be removed in TYPO3 v10.0.
|
||||
$adminPanelView = GeneralUtility::makeInstance(AdminPanelView::class);
|
||||
$hookObjectContent = $adminPanelView->callDeprecatedHookObject();
|
||||
// end legacy handling
|
||||
|
||||
$resources = ResourceUtility::getResources();
|
||||
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Main.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
$view->setLayoutRootPaths(['EXT:adminpanel/Resources/Private/Layouts']);
|
||||
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'toggleActiveUrl' => $this->generateBackendUrl('ajax_adminPanel_toggle'),
|
||||
'resources' => $resources,
|
||||
'adminPanelActive' => StateUtility::isOpen(),
|
||||
]
|
||||
);
|
||||
if (StateUtility::isOpen()) {
|
||||
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('adminpanel_requestcache');
|
||||
$requestId = $request->getAttribute('adminPanelRequestId');
|
||||
$data = $cache->get($requestId);
|
||||
$moduleResources = ResourceUtility::getAdditionalResourcesForModules($this->modules);
|
||||
$settingsModules = array_filter($this->modules, function (ModuleInterface $module) {
|
||||
return $module instanceof PageSettingsProviderInterface;
|
||||
});
|
||||
$parentModules = array_filter(
|
||||
$this->modules,
|
||||
function (ModuleInterface $module) {
|
||||
return $module instanceof SubmoduleProviderInterface && $module instanceof ShortInfoProviderInterface;
|
||||
}
|
||||
);
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'modules' => $this->modules,
|
||||
'settingsModules' => $settingsModules,
|
||||
'parentModules' => $parentModules,
|
||||
'hookObjectContent' => $hookObjectContent,
|
||||
'saveUrl' => $this->generateBackendUrl('ajax_adminPanel_saveForm'),
|
||||
'moduleResources' => $moduleResources,
|
||||
'requestId' => $requestId,
|
||||
'data' => $data ?? [],
|
||||
]
|
||||
);
|
||||
}
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores data for admin panel in cache - Called in PSR-15 Middleware
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\Middleware\AdminPanelDataPersister
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
|
||||
*/
|
||||
public function storeData(ServerRequestInterface $request): void
|
||||
{
|
||||
if (StateUtility::isOpen()) {
|
||||
$data = $this->storeDataPerModule(
|
||||
$request,
|
||||
$this->modules,
|
||||
GeneralUtility::makeInstance(ModuleDataStorageCollection::class)
|
||||
);
|
||||
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('adminpanel_requestcache');
|
||||
$cache->set($request->getAttribute('adminPanelRequestId'), $data);
|
||||
$cache->collectGarbage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a url to a backend route
|
||||
*
|
||||
* @param string $route
|
||||
* @return string
|
||||
*/
|
||||
protected function generateBackendUrl(string $route): string
|
||||
{
|
||||
return (string)$this->uriBuilder->buildUriFromRoute($route);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[] $modules
|
||||
*/
|
||||
protected function initializeModules(ServerRequestInterface $request, array $modules): void
|
||||
{
|
||||
foreach ($modules as $module) {
|
||||
if (
|
||||
($module instanceof InitializableInterface)
|
||||
&& (
|
||||
(($module instanceof ConfigurableInterface) && $module->isEnabled())
|
||||
|| (!($module instanceof ConfigurableInterface))
|
||||
)
|
||||
) {
|
||||
$module->initializeModule($request);
|
||||
}
|
||||
if ($module instanceof SubmoduleProviderInterface) {
|
||||
$this->initializeModules($request, $module->getSubModules());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[] $modules
|
||||
* @param ModuleDataStorageCollection $data
|
||||
* @return ModuleDataStorageCollection
|
||||
*/
|
||||
protected function storeDataPerModule(ServerRequestInterface $request, array $modules, ModuleDataStorageCollection $data): ModuleDataStorageCollection
|
||||
{
|
||||
foreach ($modules as $module) {
|
||||
if (
|
||||
($module instanceof DataProviderInterface)
|
||||
&& (
|
||||
(($module instanceof ConfigurableInterface) && $module->isEnabled())
|
||||
|| (!($module instanceof ConfigurableInterface))
|
||||
)
|
||||
) {
|
||||
$data->addModuleData($module, $module->getDataToStore($request));
|
||||
}
|
||||
|
||||
if ($module instanceof SubmoduleProviderInterface) {
|
||||
$this->storeDataPerModule($request, $module->getSubModules(), $data);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Exceptions;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for invalid admin panel configuration
|
||||
*/
|
||||
class InvalidConfigurationException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Log;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\Logging\SQLLogger;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use TYPO3\CMS\Adminpanel\Utility\MemoryUtility;
|
||||
|
||||
/**
|
||||
* Doctrine SQL Logger implementation for recording queries for the admin panel
|
||||
*/
|
||||
class DoctrineSqlLogger implements SQLLogger, LoggerAwareInterface
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/**
|
||||
* Executed SQL queries.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $queries = [];
|
||||
|
||||
/**
|
||||
* If Debug Stack is enabled (log queries) or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled = true;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $start;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $currentQuery = 0;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function startQuery($sql, array $params = null, array $types = null)
|
||||
{
|
||||
if ($this->enabled && MemoryUtility::isMemoryConsumptionTooHigh()) {
|
||||
$this->enabled = false;
|
||||
$this->logger->warning('SQL Logging consumed too much memory, aborted. Not all queries have been recorded.');
|
||||
}
|
||||
if ($this->enabled) {
|
||||
$this->start = microtime(true);
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 7);
|
||||
// remove this method
|
||||
array_shift($backtrace);
|
||||
// remove doctrine execute query
|
||||
array_shift($backtrace);
|
||||
// remove queryBuilder execute
|
||||
array_shift($backtrace);
|
||||
$this->queries[++$this->currentQuery] = [
|
||||
'sql' => $sql,
|
||||
'params' => $params,
|
||||
'types' => $types,
|
||||
'executionMS' => 0,
|
||||
'backtrace' => $backtrace
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function stopQuery()
|
||||
{
|
||||
if ($this->enabled) {
|
||||
$this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getQueries(): array
|
||||
{
|
||||
return $this->queries;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Log;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\Utility\MemoryUtility;
|
||||
use TYPO3\CMS\Core\Log\LogLevel;
|
||||
use TYPO3\CMS\Core\Log\LogRecord;
|
||||
use TYPO3\CMS\Core\Log\Writer\AbstractWriter;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Log writer that writes the log records into a static public class variable
|
||||
* for InMemory processing
|
||||
*/
|
||||
class InMemoryLogWriter extends AbstractWriter
|
||||
{
|
||||
public static $log = [];
|
||||
|
||||
private static $memoryLock = false;
|
||||
|
||||
/**
|
||||
* Writes the log record
|
||||
*
|
||||
* @param LogRecord $record Log record
|
||||
* @return self
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function writeLog(LogRecord $record): self
|
||||
{
|
||||
// Guard: Locked Writer
|
||||
if (self::$memoryLock === true) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Guard: Memory Usage
|
||||
if (!self::$memoryLock && MemoryUtility::isMemoryConsumptionTooHigh()) {
|
||||
$this->lockWriter();
|
||||
return $this;
|
||||
}
|
||||
|
||||
self::$log[] = $record;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock writer and add a info message that there may potentially be more entries.
|
||||
*/
|
||||
protected function lockWriter(): void
|
||||
{
|
||||
self::$memoryLock = true;
|
||||
/** @var LogRecord $record */
|
||||
$record = GeneralUtility::makeInstance(
|
||||
LogRecord::class,
|
||||
'TYPO3.CMS.AdminPanel.Log.InMemoryLogWriter',
|
||||
LogLevel::INFO,
|
||||
'... Further log entries omitted, memory usage too high.'
|
||||
);
|
||||
self::$log[] = $record;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Middleware;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use TYPO3\CMS\Adminpanel\Controller\MainController;
|
||||
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
|
||||
use TYPO3\CMS\Core\Http\NullResponse;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Store request data of current request in cache for rendering in admin panel
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class AdminPanelDataPersister implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* Render the admin panel if activated
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$response = $handler->handle($request);
|
||||
if (
|
||||
!($response instanceof NullResponse)
|
||||
&& $GLOBALS['TSFE'] instanceof TypoScriptFrontendController
|
||||
&& $GLOBALS['TSFE']->isOutputting()
|
||||
&& StateUtility::isActivatedForUser()
|
||||
&& StateUtility::isActivatedInTypoScript()
|
||||
&& !StateUtility::isHiddenForUser()
|
||||
) {
|
||||
$mainController = GeneralUtility::makeInstance(MainController::class);
|
||||
$mainController->storeData($request);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Middleware;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use TYPO3\CMS\Adminpanel\Controller\MainController;
|
||||
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
|
||||
use TYPO3\CMS\Adminpanel\View\AdminPanelView;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* PSR-15 Middleware to initialize the admin panel
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class AdminPanelInitiator implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* Initialize the adminPanel if
|
||||
* - backend user is logged in
|
||||
* - at least one adminpanel functionality is enabled
|
||||
* - admin panel is open
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
if (StateUtility::isActivatedForUser() && StateUtility::isOpen()) {
|
||||
$request = $request->withAttribute('adminPanelRequestId', substr(md5(uniqid('', true)), 0, 13));
|
||||
$adminPanelController = GeneralUtility::makeInstance(
|
||||
MainController::class
|
||||
);
|
||||
$adminPanelController->initialize($request);
|
||||
// legacy handling
|
||||
$beUser = $GLOBALS['BE_USER'];
|
||||
$beUser->adminPanel = GeneralUtility::makeInstance(AdminPanelView::class);
|
||||
$beUser->extAdmEnabled = true;
|
||||
}
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Middleware;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use TYPO3\CMS\Adminpanel\Controller\MainController;
|
||||
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
|
||||
use TYPO3\CMS\Core\Http\NullResponse;
|
||||
use TYPO3\CMS\Core\Http\Stream;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Render the admin panel via PSR-15 middleware
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class AdminPanelRenderer implements MiddlewareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Render the admin panel if activated
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$response = $handler->handle($request);
|
||||
if (
|
||||
!($response instanceof NullResponse)
|
||||
&& $GLOBALS['TSFE'] instanceof TypoScriptFrontendController
|
||||
&& $GLOBALS['TSFE']->isOutputting()
|
||||
&& StateUtility::isActivatedForUser()
|
||||
&& StateUtility::isActivatedInTypoScript()
|
||||
&& !StateUtility::isHiddenForUser()
|
||||
) {
|
||||
$mainController = GeneralUtility::makeInstance(MainController::class);
|
||||
$body = $response->getBody();
|
||||
$body->rewind();
|
||||
$contents = $response->getBody()->getContents();
|
||||
$content = str_ireplace(
|
||||
'</body>',
|
||||
$mainController->render($request) . '</body>',
|
||||
$contents
|
||||
);
|
||||
$body = new Stream('php://temp', 'rw');
|
||||
$body->write($content);
|
||||
$response = $response->withBody($body);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Middleware;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use TYPO3\CMS\Adminpanel\Log\DoctrineSqlLogger;
|
||||
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Enable sql logging for the admin panel
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class SqlLogging implements MiddlewareInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Enable SQL Logging as early as possible to catch all queries if the admin panel is active
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
if (StateUtility::isActivatedForUser() && StateUtility::isOpen()) {
|
||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
$connection = $connectionPool->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
|
||||
$connection->getConfiguration()->setSQLLogger(GeneralUtility::makeInstance(DoctrineSqlLogger::class));
|
||||
}
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Abstract base class for Admin Panel Modules containing helper methods and default interface implementations
|
||||
* Extend this class when writing own admin panel modules (or implement the Interface directly)
|
||||
*/
|
||||
abstract class AbstractModule implements ModuleInterface, ConfigurableInterface, SubmoduleProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var ModuleInterface[]
|
||||
*/
|
||||
protected $subModules = [];
|
||||
|
||||
/**
|
||||
* Main Configuration (from UserTSConfig, admPanel)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $mainConfiguration;
|
||||
|
||||
/**
|
||||
* @var ConfigurationService
|
||||
*/
|
||||
protected $configurationService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
|
||||
$this->mainConfiguration = $this->configurationService->getMainConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the module is
|
||||
* -> either enabled via TSConfig admPanel.enable
|
||||
* -> or any setting is overridden
|
||||
* override is a way to use functionality of the admin panel without displaying the admin panel to users
|
||||
* for example: hidden records or pages can be displayed by default
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
$identifier = $this->getIdentifier();
|
||||
$result = $this->isEnabledViaTsConfig();
|
||||
if ($this->mainConfiguration['override.'][$identifier] ?? false) {
|
||||
$result = (bool)$this->mainConfiguration['override.'][$identifier];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setSubModules(array $subModules): void
|
||||
{
|
||||
$this->subModules = $subModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSubModules(): array
|
||||
{
|
||||
return $this->subModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function hasSubmoduleSettings(): bool
|
||||
{
|
||||
$hasSettings = false;
|
||||
foreach ($this->subModules as $subModule) {
|
||||
if ($subModule instanceof ModuleSettingsProviderInterface) {
|
||||
$hasSettings = true;
|
||||
break;
|
||||
}
|
||||
if ($subModule instanceof SubmoduleProviderInterface) {
|
||||
$hasSettings = $subModule->hasSubmoduleSettings();
|
||||
}
|
||||
}
|
||||
return $hasSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current BE user.
|
||||
*
|
||||
* @return BackendUserAuthentication|FrontendBackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns LanguageService
|
||||
*
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if TSConfig admPanel.enable is set for this module (or all modules)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isEnabledViaTsConfig(): bool
|
||||
{
|
||||
$result = false;
|
||||
$identifier = $this->getIdentifier();
|
||||
if (!empty($this->mainConfiguration['enable.']['all'])) {
|
||||
$result = true;
|
||||
} elseif (!empty($this->mainConfiguration['enable.'][$identifier])) {
|
||||
$result = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
|
||||
/**
|
||||
* Abstract SubModule - Base class for sub modules in the admin panel
|
||||
*
|
||||
* Extend this class when writing own sub modules
|
||||
*/
|
||||
abstract class AbstractSubModule implements ModuleInterface, ContentProviderInterface
|
||||
{
|
||||
/**
|
||||
* Returns LanguageService
|
||||
*
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* AdminPanel ConfigurableInterface
|
||||
*
|
||||
* Used to indicate that an adminpanel module can be enabled or disabled via configuration
|
||||
*
|
||||
* Usual implementation is done via user tsconfig
|
||||
* @see \TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule::isEnabled()
|
||||
*/
|
||||
interface ConfigurableInterface
|
||||
{
|
||||
/**
|
||||
* Module is enabled
|
||||
* -> should be initialized
|
||||
* A module may be enabled but not shown
|
||||
* -> only the initializeModule() method
|
||||
* will be called
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled(): bool;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel interface to denote that a module has content to be rendered
|
||||
*
|
||||
* In general there are two main types of admin panel modules: those providing settings influencing page rendering
|
||||
* (for example the preview module provides settings for displaying hidden pages or records) and those rendering
|
||||
* information regarding the current request (for example the log module).
|
||||
*
|
||||
* Modules implementing this interface denote that they render module content.
|
||||
*/
|
||||
interface ContentProviderInterface
|
||||
{
|
||||
/**
|
||||
* Main method for content generation of an admin panel module.
|
||||
* Return content as HTML. For modules implementing the DataProviderInterface
|
||||
* the "ModuleData" object is automatically filled with the stored data - if
|
||||
* no data is given a "fresh" ModuleData object is injected.
|
||||
*
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData $data
|
||||
* @return string
|
||||
*/
|
||||
public function getContent(ModuleData $data): string;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
/**
|
||||
* Adminpanel interface to denote that a module provides data to be stored for the current request
|
||||
*
|
||||
* Adminpanel modules can save data to the adminpanel request cache and access this data in the rendering process.
|
||||
* Data necessary for rendering the module content has to be returned via this interface implementation, as this allows
|
||||
* for separate data collection and rendering and is a pre-requisite for a standalone debug tool.
|
||||
*/
|
||||
interface DataProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @return \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData
|
||||
*/
|
||||
public function getDataToStore(ServerRequestInterface $request): ModuleData;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
/**
|
||||
* Adminpanel interface to denote that a module has tasks to perform on initialization of the request
|
||||
*
|
||||
* Modules that need to set data / options early in the rendering process to be able to collect data, should implement
|
||||
* this interface - for example the log module uses the initialization to register the admin panel log collection early
|
||||
* in the rendering process.
|
||||
*
|
||||
* Initialize is called in the PSR-15 middleware stack through admin panel initialisation via the AdminPanel MainController.
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\Middleware\AdminPanelInitiator::process()
|
||||
* @see \TYPO3\CMS\Adminpanel\Controller\MainController::initialize()
|
||||
*/
|
||||
interface InitializableInterface
|
||||
{
|
||||
/**
|
||||
* Initialize the module - runs early in a TYPO3 request
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
*/
|
||||
public function initializeModule(ServerRequestInterface $request): void;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/**
|
||||
* ModuleData is a simple wrapper object which extends ArrayObject
|
||||
* which is used to hold Adminpanel module data
|
||||
*
|
||||
* It's a separate class to add semantic meaning to its' usage
|
||||
*/
|
||||
class ModuleData extends \ArrayObject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* ModuleDataStorageCollection is an object storage for adminpanel modules and their data
|
||||
*/
|
||||
class ModuleDataStorageCollection extends \SplObjectStorage
|
||||
{
|
||||
public function addModuleData(DataProviderInterface $module, ModuleData $moduleData): void
|
||||
{
|
||||
$this->attach($module, $moduleData);
|
||||
}
|
||||
|
||||
public function getHash($object)
|
||||
{
|
||||
if ($object instanceof ModuleInterface) {
|
||||
return $object->getIdentifier();
|
||||
}
|
||||
throw new \InvalidArgumentException(
|
||||
'Only modules implementing ' . ModuleInterface::class . ' are allowed to be stored',
|
||||
1535301628
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel interface for all modules
|
||||
*
|
||||
* Every adminpanel module needs to implement this interface as a bare minimum.
|
||||
*/
|
||||
interface ModuleInterface
|
||||
{
|
||||
/**
|
||||
* Identifier for this module,
|
||||
* for example "preview" or "cache"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string;
|
||||
|
||||
/**
|
||||
* Module label
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel(): string;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel module settings interface denotes that a module has own settings.
|
||||
*
|
||||
* The adminpanel knows two types of settings:
|
||||
* - ModuleSettings are relevant for the module itself and its representation (for example the log module provides settings
|
||||
* where displayed log level and grouping of the module can be configured)
|
||||
* - PageSettings are relevant for rendering the page (for example the preview module provides settings showing or hiding
|
||||
* hidden content elements or simulating a specific rendering time)
|
||||
*
|
||||
* If a module provides settings relevant to its own content, use this interface.
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface
|
||||
*/
|
||||
interface ModuleSettingsProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSettings(): string;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
/**
|
||||
* Adminpanel interface for modules that need to react on changed configuration
|
||||
* (for example if fluid debug settings change, the frontend cache should be cleared)
|
||||
*/
|
||||
interface OnSubmitActorInterface
|
||||
{
|
||||
/**
|
||||
* Executed on saving / submit of the configuration form
|
||||
* Can be used to react to changed settings
|
||||
* (for example: clearing a specific cache)
|
||||
*
|
||||
* @param array $configurationToSave
|
||||
* @param ServerRequestInterface $request
|
||||
*/
|
||||
public function onSubmit(array $configurationToSave, ServerRequestInterface $request): void;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel page settings interface denotes that a module has settings regarding the page rendering.
|
||||
* The adminpanel knows two types of settings:
|
||||
* - ModuleSettings are relevant for the module itself and its representation (for example the log module provides settings
|
||||
* where displayed log level and grouping of the module can be configured)
|
||||
* - PageSettings are relevant for rendering the page (for example the preview module provides settings showing or hiding
|
||||
* hidden content elements or simulating a specific rendering time)
|
||||
* If a module provides settings changing the rendering of the main page request, use this interface.
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\ModuleApi\ModuleSettingsProviderInterface
|
||||
*/
|
||||
interface PageSettingsProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPageSettings(): string;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel interface to denote that a module has own resource files.
|
||||
*
|
||||
* An adminpanel module implementing this interface may deliver custom JavaScript and Css files to provide additional
|
||||
* styling and JavaScript functionality
|
||||
*/
|
||||
interface ResourceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Returns a string array with javascript files that will be rendered after the module
|
||||
*
|
||||
* Example: return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Edit.js'];
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJavaScriptFiles(): array;
|
||||
|
||||
/**
|
||||
* Returns a string array with css files that will be rendered after the module
|
||||
*
|
||||
* Example: return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Edit.css'];
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCssFiles(): array;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel shortinfo provider interface can be used to add the module to the short info bar of the adminpanel
|
||||
*
|
||||
* Modules providing shortinfo will be displayed in the bottom bar of the adminpanel and may provide "at a glance" info
|
||||
* about the current state (for example the log module provides the number of warnings and errors directly).
|
||||
*
|
||||
* Be aware that modules with submodules at the moment can only render one short info (the one of the "parent" module).
|
||||
* This will likely change in TYPO3 v10.0.
|
||||
*/
|
||||
interface ShortInfoProviderInterface
|
||||
{
|
||||
/**
|
||||
* Displayed directly in the bar
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getShortInfo(): string;
|
||||
|
||||
/**
|
||||
* Icon identifier - needs to be registered in iconRegistry
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIconIdentifier(): string;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ModuleApi;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adminpanel interface providing hierarchical functionality for modules
|
||||
*
|
||||
* A module implementing this interface may have submodules. Be aware that the current implementation of the adminpanel
|
||||
* renders a maximum level of 2 for modules. If you need to render more levels, write your own module and implement
|
||||
* multi-hierarchical rendering in the getContent method
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\ModuleApi\ContentProviderInterface::getContent()
|
||||
*/
|
||||
interface SubmoduleProviderInterface
|
||||
{
|
||||
/**
|
||||
* Sets array of module instances (instances of `ModuleInterface`) as submodules
|
||||
*
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[] $subModules
|
||||
*/
|
||||
public function setSubModules(array $subModules): void;
|
||||
|
||||
/**
|
||||
* Returns an array of module instances
|
||||
*
|
||||
* @return \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[]
|
||||
*/
|
||||
public function getSubModules(): array;
|
||||
|
||||
/**
|
||||
* Return true if any of the submodules has settings to be rendered
|
||||
* (can be used to render settings in a central place)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSubmoduleSettings(): bool;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ResourceProviderInterface;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
class CacheModule extends AbstractModule implements PageSettingsProviderInterface, InitializableInterface, ResourceProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIconIdentifier(): string
|
||||
{
|
||||
return 'apps-toolbar-menu-cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPageSettings(): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Settings/Cache.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
$feCacheClear = $this->getBackendUser()->isAdmin() || $this->getBackendUser()->getTSConfig()['options.']['clearCache.']['pages'];
|
||||
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'isEnabled' => $this->getBackendUser()->uc['AdminPanel']['display_cache'],
|
||||
'noCache' => $this->getBackendUser()->uc['AdminPanel']['cache_noCache'],
|
||||
'currentId' => $this->getTypoScriptFrontendController()->id,
|
||||
'clearPageCacheUrl' => $feCacheClear ? (string)$uriBuilder->buildUriFromRoute('tce_db', ['cacheCmd' => 'pages']) : '',
|
||||
'clearCurrentPageCacheUrl' => (string)$uriBuilder->buildUriFromRoute(
|
||||
'tce_db',
|
||||
[
|
||||
'cacheCmd' => $this->getTypoScriptFrontendController()->id,
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
$locallangFileAndPath = 'LLL:EXT:adminpanel/Resources/Private/Language/locallang_cache.xlf:module.label';
|
||||
return $this->getLanguageService()->sL($locallangFileAndPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function initializeModule(ServerRequestInterface $request): void
|
||||
{
|
||||
if ($this->configurationService->getConfigurationOption('cache', 'noCache')) {
|
||||
$this->getTypoScriptFrontendController()->set_no_cache('Admin Panel: No Caching', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getJavaScriptFiles(): array
|
||||
{
|
||||
return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Cache.js'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string array with css files that will be rendered after the module
|
||||
*
|
||||
* Example: return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Edit.css'];
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCssFiles(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules\Debug;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\Log\InMemoryLogWriter;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleSettingsProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
|
||||
use TYPO3\CMS\Core\Log\LogLevel;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
/**
|
||||
* Log Sub Module of the AdminPanel
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Log extends AbstractSubModule implements DataProviderInterface, ModuleSettingsProviderInterface, InitializableInterface
|
||||
{
|
||||
protected $logLevel = LogLevel::INFO;
|
||||
|
||||
/**
|
||||
* @var ConfigurationService
|
||||
*/
|
||||
protected $configurationService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'debug_log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-Module label
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.log.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDataToStore(ServerRequestInterface $request): ModuleData
|
||||
{
|
||||
$levels = [];
|
||||
for ($i = 1; $i <= LogLevel::DEBUG; $i++) {
|
||||
$levels[] = [
|
||||
'level' => $i,
|
||||
'levelName' => LogLevel::getName($i),
|
||||
];
|
||||
}
|
||||
|
||||
$log = InMemoryLogWriter::$log;
|
||||
|
||||
$logArray = [];
|
||||
/** @var \TYPO3\CMS\Core\Log\LogRecord $logRecord */
|
||||
foreach ($log as $logRecord) {
|
||||
$entry = $logRecord->toArray();
|
||||
// store only necessary info
|
||||
unset($entry['data']);
|
||||
$logArray[] = $entry;
|
||||
}
|
||||
return new ModuleData(
|
||||
[
|
||||
'levels' => $levels,
|
||||
'startLevel' => (int)$this->getConfigOption('startLevel'),
|
||||
'log' => $logArray,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSettings(): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Debug/LogSettings.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$levels = [];
|
||||
for ($i = 1; $i <= LogLevel::DEBUG; $i++) {
|
||||
$levels[] = [
|
||||
'level' => $i,
|
||||
'levelName' => LogLevel::getName($i),
|
||||
];
|
||||
}
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'levels' => $levels,
|
||||
'startLevel' => (int)$this->getConfigOption('startLevel'),
|
||||
'groupByComponent' => $this->getConfigOption('groupByComponent'),
|
||||
'groupByLevel' => $this->getConfigOption('groupByLevel'),
|
||||
]
|
||||
);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-Module content as rendered HTML
|
||||
*
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData $data
|
||||
* @return string
|
||||
*/
|
||||
public function getContent(ModuleData $data): string
|
||||
{
|
||||
$this->logLevel = $this->getConfigOption('startLevel');
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Debug/Log.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
$sortedLog = [];
|
||||
// settings for this module
|
||||
$groupByComponent = $this->getConfigOption('groupByComponent');
|
||||
$groupByLevel = $this->getConfigOption('groupByLevel');
|
||||
|
||||
foreach ($data['log'] as $logRecord) {
|
||||
if ($logRecord['level'] > $this->logLevel) {
|
||||
continue;
|
||||
}
|
||||
if ($groupByComponent && $groupByLevel) {
|
||||
$sortedLog[$logRecord['component']][LogLevel::getName($logRecord['level'])][] = $logRecord;
|
||||
} elseif ($groupByComponent) {
|
||||
$sortedLog[$logRecord['component']][] = $logRecord;
|
||||
} elseif ($groupByLevel) {
|
||||
$sortedLog[$logRecord['level']][] = $logRecord;
|
||||
} else {
|
||||
$sortedLog[] = $logRecord;
|
||||
}
|
||||
}
|
||||
$data['log'] = $sortedLog;
|
||||
$data['groupByComponent'] = $groupByComponent;
|
||||
$data['groupByLevel'] = $groupByLevel;
|
||||
$view->assignMultiple($data->getArrayCopy());
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function initializeModule(ServerRequestInterface $request): void
|
||||
{
|
||||
$this->logLevel = $this->getConfigOption('startLevel');
|
||||
|
||||
// set inMemoryLogWriter recursively for all configured namespaces/areas so we don't lose log entries
|
||||
$configWithInMemoryWriter = $this->setLoggingConfigRecursive($GLOBALS['TYPO3_CONF_VARS']['LOG'] ?? []);
|
||||
|
||||
// in case there are empty array parts, remove them
|
||||
$GLOBALS['TYPO3_CONF_VARS']['LOG'] = array_filter(
|
||||
$configWithInMemoryWriter
|
||||
);
|
||||
}
|
||||
|
||||
protected function setLoggingConfigRecursive(array $logConfig): array
|
||||
{
|
||||
foreach ($logConfig as $key => $value) {
|
||||
if ($key === 'writerConfiguration') {
|
||||
$logConfig[$key] = $value;
|
||||
$logConfig[$key][LogLevel::DEBUG][InMemoryLogWriter::class] = [];
|
||||
} elseif (is_array($value)) {
|
||||
$logConfig[$key] = $this->setLoggingConfigRecursive($value);
|
||||
}
|
||||
}
|
||||
return $logConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $option
|
||||
* @return string
|
||||
*/
|
||||
protected function getConfigOption(string $option): string
|
||||
{
|
||||
return $this->configurationService->getConfigurationOption('debug_log', $option);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules\Debug;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\Log\DoctrineSqlLogger;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
/**
|
||||
* Admin Panel Query Information module for showing SQL Queries
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class QueryInformation extends AbstractSubModule implements DataProviderInterface
|
||||
{
|
||||
/**
|
||||
* Identifier for this Sub-module,
|
||||
* for example "preview" or "cache"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'debug_queryinformation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-Module label
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function getDataToStore(ServerRequestInterface $request): ModuleData
|
||||
{
|
||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
$connection = $connectionPool->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
|
||||
$logger = $connection->getConfiguration()->getSQLLogger();
|
||||
$data = [];
|
||||
if ($logger instanceof DoctrineSqlLogger) {
|
||||
$queries = $logger->getQueries();
|
||||
$data['queries'] = $this->groupQueries($queries) ?? [];
|
||||
$data['totalTime'] = array_sum(array_column($queries, 'executionMS')) * 1000;
|
||||
}
|
||||
return new ModuleData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData $data
|
||||
* @return string Returns content of admin panel
|
||||
*/
|
||||
public function getContent(ModuleData $data): string
|
||||
{
|
||||
$view = new StandaloneView();
|
||||
$view->setTemplatePathAndFilename(
|
||||
'EXT:adminpanel/Resources/Private/Templates/Modules/Debug/QueryInformation.html'
|
||||
);
|
||||
$this->getLanguageService()->includeLLFile('EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf');
|
||||
$view->assignMultiple($data->getArrayCopy());
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $queries
|
||||
* @return array
|
||||
*/
|
||||
protected function groupQueries(array $queries): array
|
||||
{
|
||||
$groupedQueries = [];
|
||||
foreach ($queries as $query) {
|
||||
$identifier = sha1($query['sql']) . sha1(json_encode($query['backtrace']));
|
||||
if (is_array($query['params'])) {
|
||||
foreach ($query['params'] as $k => $param) {
|
||||
if (is_array($param)) {
|
||||
$query['params'][$k] = implode(',', $param);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($groupedQueries[$identifier])) {
|
||||
$groupedQueries[$identifier]['count']++;
|
||||
$groupedQueries[$identifier]['time'] += ($query['executionMS'] * 1000);
|
||||
$groupedQueries[$identifier]['queries'][] = $query;
|
||||
} else {
|
||||
$groupedQueries[$identifier] = [
|
||||
'sql' => $query['sql'],
|
||||
'time' => $query['executionMS'] * 1000,
|
||||
'count' => 1,
|
||||
'queries' => [
|
||||
$query,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
uasort(
|
||||
$groupedQueries,
|
||||
function ($a, $b) {
|
||||
return $b['time'] <=> $a['time'];
|
||||
}
|
||||
);
|
||||
return $groupedQueries;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\Log\InMemoryLogWriter;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
|
||||
use TYPO3\CMS\Core\Log\LogRecord;
|
||||
|
||||
/**
|
||||
* Debug Module of the AdminPanel
|
||||
*/
|
||||
class DebugModule extends AbstractModule implements ShortInfoProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'debug';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIconIdentifier(): string
|
||||
{
|
||||
return 'actions-debug';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:module.label'
|
||||
);
|
||||
}
|
||||
|
||||
public function getShortInfo(): string
|
||||
{
|
||||
$errorsAndWarnings = array_filter(InMemoryLogWriter::$log, function (LogRecord $entry) {
|
||||
return $entry->getLevel() <= 4;
|
||||
});
|
||||
return sprintf($this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:module.shortinfo'
|
||||
), count($errorsAndWarnings));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ResourceProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\Service\EditToolbarService;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Admin Panel Edit Module
|
||||
*/
|
||||
class EditModule extends AbstractModule implements PageSettingsProviderInterface, InitializableInterface, ResourceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Creates the content for the "edit" section ("module") of the Admin Panel
|
||||
*
|
||||
* @return string HTML content for the section. Consists of a string with table-rows with four columns.
|
||||
*/
|
||||
public function getPageSettings(): string
|
||||
{
|
||||
$editToolbarService = GeneralUtility::makeInstance(EditToolbarService::class);
|
||||
$toolbar = $editToolbarService->createToolbar();
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Settings/Edit.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'feEdit' => ExtensionManagementUtility::isLoaded('feedit'),
|
||||
'display' => [
|
||||
'fieldIcons' => $this->configurationService->getConfigurationOption('edit', 'displayFieldIcons'),
|
||||
'displayIcons' => $this->configurationService->getConfigurationOption('edit', 'displayIcons'),
|
||||
],
|
||||
'toolbar' => $toolbar,
|
||||
'script' => [
|
||||
'pageUid' => (int)$this->getTypoScriptFrontendController()->page['uid'],
|
||||
'pageModule' => $this->getPageModule(),
|
||||
'backendScript' => BackendUtility::getBackendScript(),
|
||||
't3BeSitenameMd5' => md5('Typo3Backend-' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']),
|
||||
],
|
||||
]
|
||||
);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getPageModule(): string
|
||||
{
|
||||
$pageModule = trim($this->getBackendUser()->getTSConfig()['options.']['overridePageModule'] ?? '');
|
||||
return BackendUtility::isModuleSetInTBE_MODULES($pageModule) ? $pageModule : 'web_layout';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'edit';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIconIdentifier(): string
|
||||
{
|
||||
return 'actions-open';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
$locallangFileAndPath = 'LLL:EXT:adminpanel/Resources/Private/Language/locallang_edit.xlf:module.label';
|
||||
return $this->getLanguageService()->sL($locallangFileAndPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the edit module
|
||||
* Includes the frontend edit initialization
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
*
|
||||
* @todo move into fe_edit (including the module)
|
||||
*/
|
||||
public function initializeModule(ServerRequestInterface $request): void
|
||||
{
|
||||
$extFeEditLoaded = ExtensionManagementUtility::isLoaded('feedit');
|
||||
$typoScriptFrontend = $this->getTypoScriptFrontendController();
|
||||
$typoScriptFrontend->displayEditIcons = $this->configurationService->getConfigurationOption('edit', 'displayIcons');
|
||||
$typoScriptFrontend->displayFieldEditIcons = $this->configurationService->getConfigurationOption('edit', 'displayFieldIcons');
|
||||
|
||||
if ($request->getQueryParams()['ADMCMD_editIcons'] ?? $request->getParsedBody()['ADMCMD_editIcons'] ?? false) {
|
||||
$typoScriptFrontend->displayFieldEditIcons = '1';
|
||||
}
|
||||
if ($extFeEditLoaded && $typoScriptFrontend->displayEditIcons) {
|
||||
$typoScriptFrontend->set_no_cache('Admin Panel: Display edit icons', true);
|
||||
}
|
||||
if ($extFeEditLoaded && $typoScriptFrontend->displayFieldEditIcons) {
|
||||
$typoScriptFrontend->set_no_cache('Admin Panel: Display field edit icons', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getJavaScriptFiles(): array
|
||||
{
|
||||
return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Edit.js'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string array with css files that will be rendered after the module
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCssFiles(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules\Info;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Context\UserAspect;
|
||||
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* General information module displaying info about the current
|
||||
* request
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class GeneralInformation extends AbstractSubModule implements DataProviderInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDataToStore(ServerRequestInterface $request): ModuleData
|
||||
{
|
||||
/** @var UserAspect $frontendUserAspect */
|
||||
$frontendUserAspect = GeneralUtility::makeInstance(Context::class)->getAspect('frontend.user');
|
||||
$tsfe = $this->getTypoScriptFrontendController();
|
||||
return new ModuleData(
|
||||
[
|
||||
'post' => $_POST,
|
||||
'get' => $_GET,
|
||||
'cookie' => $_COOKIE,
|
||||
'server' => $_SERVER,
|
||||
'info' => [
|
||||
'pageUid' => $tsfe->id,
|
||||
'pageType' => $tsfe->type,
|
||||
'groupList' => implode(',', $frontendUserAspect->getGroupIds()),
|
||||
'noCache' => $this->isNoCacheEnabled(),
|
||||
'countUserInt' => count($tsfe->config['INTincScript'] ?? []),
|
||||
'totalParsetime' => $this->getTimeTracker()->getParseTime(),
|
||||
'feUser' => [
|
||||
'uid' => $frontendUserAspect->get('id') ?: 0,
|
||||
'username' => $frontendUserAspect->get('username') ?: '',
|
||||
],
|
||||
'imagesOnPage' => $this->collectImagesOnPage(),
|
||||
'documentSize' => $this->collectDocumentSize(),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the content for the "info" section ("module") of the Admin Panel
|
||||
*
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleData $data
|
||||
* @return string HTML content for the section. Consists of a string with table-rows with four columns.
|
||||
* @see display()
|
||||
*/
|
||||
public function getContent(ModuleData $data): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Info/General.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$view->assignMultiple($data->getArrayCopy());
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifier for this Sub-module,
|
||||
* for example "preview" or "cache"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'info_general';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_info.xlf:sub.general.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects images from TypoScriptFrontendController and calculates the total size.
|
||||
* Returns human readable image sizes for fluid template output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function collectImagesOnPage(): array
|
||||
{
|
||||
$imagesOnPage = [
|
||||
'files' => [],
|
||||
'total' => 0,
|
||||
'totalSize' => 0,
|
||||
'totalSizeHuman' => GeneralUtility::formatSize(0),
|
||||
];
|
||||
|
||||
if ($this->isNoCacheEnabled() === false) {
|
||||
return $imagesOnPage;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
$totalImageSize = 0;
|
||||
if (!empty($this->getTypoScriptFrontendController()->imagesOnPage)) {
|
||||
foreach ($this->getTypoScriptFrontendController()->imagesOnPage as $file) {
|
||||
$fileSize = @filesize($file);
|
||||
$imagesOnPage['files'][] = [
|
||||
'name' => $file,
|
||||
'size' => $fileSize,
|
||||
'sizeHuman' => GeneralUtility::formatSize($fileSize),
|
||||
];
|
||||
$totalImageSize += $fileSize;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$imagesOnPage['totalSize'] = GeneralUtility::formatSize($totalImageSize);
|
||||
$imagesOnPage['total'] = $count;
|
||||
return $imagesOnPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the document size from the current page in a human readable format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function collectDocumentSize(): string
|
||||
{
|
||||
$documentSize = 0;
|
||||
if ($this->isNoCacheEnabled() === true) {
|
||||
$documentSize = mb_strlen($this->getTypoScriptFrontendController()->content, 'UTF-8');
|
||||
}
|
||||
|
||||
return GeneralUtility::formatSize($documentSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isNoCacheEnabled(): bool
|
||||
{
|
||||
return (bool)$this->getTypoScriptFrontendController()->no_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TimeTracker
|
||||
*/
|
||||
protected function getTimeTracker(): TimeTracker
|
||||
{
|
||||
return GeneralUtility::makeInstance(TimeTracker::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules\Info;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
/**
|
||||
* PhpInformation admin panel sub module
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class PhpInformation extends AbstractSubModule implements DataProviderInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'info_php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_info.xlf:sub.php.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDataToStore(ServerRequestInterface $request): ModuleData
|
||||
{
|
||||
return new ModuleData(
|
||||
[
|
||||
'general' => [
|
||||
'PHP_VERSION' => PHP_VERSION,
|
||||
'PHP_OS' => PHP_OS,
|
||||
'PHP_SAPI' => PHP_SAPI,
|
||||
'Peak Memory Usage' => GeneralUtility::formatSize(memory_get_peak_usage()),
|
||||
],
|
||||
'loadedExtensions' => implode(', ', get_loaded_extensions()),
|
||||
'constants' => get_defined_constants(true),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getContent(ModuleData $data): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Info/PhpInfo.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$view->assignMultiple($data->getArrayCopy());
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules\Info;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
|
||||
/**
|
||||
* RequestInformation submodule of the admin panel
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RequestInformation extends AbstractSubModule implements DataProviderInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'info-request';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_info.xlf:sub.request.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getDataToStore(ServerRequestInterface $request): ModuleData
|
||||
{
|
||||
return new ModuleData(
|
||||
[
|
||||
'post' => $_POST,
|
||||
'get' => $_GET,
|
||||
'cookie' => $_COOKIE,
|
||||
'session' => $_SESSION,
|
||||
'server' => $_SERVER,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getContent(ModuleData $data): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Info/RequestInformation.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$view->assignMultiple($data->getArrayCopy());
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
|
||||
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Admin Panel Info Module
|
||||
*/
|
||||
class InfoModule extends AbstractModule implements ShortInfoProviderInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIconIdentifier(): string
|
||||
{
|
||||
return 'actions-document-info';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'info';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_info.xlf:module.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getShortInfo(): string
|
||||
{
|
||||
$parseTime = $this->getTimeTracker()->getParseTime();
|
||||
return sprintf($this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_info.xlf:module.shortinfo'
|
||||
), $parseTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TimeTracker
|
||||
*/
|
||||
protected function getTimeTracker(): TimeTracker
|
||||
{
|
||||
return GeneralUtility::makeInstance(TimeTracker::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ResourceProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\Repositories\FrontendGroupsRepository;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Context\DateTimeAspect;
|
||||
use TYPO3\CMS\Core\Context\UserAspect;
|
||||
use TYPO3\CMS\Core\Context\VisibilityAspect;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Admin Panel Preview Module
|
||||
*/
|
||||
class PreviewModule extends AbstractModule implements InitializableInterface, PageSettingsProviderInterface, ResourceProviderInterface
|
||||
{
|
||||
/**
|
||||
* module configuration, set on initialize
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIconIdentifier(): string
|
||||
{
|
||||
return 'actions-preview';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'preview';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_preview.xlf:module.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function initializeModule(ServerRequestInterface $request): void
|
||||
{
|
||||
// Backend preview params (ADMCMD_) take precedence over configured admin panel values
|
||||
$simulateGroupByRequest = (int)($request->getQueryParams()['ADMCMD_simUser'] ?? 0);
|
||||
$simulateTimeByRequest = (int)($request->getQueryParams()['ADMCMD_simTime'] ?? 0);
|
||||
$this->config = [
|
||||
'showHiddenPages' => (bool)$this->getConfigOptionForModule('showHiddenPages'),
|
||||
'simulateDate' => $simulateTimeByRequest ?: (int)$this->getConfigOptionForModule('simulateDate'),
|
||||
'showHiddenRecords' => (bool)$this->getConfigOptionForModule('showHiddenRecords'),
|
||||
'simulateUserGroup' => $simulateGroupByRequest ?: (int)$this->getConfigOptionForModule('simulateUserGroup'),
|
||||
'showFluidDebug' => (bool)$this->getConfigOptionForModule('showFluidDebug'),
|
||||
];
|
||||
if ($this->config['showFluidDebug']) {
|
||||
// forcibly unset fluid caching as it does not care about the tsfe based caching settings
|
||||
unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['fluid_template']['frontend']);
|
||||
$GLOBALS['TSFE']->set_no_cache('Cache is disabled if fluid debugging is enabled', true);
|
||||
}
|
||||
$this->initializeFrontendPreview(
|
||||
$this->config['showHiddenPages'],
|
||||
$this->config['showHiddenRecords'],
|
||||
$this->config['simulateDate'],
|
||||
$this->config['simulateUserGroup']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getPageSettings(): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/Settings/Preview.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$frontendGroupsRepository = GeneralUtility::makeInstance(FrontendGroupsRepository::class);
|
||||
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'show' => [
|
||||
'pageId' => (int)$this->getTypoScriptFrontendController()->id,
|
||||
'hiddenPages' => $this->config['showHiddenPages'],
|
||||
'hiddenRecords' => $this->config['showHiddenRecords'],
|
||||
'fluidDebug' => $this->config['showFluidDebug'],
|
||||
],
|
||||
'simulateDate' => $this->config['simulateDate'],
|
||||
'frontendUserGroups' => [
|
||||
'availableGroups' => $frontendGroupsRepository->getAvailableFrontendUserGroups(),
|
||||
'selected' => (int)$this->config['simulateUserGroup'],
|
||||
],
|
||||
]
|
||||
);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $option
|
||||
* @return string
|
||||
*/
|
||||
protected function getConfigOptionForModule(string $option): string
|
||||
{
|
||||
return $this->configurationService->getConfigurationOption(
|
||||
'preview',
|
||||
$option
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize frontend preview functionality incl.
|
||||
* simulation of users or time
|
||||
*
|
||||
* @param bool $showHiddenPages
|
||||
* @param bool $showHiddenRecords
|
||||
* @param int $simulateDate
|
||||
* @param int $simulateUserGroup UID of the fe_group to simulate
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function initializeFrontendPreview(
|
||||
bool $showHiddenPages,
|
||||
bool $showHiddenRecords,
|
||||
int $simulateDate,
|
||||
int $simulateUserGroup
|
||||
): void {
|
||||
$context = GeneralUtility::makeInstance(Context::class);
|
||||
$typoScriptFrontendController = $this->getTypoScriptFrontendController();
|
||||
$typoScriptFrontendController->clear_preview();
|
||||
$typoScriptFrontendController->fePreview = 1;
|
||||
|
||||
// Modify visibility settings (hidden pages + hidden content)
|
||||
$context->setAspect(
|
||||
'visibility',
|
||||
GeneralUtility::makeInstance(VisibilityAspect::class, $showHiddenPages, $showHiddenRecords)
|
||||
);
|
||||
|
||||
// Simulate date
|
||||
$simTime = null;
|
||||
if ($simulateDate) {
|
||||
$simTime = $this->parseDate($simulateDate);
|
||||
if ($simTime) {
|
||||
$GLOBALS['SIM_EXEC_TIME'] = $simTime;
|
||||
$GLOBALS['SIM_ACCESS_TIME'] = $simTime - $simTime % 60;
|
||||
$context->setAspect(
|
||||
'date',
|
||||
GeneralUtility::makeInstance(
|
||||
DateTimeAspect::class,
|
||||
new \DateTimeImmutable('@' . $GLOBALS['SIM_EXEC_TIME'])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// simulate usergroup
|
||||
if ($simulateUserGroup) {
|
||||
$typoScriptFrontendController->simUserGroup = $simulateUserGroup;
|
||||
if (!$typoScriptFrontendController->fe_user instanceof FrontendUserAuthentication) {
|
||||
$typoScriptFrontendController->fe_user = GeneralUtility::makeInstance(
|
||||
FrontendUserAuthentication::class
|
||||
);
|
||||
}
|
||||
if (!is_array($typoScriptFrontendController->fe_user->user)) {
|
||||
// This can be removed once #90989 is fixed
|
||||
$typoScriptFrontendController->fe_user->user = ['uid' => PHP_INT_MAX];
|
||||
}
|
||||
$typoScriptFrontendController->fe_user->user[$typoScriptFrontendController->fe_user->usergroup_column] = $simulateUserGroup;
|
||||
$context->setAspect(
|
||||
'frontend.user',
|
||||
GeneralUtility::makeInstance(
|
||||
UserAspect::class,
|
||||
$typoScriptFrontendController->fe_user ?: null,
|
||||
[$simulateUserGroup]
|
||||
)
|
||||
);
|
||||
}
|
||||
if (!$simulateUserGroup && !$simTime && !$showHiddenPages && !$showHiddenRecords) {
|
||||
$typoScriptFrontendController->fePreview = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getJavaScriptFiles(): array
|
||||
{
|
||||
return ['EXT:adminpanel/Resources/Public/JavaScript/Modules/Preview.js'];
|
||||
}
|
||||
|
||||
/**
|
||||
* The simulated date needs to be a timestring (UTC)
|
||||
*
|
||||
* Simulation date is either set via configuration of AdminPanel (Date and Time Fields) or via ADMCMD_ $_GET
|
||||
* parameter from backend previews
|
||||
*
|
||||
* @param int $simulateDate
|
||||
* @return int
|
||||
*/
|
||||
protected function parseDate(int $simulateDate): ?int
|
||||
{
|
||||
try {
|
||||
$simTime = (new \DateTime('@' . $simulateDate))->getTimestamp();
|
||||
$simTime = max($simTime, 60);
|
||||
} catch (\Exception $e) {
|
||||
$simTime = null;
|
||||
}
|
||||
return $simTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string array with css files that will be rendered after the module
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCssFiles(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules\TsDebug;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleSettingsProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Class TypoScriptWaterfall
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TypoScriptWaterfall extends AbstractSubModule implements InitializableInterface, ModuleSettingsProviderInterface
|
||||
{
|
||||
/**
|
||||
* @var ConfigurationService
|
||||
*/
|
||||
protected $configurationService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'typoscript-waterfall';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_tsdebug.xlf:sub.waterfall.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function initializeModule(ServerRequestInterface $request): void
|
||||
{
|
||||
$typoScriptFrontend = $this->getTypoScriptFrontendController();
|
||||
$typoScriptFrontend->forceTemplateParsing = $this->getConfigurationOption(
|
||||
'forceTemplateParsing'
|
||||
);
|
||||
if ($typoScriptFrontend->forceTemplateParsing) {
|
||||
$typoScriptFrontend->set_no_cache('Admin Panel: Force template parsing', true);
|
||||
}
|
||||
$this->getTimeTracker()->LR = (bool)$this->getConfigurationOption('LR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the content for the "tsdebug" section ("module") of the Admin Panel
|
||||
*
|
||||
* @param ModuleData $data
|
||||
* @return string HTML
|
||||
*/
|
||||
public function getContent(ModuleData $data): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/TsDebug/TypoScript.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'tree' => (int)$this->getConfigurationOption('tree'),
|
||||
'display' => [
|
||||
'times' => (int)$this->getConfigurationOption('displayTimes'),
|
||||
'messages' => (int)$this->getConfigurationOption('displayMessages'),
|
||||
'content' => (int)$this->getConfigurationOption('displayContent'),
|
||||
],
|
||||
'trackContentRendering' => (int)$this->getConfigurationOption('LR'),
|
||||
'forceTemplateParsing' => (int)$this->getConfigurationOption('forceTemplateParsing'),
|
||||
'typoScriptLog' => $this->renderTypoScriptLog(),
|
||||
]
|
||||
);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getSettings(): string
|
||||
{
|
||||
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Modules/TsDebug/TypoScriptSettings.html';
|
||||
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
|
||||
$view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
|
||||
|
||||
$view->assignMultiple(
|
||||
[
|
||||
'tree' => (int)$this->getConfigurationOption('tree'),
|
||||
'display' => [
|
||||
'times' => (int)$this->getConfigurationOption('displayTimes'),
|
||||
'messages' => (int)$this->getConfigurationOption('displayMessages'),
|
||||
'content' => (int)$this->getConfigurationOption('displayContent'),
|
||||
],
|
||||
'trackContentRendering' => (int)$this->getConfigurationOption('LR'),
|
||||
'forceTemplateParsing' => (int)$this->getConfigurationOption('forceTemplateParsing')
|
||||
]
|
||||
);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current BE user.
|
||||
*
|
||||
* @return BackendUserAuthentication|FrontendBackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $option
|
||||
* @return bool
|
||||
*/
|
||||
protected function getConfigurationOption(string $option): bool
|
||||
{
|
||||
return (bool)$this->configurationService->getConfigurationOption('tsdebug', $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the TypoScript log as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderTypoScriptLog(): string
|
||||
{
|
||||
$timeTracker = $this->getTimeTracker();
|
||||
$timeTracker->printConf['flag_tree'] = $this->getConfigurationOption('tree');
|
||||
$timeTracker->printConf['allTime'] = $this->getConfigurationOption(
|
||||
'displayTimes'
|
||||
);
|
||||
$timeTracker->printConf['flag_messages'] = $this->getConfigurationOption(
|
||||
'displayMessages'
|
||||
);
|
||||
$timeTracker->printConf['flag_content'] = $this->getConfigurationOption(
|
||||
'displayContent'
|
||||
);
|
||||
return $timeTracker->printTSlog();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TimeTracker
|
||||
*/
|
||||
protected function getTimeTracker(): TimeTracker
|
||||
{
|
||||
return GeneralUtility::makeInstance(TimeTracker::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Modules;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
|
||||
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Admin Panel TypoScript Debug Module
|
||||
*/
|
||||
class TsDebugModule extends AbstractModule implements ShortInfoProviderInterface
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'tsdebug';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIconIdentifier(): string
|
||||
{
|
||||
return 'mimetypes-x-content-template-static';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getLabel(): string
|
||||
{
|
||||
return $this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_tsdebug.xlf:module.label'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getShortInfo(): string
|
||||
{
|
||||
$messageCount = 0;
|
||||
foreach ($this->getTimeTracker()->tsStackLog as $log) {
|
||||
$messageCount += count($log['message'] ?? []);
|
||||
}
|
||||
return sprintf(
|
||||
$this->getLanguageService()->sL(
|
||||
'LLL:EXT:adminpanel/Resources/Private/Language/locallang_tsdebug.xlf:module.shortinfo'
|
||||
),
|
||||
$messageCount
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TimeTracker
|
||||
*/
|
||||
protected function getTimeTracker(): TimeTracker
|
||||
{
|
||||
return GeneralUtility::makeInstance(TimeTracker::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Repositories;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Admin Panel Frontend Groups Repository
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FrontendGroupsRepository
|
||||
{
|
||||
/**
|
||||
* returns an array of all available frontend user groups including hidden ones.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAvailableFrontendUserGroups(): array
|
||||
{
|
||||
$optionCount = $this->getUserGroupOptionCountByBackendUser($this->getBackendUser());
|
||||
|
||||
$frontendGroups = [];
|
||||
if ($optionCount > 0) {
|
||||
$frontendGroups = $this->getUserGroupsForPagesByBackendUser($this->getBackendUser());
|
||||
}
|
||||
|
||||
return $frontendGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches the amount of user groups
|
||||
*
|
||||
* @param FrontendBackendUserAuthentication $beUser
|
||||
* @return int
|
||||
*/
|
||||
protected function getUserGroupOptionCountByBackendUser(FrontendBackendUserAuthentication $beUser): int
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('fe_groups');
|
||||
|
||||
$queryBuilder->getRestrictions()
|
||||
->removeAll()
|
||||
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
|
||||
$optionCount = $queryBuilder->count('fe_groups.uid')
|
||||
->from('fe_groups', 'fe_groups')
|
||||
->innerJoin(
|
||||
'fe_groups',
|
||||
'pages',
|
||||
'pages',
|
||||
$queryBuilder->expr()->eq('pages.uid', $queryBuilder->quoteIdentifier('fe_groups.pid'))
|
||||
)
|
||||
->where(
|
||||
$beUser->getPagePermsClause(Permission::PAGE_SHOW)
|
||||
)
|
||||
->execute()
|
||||
->fetchColumn(0);
|
||||
|
||||
return (int)$optionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches all frontend user groups, except deleted, for pages
|
||||
*
|
||||
* @param FrontendBackendUserAuthentication $beUser
|
||||
* @return array
|
||||
*/
|
||||
protected function getUserGroupsForPagesByBackendUser(FrontendBackendUserAuthentication $beUser): array
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('fe_groups');
|
||||
|
||||
$queryBuilder->getRestrictions()
|
||||
->removeAll()
|
||||
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
|
||||
return $queryBuilder->select('fe_groups.uid', 'fe_groups.title')
|
||||
->from('fe_groups')
|
||||
->innerJoin(
|
||||
'fe_groups',
|
||||
'pages',
|
||||
'pages',
|
||||
$queryBuilder->expr()->eq('pages.uid', $queryBuilder->quoteIdentifier('fe_groups.pid'))
|
||||
)
|
||||
->where(
|
||||
$beUser->getPagePermsClause(Permission::PAGE_SHOW)
|
||||
)
|
||||
->orderBy('fe_groups.title')
|
||||
->execute()
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current BE user.
|
||||
*
|
||||
* @return FrontendBackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser(): FrontendBackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Service;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\OnSubmitActorInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
/**
|
||||
* Admin Panel Service Class for Configuration Handling
|
||||
*
|
||||
* Scope: User TSConfig + Backend User UC
|
||||
*/
|
||||
class ConfigurationService implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mainConfiguration;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->mainConfiguration = $this->getBackendUser()->getTSConfig()['admPanel.'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MainConfiguration (User TSConfig admPanel)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMainConfiguration(): array
|
||||
{
|
||||
return $this->mainConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to return configuration options
|
||||
* Checks User TSConfig overrides and current backend user session
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param string $option
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigurationOption(string $identifier, string $option): string
|
||||
{
|
||||
if ($identifier === '' || $option === '') {
|
||||
throw new \InvalidArgumentException('Identifier and option may not be empty', 1532861423);
|
||||
}
|
||||
|
||||
if (isset($this->mainConfiguration['override.'][$identifier . '.'][$option])) {
|
||||
$returnValue = $this->mainConfiguration['override.'][$identifier . '.'][$option];
|
||||
} else {
|
||||
$returnValue = $this->getBackendUser()->uc['AdminPanel'][$identifier . '_' . $option] ?? '';
|
||||
}
|
||||
|
||||
return (string)$returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save admin panel configuration to backend user UC
|
||||
* triggers onSubmit method of modules to enable each module
|
||||
* to enhance the save action
|
||||
*
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[] $modules
|
||||
* @param ServerRequestInterface $request
|
||||
*/
|
||||
public function saveConfiguration(array $modules, ServerRequestInterface $request): void
|
||||
{
|
||||
$configurationToSave = $request->getParsedBody()['TSFE_ADMIN_PANEL'] ?? [];
|
||||
$beUser = $this->getBackendUser();
|
||||
$this->triggerOnSubmitActors($modules, $request, $configurationToSave);
|
||||
|
||||
$existingConfiguration = $beUser->uc['AdminPanel'] ?? [];
|
||||
$existingConfiguration = is_array($existingConfiguration) ? $existingConfiguration : [];
|
||||
|
||||
// Settings
|
||||
$beUser->uc['AdminPanel'] = array_merge($existingConfiguration, $configurationToSave);
|
||||
unset($beUser->uc['AdminPanel']['action']);
|
||||
// Saving
|
||||
$beUser->writeUC();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current BE user.
|
||||
*
|
||||
* @return BackendUserAuthentication|FrontendBackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $modules
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request
|
||||
* @param $configurationToSave
|
||||
*/
|
||||
protected function triggerOnSubmitActors(
|
||||
array $modules,
|
||||
ServerRequestInterface $request,
|
||||
$configurationToSave
|
||||
): void {
|
||||
foreach ($modules as $module) {
|
||||
if (
|
||||
$module instanceof OnSubmitActorInterface
|
||||
&& (
|
||||
($module instanceof ConfigurableInterface && $module->isEnabled())
|
||||
|| !($module instanceof ConfigurableInterface)
|
||||
)
|
||||
) {
|
||||
$module->onSubmit($configurationToSave, $request);
|
||||
}
|
||||
if ($module instanceof SubmoduleProviderInterface) {
|
||||
$this->triggerOnSubmitActors($module->getSubModules(), $request, $configurationToSave);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Service;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Context\LanguageAspect;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Class for the Edit Toolbar
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class EditToolbarService
|
||||
{
|
||||
|
||||
/**
|
||||
* Creates the tool bar links for the "edit" section of the Admin Panel.
|
||||
*
|
||||
* @return string A string containing images wrapped in <a>-tags linking them to proper functions.
|
||||
*/
|
||||
public function createToolbar(): string
|
||||
{
|
||||
/** @var LanguageAspect $languageAspect */
|
||||
$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
|
||||
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
$tsfe = $this->getTypoScriptFrontendController();
|
||||
// If mod.newContentElementWizard.override is set, use that extension's create new content wizard instead:
|
||||
$moduleName = BackendUtility::getPagesTSconfig($tsfe->page['uid'])['mod.']['newContentElementWizard.']['override'] ?? 'new_content_element';
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
$perms = $this->getBackendUser()->calcPerms($tsfe->page);
|
||||
$langAllowed = $this->getBackendUser()->checkLanguageAccess($languageAspect->getId());
|
||||
$id = $tsfe->id;
|
||||
$returnUrl = GeneralUtility::getIndpEnv('REQUEST_URI');
|
||||
$classes = 'typo3-adminPanel-btn typo3-adminPanel-btn-default';
|
||||
$output = [];
|
||||
$output[] = '<div class="typo3-adminPanel-form-group">';
|
||||
$output[] = ' <div class="typo3-adminPanel-btn-group" role="group">';
|
||||
|
||||
// History
|
||||
$link = (string)$uriBuilder->buildUriFromRoute(
|
||||
'record_history',
|
||||
[
|
||||
'element' => 'pages:' . $id,
|
||||
'returnUrl' => $returnUrl,
|
||||
]
|
||||
);
|
||||
$title = $this->getLabel('edit_recordHistory');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'#latest" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $iconFactory->getIcon('actions-document-history-open', Icon::SIZE_SMALL)->render();
|
||||
$output[] = '</a>';
|
||||
|
||||
// New Content
|
||||
if ($perms & Permission::CONTENT_EDIT && $langAllowed) {
|
||||
$linkParameters = [
|
||||
'id' => $id,
|
||||
'returnUrl' => $returnUrl,
|
||||
];
|
||||
if (!empty($languageAspect->getId())) {
|
||||
$linkParameters['sys_language_uid'] = $languageAspect->getId();
|
||||
}
|
||||
$link = (string)$uriBuilder->buildUriFromRoute($moduleName, $linkParameters);
|
||||
$icon = $iconFactory->getIcon('actions-add', Icon::SIZE_SMALL)->render();
|
||||
$title = $this->getLabel('edit_newContentElement');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $icon;
|
||||
$output[] = '</a>';
|
||||
}
|
||||
|
||||
// Move Page
|
||||
if ($perms & Permission::PAGE_EDIT) {
|
||||
$link = (string)$uriBuilder->buildUriFromRoute(
|
||||
'move_element',
|
||||
[
|
||||
'table' => 'pages',
|
||||
'uid' => $id,
|
||||
'returnUrl' => $returnUrl,
|
||||
]
|
||||
);
|
||||
$icon = $iconFactory->getIcon('actions-document-move', Icon::SIZE_SMALL)->render();
|
||||
$title = $this->getLabel('edit_move_page');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $icon;
|
||||
$output[] = '</a>';
|
||||
}
|
||||
|
||||
// New Page
|
||||
if ($perms & Permission::PAGE_NEW) {
|
||||
$link = (string)$uriBuilder->buildUriFromRoute(
|
||||
'db_new',
|
||||
[
|
||||
'id' => $id,
|
||||
'pagesOnly' => 1,
|
||||
'returnUrl' => $returnUrl,
|
||||
]
|
||||
);
|
||||
$icon = $iconFactory->getIcon('actions-page-new', Icon::SIZE_SMALL)->render();
|
||||
$title = $this->getLabel('edit_newPage');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $icon;
|
||||
$output[] = '</a>';
|
||||
}
|
||||
|
||||
// Edit Page
|
||||
if ($perms & Permission::PAGE_EDIT) {
|
||||
$link = (string)$uriBuilder->buildUriFromRoute(
|
||||
'record_edit',
|
||||
[
|
||||
'edit[pages][' . $id . ']' => 'edit',
|
||||
'noView' => 1,
|
||||
'returnUrl' => $returnUrl,
|
||||
]
|
||||
);
|
||||
$icon = $iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)->render();
|
||||
$title = $this->getLabel('edit_editPageProperties');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $icon;
|
||||
$output[] = '</a>';
|
||||
}
|
||||
|
||||
// Edit Page Overlay
|
||||
if ($perms & Permission::PAGE_EDIT && $languageAspect->getId() > 0 && $langAllowed) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('pages');
|
||||
$queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
|
||||
$row = $queryBuilder
|
||||
->select('uid', 'pid', 't3ver_state')
|
||||
->from('pages')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
|
||||
$queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
$GLOBALS['TCA']['pages']['ctrl']['languageField'],
|
||||
$queryBuilder->createNamedParameter($languageAspect->getId(), \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->setMaxResults(1)
|
||||
->execute()
|
||||
->fetch();
|
||||
$tsfe->sys_page->versionOL('pages', $row);
|
||||
if (is_array($row)) {
|
||||
$link = (string)$uriBuilder->buildUriFromRoute(
|
||||
'record_edit',
|
||||
[
|
||||
'edit[pages][' . $row['uid'] . ']' => 'edit',
|
||||
'noView' => 1,
|
||||
'returnUrl' => $returnUrl,
|
||||
]
|
||||
);
|
||||
$icon = $iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)
|
||||
->render();
|
||||
$title = $this->getLabel('edit_editPageOverlay');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $icon;
|
||||
$output[] = '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
// Open list view
|
||||
if ($this->getBackendUser()->check('modules', 'web_list')) {
|
||||
$link = (string)$uriBuilder->buildUriFromRoute(
|
||||
'web_list',
|
||||
[
|
||||
'id' => $id,
|
||||
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI'),
|
||||
]
|
||||
);
|
||||
$icon = $iconFactory->getIcon('actions-system-list-open', Icon::SIZE_SMALL)->render();
|
||||
$title = $this->getLabel('edit_db_list');
|
||||
$output[] = '<a class="' .
|
||||
$classes .
|
||||
'" href="' .
|
||||
htmlspecialchars($link, ENT_QUOTES | ENT_HTML5) .
|
||||
'" title="' .
|
||||
$title .
|
||||
'">';
|
||||
$output[] = ' ' . $icon;
|
||||
$output[] = '</a>';
|
||||
}
|
||||
|
||||
$output[] = ' </div>';
|
||||
$output[] = '</div>';
|
||||
return implode('', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate given key
|
||||
*
|
||||
* @param string $key Key for a label in the $LOCAL_LANG array of "sysext/core/Resources/Private/Language/locallang_tsfe.xlf
|
||||
* @return string The value for the $key
|
||||
*/
|
||||
protected function getLabel($key): ?string
|
||||
{
|
||||
return htmlspecialchars($this->getLanguageService()->getLL($key), ENT_QUOTES | ENT_HTML5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FrontendBackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser(): FrontendBackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Service;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\Exceptions\InvalidConfigurationException;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
|
||||
use TYPO3\CMS\Core\Service\DependencyOrderingService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Admin Panel Module Loader
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ModuleLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* Validates, sorts and initiates the registered modules
|
||||
*
|
||||
* @param array $modules
|
||||
* @return \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[]
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function validateSortAndInitializeModules(array $modules): array
|
||||
{
|
||||
if (empty($modules)) {
|
||||
return [];
|
||||
}
|
||||
foreach ($modules as $identifier => $configuration) {
|
||||
if (empty($configuration) || !is_array($configuration)) {
|
||||
throw new InvalidConfigurationException(
|
||||
'Missing configuration for module "' . $identifier . '".',
|
||||
1519490105
|
||||
);
|
||||
}
|
||||
if (!is_string($configuration['module']) ||
|
||||
empty($configuration['module']) ||
|
||||
!class_exists($configuration['module']) ||
|
||||
!is_subclass_of(
|
||||
$configuration['module'],
|
||||
ModuleInterface::class,
|
||||
true
|
||||
)
|
||||
) {
|
||||
throw new InvalidConfigurationException(
|
||||
'The module "' .
|
||||
$identifier .
|
||||
'" defines an invalid module class. Ensure the class exists and implements the "' .
|
||||
ModuleInterface::class .
|
||||
'".',
|
||||
1519490112
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$orderedModules = GeneralUtility::makeInstance(DependencyOrderingService::class)->orderByDependencies(
|
||||
$modules
|
||||
);
|
||||
|
||||
$moduleInstances = [];
|
||||
foreach ($orderedModules as $moduleConfiguration) {
|
||||
$module = GeneralUtility::makeInstance($moduleConfiguration['module']);
|
||||
if (
|
||||
$module instanceof ModuleInterface
|
||||
&& (
|
||||
($module instanceof ConfigurableInterface && $module->isEnabled())
|
||||
|| !($module instanceof ConfigurableInterface)
|
||||
)
|
||||
) {
|
||||
$moduleInstances[$module->getIdentifier()] = $module;
|
||||
}
|
||||
if ($module instanceof SubmoduleProviderInterface) {
|
||||
$subModuleInstances = $this->validateSortAndInitializeModules($moduleConfiguration['submodules'] ?? []);
|
||||
$module->setSubModules($subModuleInstances);
|
||||
}
|
||||
}
|
||||
return $moduleInstances;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Utility;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Helper class to keep track of memory consumption in loggers to reduce risk of running out of memory
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class MemoryUtility
|
||||
{
|
||||
private const MINIMAL_PERCENT_OF_FREE_MEMORY = 0.30;
|
||||
|
||||
/**
|
||||
* Checks memory usage used in current process - this is no guarantee for not running out of memory
|
||||
* but should prevent memory exhaustion due to the admin panel in most cases.
|
||||
* The loggers will stop logging once the amount of free memory falls below the threshold (see
|
||||
* MINIMAL_PERCENT_OF_FREE_MEMORY const).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isMemoryConsumptionTooHigh(): bool
|
||||
{
|
||||
$iniLimit = ini_get('memory_limit');
|
||||
$memoryLimit = $iniLimit === '-1' ? -1 : GeneralUtility::getBytesFromSizeMeasurement($iniLimit);
|
||||
$freeMemory = $memoryLimit - memory_get_usage(true);
|
||||
|
||||
return $memoryLimit > 0 && $freeMemory < (self::MINIMAL_PERCENT_OF_FREE_MEMORY * $memoryLimit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Utility;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ResourceProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
class ResourceUtility
|
||||
{
|
||||
/**
|
||||
* Get additional resources (css, js) from modules and merge it to
|
||||
* one array - returns an array of full html tags
|
||||
*
|
||||
* @param \TYPO3\CMS\Adminpanel\ModuleApi\ResourceProviderInterface[] $modules
|
||||
* @return array
|
||||
*/
|
||||
public static function getAdditionalResourcesForModules(array $modules): array
|
||||
{
|
||||
$result = [
|
||||
'js' => '',
|
||||
'css' => '',
|
||||
];
|
||||
foreach ($modules as $module) {
|
||||
if ($module instanceof ResourceProviderInterface) {
|
||||
foreach ($module->getJavaScriptFiles() as $file) {
|
||||
$result['js'] .= static::getJsTag($file);
|
||||
}
|
||||
foreach ($module->getCssFiles() as $file) {
|
||||
$result['css'] .= static::getCssTag($file);
|
||||
}
|
||||
}
|
||||
if ($module instanceof SubmoduleProviderInterface) {
|
||||
$subResult = self::getAdditionalResourcesForModules($module->getSubModules());
|
||||
$result['js'] .= $subResult['js'];
|
||||
$result['css'] .= $subResult['css'];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getAdditionalResourcesForModule(ResourceProviderInterface $module): array
|
||||
{
|
||||
$result = [
|
||||
'js' => '',
|
||||
'css' => '',
|
||||
];
|
||||
foreach ($module->getJavaScriptFiles() as $file) {
|
||||
$result['js'] .= static::getJsTag($file);
|
||||
}
|
||||
foreach ($module->getCssFiles() as $file) {
|
||||
$result['css'] .= static::getCssTag($file);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a link tag with the admin panel stylesheet
|
||||
* defined using TBE_STYLES
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getAdminPanelStylesheet(): string
|
||||
{
|
||||
$result = '';
|
||||
if (!empty($GLOBALS['TBE_STYLES']['stylesheets']['admPanel'])) {
|
||||
$stylesheet = GeneralUtility::locationHeaderUrl($GLOBALS['TBE_STYLES']['stylesheets']['admPanel']);
|
||||
$result = '<link rel="stylesheet" type="text/css" href="' .
|
||||
htmlspecialchars($stylesheet, ENT_QUOTES | ENT_HTML5) . '" />';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a css tag for file - with absolute web path resolving
|
||||
*
|
||||
* @param string $cssFileLocation
|
||||
* @return string
|
||||
*/
|
||||
protected static function getCssTag(string $cssFileLocation): string
|
||||
{
|
||||
$css = '<link type="text/css" rel="stylesheet" href="' .
|
||||
htmlspecialchars(
|
||||
PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName($cssFileLocation)),
|
||||
ENT_QUOTES | ENT_HTML5
|
||||
) .
|
||||
'" media="all" />';
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a script tag for JavaScript with absolute paths
|
||||
*
|
||||
* @param string $jsFileLocation
|
||||
* @return string
|
||||
*/
|
||||
protected static function getJsTag(string $jsFileLocation): string
|
||||
{
|
||||
$js = '<script type="text/javascript" src="' .
|
||||
htmlspecialchars(
|
||||
PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName($jsFileLocation)),
|
||||
ENT_QUOTES | ENT_HTML5
|
||||
) .
|
||||
'"></script>';
|
||||
return $js;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string with tags for main admin panel resources
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getResources(): array
|
||||
{
|
||||
$jsFileLocation = 'EXT:adminpanel/Resources/Public/JavaScript/AdminPanel.js';
|
||||
$js = ResourceUtility::getJsTag($jsFileLocation);
|
||||
$cssFileLocation = 'EXT:adminpanel/Resources/Public/Css/adminpanel.css';
|
||||
$css = ResourceUtility::getCssTag($cssFileLocation);
|
||||
|
||||
return [
|
||||
'css' => $css . ResourceUtility::getAdminPanelStylesheet(),
|
||||
'js' => $js,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\Utility;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
|
||||
/**
|
||||
* Helper class to check if the admin panel is enabled and active from outside
|
||||
*
|
||||
* Useful for initialization, checks in early hooks or middleware implementations
|
||||
*/
|
||||
class StateUtility
|
||||
{
|
||||
/**
|
||||
* Checks if adminPanel was configured to be shown
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isActivatedForUser(): bool
|
||||
{
|
||||
$beUser = $GLOBALS['BE_USER'] ?? null;
|
||||
if ($beUser instanceof FrontendBackendUserAuthentication) {
|
||||
$adminPanelConfiguration = $beUser->getTSConfig()['admPanel.'] ?? [];
|
||||
// set legacy config
|
||||
$beUser->extAdminConfig = $adminPanelConfiguration;
|
||||
if (isset($adminPanelConfiguration['enable.'])) {
|
||||
// only enabled if at least one module is enabled.
|
||||
return (bool)array_filter($adminPanelConfiguration['enable.']);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if admin panel was activated
|
||||
* (switched "on" via GUI)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isOpen(): bool
|
||||
{
|
||||
$beUser = $GLOBALS['BE_USER'] ?? null;
|
||||
return (bool)($beUser->uc['AdminPanel']['display_top'] ?? false);
|
||||
}
|
||||
|
||||
public static function isActivatedInTypoScript(): bool
|
||||
{
|
||||
return (bool)($GLOBALS['TSFE']->config['config']['admPanel'] ?? false);
|
||||
}
|
||||
|
||||
public static function isHiddenForUser(): bool
|
||||
{
|
||||
return (bool)($GLOBALS['BE_USER']->extAdminConfig['hide'] ?? false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,480 @@
|
||||
<?php
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\View;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface;
|
||||
use TYPO3\CMS\Adminpanel\Service\EditToolbarService;
|
||||
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
|
||||
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
/**
|
||||
* View class for the admin panel in frontend editing.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class AdminPanelView
|
||||
{
|
||||
/**
|
||||
* Force preview
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $ext_forcePreview = false;
|
||||
|
||||
/**
|
||||
* Array of adminPanel modules
|
||||
*
|
||||
* @var \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[]
|
||||
*/
|
||||
protected $modules = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* Setter for injecting new-style modules
|
||||
*
|
||||
* @see \TYPO3\CMS\Adminpanel\Controller\MainController::render()
|
||||
* @param array $modules
|
||||
* @internal
|
||||
*/
|
||||
public function setModules(array $modules): void
|
||||
{
|
||||
$this->modules = $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns LanguageService
|
||||
*
|
||||
* @return \TYPO3\CMS\Core\Localization\LanguageService
|
||||
*/
|
||||
protected function getLanguageService()
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current BE user.
|
||||
*
|
||||
* @return FrontendBackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Admin Panel: Deprecated API
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
* Backwards compatibility method ensuring hook still gets the same content as before
|
||||
*
|
||||
* @deprecated since TYPO3 v9 - remove when hook can be removed
|
||||
* @internal
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public function callDeprecatedHookObject(): string
|
||||
{
|
||||
$moduleContent = '';
|
||||
if (StateUtility::isOpen()) {
|
||||
foreach ($this->modules as $module) {
|
||||
$moduleContent .= $this->getModule($module);
|
||||
}
|
||||
|
||||
foreach (
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_adminpanel.php']['extendAdminPanel']
|
||||
??
|
||||
[] as $className
|
||||
) {
|
||||
trigger_error(
|
||||
'The hook $GLOBALS[TYPO3_CONF_VARS][SC_OPTIONS][tslib/class.tslib_adminpanel.php][extendAdminPanel] will be removed in TYPO3 v10.0, register an AdminPanelModule instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$hookObject = GeneralUtility::makeInstance($className);
|
||||
if (!$hookObject instanceof AdminPanelViewHookInterface) {
|
||||
throw new \UnexpectedValueException(
|
||||
$className . ' must implement interface ' . AdminPanelViewHookInterface::class,
|
||||
1311942539
|
||||
);
|
||||
}
|
||||
$content = $hookObject->extendAdminPanel($moduleContent, $this);
|
||||
if ($content) {
|
||||
$moduleContent .= '<div class="typo3-adminPanel-section typo3-adminPanel-section-open">';
|
||||
$moduleContent .= ' <div class="typo3-adminPanel-section-body">';
|
||||
$moduleContent .= ' ' . $content;
|
||||
$moduleContent .= ' </div>';
|
||||
$moduleContent .= '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $moduleContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single module with header panel
|
||||
*
|
||||
* @deprecated since TYPO3 v9 - only used in deprecated hook call (which triggers the corresponding deprecation error)
|
||||
* @param ModuleInterface $module
|
||||
* @return string
|
||||
*/
|
||||
protected function getModule(ModuleInterface $module): string
|
||||
{
|
||||
$output = [];
|
||||
|
||||
if ($module instanceof ConfigurableInterface && $module->isEnabled()) {
|
||||
$output[] = '<div class="typo3-adminPanel-section typo3-adminPanel-section-open">';
|
||||
$output[] = ' <div class="typo3-adminPanel-section-title">';
|
||||
$output[] = ' ' . $this->getSectionOpenerLink($module);
|
||||
$output[] = ' </div>';
|
||||
$output[] = '<div class="typo3-adminPanel-section-body">';
|
||||
$output[] = ' ' . $module->getContent();
|
||||
$output[] = '</div>';
|
||||
$output[] = '</div>';
|
||||
}
|
||||
|
||||
if ($module instanceof DataProviderInterface) {
|
||||
foreach ($module->getJavaScriptFiles() as $javaScriptFile) {
|
||||
$output[] =
|
||||
'<script src="' .
|
||||
PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName($javaScriptFile)) .
|
||||
'"></script>';
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $output);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Admin Panel Layout Helper functions
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
* Wraps a string in a link which will open/close a certain part of the Admin Panel
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Only used in deprecated hook call (which triggers the corresponding deprecation error)
|
||||
* @param ModuleInterface $module
|
||||
* @return string
|
||||
*/
|
||||
protected function getSectionOpenerLink(ModuleInterface $module): string
|
||||
{
|
||||
$identifier = $module->getIdentifier();
|
||||
$onclick = 'document.TSFE_ADMIN_PANEL_FORM[' .
|
||||
GeneralUtility::quoteJSvalue('TSFE_ADMIN_PANEL[display_' . $identifier . ']') .
|
||||
'].value=' .
|
||||
($this->getBackendUser()->uc['AdminPanel']['display_' . $identifier] ? '0' : '1') .
|
||||
';document.TSFE_ADMIN_PANEL_FORM.submit();return false;';
|
||||
|
||||
$output = [];
|
||||
$output[] = '<span class="typo3-adminPanel-section-title-identifier"></span>';
|
||||
$output[] = '<a href="javascript:void(0)" onclick="' . htmlspecialchars($onclick) . '">';
|
||||
$output[] = ' ' . htmlspecialchars($module->getLabel());
|
||||
$output[] = '</a>';
|
||||
$output[] = '<input type="hidden" name="TSFE_ADMIN_PANEL[display_' .
|
||||
$identifier .
|
||||
']" value="' .
|
||||
1 .
|
||||
'" />';
|
||||
|
||||
return implode('', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the tool bar links for the "edit" section of the Admin Panel.
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Use EditToolbarService instead or create buttons via fluid
|
||||
* @return string A string containing images wrapped in <a>-tags linking them to proper functions.
|
||||
*/
|
||||
public function ext_makeToolBar(): string
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView::ext_makeToolBar() will be removed in TYPO3 v10.0, use fluid and backend uri builder to create a toolbar.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$editToolbarService = GeneralUtility::makeInstance(EditToolbarService::class);
|
||||
return $editToolbarService->createToolbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate given key
|
||||
*
|
||||
* @param string $key Key for a label in the $LOCAL_LANG array of "EXT:core/Resources/Private/Language/locallang_tsfe.xlf
|
||||
* @param bool $convertWithHtmlspecialchars If TRUE the language-label will be sent through htmlspecialchars
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - only used in deprecated methods
|
||||
* @return string The value for the $key
|
||||
*/
|
||||
protected function extGetLL($key, $convertWithHtmlspecialchars = true)
|
||||
{
|
||||
$labelStr = $this->getLanguageService()->getLL($key);
|
||||
if ($convertWithHtmlspecialchars) {
|
||||
$labelStr = htmlspecialchars($labelStr);
|
||||
}
|
||||
return $labelStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an additional stylesheet
|
||||
*
|
||||
* @return string
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
|
||||
*/
|
||||
public function getAdminPanelHeaderData()
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->getAdminPanelHeaderData() will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$result = '';
|
||||
if (!empty($GLOBALS['TBE_STYLES']['stylesheets']['admPanel'])) {
|
||||
$stylesheet = GeneralUtility::locationHeaderUrl($GLOBALS['TBE_STYLES']['stylesheets']['admPanel']);
|
||||
$result = '<link rel="stylesheet" type="text/css" href="' .
|
||||
htmlspecialchars($stylesheet, ENT_QUOTES | ENT_HTML5) . '" />';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an Admin Panel section ("module") is available for the user. If so, TRUE is returned.
|
||||
*
|
||||
* @param string $key The module key, eg. "edit", "preview", "info" etc.
|
||||
* @return bool
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
|
||||
*/
|
||||
public function isAdminModuleEnabled($key)
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->isAdminModuleEnabled() will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$result = false;
|
||||
// Returns TRUE if the module checked is "preview" and the forcePreview flag is set.
|
||||
if ($key === 'preview' && $this->ext_forcePreview) {
|
||||
$result = true;
|
||||
} elseif (!empty($this->configuration['enable.']['all'])) {
|
||||
$result = true;
|
||||
} elseif (!empty($this->configuration['enable.'][$key])) {
|
||||
$result = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any change in settings made in the Admin Panel.
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
|
||||
*/
|
||||
public function saveConfigOptions()
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->saveConfigOptions() will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$input = GeneralUtility::_GP('TSFE_ADMIN_PANEL');
|
||||
$beUser = $this->getBackendUser();
|
||||
if (is_array($input)) {
|
||||
// Setting
|
||||
$beUser->uc['AdminPanel'] = array_merge(
|
||||
!is_array($beUser->uc['AdminPanel']) ? [] : $beUser->uc['AdminPanel'],
|
||||
$input
|
||||
);
|
||||
unset($beUser->uc['AdminPanel']['action']);
|
||||
|
||||
foreach ($this->modules as $module) {
|
||||
if ($module->isEnabled()) {
|
||||
// We use TYPO3_REQUEST for compatibility reasons. The object and this method are deprecated anyway, this should be fine.
|
||||
$module->onSubmit($input, $GLOBALS['TYPO3_REQUEST']);
|
||||
}
|
||||
}
|
||||
// Saving
|
||||
$beUser->writeUC();
|
||||
// Flush fluid template cache
|
||||
$cacheManager = new CacheManager();
|
||||
$cacheManager->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
|
||||
$cacheManager->getCache('fluid_template')->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for an Admin Panel setting.
|
||||
*
|
||||
* @param string $sectionName Module key
|
||||
* @param string $val Setting key
|
||||
* @return mixed The setting value
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - implement AdminPanelModules via the new API (see AdminPanelModuleInterface)
|
||||
*/
|
||||
public function extGetFeAdminValue($sectionName, $val = '')
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->extGetFeAdminValue() will be removed in TYPO3 v10.0. Implement AdminPanelModules via the new API (see AdminPanelModuleInterface).',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
if (!$this->isAdminModuleEnabled($sectionName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$beUser = $this->getBackendUser();
|
||||
// Exceptions where the values can be overridden (forced) from backend:
|
||||
// deprecated
|
||||
if (
|
||||
$sectionName === 'edit' && (
|
||||
$val === 'displayIcons' && $this->configuration['module.']['edit.']['forceDisplayIcons'] ||
|
||||
$val === 'displayFieldIcons' && $this->configuration['module.']['edit.']['forceDisplayFieldIcons'] ||
|
||||
$val === 'editNoPopup' && $this->configuration['module.']['edit.']['forceNoPopup']
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Override all settings with user TSconfig
|
||||
if ($val && isset($this->configuration['override.'][$sectionName . '.'][$val])) {
|
||||
return $this->configuration['override.'][$sectionName . '.'][$val];
|
||||
}
|
||||
if (!$val && isset($this->configuration['override.'][$sectionName])) {
|
||||
return $this->configuration['override.'][$sectionName];
|
||||
}
|
||||
|
||||
$returnValue = $val ? $beUser->uc['AdminPanel'][$sectionName . '_' . $val] : 1;
|
||||
|
||||
// Exception for preview
|
||||
if ($sectionName === 'preview' && $this->ext_forcePreview) {
|
||||
return !$val ? true : $returnValue;
|
||||
}
|
||||
|
||||
// See if the menu is expanded!
|
||||
return $this->isAdminModuleOpen($sectionName) ? $returnValue : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the force preview option.
|
||||
*
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - see AdminPanelModule: Preview
|
||||
*/
|
||||
public function forcePreview()
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->forcePreview() will be removed in TYPO3 v10.0. Use new AdminPanel Preview Module instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$this->ext_forcePreview = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if admin panel module is open
|
||||
*
|
||||
* @param string $key Module key
|
||||
* @return bool TRUE, if the admin panel is open for the specified admin panel module key.
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
|
||||
*/
|
||||
public function isAdminModuleOpen($key)
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->isAdminModuleOpen() will be removed in TYPO3 v10.0. Use new AdminPanel API instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
return $this->getBackendUser()->uc['AdminPanel']['display_top'] &&
|
||||
$this->getBackendUser()->uc['AdminPanel']['display_' . $key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a row (with 4 columns) for content in a section of the Admin Panel.
|
||||
* It will take $pre as a key to a label to display and $element as the content to put into the forth cell.
|
||||
*
|
||||
* @param string $title Key to label
|
||||
* @param string $content The HTML content for the forth table cell.
|
||||
* @param string $checkbox The HTML for a checkbox or hidden fields.
|
||||
* @param string $innerDivClass The Class attribute for the td element.
|
||||
* @param string $outerDivClass The Class attribute for the tr element.
|
||||
* @return string HTML table row.
|
||||
* @see extGetHead()
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
|
||||
*/
|
||||
public function extGetItem($title, $content = '', $checkbox = '', $outerDivClass = null, $innerDivClass = null)
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->extGetItem() will be removed in TYPO3 v10.0. Use new AdminPanel API instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$title = $title ? '<label for="' . htmlspecialchars($title) . '">' . $this->extGetLL($title) . '</label>' : '';
|
||||
$out = '';
|
||||
$out .= (string)$outerDivClass ? '<div class="' . htmlspecialchars($outerDivClass) . '">' : '<div>';
|
||||
$out .= (string)$innerDivClass ? '<div class="' . htmlspecialchars($innerDivClass) . '">' : '<div>';
|
||||
$out .= $checkbox . $title . $content . '</div></div>';
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a row (with colspan=4) which is a header for a section in the Admin Panel.
|
||||
* It will have a plus/minus icon and a label which is linked so that it submits the form which surrounds the whole Admin Panel when clicked, alterting the TSFE_ADMIN_PANEL[display_' . $pre . '] value
|
||||
* See the functions get*Module
|
||||
*
|
||||
* @param string $sectionSuffix The suffix to the display_ label. Also selects the label from the LOCAL_LANG array.
|
||||
* @return string HTML table row.
|
||||
* @see extGetItem()
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
|
||||
*/
|
||||
public function extGetHead($sectionSuffix)
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->extGetHead() will be removed in TYPO3 v10.0. Use new AdminPanel API instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
return $this->linkSectionHeader($sectionSuffix, $this->extGetLL($sectionSuffix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a string in a link which will open/close a certain part of the Admin Panel
|
||||
*
|
||||
* @param string $sectionSuffix The code for the display_ label/key
|
||||
* @param string $sectionTitle Title (HTML-escaped)
|
||||
* @param string $className The classname for the <a> tag
|
||||
* @return string $className Linked input string
|
||||
* @see extGetHead()
|
||||
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0 - use new AdminPanel API instead
|
||||
*/
|
||||
public function linkSectionHeader($sectionSuffix, $sectionTitle, $className = '')
|
||||
{
|
||||
trigger_error(
|
||||
'AdminPanelView->linkSectionHeader() will be removed in TYPO3 v10.0. Use new AdminPanel API instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$onclick = 'document.TSFE_ADMIN_PANEL_FORM[' .
|
||||
GeneralUtility::quoteJSvalue('TSFE_ADMIN_PANEL[display_' . $sectionSuffix . ']') .
|
||||
'].value=' .
|
||||
($this->getBackendUser()->uc['AdminPanel']['display_' . $sectionSuffix] ? '0' : '1') .
|
||||
';document.TSFE_ADMIN_PANEL_FORM.submit();return false;';
|
||||
|
||||
$output = [];
|
||||
$output[] = '<span class="typo3-adminPanel-section-title-identifier"></span>';
|
||||
$output[] = '<a href="javascript:void(0)" onclick="' . htmlspecialchars($onclick) . '">';
|
||||
$output[] = ' ' . $sectionTitle;
|
||||
$output[] = '</a>';
|
||||
$output[] = '<input type="hidden" name="TSFE_ADMIN_PANEL[display_' .
|
||||
$sectionSuffix .
|
||||
']" value="' .
|
||||
(int)$this->isAdminModuleOpen($sectionSuffix) .
|
||||
'" />';
|
||||
|
||||
return implode('', $output);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Adminpanel\View;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for classes which hook into AdminPanelView
|
||||
*
|
||||
* @deprecated since TYPO3 v9 will be removed in TYPO3 v10.0 - see AdminPanelModuleInterface
|
||||
*/
|
||||
interface AdminPanelViewHookInterface
|
||||
{
|
||||
/**
|
||||
* Extend the adminPanel
|
||||
*
|
||||
* @param string $moduleContent Content of the admin panel
|
||||
* @param \TYPO3\CMS\Adminpanel\View\AdminPanelView $obj The adminPanel object
|
||||
* @return string Returns content of admin panel
|
||||
*/
|
||||
public function extendAdminPanel($moduleContent, AdminPanelView $obj);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Checks whether the given value is an array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class IsArrayViewHelper extends AbstractViewHelper
|
||||
{
|
||||
public function initializeArguments()
|
||||
{
|
||||
$this->registerArgument('value', 'mixed', 'The variable being checked', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return bool
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
): bool {
|
||||
return is_array($arguments['value']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Log\LogLevel;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Get speaking log level from constant
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class SpeakingLogLevelViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* First level cache of user names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $usernameRuntimeCache = [];
|
||||
|
||||
/**
|
||||
* Initializes the arguments
|
||||
*/
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('level', 'int', 'Log Level', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve user name from backend user id.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string Username or an empty string if there is no user with that UID
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
): string {
|
||||
return LogLevel::getName($arguments['level']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace TYPO3\CMS\Adminpanel\ViewHelpers;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ContentProviderInterface;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
|
||||
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleDataStorageCollection;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Render submodule content
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class SubModuleRenderViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* First level cache of user names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $usernameRuntimeCache = [];
|
||||
|
||||
/**
|
||||
* Initializes the arguments
|
||||
*/
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument(
|
||||
'module',
|
||||
ContentProviderInterface::class,
|
||||
'SubModule instance to be rendered',
|
||||
true
|
||||
);
|
||||
$this->registerArgument('data', ModuleDataStorageCollection::class, 'Data to be used for rendering', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve user name from backend user id.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string Username or an empty string if there is no user with that UID
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
): string {
|
||||
$module = $arguments['module'];
|
||||
/** @var \TYPO3\CMS\Adminpanel\ModuleApi\ModuleDataStorageCollection $data */
|
||||
$data = $arguments['data'];
|
||||
$moduleData = $data->contains($module) ? $data->offsetGet($module) : new ModuleData();
|
||||
return $module->getContent($moduleData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Definitions for routes provided by EXT:adminpanel
|
||||
* Contains all AJAX-based routes for entry points
|
||||
*/
|
||||
return [
|
||||
'adminPanel_saveForm' => [
|
||||
'path' => '/adminpanel/form/save',
|
||||
'target' => \TYPO3\CMS\Adminpanel\Controller\AjaxController::class . '::saveDataAction'
|
||||
],
|
||||
'adminPanel_toggle' => [
|
||||
'path' => '/adminpanel/toggleActiveState',
|
||||
'target' => \TYPO3\CMS\Adminpanel\Controller\AjaxController::class . '::toggleActiveState'
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* An array consisting of implementations of middlewares for a middleware stack to be registered
|
||||
* 'stackname' => [
|
||||
* 'middleware-identifier' => [
|
||||
* 'target' => classname or callable
|
||||
* 'before/after' => array of dependencies
|
||||
* ]
|
||||
* ]
|
||||
*/
|
||||
return [
|
||||
'frontend' => [
|
||||
'typo3/cms-adminpanel/initiator' => [
|
||||
'target' => \TYPO3\CMS\Adminpanel\Middleware\AdminPanelInitiator::class,
|
||||
'before' => [
|
||||
'typo3/cms-frontend/prepare-tsfe-rendering',
|
||||
'typo3/cms-frontend/page-resolver'
|
||||
],
|
||||
'after' => [
|
||||
'typo3/cms-frontend/tsfe',
|
||||
'typo3/cms-frontend/authentication',
|
||||
'typo3/cms-frontend/backend-user-authentication',
|
||||
]
|
||||
],
|
||||
'typo3/cms-adminpanel/sql-logging' => [
|
||||
'target' => \TYPO3\CMS\Adminpanel\Middleware\SqlLogging::class,
|
||||
'after' => [
|
||||
'typo3/cms-frontend/authentication',
|
||||
'typo3/cms-frontend/backend-user-authentication',
|
||||
],
|
||||
'before' => [
|
||||
'typo3/cms-frontend/site'
|
||||
]
|
||||
],
|
||||
'typo3/cms-adminpanel/data-persister' => [
|
||||
'target' => \TYPO3\CMS\Adminpanel\Middleware\AdminPanelDataPersister::class,
|
||||
'after' => [
|
||||
'typo3/cms-adminpanel/initiator',
|
||||
'typo3/cms-frontend/content-length-headers',
|
||||
'typo3/cms-adminpanel/renderer'
|
||||
],
|
||||
],
|
||||
'typo3/cms-adminpanel/renderer' => [
|
||||
'target' => \TYPO3\CMS\Adminpanel\Middleware\AdminPanelRenderer::class,
|
||||
'after' => [
|
||||
'typo3/cms-adminpanel/initiator',
|
||||
'typo3/cms-frontend/content-length-headers'
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
@@ -0,0 +1,345 @@
|
||||
Some icons used in the TYPO3 project are retrieved from the "Silk" icon set of
|
||||
Mark James, which can be found at http://famfamfam.com/lab/icons/silk/. This
|
||||
set is distributed under a Creative Commons Attribution 2.5 License. The
|
||||
license can be found at http://creativecommons.org/licenses/by/2.5/.
|
||||
---------------------------------
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
return [
|
||||
'TYPO3\\CMS\\Frontend\\View\\AdminPanelView' => \TYPO3\CMS\Adminpanel\View\AdminPanelView::class,
|
||||
'TYPO3\\CMS\\Frontend\\View\\AdminPanelViewHookInterface' => \TYPO3\CMS\Adminpanel\View\AdminPanelViewHookInterface::class
|
||||
];
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace {
|
||||
die('Access denied');
|
||||
}
|
||||
|
||||
namespace TYPO3\CMS\Frontend\View {
|
||||
class AdminPanelView extends \TYPO3\CMS\Adminpanel\View\AdminPanelView
|
||||
{
|
||||
}
|
||||
interface AdminPanelViewHookInterface extends \TYPO3\CMS\Adminpanel\View\AdminPanelViewHookInterface
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1520838123" source-language="en" datatype="plaintext" original="EXT:adminpanel/Resources/Private/Language/locallang.xlf" date="2018-03-31T08:08:00Z"
|
||||
product-name="adminpanel">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="deprecatedModuleLabel" resname="deprecatedModuleLabel">
|
||||
<source>General</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="settings.label" resname="settings.label">
|
||||
<source>Settings</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="settings.updateButtonLabel" resname="settings.updateButtonLabel">
|
||||
<source>Update Settings</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="button.close" resname="button.close">
|
||||
<source>Close</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="button.view" resname="button.view">
|
||||
<source>View</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1520862804" source-language="en" datatype="plaintext" original="EXT:adminpanel/Resources/Private/Language/locallang_cache.xlf" date="2018-03-12T13:52:00Z"
|
||||
product-name="adminpanel">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="module.label" resname="module.label">
|
||||
<source>Cache</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="cache.no_cache" resname="cache.no_cache">
|
||||
<source>No caching</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="cache.clear_current" resname="cache.clear_current">
|
||||
<source>Clear cache of current page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="cache.clear_pages" resname="cache.clear_pages">
|
||||
<source>Clear frontend cache</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||