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>
|
||||||