...
 
Commits (124)
solr/mycores/*
sequelpro.spf
db_snapshots
docker-compose.yaml
#ddev-generated: Automatically generated ddev .gitignore.
# You can remove the above line if you want to edit and maintain this file yourself.
/commands/*/*.example
/commands/*/README.txt
/commands/host/launch
/commands/db/mysql
/homeadditions/*.example
/homeadditions/README.txt
/.gitignore
/import.yaml
/docker-compose.yaml
/db_snapshots
/sequelpro.spf
/import-db
/.bgsync*
/config.*.y*ml
/.webimageBuild
/.dbimageBuild
/.bgsyncimageBuild
/.sshimageBuild
/.webimageExtra
/.dbimageExtra
/*-build/Dockerfile.example
APIVersion: v1.8.0
APIVersion: v1.12.1
name: ter
type: typo3
docroot: public
php_version: "7.2"
webserver_type: nginx-fpm
dbimage: drud/ddev-dbserver:v1.6.0-10.1
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: false
additional_hostnames: []
additional_fqdns: []
mariadb_version: "10.1"
mariadb_version: "10.2"
nfs_mount_enabled: false
provider: default
hooks:
post-start:
- exec: bash -c "sudo -E apt-get update"
- exec: bash -c "sudo -E apt-get install --yes --no-install-recommends apt-utils"
- exec: bash -c "sudo -E apt-get install --yes php7.2-ldap -o Dpkg::Options::=\"--force-confdef\"
-o Dpkg::Options::=\"--force-confold\" && killall -HUP php-fpm"
- exec: cp private/typo3conf/AdditionalConfiguration.ddev.php private/typo3conf/AdditionalConfiguration.php
- exec: composer install
- exec: npm --prefix private/typo3conf/ext/t3olayout/Build install
- exec: npm --prefix private/typo3conf/ext/t3olayout/Build run-script build
- exec: vendor/bin/typo3cms install:generatepackagestates
- exec: vendor/bin/typo3cms install:extensionsetupifpossible
webimage_extra_packages: [php7.2-ldap, build-essential]
use_dns_when_possible: true
timezone: Europe/Berlin
# This config.yaml was created with ddev version v1.8.0
# webimage: drud/ddev-webserver:v1.8.0
# dbimage: drud/ddev-dbserver:v1.8.0-10.2
# dbaimage: drud/phpmyadmin:v1.8.0
# bgsyncimage: drud/ddev-bgsync:v1.8.0
# This config.yaml was created with ddev version v1.12.1
# webimage: drud/ddev-webserver:v1.12.1
# dbimage: drud/ddev-dbserver-mariadb-10.2:v1.12.0
# dbaimage: drud/phpmyadmin:v1.12.0
# bgsyncimage: drud/ddev-bgsync:v1.12.0
# However we do not recommend explicitly wiring these images into the
# config.yaml as they may break future versions of ddev.
# You can update this config.yaml using 'ddev config'.
......@@ -39,13 +37,13 @@ hooks:
# Key features of ddev's config.yaml:
# name: <projectname> # Name of the project, automatically provides
# http://projectname.ddev.local and https://projectname.ddev.local
# http://projectname.ddev.site and https://projectname.ddev.site
# type: <projecttype> # drupal6/7/8, backdrop, typo3, wordpress, php
# docroot: <relative_path> # Relative path to the directory containing index.php.
# php_version: "7.1" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3"
# php_version: "7.2" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4"
# You can explicitly specify the webimage, dbimage, dbaimage lines but this
# is not recommended, as the images are often closely tied to ddev's' behavior,
......@@ -56,18 +54,33 @@ hooks:
# dbaimage: <docker_image>
# bgsyncimage: <docker_image>
# mariadb_version and mysql_version
# ddev can use many versions of mariadb and mysql
# However these directives are mutually exclusive
# mariadb_version: 10.2
# mysql_version: 8.0
# router_http_port: <port> # Port to be used for http (defaults to port 80)
# router_https_port: <port> # Port for https (defaults to 443)
# xdebug_enabled: false # Set to true to enable xdebug and "ddev start" or "ddev restart"
# Note that for most people the commands
# "ddev exec enable_xdebug" and "ddev exec disable_xdebug" work better,
# as leaving xdebug enabled all the time is a big performance hit.
# webserver_type: nginx-fpm # Can be set to apache-fpm or apache-cgi as well
# timezone: Europe/Berlin
# This is the timezone used in the containers and by PHP;
# it can be set to any valid timezone,
# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# For example Europe/Dublin or MST7MDT
# additional_hostnames:
# - somename
# - someothername
# would provide http and https URLs for "somename.ddev.local"
# and "someothername.ddev.local".
# would provide http and https URLs for "somename.ddev.site"
# and "someothername.ddev.site".
# additional_fqdns:
# - example.com
......@@ -81,14 +94,14 @@ hooks:
# working_dir:
# web: /var/www/html
# db: /home
# would set the default working directory for the web and db services.
# These values specify the destination directory for ddev ssh and the
# directory in which commands passed into ddev exec are run.
# would set the default working directory for the web and db services.
# These values specify the destination directory for ddev ssh and the
# directory in which commands passed into ddev exec are run.
# omit_containers: ["dba", "ddev-ssh-agent"]
# would omit the dba (phpMyAdmin) and ddev-ssh-agent containers. Currently
# only those two containers can be omitted here.
# Note that these containers can also be omitted globally in the
# Note that these containers can also be omitted globally in the
# ~/.ddev/global_config.yaml or with the "ddev config global" command.
# nfs_mount_enabled: false
......@@ -96,8 +109,8 @@ hooks:
# See https://ddev.readthedocs.io/en/stable/users/performance/#using-nfs-to-mount-the-project-into-the-container
# webcache_enabled: false (deprecated)
# Was only for macOS, but now deprecated.
# See https://ddev.readthedocs.io/en/stable/users/performance/#using-webcache_enabled-to-cache-the-project-directory
# Was only for macOS, but now deprecated.
# See https://ddev.readthedocs.io/en/stable/users/performance/#webcache
# host_https_port: "59002"
# The host port binding for https can be explicitly specified. It is
......@@ -115,21 +128,42 @@ hooks:
# The host port binding for the ddev-dbserver can be explicitly specified. It is dynamic
# unless explicitly specified.
# phpmyadmin_port: "1000"
# The PHPMyAdmin port can be changed from the default 8036
# mailhog_port: "1001"
# The MailHog port can be changed from the default 8025
# webimage_extra_packages: [php-yaml, php7.3-ldap]
# Extra Debian packages that are needed in the webimage can be added here
# This is ignored if a free-form .ddev/web-build/Dockerfile is provided
# dbimage_extra_packages: [telnet,netcat]
# Extra Debian packages that are needed in the dbimage can be added here
# This is ignored if a free-form .ddev/db-build/Dockerfile is provided
# use_dns_when_possible: true
# If the host has internet access and the domain configured can
# successfully be looked up, DNS will be used for hostname resolution
# instead of editing /etc/hosts
# Defaults to true
# project_tld: ddev.site
# The top-level domain used for project URLs
# The default "ddev.site" allows DNS lookup via a wildcard
# If you prefer you can change this to "ddev.local" to preserve
# pre-v1.9 behavior.
# ngrok_args: --subdomain mysite --auth username:pass
# Provide extra flags to the "ngrok http" command, see
# https://ngrok.com/docs#http or run "ngrok http -h"
# provider: default # Currently either "default" or "pantheon"
#
# Many ddev commands can be extended to run tasks after the ddev command is
# executed.
# Many ddev commands can be extended to run tasks before or after the
# ddev command is executed, for example "post-start", "post-import-db",
# "pre-composer", "post-composer"
# See https://ddev.readthedocs.io/en/stable/users/extending-commands/ for more
# information on the commands that can be extended and the tasks you can define
# for them. Example:
#hooks:
# post-start:
# - exec: composer install -d /var/www/html
\ No newline at end of file
# - exec: composer install -d /var/www/html
# You can copy this Dockerfile.example to Dockerfile to add configuration
# or packages or anything else to your dbimage
ARG BASE_IMAGE=drud/ddev-dbserver:v1.6.0-10.1
FROM $BASE_IMAGE
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y telnet netcat
RUN echo "Built from drud/ddev-dbserver:v1.6.0-10.1" >/var/tmp/built-from.txt
......@@ -3,6 +3,4 @@ version: '3.6'
services:
web:
environment:
- TYPO3_CONTEXT=Development
- PHP_IDE_CONFIG="serverName=ter.ddev.local"
- DEBIAN_FRONTEND=noninteractive
\ No newline at end of file
- TYPO3_CONTEXT=Development
\ No newline at end of file
# ddev apache solr recipe file
#
# To use this in your own project: Copy this file to your project's .ddev folder,
# and create the folder path .ddev/solr/conf. Then, copy the solr configuration
# files for your project to .ddev/solr/conf. E.g., using Drupal Search API Solr,
# you would copy the solr-conf/5.x/ contents into .ddev/solr/conf. The configuration
# files must be present before running `ddev start`.
version: '3.6'
services:
solr: # This is the service name used when running ddev commands accepting the --service flag
container_name: ddev-${DDEV_SITENAME}-solr # This is the name of the container. It is recommended to follow the same name convention used in the main docker-compose.yml file.
image: solr:6.6.3
restart: on-failure
solr:
container_name: ddev-${DDEV_SITENAME}-solr
image: typo3solr/ext-solr:10.0.1
restart: "no"
ports:
- 8983 # Solr is served from this port inside the container
- 8983
labels:
# These labels ensure this service is discoverable by ddev
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
com.ddev.app-url: $DDEV_URL
environment:
- VIRTUAL_HOST=$DDEV_HOSTNAME # This defines the host name the service should be accessible from. This will be sitename.ddev.local
- HTTP_EXPOSE=8983 # This defines the port the service should be accessible from at sitename.ddev.local
- VIRTUAL_HOST=$DDEV_HOSTNAME
- HTTP_EXPOSE=8983
volumes:
- "./solr:/solr-conf" # This exposes a mount to the host system `.ddev/solr-conf` directory.
- "./solr/configsets:/opt/solr/server/solr/configsets" # ext:solr configsets linking
- "./solr/mycores:/opt/solr/server/solr/mycores"
entrypoint:
- docker-entrypoint.sh
- solr-precreate
- t3o
- /solr-conf
# This links the solr service to the web service defined in the main docker-compose.yml, allowing applications running in the web service to access the solr service at sitename.ddev.local:8983
- "./solr:/opt/solr/server/solr"
web:
links:
- solr:$DDEV_HOSTNAME
<solr>
<solrcloud>
<str name="host">${host:}</str>
<int name="hostPort">${jetty.port:8983}</int>
<str name="hostContext">${hostContext:solr}</str>
<int name="zkClientTimeout">${zkClientTimeout:15000}</int>
<bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
</solrcloud>
<shardHandlerFactory name="shardHandlerFactory"
class="HttpShardHandlerFactory">
<int name="socketTimeout">${socketTimeout:0}</int>
<int name="connTimeout">${connTimeout:0}</int>
</shardHandlerFactory>
</solr>
\ No newline at end of file
# You can copy this Dockerfile.example to Dockerfile to add configuration
# or packages or anything else to your webimage
ARG BASE_IMAGE=drud/ddev-webserver:v1.8.0
FROM $BASE_IMAGE
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y php-yaml
RUN npm install --global gulp-cli
RUN ln -fs /usr/share/zoneinfo/Europe/Berlin /etc/localtime && dpkg-reconfigure --frontend noninteractive tzdata
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# CSS-Files
[*.css]
indent_style = space
indent_size = 4
# HTML-Files
[*.html]
indent_style = space
indent_size = 4
# TMPL-Files
[*.tmpl]
indent_style = space
indent_size = 4
# SCSS-Files
[*.scss]
indent_style = space
indent_size = 4
# JS-Files
[*.js]
indent_style = space
indent_size = 4
# JSON-Files
[*.json]
indent_style = space
indent_size = 4
# PHP-Files
[*.php]
indent_style = space
indent_size = 4
# ReST-Files
[*.rst]
indent_style = space
indent_size = 3
# MD-Files
[*.md]
indent_style = space
indent_size = 4
# YAML-Files
[{*.yaml,*.yml}]
indent_style = space
indent_size = 2
# package.json
# .travis.yml
# bower.json
[{package.json,.travis.yml,bower.json}]
indent_style = space
indent_size = 4
# TypoScript
[*.ts]
indent_style = space
indent_size = 4
[*.typoscript]
indent_style = space
indent_size = 4
# XLF-Files
[*.xlf]
indent_style = space
indent_size = 4
# SQL-Files
[*.sql]
indent_style = space
indent_size = 2
.idea
/vendor
/var
/private
!/private/typo3conf/LocalConfiguration.php
!/private/typo3conf/AdditionalConfiguration.ddev.php
!/private/typo3conf/RealurlConfiguration.php
/public/
!/public/.well-known/security.txt
/auth.json
/assets/
sequelpro.spf
......
......@@ -8,7 +8,8 @@ require_once '/tmp/vendor/deployer/recipes/recipe/rsync.php';
$sharedDirectories = [
'private/fileadmin',
'private/uploads',
'public/.well-known'
'public/.well-known',
'var'
];
set('shared_dirs', $sharedDirectories);
......@@ -58,6 +59,10 @@ task('typo3', function() {
run('cd {{release_path}} && {{php}} {{bin_folder}}typo3cms install:extensionsetupifpossible');
});
task('solr_host', function() {
run('cd {{deploy_path}} && ./solr_change_host.sh');
});
task('typo3:ter_wsdl', function() {
run('cd {{release_path}}/public/typo3conf/ext && mkdir ter');
run('cd {{release_path}}/public/typo3conf/ext/ter && ln -s ../../../../private/typo3conf/ext/ter/tx_ter_wsdl.php');
......@@ -79,6 +84,7 @@ task('deploy', [
'typo3',
'typo3:ter_wsdl',
'deploy:symlink',
'solr_host',
'cache',
'cleanup'
]);
......@@ -6,7 +6,7 @@ master:
writable_mode: chmod
forward_agent: true
deploy_path: ~/ci/
keep_releases: 5
keep_releases: 2
develop:
stage: stage
hostname: extensions-stage-v9.typo3.org
......
This diff is collapsed.
rootPageId: 1
base: 'https://extensions.typo3.org/'
baseVariants:
-
base: 'https://ter.ddev.site'
condition: 'applicationContext == "Development"'
-
base: 'https://extensions-stage.typo3.org'
condition: 'applicationContext == "Testing"'
-
base: 'https://extensions.typo3.org'
condition: 'applicationContext == "Production"'
languages:
-
title: English
enabled: true
languageId: '0'
base: /
typo3Language: default
locale: en_GB.UTF-8
iso-639-1: en
navigationTitle: English
hreflang: en-GB
direction: ''
flag: gb
solr_core_read: core_en
errorHandling:
- errorCode: '404'
errorHandler: Page
errorContentSource: 't3://page?uid=404'
- errorCode: '403'
errorHandler: Page
errorContentSource: 't3://page?uid=12'
routes: { }
solr_enabled_read: true
solr_scheme_read: http
solr_host_read: solr
solr_port_read: 8983
solr_path_read: /solr/
solr_use_write_connection: false
imports:
- { resource: "EXT:ter_fe2/Configuration/Routes/Extensions.yml" }
......@@ -36,7 +36,7 @@ class ExtConf implements SingletonInterface
public function __construct()
{
// get global configuration
$extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['ter']);
$extConf = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ter'];
if (is_array($extConf) && count($extConf)) {
// call setter method foreach configuration entry
foreach ($extConf as $key => $value) {
......
......@@ -14,6 +14,7 @@ namespace T3o\Ter\Task;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
......@@ -42,7 +43,7 @@ class UpdateCurrentVersionListTask extends \TYPO3\CMS\Extbase\Scheduler\Task
protected function fetchCurrentCoreData()
{
$result = false;
$targetFile = PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . 'currentcoredata.json';
$targetFile = Environment::getPublicPath() . '/' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . 'currentcoredata.json';
$sourceData = GeneralUtility::getUrl('http://get.typo3.org/json');
if (json_decode($sourceData, true) !== null) {
$result = GeneralUtility::writeFile($targetFile, $sourceData);
......@@ -57,7 +58,7 @@ class UpdateCurrentVersionListTask extends \TYPO3\CMS\Extbase\Scheduler\Task
protected function fetchCurrentDocumentationData()
{
$result = false;
$targetFile = PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . 'currentdocumentationdata.json';
$targetFile = Environment::getPublicPath() . '/' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . 'currentdocumentationdata.json';
$sourceData = GeneralUtility::getUrl('https://intercept.typo3.com/assets/docs/manuals.json');
if (json_decode($sourceData, true) !== null) {
$result = GeneralUtility::writeFile($targetFile, $sourceData);
......@@ -76,12 +77,12 @@ class UpdateCurrentVersionListTask extends \TYPO3\CMS\Extbase\Scheduler\Task
protected function generateExtensionFilesForExtensionManager(): bool
{
// Check extension configuration
if (empty($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['ter'])) {
if (empty($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ter'])) {
throw new \Exception('No extension configuration found in $TYPO3_CONF_VARS', 1303220916);
}
// Check extension repository path
$extensionConfig = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['ter']);
$extensionConfig = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ter'];
if (empty($extensionConfig['repositoryDir'])) {
throw new \Exception('No repository path found in extension configuration', 1303220917);
}
......
......@@ -16,10 +16,9 @@ $extensionKey = 'ter';
return [
'ctrl' => [
'label' => 'extensionuid',
'label_userFunc' => 'EXT:ter/class.tx_ter_tcaLabel.php:tx_ter_tcaLabel->getExtensionKey',
'default_sortby' => 'ORDER BY extensionuid',
'title' => 'LLL:EXT:ter/locallang_tca.xml:tx_ter_extensiondetails',
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extensionKey) . 'tx_ter_extensiondetails.gif',
'iconfile' => \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($extensionKey)) . 'tx_ter_extensiondetails.gif',
'dividers2tabs' => true,
],
'interface' => [
......
......@@ -20,7 +20,7 @@ return [
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'title' => 'LLL:EXT:ter/locallang_tca.xml:tx_ter_extensionkeys',
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extensionKey) . 'tx_ter_extensionkeys.gif',
'iconfile' => \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($extensionKey)) . 'tx_ter_extensionkeys.gif',
'dividers2tabs' => true,
],
'interface' => [
......
......@@ -18,7 +18,7 @@ return [
'label' => 'extensionkey',
'default_sortby' => 'ORDER BY extensionkey',
'title' => 'LLL:EXT:ter/locallang_tca.xml:tx_ter_extensionmembers',
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extensionKey) . 'tx_ter_extensionmembers.gif',
'iconfile' => \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($extensionKey)) . 'tx_ter_extensionmembers.gif',
'dividers2tabs' => true,
],
'interface' => [
......
......@@ -21,7 +21,7 @@ return [
'tstamp' => 'tstamp',
'delete' => 'deleted',
'title' => 'LLL:EXT:ter/locallang_tca.xml:tx_ter_extensionqueue',
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extensionKey) . 'tx_ter_extensionqueue.gif',
'iconfile' => \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($extensionKey)) . 'tx_ter_extensionqueue.gif',
'dividers2tabs' => true,
],
'interface' => [
......
......@@ -20,7 +20,7 @@ return [
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'title' => 'LLL:EXT:ter/locallang_tca.xml:tx_ter_extensions',
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extensionKey) . 'tx_ter_extensions.gif',
'iconfile' => \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($extensionKey)) . 'tx_ter_extensions.gif',
'dividers2tabs' => true,
],
'interface' => [
......
......@@ -315,7 +315,7 @@ class tx_ter_api
);
}
$extensionKeyRecordArr = $this->helperObj->getExtensionKeyRecord($extensionKey);
if ($extensionKeyRecordArr == false) {
if ($extensionKeyRecordArr === false) {
throw new \T3o\Ter\Exception\NotFoundException(
'Extension does not exist.',
TX_TER_ERROR_DELETEEXTENSION_EXTENSIONDOESNTEXIST
......@@ -414,27 +414,26 @@ class tx_ter_api
{
$extensionKeyDataArr = [];
$whereClause = 'pid=' . (int)$this->parentObj->extensionsPID;
if (!empty($extensionKeyFilterOptions->username)) {
$whereClause .= ' AND ownerusername = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$whereClause = 'ownerusername = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$extensionKeyFilterOptions->username,
'tx_ter_extensionkeys'
);
}
if (!empty($extensionKeyFilterOptions->title)) {
$whereClause .= ' AND title = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$whereClause = 'title = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$extensionKeyFilterOptions->title,
'tx_ter_extensionkeys'
);
}
if (!empty($extensionKeyFilterOptions->description)) {
$whereClause .= ' AND description = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$whereClause = 'description = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$extensionKeyFilterOptions->description,
'tx_ter_extensionkeys'
);
}
if (!empty($extensionKeyFilterOptions->extensionKey)) {
$whereClause .= ' AND extensionkey = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$whereClause = 'extensionkey = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$extensionKeyFilterOptions->extensionKey,
'tx_ter_extensionkeys'
);
......@@ -485,9 +484,8 @@ class tx_ter_api
$extensionKeyRecordArr = $this->helperObj->getExtensionKeyRecord($extensionKey);
if (is_array($extensionKeyRecordArr)) {
if (strtolower($extensionKeyRecordArr['ownerusername']) != strtolower(
$accountData->username
) && $userRecordArr['admin'] !== true
if ($userRecordArr['admin'] !== true
&& strtolower($extensionKeyRecordArr['ownerusername']) !== strtolower($accountData->username)
) {
throw new \T3o\Ter\Exception\UnauthorizedException('Access denied.', TX_TER_ERROR_DELETEEXTENSIONKEY_ACCESSDENIED);
}
......@@ -498,7 +496,7 @@ class tx_ter_api
'extensionkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$extensionKey,
'tx_ter_extensions'
) . ' AND pid=' . (int)$this->parentObj->extensionsPID
)
);
if ($res) {
......@@ -510,7 +508,7 @@ class tx_ter_api
'extensionkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$extensionKey,
'tx_ter_extensions'
) . ' AND pid=' . (int)$this->parentObj->extensionsPID
)
);
if (!$res) {
throw new \T3o\Ter\Exception\InternalServerErrorException(
......@@ -566,9 +564,8 @@ class tx_ter_api
$extensionKeyRecordArr = $this->helperObj->getExtensionKeyRecord($modifyExtensionKeyData->extensionKey);
if (is_array($extensionKeyRecordArr)) {
if (strtolower($extensionKeyRecordArr['ownerusername']) != strtolower(
$accountData->username
) && $userRecordArr['admin'] !== true
if ($userRecordArr['admin'] !== true
&& strtolower($extensionKeyRecordArr['ownerusername']) !== strtolower($accountData->username)
) {
throw new \T3o\Ter\Exception\UnauthorizedException('Access denied.', TX_TER_ERROR_MODIFYEXTENSIONKEY_ACCESSDENIED);
}
......@@ -599,7 +596,7 @@ class tx_ter_api
public function setReviewState($accountData, $setReviewStateData)
{
$userRecordArr = $this->helperObj->getValidUser($accountData);
$reviewersFrontendUsergroupUid = (int)$this->parentObj->conf['reviewersFrontendUsergroupUid'];
$reviewersFrontendUsergroupUid = (int)$GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_ter_pi1.']['reviewersFrontendUsergroupUid'];
if ($reviewersFrontendUsergroupUid == 0) {
throw new \T3o\Ter\Exception\InternalServerErrorException(
......@@ -942,7 +939,7 @@ class tx_ter_api
$extensionRow = [
'tstamp' => $GLOBALS['SIM_EXEC_TIME'],
'crdate' => $GLOBALS['SIM_EXEC_TIME'],
'pid' => (int)$this->parentObj->extensionsPID,
'pid' => 2,
'extensionkey' => $extensionKey,
'version' => $extensionInfoData->version,
'title' => $extensionInfoData->metaData->title,
......@@ -987,7 +984,7 @@ class tx_ter_api
// Prepare details row
$extensionDetailsRow = [
'pid' => (int)$this->parentObj->extensionsPID,
'pid' => 2,
'extensionuid' => (int)$extensionUid,
'uploadcomment' => (string)$extensionInfoData->infoData->uploadComment,
'lastuploadbyusername' => $accountData->username,
......@@ -1023,7 +1020,7 @@ class tx_ter_api
// Put new extension version into queue
$extensionQueue = [
'pid' => (int)$this->parentObj->extensionsPID,
'pid' => 2,
'extensionuid' => (int)$extensionUid,
'extensionkey' => $extensionKey,
];
......@@ -1066,7 +1063,7 @@ class tx_ter_api
) . ' AND version=' . $GLOBALS['TYPO3_DB']->fullQuoteStr(
$version,
'tx_ter_extensions'
) . ' AND pid=' . (int)$this->parentObj->extensionsPID
)
);
if (!$result) {
throw new \T3o\Ter\Exception\InternalServerErrorException(
......@@ -1325,12 +1322,12 @@ class tx_ter_api
protected function registerExtensionKey_writeExtensionKeyInfoToDB($accountData, $extensionKeyData)
{
$extensionKeysRow = [
'pid' => $this->parentObj->extensionsPID,
'pid' => 2,
'tstamp' => time(),
'crdate' => time(),
'extensionkey' => $extensionKeyData->extensionKey,
'title' => $GLOBALS['TSFE']->csConvObj->strtrunc('utf-8', $extensionKeyData->title, 50),
'description' => $GLOBALS['TSFE']->csConvObj->strtrunc('utf-8', $extensionKeyData->description, 255),
'title' => mb_strcut($extensionKeyData->title, 0, 50, 'utf-8'),
'description' => mb_strcut($extensionKeyData->description, 0, 255, 'utf-8'),
'ownerusername' => $accountData->username,
'maxstoresize' => 0
];
......
......@@ -116,6 +116,8 @@ class tx_ter_helper
public function __construct($pluginObj)
{
$this->pluginObj = $pluginObj;
$this->pluginObj->conf['adminFrontendUsergroupUid'] = 26;
$this->pluginObj->conf['securityTeamFrontendUsergroupUid'] = 22;
}
/**
......@@ -142,7 +144,7 @@ class tx_ter_helper
if ($row = $this->getDatabaseConnection()->sql_fetch_assoc($res)) {
if (!$this->userIsAlreadyLoggedIn(
$accountData
) && !$this->ldapValidationSucceeded($accountData)
) && !$this->ldapValidationSucceeded($accountData)
) {
throw new \T3o\Ter\Exception\UnauthorizedException('Wrong password.', TX_TER_ERROR_GENERAL_WRONGPASSWORD);
}
......@@ -264,7 +266,7 @@ class tx_ter_helper
$res = $this->getDatabaseConnection()->exec_SELECTquery(
'extensionkey',
'tx_ter_extensionkeys',
'pid=' . intval($this->pluginObj->extensionsPID)
'1'
);
while ($row = $this->getDatabaseConnection()->sql_fetch_row($res)) {
if ($cleanedExtensionKey === str_replace('_', '', $row[0])) {
......@@ -288,7 +290,6 @@ class tx_ter_helper
'*',
'tx_ter_extensionkeys',
'extensionkey=' . $this->getDatabaseConnection()->fullQuoteStr($extKey, 'tx_ter_extensionkeys') .
'AND pid=' . intval($this->pluginObj->extensionsPID) .
$this->getTyposcriptFrontendObject()->sys_page->enableFields('tx_ter_extensionkeys')
);
......@@ -362,7 +363,7 @@ class tx_ter_helper
// Check if update of files requested
$updateRequestedFile = $this->pluginObj->repositoryDir . 'extensions.xml.gz.needsupdate';
if (@filemtime($updateRequestedFile) <= @filemtime($this->pluginObj->repositoryDir . 'extensions.xml.gz')) {
if (file_exists($updateRequestedFile) && @filemtime($updateRequestedFile) <= @filemtime($this->pluginObj->repositoryDir . 'extensions.xml.gz')) {
return;
}
......@@ -401,6 +402,7 @@ class tx_ter_helper
$dom = new DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true;
$extensionsObj = $dom->appendChild(new DOMElement('extensions'));
$documentationService = GeneralUtility::makeInstance(\T3o\TerFe2\Service\DocumentationService::class);
// Create the nested XML structure:
foreach ($extensionsAndVersionsArr as $extensionKey => $extensionVersionsArr) {
......@@ -412,6 +414,16 @@ class tx_ter_helper
$this->xmlentities($extensionsTotalDownloadsArr[$extensionKey])
)
);
$extensionRecord = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ConnectionPool::class)
->getConnectionForTable('tx_terfe2_domain_model_extension')
->select(
['uid', 'external_manual'],
'tx_terfe2_domain_model_extension',
[
'ext_key' => $extensionKey
]
)
->fetch();
foreach ($extensionVersionsArr['versions'] as $versionNumber => $extensionVersionArr) {
$versionObj = $extensionObj->appendChild(new DOMElement('version'));
......@@ -463,6 +475,12 @@ class tx_ter_helper
)
);
$versionObj->appendChild(new DOMElement('t3xfilemd5', $extensionVersionArr['t3xfilemd5']));
$documentationLink = '';
try {
$documentationLink = $documentationService->getDocumentationLink($extensionKey, $versionNumber, true);
} catch (Exception $e) {
}
$versionObj->appendChild(new DOMElement('documentation_link', $extensionRecord['external_manual'] ?: $documentationLink));
}
}
......
......@@ -18,8 +18,9 @@
"issues": "https://git-t3o.typo3.org/t3o/ter/issues"
},
"license": "GPL-2.0+",
"version": "2.0.9",
"require": {
"typo3/cms-core": ">= 8.7.0, <= 8.7.99"
"typo3/cms-core": "^8.7 || ^9.5"
},
"autoload": {
"psr-4": {
......@@ -29,8 +30,7 @@
"Classes",
"pi1",
"class.tx_ter_api.php",
"class.tx_ter_helper.php",
"class.tx_ter_tcaLabel.php"
"class.tx_ter_helper.php"
]
},
"replace": {
......
......@@ -28,9 +28,7 @@ $EM_CONF[$_EXTKEY] = [
'author_company' => 'TYPO3 Association',
'version' => '2.0.9',
'constraints' => [
'depends' => [
'saltedpasswords' => '',
],
'depends' => [],
'conflicts' => [],
'suggests' => [],
],
......
......@@ -7,7 +7,7 @@ if (!defined('TYPO3_MODE')) {
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist'][$_EXTKEY . '_pi1'] = 'layout,select_key,pages,recursive';
// Add plugin and datasets
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(['TER SOAP Server', $_EXTKEY . '_pi1']);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(['TER SOAP Server', $_EXTKEY . '_pi1'], 'list_type', $_EXTKEY);
// Add static configuration files
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'resources/static/', 'TER Server');
......@@ -30,11 +30,8 @@
* TOTAL FUNCTIONS: 1
* (This index is automatically created/updated by the extension "extdeveval")
*/
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Frontend\Plugin\AbstractPlugin;
require_once(ExtensionManagementUtility::extPath('ter') . 'class.tx_ter_api.php');
/**
* TYPO3 Extension Repository, frontend plugin for SOAP service
*
......@@ -50,14 +47,12 @@ class tx_ter_pi1 extends AbstractPlugin
public function main($content, $conf)
{
global $TSFE;
$this->pi_initPIflexForm();
$this->conf = $conf;
$this->extensionsPID = $conf['pid'];
$this->wsdlNamespace = $conf['wsdlNamespace'];
$staticConfArr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['ter']);
$staticConfArr = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ter'];
if (is_array($staticConfArr)) {
$this->repositoryDir = $staticConfArr['repositoryDir'];
if (substr($this->repositoryDir, -1, 1) != '/') {
......
......@@ -23,21 +23,7 @@
*/
error_reporting(E_ALL ^ E_NOTICE);
define('TYPO3_OS', stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin') ? 'WIN' : '');
define('TYPO3_MODE', 'FE');
define('PATH_thisScript', str_replace('//', '/', str_replace(
'\\',
'/',
(php_sapi_name() == 'cgi' || php_sapi_name() == 'isapi' || php_sapi_name() == 'cgi-fcgi') && ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) ? ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) : ($_SERVER['ORIG_SCRIPT_FILENAME'] ? $_SERVER['ORIG_SCRIPT_FILENAME'] : $_SERVER['SCRIPT_FILENAME'])
)));
define('PATH_site', str_replace(['/wsdl', '/typo3conf/ext/ter'], '', dirname(PATH_thisScript)) . '/');
define('PATH_typo3', PATH_site . 'typo3/');
define('PATH_tslib', PATH_typo3 . 'sysext/cms/tslib/');
define('PATH_typo3conf', PATH_site . 'typo3conf/');
define('TYPO3_mainDir', 'typo3/');
$serviceLocation = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?id=ter';
$serviceLocation = 'https://' . $_SERVER['HTTP_HOST'] . '/ter';
$wsdlFileName = 'tx_ter.wsdl';
if (getenv('TYPO3_CONTEXT') === 'Production/Stage') {
......
......@@ -95,17 +95,11 @@ abstract class AbstractTerBasedController extends \T3o\TerFe2\Controller\Abstrac
*/
protected function getTerConnection()
{
// Check the wsdl uri
if (empty($this->terSettings['wsdl'])) {
throw new \Exception('No wsdl set to connect to TER server');
}
if (empty($this->terSettings['httpAuth'])) {
$this->terSettings['httpAuth'] = [];
}
// Create connection
$wsdl = $this->terSettings['wsdl'];
return $this->objectManager->get(\T3o\TerFe2\Service\TerService::class, $wsdl, $this->terAccount['username'], $this->terAccount['password'], $this->terSettings['httpAuth']);
return $this->objectManager->get(\T3o\TerFe2\Service\TerService::class, $this->terAccount['username'], $this->terAccount['password'], $this->terSettings['httpAuth']);
}
}
......@@ -24,6 +24,7 @@ class ExtensionController
{
/**
* TODO: Do we still need this?
* @var \TYPO3\CMS\Core\Database\DatabaseConnection
*/
protected $databaseConnection;
......
......@@ -15,6 +15,9 @@ namespace T3o\TerFe2\Controller;
*/
use T3o\TerFe2\Validation\Validator\ComposerNameValidator;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Controller for the extension object
......@@ -160,7 +163,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
* Action that displays a single extension
*
* @param \T3o\TerFe2\Domain\Model\Extension $extension The extension to display
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
*/
public function showAction(\T3o\TerFe2\Domain\Model\Extension $extension = null)
{
......@@ -191,10 +194,11 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
$documentationLink = $documentationService->getDocumentationLink($extension->getExtKey(), $extension->getLastVersion()->getVersionString(), true);
$this->view->assign('documentationLink', $documentationLink);
$pageRenderer = $this->objectManager->get(\TYPO3\CMS\Core\Page\PageRenderer::class);
$pageRenderer->addMetaTag('<meta name="description" content="' . htmlspecialchars($extension->getLastVersion()->getDescription()) . '" />');
/** @var PageRenderer $pageRenderer */
$pageRenderer = $this->objectManager->get(PageRenderer::class);
$pageRenderer->setMetaTag('name', 'description', htmlspecialchars($extension->getLastVersion()->getDescription()));
if ($extension->getTags()->count() > 0) {
$pageRenderer->addMetaTag('<meta name="keywords" content="' . htmlspecialchars(implode(',', $extension->getTags()->toArray())) . '" />');
$pageRenderer->setMetaTag('name', 'keywords', htmlspecialchars(implode(',', $extension->getTags()->toArray())));
}
// gets all other extensions from the owner
......@@ -220,7 +224,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
* Displays a form to edit an existing extension
*
* @param \T3o\TerFe2\Domain\Model\Extension $extension The extension to display
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
*/
public function editAction(\T3o\TerFe2\Domain\Model\Extension $extension)
{
......@@ -318,7 +322,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
/**
* @param \T3o\TerFe2\Domain\Model\Extension $extension
* @param \T3o\TerFe2\Domain\Model\Tag $tag
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
*/
public function removeTagAction(\T3o\TerFe2\Domain\Model\Extension $extension, \T3o\TerFe2\Domain\Model\Tag $tag)
{
......@@ -354,7 +358,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
* @param \T3o\TerFe2\Domain\Model\Extension $extension The extension object
* @param string $versionString An existing version string
* @param string $format Format of the file output
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
* @throws \Exception
*/
public function downloadAction(\T3o\TerFe2\Domain\Model\Extension $extension, $versionString = '', $format = '')
......@@ -441,7 +445,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
*
* @param \T3o\TerFe2\Domain\Model\Extension $extension The extension object
* @param array $form Form information for the new version
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
*/
public function uploadVersionAction(\T3o\TerFe2\Domain\Model\Extension $extension, array $form = [])
{
......@@ -457,7 +461,7 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
*
* @param \T3o\TerFe2\Domain\Model\Extension $extension The extension object
* @param array $form Form information for the new version
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
*/
public function createVersionAction(\T3o\TerFe2\Domain\Model\Extension $extension, array $form)
{
......@@ -579,23 +583,28 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
/**
* Check if current frontend user can upload given extension
*
* There is no better (and faster) way to do this at the momement.
* There is no better (and faster) way to do this at the moment.
*
* @param string $extensionKey The extension key
* @return bool TRUE if upload is allowed
*/
protected function userIsAllowedToUploadExtension($extensionKey)
protected function userIsAllowedToUploadExtension($extensionKey): bool
{
$this->frontendUser = (!empty($GLOBALS['TSFE']->fe_user->user) ? $GLOBALS['TSFE']->fe_user->user : []);
if (empty($this->frontendUser['username'])) {
return false;
}
$isAllowedToUploadKey = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_ter_extensionkeys');
$isAllowedToUploadKey = $connection->count(
'uid',
'tx_ter_extensionkeys',
'ownerusername LIKE "' . $GLOBALS['TYPO3_DB']->quoteStr($this->frontendUser['username'], 'foo') . '"
AND extensionkey LIKE "' . $GLOBALS['TYPO3_DB']->quoteStr($extensionKey, 'foo') . '"'
[
'ownerusername' => $this->frontendUser['username'],
'extensionkey' => $extensionKey
]
);
return !empty($isAllowedToUploadKey);
}
......@@ -614,24 +623,31 @@ class ExtensionController extends \T3o\TerFe2\Controller\AbstractController
/**
* Check if an version does not exist for extension
*
* There is no better (and faster) way to do this at the momement.
* There is no better (and faster) way to do this at the moment.
*
* @param string $extensionKey The extension key
* @param string $versionString The extension version
* @return bool TRUE if version already exists
*
* TODO: Discuss with Thomas, logic looks incorrect with naming and return value.
*/
protected function versionIsPossibleForExtension($extensionKey, $versionString)
{
if (empty($extensionKey) || empty($versionString)) {
return false;
}
$versionExistsForExtension = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_ter_extensions');
$versionExistsForExtension = $connection->count(
'uid',
'tx_ter_extensions',
'extensionkey = "' . $GLOBALS['TYPO3_DB']->quoteStr($extensionKey, 'foo') . '"
AND version LIKE "' . $GLOBALS['TYPO3_DB']->quoteStr($versionString, 'foo') . '"'
[
'extensionkey' => $extensionKey,
'version' => $versionString
]
);
return empty($versionExistsForExtension);
return !$versionExistsForExtension;
}
/**
......
......@@ -165,7 +165,7 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
*
* @param string $newUser Username of the assignee
* @param \T3o\TerFe2\Domain\Model\Extension $extension Extension to transfer
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
*/
public function transferAction($newUser, \T3o\TerFe2\Domain\Model\Extension $extension)
{
......@@ -252,7 +252,7 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
* The process for getting expiring extensions will be back in 1 year
*
* @param \T3o\TerFe2\Domain\Model\Extension $extension
* @ignorevalidation $extension
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("extension")
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
*/
public function keepAction(\T3o\TerFe2\Domain\Model\Extension $extension)
......@@ -266,7 +266,7 @@ class RegisterkeyController extends \T3o\TerFe2\Controller\AbstractTerBasedContr
* Delete an extension version from ter server
*
* @param \T3o\TerFe2\Domain\Model\Version $version Extension to delete
* @ignorevalidation $version
* @TYPO3\CMS\Extbase\Annotation\IgnoreValidation("version")
*/
public function deleteExtensionVersionAction(\T3o\TerFe2\Domain\Model\Version $version)
{
......
......@@ -615,4 +615,14 @@ class Extension extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
$this->notifications = $notifications;
}
public function getMatrixOfSupportedTypo3Versions(): array
{
$supportedTypo3Versions = [];
foreach ($this->versions as $version) {
$version->getMatrixOfSupportedTypo3Versions($supportedTypo3Versions);
}
return $supportedTypo3Versions;
}
}
......@@ -21,6 +21,8 @@ use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
*/
class Version extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
const VERSION_IS_INSECURE = -1;
const VERSION_IS_OUTDATED = -2;
/**
* Title of the extension
......@@ -1134,7 +1136,7 @@ class Version extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
}
/**
* @return \T3o\TerFe2\Domain\Model\Relation
* @return \T3o\TerFe2\Domain\Model\Relation|null
*/
public function getTypo3Dependency()
{
......@@ -1151,31 +1153,59 @@ class Version extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
}
/**
* @param array $supportedTypo3Versions
* @return array
*/
public function getMatrixOfSupportedTypo3Versions(): array
public function getMatrixOfSupportedTypo3Versions(array $supportedTypo3Versions = []): array
{
// @todo: Get these versions automatically
$typo3Versions = [
'7 LTS' => 7006000,
'8 LTS' => 8007000,
'9 LTS' => 9005000
];
$supportedTypo3Versions = [];
$ltsVersionService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\T3o\TerFe2\Service\LTSVersionService::class);
$oldLTSVersions = $ltsVersionService->getOldLTSVersions();
$this->getSupportedTypo3Versions($supportedTypo3Versions, $oldLTSVersions, 'warning');
foreach ($typo3Versions as $label => $mainVersion) {
$supportedTypo3Versions[$label] = \T3o\TerFe2\Utility\VersionUtility::doesExtensionSupportTypo3Version($this->getExtension(), $mainVersion);
$currentStableVersions = $ltsVersionService->getCurrentStableVersions(true);
$this->getSupportedTypo3Versions($supportedTypo3Versions, $currentStableVersions, 'success');
if ($this->doesSupportTypo3Version($ltsVersionService->getLatestDevelopmentVersion(true))) {
$supportedTypo3Versions[$ltsVersionService->getVersionLabelOfRelease($ltsVersionService->getLatestDevelopmentVersion(true))] = [
'label' => $ltsVersionService->getVersionLabelOfRelease($ltsVersionService->getLatestDevelopmentVersion(true)) . '-dev',
'badgeClass' => 'info'
];
}
return $supportedTypo3Versions;
}
/**
* @return bool
*/
public function hasTypo3Dependency()
public function doesSupportTypo3Version(int $versionNumber): bool
{
return $this->getTypo3Dependency() !== null;
if ($this->getTypo3Dependency() === null || $this->getReviewState() === \T3o\TerFe2\Domain\Model\Version::VERSION_IS_INSECURE) {
return false;
}
// reset from e.g. 7.6.21 to 7.6.0 for valid check
$resetMinimumVersion = (int)($this->getTypo3Dependency()->getMinimumVersion() / \T3o\TerFe2\Service\LTSVersionService::FACTOR_MINOR_VERSION) * \T3o\TerFe2\Service\LTSVersionService::FACTOR_MINOR_VERSION;
$resetVersionNumber = (int)($versionNumber / \T3o\TerFe2\Service\LTSVersionService::FACTOR_MINOR_VERSION) * \T3o\TerFe2\Service\LTSVersionService::FACTOR_MINOR_VERSION;
$supportsTypo3Version = $resetMinimumVersion <= $versionNumber && $this->getTypo3Dependency()->getMaximumVersion() >= $resetVersionNumber;
if ($supportsTypo3Version) {
return true;
}
return false;
}
private function getSupportedTypo3Versions(array &$supportedTypo3Versions, array $versions, string $badgeClass)
{
$ltsVersionService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\T3o\TerFe2\Service\LTSVersionService::class);
foreach ($versions as $versionNumber) {
$label = $ltsVersionService->getVersionLabelOfRelease($versionNumber) . ' LTS';
if ($this->doesSupportTypo3Version($versionNumber)) {
$supportedTypo3Versions[$ltsVersionService->getVersionLabelOfRelease($versionNumber)] = [
'label' => $label,
'badgeClass' => $badgeClass
];
}
}
}
/**
......
......@@ -107,6 +107,19 @@ class ExtensionRepository extends \T3o\TerFe2\Domain\Repository\AbstractReposito
return $query->execute()->getFirst();
}
/**
* Returns extension by extension key
*
* @param $extensionKey
* @return int
*/
public function countByExtKey($extensionKey)
{
$query = $this->createQuery(0, 1);
$this->match($query, $query->equals('extKey', $extensionKey));
return $query->execute()->count();
}
/**
* Returns new and updated extensions
*
......
......@@ -14,6 +14,8 @@ namespace T3o\TerFe2\Provider;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Abstract extension provider
*/
......@@ -123,7 +125,7 @@ abstract class AbstractProvider implements \T3o\TerFe2\Provider\ProviderInterfac
*/
protected function getVersionByRange($version)
{
$version = \TYPO3\CMS\Extbase\Utility\ArrayUtility::trimExplode('-', $version);
$version = GeneralUtility::trimExplode('-', $version);
$minimum = (!empty($version[0]) ? \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger($version[0]) : 0);
$maximum = (!empty($version[1]) ? \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger($version[1]) : 0);
......
<?php
namespace T3o\TerFe2\Routing\Aspect;
/*
* This file is part of the TYPO3 CMS project.
* This file is part of a TYPO3 extension.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
......@@ -12,37 +14,29 @@
* The TYPO3 project - inspiring people to share!
*/
/**
* TCA label provider
*
* @author Kai Vogel <kai.vogel@speedprogs.de>
*/
class tx_ter_tcaLabel
class VersionMapper implements \TYPO3\CMS\Core\Routing\Aspect\StaticMappableAspectInterface
{
/**
* Returns an extension key by given params
*
* @param array $params Parameters
* @param object $pObj Parent object reference
* @return string
* @var string
*/
public function getExtensionKey(&$params, &$pObj)
{
if (empty($params['row']['uid'])) {
return;
}
protected $versionRegExp = '/(\d+)\.(\d+)\.(\d+)/';
$result = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
'extensionkey',
'tx_ter_extensions',
'uid=' . (int)$params['row']['uid']
);
/**
* @param string $value
* @return string|null
*/
public function generate(string $value): ?string
{
return preg_match($this->versionRegExp, $value) ? $value : null;
}
if (!empty($result['extensionkey'])) {
$params['title'] = htmlspecialchars($result['extensionkey']);
} else {
$params['title'] = (int)$params['row']['uid'];
}
/**
* @param string $value
* @return string|null
*/
public function resolve(string $value): ?string
{
return preg_match($this->versionRegExp, $value) ? $value : null;
}
}