https://t.me/RX1948
Server : Apache
System : Linux s1230 5.15.0-139-generic #149~20.04.1 SMP Tue Jul 14 11:21:49 UTC 2026 x86_64
User : p141464 ( 418825)
PHP Version : 7.4.33.12
Disable Function : NONE
Directory :  /usr/local/bin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/local/bin/mw-t3uc
#!/bin/bash

SCRIPT_VERSION='1.0.1'
BY='@andrej'

# help
function usage() {
    echo "TYPO3 update checker v${SCRIPT_VERSION}"
    echo
    echo "Usage: ${0} [OPTIONS]"
    echo "Options:"
    echo "   -h    --help                               This help message"
    echo
    echo "   -i    --no-print-inactive                  Disable printing of inactive extensions"
    echo "   -j    --json                               Print as JSON"
    echo "   -m    --no-print-missing                   Disable printing of extensions without defined TYPO3 dependency"
    echo "   -p    --installation-path (required)       Installation path of TYPO3 CMS (like /home/www/p1337/html/typo3/)"
    echo "   -t    --target-version (required)          Check extension compatibility against this TYPO3 version (like 12.4)"
    echo "   -v    --version                            Print version"
    exit 1
}

# get the cli options
[[ "${#}" -le 0 ]] && { echo "missing required arguments"; usage; }

OPTIONS=$(getopt -o hvijmp:t: --long help,version,no-print-inactive,json,no-print-missing,installation-path:,target-version: -- "${@}")
[[ "${?}" -ne 0 ]] && { usage; }
eval set -- "${OPTIONS}"

# set defaults
TYPO3_INSTALL_PATH=""
TYPO3_TARGET_VERSION=""
PRINT_AS_JSON="${PRINT_AS_JSON:-off}" # default off
NO_PRINT_INACTIVE="${NO_PRINT_INACTIVE:-off}" # default off
NO_PRINT_MISSING_DEPENDENCY="${NO_PRINT_MISSING_DEPENDENCY:-off}" # default off

while true; do
    case ${1} in
        -h | --help)                usage
                                    shift
                                    ;;
        -i | --no-print-inactive)   NO_PRINT_INACTIVE="on"
                                    shift
                                    ;;
        -j | --json)                PRINT_AS_JSON="on"
                                    shift
                                    ;;
        -m | --no-print-missing)    NO_PRINT_MISSING_DEPENDENCY="on"
                                    shift
                                    ;;
        -p | --installation-path)   TYPO3_INSTALL_PATH="${2%/}" # docroot like /home/www/{{PROJECT}}/html/typo3 or /html/typo3
                                    shift 2
                                    ;;
        -t | --target-version)      TYPO3_TARGET_VERSION="$( cut -d'.' -f1-2 <<< ${2} )" # MAJOR + MINOR (PATCH level will be cutoff)
                                    shift 2
                                    ;;
        -v | --version)             echo "${SCRIPT_VERSION}" && exit 0
                                    ;;
        --)                         shift
                                    break
                                    ;;
        *)                          break
                                    ;;
    esac
done

[[ -z "${TYPO3_INSTALL_PATH}" ]] || [[ -z "${TYPO3_TARGET_VERSION}" ]] && { echo "missing required arguments"; usage; }

if [[ ! "${TYPO3_INSTALL_PATH}" =~ ^(/home/www/p.*)?/html/.* ]] && [[ ! -d "${TYPO3_INSTALL_PATH}" ]]; then
    echo "wrong installation path: ${TYPO3_INSTALL_PATH}"
    usage
fi

TYPO3_EXTENSION_PATH="${TYPO3_INSTALL_PATH}/typo3conf/ext"
PACKAGESTATE_FILE="${TYPO3_INSTALL_PATH}/typo3conf/PackageStates.php"

