Fixes from phpstan checks, add PHP CI/CD github action
This commit is contained in:
@@ -1,33 +0,0 @@
|
|||||||
name: CI
|
|
||||||
run-name: ${{ github.actor}} runs CI
|
|
||||||
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
phpstan:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# - uses: php-actions/composer@v6
|
|
||||||
# env:
|
|
||||||
# COMPOSER_ROOT_VERSION: dev-master
|
|
||||||
- name: "Restore result cache"
|
|
||||||
uses: actions/cache/restore@v4
|
|
||||||
with:
|
|
||||||
path: ./tmp
|
|
||||||
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
|
|
||||||
restore-keys: |
|
|
||||||
result-cache-v1-${{ matrix.php-version }}-
|
|
||||||
- name: PHPStan Static Analysis
|
|
||||||
uses: php-actions/phpstan@v3
|
|
||||||
with:
|
|
||||||
path: src/
|
|
||||||
- name: "Save result cache"
|
|
||||||
uses: actions/cache/save@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
path: ./tmp
|
|
||||||
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
|
|
||||||
# - name: PHPunit Tests
|
|
||||||
# run: |
|
|
||||||
# vendor/bin/phpunit
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
name: Call PHP Static Checks and Tests
|
||||||
|
run-name: ${{ github.actor }} calls Content.github-actions/php-static-checks-and-tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [master, staging, development]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-check-and-build:
|
||||||
|
# call local if repository name is Composer/CoreLibs-Composer-All.git
|
||||||
|
uses: ${{ github.repository == 'Composer/CoreLibs-Composer-All' && './.github/workflows/php-static-checks-and-tests.yml' || 'OmnicomProduction-Japan/Content.github-actions/.github/workflows/php-static-checks-and-tests.yml@v1' }}
|
||||||
|
with:
|
||||||
|
php-version: '8.4,8.5'
|
||||||
|
composer-directory: './www'
|
||||||
|
source-directory: './www'
|
||||||
|
disable-phan: ${{ vars.DISABLE_PHAN_CHECK == 'true' || false }}
|
||||||
|
secrets:
|
||||||
|
opj-package-user: ${{ secrets.OPJ_PACKAGE_USER }}
|
||||||
|
opj-package-api-key: ${{ secrets.OPJ_PACKAGE_API_KEY }}
|
||||||
|
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
# external call not yet setup, only copy to repo at the moment
|
||||||
|
name: PHP Static Checks and Tests Matrix Workflow
|
||||||
|
run-name: ${{ github.actor}} runs PHP-MATRIX-CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
php-version:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: '8.5'
|
||||||
|
description: 'PHP versions to use for the checks and tests, default is 8.4 and 8.5, can be a comma-separated list of versions'
|
||||||
|
phpunit-version:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: '^13'
|
||||||
|
description: 'PHPUnit versions to use for the tests, default is ^13, can be a comma-separated list of versions'
|
||||||
|
operating-system:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: 'ubuntu-latest'
|
||||||
|
description: 'Operating systems to run the tests on, default is ubuntu-latest, can be a comma-separated list of operating systems'
|
||||||
|
disable-phan:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
|
description: 'Set to "true" to skip running phan'
|
||||||
|
composer-directory:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: './'
|
||||||
|
description: 'Directory where composer.json is located, relative to the repository root'
|
||||||
|
source-directory:
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
default: './src'
|
||||||
|
description: 'Directory where the PHP source code is located, relative to the repository root'
|
||||||
|
secrets:
|
||||||
|
opj-package-user:
|
||||||
|
required: true
|
||||||
|
description: 'Username for private package repository'
|
||||||
|
opj-package-api-key:
|
||||||
|
required: true
|
||||||
|
description: 'API key for private package repository'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
setup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
php-version: ${{ steps.set-matrix.outputs.php-version }}
|
||||||
|
phpunit-version: ${{ steps.set-matrix.outputs.phpunit-version }}
|
||||||
|
operating-system: ${{ steps.set-matrix.outputs.operating-system }}
|
||||||
|
steps:
|
||||||
|
- name: Set matrix values
|
||||||
|
id: set-matrix
|
||||||
|
run: |
|
||||||
|
echo "php-version=$(echo '${{ inputs.php-version }}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R . | jq -cs .)" >> $GITHUB_OUTPUT
|
||||||
|
echo "phpunit-version=$(echo '${{ inputs.phpunit-version }}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R . | jq -cs .)" >> $GITHUB_OUTPUT
|
||||||
|
echo "operating-system=$(echo '${{ inputs.operating-system }}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R . | jq -cs .)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
php-check-and-test-matrix:
|
||||||
|
needs: setup
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
operating-system: ${{fromJSON(needs.setup.outputs.operating-system)}}
|
||||||
|
php-version: ${{fromJSON(needs.setup.outputs.php-version)}}
|
||||||
|
phpunit-version: ${{fromJSON(needs.setup.outputs.phpunit-version)}}
|
||||||
|
# include:
|
||||||
|
# - operating-system: ubuntu-latest
|
||||||
|
# php-version: '8.4'
|
||||||
|
# phpunit-version: '^13'
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php-version }}
|
||||||
|
extensions: mbstring, intl, sqlite, pdo_sqlite
|
||||||
|
# ini-values: post_max_size=256M, max_execution_time=180
|
||||||
|
tools: composer, ${{ inputs.disable-phan == false && 'phan, ' || '' }}phpstan, phpcs, phpunit:${{ matrix.phpunit-version }}, cs2pr
|
||||||
|
# coverage: pcov
|
||||||
|
coverage: xdebug
|
||||||
|
# env:
|
||||||
|
# # Does not work, hast to be set in dependencies step, see below in "install dependencies"
|
||||||
|
# COMPOSER_AUTH: |
|
||||||
|
# {
|
||||||
|
# "http-basic": {
|
||||||
|
# "packages.omnicomproduction.jp": {
|
||||||
|
# "username": "${{ secrets.OPJ_PACKAGE_USER }}",
|
||||||
|
# "password": "${{ secrets.OPJ_PACKAGE_API_KEY }}"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
- name: Check Tools setup
|
||||||
|
id: check-tools
|
||||||
|
run: |
|
||||||
|
REQUIRED_TOOLS=("composer" "phpunit" "phpstan" ${{ inputs.disable-phan == false && '"phan" ' || '' }}"phpcs" "cs2pr")
|
||||||
|
SKIP_IF_FAILED=("phan")
|
||||||
|
for tool in "${REQUIRED_TOOLS[@]}"; do
|
||||||
|
if ! command -v "$tool" &> /dev/null; then
|
||||||
|
if [[ " ${SKIP_IF_FAILED[@]} " =~ " ${tool} " ]]; then
|
||||||
|
echo "⚠️ Warning: $tool is not installed, but it's optional. Skipping..."
|
||||||
|
echo "${tool}=skip" >> $GITHUB_OUTPUT
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo "❌ Error: $tool failed to load!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# the tool path does not have "setup-php/tools/ inside
|
||||||
|
tool_path=$(which "$tool")
|
||||||
|
if [[ "$tool_path" != */setup-php/tools/* ]]; then
|
||||||
|
if [[ " ${SKIP_IF_FAILED[@]} " =~ " ${tool} " ]]; then
|
||||||
|
echo "⚠️ Warning: $tool installation check failed, but it's optional. Skipping..."
|
||||||
|
echo "${tool}=skip" >> $GITHUB_OUTPUT
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo "❌ Error: $tool path lookup failed!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
tool_version=$("$tool" --version 2>&1)
|
||||||
|
echo "✅ $tool loaded successfully: $tool_version ($(which $tool))"
|
||||||
|
echo "${tool}=ok" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
- name: Check source folder and composer.json setup
|
||||||
|
run: |
|
||||||
|
if [ ! -d "${{ inputs.source-directory }}" ]; then
|
||||||
|
echo "❌ Error: Source directory '${{ inputs.source-directory }}' does not exist!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -f "${{ inputs.composer-directory }}/composer.json" ]; then
|
||||||
|
echo "❌ Error: composer.json not found in '${{ inputs.composer-directory }}'!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- name: Setup problem matchers for PHP
|
||||||
|
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||||
|
- name: Setup problem matchers for PHPUnit
|
||||||
|
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
working-directory: ${{ inputs.composer-directory }}
|
||||||
|
|
||||||
|
- name: Cache dependencies
|
||||||
|
uses: actions/cache@v5
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
composer config http-basic.packages.omnicomproduction.jp "${{ secrets.opj-package-user }}" "${{ secrets.opj-package-api-key }}"
|
||||||
|
composer install --prefer-dist
|
||||||
|
working-directory: ${{ inputs.composer-directory }}
|
||||||
|
|
||||||
|
- name: Run composer audit
|
||||||
|
id: run-composer-audit
|
||||||
|
run: composer audit --format=json --no-scripts --no-plugins --no-interaction > composer-audit-output.json
|
||||||
|
# some post action with the composer output format file
|
||||||
|
working-directory: ${{ inputs.composer-directory }}
|
||||||
|
|
||||||
|
- name: Run phpcs
|
||||||
|
id: run-phpcs
|
||||||
|
run: phpcs -q --report=checkstyle --standard=phpcs.xml --ignore=vendor/ ${{ inputs.source-directory }} | cs2pr
|
||||||
|
|
||||||
|
- name: Run phan
|
||||||
|
id: run-phan
|
||||||
|
if: ${{ ! inputs.disable-phan && steps.check-tools.outputs.phan == 'ok' }}
|
||||||
|
run: phan --analyze-twice --no-progress-bar --config-file=./.phan/config.php
|
||||||
|
|
||||||
|
# Must have "./tmp" directory set in configuration
|
||||||
|
# if we have "./tmp/phpstan" or anything different adjust the path below
|
||||||
|
- name: "Restore result cache"
|
||||||
|
uses: actions/cache/restore@v5
|
||||||
|
with:
|
||||||
|
path: ./tmp
|
||||||
|
key: "result-cache-${{ github.run_id }}"
|
||||||
|
restore-keys: |
|
||||||
|
result-cache-v1-
|
||||||
|
- name: Run PHPStan
|
||||||
|
id: run-phpstan
|
||||||
|
run: phpstan analyse --no-progress --configuration=phpstan.neon
|
||||||
|
- name: "Save result cache"
|
||||||
|
uses: actions/cache/save@v5
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
path: ./tmp
|
||||||
|
key: "result-cache-${{ github.run_id }}"
|
||||||
|
|
||||||
|
- name: Test with phpunit
|
||||||
|
id: run-phpunit
|
||||||
|
run: |
|
||||||
|
phpunit --colors=never \
|
||||||
|
--no-coverage \
|
||||||
|
--coverage-text=phpunit-coverage.txt \
|
||||||
|
--only-summary-for-coverage-text \
|
||||||
|
--coverage-openclover=phpunit-openclover.xml
|
||||||
|
|
||||||
|
- name: Code Coverage Summary Report
|
||||||
|
uses: saschanowak/CloverCodeCoverageSummary@1.1.1
|
||||||
|
with:
|
||||||
|
filename: phpunit-openclover.xml
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
if: always()
|
||||||
|
env:
|
||||||
|
COMPOSER_AUDIT_RESULT: ${{ steps.run-composer-audit.outcome }}
|
||||||
|
COMPOSER_AUDIT_FILE: ${{ inputs.composer-directory }}/composer-audit-output.json
|
||||||
|
PHPCS_RESULT: ${{ steps.run-phpcs.outcome }}
|
||||||
|
PHAN_RESULT: ${{ steps.run-phan.outcome }}
|
||||||
|
PHPSTAN_RESULT: ${{ steps.run-phpstan.outcome }}
|
||||||
|
PHPUNIT_RESULT: ${{ steps.run-phpunit.outcome }}
|
||||||
|
run: |
|
||||||
|
icon() { if [[ "$1" == "success" ]]; then echo "✅"; elif [[ "$1" == "skipped" ]]; then echo "⏭️"; else echo "❌"; fi; }
|
||||||
|
row() { echo "<tr><td><b>$1</b></td><td>$(icon $2) $2</td></tr>"; }
|
||||||
|
|
||||||
|
cat >> $GITHUB_STEP_SUMMARY << EOF
|
||||||
|
<h2>PHP CI Results</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Check</th><th>Status</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
$(row "composer audit" "$COMPOSER_AUDIT_RESULT")
|
||||||
|
$(row "phpcs" "$PHPCS_RESULT")
|
||||||
|
$(row "phan" "$PHAN_RESULT")
|
||||||
|
$(row "phpstan" "$PHPSTAN_RESULT")
|
||||||
|
$(row "phpunit" "$PHPUNIT_RESULT")
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Run details</summary>
|
||||||
|
|
||||||
|
| Input | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| PHP version | \`${{ inputs.php-version }}\` |
|
||||||
|
| PHPUnit version | \`${{ inputs.phpunit-version }}\` |
|
||||||
|
| Operating system | \`${{ inputs.operating-system }}\` |
|
||||||
|
| Phan disabled | \`${{ inputs.disable-phan }}\` |
|
||||||
|
| Composer directory | \`${{ inputs.composer-directory }}\` |
|
||||||
|
| Source directory | \`${{ inputs.source-directory }}\` |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ -f phpunit-coverage.txt ]; then
|
||||||
|
{
|
||||||
|
echo "<h3>Code Coverage</h3>"
|
||||||
|
echo ""
|
||||||
|
echo "| Metric | Coverage | Status |"
|
||||||
|
echo "| --- | --- | --- |"
|
||||||
|
grep -E '^\s+(Classes|Methods|Lines):' phpunit-coverage.txt | head -3 | while IFS= read -r line; do
|
||||||
|
name=$(echo "$line" | sed 's/^[[:space:]]*//' | cut -d: -f1)
|
||||||
|
value=$(echo "$line" | cut -d: -f2- | sed 's/^[[:space:]]*//')
|
||||||
|
pct=$(echo "$value" | grep -oE '[0-9]+\.[0-9]+' | head -1)
|
||||||
|
circle=$(awk -v p="$pct" 'BEGIN { if (p+0 == 100) print "🟢"; else if (p+0 >= 60) print "🟠"; else print "🔴" }')
|
||||||
|
echo "| $name | $value | $circle |"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo "<details><summary>Full coverage report</summary>"
|
||||||
|
echo ""
|
||||||
|
echo '```'
|
||||||
|
cat phpunit-coverage.txt
|
||||||
|
echo '```'
|
||||||
|
echo ""
|
||||||
|
echo "</details>"
|
||||||
|
} >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat code-coverage-summary.md >> $GITHUB_STEP_SUMMARY
|
||||||
|
cat code-coverage-details.md >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ -f "$COMPOSER_AUDIT_FILE" ] && jq empty "$COMPOSER_AUDIT_FILE" 2>/dev/null; then
|
||||||
|
{
|
||||||
|
echo "<h3>Composer Audit</h3>"
|
||||||
|
echo ""
|
||||||
|
PACKAGES_AUDITED=$(jq -r '.metadata["packages-audited"] // "?"' "$COMPOSER_AUDIT_FILE")
|
||||||
|
ADVISORIES_COUNT=$(jq -r '.metadata["packages-with-advisories"] // 0' "$COMPOSER_AUDIT_FILE")
|
||||||
|
echo "| Packages audited | With advisories |"
|
||||||
|
echo "| --- | --- |"
|
||||||
|
echo "| $PACKAGES_AUDITED | $ADVISORIES_COUNT |"
|
||||||
|
echo ""
|
||||||
|
ADVISORY_ROWS=$(jq -r '
|
||||||
|
.packages[]
|
||||||
|
| select(.advisories and (.advisories | length) > 0)
|
||||||
|
| .name as $name | .version as $ver
|
||||||
|
| .advisories[]
|
||||||
|
| "| \($name) | \($ver) | \(.cve // "N/A") | \(.title) |"
|
||||||
|
' "$COMPOSER_AUDIT_FILE" 2>/dev/null || true)
|
||||||
|
if [ -n "$ADVISORY_ROWS" ]; then
|
||||||
|
echo "| Package | Version | CVE | Title |"
|
||||||
|
echo "| --- | --- | --- | --- |"
|
||||||
|
echo "$ADVISORY_ROWS"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
echo "<details><summary>Full audit output</summary>"
|
||||||
|
echo ""
|
||||||
|
echo '```json'
|
||||||
|
cat "$COMPOSER_AUDIT_FILE"
|
||||||
|
echo '```'
|
||||||
|
echo ""
|
||||||
|
echo "</details>"
|
||||||
|
} >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phive xmlns="https://phar.io/phive">
|
<phive xmlns="https://phar.io/phive">
|
||||||
<phar name="phpunit" version="^9.6" installed="9.6.31" location="./tools/phpunit" copy="false"/>
|
<phar name="phpunit" version="^9.6" installed="9.6.34" location="./tools/phpunit" copy="false"/>
|
||||||
<phar name="phpcs" version="^4.0.0" installed="4.0.1" location="./tools/phpcs" copy="false"/>
|
<phar name="phpcs" version="^4.0.0" installed="4.0.1" location="./tools/phpcs" copy="false"/>
|
||||||
<phar name="phpcbf" version="^4.0.0" installed="4.0.1" location="./tools/phpcbf" copy="false"/>
|
<phar name="phpcbf" version="^4.0.0" installed="4.0.1" location="./tools/phpcbf" copy="false"/>
|
||||||
<phar name="psalm" version="^5.15.0" installed="5.26.1" location="./tools/psalm" copy="false"/>
|
<phar name="psalm" version="^5.15.0" installed="5.26.1" location="./tools/psalm" copy="false"/>
|
||||||
<phar name="phpstan" version="^2.0.0" installed="2.1.33" location="./tools/phpstan" copy="false"/>
|
<phar name="phpstan" version="^2.0.0" installed="2.2.2" location="./tools/phpstan" copy="false"/>
|
||||||
<phar name="phan" version="^5.4.2" installed="5.5.2" location="./tools/phan" copy="false"/>
|
<phar name="phan" version="^5.4.2" installed="5.5.2" location="./tools/phan" copy="false"/>
|
||||||
</phive>
|
</phive>
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ class Byte
|
|||||||
public static function humanReadableByteFormat(string|int|float $bytes, int $flags = 0): string
|
public static function humanReadableByteFormat(string|int|float $bytes, int $flags = 0): string
|
||||||
{
|
{
|
||||||
// if not numeric, return as is
|
// if not numeric, return as is
|
||||||
if (is_numeric($bytes)) {
|
if (!is_numeric($bytes)) {
|
||||||
|
// if anything other return as string
|
||||||
|
return (string)$bytes;
|
||||||
|
}
|
||||||
// flags bit wise check
|
// flags bit wise check
|
||||||
// remove space between number and suffix
|
// remove space between number and suffix
|
||||||
if ($flags & self::BYTE_FORMAT_NOSPACE) {
|
if ($flags & self::BYTE_FORMAT_NOSPACE) {
|
||||||
@@ -104,10 +107,6 @@ class Byte
|
|||||||
} else {
|
} else {
|
||||||
return round($bytes_calc, 2) . $pre;
|
return round($bytes_calc, 2) . $pre;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// if anything other return as string
|
|
||||||
return (string)$bytes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-3
@@ -2232,9 +2232,9 @@ class IO
|
|||||||
$milliseconds = $matches[13] ?? '';
|
$milliseconds = $matches[13] ?? '';
|
||||||
|
|
||||||
// clean up, hide entries that have 00 in the time group
|
// clean up, hide entries that have 00 in the time group
|
||||||
$hour = $hour != '00' ? preg_replace('/^0/', '', $hour) : '';
|
$hour = !empty($hour) ? preg_replace('/^0/', '', $hour) : '';
|
||||||
$minutes = $minutes != '00' ? preg_replace('/^0/', '', $minutes) : '';
|
$minutes = !empty($minutes) ? preg_replace('/^0/', '', $minutes) : '';
|
||||||
$seconds = $seconds != '00' ? preg_replace('/^0/', '', $seconds) : '';
|
$seconds = !empty($seconds) ? preg_replace('/^0/', '', $seconds) : '';
|
||||||
|
|
||||||
// strip any leading or trailing spaces
|
// strip any leading or trailing spaces
|
||||||
$time_string = trim(
|
$time_string = trim(
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class L10n
|
|||||||
* @param string $locale language name, if not set, try previous set
|
* @param string $locale language name, if not set, try previous set
|
||||||
* @param string $domain set name for mo file, if not set, try previous set
|
* @param string $domain set name for mo file, if not set, try previous set
|
||||||
* @param string $path path, if not set try to get from paths array, else self
|
* @param string $path path, if not set try to get from paths array, else self
|
||||||
* @param string $override_encoding if locale does not env encoding set, use this one
|
* @param string $override_encoding if locale does not have encoding set, use this one
|
||||||
* @return GetTextReader the main gettext reader object
|
* @return GetTextReader the main gettext reader object
|
||||||
*/
|
*/
|
||||||
public function getTranslator(
|
public function getTranslator(
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ enum Level: int
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param value-of<self::NAMES>|LogLevel::*|'Debug'|'Info'|'Notice'|'Warning'|'Error'|'Critical'|'Alert'|'Emergency' $name
|
* @param value-of<self::NAMES>|LogLevel::*|'Debug'|'Info'|'Notice'|'Warning'|'Error'|'Critical'|'Alert'|'Emergency' $name
|
||||||
* @return static
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function fromName(string $name): self
|
public static function fromName(string $name): self
|
||||||
{
|
{
|
||||||
@@ -104,7 +104,7 @@ enum Level: int
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param value-of<self::VALUES> $value
|
* @param value-of<self::VALUES> $value
|
||||||
* @return static
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function fromValue(int $value): self
|
public static function fromValue(int $value): self
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -232,8 +232,15 @@ class Elements
|
|||||||
* @param string $class style sheet
|
* @param string $class style sheet
|
||||||
* @return string correct string for url href process
|
* @return string correct string for url href process
|
||||||
*/
|
*/
|
||||||
private static function createUrl($href, $atag, $_1, $_2, $_3, $name, $class): string
|
private static function createUrl(
|
||||||
{
|
string $href,
|
||||||
|
string $atag,
|
||||||
|
string $_1,
|
||||||
|
string $_2,
|
||||||
|
string $_3,
|
||||||
|
string $name,
|
||||||
|
string $class
|
||||||
|
): string {
|
||||||
// $this->debug('URL', "1: $_1 - 2: $_2 - $_3 - atag: $atag - name: $name - class: $class");
|
// $this->debug('URL', "1: $_1 - 2: $_2 - $_3 - atag: $atag - name: $name - class: $class");
|
||||||
// if $_1 ends with //, then we strip $_1 complete & target is also blanked (its an internal link)
|
// if $_1 ends with //, then we strip $_1 complete & target is also blanked (its an internal link)
|
||||||
if (preg_match("/\/\/$/", $_1) && preg_match("/^\//", $_2)) {
|
if (preg_match("/\/\/$/", $_1) && preg_match("/^\//", $_2)) {
|
||||||
@@ -250,11 +257,8 @@ class Elements
|
|||||||
. "##GT##" . ($name ? $name : $_2 . $_3) . "##LT##/a##GT##";
|
. "##GT##" . ($name ? $name : $_2 . $_3) . "##LT##/a##GT##";
|
||||||
} elseif ($href && !$atag) {
|
} elseif ($href && !$atag) {
|
||||||
return "href=##QUOT##$_1$_2$_3##QUOT##";
|
return "href=##QUOT##$_1$_2$_3##QUOT##";
|
||||||
} elseif ($atag) {
|
|
||||||
return $atag . $_2 . $_3;
|
|
||||||
} else {
|
|
||||||
return $href;
|
|
||||||
}
|
}
|
||||||
|
return $atag . $_2 . $_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -269,8 +273,15 @@ class Elements
|
|||||||
* @param string $class style sheet
|
* @param string $class style sheet
|
||||||
* @return string created html email a href string
|
* @return string created html email a href string
|
||||||
*/
|
*/
|
||||||
private static function createEmail($mailto, $atag, $_1, $_2, $_3, $title, $class)
|
private static function createEmail(
|
||||||
{
|
string $mailto,
|
||||||
|
string $atag,
|
||||||
|
string $_1,
|
||||||
|
string $_2,
|
||||||
|
string $_3,
|
||||||
|
string $title,
|
||||||
|
string $class
|
||||||
|
): string {
|
||||||
$email = $_1 . "@" . $_2 . "." . $_3;
|
$email = $_1 . "@" . $_2 . "." . $_3;
|
||||||
if (!$mailto && !$atag) {
|
if (!$mailto && !$atag) {
|
||||||
return "##LT##a href=##QUOT##mailto:" . $email . "##QUOT##"
|
return "##LT##a href=##QUOT##mailto:" . $email . "##QUOT##"
|
||||||
@@ -278,12 +289,8 @@ class Elements
|
|||||||
. "##GT##" . ($title ? $title : $email) . "##LT##/a##GT##";
|
. "##GT##" . ($title ? $title : $email) . "##LT##/a##GT##";
|
||||||
} elseif ($mailto && !$atag) {
|
} elseif ($mailto && !$atag) {
|
||||||
return "mailto:" . $email;
|
return "mailto:" . $email;
|
||||||
} elseif ($atag) {
|
|
||||||
return $atag . $email;
|
|
||||||
} else {
|
|
||||||
// else just return email as is
|
|
||||||
return $email;
|
|
||||||
}
|
}
|
||||||
|
return $atag . $email;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -954,11 +954,10 @@ class Curl implements Interface\RequestsInterface
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
unset($this->config['headers'][$header_key]);
|
unset($this->config['headers'][$header_key]);
|
||||||
unset($this->headers_named[$header_key]);
|
unset($this->headers_named[strtolower($header_key)]);
|
||||||
} elseif (
|
} elseif (
|
||||||
// string value, array keys = in
|
// right side is array, and value is anything string or array
|
||||||
// or both array and not a full match in the one before
|
// if right side is string, and we give value array, we do nothing
|
||||||
(is_string($value) || is_array($value)) &&
|
|
||||||
is_array($this->config['headers'][$header_key])
|
is_array($this->config['headers'][$header_key])
|
||||||
) {
|
) {
|
||||||
// part remove of key, value must be array
|
// part remove of key, value must be array
|
||||||
@@ -966,10 +965,14 @@ class Curl implements Interface\RequestsInterface
|
|||||||
$value = [$value];
|
$value = [$value];
|
||||||
}
|
}
|
||||||
// array values so we rewrite the key pos
|
// array values so we rewrite the key pos
|
||||||
$this->config['headers'][$header_key] = array_values(array_diff(
|
/** @var array<int|string,string> $headers */
|
||||||
$this->config['headers'][$header_key],
|
$headers = $this->config['headers'][$header_key];
|
||||||
|
$this->config['headers'][$header_key] = array_values(
|
||||||
|
array_diff(
|
||||||
|
$headers,
|
||||||
$value
|
$value
|
||||||
));
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
test.env
|
||||||
Reference in New Issue
Block a user