# check activation state of an extension
function check_extension_activation_state() {
    local EXT_NAME="${1}"

    ACTIVATION_STATE="$( sed -rne 's/\r$//' -e 's/\t//g' -e "\@^\ *'${EXT_NAME}'@,\@packagePath@{\@packagePath@{s/packagePath//;s/['=>, ]//gp}}" ${PACKAGESTATE_FILE} )"

    if [[ -n "${ACTIVATION_STATE}" ]]; then
        # active when ACTIVATION_STATE is not null
        echo "active"
    else
        echo "inactive"
    fi
}

# check compatibility of extension agains typo3 target version
function check_extension_compatibility() {
    local EXTENSION_MAX_COMPAT_VERSION="$( cut -d'.' -f1-2 <<< ${1#*\-} )" # if it's a version range, get 2nd part after dash, else the remaining (like "9.5")
    local EXTENSION_MIN_COMPAT_VERSION="$( cut -d'.' -f1-2 <<< ${1%\-*} )" # if it's a version range, get 1st part before dash, else the remaining (like "9.5")

    # if EXTENSION_MAX_COMPAT_VERSION matched a string or is empty, assign value 0
    if [[ "${EXTENSION_MAX_COMPAT_VERSION}" =~ [a-zA-Z] ]] || [[ -z "${EXTENSION_MAX_COMPAT_VERSION}" ]]; then
        EXTENSION_MAX_COMPAT_VERSION="0"
    fi

    # if EXTENSION_MIN_COMPAT_VERSION matched a string or is empty, assign value 0
    if [[ "${EXTENSION_MIN_COMPAT_VERSION}" =~ [a-zA-Z] ]] || [[ -z "${EXTENSION_MIN_COMPAT_VERSION}" ]]; then
        EXTENSION_MIN_COMPAT_VERSION="0"
    fi

    # EXTENSION_MAX_COMPAT_VERSION must be greater than or equal to TYPO3_TARGET_VERSION & EXTENSION_MIN_COMPAT_VERSION
    # EXTENSION_MAX_COMPAT_VERSION cannot be 0
    # EXTENSION_MIN_COMPAT_VERSION must be smaller than or equal to TYPO3_TARGET_VERSION
    if [[ $( echo "scale=1;${EXTENSION_MAX_COMPAT_VERSION} > ${EXTENSION_MIN_COMPAT_VERSION}" | bc -lq ) == 1 || ${EXTENSION_MAX_COMPAT_VERSION} == ${EXTENSION_MIN_COMPAT_VERSION} ]] && \
       [[ ${EXTENSION_MAX_COMPAT_VERSION} != 0 ]] && \
       [[ $(echo "scale=1;${EXTENSION_MIN_COMPAT_VERSION} < ${TYPO3_TARGET_VERSION}" | bc -lq ) == 1 || ${EXTENSION_MIN_COMPAT_VERSION} == ${TYPO3_TARGET_VERSION} ]] && \
       [[ $(echo "scale=1;${EXTENSION_MAX_COMPAT_VERSION} > ${TYPO3_TARGET_VERSION}" | bc -lq ) == 1 || ${EXTENSION_MAX_COMPAT_VERSION} == ${TYPO3_TARGET_VERSION} ]]; then
        echo "compatible"
    else
        echo "incompatible"
    fi
}

##################
# JSON functions #
##################

function out() {
    echo -n "${@}"
}

function new_array() {
    out '['
}

function close_array() {
    out ']'
}

function new_object() {
    out '{'
}

function close_object() {
    out '}'
}

function add_key() {
    out "\"${@}\":"
}

function add_value() {
    out "\"${@}\""
}

function add_key_value_pair() {
    out "\"${1}\":\"${2}\""
}

function comma() {
    out ","
}

function prepend_comma() {
    if [[ "${NEXT_OBJECT_MUST_PREPEND_COMMA}" == "True" ]]; then
        comma
        unset NEXT_OBJECT_MUST_PREPEND_COMMA
    fi
}

function print_title_by_condition() {
    if [[ "${PRINT_AS_JSON}" == "on" ]]; then
        prepend_comma
        new_object
        add_key_value_pair "title" "${TITLE}"
        comma
        add_key_value_pair "description" "${DESCRIPTION}"
        comma
        add_key "extensions"
        new_array
    else
        echo "### ${TITLE}"
        echo "${DESCRIPTION}:"
        echo ''
    fi
}

PRINT_TITLE_GEN=true
PRINT_TITLE_INA=true
PRINT_TITLE_DEP=true

function print_title_general() {
    if [[ ${PRINT_TITLE_GEN} == true ]]; then
        local TITLE="Inkompatible Extensions"
        local DESCRIPTION="Die folgenden Extensions sind laut Angabe der Entwickler*innen nicht mit TYPO3 ${TYPO3_TARGET_VERSION} kompatibel"

        print_title_by_condition
    fi
    PRINT_TITLE_GEN=false
}

function print_title_inactive() {
    if [[ ${PRINT_TITLE_INA} == true ]]; then
        local TITLE="Deaktivierte Extensions"
        local DESCRIPTION="Auch wenn die folgenden Extensions inaktiv sind, könnten sie beim Update auf TYPO3 ${TYPO3_TARGET_VERSION} Probleme verursachen, da sie laut Angabe der Entwickler*innen nicht kompatibel sind"
        
        print_title_by_condition
    fi
    PRINT_TITLE_INA=false
}

function print_title_dependency() {
    if [[ ${PRINT_TITLE_DEP} == true ]]; then
        local TITLE="Extensions ohne Abhängigkeit zu TYPO3"
        local DESCRIPTION="Für die folgenden Extensions wurde keine spezifische Version für TYPO3 von den Entwickler*innen festgelegt, daher ist es wahrscheinlich, dass sie nicht mit TYPO3 ${TYPO3_TARGET_VERSION} kompatibel sind"
        
        print_title_by_condition
    fi
    PRINT_TITLE_DEP=false
}

# print extensions as JSON object, or unformatted
function print_extension() {
    if [[ "${PRINT_AS_JSON}" == "on" ]]; then
        new_object
        add_key_value_pair "name" "${1}"
        comma
        add_key_value_pair "version" "${2}"
        close_object
    else
        echo "- ${1} (v${2})"
    fi
}

# do not print these extensions in a loop
function check_ignore_extension() {
    local EXT_NAME="${1}"
    local EXT_TO_IGNORE=(typo3_console)

    for EXT in ${EXT_TO_IGNORE[@]}; do
        if [[ "${EXT}" == "${EXT_NAME}" ]]; then
            echo 'continue'
        fi
    done
}

# get typo3 extensions and versions
function find_extensions() {
    local EXT_CONF_FILES
    local EXT_VERSIONS
    local EXT_DEPENDENCIES
    local PRINT_TYPO3_DEPENDENCY

    # get extension configuration files
    EXT_CONF_FILES=()
    for CONF in $( find ${TYPO3_EXTENSION_PATH}/ -maxdepth 2 -type f -name 'ext_emconf.php' ); do
        if [[ -n "${CONF}" ]]; then
            EXT_CONF_FILES+=("${CONF}") # full path to ext_emconf.php
        fi
    done

    # get extension versions
    EXT_VERSIONS=()
    for FILE in "${EXT_CONF_FILES[@]}"; do
        FILE=${FILE%$'\r'} # remove carriage return "\r"
        VERSION="$( sed -nre 's/\r$//' -e 's/\t//g' -e "/'version'\ /{/[0-9]/s/[\"'=>, version]//g;s/([0-9\.]{1,}).*/\1/gp}" ${FILE} )"
        EXT_VERSIONS+=("${VERSION:-0}") # default value 0
    done

    # get extension dependency versions of typo3
    EXT_DEPENDENCIES=()
    for FILE in "${EXT_CONF_FILES[@]}"; do
        FILE=${FILE%$'\r'} # remove carriage return "\r"
        DEPENDS="$( sed -rne 's/\r$//' -e 's/\t//g' -e "/depends/,/typo3|cms-core/{/typo3|cms-core\>/{s/typo3|cms-core//;s/['=>, \*]//gp}}" ${FILE} )"
        EXT_DEPENDENCIES+=("${DEPENDS:-0}") # default value 0
    done

    #################################
    # print incompatible extensions #
    #################################
    EXTENSION_ARRAY=()
    for ((i=0; i<${#EXT_CONF_FILES[@]}; i++)); do
        EXTENSION_NAME="$( echo ${EXT_CONF_FILES[${i}]%$'\r'} | grep -o 'typo3conf/ext/.*/' | cut -d'/' -f3 )"
        EXTENSION_VERSION="${EXT_VERSIONS[${i}]%$'\r'}"
        EXTENSION_DEPENDENCY="${EXT_DEPENDENCIES[${i}]%$'\r'}"
        EXTENSION_ACTIVATION_STATE="$( check_extension_activation_state "${EXTENSION_NAME}" )"

        if [[ $( check_ignore_extension "${EXTENSION_NAME}" ) == 'continue' ]]; then
            continue
        fi

        RESULT="$( check_extension_compatibility "${EXTENSION_DEPENDENCY}" )"
        if [[ "${RESULT}" == "incompatible" ]]; then

            if [[ "${EXTENSION_ACTIVATION_STATE}" == "inactive" ]]; then
                continue # skip all inactive extensions
            fi

            if [[ ${EXTENSION_DEPENDENCY} == 0 ]]; then
                continue # skip all extensions with missing TYPO3 dependency
            fi
            
            IFS=$'\n'
            EXTENSION_ARRAY+=($(print_extension "${EXTENSION_NAME}" "${EXTENSION_VERSION}"))
        fi
    done

    if [[ ${#EXTENSION_ARRAY[@]} > 0 ]]; then
        print_title_general
        
        if [[ "${PRINT_AS_JSON}" == "on" ]]; then

            for ((elem=0; elem<${#EXTENSION_ARRAY[@]}; elem++)); do
                echo -n "${EXTENSION_ARRAY[${elem}]}"
            
                # add a comma as long elem isn't the last element of EXTENSION_ARRAY
                if [[ ${elem} != $((${#EXTENSION_ARRAY[@]} - 1)) ]]; then
                    comma
                fi
            done

            close_array
            close_object
            NEXT_OBJECT_MUST_PREPEND_COMMA=True

        else
            for ((elem=0; elem<${#EXTENSION_ARRAY[@]}; elem++)); do
                echo "${EXTENSION_ARRAY[${elem}]}"
            done
            echo
        fi
    fi

    #############################
    # print inactive extensions #
    #############################
    #INACTIVE_COUNT=0
    EXTENSION_ARRAY=()
    for ((i=0; i<${#EXT_CONF_FILES[@]}; i++)); do
        EXTENSION_NAME="$( echo ${EXT_CONF_FILES[${i}]%$'\r'} | grep -o 'typo3conf/ext/.*/' | cut -d'/' -f3 )"
        EXTENSION_VERSION="${EXT_VERSIONS[${i}]%$'\r'}"
        EXTENSION_DEPENDENCY="${EXT_DEPENDENCIES[${i}]%$'\r'}"
        EXTENSION_ACTIVATION_STATE="$( check_extension_activation_state "${EXTENSION_NAME}" )"

        if [[ $( check_ignore_extension "${EXTENSION_NAME}" ) == 'continue' ]]; then
            continue
        fi

        RESULT="$( check_extension_compatibility "${EXTENSION_DEPENDENCY}" )"
        if [[ "${RESULT}" == "incompatible" ]]; then

            if [[ ${NO_PRINT_MISSING_DEPENDENCY} == 'on' && ${EXTENSION_DEPENDENCY} == 0 ]]; then
                continue # skip extensions with missing TYPO3 dependency
            fi

            if [[ "${NO_PRINT_INACTIVE}" == 'on' && "${EXTENSION_ACTIVATION_STATE}" == "inactive" ]]; then
                continue # skip inactive extensions
            elif [[ "${NO_PRINT_INACTIVE}" == 'off' && "${EXTENSION_ACTIVATION_STATE}" == "inactive" ]]; then
                IFS=$'\n'
                EXTENSION_ARRAY+=($(print_extension "${EXTENSION_NAME}" "${EXTENSION_VERSION}"))
            fi
        fi
    done

    if [[ ${#EXTENSION_ARRAY[@]} > 0 ]]; then
        print_title_inactive
        
        if [[ "${PRINT_AS_JSON}" == "on" ]]; then

            for ((elem=0; elem<${#EXTENSION_ARRAY[@]}; elem++)); do
                echo -n "${EXTENSION_ARRAY[${elem}]}"
            
                # add a comma as long elem isn't the last element of EXTENSION_ARRAY
                if [[ ${elem} != $((${#EXTENSION_ARRAY[@]} - 1)) ]]; then
                    comma
                fi
            done

            close_array
            close_object
            NEXT_OBJECT_MUST_PREPEND_COMMA=True

        else
            for ((elem=0; elem<${#EXTENSION_ARRAY[@]}; elem++)); do
                echo "${EXTENSION_ARRAY[${elem}]}"
            done
            echo
        fi
    fi

    ##############################################
    # print extensions with missing dependencies #
    ##############################################
    EXTENSION_ARRAY=()
    for ((i=0; i<${#EXT_CONF_FILES[@]}; i++)); do
        EXTENSION_NAME="$( echo ${EXT_CONF_FILES[${i}]%$'\r'} | grep -o 'typo3conf/ext/.*/' | cut -d'/' -f3 )"
        EXTENSION_VERSION="${EXT_VERSIONS[${i}]%$'\r'}"
        EXTENSION_DEPENDENCY="${EXT_DEPENDENCIES[${i}]%$'\r'}"
        EXTENSION_ACTIVATION_STATE="$( check_extension_activation_state "${EXTENSION_NAME}" )"

        if [[ $( check_ignore_extension "${EXTENSION_NAME}" ) == 'continue' ]]; then
            continue
        fi

        RESULT="$( check_extension_compatibility "${EXTENSION_DEPENDENCY}" )"
        if [[ "${RESULT}" == "incompatible" ]]; then

            if [[ "${NO_PRINT_INACTIVE}" == 'on' && "${EXTENSION_ACTIVATION_STATE}" == "inactive" ]]; then
                continue # skip inactive extensions
            fi

            if [[ ${NO_PRINT_MISSING_DEPENDENCY} == 'on' && ${EXTENSION_DEPENDENCY} == 0 ]]; then
                continue # skip extensions with missing TYPO3 dependency
            elif [[ ${NO_PRINT_MISSING_DEPENDENCY} == 'off' && ${EXTENSION_DEPENDENCY} == 0 ]]; then
                IFS=$'\n'
                EXTENSION_ARRAY+=($(print_extension "${EXTENSION_NAME}" "${EXTENSION_VERSION}"))
            fi
        fi
    done

    if [[ ${#EXTENSION_ARRAY[@]} > 0 ]]; then
        print_title_dependency
        
        if [[ "${PRINT_AS_JSON}" == "on" ]]; then

            for ((elem=0; elem<${#EXTENSION_ARRAY[@]}; elem++)); do
                echo -n "${EXTENSION_ARRAY[${elem}]}"
            
                # add a comma as long elem isn't the last element of EXTENSION_ARRAY
                if [[ ${elem} != $((${#EXTENSION_ARRAY[@]} - 1)) ]]; then
                    comma
                fi
            done

            close_array
            close_object
            # end: no comma

        else
            for ((elem=0; elem<${#EXTENSION_ARRAY[@]}; elem++)); do
                echo "${EXTENSION_ARRAY[${elem}]}"
            done
        fi
    fi
}

if [[ "${PRINT_AS_JSON}" == "on" ]]; then
    # wrap a json array around the output
    new_array
    find_extensions # execute script
    close_array
else
    find_extensions # execute script
    echo ''
fi

https://t.me/RX1948 - 2025