diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..862d102d5 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,5 @@ +# End of line reformating +3daf6593d89c608a6660a6c0b872eeb2607548ba +# Convert all tabs to spaces +a4cb0561f627c918cf304663fd32fd2b192f1565 + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b163007b..d26197188 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,13 +13,11 @@ jobs: strategy: fail-fast: false matrix: - php: ['8.0', '8.1', '8.2'] - phpunit: ['9'] + php: ['8.1', '8.2', '8.3', '8.4'] include: - - php: '7.4' - phpunit: '8' - coverage: xdebug - flags: '--coverage-clover clover.xml' + - php: '8.1' + coverage: xdebug + flags: '--coverage-clover clover.xml' services: mysql: @@ -30,17 +28,19 @@ jobs: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: yourls_tests - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + MARIADB_MYSQL_LOCALHOST_USER: 1 + MARIADB_MYSQL_LOCALHOST_GRANTS: USAGE + options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - name: Use PHP ${{ matrix.php }} - uses: shivammathur/setup-php@2.24.0 + uses: shivammathur/setup-php@2.35.5 with: php-version: ${{ matrix.php }} extensions: mbstring, curl, zip, dom, simplexml, intl, pdo_mysql - tools: phpunit:${{ matrix.phpunit }} + tools: phpunit coverage: ${{ matrix.coverage }} # - name: Validate composer.json and composer.lock @@ -71,7 +71,6 @@ jobs: cp tests/data/config/yourls-tests-config-ci.php user/config.php - name: Test - run: phpunit --configuration phpunit.xml.dist ${{ matrix.flags }} + run: phpunit --configuration phpunit.xml.dist --testdox --display-deprecations --display-notices --display-warnings --display-errors ${{ matrix.flags }} env: DB_PORT: ${{ job.services.mysql.ports['3306'] }} - diff --git a/.github/workflows/update-certificates.yml b/.github/workflows/update-certificates.yml index 41e6e96a2..1be5c2a50 100644 --- a/.github/workflows/update-certificates.yml +++ b/.github/workflows/update-certificates.yml @@ -13,6 +13,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: write + pull-requests: write + jobs: certificate-check: name: "Check for updated certificate bundle" @@ -22,7 +26,20 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 + + - name: Generate token + uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ vars.BOT_APP_ID }} + private-key: ${{ secrets.BOT_PRIVATE_KEY }} + + - name: Get GitHub App User ID + id: get-user-id + run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Get current certificate bundle working-directory: ./includes/vendor/rmccue/requests/certificates @@ -42,8 +59,11 @@ jobs: run: echo "DATE=$(/bin/date -u "+%F")" >> $GITHUB_OUTPUT - name: Create pull request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v7 + id: pull-request with: + token: ${{ steps.app-token.outputs.token }} + author: "${{ steps.app-token.outputs.app-slug }}[bot] <${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com>" base: master branch: auto-update-cacert delete-branch: true @@ -55,7 +75,17 @@ jobs: Source: https://curl.se/docs/caextract.html labels: | dependencies - reviewers: | - ozh - LeoColomb - dgw + + - name: Approve a PR + if: ${{ steps.pull-request.outputs.pull-request-url && steps.pull-request.outputs.pull-request-operation != 'none' }} + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{ steps.pull-request.outputs.pull-request-url }} + GITHUB_TOKEN: ${{ github.token }} + + - name: Enable Pull Request Automerge + if: ${{ steps.pull-request.outputs.pull-request-url && steps.pull-request.outputs.pull-request-operation != 'none' }} + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{ steps.pull-request.outputs.pull-request-url }} + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/update-geoip.yml b/.github/workflows/update-geoip.yml index 4bd1207e3..6800cf98e 100644 --- a/.github/workflows/update-geoip.yml +++ b/.github/workflows/update-geoip.yml @@ -13,6 +13,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: write + pull-requests: write + jobs: update-geoip: name: "Check for updated GeoIP DB" @@ -20,14 +24,20 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v5 - name: Generate token - uses: tibdex/github-app-token@v1 - id: generate-token + uses: actions/create-github-app-token@v2 + id: app-token with: - app_id: ${{ secrets.BOT_APP_ID }} - private_key: ${{ secrets.BOT_PRIVATE_KEY }} + app-id: ${{ vars.BOT_APP_ID }} + private-key: ${{ secrets.BOT_PRIVATE_KEY }} + + - name: Get GitHub App User ID + id: get-user-id + run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Check if newer GeoIP DB env: @@ -36,12 +46,12 @@ jobs: URL="https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=${MAXMIND_API_KEY}&suffix=tar.gz" REMOTE_MODIFIED=$(curl --silent --head "$URL" | grep "last-modified" | sed 's/last-modified: //') REMOTE_CTIME=$(date -d "$REMOTE_MODIFIED" +%s) - LOCAL_MODIFIED=$(curl -sL https://api.github.com/repos/YOURLS/YOURLS/commits?path=includes/geo/GeoLite2-Country.mmdb | \ + LOCAL_MODIFIED=$(curl -fsSL https://api.github.com/repos/YOURLS/YOURLS/commits?path=includes/geo/GeoLite2-Country.mmdb | \ jq -r '.[0]["commit"]["author"]["date"]') LOCAL_CTIME=$(date -d "$LOCAL_MODIFIED" +%s) echo "Remote: $REMOTE_CTIME ($(date -d @$REMOTE_CTIME))" echo "Local: $LOCAL_CTIME ($(date -d @$LOCAL_CTIME))" - if [ $LOCAL_CTIME -lt $REMOTE_CTIME ] ; then curl -s "$URL" | tar -zvx -C includes/geo/ --strip-components 1 -- ; fi + if [ $LOCAL_CTIME -lt $REMOTE_CTIME ] ; then curl -fsSL "$URL" | tar -zvx -C includes/geo/ --strip-components 1 -- ; fi - name: "Debug info: Show git status" run: git status -vv --untracked=all @@ -51,9 +61,11 @@ jobs: run: echo "DATE=$(/bin/date -u "+%F")" >> $GITHUB_OUTPUT - name: Create pull request - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v7 + id: pull-request with: - token: ${{ steps.generate-token.outputs.token }} + token: ${{ steps.app-token.outputs.token }} + author: "${{ steps.app-token.outputs.app-slug }}[bot] <${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com>" base: master branch: auto-update-geoip commit-message: "Update GeoIP DB" @@ -64,3 +76,17 @@ jobs: Source: https://www.maxmind.com/en/account/login labels: | dependencies + + - name: Approve a PR + if: ${{ steps.pull-request.outputs.pull-request-url && steps.pull-request.outputs.pull-request-operation != 'none' }} + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{ steps.pull-request.outputs.pull-request-url }} + GITHUB_TOKEN: ${{ github.token }} + + - name: Enable Pull Request Automerge + if: ${{ steps.pull-request.outputs.pull-request-url && steps.pull-request.outputs.pull-request-operation != 'none' }} + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{ steps.pull-request.outputs.pull-request-url }} + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/update-translations.yml b/.github/workflows/update-translations.yml new file mode 100644 index 000000000..9034d576a --- /dev/null +++ b/.github/workflows/update-translations.yml @@ -0,0 +1,115 @@ +name: Update translations + +on: + push: + tags: + - '*' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + translations-check: + name: Check for updated translations + if: ${{ github.event_name != 'schedule' || github.repository == 'YOURLS/YOURLS' }} + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Install GNU gettext + run: sudo apt-get install gettext + + - name: Get version + id: get-version + run: echo "yourls-version=$(php -r 'require "includes/version.php"; echo YOURLS_VERSION;')" >> $GITHUB_OUTPUT + + - name: Extract translations + env: + YOURLS_VERSION: ${{ steps.get-version.outputs.yourls-version }} + run: | + find . -name "*.php" ! -path "./user/*" ! -path "./tests/*" ! -path "./includes/vendor/*" \ + | xargs xgettext \ + --output=YOURLS.pot --package-name=YOURLS --package-version=$YOURLS_VERSION --foreign-user \ + --add-location --language=PHP --from-code=UTF-8 --sort-by-file \ + --keyword=yourls__ \ + --keyword=yourls_e \ + --keyword=yourls_s \ + --keyword=yourls_se \ + --keyword=yourls_esc_attr__ \ + --keyword=yourls_esc_html__ \ + --keyword=yourls_x \ + --keyword=yourls_ex \ + --keyword=yourls_esc_attr_x \ + --keyword=yourls_esc_html_x \ + --keyword=yourls_n:1,2 \ + --keyword=yourls_nx:1,2 \ + --keyword=yourls_n_noop:1,2 \ + --keyword=yourls_nx_noop:1,2 + + - uses: actions/upload-artifact@v4 + with: + name: YOURLS-pot + path: YOURLS.pot + + translations-submit: + name: Submit updated translations + if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'YOURLS/YOURLS' }} + runs-on: ubuntu-latest + needs: + - translations-check + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + repository: YOURLS/YOURLS.pot + + - uses: actions/download-artifact@v5 + with: + name: YOURLS-pot + + - name: Generate token + uses: actions/create-github-app-token@v2 + id: app-token + with: + app-id: ${{ vars.BOT_APP_ID }} + private-key: ${{ secrets.BOT_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - name: Get GitHub App User ID + id: get-user-id + run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + + - name: Show git status + run: git status -vv --untracked=all + + - name: Get date + id: get-date + run: echo "DATE=$(/bin/date -u "+%F")" >> $GITHUB_OUTPUT + + - name: Create pull request + uses: peter-evans/create-pull-request@v7 + id: pull-request + with: + token: ${{ steps.app-token.outputs.token }} + author: "${{ steps.app-token.outputs.app-slug }}[bot] <${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com>" + base: main + branch: auto-update-translations + delete-branch: true + commit-message: "Update translations" + title: "Update translations" + body: | + Updated translations, last verified on ${{ steps.get-date.outputs.DATE }}. + labels: | + dependencies + + - name: Enable Pull Request Automerge + if: ${{ steps.pull-request.outputs.pull-request-url && steps.pull-request.outputs.pull-request-operation != 'none' }} + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{ steps.pull-request.outputs.pull-request-url }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.gitignore b/.gitignore index 3b293ef24..99aa9a942 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,8 @@ Thumbs.db Desktop.ini # Mac crap .DS_Store -# NetBeans files +# IDE files /nbproject/ .idea +.vs +.vscode diff --git a/CHANGELOG.md b/CHANGELOG.md index 58c1ddc09..2beb5f628 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ YOURLS Changelog _This file lists the main changes through all versions of YOURLS. For a much more detailed list, simply refer to [commit messages](https://github.com/YOURLS/YOURLS/commits/master)._ +1.10.2 +--- +- fixed: `admin/tools.php` now uses `yourls_get_nonce_life()` (#3906) +- fixed: "Display 1 to 0 of 0 URLs" on admin list page (#3910) +- fixed: replace deprecated `get_all_options` filter with an action (#3683) +- fixed: defer loading text domain after plugins (#3679) +- removed: Gandi references (#3929) + +1.10.1 +--- +- fixed: sandbox exceptions when disabling plugins (#3893) +- fixed: stats date calculation are now correct (#3895) +- fixed: unexpected warning raised on login page +- removed: unsupported installation cases with Composer + +1.10.0 +--- +- added: Support PHP 8.3 & 8.4 +- removed: Support for PHP prior to 8.1 which is now minimal requirement +- changed: Ensure all `statusCode`/`errorCode` API values are strings (#3756) +- fixed: Results with 0 clicks on search (#3589) +- fixed: Upgrade Aura.SQL to fix PHP 8.4 compatibility (#3852) +- fixed: login page accessibility (#3660) +- fixed: MySQL 8+ compatibility (#3828) +- changed: Upgrade dependencies +- changed: Update GeoIP DB +- changed: Update certificates + 1.9.2 --- - added: Support PHP 8.2 (#3474) diff --git a/README.md b/README.md index ad74448be..1a57344bf 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,15 @@ > Your Own URL Shortener -![CI](https://github.com/YOURLS/YOURLS/workflows/CI/badge.svg) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/YOURLS/YOURLS/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/YOURLS/YOURLS/?branch=master) ![PHP Version Support](https://img.shields.io/packagist/php-v/yourls/yourls) [![Packagist](https://img.shields.io/packagist/v/yourls/yourls.svg)](https://packagist.org/packages/yourls/yourls) [![OpenCollective](https://opencollective.com/yourls/backers/badge.svg)](https://opencollective.com/yourls#contributors) +[![CI](https://github.com/YOURLS/YOURLS/actions/workflows/ci.yml/badge.svg)](https://github.com/YOURLS/YOURLS/actions/workflows/ci.yml) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/YOURLS/YOURLS/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/YOURLS/YOURLS/?branch=master) ![PHP Version Support](https://img.shields.io/packagist/php-v/yourls/yourls) [![Packagist](https://img.shields.io/packagist/v/yourls/yourls.svg)](https://packagist.org/packages/yourls/yourls) [![OpenCollective](https://opencollective.com/yourls/backers/badge.svg)](https://opencollective.com/yourls#contributors) [![OpenCollective](https://opencollective.com/yourls/sponsors/badge.svg)](#sponsors) **YOURLS** is a set of PHP scripts that will allow you to run Your Own URL Shortener, on **your** server. You'll have full control over your data, detailed stats, analytics, plugins, and more. It's free and open-source. -## Quick Start +## Getting Started -Get YOURLS : -* Download the latest [release](https://github.com/YOURLS/YOURLS/releases) -* Using Composer? You can simply `composer create-project yourls/yourls .` in an empty directory. - -Install YOURLS: -* Read [yourls.org](https://yourls.org) for starters -* The complete documentation is on [docs.yourls.org](https://docs.yourls.org) and contains everything from beginners to experts. +Check out the complete documentation on [docs.yourls.org](https://docs.yourls.org). +It contains everything from beginners to experts. ## Community news, tips and tricks @@ -34,7 +29,6 @@ Feature suggestion? Bug to report? __Before opening any issue, please search for existing [issues](https://github.com/YOURLS/YOURLS/issues) (open and closed) and read the [Contributing Guidelines](https://github.com/YOURLS/.github/blob/master/CONTRIBUTING.md).__ - ## Backers Do you use and enjoy YOURLS? [Become a backer](https://opencollective.com/yourls#backer) and show your support to our open source project. diff --git a/admin/admin-ajax.php b/admin/admin-ajax.php index 88de236b2..edfa16a49 100644 --- a/admin/admin-ajax.php +++ b/admin/admin-ajax.php @@ -10,38 +10,38 @@ yourls_no_frame_header(); if( !isset( $_REQUEST['action'] ) ) - die(); + die(); // Pick action $action = $_REQUEST['action']; switch( $action ) { - case 'add': - yourls_verify_nonce( 'add_url', $_REQUEST['nonce'], false, 'omg error' ); - $return = yourls_add_new_link( $_REQUEST['url'], $_REQUEST['keyword'], '', $_REQUEST['rowid'] ); - echo json_encode($return); - break; - - case 'edit_display': - yourls_verify_nonce( 'edit-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); - $row = yourls_table_edit_row ( $_REQUEST['keyword'], $_REQUEST['id'] ); - echo json_encode( array('html' => $row) ); - break; - - case 'edit_save': - yourls_verify_nonce( 'edit-save_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); - $return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['keyword'], $_REQUEST['newkeyword'], $_REQUEST['title'] ); - echo json_encode($return); - break; - - case 'delete': - yourls_verify_nonce( 'delete-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); - $query = yourls_delete_link_by_keyword( $_REQUEST['keyword'] ); - echo json_encode(array('success'=>$query)); - break; - - default: - yourls_do_action( 'yourls_ajax_'.$action ); + case 'add': + yourls_verify_nonce( 'add_url', $_REQUEST['nonce'], false, 'omg error' ); + $return = yourls_add_new_link( $_REQUEST['url'], $_REQUEST['keyword'], '', $_REQUEST['rowid'] ); + echo json_encode($return); + break; + + case 'edit_display': + yourls_verify_nonce( 'edit-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); + $row = yourls_table_edit_row ( $_REQUEST['keyword'], $_REQUEST['id'] ); + echo json_encode( array('html' => $row) ); + break; + + case 'edit_save': + yourls_verify_nonce( 'edit-save_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); + $return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['keyword'], $_REQUEST['newkeyword'], $_REQUEST['title'] ); + echo json_encode($return); + break; + + case 'delete': + yourls_verify_nonce( 'delete-link_'.$_REQUEST['id'], $_REQUEST['nonce'], false, 'omg error' ); + $query = yourls_delete_link_by_keyword( $_REQUEST['keyword'] ); + echo json_encode(array('success'=>$query)); + break; + + default: + yourls_do_action( 'yourls_ajax_'.$action ); } diff --git a/admin/index.php b/admin/index.php index d1919ad71..d3a59861a 100644 --- a/admin/index.php +++ b/admin/index.php @@ -30,17 +30,20 @@ $search_in = $view_params->get_search_in(); $search_in_text = $view_params->get_param_long_name($search_in); if( $search && $search_in && $search_in_text ) { - $search_sentence = yourls_s( 'Searching for %1$s in %2$s.', yourls_esc_html( $search ), yourls_esc_html( $search_in_text ) ); - $search_text = $search; - $search = str_replace( '*', '%', '*' . $search . '*' ); + $search_sentence = yourls_s( 'Searching for %1$s in %2$s.', yourls_esc_html( $search ), yourls_esc_html( $search_in_text ) ); + $search_text = $search; + $search = str_replace( '*', '%', '*' . $search . '*' ); if( $search_in == 'all' ) { - $where['sql'] .= " AND CONCAT_WS('',`keyword`,`url`,`title`,`ip`) LIKE (:search)"; - // Search across all fields. The resulting SQL will be something like: - // SELECT * FROM `yourls_url` WHERE CONCAT_WS('',`keyword`,`url`,`title`,`ip`) LIKE ("%ozh%") - // CONCAT_WS because CONCAT('foo', 'bar', NULL) = NULL. NULL wins. Not sure if values can be NULL now or in the future, so better safe. - // TODO: pay attention to this bit when the DB schema changes + $where['sql'] .= " AND `keyword` LIKE (:search) + OR `url` LIKE (:search) + OR `title` COLLATE utf8mb4_unicode_ci LIKE (:search) COLLATE utf8mb4_unicode_ci + OR `ip` LIKE (:search) "; } else { - $where['sql'] .= " AND `$search_in` LIKE (:search)"; + $collate = ''; + if( $search_in == 'title' ) { + $collate = ' COLLATE utf8mb4_unicode_ci'; + } + $where['sql'] .= " AND `$search_in` $collate LIKE (:search) $collate"; } $where['binds']['search'] = $search; } @@ -96,139 +99,139 @@ // Get URLs Count for current filter, total links in DB & total clicks list( $total_urls, $total_clicks ) = array_values( yourls_get_db_stats() ); if ( !empty($where['sql']) ) { - list( $total_items, $total_items_clicks ) = array_values( yourls_get_db_stats( $where ) ); + list( $total_items, $total_items_clicks ) = array_values( yourls_get_db_stats( $where ) ); } else { - $total_items = $total_urls; - $total_items_clicks = false; + $total_items = $total_urls; + $total_items_clicks = false; } // This is a bookmarklet if ( isset( $_GET['u'] ) or isset( $_GET['up'] ) ) { - $is_bookmark = true; - yourls_do_action( 'bookmarklet' ); - - // No sanitization needed here: everything happens in yourls_add_new_link() - if( isset( $_GET['u'] ) ) { - // Old school bookmarklet: ?u= - $url = $_GET['u']; - } else { - // New style bookmarklet: ?up=&us=&ur= - $url = $_GET['up'] . $_GET['us'] . $_GET['ur']; - } - $keyword = ( isset( $_GET['k'] ) ? ( $_GET['k'] ) : '' ); - $title = ( isset( $_GET['t'] ) ? ( $_GET['t'] ) : '' ); - $return = yourls_add_new_link( $url, $keyword, $title ); - - // If fails because keyword already exist, retry with no keyword - if ( isset( $return['status'] ) && $return['status'] == 'fail' && isset( $return['code'] ) && $return['code'] == 'error:keyword' ) { - $msg = $return['message']; - $return = yourls_add_new_link( $url, '' ); - $return['message'] .= ' ('.$msg.')'; - } - - // Stop here if bookmarklet with a JSON callback function - if( isset( $_GET['jsonp'] ) && $_GET['jsonp'] == 'yourls' ) { - $short = $return['shorturl'] ? $return['shorturl'] : ''; - $message = $return['message']; - yourls_content_type_header( 'application/javascript' ); - echo yourls_apply_filter( 'bookmarklet_jsonp', "yourls_callback({'short_url':'$short','message':'$message'});" ); - - die(); - } - - // Now use the URL that has been sanitized and returned by yourls_add_new_link() - $url = $return['url']['url']; - $where['sql'] .= ' AND `url` LIKE :url '; + $is_bookmark = true; + yourls_do_action( 'bookmarklet' ); + + // No sanitization needed here: everything happens in yourls_add_new_link() + if( isset( $_GET['u'] ) ) { + // Old school bookmarklet: ?u= + $url = $_GET['u']; + } else { + // New style bookmarklet: ?up=&us=&ur= + $url = $_GET['up'] . $_GET['us'] . $_GET['ur']; + } + $keyword = ( isset( $_GET['k'] ) ? ( $_GET['k'] ) : '' ); + $title = ( isset( $_GET['t'] ) ? ( $_GET['t'] ) : '' ); + $return = yourls_add_new_link( $url, $keyword, $title ); + + // If fails because keyword already exist, retry with no keyword + if ( isset( $return['status'] ) && $return['status'] == 'fail' && isset( $return['code'] ) && $return['code'] == 'error:keyword' ) { + $msg = $return['message']; + $return = yourls_add_new_link( $url, '' ); + $return['message'] .= ' ('.$msg.')'; + } + + // Stop here if bookmarklet with a JSON callback function + if( isset( $_GET['jsonp'] ) && $_GET['jsonp'] == 'yourls' ) { + $short = $return['shorturl'] ? $return['shorturl'] : ''; + $message = $return['message']; + yourls_content_type_header( 'application/javascript' ); + echo yourls_apply_filter( 'bookmarklet_jsonp', "yourls_callback({'short_url':'$short','message':'$message'});" ); + + die(); + } + + // Now use the URL that has been sanitized and returned by yourls_add_new_link() + $url = $return['url']['url']; + $where['sql'] .= ' AND `url` LIKE :url '; $where['binds']['url'] = $url; - $page = $total_pages = $perpage = 1; - $offset = 0; - - $text = ( isset( $_GET['s'] ) ? stripslashes( $_GET['s'] ) : '' ); - - // Sharing with social bookmarklets - if( !empty($_GET['share']) ) { - yourls_do_action( 'pre_share_redirect' ); - switch ( $_GET['share'] ) { - case 'twitter': - // share with Twitter - $destination = sprintf( "https://twitter.com/intent/tweet?url=%s&text=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); - yourls_redirect( $destination, 303 ); - - // Deal with the case when redirection failed: - $return['status'] = 'error'; - $return['errorCode'] = 400; - $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Twitter' ); - break; - - case 'facebook': - // share with Facebook - $destination = sprintf( "https://www.facebook.com/sharer/sharer.php?u=%s&t=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); - yourls_redirect( $destination, 303 ); - - // Deal with the case when redirection failed: - $return['status'] = 'error'; - $return['errorCode'] = 400; - $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Facebook' ); - break; - - case 'tumblr': - // share with Tumblr - $destination = sprintf( "https://www.tumblr.com/share?v=3&u=%s&t=%s&s=%s", urlencode( $return['shorturl'] ), urlencode( $title ), urlencode( $text ) ); - yourls_redirect( $destination, 303 ); - - // Deal with the case when redirection failed: - $return['status'] = 'error'; - $return['errorCode'] = 400; - $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Tumblr' ); - break; - - default: - // Is there a custom registered social bookmark? - yourls_do_action( 'share_redirect_' . $_GET['share'], $return ); - - // Still here? That was an unknown 'share' method, then. - $return['status'] = 'error'; - $return['errorCode'] = 400; - $return['message'] = yourls__( 'Unknown "Share" bookmarklet' ); - break; - } - } + $page = $total_pages = $perpage = 1; + $offset = 0; + + $text = ( isset( $_GET['s'] ) ? stripslashes( $_GET['s'] ) : '' ); + + // Sharing with social bookmarklets + if( !empty($_GET['share']) ) { + yourls_do_action( 'pre_share_redirect' ); + switch ( $_GET['share'] ) { + case 'twitter': + // share with Twitter + $destination = sprintf( "https://twitter.com/intent/tweet?url=%s&text=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); + yourls_redirect( $destination, 303 ); + + // Deal with the case when redirection failed: + $return['status'] = 'error'; + $return['errorCode'] = '400'; + $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Twitter' ); + break; + + case 'facebook': + // share with Facebook + $destination = sprintf( "https://www.facebook.com/sharer/sharer.php?u=%s&t=%s", urlencode( $return['shorturl'] ), urlencode( $title ) ); + yourls_redirect( $destination, 303 ); + + // Deal with the case when redirection failed: + $return['status'] = 'error'; + $return['errorCode'] = '400'; + $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Facebook' ); + break; + + case 'tumblr': + // share with Tumblr + $destination = sprintf( "https://www.tumblr.com/share?v=3&u=%s&t=%s&s=%s", urlencode( $return['shorturl'] ), urlencode( $title ), urlencode( $text ) ); + yourls_redirect( $destination, 303 ); + + // Deal with the case when redirection failed: + $return['status'] = 'error'; + $return['errorCode'] = '400'; + $return['message'] = yourls_s( 'Short URL created, but could not redirect to %s !', 'Tumblr' ); + break; + + default: + // Is there a custom registered social bookmark? + yourls_do_action( 'share_redirect_' . $_GET['share'], $return ); + + // Still here? That was an unknown 'share' method, then. + $return['status'] = 'error'; + $return['errorCode'] = '400'; + $return['message'] = yourls__( 'Unknown "Share" bookmarklet' ); + break; + } + } // This is not a bookmarklet } else { - $is_bookmark = false; - - // Checking $page, $offset, $perpage - if( empty($page) || $page == 0 ) { - $page = 1; - } - if( empty($offset) ) { - $offset = 0; - } - if( empty($perpage) || $perpage == 0) { - $perpage = 50; - } - - // Determine $offset - $offset = ( $page-1 ) * $perpage; - - // Determine Max Number Of Items To Display On Page - if( ( $offset + $perpage ) > $total_items ) { - $max_on_page = $total_items; - } else { - $max_on_page = ( $offset + $perpage ); - } - - // Determine Number Of Items To Display On Page - if ( ( $offset + 1 ) > $total_items ) { - $display_on_page = $total_items; - } else { - $display_on_page = ( $offset + 1 ); - } - - // Determine Total Amount Of Pages - $total_pages = ceil( $total_items / $perpage ); + $is_bookmark = false; + + // Checking $page, $offset, $perpage + if( empty($page) || $page == 0 ) { + $page = 1; + } + if( empty($offset) ) { + $offset = 0; + } + if( empty($perpage) || $perpage == 0) { + $perpage = 50; + } + + // Determine $offset + $offset = ( $page-1 ) * $perpage; + + // Determine Max Number Of Items To Display On Page + if( ( $offset + $perpage ) > $total_items ) { + $max_on_page = $total_items; + } else { + $max_on_page = ( $offset + $perpage ); + } + + // Determine Number Of Items To Display On Page + if ( ( $offset + 1 ) > $total_items ) { + $display_on_page = $total_items; + } else { + $display_on_page = ( $offset + 1 ); + } + + // Determine Total Amount Of Pages + $total_pages = ceil( $total_items / $perpage ); } @@ -241,12 +244,18 @@ yourls_do_action( 'admin_page_before_content' ); if ( !$is_bookmark ) { ?> -

-

%1$s to %2$s of %3$s URLs' ), $display_on_page, $max_on_page, $total_items ); - if( $total_items_clicks !== false ) - echo ", " . sprintf( yourls_n( 'counting 1 click', 'counting %s clicks', $total_items_clicks ), yourls_number_format_i18n( $total_items_clicks ) ); - ?>.

+

+

%1$s to %2$s of %3$s URLs' ), $display_on_page, $max_on_page, $total_items ); + if( $total_items_clicks !== false ) + echo ", " . sprintf( yourls_n( 'counting 1 click', 'counting %s clicks', $total_items_clicks ), yourls_number_format_i18n( $total_items_clicks ) ); + } + ?>.

%1$s links, %2$s clicks, and counting!' ), yourls_number_format_i18n( $total_urls ), yourls_number_format_i18n( $total_clicks ) ); ?>

$(document).ready(function(){ - feedback( "' . $return['message'] . '", "'. $return['status'] .'"); - init_clipboard(); - });'; + echo ''; } yourls_do_action( 'admin_page_before_table' ); @@ -270,22 +279,22 @@ yourls_table_head(); if ( !$is_bookmark ) { - $params = array( - 'search' => $search, - 'search_text' => $search_text, - 'search_in' => $search_in, - 'sort_by' => $sort_by, - 'sort_order' => $sort_order, - 'page' => $page, - 'perpage' => $perpage, - 'click_filter' => $click_filter, - 'click_limit' => $click_limit, - 'total_pages' => $total_pages, - 'date_filter' => $date_filter, - 'date_first' => $date_first, - 'date_second' => $date_second, - ); - yourls_html_tfooter( $params ); + $params = array( + 'search' => $search, + 'search_text' => $search_text, + 'search_in' => $search_in, + 'sort_by' => $sort_by, + 'sort_order' => $sort_order, + 'page' => $page, + 'perpage' => $perpage, + 'click_filter' => $click_filter, + 'click_limit' => $click_limit, + 'total_pages' => $total_pages, + 'date_filter' => $date_filter, + 'date_first' => $date_first, + 'date_second' => $date_second, + ); + yourls_html_tfooter( $params ); } yourls_table_tbody_start(); @@ -295,17 +304,17 @@ $url_results = yourls_get_db()->fetchObjects( "SELECT * FROM `$table_url` WHERE 1=1 {$where['sql']} ORDER BY `$sort_by` $sort_order LIMIT $offset, $perpage;", $where['binds'] ); $found_rows = false; if( $url_results ) { - $found_rows = true; - foreach( $url_results as $url_result ) { - $keyword = yourls_sanitize_keyword($url_result->keyword); - $timestamp = strtotime( $url_result->timestamp ); - $url = stripslashes( $url_result->url ); - $ip = $url_result->ip; - $title = $url_result->title ? $url_result->title : ''; - $clicks = $url_result->clicks; - - echo yourls_table_add_row( $keyword, $url, $title, $ip, $clicks, $timestamp ); - } + $found_rows = true; + foreach( $url_results as $url_result ) { + $keyword = yourls_sanitize_keyword($url_result->keyword); + $timestamp = strtotime( $url_result->timestamp ); + $url = stripslashes( $url_result->url ); + $ip = $url_result->ip; + $title = $url_result->title ? $url_result->title : ''; + $clicks = $url_result->clicks; + + echo yourls_table_add_row( $keyword, $url, $title, $ip, $clicks, $timestamp ); + } } $display = $found_rows ? 'display:none' : ''; @@ -318,7 +327,7 @@ yourls_do_action( 'admin_page_after_table' ); if ( $is_bookmark ) - yourls_share_box( $url, $return['shorturl'], $title, $text ); + yourls_share_box( $url, $return['shorturl'], $title, $text ); ?> diff --git a/admin/install.php b/admin/install.php index 3b004508c..3d4b99a1a 100644 --- a/admin/install.php +++ b/admin/install.php @@ -9,44 +9,44 @@ // Check pre-requisites if ( !yourls_check_PDO() ) { - $error[] = yourls__( 'PHP extension for PDO not found' ); - yourls_debug_log( 'PHP PDO extension not found' ); + $error[] = yourls__( 'PHP extension for PDO not found' ); + yourls_debug_log( 'PHP PDO extension not found' ); } if ( !yourls_check_database_version() ) { - $error[] = yourls_s( '%s version is too old. Ask your server admin for an upgrade.', 'MySQL' ); - yourls_debug_log( 'MySQL version: ' . yourls_get_database_version() ); + $error[] = yourls_s( '%s version is too old. Ask your server admin for an upgrade.', 'MySQL' ); + yourls_debug_log( 'MySQL version: ' . yourls_get_database_version() ); } if ( !yourls_check_php_version() ) { - $error[] = yourls_s( '%s version is too old. Ask your server admin for an upgrade.', 'PHP' ); - yourls_debug_log( 'PHP version: ' . PHP_VERSION ); + $error[] = yourls_s( '%s version is too old. Ask your server admin for an upgrade.', 'PHP' ); + yourls_debug_log( 'PHP version: ' . PHP_VERSION ); } // Is YOURLS already installed ? if ( yourls_is_installed() ) { - $error[] = yourls__( 'YOURLS already installed.' ); - // check if .htaccess exists, recreate otherwise. No error checking. - if( !file_exists( YOURLS_ABSPATH.'/.htaccess' ) ) { - yourls_create_htaccess(); - } + $error[] = yourls__( 'YOURLS already installed.' ); + // check if .htaccess exists, recreate otherwise. No error checking. + if( !file_exists( YOURLS_ABSPATH.'/.htaccess' ) ) { + yourls_create_htaccess(); + } } // Start install if possible and needed if ( isset($_REQUEST['install']) && count( $error ) == 0 ) { - // Create/update .htaccess file - if ( yourls_create_htaccess() ) { - $success[] = yourls__( 'File .htaccess successfully created/updated.' ); - } else { - $warning[] = yourls__( 'Could not write file .htaccess in YOURLS root directory. You will have to do it manually. See how.' ); - } + // Create/update .htaccess file + if ( yourls_create_htaccess() ) { + $success[] = yourls__( 'File .htaccess successfully created/updated.' ); + } else { + $warning[] = yourls__( 'Could not write file .htaccess in YOURLS root directory. You will have to do it manually. See how.' ); + } - // Create SQL tables - $install = yourls_create_sql_tables(); - if ( isset( $install['error'] ) ) - $error = array_merge( $error, $install['error'] ); - if ( isset( $install['success'] ) ) - $success = array_merge( $success, $install['success'] ); + // Create SQL tables + $install = yourls_create_sql_tables(); + if ( isset( $install['error'] ) ) + $error = array_merge( $error, $install['error'] ); + if ( isset( $install['success'] ) ) + $success = array_merge( $success, $install['success'] ); } @@ -54,30 +54,30 @@ yourls_html_head( 'install', yourls__( 'Install YOURLS' ) ); ?>
-
-

- -

- 0 ) { - echo "
    "; - foreach( $$info as $msg ) { - echo '
  • '.$msg."
  • \n"; - } - echo '
'; - } - } + +

+ +

+ 0 ) { + echo "
    "; + foreach( $$info as $msg ) { + echo '
  • '.$msg."
  • \n"; + } + echo '
'; + } + } - // Display install button or link to admin area if applicable - if( !yourls_is_installed() && !isset($_REQUEST['install']) ) { - echo '

'; - } else { - if( count($error) == 0 ) - echo '

» ' . yourls__( 'YOURLS Administration Page') . '

'; - } - ?> -
+ // Display install button or link to admin area if applicable + if( !yourls_is_installed() && !isset($_REQUEST['install']) ) { + echo '

'; + } else { + if( count($error) == 0 ) + echo '

» ' . yourls__( 'YOURLS Administration Page') . '

'; + } + ?> +
diff --git a/admin/plugins.php b/admin/plugins.php index ad81339e8..8d02b96dd 100644 --- a/admin/plugins.php +++ b/admin/plugins.php @@ -5,56 +5,56 @@ // Handle plugin administration pages if( isset( $_GET['page'] ) && !empty( $_GET['page'] ) ) { - yourls_plugin_admin_page( $_GET['page'] ); + yourls_plugin_admin_page( $_GET['page'] ); die(); } // Handle activation/deactivation of plugins if( isset( $_GET['action'] ) ) { - // Check nonce - yourls_verify_nonce( 'manage_plugins', $_REQUEST['nonce'] ?? ''); + // Check nonce + yourls_verify_nonce( 'manage_plugins', $_REQUEST['nonce'] ?? ''); - // Check plugin file is valid - if(isset( $_GET['plugin'] ) && yourls_is_a_plugin_file(YOURLS_PLUGINDIR . '/' . $_GET['plugin'] . '/plugin.php') ) { + // Check plugin file is valid + if(isset( $_GET['plugin'] ) && yourls_is_a_plugin_file(YOURLS_PLUGINDIR . '/' . $_GET['plugin'] . '/plugin.php') ) { - // Activate / Deactive - switch( $_GET['action'] ) { - case 'activate': - $result = yourls_activate_plugin( $_GET['plugin'].'/plugin.php' ); - if( $result === true ) { + // Activate / Deactive + switch( $_GET['action'] ) { + case 'activate': + $result = yourls_activate_plugin( $_GET['plugin'].'/plugin.php' ); + if( $result === true ) { yourls_redirect(yourls_admin_url('plugins.php?success=activated'), 302); exit(); } - break; + break; - case 'deactivate': - $result = yourls_deactivate_plugin( $_GET['plugin'].'/plugin.php' ); - if( $result === true ) { + case 'deactivate': + $result = yourls_deactivate_plugin( $_GET['plugin'].'/plugin.php' ); + if( $result === true ) { yourls_redirect(yourls_admin_url('plugins.php?success=deactivated'), 302); exit(); } - break; + break; - default: - $result = yourls__( 'Unsupported action' ); - break; - } - } else { - $result = yourls__( 'No plugin specified, or not a valid plugin' ); - } + default: + $result = yourls__( 'Unsupported action' ); + break; + } + } else { + $result = yourls__( 'No plugin specified, or not a valid plugin' ); + } - yourls_add_notice( $result ); + yourls_add_notice( $result ); } // Handle message upon successful (de)activation if( isset( $_GET['success'] ) && ( ( $_GET['success'] == 'activated' ) OR ( $_GET['success'] == 'deactivated' ) ) ) { - if( $_GET['success'] == 'activated' ) { - $message = yourls__( 'Plugin has been activated' ); - } elseif ( $_GET['success'] == 'deactivated' ) { - $message = yourls__( 'Plugin has been deactivated' ); - } - yourls_add_notice( $message ); + if( $_GET['success'] == 'activated' ) { + $message = yourls__( 'Plugin has been activated' ); + } elseif ( $_GET['success'] == 'deactivated' ) { + $message = yourls__( 'Plugin has been deactivated' ); + } + yourls_add_notice( $message ); } yourls_html_head( 'plugins', yourls__( 'Manage Plugins' ) ); @@ -62,106 +62,110 @@ yourls_html_menu(); ?> -
-

- - - -

%1$s installed, and %2$s activated', $plugins_count, $count_active ); ?>

- - - - - - - - - - - - - $plugin ) { - - // default fields to read from the plugin header - $fields = array( - 'name' => 'Plugin Name', - 'uri' => 'Plugin URI', - 'desc' => 'Description', - 'version' => 'Version', - 'author' => 'Author', - 'author_uri' => 'Author URI' - ); - - // Loop through all default fields, get value if any and reset it - foreach( $fields as $field=>$value ) { - if( isset( $plugin[ $value ] ) ) { - $data[ $field ] = $plugin[ $value ]; - } else { - $data[ $field ] = yourls__('(no info)'); - } - unset( $plugin[$value] ); - } - - $plugindir = trim( dirname( $file ), '/' ); - - if( yourls_is_active_plugin( $file ) ) { - $class = 'active'; - $action_url = yourls_nonce_url( 'manage_plugins', yourls_add_query_arg( array('action' => 'deactivate', 'plugin' => $plugindir ), yourls_admin_url('plugins.php') ) ); - $action_anchor = yourls__( 'Deactivate' ); - } else { - $class = 'inactive'; - $action_url = yourls_nonce_url( 'manage_plugins', yourls_add_query_arg( array('action' => 'activate', 'plugin' => $plugindir ), yourls_admin_url('plugins.php') ) ); - $action_anchor = yourls__( 'Activate' ); - } - - // Other "Fields: Value" in the header? Get them too - if( $plugin ) { - foreach( $plugin as $extra_field=>$extra_value ) { - $data['desc'] .= "
\n$extra_field: $extra_value"; - unset( $plugin[$extra_value] ); - } - } - - $data['desc'] .= '
' . yourls_s( 'plugin file location: %s', $file) . ''; - - printf( "", - $class, $data['uri'], $data['name'], $data['version'], $data['desc'], $data['author_uri'], $data['author'], $action_url, $action_anchor - ); - - } - ?> - -
%s%s%s%s%s
- - - -

plugin.php.' ); ?>

- -

- -

Plugin list.' ); ?>

-
+
+

+ + + +

%1$s installed, and %2$s activated', $plugins_count, $count_active ); ?>

+ + + + + + + + + + + + + $plugin ) { + + // default fields to read from the plugin header + $fields = array( + 'name' => 'Plugin Name', + 'uri' => 'Plugin URI', + 'desc' => 'Description', + 'version' => 'Version', + 'author' => 'Author', + 'author_uri' => 'Author URI' + ); + + // Loop through all default fields, get value if any and reset it + foreach( $fields as $field=>$value ) { + if( isset( $plugin[ $value ] ) ) { + $data[ $field ] = $plugin[ $value ]; + } else { + $data[ $field ] = yourls__('(no info)'); + # If it's a URL, set to # + if( in_array( $field, array('uri', 'author_uri') ) ) { + $data[$field] = '#' . $data[$field]; + } + } + unset( $plugin[$value] ); + } + + $plugindir = trim( dirname( $file ), '/' ); + + if( yourls_is_active_plugin( $file ) ) { + $class = 'active'; + $action_url = yourls_nonce_url( 'manage_plugins', yourls_add_query_arg( array('action' => 'deactivate', 'plugin' => $plugindir ), yourls_admin_url('plugins.php') ) ); + $action_anchor = yourls__( 'Deactivate' ); + } else { + $class = 'inactive'; + $action_url = yourls_nonce_url( 'manage_plugins', yourls_add_query_arg( array('action' => 'activate', 'plugin' => $plugindir ), yourls_admin_url('plugins.php') ) ); + $action_anchor = yourls__( 'Activate' ); + } + + // Other "Fields: Value" in the header? Get them too + if( $plugin ) { + foreach( $plugin as $extra_field=>$extra_value ) { + $data['desc'] .= "
\n$extra_field: $extra_value"; + unset( $plugin[$extra_value] ); + } + } + + $data['desc'] .= '
' . yourls_s( 'plugin file location: %s', $file) . ''; + + printf( "", + $class, $data['uri'], $data['name'], $data['version'], $data['desc'], $data['author_uri'], $data['author'], $action_url, $action_anchor + ); + + } + ?> + +
%s%s%s%s%s
+ + + +

plugin.php.' ); ?>

+ +

+ +

Plugin list.' ); ?>

+
diff --git a/admin/tools.php b/admin/tools.php index fd1d167b5..b77206169 100644 --- a/admin/tools.php +++ b/admin/tools.php @@ -8,49 +8,49 @@ yourls_html_menu(); ?> -
+
-

+

-

bookmarklets for easier link shortening and sharing.' ); ?>

+

bookmarklets for easier link shortening and sharing.' ); ?>

-

+

-
    -
  • Standard Bookmarklets will take you to a page where you can easily edit or delete your brand new short URL.' ); ?>
  • +
      +
    • Standard Bookmarklets will take you to a page where you can easily edit or delete your brand new short URL.' ); ?>
    • -
    • Instant Bookmarklets will pop the short URL without leaving the page you are viewing (depending on the page and server configuration, they may silently fail)' ); ?>
    • +
    • Instant Bookmarklets will pop the short URL without leaving the page you are viewing (depending on the page and server configuration, they may silently fail)' ); ?>
    • -
    • Simple Bookmarklets will generate a short URL with a random or sequential keyword.' ); ?>
    • +
    • Simple Bookmarklets will generate a short URL with a random or sequential keyword.' ); ?>
    • -
    • Custom Keyword Bookmarklets will prompt you for a custom keyword first.' ); ?>
    • -
    +
  • Custom Keyword Bookmarklets will prompt you for a custom keyword first.' ); ?>
  • +
-

select text on the page you're viewing before clicking on your bookmarklet link" ); - ?>

+

select text on the page you're viewing before clicking on your bookmarklet link" ); + ?>

Important Note: bookmarklets may fail on websites with https, especially the "Instant" bookrmarklets. There is nothing you can do about this.'); ?>

-

+

-

+

- - - - - - - - - - - - + + + + + + + + + + + - - - + + - - - -
 
+
 
+
+
+ + + -

+

-

-

+

+

-

+

- + -

+

-

+

-

%s\" to the beginning of the current URL (right before its 'http://' part) and hit enter.", preg_replace('@https?://@', '', yourls_get_yourls_site()) . '/' ); ?>

+

%s\" to the beginning of the current URL (right before its 'http://' part) and hit enter.", preg_replace('@https?://@', '', yourls_get_yourls_site()) . '/' ); ?>

-

.

+

.

- + -

+

-

username and password parameters.' ); - echo "\n"; - yourls_e( "If you're worried about sending your credentials into the wild, you can also make API calls without using your login or your password, using a secret signature token." ); - ?>

+

username and password parameters.' ); + echo "\n"; + yourls_e( "If you're worried about sending your credentials into the wild, you can also make API calls without using your login or your password, using a secret signature token." ); + ?>

-

%s', yourls_auth_signature() ); ?> +

%s', yourls_auth_signature() ); ?>

-

+

-
    -
  • -

    signature in your API requests. Example:' ); ?>

    -

    /yourls-api.php?signature=&action=...

    -
  • +
      +
    • +

      signature in your API requests. Example:' ); ?>

      +

      /yourls-api.php?signature=&action=...

      +
    • -
    • +
    • <?php
       $timestamp = time();
       //  $time = 
      @@ -322,19 +322,19 @@
       //  $signature = ""
       ?>
       
      -

      signature and timestamp in your API requests. Example:' ); ?>

      -

      /yourls-api.php?timestamp=$timestamp&signature=$signature&action=...

      -


      - /yourls-api.php?timestamp=&signature=&action=...

      -

      -
    • -
    +

    signature and timestamp in your API requests. Example:' ); ?>

    +

    /yourls-api.php?timestamp=$timestamp&signature=$signature&action=...

    +


    + /yourls-api.php?timestamp=&signature=&action=...

    +

    + +
-

Passwordless API page on the wiki.', 'https://yourls.org/passwordlessapi' ); ?> - API documentation for more', yourls_get_yourls_site() . '/readme.html#API' ); ?>

+

Passwordless API page on the wiki.', 'https://yourls.org/passwordlessapi' ); ?> + API documentation for more', yourls_get_yourls_site() . '/readme.html#API' ); ?>

-
+
- + diff --git a/admin/upgrade.php b/admin/upgrade.php index 536a9f873..957870cda 100644 --- a/admin/upgrade.php +++ b/admin/upgrade.php @@ -8,73 +8,73 @@ yourls_html_logo(); yourls_html_menu(); ?> -

+

' . yourls_s( 'Upgrade not required. Go back to play!', yourls_admin_url('index.php') ) . '

'; + echo '

' . yourls_s( 'Upgrade not required. Go back to play!', yourls_admin_url('index.php') ) . '

'; } else { - /* - step 1: create new tables and populate them, update old tables structure, - step 2: convert each row of outdated tables if needed - step 3: - if applicable finish updating outdated tables (indexes etc) - - update version & db_version in options, this is all done! - */ + /* + step 1: create new tables and populate them, update old tables structure, + step 2: convert each row of outdated tables if needed + step 3: - if applicable finish updating outdated tables (indexes etc) + - update version & db_version in options, this is all done! + */ - // From what are we upgrading? - if ( isset( $_GET['oldver'] ) && isset( $_GET['oldsql'] ) ) { - $oldver = yourls_sanitize_version($_GET['oldver']); - $oldsql = intval($_GET['oldsql']); - } else { - list( $oldver, $oldsql ) = yourls_get_current_version_from_sql(); - } + // From what are we upgrading? + if ( isset( $_GET['oldver'] ) && isset( $_GET['oldsql'] ) ) { + $oldver = yourls_sanitize_version($_GET['oldver']); + $oldsql = intval($_GET['oldsql']); + } else { + list( $oldver, $oldsql ) = yourls_get_current_version_from_sql(); + } - // To what are we upgrading ? - $newver = YOURLS_VERSION; - $newsql = YOURLS_DB_VERSION; + // To what are we upgrading ? + $newver = YOURLS_VERSION; + $newsql = YOURLS_DB_VERSION; - // Verbose & ugly details - yourls_debug_mode(true); + // Verbose & ugly details + yourls_debug_mode(true); - // Let's go - $step = ( isset( $_GET['step'] ) ? intval( $_GET['step'] ) : 0 ); - switch( $step ) { + // Let's go + $step = ( isset( $_GET['step'] ) ? intval( $_GET['step'] ) : 0 ); + switch( $step ) { - default: - case 0: - ?> -

-

backup your database
(you should do this regularly anyway)' ); ?>

-

should happen, but this doesn't mean it won't happen, right? ;)" ); ?>

-

something goes wrong, you'll see a message and hopefully a way to fix." ); ?>

-

good for you, let it go :)' ); ?>

-

- - - - - - - - "; + default: + case 0: + ?> +

+

backup your database
(you should do this regularly anyway)' ); ?>

+

should happen, but this doesn't mean it won't happen, right? ;)" ); ?>

+

something goes wrong, you'll see a message and hopefully a way to fix." ); ?>

+

good for you, let it go :)' ); ?>

+

+ + + + + + + + "; - break; + break; - case 1: - case 2: - $upgrade = yourls_upgrade( $step, $oldver, $newver, $oldsql, $newsql ); - break; + case 1: + case 2: + $upgrade = yourls_upgrade( $step, $oldver, $newver, $oldsql, $newsql ); + break; - case 3: - $upgrade = yourls_upgrade( 3, $oldver, $newver, $oldsql, $newsql ); - echo '

' . yourls__( 'Your installation is now up to date ! ' ) . '

'; - echo '

' . yourls_s( 'Go back to the admin interface', yourls_admin_url('index.php') ) . '

'; - } + case 3: + $upgrade = yourls_upgrade( 3, $oldver, $newver, $oldsql, $newsql ); + echo '

' . yourls__( 'Your installation is now up to date ! ' ) . '

'; + echo '

' . yourls_s( 'Go back to the admin interface', yourls_admin_url('index.php') ) . '

'; + } } diff --git a/composer.json b/composer.json index 5b41af073..e604afd80 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "source": "https://github.com/YOURLS/YOURLS" }, "require": { - "php": ">=7.4", + "php": "^8.1", "ext-dom": "*", "ext-filter": "*", "ext-hash": "*", @@ -27,7 +27,7 @@ "rmccue/requests" : "^2.0", "pomo/pomo" : "^1.4", "geoip2/geoip2" : "^2.10", - "aura/sql": "^3.0", + "aura/sql": "^6.0", "jakeasmith/http_build_url": "^1.0", "symfony/polyfill-mbstring": "^1.15", "symfony/polyfill-intl-idn": "^1.17", @@ -39,7 +39,7 @@ "config": { "vendor-dir": "includes/vendor", "platform": { - "php": "7.4.0" + "php": "8.1.0" } }, "autoload": { diff --git a/composer.lock b/composer.lock index 1db41c64c..764732b14 100644 --- a/composer.lock +++ b/composer.lock @@ -4,29 +4,30 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9b65f2d0608ea42bf57901047d69e5bb", + "content-hash": "5e687d6aa23e978bd628bd3cda68d716", "packages": [ { "name": "aura/sql", - "version": "3.1.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/auraphp/Aura.Sql.git", - "reference": "88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca" + "reference": "8e2bb362e8953198df3682c9122e8b9edab5ff20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/auraphp/Aura.Sql/zipball/88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca", - "reference": "88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca", + "url": "https://api.github.com/repos/auraphp/Aura.Sql/zipball/8e2bb362e8953198df3682c9122e8b9edab5ff20", + "reference": "8e2bb362e8953198df3682c9122e8b9edab5ff20", "shasum": "" }, "require": { - "php": ">=5.6.0", - "psr/log": "^1.0 || ^2.0" + "ext-pdo": "*", + "php": "^8.4", + "psr/log": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "pds/skeleton": "~1.0", - "yoast/phpunit-polyfills": "~1.0" + "phpunit/phpunit": "^9.5" }, "type": "library", "autoload": { @@ -59,34 +60,34 @@ ], "support": { "issues": "https://github.com/auraphp/Aura.Sql/issues", - "source": "https://github.com/auraphp/Aura.Sql/tree/3.1.0" + "source": "https://github.com/auraphp/Aura.Sql/tree/6.0.0" }, - "time": "2022-04-28T05:11:23+00:00" + "time": "2025-01-22T06:43:21+00:00" }, { "name": "composer/ca-bundle", - "version": "1.3.4", + "version": "1.5.5", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5" + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/69098eca243998b53eed7a48d82dedd28b447cd5", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/08c50d5ec4c6ced7d0271d2862dec8c1033283e6", + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6", "shasum": "" }, "require": { "ext-openssl": "*", "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "psr/log": "^1.0", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "type": "library", "extra": { @@ -121,7 +122,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.4" + "source": "https://github.com/composer/ca-bundle/tree/1.5.5" }, "funding": [ { @@ -137,14 +138,14 @@ "type": "tidelift" } ], - "time": "2022-10-12T12:08:29+00:00" + "time": "2025-01-08T16:17:16+00:00" }, { "name": "geoip2/geoip2", "version": "v2.13.0", "source": { "type": "git", - "url": "git@github.com:maxmind/GeoIP2-php.git", + "url": "https://github.com/maxmind/GeoIP2-php.git", "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23" }, "dist": { @@ -191,6 +192,10 @@ "geolocation", "maxmind" ], + "support": { + "issues": "https://github.com/maxmind/GeoIP2-php/issues", + "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.13.0" + }, "time": "2022-08-05T20:32:58+00:00" }, { @@ -232,29 +237,27 @@ }, { "name": "maxmind-db/reader", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", - "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b" + "reference": "5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b1f3c0699525336d09cc5161a2861268d9f2ae5b", - "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90", + "reference": "5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90", "shasum": "" }, "require": { "php": ">=7.2" }, "conflict": { - "ext-maxminddb": "<1.10.1,>=2.0.0" + "ext-maxminddb": "<1.11.1 || >=2.0.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.*", - "php-coveralls/php-coveralls": "^2.1", "phpstan/phpstan": "*", - "phpunit/phpcov": ">=6.0.0", "phpunit/phpunit": ">=8.0.0,<10.0.0", "squizlabs/php_codesniffer": "3.*" }, @@ -291,29 +294,29 @@ ], "support": { "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", - "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.11.0" + "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.12.0" }, - "time": "2021-10-18T15:23:10+00:00" + "time": "2024-11-14T22:43:47+00:00" }, { "name": "maxmind/web-service-common", - "version": "v0.9.0", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/maxmind/web-service-common-php.git", - "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53" + "reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", - "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4", + "reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0.3", "ext-curl": "*", "ext-json": "*", - "php": ">=7.2" + "php": ">=8.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.*", @@ -342,9 +345,9 @@ "homepage": "https://github.com/maxmind/web-service-common-php", "support": { "issues": "https://github.com/maxmind/web-service-common-php/issues", - "source": "https://github.com/maxmind/web-service-common-php/tree/v0.9.0" + "source": "https://github.com/maxmind/web-service-common-php/tree/v0.10.0" }, - "time": "2022-03-28T17:43:20+00:00" + "time": "2024-11-14T23:14:52+00:00" }, { "name": "ozh/bookmarkletgen", @@ -461,30 +464,30 @@ }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -505,22 +508,22 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "rmccue/requests", - "version": "v2.0.5", + "version": "v2.0.15", "source": { "type": "git", "url": "https://github.com/WordPress/Requests.git", - "reference": "b717f1d2f4ef7992ec0c127747ed8b7e170c2f49" + "reference": "877cd66169755899682f1595e057334b40d9d149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/Requests/zipball/b717f1d2f4ef7992ec0c127747ed8b7e170c2f49", - "reference": "b717f1d2f4ef7992ec0c127747ed8b7e170c2f49", + "url": "https://api.github.com/repos/WordPress/Requests/zipball/877cd66169755899682f1595e057334b40d9d149", + "reference": "877cd66169755899682f1595e057334b40d9d149", "shasum": "" }, "require": { @@ -538,6 +541,12 @@ "wp-coding-standards/wpcs": "^2.0", "yoast/phpunit-polyfills": "^1.0.0" }, + "suggest": { + "art4/requests-psr18-adapter": "For using Requests as a PSR-18 HTTP Client", + "ext-curl": "For improved performance", + "ext-openssl": "For secure transport support", + "ext-zlib": "For improved performance when decompressing encoded streams" + }, "type": "library", "autoload": { "files": [ @@ -588,7 +597,7 @@ "issues": "https://github.com/WordPress/Requests/issues", "source": "https://github.com/WordPress/Requests" }, - "time": "2022-10-11T08:15:28+00:00" + "time": "2025-01-21T10:13:31+00:00" }, { "name": "spatie/array-to-xml", @@ -656,34 +665,30 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.27.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -723,7 +728,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { @@ -739,36 +744,33 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -807,7 +809,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -823,24 +825,24 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -850,12 +852,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -890,83 +889,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -982,17 +905,17 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-09-09T11:45:10+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.4", + "php": "^8.1", "ext-dom": "*", "ext-filter": "*", "ext-hash": "*", @@ -1004,7 +927,7 @@ "ext-ctype": "*" }, "platform-overrides": { - "php": "7.4.0" + "php": "8.1.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/css/style.css b/css/style.css index d7f50d971..e1d350df7 100644 --- a/css/style.css +++ b/css/style.css @@ -203,7 +203,7 @@ td.actions .button_stats { background:#efe; } #login { - width: 300px; + max-width: 300px; margin: 200px auto 0px auto; } #login p{ diff --git a/includes/Config/Init.php b/includes/Config/Init.php index d9f201247..d97d9ae2f 100644 --- a/includes/Config/Init.php +++ b/includes/Config/Init.php @@ -32,11 +32,6 @@ public function __construct(InitDefaults $actions) { date_default_timezone_set( 'UTC' ); } - // Load locale - if ($actions->load_default_textdomain === true) { - yourls_load_default_textdomain(); - } - // Check if we are in maintenance mode - if yes, it will die here. if ($actions->check_maintenance_mode === true) { yourls_check_maintenance_mode(); @@ -110,6 +105,11 @@ public function __construct(InitDefaults $actions) { yourls_do_action( 'plugins_loaded' ); } + // Load locale + if ($actions->load_default_textdomain === true) { + yourls_load_default_textdomain(); + } + // Is there a new version of YOURLS ? if ($actions->check_new_version === true) { if (yourls_is_installed() && !yourls_is_upgrading()) { diff --git a/includes/Database/Logger.php b/includes/Database/Logger.php index 6c77adea8..3c256dbda 100644 --- a/includes/Database/Logger.php +++ b/includes/Database/Logger.php @@ -49,7 +49,7 @@ class Logger extends AbstractLogger { * * @return void */ - public function log($level, $message, array $context = []) { + public function log($level, string|\Stringable $message, array $context = []): void { // if it's an internal SQL query, format the message, otherwise store a string if($level === 'query') { $this->messages[] = sprintf( diff --git a/includes/Database/Options.php b/includes/Database/Options.php index 2eebb641b..f175f08be 100644 --- a/includes/Database/Options.php +++ b/includes/Database/Options.php @@ -75,7 +75,7 @@ public function get_all_options() { $this->ydb->set_option($name, yourls_maybe_unserialize($value)); } - yourls_apply_filter('get_all_options', 'deprecated'); + yourls_do_action('get_all_options', $options); return true; } @@ -172,7 +172,7 @@ public function update($name, $newvalue) { // Cache option value to save a DB query if needed later $this->ydb->set_option($name, $newvalue); - yourls_do_action( 'update_option', $name, $oldvalue, $newvalue ); + yourls_do_action( 'update_option', $name, $oldvalue, $newvalue ); return true; } diff --git a/includes/Database/Profiler.php b/includes/Database/Profiler.php index be8f56c2e..ea9e4d222 100644 --- a/includes/Database/Profiler.php +++ b/includes/Database/Profiler.php @@ -23,7 +23,7 @@ class Profiler extends \Aura\Sql\Profiler\Profiler { * @param array $values The values bound to the statement, if any. * @return void */ - public function finish($statement = null, array $values = []) + public function finish(?string $statement = null, array $values = []): void { if (! $this->active) { return; diff --git a/includes/Database/YDB.php b/includes/Database/YDB.php index f13e145d1..4053f3383 100644 --- a/includes/Database/YDB.php +++ b/includes/Database/YDB.php @@ -1,12 +1,12 @@ option, or $ydb->set_option(), use yourls_*_options() functions instead). + * function wrappers (e.g. don't use $ydb->option, or $ydb->set_option(), use yourls_*_options() functions instead). * * @since 1.7.3 */ @@ -33,7 +33,7 @@ class YDB extends ExtendedPdo { protected $context = ''; /** - * Information related to a short URL keyword (eg timestamp, long URL, ...) + * Information related to a short URL keyword (e.g. timestamp, long URL, ...) * * @var array * @@ -53,13 +53,13 @@ class YDB extends ExtendedPdo { protected $option = []; /** - * Plugin admin pages informations + * Plugin admin pages information * @var array */ protected $plugin_pages = []; /** - * Plugin informations + * Plugin information * @var array */ protected $plugins = []; @@ -78,15 +78,15 @@ class YDB extends ExtendedPdo { * @param array $options Driver-specific options * @param array $attributes Attributes to set after a connection */ - public function __construct($dsn, $user, $pass, $options, $attributes) { - parent::__construct($dsn, $user, $pass, $options, $attributes); + public function __construct($dsn, $user, $pass, $options) { + parent::__construct($dsn, $user, $pass, $options); } /** * Init everything needed * * Everything we need to set up is done here in init(), not in the constructor, so even - * when the connection fails (eg config error or DB dead), the constructor has worked + * when the connection fails (e.g. config error or DB dead), the constructor has worked, * and we have a $ydb object properly instantiated (and for instance yourls_die() can * correctly die, even if using $ydb methods) * @@ -140,7 +140,8 @@ public function get_emulate_state() { */ public function connect_to_DB() { try { - $this->connect(); + list($dsn, $_user, $_pwd, $_opt, $_queries) = $this->args; + $this->connect($dsn); } catch ( \Exception $e ) { $this->dead_or_error($e); } @@ -404,22 +405,13 @@ public function is_installed() { } /** - * Return standardized DB version - * - * The regex removes everything that's not a number at the start of the string, or remove anything that's not a number and what - * follows after that. - * 'omgmysql-5.5-ubuntu-4.20' => '5.5' - * 'mysql5.5-ubuntu-4.20' => '5.5' - * '5.5-ubuntu-4.20' => '5.5' - * '5.5-beta2' => '5.5' - * '5.5' => '5.5' + * Return MySQL version * * @since 1.7.3 * @return string */ public function mysql_version() { - $version = $this->pdo->getAttribute(PDO::ATTR_SERVER_VERSION); - return $version; + return $this->pdo->getAttribute(PDO::ATTR_SERVER_VERSION); } } diff --git a/includes/Views/AdminParams.php b/includes/Views/AdminParams.php index 75de39e90..892684da6 100644 --- a/includes/Views/AdminParams.php +++ b/includes/Views/AdminParams.php @@ -222,8 +222,15 @@ public function get_click_filter() public function get_click_limit() { // @hook Default link click threshold (unset) - return (isset($_GET['click_limit']) && intval($_GET['click_limit']) >= 0) ? - intval($_GET['click_limit']) : yourls_apply_filter('admin_view_click_limit', ''); + if ( + isset($_GET['click_limit']) // Exists in the query string + && ($_GET['click_limit'] !== '') // Not empty (&stuff=&click_limit=&otherstuff=) + && intval($_GET['click_limit']) >= 0 // A number >= 0 + ) { + return intval($_GET['click_limit']); + } else { + return yourls_apply_filter('admin_view_click_limit', ''); + } } diff --git a/includes/auth.php b/includes/auth.php index 58e15c979..be98a87da 100644 --- a/includes/auth.php +++ b/includes/auth.php @@ -6,23 +6,23 @@ if( $auth !== true ) { - // API mode, - if ( yourls_is_API() ) { - $format = ( isset($_REQUEST['format']) ? $_REQUEST['format'] : 'xml' ); - $callback = ( isset($_REQUEST['callback']) ? $_REQUEST['callback'] : '' ); - yourls_api_output( $format, array( - 'simple' => $auth, - 'message' => $auth, - 'errorCode' => 403, - 'callback' => $callback, - ) ); - - // Regular mode - } else { - yourls_login_screen( $auth ); - } - - die(); + // API mode, + if ( yourls_is_API() ) { + $format = ( isset($_REQUEST['format']) ? $_REQUEST['format'] : 'xml' ); + $callback = ( isset($_REQUEST['callback']) ? $_REQUEST['callback'] : '' ); + yourls_api_output( $format, array( + 'simple' => $auth, + 'message' => $auth, + 'errorCode' => '403', + 'callback' => $callback, + ) ); + + // Regular mode + } else { + yourls_login_screen( $auth ); + } + + die(); } yourls_do_action( 'auth_successful' ); @@ -36,12 +36,12 @@ // Did we just fail at encrypting passwords ? if ( isset( $_GET['dismiss'] ) && $_GET['dismiss'] == 'hasherror' ) { - yourls_update_option( 'defer_hashing_error', time() + 86400 * 7 ); // now + 1 week + yourls_update_option( 'defer_hashing_error', time() + 86400 * 7 ); // now + 1 week } else { - // Encrypt passwords that are clear text - if ( yourls_maybe_hash_passwords() ) { + // Encrypt passwords that are clear text + if ( yourls_maybe_hash_passwords() ) { $hash = yourls_hash_passwords_now( YOURLS_CONFIGFILE ); if ( $hash === true ) { // Hashing successful. Remove flag from DB if any. @@ -59,5 +59,5 @@ yourls_add_notice( $message ); } } - } + } } diff --git a/includes/functions-api.php b/includes/functions-api.php index 45395ac89..6ef3e2740 100644 --- a/includes/functions-api.php +++ b/includes/functions-api.php @@ -15,13 +15,13 @@ * @return array Result of API call */ function yourls_api_action_shorturl() { - $url = ( isset( $_REQUEST['url'] ) ? $_REQUEST['url'] : '' ); - $keyword = ( isset( $_REQUEST['keyword'] ) ? $_REQUEST['keyword'] : '' ); - $title = ( isset( $_REQUEST['title'] ) ? $_REQUEST['title'] : '' ); - $return = yourls_add_new_link( $url, $keyword, $title ); - $return['simple'] = ( isset( $return['shorturl'] ) ? $return['shorturl'] : '' ); // This one will be used in case output mode is 'simple' - unset( $return['html'] ); // in API mode, no need for our internal HTML output - return yourls_apply_filter( 'api_result_shorturl', $return ); + $url = ( isset( $_REQUEST['url'] ) ? $_REQUEST['url'] : '' ); + $keyword = ( isset( $_REQUEST['keyword'] ) ? $_REQUEST['keyword'] : '' ); + $title = ( isset( $_REQUEST['title'] ) ? $_REQUEST['title'] : '' ); + $return = yourls_add_new_link( $url, $keyword, $title ); + $return['simple'] = ( isset( $return['shorturl'] ) ? $return['shorturl'] : '' ); // This one will be used in case output mode is 'simple' + unset( $return['html'] ); // in API mode, no need for our internal HTML output + return yourls_apply_filter( 'api_result_shorturl', $return ); } /** @@ -31,10 +31,10 @@ function yourls_api_action_shorturl() { * @return array Result of API call */ function yourls_api_action_stats() { - $filter = ( isset( $_REQUEST['filter'] ) ? $_REQUEST['filter'] : '' ); - $limit = ( isset( $_REQUEST['limit'] ) ? $_REQUEST['limit'] : '' ); - $start = ( isset( $_REQUEST['start'] ) ? $_REQUEST['start'] : '' ); - return yourls_apply_filter( 'api_result_stats', yourls_api_stats( $filter, $limit, $start ) ); + $filter = ( isset( $_REQUEST['filter'] ) ? $_REQUEST['filter'] : '' ); + $limit = ( isset( $_REQUEST['limit'] ) ? $_REQUEST['limit'] : '' ); + $start = ( isset( $_REQUEST['start'] ) ? $_REQUEST['start'] : '' ); + return yourls_apply_filter( 'api_result_stats', yourls_api_stats( $filter, $limit, $start ) ); } /** @@ -44,7 +44,7 @@ function yourls_api_action_stats() { * @return array Result of API call */ function yourls_api_action_db_stats() { - return yourls_apply_filter( 'api_result_db_stats', yourls_api_db_stats() ); + return yourls_apply_filter( 'api_result_db_stats', yourls_api_db_stats() ); } /** @@ -54,8 +54,8 @@ function yourls_api_action_db_stats() { * @return array Result of API call */ function yourls_api_action_url_stats() { - $shorturl = ( isset( $_REQUEST['shorturl'] ) ? $_REQUEST['shorturl'] : '' ); - return yourls_apply_filter( 'api_result_url_stats', yourls_api_url_stats( $shorturl ) ); + $shorturl = ( isset( $_REQUEST['shorturl'] ) ? $_REQUEST['shorturl'] : '' ); + return yourls_apply_filter( 'api_result_url_stats', yourls_api_url_stats( $shorturl ) ); } /** @@ -65,8 +65,8 @@ function yourls_api_action_url_stats() { * @return array Result of API call */ function yourls_api_action_expand() { - $shorturl = ( isset( $_REQUEST['shorturl'] ) ? $_REQUEST['shorturl'] : '' ); - return yourls_apply_filter( 'api_result_expand', yourls_api_expand( $shorturl ) ); + $shorturl = ( isset( $_REQUEST['shorturl'] ) ? $_REQUEST['shorturl'] : '' ); + return yourls_apply_filter( 'api_result_expand', yourls_api_expand( $shorturl ) ); } /** @@ -76,10 +76,10 @@ function yourls_api_action_expand() { * @return array Result of API call */ function yourls_api_action_version() { - $return['version'] = $return['simple'] = YOURLS_VERSION; - if( isset( $_REQUEST['db'] ) && $_REQUEST['db'] == 1 ) - $return['db_version'] = YOURLS_DB_VERSION; - return yourls_apply_filter( 'api_result_version', $return ); + $return['version'] = $return['simple'] = YOURLS_VERSION; + if( isset( $_REQUEST['db'] ) && $_REQUEST['db'] == 1 ) + $return['db_version'] = YOURLS_DB_VERSION; + return yourls_apply_filter( 'api_result_version', $return ); } /** @@ -99,12 +99,12 @@ function yourls_api_action_version() { * @return string API output, as an XML / JSON / JSONP / raw text string */ function yourls_api_output( $mode, $output, $send_headers = true, $echo = true ) { - if( isset( $output['simple'] ) ) { - $simple = $output['simple']; - unset( $output['simple'] ); - } + if( isset( $output['simple'] ) ) { + $simple = $output['simple']; + unset( $output['simple'] ); + } - yourls_do_action( 'pre_api_output', $mode, $output, $send_headers, $echo ); + yourls_do_action( 'pre_api_output', $mode, $output, $send_headers, $echo ); if( $send_headers ) { if( isset( $output['statusCode'] ) ) { @@ -119,43 +119,43 @@ function yourls_api_output( $mode, $output, $send_headers = true, $echo = true ) $result = ''; - switch ( $mode ) { - case 'jsonp': + switch ( $mode ) { + case 'jsonp': if( $send_headers ) yourls_content_type_header( 'application/javascript' ); $callback = isset( $output['callback'] ) ? $output['callback'] : ''; - $result = $callback . '(' . json_encode( $output ) . ')'; - break; + $result = $callback . '(' . json_encode( $output ) . ')'; + break; - case 'json': + case 'json': if( $send_headers ) yourls_content_type_header( 'application/json' ); - $result = json_encode( $output ); - break; + $result = json_encode( $output ); + break; - case 'xml': + case 'xml': if( $send_headers ) yourls_content_type_header( 'application/xml' ); - $result = yourls_xml_encode( $output ); - break; + $result = yourls_xml_encode( $output ); + break; - case 'simple': - default: + case 'simple': + default: if( $send_headers ) yourls_content_type_header( 'text/plain' ); - $result = isset( $simple ) ? $simple : ''; - break; - } + $result = isset( $simple ) ? $simple : ''; + break; + } if( $echo ) { echo $result; } - yourls_do_action( 'api_output', $mode, $output, $send_headers, $echo ); + yourls_do_action( 'api_output', $mode, $output, $send_headers, $echo ); return $result; } @@ -169,10 +169,10 @@ function yourls_api_output( $mode, $output, $send_headers = true, $echo = true ) * @return array */ function yourls_api_stats($filter = 'top', $limit = 10, $start = 0 ) { - $return = yourls_get_stats( $filter, $limit, $start ); - $return['simple'] = 'Need either XML or JSON format for stats'; - $return['message'] = 'success'; - return yourls_apply_filter( 'api_stats', $return, $filter, $limit, $start ); + $return = yourls_get_stats( $filter, $limit, $start ); + $return['simple'] = 'Need either XML or JSON format for stats'; + $return['message'] = 'success'; + return yourls_apply_filter( 'api_stats', $return, $filter, $limit, $start ); } /** @@ -181,14 +181,14 @@ function yourls_api_stats($filter = 'top', $limit = 10, $start = 0 ) { * @return array */ function yourls_api_db_stats() { - $return = array( - 'db-stats' => yourls_get_db_stats(), - 'statusCode' => 200, - 'simple' => 'Need either XML or JSON format for stats', - 'message' => 'success', - ); - - return yourls_apply_filter( 'api_db_stats', $return ); + $return = array( + 'db-stats' => yourls_get_db_stats(), + 'statusCode' => '200', + 'simple' => 'Need either XML or JSON format for stats', + 'message' => 'success', + ); + + return yourls_apply_filter( 'api_db_stats', $return ); } /** @@ -198,12 +198,12 @@ function yourls_api_db_stats() { * @return array */ function yourls_api_url_stats( $shorturl ) { - $keyword = str_replace( yourls_get_yourls_site() . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc' - $keyword = yourls_sanitize_keyword( $keyword ); + $keyword = str_replace( yourls_get_yourls_site() . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc' + $keyword = yourls_sanitize_keyword( $keyword ); - $return = yourls_get_keyword_stats( $keyword ); - $return['simple'] = 'Need either XML or JSON format for stats'; - return yourls_apply_filter( 'api_url_stats', $return, $shorturl ); + $return = yourls_get_keyword_stats( $keyword ); + $return['simple'] = 'Need either XML or JSON format for stats'; + return yourls_apply_filter( 'api_url_stats', $return, $shorturl ); } /** @@ -213,29 +213,29 @@ function yourls_api_url_stats( $shorturl ) { * @return array */ function yourls_api_expand( $shorturl ) { - $keyword = str_replace( yourls_get_yourls_site() . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc' - $keyword = yourls_sanitize_keyword( $keyword ); + $keyword = str_replace( yourls_get_yourls_site() . '/' , '', $shorturl ); // accept either 'http://ozh.in/abc' or 'abc' + $keyword = yourls_sanitize_keyword( $keyword ); - $longurl = yourls_get_keyword_longurl( $keyword ); + $longurl = yourls_get_keyword_longurl( $keyword ); - if( $longurl ) { - $return = array( - 'keyword' => $keyword, - 'shorturl' => yourls_link($keyword), - 'longurl' => $longurl, + if( $longurl ) { + $return = array( + 'keyword' => $keyword, + 'shorturl' => yourls_link($keyword), + 'longurl' => $longurl, 'title' => yourls_get_keyword_title( $keyword ), - 'simple' => $longurl, - 'message' => 'success', - 'statusCode' => 200, - ); - } else { - $return = array( - 'keyword' => $keyword, - 'simple' => 'not found', - 'message' => 'Error: short URL not found', - 'errorCode' => 404, - ); - } - - return yourls_apply_filter( 'api_expand', $return, $shorturl ); + 'simple' => $longurl, + 'message' => 'success', + 'statusCode' => '200', + ); + } else { + $return = array( + 'keyword' => $keyword, + 'simple' => 'not found', + 'message' => 'Error: short URL not found', + 'errorCode' => '404', + ); + } + + return yourls_apply_filter( 'api_expand', $return, $shorturl ); } diff --git a/includes/functions-auth.php b/includes/functions-auth.php index f074c21c6..cadf538b4 100644 --- a/includes/functions-auth.php +++ b/includes/functions-auth.php @@ -10,12 +10,12 @@ * @return void */ function yourls_maybe_require_auth() { - if( yourls_is_private() ) { - yourls_do_action( 'require_auth' ); - require_once( YOURLS_INC.'/auth.php' ); - } else { - yourls_do_action( 'require_no_auth' ); - } + if( yourls_is_private() ) { + yourls_do_action( 'require_auth' ); + require_once( YOURLS_INC.'/auth.php' ); + } else { + yourls_do_action( 'require_no_auth' ); + } } /** @@ -24,102 +24,102 @@ function yourls_maybe_require_auth() { * @return bool|string|mixed true if valid user, error message otherwise. Can also call yourls_die() or redirect to login page. Oh my. */ function yourls_is_valid_user() { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_is_valid_user', null ); - if ( null !== $pre ) { - return $pre; - } + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_is_valid_user', null ); + if ( null !== $pre ) { + return $pre; + } - // $unfiltered_valid : are credentials valid? Boolean value. It's "unfiltered" to allow plugins to eventually filter it. - $unfiltered_valid = false; + // $unfiltered_valid : are credentials valid? Boolean value. It's "unfiltered" to allow plugins to eventually filter it. + $unfiltered_valid = false; - // Logout request - if( isset( $_GET['action'] ) && $_GET['action'] == 'logout' && isset( $_REQUEST['nonce'] ) ) { + // Logout request + if( isset( $_GET['action'] ) && $_GET['action'] == 'logout' && isset( $_REQUEST['nonce'] ) ) { // The logout nonce is associated to fake user 'logout' since at this point we don't know the real user yourls_verify_nonce('admin_logout', $_REQUEST['nonce'], 'logout'); - yourls_do_action( 'logout' ); - yourls_store_cookie( '' ); - return yourls__( 'Logged out successfully' ); - } - - // Check cookies or login request. Login form has precedence. - - yourls_do_action( 'pre_login' ); - - // Determine auth method and check credentials - if - // API only: Secure (no login or pwd) and time limited token - // ?timestamp=12345678&signature=md5(totoblah12345678) - ( yourls_is_API() && - isset( $_REQUEST['timestamp'] ) && !empty($_REQUEST['timestamp'] ) && - isset( $_REQUEST['signature'] ) && !empty($_REQUEST['signature'] ) - ) - { - yourls_do_action( 'pre_login_signature_timestamp' ); - $unfiltered_valid = yourls_check_signature_timestamp(); - } - - elseif - // API only: Secure (no login or pwd) - // ?signature=md5(totoblah) - ( yourls_is_API() && - !isset( $_REQUEST['timestamp'] ) && - isset( $_REQUEST['signature'] ) && !empty( $_REQUEST['signature'] ) - ) - { - yourls_do_action( 'pre_login_signature' ); - $unfiltered_valid = yourls_check_signature(); - } - - elseif - // API or normal: login with username & pwd - ( isset( $_REQUEST['username'] ) && isset( $_REQUEST['password'] ) - && !empty( $_REQUEST['username'] ) && !empty( $_REQUEST['password'] ) ) - { - yourls_do_action( 'pre_login_username_password' ); - $unfiltered_valid = yourls_check_username_password(); - } - - elseif - // Normal only: cookies - ( !yourls_is_API() && - isset( $_COOKIE[ yourls_cookie_name() ] ) ) - { - yourls_do_action( 'pre_login_cookie' ); - $unfiltered_valid = yourls_check_auth_cookie(); - } - - // Regardless of validity, allow plugins to filter the boolean and have final word - $valid = yourls_apply_filter( 'is_valid_user', $unfiltered_valid ); - - // Login for the win! - if ( $valid ) { - yourls_do_action( 'login' ); - - // (Re)store encrypted cookie if needed - if ( !yourls_is_API() ) { - yourls_store_cookie( YOURLS_USER ); - - // Login form : redirect to requested URL to avoid re-submitting the login form on page reload - if( isset( $_REQUEST['username'] ) && isset( $_REQUEST['password'] ) && isset( $_SERVER['REQUEST_URI'] ) ) { - // The return makes sure we exit this function before waiting for redirection. + yourls_do_action( 'logout' ); + yourls_store_cookie( '' ); + return yourls__( 'Logged out successfully' ); + } + + // Check cookies or login request. Login form has precedence. + + yourls_do_action( 'pre_login' ); + + // Determine auth method and check credentials + if + // API only: Secure (no login or pwd) and time limited token + // ?timestamp=12345678&signature=md5(totoblah12345678) + ( yourls_is_API() && + isset( $_REQUEST['timestamp'] ) && !empty($_REQUEST['timestamp'] ) && + isset( $_REQUEST['signature'] ) && !empty($_REQUEST['signature'] ) + ) + { + yourls_do_action( 'pre_login_signature_timestamp' ); + $unfiltered_valid = yourls_check_signature_timestamp(); + } + + elseif + // API only: Secure (no login or pwd) + // ?signature=md5(totoblah) + ( yourls_is_API() && + !isset( $_REQUEST['timestamp'] ) && + isset( $_REQUEST['signature'] ) && !empty( $_REQUEST['signature'] ) + ) + { + yourls_do_action( 'pre_login_signature' ); + $unfiltered_valid = yourls_check_signature(); + } + + elseif + // API or normal: login with username & pwd + ( isset( $_REQUEST['username'] ) && isset( $_REQUEST['password'] ) + && !empty( $_REQUEST['username'] ) && !empty( $_REQUEST['password'] ) ) + { + yourls_do_action( 'pre_login_username_password' ); + $unfiltered_valid = yourls_check_username_password(); + } + + elseif + // Normal only: cookies + ( !yourls_is_API() && + isset( $_COOKIE[ yourls_cookie_name() ] ) ) + { + yourls_do_action( 'pre_login_cookie' ); + $unfiltered_valid = yourls_check_auth_cookie(); + } + + // Regardless of validity, allow plugins to filter the boolean and have final word + $valid = yourls_apply_filter( 'is_valid_user', $unfiltered_valid ); + + // Login for the win! + if ( $valid ) { + yourls_do_action( 'login' ); + + // (Re)store encrypted cookie if needed + if ( !yourls_is_API() ) { + yourls_store_cookie( YOURLS_USER ); + + // Login form : redirect to requested URL to avoid re-submitting the login form on page reload + if( isset( $_REQUEST['username'] ) && isset( $_REQUEST['password'] ) && isset( $_SERVER['REQUEST_URI'] ) ) { + // The return makes sure we exit this function before waiting for redirection. // See #3189 and note in yourls_redirect() - return yourls_redirect( yourls_sanitize_url_safe($_SERVER['REQUEST_URI']) ); - } - } + return yourls_redirect( yourls_sanitize_url_safe($_SERVER['REQUEST_URI']) ); + } + } - // Login successful - return true; - } + // Login successful + return true; + } - // Login failed - yourls_do_action( 'login_failed' ); + // Login failed + yourls_do_action( 'login_failed' ); - if ( isset( $_REQUEST['username'] ) || isset( $_REQUEST['password'] ) ) { - return yourls__( 'Invalid username or password' ); - } else { - return yourls__( 'Please log in' ); - } + if ( isset( $_REQUEST['username'] ) || isset( $_REQUEST['password'] ) ) { + return yourls__( 'Invalid username or password' ); + } else { + return yourls__( 'Please log in' ); + } } /** @@ -128,18 +128,18 @@ function yourls_is_valid_user() { * @return bool true if login/pwd pair is valid (and sets user if applicable), false otherwise */ function yourls_check_username_password() { - global $yourls_user_passwords; + global $yourls_user_passwords; - // If login form (not API), check for nonce + // If login form (not API), check for nonce if(!yourls_is_API()) { yourls_verify_nonce('admin_login'); } - if( isset( $yourls_user_passwords[ $_REQUEST['username'] ] ) && yourls_check_password_hash( $_REQUEST['username'], $_REQUEST['password'] ) ) { - yourls_set_user( $_REQUEST['username'] ); - return true; - } - return false; + if( isset( $yourls_user_passwords[ $_REQUEST['username'] ] ) && yourls_check_password_hash( $_REQUEST['username'], $_REQUEST['password'] ) ) { + yourls_set_user( $_REQUEST['username'] ); + return true; + } + return false; } /** @@ -150,24 +150,24 @@ function yourls_check_username_password() { * @return bool */ function yourls_check_password_hash($user, $submitted_password ) { - global $yourls_user_passwords; + global $yourls_user_passwords; - if( !isset( $yourls_user_passwords[ $user ] ) ) - return false; + if( !isset( $yourls_user_passwords[ $user ] ) ) + return false; - if ( yourls_has_phpass_password( $user ) ) { - // Stored password is hashed - list( , $hash ) = explode( ':', $yourls_user_passwords[ $user ] ); - $hash = str_replace( '!', '$', $hash ); - return ( yourls_phpass_check( $submitted_password, $hash ) ); - } else if( yourls_has_md5_password( $user ) ) { - // Stored password is a salted md5 hash: "md5:<$r = rand(10000,99999)>:" - list( , $salt, ) = explode( ':', $yourls_user_passwords[ $user ] ); - return( $yourls_user_passwords[ $user ] == 'md5:'.$salt.':'.md5( $salt . $submitted_password ) ); - } else { - // Password stored in clear text - return( $yourls_user_passwords[ $user ] === $submitted_password ); - } + if ( yourls_has_phpass_password( $user ) ) { + // Stored password is hashed + list( , $hash ) = explode( ':', $yourls_user_passwords[ $user ] ); + $hash = str_replace( '!', '$', $hash ); + return ( yourls_phpass_check( $submitted_password, $hash ) ); + } else if( yourls_has_md5_password( $user ) ) { + // Stored password is a salted md5 hash: "md5:<$r = rand(10000,99999)>:" + list( , $salt, ) = explode( ':', $yourls_user_passwords[ $user ] ); + return( $yourls_user_passwords[ $user ] == 'md5:'.$salt.':'.md5( $salt . $submitted_password ) ); + } else { + // Password stored in clear text + return( $yourls_user_passwords[ $user ] === $submitted_password ); + } } /** @@ -178,66 +178,66 @@ function yourls_check_password_hash($user, $submitted_password ) { * @return true|string if overwrite was successful, an error message otherwise */ function yourls_hash_passwords_now( $config_file ) { - if( !is_readable( $config_file ) ) { + if( !is_readable( $config_file ) ) { yourls_debug_log( 'Cannot hash passwords: cannot read file ' . $config_file ); return 'cannot read file'; // not sure that can actually happen... } - if( !is_writable( $config_file ) ) { + if( !is_writable( $config_file ) ) { yourls_debug_log( 'Cannot hash passwords: cannot write file ' . $config_file ); - return 'cannot write file'; + return 'cannot write file'; } $yourls_user_passwords = []; - // Include file to read value of $yourls_user_passwords - // Temporary suppress error reporting to avoid notices about redeclared constants - $errlevel = error_reporting(); - error_reporting( 0 ); - require $config_file; - error_reporting( $errlevel ); + // Include file to read value of $yourls_user_passwords + // Temporary suppress error reporting to avoid notices about redeclared constants + $errlevel = error_reporting(); + error_reporting( 0 ); + require $config_file; + error_reporting( $errlevel ); - $configdata = file_get_contents( $config_file ); + $configdata = file_get_contents( $config_file ); if( $configdata == false ) { yourls_debug_log('Cannot hash passwords: file_get_contents() false with ' . $config_file); return 'could not read file'; } - $to_hash = 0; // keep track of number of passwords that need hashing - foreach ( $yourls_user_passwords as $user => $password ) { + $to_hash = 0; // keep track of number of passwords that need hashing + foreach ( $yourls_user_passwords as $user => $password ) { // avoid "deprecated" warning when password is null -- see test case in tests/data/auth/preg_replace_problem.php $password ??= ''; - if ( !yourls_has_phpass_password( $user ) && !yourls_has_md5_password( $user ) ) { - $to_hash++; - $hash = yourls_phpass_hash( $password ); - // PHP would interpret $ as a variable, so replace it in storage. - $hash = str_replace( '$', '!', $hash ); - $quotes = "'" . '"'; - $pattern = "/[$quotes]" . preg_quote( $user, '/' ) . "[$quotes]\s*=>\s*[$quotes]" . preg_quote( $password, '/' ) . "[$quotes]/"; - $replace = "'$user' => 'phpass:$hash' /* Password encrypted by YOURLS */ "; - $count = 0; - $configdata = preg_replace( $pattern, $replace, $configdata, -1, $count ); - // There should be exactly one replacement. Otherwise, fast fail. - if ( $count != 1 ) { - yourls_debug_log( "Problem with preg_replace for password hash of user $user" ); - return 'preg_replace problem'; - } - } - } - - if( $to_hash == 0 ) { + if ( !yourls_has_phpass_password( $user ) && !yourls_has_md5_password( $user ) ) { + $to_hash++; + $hash = yourls_phpass_hash( $password ); + // PHP would interpret $ as a variable, so replace it in storage. + $hash = str_replace( '$', '!', $hash ); + $quotes = "'" . '"'; + $pattern = "/[$quotes]" . preg_quote( $user, '/' ) . "[$quotes]\s*=>\s*[$quotes]" . preg_quote( $password, '/' ) . "[$quotes]/"; + $replace = "'$user' => 'phpass:$hash' /* Password encrypted by YOURLS */ "; + $count = 0; + $configdata = preg_replace( $pattern, $replace, $configdata, -1, $count ); + // There should be exactly one replacement. Otherwise, fast fail. + if ( $count != 1 ) { + yourls_debug_log( "Problem with preg_replace for password hash of user $user" ); + return 'preg_replace problem'; + } + } + } + + if( $to_hash == 0 ) { yourls_debug_log('Cannot hash passwords: no password found in ' . $config_file); return 'no password found'; } - $success = file_put_contents( $config_file, $configdata ); - if ( $success === FALSE ) { - yourls_debug_log( 'Failed writing to ' . $config_file ); - return 'could not write file'; - } + $success = file_put_contents( $config_file, $configdata ); + if ( $success === FALSE ) { + yourls_debug_log( 'Failed writing to ' . $config_file ); + return 'could not write file'; + } yourls_debug_log('Successfully encrypted passwords in ' . basename($config_file)); - return true; + return true; } /** @@ -277,7 +277,7 @@ function yourls_phpass_hash( $password ) { * @return bool true if the hash matches the password, false otherwise */ function yourls_phpass_check( $password, $hash ) { - return password_verify($password, $hash); + return password_verify($password, $hash); } @@ -288,13 +288,13 @@ function yourls_phpass_check( $password, $hash ) { * @return bool true if any passwords are cleartext */ function yourls_has_cleartext_passwords() { - global $yourls_user_passwords; - foreach ( $yourls_user_passwords as $user => $pwdata ) { - if ( !yourls_has_md5_password( $user ) && !yourls_has_phpass_password( $user ) ) { - return true; - } - } - return false; + global $yourls_user_passwords; + foreach ( $yourls_user_passwords as $user => $pwdata ) { + if ( !yourls_has_md5_password( $user ) && !yourls_has_phpass_password( $user ) ) { + return true; + } + } + return false; } /** @@ -308,11 +308,11 @@ function yourls_has_cleartext_passwords() { * @return bool true if password hashed, false otherwise */ function yourls_has_md5_password( $user ) { - global $yourls_user_passwords; - return( isset( $yourls_user_passwords[ $user ] ) - && substr( $yourls_user_passwords[ $user ], 0, 4 ) == 'md5:' - && strlen( $yourls_user_passwords[ $user ] ) == 42 // http://www.google.com/search?q=the+answer+to+life+the+universe+and+everything - ); + global $yourls_user_passwords; + return( isset( $yourls_user_passwords[ $user ] ) + && substr( $yourls_user_passwords[ $user ], 0, 4 ) == 'md5:' + && strlen( $yourls_user_passwords[ $user ] ) == 42 // http://www.google.com/search?q=the+answer+to+life+the+universe+and+everything + ); } /** @@ -327,10 +327,10 @@ function yourls_has_md5_password( $user ) { * @return bool true if password hashed with password_hash, otherwise false */ function yourls_has_phpass_password( $user ) { - global $yourls_user_passwords; - return( isset( $yourls_user_passwords[ $user ] ) - && substr( $yourls_user_passwords[ $user ], 0, 7 ) == 'phpass:' - ); + global $yourls_user_passwords; + return( isset( $yourls_user_passwords[ $user ] ) + && substr( $yourls_user_passwords[ $user ], 0, 7 ) == 'phpass:' + ); } /** @@ -339,14 +339,14 @@ function yourls_has_phpass_password( $user ) { * @return bool true if authenticated, false otherwise */ function yourls_check_auth_cookie() { - global $yourls_user_passwords; - foreach( $yourls_user_passwords as $valid_user => $valid_password ) { - if ( yourls_cookie_value( $valid_user ) === $_COOKIE[ yourls_cookie_name() ] ) { - yourls_set_user( $valid_user ); - return true; - } - } - return false; + global $yourls_user_passwords; + foreach( $yourls_user_passwords as $valid_user => $valid_password ) { + if ( yourls_cookie_value( $valid_user ) === $_COOKIE[ yourls_cookie_name() ] ) { + yourls_set_user( $valid_user ); + return true; + } + } + return false; } /** @@ -380,21 +380,21 @@ function yourls_check_signature_timestamp() { return false; } - // Check signature & timestamp against all possible users - global $yourls_user_passwords; - foreach( $yourls_user_passwords as $valid_user => $valid_password ) { - if ( + // Check signature & timestamp against all possible users + global $yourls_user_passwords; + foreach( $yourls_user_passwords as $valid_user => $valid_password ) { + if ( hash( $hash_function, $_REQUEST['timestamp'].yourls_auth_signature( $valid_user ) ) === $_REQUEST['signature'] or hash( $hash_function, yourls_auth_signature( $valid_user ).$_REQUEST['timestamp'] ) === $_REQUEST['signature'] - ) { - yourls_set_user( $valid_user ); - return true; - } - } + ) { + yourls_set_user( $valid_user ); + return true; + } + } // Signature doesn't match known user - return false; + return false; } /** @@ -407,17 +407,17 @@ function yourls_check_signature() { if( !isset( $_REQUEST['signature'] ) OR empty( $_REQUEST['signature'] ) ) return false; - // Check signature against all possible users + // Check signature against all possible users global $yourls_user_passwords; - foreach( $yourls_user_passwords as $valid_user => $valid_password ) { - if ( yourls_auth_signature( $valid_user ) === $_REQUEST['signature'] ) { - yourls_set_user( $valid_user ); - return true; - } - } + foreach( $yourls_user_passwords as $valid_user => $valid_password ) { + if ( yourls_auth_signature( $valid_user ) === $_REQUEST['signature'] ) { + yourls_set_user( $valid_user ); + return true; + } + } // Signature doesn't match known user - return false; + return false; } /** @@ -427,10 +427,10 @@ function yourls_check_signature() { * @return string Signature */ function yourls_auth_signature( $username = false ) { - if( !$username && defined('YOURLS_USER') ) { - $username = YOURLS_USER; - } - return ( $username ? substr( yourls_salt( $username ), 0, 10 ) : 'Cannot generate auth signature: no username' ); + if( !$username && defined('YOURLS_USER') ) { + $username = YOURLS_USER; + } + return ( $username ? substr( yourls_salt( $username ), 0, 10 ) : 'Cannot generate auth signature: no username' ); } /** @@ -440,9 +440,9 @@ function yourls_auth_signature( $username = false ) { * @return bool True if timestamp is valid */ function yourls_check_timestamp( $time ) { - $now = time(); - // Allow timestamp to be a little in the future or the past -- see Issue 766 - return yourls_apply_filter( 'check_timestamp', abs( $now - (int)$time ) < yourls_get_nonce_life(), $time ); + $now = time(); + // Allow timestamp to be a little in the future or the past -- see Issue 766 + return yourls_apply_filter( 'check_timestamp', abs( $now - (int)$time ) < yourls_get_nonce_life(), $time ); } /** @@ -454,30 +454,30 @@ function yourls_check_timestamp( $time ) { function yourls_store_cookie( $user = '' ) { // No user will delete the cookie with a cookie time from the past - if( !$user ) { - $time = time() - 3600; - } else { - $time = time() + yourls_get_cookie_life(); - } + if( !$user ) { + $time = time() - 3600; + } else { + $time = time() + yourls_get_cookie_life(); + } $path = yourls_apply_filter( 'setcookie_path', '/' ); - $domain = yourls_apply_filter( 'setcookie_domain', parse_url( yourls_get_yourls_site(), PHP_URL_HOST ) ); - $secure = yourls_apply_filter( 'setcookie_secure', yourls_is_ssl() ); - $httponly = yourls_apply_filter( 'setcookie_httponly', true ); + $domain = yourls_apply_filter( 'setcookie_domain', parse_url( yourls_get_yourls_site(), PHP_URL_HOST ) ); + $secure = yourls_apply_filter( 'setcookie_secure', yourls_is_ssl() ); + $httponly = yourls_apply_filter( 'setcookie_httponly', true ); - // Some browsers refuse to store localhost cookie - if ( $domain == 'localhost' ) - $domain = ''; + // Some browsers refuse to store localhost cookie + if ( $domain == 'localhost' ) + $domain = ''; - yourls_do_action( 'pre_setcookie', $user, $time, $path, $domain, $secure, $httponly ); + yourls_do_action( 'pre_setcookie', $user, $time, $path, $domain, $secure, $httponly ); if ( !headers_sent( $filename, $linenum ) ) { yourls_setcookie( yourls_cookie_name(), yourls_cookie_value( $user ), $time, $path, $domain, $secure, $httponly ); - } else { - // For some reason cookies were not stored: action to be able to debug that - yourls_do_action( 'setcookie_failed', $user ); + } else { + // For some reason cookies were not stored: action to be able to debug that + yourls_do_action( 'setcookie_failed', $user ); yourls_debug_log( "Could not store cookie: headers already sent in $filename on line $linenum" ); - } + } } /** @@ -517,8 +517,8 @@ function yourls_setcookie($name, $value, $expire, $path, $domain, $secure, $http * @return void */ function yourls_set_user( $user ) { - if( !defined( 'YOURLS_USER' ) ) - define( 'YOURLS_USER', $user ); + if( !defined( 'YOURLS_USER' ) ) + define( 'YOURLS_USER', $user ); } /** @@ -532,7 +532,7 @@ function yourls_set_user( $user ) { * @return integer cookie life span, in seconds */ function yourls_get_cookie_life() { - return yourls_apply_filter( 'get_cookie_life', YOURLS_COOKIE_LIFE ); + return yourls_apply_filter( 'get_cookie_life', YOURLS_COOKIE_LIFE ); } /** @@ -547,7 +547,7 @@ function yourls_get_cookie_life() { * @return integer nonce life span, in seconds */ function yourls_get_nonce_life() { - return yourls_apply_filter( 'get_nonce_life', YOURLS_NONCE_LIFE ); + return yourls_apply_filter( 'get_nonce_life', YOURLS_NONCE_LIFE ); } /** @@ -572,7 +572,7 @@ function yourls_cookie_name() { * @return string cookie value */ function yourls_cookie_value( $user ) { - return yourls_apply_filter( 'set_cookie_value', yourls_salt( $user ?? '' ), $user ); + return yourls_apply_filter( 'set_cookie_value', yourls_salt( $user ?? '' ), $user ); } /** @@ -583,7 +583,7 @@ function yourls_cookie_value( $user ) { * @return float */ function yourls_tick() { - return ceil( time() / yourls_get_nonce_life() ); + return ceil( time() / yourls_get_nonce_life() ); } /** @@ -596,8 +596,8 @@ function yourls_tick() { * @return string hashed string */ function yourls_salt( $string ) { - $salt = defined('YOURLS_COOKIEKEY') ? YOURLS_COOKIEKEY : md5(__FILE__) ; - return yourls_apply_filter( 'yourls_salt', hash_hmac( yourls_hmac_algo(), $string, $salt), $string ); + $salt = defined('YOURLS_COOKIEKEY') ? YOURLS_COOKIEKEY : md5(__FILE__) ; + return yourls_apply_filter( 'yourls_salt', hash_hmac( yourls_hmac_algo(), $string, $salt), $string ); } /** @@ -622,13 +622,13 @@ function yourls_hmac_algo() { * @return string Nonce token */ function yourls_create_nonce($action, $user = false ) { - if( false === $user ) { + if( false === $user ) { $user = defined('YOURLS_USER') ? YOURLS_USER : '-1'; } - $tick = yourls_tick(); - $nonce = substr( yourls_salt($tick . $action . $user), 0, 10 ); - // Allow plugins to alter the nonce - return yourls_apply_filter( 'create_nonce', $nonce, $action, $user ); + $tick = yourls_tick(); + $nonce = substr( yourls_salt($tick . $action . $user), 0, 10 ); + // Allow plugins to alter the nonce + return yourls_apply_filter( 'create_nonce', $nonce, $action, $user ); } /** @@ -641,10 +641,10 @@ function yourls_create_nonce($action, $user = false ) { * @return string Nonce field */ function yourls_nonce_field($action, $name = 'nonce', $user = false, $echo = true ) { - $field = ''; - if( $echo ) - echo $field."\n"; - return $field; + $field = ''; + if( $echo ) + echo $field."\n"; + return $field; } /** @@ -657,8 +657,8 @@ function yourls_nonce_field($action, $name = 'nonce', $user = false, $echo = tru * @return string URL with nonce added */ function yourls_nonce_url($action, $url = false, $name = 'nonce', $user = false ) { - $nonce = yourls_create_nonce( $action, $user ); - return yourls_add_query_arg( $name, $nonce, $url ); + $nonce = yourls_create_nonce( $action, $user ); + return yourls_add_query_arg( $name, $nonce, $url ); } /** @@ -674,31 +674,31 @@ function yourls_nonce_url($action, $url = false, $name = 'nonce', $user = false * @return bool|void True if valid, dies otherwise */ function yourls_verify_nonce($action, $nonce = false, $user = false, $return = '' ) { - // Get user - if( false === $user ) { + // Get user + if( false === $user ) { $user = defined('YOURLS_USER') ? YOURLS_USER : '-1'; } - // Get nonce value from $_REQUEST if not specified - if( false === $nonce && isset( $_REQUEST['nonce'] ) ) { + // Get nonce value from $_REQUEST if not specified + if( false === $nonce && isset( $_REQUEST['nonce'] ) ) { $nonce = $_REQUEST['nonce']; } - // Allow plugins to short-circuit the rest of the function - if (yourls_apply_filter( 'verify_nonce', false, $action, $nonce, $user, $return ) === true) { - return true; - } + // Allow plugins to short-circuit the rest of the function + if (yourls_apply_filter( 'verify_nonce', false, $action, $nonce, $user, $return ) === true) { + return true; + } - // What nonce should be - $valid = yourls_create_nonce( $action, $user ); + // What nonce should be + $valid = yourls_create_nonce( $action, $user ); - if( $nonce === $valid ) { - return true; - } else { - if( $return ) - die( $return ); - yourls_die( yourls__( 'Unauthorized action or expired link' ), yourls__( 'Error' ), 403 ); - } + if( $nonce === $valid ) { + return true; + } else { + if( $return ) + die( $return ); + yourls_die( yourls__( 'Unauthorized action or expired link' ), yourls__( 'Error' ), 403 ); + } } /** @@ -708,7 +708,7 @@ function yourls_verify_nonce($action, $nonce = false, $user = false, $return = ' * @return bool true if YOURLS_USER and YOURLS_PASSWORD are defined as environment variables */ function yourls_is_user_from_env() { - return yourls_apply_filter('is_user_from_env', getenv('YOURLS_USER') && getenv('YOURLS_PASSWORD')); + return yourls_apply_filter('is_user_from_env', getenv('YOURLS_USER') && getenv('YOURLS_PASSWORD')); } diff --git a/includes/functions-compat.php b/includes/functions-compat.php index 4bc1330e4..2dc17d342 100644 --- a/includes/functions-compat.php +++ b/includes/functions-compat.php @@ -11,9 +11,9 @@ * */ if( !function_exists( 'json_encode' ) ) { - function json_encode( $array ) { - return yourls_array_to_json( $array ); - } + function json_encode( $array ) { + return yourls_array_to_json( $array ); + } } /** @@ -26,60 +26,60 @@ function json_encode( $array ) { */ function yourls_array_to_json( $array ){ - if( !is_array( $array ) ){ - return false; - } + if( !is_array( $array ) ){ + return false; + } - $associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) )); - if( $associative ){ + $associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) )); + if( $associative ){ - $construct = array(); - foreach( $array as $key => $value ){ + $construct = array(); + foreach( $array as $key => $value ){ - // We first copy each key/value pair into a staging array, - // formatting each key and value properly as we go. + // We first copy each key/value pair into a staging array, + // formatting each key and value properly as we go. - // Format the key: - if( is_numeric( $key ) ){ - $key = "key_$key"; - } - $key = '"'.addslashes( $key ).'"'; + // Format the key: + if( is_numeric( $key ) ){ + $key = "key_$key"; + } + $key = '"'.addslashes( $key ).'"'; - // Format the value: - if( is_array( $value )){ - $value = yourls_array_to_json( $value ); - } else if( !is_numeric( $value ) || is_string( $value ) ){ - $value = '"'.addslashes( $value ).'"'; - } + // Format the value: + if( is_array( $value )){ + $value = yourls_array_to_json( $value ); + } else if( !is_numeric( $value ) || is_string( $value ) ){ + $value = '"'.addslashes( $value ).'"'; + } - // Add to staging array: - $construct[] = "$key: $value"; - } + // Add to staging array: + $construct[] = "$key: $value"; + } - // Then we collapse the staging array into the JSON form: - $result = "{ " . implode( ", ", $construct ) . " }"; + // Then we collapse the staging array into the JSON form: + $result = "{ " . implode( ", ", $construct ) . " }"; - } else { // If the array is a vector (not associative): + } else { // If the array is a vector (not associative): - $construct = array(); - foreach( $array as $value ){ + $construct = array(); + foreach( $array as $value ){ - // Format the value: - if( is_array( $value )){ - $value = yourls_array_to_json( $value ); - } else if( !is_numeric( $value ) || is_string( $value ) ){ - $value = '"'.addslashes($value).'"'; - } + // Format the value: + if( is_array( $value )){ + $value = yourls_array_to_json( $value ); + } else if( !is_numeric( $value ) || is_string( $value ) ){ + $value = '"'.addslashes($value).'"'; + } - // Add to staging array: - $construct[] = $value; - } + // Add to staging array: + $construct[] = $value; + } - // Then we collapse the staging array into the JSON form: - $result = "[ " . implode( ", ", $construct ) . " ]"; - } + // Then we collapse the staging array into the JSON form: + $result = "[ " . implode( ", ", $construct ) . " ]"; + } - return $result; + return $result; } @@ -88,23 +88,23 @@ function yourls_array_to_json( $array ){ * */ if ( !function_exists( 'bcdiv' ) ) { - function bcdiv( $dividend, $divisor ) { - $quotient = floor( $dividend/$divisor ); - return $quotient; - } - function bcmod( $dividend, $modulo ) { - $remainder = $dividend%$modulo; - return $remainder; - } - function bcmul( $left, $right ) { - return $left * $right; - } - function bcadd( $left, $right ) { - return $left + $right; - } - function bcpow( $base, $power ) { - return pow( $base, $power ); - } + function bcdiv( $dividend, $divisor ) { + $quotient = floor( $dividend/$divisor ); + return $quotient; + } + function bcmod( $dividend, $modulo ) { + $remainder = $dividend%$modulo; + return $remainder; + } + function bcmul( $left, $right ) { + return $left * $right; + } + function bcadd( $left, $right ) { + return $left + $right; + } + function bcpow( $base, $power ) { + return pow( $base, $power ); + } } // @codeCoverageIgnoreEnd diff --git a/includes/functions-debug.php b/includes/functions-debug.php index 4e5a5572b..374c68996 100644 --- a/includes/functions-debug.php +++ b/includes/functions-debug.php @@ -40,7 +40,7 @@ function yourls_get_debug_log() { * @return int */ function yourls_get_num_queries() { - return yourls_apply_filter( 'get_num_queries', yourls_get_db()->get_num_queries() ); + return yourls_apply_filter( 'get_num_queries', yourls_get_db()->get_num_queries() ); } /** diff --git a/includes/functions-deprecated.php b/includes/functions-deprecated.php index 3154c174f..7c2ed10fc 100644 --- a/includes/functions-deprecated.php +++ b/includes/functions-deprecated.php @@ -129,12 +129,12 @@ function yourls_get_search_text() { */ function yourls_current_time( $type, $gmt = 0 ) { yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_get_timestamp' ); - switch ( $type ) { - case 'mysql': - return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', yourls_get_timestamp( time() )); - case 'timestamp': - return ( $gmt ) ? time() : yourls_get_timestamp( time() ); - } + switch ( $type ) { + case 'mysql': + return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate( 'Y-m-d H:i:s', yourls_get_timestamp( time() )); + case 'timestamp': + return ( $gmt ) ? time() : yourls_get_timestamp( time() ); + } } /** @@ -169,8 +169,8 @@ function yourls_sanitize_string( $string, $restrict_to_shorturl_charset = false * */ function yourls_favicon( $echo = true ) { - yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_get_yourls_favicon_url' ); - return yourls_get_yourls_favicon_url( $echo ); + yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_get_yourls_favicon_url' ); + return yourls_get_yourls_favicon_url( $echo ); } /** @@ -180,8 +180,8 @@ function yourls_favicon( $echo = true ) { * */ function yourls_get_link_stats( $url ) { - yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_get_keyword_stats' ); - return yourls_get_keyword_stats( $url ); + yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_get_keyword_stats' ); + return yourls_get_keyword_stats( $url ); } /** @@ -192,8 +192,8 @@ function yourls_get_link_stats( $url ) { * */ function yourls_url_exists( $url ) { - yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_long_url_exists' ); - return yourls_long_url_exists( $url ); + yourls_deprecated_function( __FUNCTION__, '1.7.10', 'yourls_long_url_exists' ); + return yourls_long_url_exists( $url ); } /** @@ -201,8 +201,8 @@ function yourls_url_exists( $url ) { * */ function yourls_plural( $word, $count=1 ) { - yourls_deprecated_function( __FUNCTION__, '1.6', 'yourls_n' ); - return $word . ($count > 1 ? 's' : ''); + yourls_deprecated_function( __FUNCTION__, '1.6', 'yourls_n' ); + return $word . ($count > 1 ? 's' : ''); } /** @@ -210,10 +210,10 @@ function yourls_plural( $word, $count=1 ) { * */ function yourls_get_duplicate_keywords( $longurl ) { - yourls_deprecated_function( __FUNCTION__, '1.7', 'yourls_get_longurl_keywords' ); - if( !yourls_allow_duplicate_longurls() ) - return NULL; - return yourls_apply_filter( 'get_duplicate_keywords', yourls_get_longurl_keywords ( $longurl ), $longurl ); + yourls_deprecated_function( __FUNCTION__, '1.7', 'yourls_get_longurl_keywords' ); + if( !yourls_allow_duplicate_longurls() ) + return NULL; + return yourls_apply_filter( 'get_duplicate_keywords', yourls_get_longurl_keywords ( $longurl ), $longurl ); } /** @@ -223,8 +223,8 @@ function yourls_get_duplicate_keywords( $longurl ) { * */ function yourls_intval( $int ) { - yourls_deprecated_function( __FUNCTION__, '1.7', 'yourls_sanitize_int' ); - return yourls_escape( $int ); + yourls_deprecated_function( __FUNCTION__, '1.7', 'yourls_sanitize_int' ); + return yourls_escape( $int ); } /** @@ -232,8 +232,8 @@ function yourls_intval( $int ) { * */ function yourls_get_remote_content( $url, $maxlen = 4096, $timeout = 5 ) { - yourls_deprecated_function( __FUNCTION__, '1.7', 'yourls_http_get_body' ); - return yourls_http_get_body( $url ); + yourls_deprecated_function( __FUNCTION__, '1.7', 'yourls_http_get_body' ); + return yourls_http_get_body( $url ); } /** @@ -250,8 +250,8 @@ function yourls_get_remote_content( $url, $maxlen = 4096, $timeout = 5 ) { * @return mixed */ function yourls_apply_filters( $hook, $value = '' ) { - yourls_deprecated_function( __FUNCTION__, '1.7.1', 'yourls_apply_filter' ); - return yourls_apply_filter( $hook, $value ); + yourls_deprecated_function( __FUNCTION__, '1.7.1', 'yourls_apply_filter' ); + return yourls_apply_filter( $hook, $value ); } /** @@ -259,10 +259,10 @@ function yourls_apply_filters( $hook, $value = '' ) { * */ function yourls_has_interface() { - yourls_deprecated_function( __FUNCTION__, '1.7.1' ); - if( yourls_is_API() or yourls_is_GO() ) - return false; - return true; + yourls_deprecated_function( __FUNCTION__, '1.7.1' ); + if( yourls_is_API() or yourls_is_GO() ) + return false; + return true; } /** @@ -274,8 +274,8 @@ function yourls_has_interface() { * @return bool true if a proxy is defined, false otherwise */ function yourls_http_proxy_is_defined() { - yourls_deprecated_function( __FUNCTION__, '1.7.1', 'yourls_http_get_proxy' ); - return yourls_apply_filter( 'http_proxy_is_defined', defined( 'YOURLS_PROXY' ) ); + yourls_deprecated_function( __FUNCTION__, '1.7.1', 'yourls_http_get_proxy' ); + return yourls_apply_filter( 'http_proxy_is_defined', defined( 'YOURLS_PROXY' ) ); } /** @@ -293,8 +293,8 @@ function yourls_http_proxy_is_defined() { * @return string Translated context string without pipe */ function yourls_ex( $text, $context, $domain = 'default' ) { - yourls_deprecated_function( __FUNCTION__, '1.7.1', 'yourls_xe' ); - echo yourls_xe( $text, $context, $domain ); + yourls_deprecated_function( __FUNCTION__, '1.7.1', 'yourls_xe' ); + echo yourls_xe( $text, $context, $domain ); } /** @@ -308,20 +308,20 @@ function yourls_ex( $text, $context, $domain = 'default' ) { * @return string|array escaped data */ function yourls_escape( $data ) { - yourls_deprecated_function( __FUNCTION__, '1.7.3', 'PDO' ); - if( is_array( $data ) ) { - foreach( $data as $k => $v ) { - if( is_array( $v ) ) { - $data[ $k ] = yourls_escape( $v ); - } else { - $data[ $k ] = yourls_escape_real( $v ); - } - } - } else { - $data = yourls_escape_real( $data ); - } + yourls_deprecated_function( __FUNCTION__, '1.7.3', 'PDO' ); + if( is_array( $data ) ) { + foreach( $data as $k => $v ) { + if( is_array( $v ) ) { + $data[ $k ] = yourls_escape( $v ); + } else { + $data[ $k ] = yourls_escape_real( $v ); + } + } + } else { + $data = yourls_escape_real( $data ); + } - return $data; + return $data; } /** @@ -338,13 +338,13 @@ function yourls_escape( $data ) { * @return string escaped string */ function yourls_escape_real( $string ) { - yourls_deprecated_function( __FUNCTION__, '1.7.3', 'PDO' ); - global $ydb; - if( isset( $ydb ) && ( $ydb instanceof \YOURLS\Database\YDB ) ) - return $ydb->escape( $string ); + yourls_deprecated_function( __FUNCTION__, '1.7.3', 'PDO' ); + global $ydb; + if( isset( $ydb ) && ( $ydb instanceof \YOURLS\Database\YDB ) ) + return $ydb->escape( $string ); - // YOURLS DB classes have been bypassed by a custom DB engine or a custom cache layer - return yourls_apply_filter( 'custom_escape_real', addslashes( $string ), $string ); + // YOURLS DB classes have been bypassed by a custom DB engine or a custom cache layer + return yourls_apply_filter( 'custom_escape_real', addslashes( $string ), $string ); } // @codeCoverageIgnoreEnd diff --git a/includes/functions-formatting.php b/includes/functions-formatting.php index f7b034fe4..da38ffce5 100644 --- a/includes/functions-formatting.php +++ b/includes/functions-formatting.php @@ -12,18 +12,18 @@ * @return string Converted number */ function yourls_int2string($num, $chars = null) { - if( $chars == null ) - $chars = yourls_get_shorturl_charset(); - $string = ''; - $len = strlen( $chars ); - while( $num >= $len ) { - $mod = bcmod( (string)$num, (string)$len ); - $num = bcdiv( (string)$num, (string)$len ); - $string = $chars[ $mod ] . $string; - } - $string = $chars[ intval( $num ) ] . $string; + if( $chars == null ) + $chars = yourls_get_shorturl_charset(); + $string = ''; + $len = strlen( $chars ); + while( $num >= $len ) { + $mod = bcmod( (string)$num, (string)$len ); + $num = bcdiv( (string)$num, (string)$len ); + $string = $chars[ $mod ] . $string; + } + $string = $chars[ intval( $num ) ] . $string; - return yourls_apply_filter( 'int2string', $string, $num, $chars ); + return yourls_apply_filter( 'int2string', $string, $num, $chars ); } /** @@ -34,18 +34,18 @@ function yourls_int2string($num, $chars = null) { * @return string Number (as a string) */ function yourls_string2int($string, $chars = null) { - if( $chars == null ) - $chars = yourls_get_shorturl_charset(); - $integer = 0; - $string = strrev( $string ); - $baselen = strlen( $chars ); - $inputlen = strlen( $string ); - for ($i = 0; $i < $inputlen; $i++) { - $index = strpos( $chars, $string[$i] ); - $integer = bcadd( (string)$integer, bcmul( (string)$index, bcpow( (string)$baselen, (string)$i ) ) ); - } + if( $chars == null ) + $chars = yourls_get_shorturl_charset(); + $integer = 0; + $string = strrev( $string ); + $baselen = strlen( $chars ); + $inputlen = strlen( $string ); + for ($i = 0; $i < $inputlen; $i++) { + $index = strpos( $chars, $string[$i] ); + $integer = bcadd( (string)$integer, bcmul( (string)$index, bcpow( (string)$baselen, (string)$i ) ) ); + } - return yourls_apply_filter( 'string2int', $integer, $string, $chars ); + return yourls_apply_filter( 'string2int', $integer, $string, $chars ); } /** @@ -58,10 +58,10 @@ function yourls_string2int($string, $chars = null) { */ function yourls_unique_element_id($prefix = 'yid', $initial_val = 1) { static $id_counter = 1; - if ($initial_val > 1) { - $id_counter = (int) $initial_val; - } - return yourls_apply_filter( 'unique_element_id', $prefix . (string) $id_counter++ ); + if ($initial_val > 1) { + $id_counter = (int) $initial_val; + } + return yourls_apply_filter( 'unique_element_id', $prefix . (string) $id_counter++ ); } /** @@ -86,7 +86,7 @@ function yourls_sanitize_keyword( $keyword, $restrict_to_shorturl_charset = fals $valid = yourls_sanitize_url( $keyword ); } - return yourls_apply_filter( 'sanitize_string', $valid, $keyword, $restrict_to_shorturl_charset ); + return yourls_apply_filter( 'sanitize_string', $valid, $keyword, $restrict_to_shorturl_charset ); } /** @@ -99,15 +99,15 @@ function yourls_sanitize_keyword( $keyword, $restrict_to_shorturl_charset = fals * @return string Safe title */ function yourls_sanitize_title( $unsafe_title, $fallback = '' ) { - $title = $unsafe_title; - $title = strip_tags( $title ); - $title = preg_replace( "/\s+/", ' ', trim( $title ) ); + $title = $unsafe_title; + $title = strip_tags( $title ); + $title = preg_replace( "/\s+/", ' ', trim( $title ) ); if ( '' === $title || false === $title ) { $title = $fallback; } - return yourls_apply_filter( 'sanitize_title', $title, $unsafe_title, $fallback ); + return yourls_apply_filter( 'sanitize_title', $title, $unsafe_title, $fallback ); } /** @@ -120,8 +120,8 @@ function yourls_sanitize_title( $unsafe_title, $fallback = '' ) { * @return string Safe URL */ function yourls_sanitize_url( $unsafe_url, $protocols = array() ) { - $url = yourls_esc_url( $unsafe_url, 'redirection', $protocols ); - return yourls_apply_filter( 'sanitize_url', $url, $unsafe_url ); + $url = yourls_esc_url( $unsafe_url, 'redirection', $protocols ); + return yourls_apply_filter( 'sanitize_url', $url, $unsafe_url ); } /** @@ -139,8 +139,8 @@ function yourls_sanitize_url( $unsafe_url, $protocols = array() ) { * @return string Safe URL */ function yourls_sanitize_url_safe( $unsafe_url, $protocols = array() ) { - $url = yourls_esc_url( $unsafe_url, 'safe', $protocols ); - return yourls_apply_filter( 'sanitize_url_safe', $url, $unsafe_url ); + $url = yourls_esc_url( $unsafe_url, 'safe', $protocols ); + return yourls_apply_filter( 'sanitize_url_safe', $url, $unsafe_url ); } /** @@ -153,18 +153,18 @@ function yourls_sanitize_url_safe( $unsafe_url, $protocols = array() ) { * @return string The string with the replaced values. */ function yourls_deep_replace($search, $subject ){ - $found = true; - while($found) { - $found = false; - foreach( (array) $search as $val ) { - while( strpos( $subject, $val ) !== false ) { - $found = true; - $subject = str_replace( $val, '', $subject ); - } - } - } + $found = true; + while($found) { + $found = false; + foreach( (array) $search as $val ) { + while( strpos( $subject, $val ) !== false ) { + $found = true; + $subject = str_replace( $val, '', $subject ); + } + } + } - return $subject; + return $subject; } /** @@ -174,7 +174,7 @@ function yourls_deep_replace($search, $subject ){ * @return string Integer as a string */ function yourls_sanitize_int($int ) { - return ( substr( preg_replace( '/[^0-9]/', '', strval( $int ) ), 0, 20 ) ); + return ( substr( preg_replace( '/[^0-9]/', '', strval( $int ) ), 0, 20 ) ); } /** @@ -185,7 +185,7 @@ function yourls_sanitize_int($int ) { * @return string IP address */ function yourls_sanitize_ip($ip ) { - return preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip ); + return preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip ); } /** @@ -195,10 +195,10 @@ function yourls_sanitize_ip($ip ) { * @return false|mixed Date in format m(m)/d(d)/yyyy or false if invalid */ function yourls_sanitize_date($date ) { - if( !preg_match( '!^\d{1,2}/\d{1,2}/\d{4}$!' , $date ) ) { - return false; - } - return $date; + if( !preg_match( '!^\d{1,2}/\d{1,2}/\d{4}$!' , $date ) ) { + return false; + } + return $date; } /** @@ -208,9 +208,9 @@ function yourls_sanitize_date($date ) { * @return false|string String in Y-m-d format for SQL search or false if malformed input */ function yourls_sanitize_date_for_sql($date) { - if( !yourls_sanitize_date( $date ) ) - return false; - return date( 'Y-m-d', strtotime( $date ) ); + if( !yourls_sanitize_date( $date ) ) + return false; + return date( 'Y-m-d', strtotime( $date ) ); } /** @@ -222,11 +222,11 @@ function yourls_sanitize_date_for_sql($date) { * @return string Trimmed string */ function yourls_trim_long_string($string, $length = 60, $append = '[...]') { - $newstring = $string; + $newstring = $string; if ( mb_strlen( $newstring ) > $length ) { $newstring = mb_substr( $newstring, 0, $length - mb_strlen( $append ), 'UTF-8' ) . $append; } - return yourls_apply_filter( 'trim_long_string', $newstring, $string, $length, $append ); + return yourls_apply_filter( 'trim_long_string', $newstring, $string, $length, $append ); } /** @@ -234,7 +234,12 @@ function yourls_trim_long_string($string, $length = 60, $append = '[...]') { * * The regexp searches for the first digits, then a period, then more digits and periods, and discards * all the rest. - * For instance, 'mysql-5.5-beta' and '5.5-RC1' return '5.5' + * Examples: + * 'omgmysql-5.5-ubuntu-4.20' => '5.5' + * 'mysql5.5-ubuntu-4.20' => '5.5' + * '5.5-ubuntu-4.20' => '5.5' + * '5.5-beta2' => '5.5' + * '5.5' => '5.5' * * @since 1.4.1 * @param string $version Version number @@ -254,9 +259,9 @@ function yourls_sanitize_version( $version ) { * @return string|null Sanitized file name (or null if it's just backslashes, ok...) */ function yourls_sanitize_filename($file) { - $file = str_replace( '\\', '/', $file ); // sanitize for Win32 installs - $file = preg_replace( '|/+|' ,'/', $file ); // remove any duplicate slash - return $file; + $file = str_replace( '\\', '/', $file ); // sanitize for Win32 installs + $file = preg_replace( '|/+|' ,'/', $file ); // remove any duplicate slash + return $file; } /** @@ -266,22 +271,22 @@ function yourls_sanitize_filename($file) { * @return bool Whether string seems valid UTF-8 */ function yourls_seems_utf8($str) { - $length = strlen( $str ); - for ( $i=0; $i < $length; $i++ ) { - $c = ord( $str[ $i ] ); - if ( $c < 0x80 ) $n = 0; # 0bbbbbbb - elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb - elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb - elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb - elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb - elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b - else return false; # Does not match any model - for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ? - if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80)) - return false; - } - } - return true; + $length = strlen( $str ); + for ( $i=0; $i < $length; $i++ ) { + $c = ord( $str[ $i ] ); + if ( $c < 0x80 ) $n = 0; # 0bbbbbbb + elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb + elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb + elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb + elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb + elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b + else return false; # Does not match any model + for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ? + if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80)) + return false; + } + } + return true; } @@ -313,28 +318,28 @@ function yourls_supports_pcre_u() { * @return string The checked text. */ function yourls_check_invalid_utf8( $string, $strip = false ) { - $string = (string) $string; + $string = (string) $string; - if ( 0 === strlen( $string ) ) { - return ''; - } + if ( 0 === strlen( $string ) ) { + return ''; + } - // We can't demand utf8 in the PCRE installation, so just return the string in those cases - if ( ! yourls_supports_pcre_u() ) { - return $string; - } + // We can't demand utf8 in the PCRE installation, so just return the string in those cases + if ( ! yourls_supports_pcre_u() ) { + return $string; + } - // preg_match fails when it encounters invalid UTF8 in $string - if ( 1 === @preg_match( '/^./us', $string ) ) { - return $string; - } + // preg_match fails when it encounters invalid UTF8 in $string + if ( 1 === @preg_match( '/^./us', $string ) ) { + return $string; + } - // Attempt to strip the bad chars if requested (not recommended) - if ( $strip && function_exists( 'iconv' ) ) { - return iconv( 'utf-8', 'utf-8', $string ); - } + // Attempt to strip the bad chars if requested (not recommended) + if ( $strip && function_exists( 'iconv' ) ) { + return iconv( 'utf-8', 'utf-8', $string ); + } - return ''; + return ''; } /** @@ -353,56 +358,56 @@ function yourls_check_invalid_utf8( $string, $strip = false ) { * @return string The encoded text with HTML entities. */ function yourls_specialchars( $string, $quote_style = ENT_NOQUOTES, $double_encode = false ) { - $string = (string) $string; + $string = (string) $string; - if ( 0 === strlen( $string ) ) - return ''; + if ( 0 === strlen( $string ) ) + return ''; - // Don't bother if there are no specialchars - saves some processing - if ( ! preg_match( '/[&<>"\']/', $string ) ) - return $string; + // Don't bother if there are no specialchars - saves some processing + if ( ! preg_match( '/[&<>"\']/', $string ) ) + return $string; - // Account for the previous behaviour of the function when the $quote_style is not an accepted value - if ( empty( $quote_style ) ) - $quote_style = ENT_NOQUOTES; - elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) - $quote_style = ENT_QUOTES; + // Account for the previous behaviour of the function when the $quote_style is not an accepted value + if ( empty( $quote_style ) ) + $quote_style = ENT_NOQUOTES; + elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) + $quote_style = ENT_QUOTES; - $charset = 'UTF-8'; + $charset = 'UTF-8'; - $_quote_style = $quote_style; + $_quote_style = $quote_style; - if ( $quote_style === 'double' ) { - $quote_style = ENT_COMPAT; - $_quote_style = ENT_COMPAT; - } elseif ( $quote_style === 'single' ) { - $quote_style = ENT_NOQUOTES; - } + if ( $quote_style === 'double' ) { + $quote_style = ENT_COMPAT; + $_quote_style = ENT_COMPAT; + } elseif ( $quote_style === 'single' ) { + $quote_style = ENT_NOQUOTES; + } - // Handle double encoding ourselves - if ( $double_encode ) { - $string = @htmlspecialchars( $string, $quote_style, $charset ); - } else { - // Decode & into & - $string = yourls_specialchars_decode( $string, $_quote_style ); + // Handle double encoding ourselves + if ( $double_encode ) { + $string = @htmlspecialchars( $string, $quote_style, $charset ); + } else { + // Decode & into & + $string = yourls_specialchars_decode( $string, $_quote_style ); - // Guarantee every &entity; is valid or re-encode the & - $string = yourls_kses_normalize_entities( $string ); + // Guarantee every &entity; is valid or re-encode the & + $string = yourls_kses_normalize_entities( $string ); - // Now re-encode everything except &entity; - $string = preg_split( '/(&#?x?[0-9a-z]+;)/i', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); + // Now re-encode everything except &entity; + $string = preg_split( '/(&#?x?[0-9a-z]+;)/i', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); - for ( $i = 0; $i < count( $string ); $i += 2 ) - $string[$i] = @htmlspecialchars( $string[$i], $quote_style, $charset ); + for ( $i = 0; $i < count( $string ); $i += 2 ) + $string[$i] = @htmlspecialchars( $string[$i], $quote_style, $charset ); - $string = implode( '', $string ); - } + $string = implode( '', $string ); + } - // Backwards compatibility - if ( 'single' === $_quote_style ) - $string = str_replace( "'", ''', $string ); + // Backwards compatibility + if ( 'single' === $_quote_style ) + $string = str_replace( "'", ''', $string ); - return $string; + return $string; } /** @@ -420,53 +425,53 @@ function yourls_specialchars( $string, $quote_style = ENT_NOQUOTES, $double_enco * @return string The decoded text without HTML entities. */ function yourls_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) { - $string = (string) $string; - - if ( 0 === strlen( $string ) ) { - return ''; - } - - // Don't bother if there are no entities - saves a lot of processing - if ( strpos( $string, '&' ) === false ) { - return $string; - } - - // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value - if ( empty( $quote_style ) ) { - $quote_style = ENT_NOQUOTES; - } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { - $quote_style = ENT_QUOTES; - } - - // More complete than get_html_translation_table( HTML_SPECIALCHARS ) - $single = array( ''' => '\'', ''' => '\'' ); - $single_preg = array( '/�*39;/' => ''', '/�*27;/i' => ''' ); - $double = array( '"' => '"', '"' => '"', '"' => '"' ); - $double_preg = array( '/�*34;/' => '"', '/�*22;/i' => '"' ); - $others = array( '<' => '<', '<' => '<', '>' => '>', '>' => '>', '&' => '&', '&' => '&', '&' => '&' ); - $others_preg = array( '/�*60;/' => '<', '/�*62;/' => '>', '/�*38;/' => '&', '/�*26;/i' => '&' ); + $string = (string) $string; + + if ( 0 === strlen( $string ) ) { + return ''; + } + + // Don't bother if there are no entities - saves a lot of processing + if ( strpos( $string, '&' ) === false ) { + return $string; + } + + // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value + if ( empty( $quote_style ) ) { + $quote_style = ENT_NOQUOTES; + } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) { + $quote_style = ENT_QUOTES; + } + + // More complete than get_html_translation_table( HTML_SPECIALCHARS ) + $single = array( ''' => '\'', ''' => '\'' ); + $single_preg = array( '/�*39;/' => ''', '/�*27;/i' => ''' ); + $double = array( '"' => '"', '"' => '"', '"' => '"' ); + $double_preg = array( '/�*34;/' => '"', '/�*22;/i' => '"' ); + $others = array( '<' => '<', '<' => '<', '>' => '>', '>' => '>', '&' => '&', '&' => '&', '&' => '&' ); + $others_preg = array( '/�*60;/' => '<', '/�*62;/' => '>', '/�*38;/' => '&', '/�*26;/i' => '&' ); $translation = $translation_preg = []; - if ( $quote_style === ENT_QUOTES ) { - $translation = array_merge( $single, $double, $others ); - $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); - } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) { - $translation = array_merge( $double, $others ); - $translation_preg = array_merge( $double_preg, $others_preg ); - } elseif ( $quote_style === 'single' ) { - $translation = array_merge( $single, $others ); - $translation_preg = array_merge( $single_preg, $others_preg ); - } elseif ( $quote_style === ENT_NOQUOTES ) { - $translation = $others; - $translation_preg = $others_preg; - } + if ( $quote_style === ENT_QUOTES ) { + $translation = array_merge( $single, $double, $others ); + $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); + } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) { + $translation = array_merge( $double, $others ); + $translation_preg = array_merge( $double_preg, $others_preg ); + } elseif ( $quote_style === 'single' ) { + $translation = array_merge( $single, $others ); + $translation_preg = array_merge( $single_preg, $others_preg ); + } elseif ( $quote_style === ENT_NOQUOTES ) { + $translation = $others; + $translation_preg = $others_preg; + } - // Remove zero padding on numeric entities - $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string ); + // Remove zero padding on numeric entities + $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string ); - // Replace characters according to translation table - return strtr( $string, $translation ); + // Replace characters according to translation table + return strtr( $string, $translation ); } @@ -479,9 +484,9 @@ function yourls_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) { * @return string */ function yourls_esc_html( $text ) { - $safe_text = yourls_check_invalid_utf8( $text ); - $safe_text = yourls_specialchars( $safe_text, ENT_QUOTES ); - return yourls_apply_filter( 'esc_html', $safe_text, $text ); + $safe_text = yourls_check_invalid_utf8( $text ); + $safe_text = yourls_specialchars( $safe_text, ENT_QUOTES ); + return yourls_apply_filter( 'esc_html', $safe_text, $text ); } /** @@ -493,9 +498,9 @@ function yourls_esc_html( $text ) { * @return string */ function yourls_esc_attr( $text ) { - $safe_text = yourls_check_invalid_utf8( $text ); - $safe_text = yourls_specialchars( $safe_text, ENT_QUOTES ); - return yourls_apply_filter( 'esc_attr', $safe_text, $text ); + $safe_text = yourls_check_invalid_utf8( $text ); + $safe_text = yourls_specialchars( $safe_text, ENT_QUOTES ); + return yourls_apply_filter( 'esc_attr', $safe_text, $text ); } /** @@ -518,38 +523,38 @@ function yourls_esc_url( $url, $context = 'display', $protocols = array() ) { // trim first -- see #1931 $url = trim( $url ); - // make sure there's only one 'http://' at the beginning (prevents pasting a URL right after the default 'http://') - $url = str_replace( - array( 'http://http://', 'http://https://' ), - array( 'http://', 'https://' ), - $url - ); + // make sure there's only one 'http://' at the beginning (prevents pasting a URL right after the default 'http://') + $url = str_replace( + array( 'http://http://', 'http://https://' ), + array( 'http://', 'https://' ), + $url + ); - if ( '' == $url ) - return $url; + if ( '' == $url ) + return $url; - $original_url = $url; + $original_url = $url; - // force scheme and domain to lowercase - see issues 591 and 1630 + // force scheme and domain to lowercase - see issues 591 and 1630 $url = yourls_normalize_uri( $url ); - $url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url ); - // Previous regexp in YOURLS was '|[^a-z0-9-~+_.?\[\]\^#=!&;,/:%@$\|*`\'<>"()\\x80-\\xff\{\}]|i' - // TODO: check if that was it too destructive + $url = preg_replace( '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url ); + // Previous regexp in YOURLS was '|[^a-z0-9-~+_.?\[\]\^#=!&;,/:%@$\|*`\'<>"()\\x80-\\xff\{\}]|i' + // TODO: check if that was it too destructive // If $context is 'safe', an extra step is taken to make sure no CRLF injection is possible. // To be used when $url can be forged by evil user (eg it's from a $_SERVER variable, a query string, etc..) - if ( 'safe' == $context ) { + if ( 'safe' == $context ) { $strip = array( '%0d', '%0a', '%0D', '%0A' ); $url = yourls_deep_replace( $strip, $url ); } - // Replace ampersands and single quotes only when displaying. - if ( 'display' == $context ) { - $url = yourls_kses_normalize_entities( $url ); - $url = str_replace( '&', '&', $url ); - $url = str_replace( "'", ''', $url ); - } + // Replace ampersands and single quotes only when displaying. + if ( 'display' == $context ) { + $url = yourls_kses_normalize_entities( $url ); + $url = str_replace( '&', '&', $url ); + $url = str_replace( "'", ''', $url ); + } // If there's a protocol, make sure it's OK if( yourls_get_protocol($url) !== '' ) { @@ -565,7 +570,7 @@ function yourls_esc_url( $url, $context = 'display', $protocols = array() ) { // I didn't use KSES function kses_bad_protocol() because it doesn't work the way I liked (returns //blah from illegal://blah) } - return yourls_apply_filter( 'esc_url', $url, $original_url, $context ); + return yourls_apply_filter( 'esc_url', $url, $original_url, $context ); } @@ -664,12 +669,12 @@ function yourls_normalize_uri( $url ) { * @return string Escaped text. */ function yourls_esc_js( $text ) { - $safe_text = yourls_check_invalid_utf8( $text ); - $safe_text = yourls_specialchars( $safe_text, ENT_COMPAT ); - $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) ); - $safe_text = str_replace( "\r", '', $safe_text ); - $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) ); - return yourls_apply_filter( 'esc_js', $safe_text, $text ); + $safe_text = yourls_check_invalid_utf8( $text ); + $safe_text = yourls_specialchars( $safe_text, ENT_COMPAT ); + $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) ); + $safe_text = str_replace( "\r", '', $safe_text ); + $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) ); + return yourls_apply_filter( 'esc_js', $safe_text, $text ); } /** @@ -681,8 +686,8 @@ function yourls_esc_js( $text ) { * @return string */ function yourls_esc_textarea( $text ) { - $safe_text = htmlspecialchars( $text, ENT_QUOTES ); - return yourls_apply_filter( 'esc_textarea', $safe_text, $text ); + $safe_text = htmlspecialchars( $text, ENT_QUOTES ); + return yourls_apply_filter( 'esc_textarea', $safe_text, $text ); } /** @@ -708,7 +713,7 @@ function yourls_backslashit($string) { * @return bool */ function yourls_is_rawurlencoded( $string ) { - return rawurldecode( $string ) != $string; + return rawurldecode( $string ) != $string; } /** @@ -722,11 +727,11 @@ function yourls_is_rawurlencoded( $string ) { * @return string */ function yourls_rawurldecode_while_encoded( $string ) { - $string = rawurldecode( $string ); - if( yourls_is_rawurlencoded( $string ) ) { - $string = yourls_rawurldecode_while_encoded( $string ); - } - return $string; + $string = rawurldecode( $string ); + if( yourls_is_rawurlencoded( $string ) ) { + $string = yourls_rawurldecode_while_encoded( $string ); + } + return $string; } /** diff --git a/includes/functions-html.php b/includes/functions-html.php index d633e70b8..ff9c995ad 100644 --- a/includes/functions-html.php +++ b/includes/functions-html.php @@ -6,16 +6,16 @@ * @return void */ function yourls_html_logo() { - yourls_do_action( 'pre_html_logo' ); - ?> -
-

- YOURLS: Your Own URL Shortener
-
-

-
- +
+

+ YOURLS: Your Own URL Shortener
+
+

+
+ + ?> > - <?php echo $title ?> - - - - + <?php echo $title ?> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- -
-

- YOURLS v ' . YOURLS_VERSION ); - $footer .= $num_queries; - echo yourls_apply_filter( 'html_footer_text', $footer ); - ?> -

-
';
-		echo join( "\n", yourls_get_debug_log() );
-		echo '
'; - } ?> - - - - + +

+ YOURLS v ' . YOURLS_VERSION ); + $footer .= $num_queries; + echo yourls_apply_filter( 'html_footer_text', $footer ); + ?> +

+
';
+        echo join( "\n", yourls_get_debug_log() );
+        echo '
'; + } ?> + + + + -
-
-
-
-
+ ?> +
+
+
+ +
: : @@ -194,12 +198,12 @@ function yourls_html_addnew( $url = '', $keyword = '' ) {
- - -
- -
- + +
+ +
+ - - - -
-
-
- '; - $_options = array( + ?> + + + +
+ +
+ '; + $_options = array( 'all' => yourls__( 'All fields' ), - 'keyword' => yourls__( 'Short URL' ), - 'url' => yourls__( 'URL' ), - 'title' => yourls__( 'Title' ), - 'ip' => yourls__( 'IP' ), - ); - $_select = yourls_html_select( 'search_in', $_options, $search_in, false, yourls__( 'Search in' ) ); - /* //translators: "Search for in in '; - yourls_se( 'Show %s rows', $_input ); - echo "
\n"; - - // Fourth search control: Show links with more than XX clicks - $_options = array( - 'more' => yourls__( 'more' ), - 'less' => yourls__( 'less' ), - ); - $_select = yourls_html_select( 'click_filter', $_options, $click_filter, false, yourls__( 'Show links with' ) ); - $_input = ' '; - /* //translators: "Show links with than clicks" */ - yourls_se( 'Show links with %1$s than %2$s clicks', $_select, $_input ); - echo "
\n"; - - // Fifth search control: Show links created before/after/between ... - $_options = array( - 'before' => yourls__('before'), - 'after' => yourls__('after'), - 'between' => yourls__('between'), - ); - $_select = yourls_html_select( 'date_filter', $_options, $date_filter, false, yourls__('Show links created') ); - $_input = ''; - $_and = ' & '; - $_input2 = ''; - /* //translators: "Show links created <"and" if applicable> " */ - yourls_se( 'Show links created %1$s %2$s %3$s %4$s', $_select, $_input, $_and, $_input2 ); - ?> - -
- -   - -
- -
- -
- - - - - - - - - \n"; + + // Fourth search control: Show links with more than XX clicks + $_options = array( + 'more' => yourls__( 'more' ), + 'less' => yourls__( 'less' ), + ); + $_select = yourls_html_select( 'click_filter', $_options, $click_filter, false, yourls__( 'Show links with' ) ); + $_input = ' '; + /* //translators: "Show links with than clicks" */ + yourls_se( 'Show links with %1$s than %2$s clicks', $_select, $_input ); + echo "
\n"; + + // Fifth search control: Show links created before/after/between ... + $_options = array( + 'before' => yourls__('before'), + 'after' => yourls__('after'), + 'between' => yourls__('between'), + ); + $_select = yourls_html_select( 'date_filter', $_options, $date_filter, false, yourls__('Show links created') ); + $_input = ''; + $_and = ' & '; + $_input2 = ''; + /* //translators: "Show links created <"and" if applicable> " */ + yourls_se( 'Show links created %1$s %2$s %3$s %4$s', $_select, $_input, $_and, $_input2 ); + ?> + +
+ +   + +
+ +
+ +
+ + + + + + + + + \n"; - foreach( $options as $value => $text ) { - $html .= "
' ); + echo yourls_apply_filter( 'table_end', '' ); } @@ -725,12 +729,12 @@ function yourls_table_end() { * @return void */ function yourls_html_link( $href, $anchor = '', $element = '' ) { - if( !$anchor ) - $anchor = $href; - if( $element ) - $element = sprintf( 'id="%s"', yourls_esc_attr( $element ) ); - $link = sprintf( '%s', yourls_esc_url( $href ), $element, yourls_esc_html( $anchor ) ); - echo yourls_apply_filter( 'html_link', $link ); + if( !$anchor ) + $anchor = $href; + if( $element ) + $element = sprintf( 'id="%s"', yourls_esc_attr( $element ) ); + $link = sprintf( '%s', yourls_esc_url( $href ), $element, yourls_esc_html( $anchor ) ); + echo yourls_apply_filter( 'html_link', $link ); } /** @@ -740,44 +744,46 @@ function yourls_html_link( $href, $anchor = '', $element = '' ) { * @return void */ function yourls_login_screen( $error_msg = '' ) { - yourls_html_head( 'login' ); - - $action = ( isset( $_GET['action'] ) && $_GET['action'] == 'logout' ? '?' : '' ); - - yourls_html_logo(); - ?> -
-
- '.$error_msg.'

'; - } - yourls_do_action( 'login_form_top' ); - ?> -

-
- -

-

-
- -

- -

- - -

- -
- -
- +
+
+
+ '.$error_msg.'

'; + } + yourls_do_action( 'login_form_top' ); + ?> +

+
+ +

+

+
+ +

+ +

+ + +

+ +
+ +
+
+ 'logout'], yourls_admin_url('index.php')), 'nonce', 'logout'); - $logout_link = yourls_apply_filter('logout_link', sprintf( yourls__('Hello %s'), YOURLS_USER ) . ' (' . yourls__( 'Logout' ) . ')' ); - } else { - $logout_link = yourls_apply_filter( 'logout_link', '' ); - } - $help_link = yourls_apply_filter( 'help_link', '' . yourls__( 'Help' ) . '' ); - - $admin_links = array(); - $admin_sublinks = array(); - - $admin_links['admin'] = array( - 'url' => yourls_admin_url( 'index.php' ), - 'title' => yourls__( 'Go to the admin interface' ), - 'anchor' => yourls__( 'Admin interface' ) - ); - - if( yourls_is_admin() ) { - $admin_links['tools'] = array( - 'url' => yourls_admin_url( 'tools.php' ), - 'anchor' => yourls__( 'Tools' ) - ); - $admin_links['plugins'] = array( - 'url' => yourls_admin_url( 'plugins.php' ), - 'anchor' => yourls__( 'Manage Plugins' ) - ); - $admin_sublinks['plugins'] = yourls_list_plugin_admin_pages(); - } - - $admin_links = yourls_apply_filter( 'admin_links', $admin_links ); - $admin_sublinks = yourls_apply_filter( 'admin_sublinks', $admin_sublinks ); - - // Now output menu - echo '\n"; - yourls_do_action( 'admin_notices' ); - yourls_do_action( 'admin_notice' ); // because I never remember if it's 'notices' or 'notice' - /* - To display a notice: - $message = "
OMG, dude, I mean!
" ); - yourls_add_action( 'admin_notices', function() use ( $message ) { echo (string) $message; } ); - */ + // Build menu links + if( defined( 'YOURLS_USER' ) ) { + // Create a logout link with a nonce associated to fake user 'logout' : the user is not yet defined + // when the logout check is done -- see yourls_is_valid_user() + $logout_url = yourls_nonce_url( 'admin_logout', + yourls_add_query_arg(['action' => 'logout'], yourls_admin_url('index.php')), 'nonce', 'logout'); + $logout_link = yourls_apply_filter('logout_link', sprintf( yourls__('Hello %s'), YOURLS_USER ) . ' (' . yourls__( 'Logout' ) . ')' ); + } else { + $logout_link = yourls_apply_filter( 'logout_link', '' ); + } + $help_link = yourls_apply_filter( 'help_link', '' . yourls__( 'Help' ) . '' ); + + $admin_links = array(); + $admin_sublinks = array(); + + $admin_links['admin'] = array( + 'url' => yourls_admin_url( 'index.php' ), + 'title' => yourls__( 'Go to the admin interface' ), + 'anchor' => yourls__( 'Admin interface' ) + ); + + if( yourls_is_admin() ) { + $admin_links['tools'] = array( + 'url' => yourls_admin_url( 'tools.php' ), + 'anchor' => yourls__( 'Tools' ) + ); + $admin_links['plugins'] = array( + 'url' => yourls_admin_url( 'plugins.php' ), + 'anchor' => yourls__( 'Manage Plugins' ) + ); + $admin_sublinks['plugins'] = yourls_list_plugin_admin_pages(); + } + + $admin_links = yourls_apply_filter( 'admin_links', $admin_links ); + $admin_sublinks = yourls_apply_filter( 'admin_sublinks', $admin_sublinks ); + + // Now output menu + echo '\n"; + yourls_do_action( 'admin_notices' ); + yourls_do_action( 'admin_notice' ); // because I never remember if it's 'notices' or 'notice' + /* + To display a notice: + $message = "
OMG, dude, I mean!
" ); + yourls_add_action( 'admin_notices', function() use ( $message ) { echo (string) $message; } ); + */ } /** @@ -870,9 +876,9 @@ function yourls_html_menu() { * @return void */ function yourls_add_notice( $message, $style = 'notice' ) { - // Escape single quotes in $message to avoid breaking the anonymous function - $message = yourls_notice_box( strtr( $message, array( "'" => "\'" ) ), $style ); - yourls_add_action( 'admin_notices', function() use ( $message ) { echo (string) $message; } ); + // Escape single quotes in $message to avoid breaking the anonymous function + $message = yourls_notice_box( strtr( $message, array( "'" => "\'" ) ), $style ); + yourls_add_action( 'admin_notices', function() use ( $message ) { echo (string) $message; } ); } /** @@ -883,10 +889,10 @@ function yourls_add_notice( $message, $style = 'notice' ) { * @return string HTML of the notice */ function yourls_notice_box( $message, $style = 'notice' ) { - return << -

$message

- + return << +

$message

+ HTML; } @@ -902,15 +908,15 @@ function yourls_notice_box( $message, $style = 'notice' ) { */ function yourls_page( $page ) { if( !yourls_is_page($page)) { - yourls_die( yourls_s('Page "%1$s" not found', $page), yourls__('Not found'), 404 ); + yourls_die( yourls_s('Page "%1$s" not found', $page), yourls__('Not found'), 404 ); } - yourls_do_action( 'pre_page', $page ); + yourls_do_action( 'pre_page', $page ); $load = yourls_include_file_sandbox(YOURLS_PAGEDIR . "/$page.php"); - if (is_string($load)) { + if (is_string($load)) { yourls_die( $load, yourls__('Not found'), 404 ); - } - yourls_do_action( 'post_page', $page ); + } + yourls_do_action( 'post_page', $page ); } /** @@ -923,24 +929,24 @@ function yourls_page( $page ) { * @return void */ function yourls_html_language_attributes() { - $attributes = array(); - $output = ''; - - $attributes[] = ( yourls_is_rtl() ? 'dir="rtl"' : 'dir="ltr"' ); - - $doctype = yourls_apply_filter( 'html_language_attributes_doctype', 'html' ); - // Experimental: get HTML lang from locale. Should work. Convert fr_FR -> fr-FR - if ( $lang = str_replace( '_', '-', yourls_get_locale() ) ) { - if( $doctype == 'xhtml' ) { - $attributes[] = "xml:lang=\"$lang\""; - } else { - $attributes[] = "lang=\"$lang\""; - } - } - - $output = implode( ' ', $attributes ); - $output = yourls_apply_filter( 'html_language_attributes', $output ); - echo $output; + $attributes = array(); + $output = ''; + + $attributes[] = ( yourls_is_rtl() ? 'dir="rtl"' : 'dir="ltr"' ); + + $doctype = yourls_apply_filter( 'html_language_attributes_doctype', 'html' ); + // Experimental: get HTML lang from locale. Should work. Convert fr_FR -> fr-FR + if ( $lang = str_replace( '_', '-', yourls_get_locale() ) ) { + if( $doctype == 'xhtml' ) { + $attributes[] = "xml:lang=\"$lang\""; + } else { + $attributes[] = "lang=\"$lang\""; + } + } + + $output = implode( ' ', $attributes ); + $output = yourls_apply_filter( 'html_language_attributes', $output ); + echo $output; } /** @@ -950,16 +956,16 @@ function yourls_html_language_attributes() { * @return void */ function yourls_l10n_calendar_strings() { - echo "\n\n"; - - // Dummy returns, to initialize l10n strings used in the calendar - yourls__( 'Today' ); - yourls__( 'Close' ); + echo "\n\n"; + + // Dummy returns, to initialize l10n strings used in the calendar + yourls__( 'Today' ); + yourls__( 'Close' ); } @@ -973,14 +979,14 @@ function yourls_l10n_calendar_strings() { function yourls_new_core_version_notice($compare_with = null) { $compare_with = $compare_with ?: YOURLS_VERSION; - $checks = yourls_get_option( 'core_version_checks' ); + $checks = yourls_get_option( 'core_version_checks' ); $latest = isset($checks->last_result->latest) ? yourls_sanitize_version($checks->last_result->latest) : false; - if( $latest AND version_compare( $latest, $compare_with, '>' ) ) { + if( $latest AND version_compare( $latest, $compare_with, '>' ) ) { yourls_do_action('new_core_version_notice', $latest); - $msg = yourls_s( 'YOURLS version %s is available. Please update!', 'http://yourls.org/download', $latest ); - yourls_add_notice( $msg ); - } + $msg = yourls_s( 'YOURLS version %s is available. Please update!', 'http://yourls.org/download', $latest ); + yourls_add_notice( $msg ); + } } /** diff --git a/includes/functions-http.php b/includes/functions-http.php index db60abcf9..4275282dc 100644 --- a/includes/functions-http.php +++ b/includes/functions-http.php @@ -31,7 +31,7 @@ * @return mixed Response object, or error string */ function yourls_http_get( $url, $headers = array(), $data = array(), $options = array() ) { - return yourls_http_request( 'GET', $url, $headers, $data, $options ); + return yourls_http_request( 'GET', $url, $headers, $data, $options ); } /** @@ -46,8 +46,8 @@ function yourls_http_get( $url, $headers = array(), $data = array(), $options = * @return mixed String (page body) or null if error */ function yourls_http_get_body( $url, $headers = array(), $data = array(), $options = array() ) { - $return = yourls_http_get( $url, $headers, $data, $options ); - return isset( $return->body ) ? $return->body : null; + $return = yourls_http_get( $url, $headers, $data, $options ); + return isset( $return->body ) ? $return->body : null; } /** @@ -64,7 +64,7 @@ function yourls_http_get_body( $url, $headers = array(), $data = array(), $optio * @return mixed Response object, or error string */ function yourls_http_post( $url, $headers = array(), $data = array(), $options = array() ) { - return yourls_http_request( 'POST', $url, $headers, $data, $options ); + return yourls_http_request( 'POST', $url, $headers, $data, $options ); } /** @@ -81,8 +81,8 @@ function yourls_http_post( $url, $headers = array(), $data = array(), $options = * @return mixed String (page body) or null if error */ function yourls_http_post_body( $url, $headers = array(), $data = array(), $options = array() ) { - $return = yourls_http_post( $url, $headers, $data, $options ); - return isset( $return->body ) ? $return->body : null; + $return = yourls_http_post( $url, $headers, $data, $options ); + return isset( $return->body ) ? $return->body : null; } /** @@ -127,18 +127,18 @@ function yourls_http_get_proxy_bypass_host() { * @return array Options */ function yourls_http_default_options() { - $options = array( - 'timeout' => yourls_apply_filter( 'http_default_options_timeout', 3 ), - 'useragent' => yourls_http_user_agent(), - 'follow_redirects' => true, - 'redirects' => 3, - ); - - if( yourls_http_get_proxy() ) { + $options = array( + 'timeout' => yourls_apply_filter( 'http_default_options_timeout', 3 ), + 'useragent' => yourls_http_user_agent(), + 'follow_redirects' => true, + 'redirects' => 3, + ); + + if( yourls_http_get_proxy() ) { $options['proxy'] = yourls_http_get_proxy(); - } + } - return yourls_apply_filter( 'http_default_options', $options ); + return yourls_apply_filter( 'http_default_options', $options ); } /** @@ -155,27 +155,27 @@ function yourls_http_default_options() { */ function yourls_send_through_proxy( $url ) { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_send_through_proxy', null, $url ); - if ( null !== $pre ) - return $pre; + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_send_through_proxy', null, $url ); + if ( null !== $pre ) + return $pre; - $check = @parse_url( $url ); + $check = @parse_url( $url ); if( !isset( $check['host'] ) ) { return false; } - // Malformed URL, can not process, but this could mean ssl, so let through anyway. - if ( $check === false ) - return true; + // Malformed URL, can not process, but this could mean ssl, so let through anyway. + if ( $check === false ) + return true; - // Self and loopback URLs are considered local (':' is parse_url() host on '::1') - $home = parse_url( yourls_get_yourls_site() ); - $local = array( 'localhost', '127.0.0.1', '127.1', '[::1]', ':', $home['host'] ); + // Self and loopback URLs are considered local (':' is parse_url() host on '::1') + $home = parse_url( yourls_get_yourls_site() ); + $local = array( 'localhost', '127.0.0.1', '127.1', '[::1]', ':', $home['host'] ); - if( in_array( $check['host'], $local ) ) - return false; + if( in_array( $check['host'], $local ) ) + return false; $bypass = yourls_http_get_proxy_bypass_host(); @@ -183,10 +183,10 @@ function yourls_send_through_proxy( $url ) { return true; } - // Build array of hosts to bypass - static $bypass_hosts; - static $wildcard_regex = false; - if ( null == $bypass_hosts ) { + // Build array of hosts to bypass + static $bypass_hosts; + static $wildcard_regex = false; + if ( null == $bypass_hosts ) { $bypass_hosts = preg_split( '|\s*,\s*|', $bypass ); if ( false !== strpos( $bypass, '*' ) ) { @@ -199,12 +199,12 @@ function yourls_send_through_proxy( $url ) { } $wildcard_regex = '/^(' . implode( '|', $wildcard_regex ) . ')$/i'; } - } + } - if ( !empty( $wildcard_regex ) ) - return !preg_match( $wildcard_regex, $check['host'] ); - else - return !in_array( $check['host'], $bypass_hosts ); + if ( !empty( $wildcard_regex ) ) + return !preg_match( $wildcard_regex, $check['host'] ); + else + return !in_array( $check['host'], $bypass_hosts ); } /** @@ -220,16 +220,16 @@ function yourls_send_through_proxy( $url ) { */ function yourls_http_request( $type, $url, $headers, $data, $options ) { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_yourls_http_request', null, $type, $url, $headers, $data, $options ); - if ( null !== $pre ) - return $pre; + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_yourls_http_request', null, $type, $url, $headers, $data, $options ); + if ( null !== $pre ) + return $pre; - $options = array_merge( yourls_http_default_options(), $options ); + $options = array_merge( yourls_http_default_options(), $options ); - if( yourls_http_get_proxy() && !yourls_send_through_proxy( $url ) ) { - unset( $options['proxy'] ); - } + if( yourls_http_get_proxy() && !yourls_send_through_proxy( $url ) ) { + unset( $options['proxy'] ); + } // filter everything $type = yourls_apply_filter('http_request_type', $type); @@ -238,13 +238,13 @@ function yourls_http_request( $type, $url, $headers, $data, $options ) { $data = yourls_apply_filter('http_request_data', $data); $options = yourls_apply_filter('http_request_options', $options); - try { - $result = Requests::request( $url, $headers, $data, $type, $options ); - } catch( \WpOrg\Requests\Exception $e ) { - $result = yourls_debug_log( $e->getMessage() . ' (' . $type . ' on ' . $url . ')' ); - }; + try { + $result = Requests::request( $url, $headers, $data, $type, $options ); + } catch( \WpOrg\Requests\Exception $e ) { + $result = yourls_debug_log( $e->getMessage() . ' (' . $type . ' on ' . $url . ')' ); + }; - return $result; + return $result; } /** @@ -254,7 +254,7 @@ function yourls_http_request( $type, $url, $headers, $data, $options ) { * @return string UA string */ function yourls_http_user_agent() { - return yourls_apply_filter( 'http_user_agent', 'YOURLS v'.YOURLS_VERSION.' +http://yourls.org/ (running on '.yourls_get_yourls_site().')' ); + return yourls_apply_filter( 'http_user_agent', 'YOURLS v'.YOURLS_VERSION.' +http://yourls.org/ (running on '.yourls_get_yourls_site().')' ); } /** @@ -274,51 +274,51 @@ function yourls_http_user_agent() { */ function yourls_check_core_version() { - global $yourls_user_passwords; + global $yourls_user_passwords; - $checks = yourls_get_option( 'core_version_checks' ); + $checks = yourls_get_option( 'core_version_checks' ); - // Invalidate check data when YOURLS version changes - if ( is_object( $checks ) && YOURLS_VERSION != $checks->version_checked ) { - $checks = false; - } + // Invalidate check data when YOURLS version changes + if ( is_object( $checks ) && YOURLS_VERSION != $checks->version_checked ) { + $checks = false; + } - if( !is_object( $checks ) ) { - $checks = new stdClass; - $checks->failed_attempts = 0; - $checks->last_attempt = 0; - $checks->last_result = ''; - $checks->version_checked = YOURLS_VERSION; - } + if( !is_object( $checks ) ) { + $checks = new stdClass; + $checks->failed_attempts = 0; + $checks->last_attempt = 0; + $checks->last_result = ''; + $checks->version_checked = YOURLS_VERSION; + } - // Total number of links and clicks + // Total number of links and clicks list( $total_urls, $total_clicks ) = array_values(yourls_get_db_stats()); - // The collection of stuff to report - $stuff = array( - // Globally uniquish site identifier + // The collection of stuff to report + $stuff = array( + // Globally uniquish site identifier // This uses const YOURLS_SITE and not yourls_get_yourls_site() to prevent creating another id for an already known install - 'md5' => md5( YOURLS_SITE . YOURLS_ABSPATH ), - - // Install information - 'failed_attempts' => $checks->failed_attempts, - 'yourls_site' => defined( 'YOURLS_SITE' ) ? yourls_get_yourls_site() : 'unknown', - 'yourls_version' => defined( 'YOURLS_VERSION' ) ? YOURLS_VERSION : 'unknown', - 'php_version' => PHP_VERSION, - 'mysql_version' => yourls_get_db()->mysql_version(), - 'locale' => yourls_get_locale(), - - // custom DB driver if any, and useful common PHP extensions - 'db_driver' => defined( 'YOURLS_DB_DRIVER' ) ? YOURLS_DB_DRIVER : 'unset', - 'db_ext_pdo' => extension_loaded( 'PDO' ) ? 1 : 0, - 'db_ext_mysql' => extension_loaded( 'mysql' ) ? 1 : 0, - 'db_ext_mysqli' => extension_loaded( 'mysqli' ) ? 1 : 0, - 'ext_curl' => extension_loaded( 'curl' ) ? 1 : 0, - - // Config information - 'yourls_private' => defined( 'YOURLS_PRIVATE' ) && YOURLS_PRIVATE ? 1 : 0, - 'yourls_unique' => defined( 'YOURLS_UNIQUE_URLS' ) && YOURLS_UNIQUE_URLS ? 1 : 0, - 'yourls_url_convert' => defined( 'YOURLS_URL_CONVERT' ) ? YOURLS_URL_CONVERT : 'unknown', + 'md5' => md5( YOURLS_SITE . YOURLS_ABSPATH ), + + // Install information + 'failed_attempts' => $checks->failed_attempts, + 'yourls_site' => defined( 'YOURLS_SITE' ) ? yourls_get_yourls_site() : 'unknown', + 'yourls_version' => defined( 'YOURLS_VERSION' ) ? YOURLS_VERSION : 'unknown', + 'php_version' => PHP_VERSION, + 'mysql_version' => yourls_get_db()->mysql_version(), + 'locale' => yourls_get_locale(), + + // custom DB driver if any, and useful common PHP extensions + 'db_driver' => defined( 'YOURLS_DB_DRIVER' ) ? YOURLS_DB_DRIVER : 'unset', + 'db_ext_pdo' => extension_loaded( 'PDO' ) ? 1 : 0, + 'db_ext_mysql' => extension_loaded( 'mysql' ) ? 1 : 0, + 'db_ext_mysqli' => extension_loaded( 'mysqli' ) ? 1 : 0, + 'ext_curl' => extension_loaded( 'curl' ) ? 1 : 0, + + // Config information + 'yourls_private' => defined( 'YOURLS_PRIVATE' ) && YOURLS_PRIVATE ? 1 : 0, + 'yourls_unique' => defined( 'YOURLS_UNIQUE_URLS' ) && YOURLS_UNIQUE_URLS ? 1 : 0, + 'yourls_url_convert' => defined( 'YOURLS_URL_CONVERT' ) ? YOURLS_URL_CONVERT : 'unknown', // Usage information 'num_users' => count( $yourls_user_passwords ), @@ -326,44 +326,44 @@ function yourls_check_core_version() { 'num_pages' => defined( 'YOURLS_PAGEDIR' ) ? count( (array) glob( YOURLS_PAGEDIR .'/*.php') ) : 0, 'num_links' => $total_urls, 'num_clicks' => $total_clicks, - ); + ); - $stuff = yourls_apply_filter( 'version_check_stuff', $stuff ); + $stuff = yourls_apply_filter( 'version_check_stuff', $stuff ); - // Send it in - $url = 'http://api.yourls.org/core/version/1.1/'; + // Send it in + $url = 'http://api.yourls.org/core/version/1.1/'; if( yourls_can_http_over_ssl() ) { $url = yourls_set_url_scheme($url, 'https'); } - $req = yourls_http_post( $url, array(), $stuff ); + $req = yourls_http_post( $url, array(), $stuff ); - $checks->last_attempt = time(); - $checks->version_checked = YOURLS_VERSION; + $checks->last_attempt = time(); + $checks->version_checked = YOURLS_VERSION; - // Unexpected results ? - if( is_string( $req ) or !$req->success ) { - $checks->failed_attempts = $checks->failed_attempts + 1; - yourls_update_option( 'core_version_checks', $checks ); - if( is_string($req) ) { + // Unexpected results ? + if( is_string( $req ) or !$req->success ) { + $checks->failed_attempts = $checks->failed_attempts + 1; + yourls_update_option( 'core_version_checks', $checks ); + if( is_string($req) ) { yourls_debug_log('Version check failed: ' . $req); } - return false; - } + return false; + } - // Parse response - $json = json_decode( trim( $req->body ) ); + // Parse response + $json = json_decode( trim( $req->body ) ); - if( yourls_validate_core_version_response($json) ) { - // All went OK - mark this down - $checks->failed_attempts = 0; - $checks->last_result = $json; - yourls_update_option( 'core_version_checks', $checks ); + if( yourls_validate_core_version_response($json) ) { + // All went OK - mark this down + $checks->failed_attempts = 0; + $checks->last_result = $json; + yourls_update_option( 'core_version_checks', $checks ); - return $json; - } + return $json; + } - // Request returned actual result, but not what we expected - return false; + // Request returned actual result, but not what we expected + return false; } /** @@ -467,33 +467,33 @@ function yourls_maybe_check_core_version() { return false; } - $checks = yourls_get_option( 'core_version_checks' ); - - /* We don't want to check if : - - last_result is set (a previous check was performed) - - and it was less than 24h ago (or less than 2h ago if it wasn't successful) - - and version checked matched version running - Otherwise, we want to check. - */ - if( !empty( $checks->last_result ) - AND - ( - ( $checks->failed_attempts == 0 && ( ( time() - $checks->last_attempt ) < 24 * 3600 ) ) - OR - ( $checks->failed_attempts > 0 && ( ( time() - $checks->last_attempt ) < 2 * 3600 ) ) - ) - AND ( $checks->version_checked == YOURLS_VERSION ) - ) - return false; - - // We want to check if there's a new version - $new_check = yourls_check_core_version(); - - // Could not check for a new version, and we don't have ancient data - if( false == $new_check && !isset( $checks->last_result->latest ) ) - return false; - - return true; + $checks = yourls_get_option( 'core_version_checks' ); + + /* We don't want to check if : + - last_result is set (a previous check was performed) + - and it was less than 24h ago (or less than 2h ago if it wasn't successful) + - and version checked matched version running + Otherwise, we want to check. + */ + if( !empty( $checks->last_result ) + AND + ( + ( $checks->failed_attempts == 0 && ( ( time() - $checks->last_attempt ) < 24 * 3600 ) ) + OR + ( $checks->failed_attempts > 0 && ( ( time() - $checks->last_attempt ) < 2 * 3600 ) ) + ) + AND ( $checks->version_checked == YOURLS_VERSION ) + ) + return false; + + // We want to check if there's a new version + $new_check = yourls_check_core_version(); + + // Could not check for a new version, and we don't have ancient data + if( false == $new_check && !isset( $checks->last_result->latest ) ) + return false; + + return true; } /** diff --git a/includes/functions-infos.php b/includes/functions-infos.php index ed972034b..4cbe8956c 100644 --- a/includes/functions-infos.php +++ b/includes/functions-infos.php @@ -9,27 +9,27 @@ */ function yourls_stats_countries_map($countries, $id = null) { - yourls_do_action( 'pre_stats_countries_map' ); + yourls_do_action( 'pre_stats_countries_map' ); - // if $id is null then assign a random string - if( $id === null ) - $id = uniqid ( 'yourls_stats_map_' ); + // if $id is null then assign a random string + if( $id === null ) + $id = uniqid ( 'yourls_stats_map_' ); - $data = array_merge( array( 'Country' => 'Hits' ), $countries ); - $data = yourls_google_array_to_data_table( $data ); + $data = array_merge( array( 'Country' => 'Hits' ), $countries ); + $data = yourls_google_array_to_data_table( $data ); - $options = array( - 'backgroundColor' => "white", - 'colorAxis' => "{colors:['A8D0ED','99C4E4','8AB8DB','7BACD2','6BA1C9','5C95C0','4D89B7','3E7DAE','2E72A5','1F669C']}", - 'width' => "550", - 'height' => "340", - 'theme' => 'maximized' - ); - $options = yourls_apply_filter( 'stats_countries_map_options', $options ); + $options = array( + 'backgroundColor' => "white", + 'colorAxis' => "{colors:['A8D0ED','99C4E4','8AB8DB','7BACD2','6BA1C9','5C95C0','4D89B7','3E7DAE','2E72A5','1F669C']}", + 'width' => "550", + 'height' => "340", + 'theme' => 'maximized' + ); + $options = yourls_apply_filter( 'stats_countries_map_options', $options ); - $map = yourls_google_viz_code( 'GeoChart', $data, $options, $id ); + $map = yourls_google_viz_code( 'GeoChart', $data, $options, $id ); - echo yourls_apply_filter( 'stats_countries_map', $map, $countries, $options, $id ); + echo yourls_apply_filter( 'stats_countries_map', $map, $countries, $options, $id ); } @@ -44,49 +44,49 @@ function yourls_stats_countries_map($countries, $id = null) { */ function yourls_stats_pie($data, $limit = 10, $size = '340x220', $id = null) { - yourls_do_action( 'pre_stats_pie' ); - - // if $id is null then assign a random string - if( $id === null ) - $id = uniqid ( 'yourls_stats_pie_' ); - - // Trim array: $limit first item + the sum of all others - if ( count( $data ) > $limit ) { - $i= 0; - $trim_data = array( 'Others' => 0 ); - foreach( $data as $item=>$value ) { - $i++; - if( $i <= $limit ) { - $trim_data[$item] = $value; - } else { - $trim_data['Others'] += $value; - } - } - $data = $trim_data; - } - - // Scale items - $_data = yourls_scale_data( $data ); - - list($width, $height) = explode( 'x', $size ); - - $options = array( - 'theme' => 'maximized', - 'width' => $width, - 'height' => $height, - 'colors' => "['A8D0ED','99C4E4','8AB8DB','7BACD2','6BA1C9','5C95C0','4D89B7','3E7DAE','2E72A5','1F669C']", - 'legend' => 'none', - 'chartArea' => '{top: "5%", height: "90%"}', - 'pieSliceText' => 'label', - ); - $options = yourls_apply_filter( 'stats_pie_options', $options ); - - $script_data = array_merge( array( 'Country' => 'Value' ), $_data ); - $script_data = yourls_google_array_to_data_table( $script_data ); - - $pie = yourls_google_viz_code( 'PieChart', $script_data, $options, $id ); - - echo yourls_apply_filter( 'stats_pie', $pie, $data, $limit, $size, $options, $id ); + yourls_do_action( 'pre_stats_pie' ); + + // if $id is null then assign a random string + if( $id === null ) + $id = uniqid ( 'yourls_stats_pie_' ); + + // Trim array: $limit first item + the sum of all others + if ( count( $data ) > $limit ) { + $i= 0; + $trim_data = array( 'Others' => 0 ); + foreach( $data as $item=>$value ) { + $i++; + if( $i <= $limit ) { + $trim_data[$item] = $value; + } else { + $trim_data['Others'] += $value; + } + } + $data = $trim_data; + } + + // Scale items + $_data = yourls_scale_data( $data ); + + list($width, $height) = explode( 'x', $size ); + + $options = array( + 'theme' => 'maximized', + 'width' => $width, + 'height' => $height, + 'colors' => "['A8D0ED','99C4E4','8AB8DB','7BACD2','6BA1C9','5C95C0','4D89B7','3E7DAE','2E72A5','1F669C']", + 'legend' => 'none', + 'chartArea' => '{top: "5%", height: "90%"}', + 'pieSliceText' => 'label', + ); + $options = yourls_apply_filter( 'stats_pie_options', $options ); + + $script_data = array_merge( array( 'Country' => 'Value' ), $_data ); + $script_data = yourls_google_array_to_data_table( $script_data ); + + $pie = yourls_google_viz_code( 'PieChart', $script_data, $options, $id ); + + echo yourls_apply_filter( 'stats_pie', $pie, $data, $limit, $size, $options, $id ); } @@ -97,72 +97,79 @@ function yourls_stats_pie($data, $limit = 10, $size = '340x220', $id = null) { * @return array[] Array of arrays of days, months, years */ function yourls_build_list_of_days($dates) { - /* Say we have an array like: - $dates = array ( - 2009 => array ( - '08' => array ( - 29 => 15, - 30 => 5, - ), - '09' => array ( - '02' => 3, - '03' => 5, - '04' => 2, - '05' => 99, - ), - ), - ) - */ - - if( !$dates ) - return array(); - - // Get first & last years from our range. In our example: 2009 & 2009 - $first_year = key( $dates ); - $_keys = array_keys( $dates ); - $last_year = end( $_keys ); - reset( $dates ); - - // Get first & last months from our range. In our example: 08 & 09 - $first_month = key( $dates[ $first_year ] ); - $_keys = array_keys( $dates[ $last_year ] ); - $last_month = end( $_keys ); - reset( $dates ); - - // Get first & last days from our range. In our example: 29 & 05 - $first_day = key( $dates[ $first_year ][ $first_month ] ); - $_keys = array_keys( $dates[ $last_year ][ $last_month ] ); - $last_day = end( $_keys ); - - unset( $_keys ); - - // Now build a list of all years (2009), month (08 & 09) and days (all from 2009-08-29 to 2009-09-05) - $list_of_years = array(); - $list_of_months = array(); - $list_of_days = array(); - for ( $year = $first_year; $year <= $last_year; $year++ ) { - $_year = sprintf( '%04d', $year ); - $list_of_years[ $_year ] = $_year; - $current_first_month = ( $year == $first_year ? $first_month : '01' ); - $current_last_month = ( $year == $last_year ? $last_month : '12' ); - for ( $month = $current_first_month; $month <= $current_last_month; $month++ ) { - $_month = sprintf( '%02d', $month ); - $list_of_months[ $_month ] = $_month; - $current_first_day = ( $year == $first_year && $month == $first_month ? $first_day : '01' ); - $current_last_day = ( $year == $last_year && $month == $last_month ? $last_day : yourls_days_in_month( $month, $year) ); - for ( $day = $current_first_day; $day <= $current_last_day; $day++ ) { - $day = sprintf( '%02d', $day ); - $key = date( 'M d, Y', mktime( 0, 0, 0, $_month, $day, $_year ) ); - $list_of_days[ $key ] = isset( $dates[$_year][$_month][$day] ) ? $dates[$_year][$_month][$day] : 0; - } - } - } - - return array( - 'list_of_days' => $list_of_days, - 'list_of_months' => $list_of_months, - 'list_of_years' => $list_of_years, - ); + /* Say we have an array like: + $dates = array ( + 2009 => array ( + '08' => array ( + 29 => 15, + 30 => 5, + ), + '09' => array ( + '02' => 3, + '03' => 5, + '04' => 2, + '05' => 99, + ), + ), + ) + */ + + if( !$dates ) + return array(); + + // Get first & last years from our range. In our example: 2009 & 2009 + $first_year = key( $dates ); + $_keys = array_keys( $dates ); + $last_year = end( $_keys ); + reset( $dates ); + + // Get first & last months from our range. In our example: 08 & 09 + $first_month = key( $dates[ $first_year ] ); + $_keys = array_keys( $dates[ $last_year ] ); + $last_month = end( $_keys ); + reset( $dates ); + + // Get first & last days from our range. In our example: 29 & 05 + $first_day = key( $dates[ $first_year ][ $first_month ] ); + $_keys = array_keys( $dates[ $last_year ][ $last_month ] ); + $last_day = end( $_keys ); + + unset( $_keys ); + + // Extend to today + $today = new DateTime(); + $today->setTime( 0, 0, 0 ); // Start of today + $today_year = $today->format( 'Y' ); + $today_month = $today->format( 'm' ); + $today_day = $today->format( 'd' ); + + // Now build a list of all years (2009), month (08 & 09) and days (all from 2009-08-29 to 2009-09-05) + $list_of_years = array(); + $list_of_months = array(); + $list_of_days = array(); + for ( $year = $first_year; $year <= $today_year; $year++ ) { + $_year = sprintf( '%04d', $year ); + $list_of_years[ $_year ] = $_year; + $current_first_month = ( $year == $first_year ? $first_month : '01' ); + $current_last_month = ( $year == $today_year ? $today_month : '12' ); + for ( $month = $current_first_month; $month <= $current_last_month; $month++ ) { + $_month = sprintf( '%02d', $month ); + $list_of_months[ $_month ] = $_month; + $current_first_day = ( $year == $first_year && $month == $first_month ? $first_day : '01' ); + $current_last_day = ( $year == $today_year && $month == $today_month ? $today_day : yourls_days_in_month( $month, $year ) ); + for ( $day = $current_first_day; $day <= $current_last_day; $day++ ) { + $day = sprintf( '%02d', $day ); + $key = date( 'M d, Y', mktime( 0, 0, 0, $_month, $day, $_year ) ); + $list_of_days[ $key ] = isset( $dates[$_year][$_month][$day] ) ? $dates[$_year][$_month][$day] : 0; + } + } + } + + return array( + 'list_of_days' => $list_of_days, + 'list_of_months' => $list_of_months, + 'list_of_years' => $list_of_years, + ); } @@ -177,38 +184,38 @@ function yourls_build_list_of_days($dates) { */ function yourls_stats_line($values, $id = null) { - yourls_do_action( 'pre_stats_line' ); + yourls_do_action( 'pre_stats_line' ); - // if $id is null then assign a random string - if( $id === null ) - $id = uniqid ( 'yourls_stats_line_' ); + // if $id is null then assign a random string + if( $id === null ) + $id = uniqid ( 'yourls_stats_line_' ); - // If we have only 1 day of data, prepend a fake day with 0 hits for a prettier graph - if ( count( $values ) == 1 ) - array_unshift( $values, 0 ); + // If we have only 1 day of data, prepend a fake day with 0 hits for a prettier graph + if ( count( $values ) == 1 ) + array_unshift( $values, 0 ); - // Keep only a subset of values to keep graph smooth - $values = yourls_array_granularity( $values, 30 ); + // Keep only a subset of values to keep graph smooth + $values = yourls_array_granularity( $values, 30 ); - $data = array_merge( array( 'Time' => 'Hits' ), $values ); - $data = yourls_google_array_to_data_table( $data ); + $data = array_merge( array( 'Time' => 'Hits' ), $values ); + $data = yourls_google_array_to_data_table( $data ); - $options = array( - "legend" => "none", - "pointSize" => "3", - "theme" => "maximized", - "curveType" => "function", - "width" => 430, - "height" => 220, - "hAxis" => "{minTextSpacing: 80, maxTextLines: 1, maxAlternation: 1}", - "vAxis" => "{minValue: 0, format: '#'}", - "colors" => "['#2a85b3']", - ); - $options = yourls_apply_filter( 'stats_line_options', $options ); + $options = array( + "legend" => "none", + "pointSize" => "3", + "theme" => "maximized", + "curveType" => "function", + "width" => 430, + "height" => 220, + "hAxis" => "{minTextSpacing: 80, maxTextLines: 1, maxAlternation: 1}", + "vAxis" => "{minValue: 0, format: '#'}", + "colors" => "['#2a85b3']", + ); + $options = yourls_apply_filter( 'stats_line_options', $options ); - $lineChart = yourls_google_viz_code( 'LineChart', $data, $options, $id ); + $lineChart = yourls_google_viz_code( 'LineChart', $data, $options, $id ); - echo yourls_apply_filter( 'stats_line', $lineChart, $values, $options, $id ); + echo yourls_apply_filter( 'stats_line', $lineChart, $values, $options, $id ); } @@ -220,8 +227,8 @@ function yourls_stats_line($values, $id = null) { * @return int */ function yourls_days_in_month($month, $year) { - // calculate number of days in a month - return $month == 2 ? ( $year % 4 ? 28 : ( $year % 100 ? 29 : ( $year % 400 ? 28 : 29 ) ) ) : ( ( $month - 1 ) % 7 % 2 ? 30 : 31 ); + // calculate number of days in a month + return $month == 2 ? ( $year % 4 ? 28 : ( $year % 100 ? 29 : ( $year % 400 ? 28 : 29 ) ) ) : ( ( $month - 1 ) % 7 % 2 ? 30 : 31 ); } @@ -232,11 +239,11 @@ function yourls_days_in_month($month, $year) { * @return array */ function yourls_stats_get_best_day($list_of_days) { - $max = max( $list_of_days ); - foreach( $list_of_days as $k=>$v ) { - if ( $v == $max ) - return array( 'day' => $k, 'max' => $max ); - } + $max = max( $list_of_days ); + foreach( $list_of_days as $k=>$v ) { + if ( $v == $max ) + return array( 'day' => $k, 'max' => $max ); + } } /** @@ -247,19 +254,19 @@ function yourls_stats_get_best_day($list_of_days) { * @return string */ function yourls_get_domain($url, $include_scheme = false) { - $parse = @parse_url( $url ); // Hiding ugly stuff coming from malformed referrer URLs + $parse = @parse_url( $url ); // Hiding ugly stuff coming from malformed referrer URLs - // Get host & scheme. Fall back to path if not found. - $host = isset( $parse['host'] ) ? $parse['host'] : ''; - $scheme = isset( $parse['scheme'] ) ? $parse['scheme'] : ''; - $path = isset( $parse['path'] ) ? $parse['path'] : ''; - if( !$host ) - $host = $path; + // Get host & scheme. Fall back to path if not found. + $host = isset( $parse['host'] ) ? $parse['host'] : ''; + $scheme = isset( $parse['scheme'] ) ? $parse['scheme'] : ''; + $path = isset( $parse['path'] ) ? $parse['path'] : ''; + if( !$host ) + $host = $path; - if ( $include_scheme && $scheme ) - $host = $scheme.'://'.$host; + if ( $include_scheme && $scheme ) + $host = $scheme.'://'.$host; - return $host; + return $host; } @@ -270,7 +277,7 @@ function yourls_get_domain($url, $include_scheme = false) { * @return string */ function yourls_get_favicon_url($url) { - return yourls_match_current_protocol( '//www.google.com/s2/favicons?domain=' . yourls_get_domain( $url, false ) ); + return yourls_match_current_protocol( '//www.google.com/s2/favicons?domain=' . yourls_get_domain( $url, false ) ); } /** @@ -280,13 +287,13 @@ function yourls_get_favicon_url($url) { * @return array */ function yourls_scale_data($data ) { - $max = max( $data ); - if( $max > 100 ) { - foreach( $data as $k=>$v ) { - $data[$k] = intval( $v / $max * 100 ); - } - } - return $data; + $max = max( $data ); + if( $max > 100 ) { + foreach( $data as $k=>$v ) { + $data[$k] = intval( $v / $max * 100 ); + } + } + return $data; } @@ -302,24 +309,24 @@ function yourls_scale_data($data ) { * @return array */ function yourls_array_granularity($array, $grain = 100, $preserve_max = true) { - if ( count( $array ) > $grain ) { - $max = max( $array ); - $step = intval( count( $array ) / $grain ); - $i = 0; - // Loop through each item and unset except every $step (optional preserve the max value) - foreach( $array as $k=>$v ) { - $i++; - if ( $i % $step != 0 ) { - if ( $preserve_max == false ) { - unset( $array[$k] ); - } else { - if ( $v < $max ) - unset( $array[$k] ); - } - } - } - } - return $array; + if ( count( $array ) > $grain ) { + $max = max( $array ); + $step = intval( count( $array ) / $grain ); + $i = 0; + // Loop through each item and unset except every $step (optional preserve the max value) + foreach( $array as $k=>$v ) { + $i++; + if ( $i % $step != 0 ) { + if ( $preserve_max == false ) { + unset( $array[$k] ); + } else { + if ( $v < $max ) + unset( $array[$k] ); + } + } + } + } + return $array; } /** @@ -329,23 +336,23 @@ function yourls_array_granularity($array, $grain = 100, $preserve_max = true) { * @return string */ function yourls_google_array_to_data_table($data){ - $str = "var data = google.visualization.arrayToDataTable([\n"; - foreach( $data as $label => $values ){ - if( !is_array( $values ) ) { - $values = array( $values ); - } - $str .= "\t['$label',"; - foreach( $values as $value ){ - if( !is_numeric( $value ) && strpos( $value, '[' ) !== 0 && strpos( $value, '{' ) !== 0 ) { - $value = "'$value'"; - } - $str .= "$value"; - } - $str .= "],\n"; - } - $str = substr( $str, 0, -2 ) . "\n"; // remove the trailing comma/return, reappend the return - $str .= "]);\n"; // wrap it up - return $str; + $str = "var data = google.visualization.arrayToDataTable([\n"; + foreach( $data as $label => $values ){ + if( !is_array( $values ) ) { + $values = array( $values ); + } + $str .= "\t['$label',"; + foreach( $values as $value ){ + if( !is_numeric( $value ) && strpos( $value, '[' ) !== 0 && strpos( $value, '{' ) !== 0 ) { + $value = "'$value'"; + } + $str .= "$value"; + } + $str .= "],\n"; + } + $str = substr( $str, 0, -2 ) . "\n"; // remove the trailing comma/return, reappend the return + $str .= "]);\n"; // wrap it up + return $str; } /** @@ -358,27 +365,27 @@ function yourls_google_array_to_data_table($data){ * @return string */ function yourls_google_viz_code($graph_type, $data, $options, $id ) { - $function_name = 'yourls_graph' . $id; - $code = "\n\n"; - $code .= "
\n"; - - return $code; + $function_name = 'yourls_graph' . $id; + $code = "\n\n"; + $code .= "
\n"; + + return $code; } diff --git a/includes/functions-install.php b/includes/functions-install.php index 2ccd11873..534510609 100644 --- a/includes/functions-install.php +++ b/includes/functions-install.php @@ -20,19 +20,19 @@ function yourls_check_database_version() { } /** - * Get DB version + * Get DB server version * * @since 1.7 * @return string sanitized DB version */ function yourls_get_database_version() { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_get_database_version', false ); - if ( false !== $pre ) { - return $pre; + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_get_database_version', false ); + if ( false !== $pre ) { + return $pre; } - return yourls_sanitize_version(yourls_get_db()->mysql_version()); + return yourls_sanitize_version(yourls_get_db()->mysql_version()); } /** @@ -53,12 +53,12 @@ function yourls_check_php_version() { * @return bool */ function yourls_is_apache() { - if( !array_key_exists( 'SERVER_SOFTWARE', $_SERVER ) ) - return false; - return ( - strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) !== false - || strpos( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) !== false - ); + if( !array_key_exists( 'SERVER_SOFTWARE', $_SERVER ) ) + return false; + return ( + strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) !== false + || strpos( $_SERVER['SERVER_SOFTWARE'], 'LiteSpeed' ) !== false + ); } /** @@ -67,7 +67,7 @@ function yourls_is_apache() { * @return bool */ function yourls_is_iis() { - return ( array_key_exists( 'SERVER_SOFTWARE', $_SERVER ) ? ( strpos( $_SERVER['SERVER_SOFTWARE'], 'IIS' ) !== false ) : false ); + return ( array_key_exists( 'SERVER_SOFTWARE', $_SERVER ) ? ( strpos( $_SERVER['SERVER_SOFTWARE'], 'IIS' ) !== false ) : false ); } @@ -77,55 +77,55 @@ function yourls_is_iis() { * @return bool */ function yourls_create_htaccess() { - $host = parse_url( yourls_get_yourls_site() ); - $path = ( isset( $host['path'] ) ? $host['path'] : '' ); - - if ( yourls_is_iis() ) { - // Prepare content for a web.config file - $content = array( - '', - '', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - '', - ); - - $filename = YOURLS_ABSPATH.'/web.config'; - $marker = 'none'; - - } else { - // Prepare content for a .htaccess file - $content = array( - '', - 'RewriteEngine On', - 'RewriteBase '.$path.'/', - 'RewriteCond %{REQUEST_FILENAME} !-f', - 'RewriteCond %{REQUEST_FILENAME} !-d', - 'RewriteRule ^.*$ '.$path.'/yourls-loader.php [L]', - '', - ); - - $filename = YOURLS_ABSPATH.'/.htaccess'; - $marker = 'YOURLS'; - - } - - return ( yourls_insert_with_markers( $filename, $marker, $content ) ); + $host = parse_url( yourls_get_yourls_site() ); + $path = ( isset( $host['path'] ) ? $host['path'] : '' ); + + if ( yourls_is_iis() ) { + // Prepare content for a web.config file + $content = array( + '', + '', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + '', + ); + + $filename = YOURLS_ABSPATH.'/web.config'; + $marker = 'none'; + + } else { + // Prepare content for a .htaccess file + $content = array( + '', + 'RewriteEngine On', + 'RewriteBase '.$path.'/', + 'RewriteCond %{REQUEST_FILENAME} !-f', + 'RewriteCond %{REQUEST_FILENAME} !-d', + 'RewriteRule ^.*$ '.$path.'/yourls-loader.php [L]', + '', + ); + + $filename = YOURLS_ABSPATH.'/.htaccess'; + $marker = 'YOURLS'; + + } + + return ( yourls_insert_with_markers( $filename, $marker, $content ) ); } /** @@ -143,54 +143,54 @@ function yourls_create_htaccess() { * @return bool True on write success, false on failure. */ function yourls_insert_with_markers( $filename, $marker, $insertion ) { - if ( !file_exists( $filename ) || is_writeable( $filename ) ) { - if ( !file_exists( $filename ) ) { - $markerdata = ''; - } else { - $markerdata = explode( "\n", implode( '', file( $filename ) ) ); - } - - if ( !$f = @fopen( $filename, 'w' ) ) - return false; - - $foundit = false; - if ( $markerdata ) { - $state = true; - foreach ( $markerdata as $n => $markerline ) { - if ( strpos( $markerline, '# BEGIN ' . $marker ) !== false ) - $state = false; - if ( $state ) { - if ( $n + 1 < count( $markerdata ) ) - fwrite( $f, "{$markerline}\n" ); - else - fwrite( $f, "{$markerline}" ); - } - if ( strpos( $markerline, '# END ' . $marker ) !== false ) { - if ( $marker != 'none' ) - fwrite( $f, "# BEGIN {$marker}\n" ); - if ( is_array( $insertion ) ) - foreach ( $insertion as $insertline ) - fwrite( $f, "{$insertline}\n" ); - if ( $marker != 'none' ) - fwrite( $f, "# END {$marker}\n" ); - $state = true; - $foundit = true; - } - } - } - if ( !$foundit ) { - if ( $marker != 'none' ) - fwrite( $f, "\n\n# BEGIN {$marker}\n" ); - foreach ( $insertion as $insertline ) - fwrite( $f, "{$insertline}\n" ); - if ( $marker != 'none' ) - fwrite( $f, "# END {$marker}\n\n" ); - } - fclose( $f ); - return true; - } else { - return false; - } + if ( !file_exists( $filename ) || is_writeable( $filename ) ) { + if ( !file_exists( $filename ) ) { + $markerdata = ''; + } else { + $markerdata = explode( "\n", implode( '', file( $filename ) ) ); + } + + if ( !$f = @fopen( $filename, 'w' ) ) + return false; + + $foundit = false; + if ( $markerdata ) { + $state = true; + foreach ( $markerdata as $n => $markerline ) { + if ( strpos( $markerline, '# BEGIN ' . $marker ) !== false ) + $state = false; + if ( $state ) { + if ( $n + 1 < count( $markerdata ) ) + fwrite( $f, "{$markerline}\n" ); + else + fwrite( $f, "{$markerline}" ); + } + if ( strpos( $markerline, '# END ' . $marker ) !== false ) { + if ( $marker != 'none' ) + fwrite( $f, "# BEGIN {$marker}\n" ); + if ( is_array( $insertion ) ) + foreach ( $insertion as $insertline ) + fwrite( $f, "{$insertline}\n" ); + if ( $marker != 'none' ) + fwrite( $f, "# END {$marker}\n" ); + $state = true; + $foundit = true; + } + } + } + if ( !$foundit ) { + if ( $marker != 'none' ) + fwrite( $f, "\n\n# BEGIN {$marker}\n" ); + foreach ( $insertion as $insertline ) + fwrite( $f, "{$insertline}\n" ); + if ( $marker != 'none' ) + fwrite( $f, "# END {$marker}\n\n" ); + } + fclose( $f ); + return true; + } else { + return false; + } } /** @@ -207,16 +207,16 @@ function yourls_create_sql_tables() { return $pre; } - $ydb = yourls_get_db(); + $ydb = yourls_get_db(); - $error_msg = array(); - $success_msg = array(); + $error_msg = array(); + $success_msg = array(); - // Create Table Query - $create_tables = array(); - $create_tables[YOURLS_DB_TABLE_URL] = + // Create Table Query + $create_tables = array(); + $create_tables[YOURLS_DB_TABLE_URL] = 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_URL.'` ('. - '`keyword` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT "",'. + '`keyword` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT \'\','. '`url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,'. '`title` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,'. '`timestamp` timestamp NOT NULL DEFAULT current_timestamp(),'. @@ -227,61 +227,61 @@ function yourls_create_sql_tables() { 'KEY `timestamp` (`timestamp`)'. ') DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;'; - $create_tables[YOURLS_DB_TABLE_OPTIONS] = - 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. - '`option_id` bigint(20) unsigned NOT NULL auto_increment,'. - '`option_name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL default "",'. - '`option_value` longtext COLLATE utf8mb4_unicode_ci NOT NULL,'. - 'PRIMARY KEY (`option_id`,`option_name`),'. - 'KEY `option_name` (`option_name`)'. - ') AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; - - $create_tables[YOURLS_DB_TABLE_LOG] = - 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. - '`click_id` int(11) NOT NULL auto_increment,'. - '`click_time` datetime NOT NULL,'. - '`shorturl` varchar(100) BINARY NOT NULL,'. - '`referrer` varchar(200) NOT NULL,'. - '`user_agent` varchar(255) NOT NULL,'. - '`ip_address` varchar(41) NOT NULL,'. - '`country_code` char(2) NOT NULL,'. - 'PRIMARY KEY (`click_id`),'. - 'KEY `shorturl` (`shorturl`)'. - ') AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; - - - $create_table_count = 0; + $create_tables[YOURLS_DB_TABLE_OPTIONS] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. + '`option_id` bigint(20) unsigned NOT NULL auto_increment,'. + '`option_name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL default \'\','. + '`option_value` longtext COLLATE utf8mb4_unicode_ci NOT NULL,'. + 'PRIMARY KEY (`option_id`,`option_name`),'. + 'KEY `option_name` (`option_name`)'. + ') AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; + + $create_tables[YOURLS_DB_TABLE_LOG] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. + '`click_id` int(11) NOT NULL auto_increment,'. + '`click_time` datetime NOT NULL,'. + '`shorturl` varchar(100) BINARY NOT NULL,'. + '`referrer` varchar(200) NOT NULL,'. + '`user_agent` varchar(255) NOT NULL,'. + '`ip_address` varchar(41) NOT NULL,'. + '`country_code` char(2) NOT NULL,'. + 'PRIMARY KEY (`click_id`),'. + 'KEY `shorturl` (`shorturl`)'. + ') AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; + + + $create_table_count = 0; yourls_debug_mode(true); - // Create tables - foreach ( $create_tables as $table_name => $table_query ) { - $ydb->perform( $table_query ); - $create_success = $ydb->fetchAffected( "SHOW TABLES LIKE '$table_name'" ); - if( $create_success ) { - $create_table_count++; - $success_msg[] = yourls_s( "Table '%s' created.", $table_name ); - } else { - $error_msg[] = yourls_s( "Error creating table '%s'.", $table_name ); - } - } - - // Initializes the option table - if( !yourls_initialize_options() ) - $error_msg[] = yourls__( 'Could not initialize options' ); - - // Insert sample links - if( !yourls_insert_sample_links() ) - $error_msg[] = yourls__( 'Could not insert sample short URLs' ); - - // Check results of operations - if ( sizeof( $create_tables ) == $create_table_count ) { - $success_msg[] = yourls__( 'YOURLS tables successfully created.' ); - } else { - $error_msg[] = yourls__( 'Error creating YOURLS tables.' ); - } - - return array( 'success' => $success_msg, 'error' => $error_msg ); + // Create tables + foreach ( $create_tables as $table_name => $table_query ) { + $ydb->perform( $table_query ); + $create_success = $ydb->fetchAffected( "SHOW TABLES LIKE '$table_name'" ); + if( $create_success ) { + $create_table_count++; + $success_msg[] = yourls_s( "Table '%s' created.", $table_name ); + } else { + $error_msg[] = yourls_s( "Error creating table '%s'.", $table_name ); + } + } + + // Initializes the option table + if( !yourls_initialize_options() ) + $error_msg[] = yourls__( 'Could not initialize options' ); + + // Insert sample links + if( !yourls_insert_sample_links() ) + $error_msg[] = yourls__( 'Could not insert sample short URLs' ); + + // Check results of operations + if ( sizeof( $create_tables ) == $create_table_count ) { + $success_msg[] = yourls__( 'YOURLS tables successfully created.' ); + } else { + $error_msg[] = yourls__( 'Error creating YOURLS tables.' ); + } + + return array( 'success' => $success_msg, 'error' => $error_msg ); } /** @@ -295,12 +295,12 @@ function yourls_create_sql_tables() { * @return bool */ function yourls_initialize_options() { - return ( bool ) ( - yourls_update_option( 'version', YOURLS_VERSION ) - & yourls_update_option( 'db_version', YOURLS_DB_VERSION ) - & yourls_update_option( 'next_id', 1 ) + return ( bool ) ( + yourls_update_option( 'version', YOURLS_VERSION ) + & yourls_update_option( 'db_version', YOURLS_DB_VERSION ) + & yourls_update_option( 'next_id', 1 ) & yourls_update_option( 'active_plugins', array() ) - ); + ); } /** @@ -310,14 +310,14 @@ function yourls_initialize_options() { * @return bool */ function yourls_insert_sample_links() { - $link1 = yourls_add_new_link( 'https://blog.yourls.org/', 'yourlsblog', 'YOURLS\' Blog' ); - $link2 = yourls_add_new_link( 'https://yourls.org/', 'yourls', 'YOURLS: Your Own URL Shortener' ); - $link3 = yourls_add_new_link( 'https://ozh.org/', 'ozh', 'ozh.org' ); - return ( bool ) ( - $link1['status'] == 'success' - & $link2['status'] == 'success' - & $link3['status'] == 'success' - ); + $link1 = yourls_add_new_link( 'https://blog.yourls.org/', 'yourlsblog', 'YOURLS\' Blog' ); + $link2 = yourls_add_new_link( 'https://yourls.org/', 'yourls', 'YOURLS: Your Own URL Shortener' ); + $link3 = yourls_add_new_link( 'https://ozh.org/', 'ozh', 'ozh.org' ); + return ( bool ) ( + $link1['status'] == 'success' + & $link2['status'] == 'success' + & $link3['status'] == 'success' + ); } @@ -329,23 +329,23 @@ function yourls_insert_sample_links() { */ function yourls_maintenance_mode( $maintenance = true ) { - $file = YOURLS_ABSPATH . '/.maintenance' ; + $file = YOURLS_ABSPATH . '/.maintenance' ; - // Turn maintenance mode on : create .maintenance file - if ( (bool)$maintenance ) { - if ( ! ( $fp = @fopen( $file, 'w' ) ) ) - return false; + // Turn maintenance mode on : create .maintenance file + if ( (bool)$maintenance ) { + if ( ! ( $fp = @fopen( $file, 'w' ) ) ) + return false; - $maintenance_string = ''; - @fwrite( $fp, $maintenance_string ); - @fclose( $fp ); - @chmod( $file, 0644 ); // Read and write for owner, read for everybody else + $maintenance_string = ''; + @fwrite( $fp, $maintenance_string ); + @fclose( $fp ); + @chmod( $file, 0644 ); // Read and write for owner, read for everybody else - // Not sure why the fwrite would fail if the fopen worked... Just in case - return( is_readable( $file ) ); + // Not sure why the fwrite would fail if the fopen worked... Just in case + return( is_readable( $file ) ); - // Turn maintenance mode off : delete the .maintenance file - } else { - return @unlink($file); - } + // Turn maintenance mode off : delete the .maintenance file + } else { + return @unlink($file); + } } diff --git a/includes/functions-kses.php b/includes/functions-kses.php index 08a20a2e0..7a81ffdb8 100644 --- a/includes/functions-kses.php +++ b/includes/functions-kses.php @@ -52,37 +52,37 @@ * @return void */ function yourls_kses_init() { - global $yourls_allowedentitynames, $yourls_allowedprotocols; - - if( ! $yourls_allowedentitynames ) { - $yourls_allowedentitynames = yourls_apply_filter( 'kses_allowed_entities', yourls_kses_allowed_entities() ); - } - - if( ! $yourls_allowedprotocols ) { - $yourls_allowedprotocols = yourls_apply_filter( 'kses_allowed_protocols', yourls_kses_allowed_protocols() ); - } - - /** See NOTE ABOUT GLOBALS ** - - if( ! $yourls_allowedtags_all ) { - $yourls_allowedtags_all = yourls_kses_allowed_tags_all(); - $yourls_allowedtags_all = array_map( '_yourls_add_global_attributes', $yourls_allowedtags_all ); - $yourls_allowedtags_all = yourls_apply_filter( 'kses_allowed_tags_all', $yourls_allowedtags_all ); - } else { - // User defined: let's sanitize - $yourls_allowedtags_all = yourls_kses_array_lc( $yourls_allowedtags_all ); - } - - if( ! $yourls_allowedtags ) { - $yourls_allowedtags = yourls_kses_allowed_tags(); - $yourls_allowedtags = array_map( '_yourls_add_global_attributes', $yourls_allowedtags ); - $yourls_allowedtags = yourls_apply_filter( 'kses_allowed_tags', $yourls_allowedtags ); - } else { - // User defined: let's sanitize - $yourls_allowedtags = yourls_kses_array_lc( $yourls_allowedtags ); - } - - /**/ + global $yourls_allowedentitynames, $yourls_allowedprotocols; + + if( ! $yourls_allowedentitynames ) { + $yourls_allowedentitynames = yourls_apply_filter( 'kses_allowed_entities', yourls_kses_allowed_entities() ); + } + + if( ! $yourls_allowedprotocols ) { + $yourls_allowedprotocols = yourls_apply_filter( 'kses_allowed_protocols', yourls_kses_allowed_protocols() ); + } + + /** See NOTE ABOUT GLOBALS ** + + if( ! $yourls_allowedtags_all ) { + $yourls_allowedtags_all = yourls_kses_allowed_tags_all(); + $yourls_allowedtags_all = array_map( '_yourls_add_global_attributes', $yourls_allowedtags_all ); + $yourls_allowedtags_all = yourls_apply_filter( 'kses_allowed_tags_all', $yourls_allowedtags_all ); + } else { + // User defined: let's sanitize + $yourls_allowedtags_all = yourls_kses_array_lc( $yourls_allowedtags_all ); + } + + if( ! $yourls_allowedtags ) { + $yourls_allowedtags = yourls_kses_allowed_tags(); + $yourls_allowedtags = array_map( '_yourls_add_global_attributes', $yourls_allowedtags ); + $yourls_allowedtags = yourls_apply_filter( 'kses_allowed_tags', $yourls_allowedtags ); + } else { + // User defined: let's sanitize + $yourls_allowedtags = yourls_kses_array_lc( $yourls_allowedtags ); + } + + /**/ } /** @@ -96,320 +96,320 @@ function yourls_kses_init() { * @return array All tags */ function yourls_kses_allowed_tags_all() { - return array( - 'address' => array(), - 'a' => array( - 'href' => true, - 'rel' => true, - 'rev' => true, - 'name' => true, - 'target' => true, - ), - 'abbr' => array(), - 'acronym' => array(), - 'area' => array( - 'alt' => true, - 'coords' => true, - 'href' => true, - 'nohref' => true, - 'shape' => true, - 'target' => true, - ), - 'article' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'aside' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'b' => array(), - 'big' => array(), - 'blockquote' => array( - 'cite' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'br' => array(), - 'button' => array( - 'disabled' => true, - 'name' => true, - 'type' => true, - 'value' => true, - ), - 'caption' => array( - 'align' => true, - ), - 'cite' => array( - 'dir' => true, - 'lang' => true, - ), - 'code' => array(), - 'col' => array( - 'align' => true, - 'char' => true, - 'charoff' => true, - 'span' => true, - 'dir' => true, - 'valign' => true, - 'width' => true, - ), - 'del' => array( - 'datetime' => true, - ), - 'dd' => array(), - 'details' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'open' => true, - 'xml:lang' => true, - ), - 'div' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'dl' => array(), - 'dt' => array(), - 'em' => array(), - 'fieldset' => array(), - 'figure' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'figcaption' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'font' => array( - 'color' => true, - 'face' => true, - 'size' => true, - ), - 'footer' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'form' => array( - 'action' => true, - 'accept' => true, - 'accept-charset' => true, - 'enctype' => true, - 'method' => true, - 'name' => true, - 'target' => true, - ), - 'h1' => array( - 'align' => true, - ), - 'h2' => array( - 'align' => true, - ), - 'h3' => array( - 'align' => true, - ), - 'h4' => array( - 'align' => true, - ), - 'h5' => array( - 'align' => true, - ), - 'h6' => array( - 'align' => true, - ), - 'header' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'hgroup' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'hr' => array( - 'align' => true, - 'noshade' => true, - 'size' => true, - 'width' => true, - ), - 'i' => array(), - 'img' => array( - 'alt' => true, - 'align' => true, - 'border' => true, - 'height' => true, - 'hspace' => true, - 'longdesc' => true, - 'vspace' => true, - 'src' => true, - 'usemap' => true, - 'width' => true, - ), - 'ins' => array( - 'datetime' => true, - 'cite' => true, - ), - 'kbd' => array(), - 'label' => array( - 'for' => true, - ), - 'legend' => array( - 'align' => true, - ), - 'li' => array( - 'align' => true, - ), - 'map' => array( - 'name' => true, - ), - 'menu' => array( - 'type' => true, - ), - 'nav' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'p' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'pre' => array( - 'width' => true, - ), - 'q' => array( - 'cite' => true, - ), - 's' => array(), - 'span' => array( - 'dir' => true, - 'align' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'section' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'small' => array(), - 'strike' => array(), - 'strong' => array(), - 'sub' => array(), - 'summary' => array( - 'align' => true, - 'dir' => true, - 'lang' => true, - 'xml:lang' => true, - ), - 'sup' => array(), - 'table' => array( - 'align' => true, - 'bgcolor' => true, - 'border' => true, - 'cellpadding' => true, - 'cellspacing' => true, - 'dir' => true, - 'rules' => true, - 'summary' => true, - 'width' => true, - ), - 'tbody' => array( - 'align' => true, - 'char' => true, - 'charoff' => true, - 'valign' => true, - ), - 'td' => array( - 'abbr' => true, - 'align' => true, - 'axis' => true, - 'bgcolor' => true, - 'char' => true, - 'charoff' => true, - 'colspan' => true, - 'dir' => true, - 'headers' => true, - 'height' => true, - 'nowrap' => true, - 'rowspan' => true, - 'scope' => true, - 'valign' => true, - 'width' => true, - ), - 'textarea' => array( - 'cols' => true, - 'rows' => true, - 'disabled' => true, - 'name' => true, - 'readonly' => true, - ), - 'tfoot' => array( - 'align' => true, - 'char' => true, - 'charoff' => true, - 'valign' => true, - ), - 'th' => array( - 'abbr' => true, - 'align' => true, - 'axis' => true, - 'bgcolor' => true, - 'char' => true, - 'charoff' => true, - 'colspan' => true, - 'headers' => true, - 'height' => true, - 'nowrap' => true, - 'rowspan' => true, - 'scope' => true, - 'valign' => true, - 'width' => true, - ), - 'thead' => array( - 'align' => true, - 'char' => true, - 'charoff' => true, - 'valign' => true, - ), - 'title' => array(), - 'tr' => array( - 'align' => true, - 'bgcolor' => true, - 'char' => true, - 'charoff' => true, - 'valign' => true, - ), - 'tt' => array(), - 'u' => array(), - 'ul' => array( - 'type' => true, - ), - 'ol' => array( - 'start' => true, - 'type' => true, - ), - 'var' => array(), - ); + return array( + 'address' => array(), + 'a' => array( + 'href' => true, + 'rel' => true, + 'rev' => true, + 'name' => true, + 'target' => true, + ), + 'abbr' => array(), + 'acronym' => array(), + 'area' => array( + 'alt' => true, + 'coords' => true, + 'href' => true, + 'nohref' => true, + 'shape' => true, + 'target' => true, + ), + 'article' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'aside' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'b' => array(), + 'big' => array(), + 'blockquote' => array( + 'cite' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'br' => array(), + 'button' => array( + 'disabled' => true, + 'name' => true, + 'type' => true, + 'value' => true, + ), + 'caption' => array( + 'align' => true, + ), + 'cite' => array( + 'dir' => true, + 'lang' => true, + ), + 'code' => array(), + 'col' => array( + 'align' => true, + 'char' => true, + 'charoff' => true, + 'span' => true, + 'dir' => true, + 'valign' => true, + 'width' => true, + ), + 'del' => array( + 'datetime' => true, + ), + 'dd' => array(), + 'details' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'open' => true, + 'xml:lang' => true, + ), + 'div' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'dl' => array(), + 'dt' => array(), + 'em' => array(), + 'fieldset' => array(), + 'figure' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'figcaption' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'font' => array( + 'color' => true, + 'face' => true, + 'size' => true, + ), + 'footer' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'form' => array( + 'action' => true, + 'accept' => true, + 'accept-charset' => true, + 'enctype' => true, + 'method' => true, + 'name' => true, + 'target' => true, + ), + 'h1' => array( + 'align' => true, + ), + 'h2' => array( + 'align' => true, + ), + 'h3' => array( + 'align' => true, + ), + 'h4' => array( + 'align' => true, + ), + 'h5' => array( + 'align' => true, + ), + 'h6' => array( + 'align' => true, + ), + 'header' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'hgroup' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'hr' => array( + 'align' => true, + 'noshade' => true, + 'size' => true, + 'width' => true, + ), + 'i' => array(), + 'img' => array( + 'alt' => true, + 'align' => true, + 'border' => true, + 'height' => true, + 'hspace' => true, + 'longdesc' => true, + 'vspace' => true, + 'src' => true, + 'usemap' => true, + 'width' => true, + ), + 'ins' => array( + 'datetime' => true, + 'cite' => true, + ), + 'kbd' => array(), + 'label' => array( + 'for' => true, + ), + 'legend' => array( + 'align' => true, + ), + 'li' => array( + 'align' => true, + ), + 'map' => array( + 'name' => true, + ), + 'menu' => array( + 'type' => true, + ), + 'nav' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'p' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'pre' => array( + 'width' => true, + ), + 'q' => array( + 'cite' => true, + ), + 's' => array(), + 'span' => array( + 'dir' => true, + 'align' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'section' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'small' => array(), + 'strike' => array(), + 'strong' => array(), + 'sub' => array(), + 'summary' => array( + 'align' => true, + 'dir' => true, + 'lang' => true, + 'xml:lang' => true, + ), + 'sup' => array(), + 'table' => array( + 'align' => true, + 'bgcolor' => true, + 'border' => true, + 'cellpadding' => true, + 'cellspacing' => true, + 'dir' => true, + 'rules' => true, + 'summary' => true, + 'width' => true, + ), + 'tbody' => array( + 'align' => true, + 'char' => true, + 'charoff' => true, + 'valign' => true, + ), + 'td' => array( + 'abbr' => true, + 'align' => true, + 'axis' => true, + 'bgcolor' => true, + 'char' => true, + 'charoff' => true, + 'colspan' => true, + 'dir' => true, + 'headers' => true, + 'height' => true, + 'nowrap' => true, + 'rowspan' => true, + 'scope' => true, + 'valign' => true, + 'width' => true, + ), + 'textarea' => array( + 'cols' => true, + 'rows' => true, + 'disabled' => true, + 'name' => true, + 'readonly' => true, + ), + 'tfoot' => array( + 'align' => true, + 'char' => true, + 'charoff' => true, + 'valign' => true, + ), + 'th' => array( + 'abbr' => true, + 'align' => true, + 'axis' => true, + 'bgcolor' => true, + 'char' => true, + 'charoff' => true, + 'colspan' => true, + 'headers' => true, + 'height' => true, + 'nowrap' => true, + 'rowspan' => true, + 'scope' => true, + 'valign' => true, + 'width' => true, + ), + 'thead' => array( + 'align' => true, + 'char' => true, + 'charoff' => true, + 'valign' => true, + ), + 'title' => array(), + 'tr' => array( + 'align' => true, + 'bgcolor' => true, + 'char' => true, + 'charoff' => true, + 'valign' => true, + ), + 'tt' => array(), + 'u' => array(), + 'ul' => array( + 'type' => true, + ), + 'ol' => array( + 'start' => true, + 'type' => true, + ), + 'var' => array(), + ); } /** @@ -422,34 +422,34 @@ function yourls_kses_allowed_tags_all() { * @return array Allowed tags */ function yourls_kses_allowed_tags() { - return array( - 'a' => array( - 'href' => true, - 'title' => true, - ), - 'abbr' => array( - 'title' => true, - ), - 'acronym' => array( - 'title' => true, - ), - 'b' => array(), - 'blockquote' => array( - 'cite' => true, - ), - 'cite' => array(), - 'code' => array(), - 'del' => array( - 'datetime' => true, - ), - 'em' => array(), - 'i' => array(), - 'q' => array( - 'cite' => true, - ), - 'strike' => array(), - 'strong' => array(), - ); + return array( + 'a' => array( + 'href' => true, + 'title' => true, + ), + 'abbr' => array( + 'title' => true, + ), + 'acronym' => array( + 'title' => true, + ), + 'b' => array(), + 'blockquote' => array( + 'cite' => true, + ), + 'cite' => array(), + 'code' => array(), + 'del' => array( + 'datetime' => true, + ), + 'em' => array(), + 'i' => array(), + 'q' => array( + 'cite' => true, + ), + 'strike' => array(), + 'strong' => array(), + ); } /** @@ -460,49 +460,49 @@ function yourls_kses_allowed_tags() { * @return array Allowed entities */ function yourls_kses_allowed_entities() { - return array( - 'nbsp', 'iexcl', 'cent', 'pound', 'curren', 'yen', - 'brvbar', 'sect', 'uml', 'copy', 'ordf', 'laquo', - 'not', 'shy', 'reg', 'macr', 'deg', 'plusmn', - 'acute', 'micro', 'para', 'middot', 'cedil', 'ordm', - 'raquo', 'iquest', 'Agrave', 'Aacute', 'Acirc', 'Atilde', - 'Auml', 'Aring', 'AElig', 'Ccedil', 'Egrave', 'Eacute', - 'Ecirc', 'Euml', 'Igrave', 'Iacute', 'Icirc', 'Iuml', - 'ETH', 'Ntilde', 'Ograve', 'Oacute', 'Ocirc', 'Otilde', - 'Ouml', 'times', 'Oslash', 'Ugrave', 'Uacute', 'Ucirc', - 'Uuml', 'Yacute', 'THORN', 'szlig', 'agrave', 'aacute', - 'acirc', 'atilde', 'auml', 'aring', 'aelig', 'ccedil', - 'egrave', 'eacute', 'ecirc', 'euml', 'igrave', 'iacute', - 'icirc', 'iuml', 'eth', 'ntilde', 'ograve', 'oacute', - 'ocirc', 'otilde', 'ouml', 'divide', 'oslash', 'ugrave', - 'uacute', 'ucirc', 'uuml', 'yacute', 'thorn', 'yuml', - 'quot', 'amp', 'lt', 'gt', 'apos', 'OElig', - 'oelig', 'Scaron', 'scaron', 'Yuml', 'circ', 'tilde', - 'ensp', 'emsp', 'thinsp', 'zwnj', 'zwj', 'lrm', - 'rlm', 'ndash', 'mdash', 'lsquo', 'rsquo', 'sbquo', - 'ldquo', 'rdquo', 'bdquo', 'dagger', 'Dagger', 'permil', - 'lsaquo', 'rsaquo', 'euro', 'fnof', 'Alpha', 'Beta', - 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', - 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', - 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon', - 'Phi', 'Chi', 'Psi', 'Omega', 'alpha', 'beta', - 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', - 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', - 'omicron', 'pi', 'rho', 'sigmaf', 'sigma', 'tau', - 'upsilon', 'phi', 'chi', 'psi', 'omega', 'thetasym', - 'upsih', 'piv', 'bull', 'hellip', 'prime', 'Prime', - 'oline', 'frasl', 'weierp', 'image', 'real', 'trade', - 'alefsym', 'larr', 'uarr', 'rarr', 'darr', 'harr', - 'crarr', 'lArr', 'uArr', 'rArr', 'dArr', 'hArr', - 'forall', 'part', 'exist', 'empty', 'nabla', 'isin', - 'notin', 'ni', 'prod', 'sum', 'minus', 'lowast', - 'radic', 'prop', 'infin', 'ang', 'and', 'or', - 'cap', 'cup', 'int', 'sim', 'cong', 'asymp', - 'ne', 'equiv', 'le', 'ge', 'sub', 'sup', - 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp', - 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang', - 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams', - ); + return array( + 'nbsp', 'iexcl', 'cent', 'pound', 'curren', 'yen', + 'brvbar', 'sect', 'uml', 'copy', 'ordf', 'laquo', + 'not', 'shy', 'reg', 'macr', 'deg', 'plusmn', + 'acute', 'micro', 'para', 'middot', 'cedil', 'ordm', + 'raquo', 'iquest', 'Agrave', 'Aacute', 'Acirc', 'Atilde', + 'Auml', 'Aring', 'AElig', 'Ccedil', 'Egrave', 'Eacute', + 'Ecirc', 'Euml', 'Igrave', 'Iacute', 'Icirc', 'Iuml', + 'ETH', 'Ntilde', 'Ograve', 'Oacute', 'Ocirc', 'Otilde', + 'Ouml', 'times', 'Oslash', 'Ugrave', 'Uacute', 'Ucirc', + 'Uuml', 'Yacute', 'THORN', 'szlig', 'agrave', 'aacute', + 'acirc', 'atilde', 'auml', 'aring', 'aelig', 'ccedil', + 'egrave', 'eacute', 'ecirc', 'euml', 'igrave', 'iacute', + 'icirc', 'iuml', 'eth', 'ntilde', 'ograve', 'oacute', + 'ocirc', 'otilde', 'ouml', 'divide', 'oslash', 'ugrave', + 'uacute', 'ucirc', 'uuml', 'yacute', 'thorn', 'yuml', + 'quot', 'amp', 'lt', 'gt', 'apos', 'OElig', + 'oelig', 'Scaron', 'scaron', 'Yuml', 'circ', 'tilde', + 'ensp', 'emsp', 'thinsp', 'zwnj', 'zwj', 'lrm', + 'rlm', 'ndash', 'mdash', 'lsquo', 'rsquo', 'sbquo', + 'ldquo', 'rdquo', 'bdquo', 'dagger', 'Dagger', 'permil', + 'lsaquo', 'rsaquo', 'euro', 'fnof', 'Alpha', 'Beta', + 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', + 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', + 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon', + 'Phi', 'Chi', 'Psi', 'Omega', 'alpha', 'beta', + 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', + 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', + 'omicron', 'pi', 'rho', 'sigmaf', 'sigma', 'tau', + 'upsilon', 'phi', 'chi', 'psi', 'omega', 'thetasym', + 'upsih', 'piv', 'bull', 'hellip', 'prime', 'Prime', + 'oline', 'frasl', 'weierp', 'image', 'real', 'trade', + 'alefsym', 'larr', 'uarr', 'rarr', 'darr', 'harr', + 'crarr', 'lArr', 'uArr', 'rArr', 'dArr', 'hArr', + 'forall', 'part', 'exist', 'empty', 'nabla', 'isin', + 'notin', 'ni', 'prod', 'sum', 'minus', 'lowast', + 'radic', 'prop', 'infin', 'ang', 'and', 'or', + 'cap', 'cup', 'int', 'sim', 'cong', 'asymp', + 'ne', 'equiv', 'le', 'ge', 'sub', 'sup', + 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp', + 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang', + 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams', + ); } /** @@ -513,51 +513,51 @@ function yourls_kses_allowed_entities() { * @return array Allowed protocols */ function yourls_kses_allowed_protocols() { - // More or less common stuff in links. From http://en.wikipedia.org/wiki/URI_scheme - return array( - // Common - 'http://', 'https://', 'ftp://', - 'file://', 'smb://', - 'sftp://', - 'feed:', 'feed://', - 'mailto:', - 'news:', 'nntp://', - - // Old school bearded geek - 'gopher://', 'telnet://', 'finger://', - 'nntp://', 'worldwind://', - - // Dev - 'ssh://', 'svn://', 'svn+ssh://', 'git://', 'cvs://', - 'apt:', - 'market://', // Google Play - 'view-source:', - - // P2P - 'ed2k://', 'magnet:', 'udp://', - - // Streaming stuff - 'mms://', 'lastfm://', 'spotify:', 'rtsp://', - - // Text & voice - 'aim:', 'facetime://', 'gtalk:', 'xmpp:', - 'irc://', 'ircs://', 'mumble://', - 'callto:', 'skype:', 'sip:', - 'teamspeak://', 'tel:', 'ventrilo://', 'xfire:', - 'ymsgr:', 'tg://', 'whatsapp://', - - // Misc - 'steam:', 'steam://', - 'bitcoin:', - 'ldap://', 'ldaps://', - - // Purposedly removed for security - /* - 'about:', 'chrome://', 'chrome-extension://', - 'javascript:', - 'data:', - */ - ); + // More or less common stuff in links. From http://en.wikipedia.org/wiki/URI_scheme + return array( + // Common + 'http://', 'https://', 'ftp://', + 'file://', 'smb://', + 'sftp://', + 'feed:', 'feed://', + 'mailto:', + 'news:', 'nntp://', + + // Old school bearded geek + 'gopher://', 'telnet://', 'finger://', + 'nntp://', 'worldwind://', + + // Dev + 'ssh://', 'svn://', 'svn+ssh://', 'git://', 'cvs://', + 'apt:', + 'market://', // Google Play + 'view-source:', + + // P2P + 'ed2k://', 'magnet:', 'udp://', + + // Streaming stuff + 'mms://', 'lastfm://', 'spotify:', 'rtsp://', + + // Text & voice + 'aim:', 'facetime://', 'gtalk:', 'xmpp:', + 'irc://', 'ircs://', 'mumble://', + 'callto:', 'skype:', 'sip:', + 'teamspeak://', 'tel:', 'ventrilo://', 'xfire:', + 'ymsgr:', 'tg://', 'whatsapp://', + + // Misc + 'steam:', 'steam://', + 'bitcoin:', + 'ldap://', 'ldaps://', + + // Purposedly removed for security + /* + 'about:', 'chrome://', 'chrome-extension://', + 'javascript:', + 'data:', + */ + ); } @@ -573,17 +573,17 @@ function yourls_kses_allowed_protocols() { * @return string Content with normalized entities */ function yourls_kses_normalize_entities($string) { - # Disarm all entities by converting & to & + # Disarm all entities by converting & to & - $string = str_replace('&', '&', $string); + $string = str_replace('&', '&', $string); - # Change back the allowed entities in our entity whitelist + # Change back the allowed entities in our entity whitelist - $string = preg_replace_callback('/&([A-Za-z]{2,8});/', 'yourls_kses_named_entities', $string); - $string = preg_replace_callback('/&#(0*[0-9]{1,7});/', 'yourls_kses_normalize_entities2', $string); - $string = preg_replace_callback('/&#[Xx](0*[0-9A-Fa-f]{1,6});/', 'yourls_kses_normalize_entities3', $string); + $string = preg_replace_callback('/&([A-Za-z]{2,8});/', 'yourls_kses_named_entities', $string); + $string = preg_replace_callback('/&#(0*[0-9]{1,7});/', 'yourls_kses_normalize_entities2', $string); + $string = preg_replace_callback('/&#[Xx](0*[0-9A-Fa-f]{1,6});/', 'yourls_kses_normalize_entities3', $string); - return $string; + return $string; } /** @@ -598,13 +598,13 @@ function yourls_kses_normalize_entities($string) { * @return string Correctly encoded entity */ function yourls_kses_named_entities($matches) { - global $yourls_allowedentitynames; + global $yourls_allowedentitynames; - if ( empty($matches[1]) ) - return ''; + if ( empty($matches[1]) ) + return ''; - $i = $matches[1]; - return ( ( ! in_array($i, $yourls_allowedentitynames) ) ? "&$i;" : "&$i;" ); + $i = $matches[1]; + return ( ( ! in_array($i, $yourls_allowedentitynames) ) ? "&$i;" : "&$i;" ); } /** @@ -620,18 +620,18 @@ function yourls_kses_named_entities($matches) { * @return string Correctly encoded entity */ function yourls_kses_normalize_entities2($matches) { - if ( empty($matches[1]) ) - return ''; - - $i = $matches[1]; - if (yourls_valid_unicode($i)) { - $i = str_pad(ltrim($i,'0'), 3, '0', STR_PAD_LEFT); - $i = "&#$i;"; - } else { - $i = "&#$i;"; - } - - return $i; + if ( empty($matches[1]) ) + return ''; + + $i = $matches[1]; + if (yourls_valid_unicode($i)) { + $i = str_pad(ltrim($i,'0'), 3, '0', STR_PAD_LEFT); + $i = "&#$i;"; + } else { + $i = "&#$i;"; + } + + return $i; } /** @@ -647,11 +647,11 @@ function yourls_kses_normalize_entities2($matches) { * @return string Correctly encoded entity */ function yourls_kses_normalize_entities3($matches) { - if ( empty($matches[1]) ) - return ''; + if ( empty($matches[1]) ) + return ''; - $hexchars = $matches[1]; - return ( ( ! yourls_valid_unicode(hexdec($hexchars)) ) ? "&#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';' ); + $hexchars = $matches[1]; + return ( ( ! yourls_valid_unicode(hexdec($hexchars)) ) ? "&#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';' ); } /** @@ -664,20 +664,20 @@ function yourls_kses_normalize_entities3($matches) { * @return array The array of attributes with global attributes added. */ function _yourls_add_global_attributes( $value ) { - $global_attributes = array( - 'class' => true, - 'id' => true, - 'style' => true, - 'title' => true, - ); + $global_attributes = array( + 'class' => true, + 'id' => true, + 'style' => true, + 'title' => true, + ); - if ( true === $value ) - $value = array(); + if ( true === $value ) + $value = array(); - if ( is_array( $value ) ) - return array_merge( $value, $global_attributes ); + if ( is_array( $value ) ) + return array_merge( $value, $global_attributes ); - return $value; + return $value; } /** @@ -689,10 +689,10 @@ function _yourls_add_global_attributes( $value ) { * @return bool True if the value was a valid Unicode number */ function yourls_valid_unicode($i) { - return ( $i == 0x9 || $i == 0xa || $i == 0xd || - ($i >= 0x20 && $i <= 0xd7ff) || - ($i >= 0xe000 && $i <= 0xfffd) || - ($i >= 0x10000 && $i <= 0x10ffff) ); + return ( $i == 0x9 || $i == 0xa || $i == 0xd || + ($i >= 0x20 && $i <= 0xd7ff) || + ($i >= 0xe000 && $i <= 0xfffd) || + ($i >= 0x10000 && $i <= 0x10ffff) ); } /** @@ -704,19 +704,19 @@ function yourls_valid_unicode($i) { * @return array Fixed array with all lowercase keys */ function yourls_kses_array_lc($inarray) { - $outarray = array (); + $outarray = array (); - foreach ( (array) $inarray as $inkey => $inval) { - $outkey = strtolower($inkey); - $outarray[$outkey] = array (); + foreach ( (array) $inarray as $inkey => $inval) { + $outkey = strtolower($inkey); + $outarray[$outkey] = array (); - foreach ( (array) $inval as $inkey2 => $inval2) { - $outkey2 = strtolower($inkey2); - $outarray[$outkey][$outkey2] = $inval2; - } # foreach $inval - } # foreach $inarray + foreach ( (array) $inval as $inkey2 => $inval2) { + $outkey2 = strtolower($inkey2); + $outarray[$outkey][$outkey2] = $inval2; + } # foreach $inval + } # foreach $inarray - return $outarray; + return $outarray; } /** @@ -732,10 +732,10 @@ function yourls_kses_array_lc($inarray) { * @return string Content after decoded entities */ function yourls_kses_decode_entities($string) { - $string = preg_replace_callback('/&#([0-9]+);/', '_yourls_kses_decode_entities_chr', $string); - $string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', '_yourls_kses_decode_entities_chr_hexdec', $string); + $string = preg_replace_callback('/&#([0-9]+);/', '_yourls_kses_decode_entities_chr', $string); + $string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', '_yourls_kses_decode_entities_chr_hexdec', $string); - return $string; + return $string; } /** @@ -747,7 +747,7 @@ function yourls_kses_decode_entities($string) { * @return string */ function _yourls_kses_decode_entities_chr( $match ) { - return chr( $match[1] ); + return chr( $match[1] ); } /** @@ -759,7 +759,7 @@ function _yourls_kses_decode_entities_chr( $match ) { * @return string */ function _yourls_kses_decode_entities_chr_hexdec( $match ) { - return chr( hexdec( $match[1] ) ); + return chr( hexdec( $match[1] ) ); } /** @@ -771,8 +771,8 @@ function _yourls_kses_decode_entities_chr_hexdec( $match ) { * @return string */ function yourls_kses_no_null($string) { - $string = preg_replace( '/\0+/', '', $string ); - $string = preg_replace( '/(\\\\0)+/', '', $string ); + $string = preg_replace( '/\0+/', '', $string ); + $string = preg_replace( '/(\\\\0)+/', '', $string ); - return $string; + return $string; } diff --git a/includes/functions-l10n.php b/includes/functions-l10n.php index d72c7865c..31c5dd4b5 100644 --- a/includes/functions-l10n.php +++ b/includes/functions-l10n.php @@ -35,18 +35,18 @@ * @return string The locale of the YOURLS instance */ function yourls_get_locale() { - global $yourls_locale; + global $yourls_locale; - if ( !isset( $yourls_locale ) ) { - // YOURLS_LANG is defined in config. - if ( defined( 'YOURLS_LANG' ) ) - $yourls_locale = YOURLS_LANG; - } + if ( !isset( $yourls_locale ) ) { + // YOURLS_LANG is defined in config. + if ( defined( 'YOURLS_LANG' ) ) + $yourls_locale = YOURLS_LANG; + } if ( !$yourls_locale ) $yourls_locale = ''; - return yourls_apply_filter( 'get_locale', $yourls_locale ); + return yourls_apply_filter( 'get_locale', $yourls_locale ); } /** @@ -56,15 +56,15 @@ function yourls_get_locale() { * @see yourls__() Don't use yourls_translate() directly, use yourls__() * @since 1.6 * @uses yourls_apply_filter() Calls 'translate' on domain translated text - * with the untranslated text as second parameter. + * with the untranslated text as second parameter. * * @param string $text Text to translate. * @param string $domain Domain to retrieve the translated text. * @return string Translated text */ function yourls_translate( $text, $domain = 'default' ) { - $translations = yourls_get_translations_for_domain( $domain ); - return yourls_apply_filter( 'translate', $translations->translate( $text ), $text, $domain ); + $translations = yourls_get_translations_for_domain( $domain ); + return yourls_apply_filter( 'translate', $translations->translate( $text ), $text, $domain ); } /** @@ -84,8 +84,8 @@ function yourls_translate( $text, $domain = 'default' ) { * @return string Translated text */ function yourls_translate_with_context( $text, $context, $domain = 'default' ) { - $translations = yourls_get_translations_for_domain( $domain ); - return yourls_apply_filter( 'translate_with_context', $translations->translate( $text, $context ), $text, $context, $domain ); + $translations = yourls_get_translations_for_domain( $domain ); + return yourls_apply_filter( 'translate_with_context', $translations->translate( $text, $context ), $text, $context, $domain ); } /** @@ -100,7 +100,7 @@ function yourls_translate_with_context( $text, $context, $domain = 'default' ) { * @return string Translated text */ function yourls__( $text, $domain = 'default' ) { - return yourls_translate( $text, $domain ); + return yourls_translate( $text, $domain ); } /** @@ -120,27 +120,27 @@ function yourls__( $text, $domain = 'default' ) { * @return string Translated text */ function yourls_s( $pattern ) { - // Get pattern and pattern arguments - $args = func_get_args(); - // If yourls_s() called by yourls_se(), all arguments are wrapped in the same array key - if( count( $args ) == 1 && is_array( $args[0] ) ) { - $args = $args[0]; - } - $pattern = $args[0]; - - // get list of sprintf tokens (%s and such) - $num_of_tokens = substr_count( $pattern, '%' ) - 2 * substr_count( $pattern, '%%' ); - - $domain = 'default'; - // More arguments passed than needed for the sprintf? The last one will be the domain - if( $num_of_tokens < ( count( $args ) - 1 ) ) { - $domain = array_pop( $args ); - } - - // Translate text - $args[0] = yourls__( $pattern, $domain ); - - return call_user_func_array( 'sprintf', $args ); + // Get pattern and pattern arguments + $args = func_get_args(); + // If yourls_s() called by yourls_se(), all arguments are wrapped in the same array key + if( count( $args ) == 1 && is_array( $args[0] ) ) { + $args = $args[0]; + } + $pattern = $args[0]; + + // get list of sprintf tokens (%s and such) + $num_of_tokens = substr_count( $pattern, '%' ) - 2 * substr_count( $pattern, '%%' ); + + $domain = 'default'; + // More arguments passed than needed for the sprintf? The last one will be the domain + if( $num_of_tokens < ( count( $args ) - 1 ) ) { + $domain = array_pop( $args ); + } + + // Translate text + $args[0] = yourls__( $pattern, $domain ); + + return call_user_func_array( 'sprintf', $args ); } /** @@ -161,7 +161,7 @@ function yourls_s( $pattern ) { * @return void Translated text */ function yourls_se( $pattern ) { - echo yourls_s( func_get_args() ); + echo yourls_s( func_get_args() ); } @@ -178,7 +178,7 @@ function yourls_se( $pattern ) { * @return string Translated text */ function yourls_esc_attr__( $text, $domain = 'default' ) { - return yourls_esc_attr( yourls_translate( $text, $domain ) ); + return yourls_esc_attr( yourls_translate( $text, $domain ) ); } /** @@ -194,7 +194,7 @@ function yourls_esc_attr__( $text, $domain = 'default' ) { * @return string Translated text */ function yourls_esc_html__( $text, $domain = 'default' ) { - return yourls_esc_html( yourls_translate( $text, $domain ) ); + return yourls_esc_html( yourls_translate( $text, $domain ) ); } /** @@ -208,7 +208,7 @@ function yourls_esc_html__( $text, $domain = 'default' ) { * @return void */ function yourls_e( $text, $domain = 'default' ) { - echo yourls_translate( $text, $domain ); + echo yourls_translate( $text, $domain ); } /** @@ -223,7 +223,7 @@ function yourls_e( $text, $domain = 'default' ) { * @return void */ function yourls_esc_attr_e( $text, $domain = 'default' ) { - echo yourls_esc_attr( yourls_translate( $text, $domain ) ); + echo yourls_esc_attr( yourls_translate( $text, $domain ) ); } /** @@ -238,7 +238,7 @@ function yourls_esc_attr_e( $text, $domain = 'default' ) { * @return void */ function yourls_esc_html_e( $text, $domain = 'default' ) { - echo yourls_esc_html( yourls_translate( $text, $domain ) ); + echo yourls_esc_html( yourls_translate( $text, $domain ) ); } /** @@ -258,7 +258,7 @@ function yourls_esc_html_e( $text, $domain = 'default' ) { * @return string Translated context string */ function yourls_x( $text, $context, $domain = 'default' ) { - return yourls_translate_with_context( $text, $context, $domain ); + return yourls_translate_with_context( $text, $context, $domain ); } /** @@ -273,7 +273,7 @@ function yourls_x( $text, $context, $domain = 'default' ) { * @return void Echoes translated context string */ function yourls_xe( $text, $context, $domain = 'default' ) { - echo yourls_x( $text, $context, $domain ); + echo yourls_x( $text, $context, $domain ); } @@ -292,7 +292,7 @@ function yourls_xe( $text, $context, $domain = 'default' ) { * @return string */ function yourls_esc_attr_x( $single, $context, $domain = 'default' ) { - return yourls_esc_attr( yourls_translate_with_context( $single, $context, $domain ) ); + return yourls_esc_attr( yourls_translate_with_context( $single, $context, $domain ) ); } /** @@ -310,7 +310,7 @@ function yourls_esc_attr_x( $single, $context, $domain = 'default' ) { * @return string */ function yourls_esc_html_x( $single, $context, $domain = 'default' ) { - return yourls_esc_html( yourls_translate_with_context( $single, $context, $domain ) ); + return yourls_esc_html( yourls_translate_with_context( $single, $context, $domain ) ); } /** @@ -327,7 +327,7 @@ function yourls_esc_html_x( $single, $context, $domain = 'default' ) { * @since 1.6 * @uses $yourls_l10n Gets list of domain translated string (gettext_reader) objects * @uses yourls_apply_filter() Calls 'translate_n' hook on domains text returned, - * along with $single, $plural, and $number parameters. Expected to return string. + * along with $single, $plural, and $number parameters. Expected to return string. * * @param string $single The text that will be used if $number is 1 * @param string $plural The text that will be used if $number is not 1 @@ -336,9 +336,9 @@ function yourls_esc_html_x( $single, $context, $domain = 'default' ) { * @return string Either $single or $plural translated text */ function yourls_n( $single, $plural, $number, $domain = 'default' ) { - $translations = yourls_get_translations_for_domain( $domain ); - $translation = $translations->translate_plural( $single, $plural, $number ); - return yourls_apply_filter( 'translate_n', $translation, $single, $plural, $number, $domain ); + $translations = yourls_get_translations_for_domain( $domain ); + $translation = $translations->translate_plural( $single, $plural, $number ); + return yourls_apply_filter( 'translate_n', $translation, $single, $plural, $number, $domain ); } /** @@ -356,9 +356,9 @@ function yourls_n( $single, $plural, $number, $domain = 'default' ) { * @return string Either $single or $plural translated text */ function yourls_nx($single, $plural, $number, $context, $domain = 'default') { - $translations = yourls_get_translations_for_domain( $domain ); - $translation = $translations->translate_plural( $single, $plural, $number, $context ); - return yourls_apply_filter( 'translate_nx', $translation, $single, $plural, $number, $context, $domain ); + $translations = yourls_get_translations_for_domain( $domain ); + $translation = $translations->translate_plural( $single, $plural, $number, $context ); + return yourls_apply_filter( 'translate_nx', $translation, $single, $plural, $number, $context, $domain ); } /** @@ -369,8 +369,8 @@ function yourls_nx($single, $plural, $number, $context, $domain = 'default') { * * Example: * $messages = array( - * 'post' => yourls_n_noop('%s post', '%s posts'), - * 'page' => yourls_n_noop('%s pages', '%s pages') + * 'post' => yourls_n_noop('%s post', '%s posts'), + * 'page' => yourls_n_noop('%s pages', '%s pages') * ); * ... * $message = $messages[$type]; @@ -383,14 +383,14 @@ function yourls_nx($single, $plural, $number, $context, $domain = 'default') { * @return array array($singular, $plural) */ function yourls_n_noop( $singular, $plural, $domain = null ) { - return array( - 0 => $singular, - 1 => $plural, - 'singular' => $singular, - 'plural' => $plural, - 'context' => null, - 'domain' => $domain - ); + return array( + 0 => $singular, + 1 => $plural, + 'singular' => $singular, + 'plural' => $plural, + 'context' => null, + 'domain' => $domain + ); } /** @@ -406,15 +406,15 @@ function yourls_n_noop( $singular, $plural, $domain = null ) { * @return array array($singular, $plural) */ function yourls_nx_noop( $singular, $plural, $context, $domain = null ) { - return array( - 0 => $singular, - 1 => $plural, - 2 => $context, - 'singular' => $singular, - 'plural' => $plural, - 'context' => $context, - 'domain' => $domain - ); + return array( + 0 => $singular, + 1 => $plural, + 2 => $context, + 'singular' => $singular, + 'plural' => $plural, + 'context' => $context, + 'domain' => $domain + ); } /** @@ -424,17 +424,17 @@ function yourls_nx_noop( $singular, $plural, $context, $domain = null ) { * @param array $nooped_plural Array with singular, plural and context keys, usually the result of yourls_n_noop() or yourls_nx_noop() * @param int $count Number of objects * @param string $domain Optional. The domain identifier the text should be retrieved in. If $nooped_plural contains - * a domain passed to yourls_n_noop() or yourls_nx_noop(), it will override this value. + * a domain passed to yourls_n_noop() or yourls_nx_noop(), it will override this value. * @return string */ function yourls_translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) { - if ( $nooped_plural['domain'] ) - $domain = $nooped_plural['domain']; + if ( $nooped_plural['domain'] ) + $domain = $nooped_plural['domain']; - if ( $nooped_plural['context'] ) - return yourls_nx( $nooped_plural['singular'], $nooped_plural['plural'], $count, $nooped_plural['context'], $domain ); - else - return yourls_n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain ); + if ( $nooped_plural['context'] ) + return yourls_nx( $nooped_plural['singular'], $nooped_plural['plural'], $count, $nooped_plural['context'], $domain ); + else + return yourls_n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain ); } /** @@ -454,34 +454,34 @@ function yourls_translate_nooped_plural( $nooped_plural, $count, $domain = 'defa * @return bool True on success, false on failure */ function yourls_load_textdomain( $domain, $mofile ) { - global $yourls_l10n; + global $yourls_l10n; - $plugin_override = yourls_apply_filter( 'override_load_textdomain', false, $domain, $mofile ); + $plugin_override = yourls_apply_filter( 'override_load_textdomain', false, $domain, $mofile ); - if ( true == $plugin_override ) { - return true; - } + if ( true == $plugin_override ) { + return true; + } - yourls_do_action( 'load_textdomain', $domain, $mofile ); + yourls_do_action( 'load_textdomain', $domain, $mofile ); - $mofile = yourls_apply_filter( 'load_textdomain_mofile', $mofile, $domain ); + $mofile = yourls_apply_filter( 'load_textdomain_mofile', $mofile, $domain ); - if ( !is_readable( $mofile ) ) { + if ( !is_readable( $mofile ) ) { trigger_error( 'Cannot read file ' . str_replace( YOURLS_ABSPATH.'/', '', $mofile ) . '.' . ' Make sure there is a language file installed. More info: http://yourls.org/translations' ); return false; } - $mo = new MO(); - if ( !$mo->import_from_file( $mofile ) ) + $mo = new MO(); + if ( !$mo->import_from_file( $mofile ) ) return false; - if ( isset( $yourls_l10n[$domain] ) ) - $mo->merge_with( $yourls_l10n[$domain] ); + if ( isset( $yourls_l10n[$domain] ) ) + $mo->merge_with( $yourls_l10n[$domain] ); - $yourls_l10n[$domain] = &$mo; + $yourls_l10n[$domain] = &$mo; - return true; + return true; } /** @@ -492,21 +492,21 @@ function yourls_load_textdomain( $domain, $mofile ) { * @return bool Whether textdomain was unloaded */ function yourls_unload_textdomain( $domain ) { - global $yourls_l10n; + global $yourls_l10n; - $plugin_override = yourls_apply_filter( 'override_unload_textdomain', false, $domain ); + $plugin_override = yourls_apply_filter( 'override_unload_textdomain', false, $domain ); - if ( $plugin_override ) - return true; + if ( $plugin_override ) + return true; - yourls_do_action( 'unload_textdomain', $domain ); + yourls_do_action( 'unload_textdomain', $domain ); - if ( isset( $yourls_l10n[$domain] ) ) { - unset( $yourls_l10n[$domain] ); - return true; - } + if ( isset( $yourls_l10n[$domain] ) ) { + unset( $yourls_l10n[$domain] ); + return true; + } - return false; + return false; } /** @@ -519,7 +519,7 @@ function yourls_unload_textdomain( $domain ) { * @return bool True on success, false on failure */ function yourls_load_default_textdomain() { - $yourls_locale = yourls_get_locale(); + $yourls_locale = yourls_get_locale(); if( !empty( $yourls_locale ) ) return yourls_load_textdomain( 'default', YOURLS_LANG_DIR . "/$yourls_locale.mo" ); @@ -535,11 +535,11 @@ function yourls_load_default_textdomain() { * @return NOOPTranslations An NOOPTranslations translation instance */ function yourls_get_translations_for_domain( $domain ) { - global $yourls_l10n; - if ( !isset( $yourls_l10n[$domain] ) ) { - $yourls_l10n[$domain] = new NOOPTranslations; - } - return $yourls_l10n[$domain]; + global $yourls_l10n; + if ( !isset( $yourls_l10n[$domain] ) ) { + $yourls_l10n[$domain] = new NOOPTranslations; + } + return $yourls_l10n[$domain]; } /** @@ -550,8 +550,8 @@ function yourls_get_translations_for_domain( $domain ) { * @return bool Whether there are translations */ function yourls_is_textdomain_loaded( $domain ) { - global $yourls_l10n; - return isset( $yourls_l10n[$domain] ); + global $yourls_l10n; + return isset( $yourls_l10n[$domain] ); } /** @@ -567,7 +567,7 @@ function yourls_is_textdomain_loaded( $domain ) { * @return string Translated role name */ function yourls_translate_user_role( $name ) { - return yourls_translate_with_context( $name, 'User role' ); + return yourls_translate_with_context( $name, 'User role' ); } /** @@ -579,15 +579,15 @@ function yourls_translate_user_role( $name ) { * @return array Array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names. */ function yourls_get_available_languages( $dir = null ) { - $languages = array(); + $languages = array(); - $dir = is_null( $dir) ? YOURLS_LANG_DIR : $dir; + $dir = is_null( $dir) ? YOURLS_LANG_DIR : $dir; - foreach( (array) glob( $dir . '/*.mo' ) as $lang_file ) { - $languages[] = basename( $lang_file, '.mo' ); - } + foreach( (array) glob( $dir . '/*.mo' ) as $lang_file ) { + $languages[] = basename( $lang_file, '.mo' ); + } - return yourls_apply_filter( 'get_available_languages', $languages ); + return yourls_apply_filter( 'get_available_languages', $languages ); } /** @@ -600,12 +600,12 @@ function yourls_get_available_languages( $dir = null ) { * @return string Converted number in string format. */ function yourls_number_format_i18n( $number, $decimals = 0 ) { - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); - $formatted = number_format( $number, abs( intval( $decimals ) ), $yourls_locale_formats->number_format['decimal_point'], $yourls_locale_formats->number_format['thousands_sep'] ); - return yourls_apply_filter( 'number_format_i18n', $formatted ); + $formatted = number_format( $number, abs( intval( $decimals ) ), $yourls_locale_formats->number_format['decimal_point'], $yourls_locale_formats->number_format['thousands_sep'] ); + return yourls_apply_filter( 'number_format_i18n', $formatted ); } /** @@ -625,46 +625,46 @@ function yourls_date_i18n( $dateformatstring, $timestamp = false ) { /** * @var YOURLS_Locale_Formats $yourls_locale_formats */ - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); - if ( false === $timestamp ) { + if ( false === $timestamp ) { $timestamp = yourls_get_timestamp( time() ); - } - - // store original value for language with untypical grammars - $req_format = $dateformatstring; - - /** - * Replace the date format characters with their translatation, if found - * Example: - * 'l d F Y' gets replaced with '\L\u\n\d\i d \M\a\i Y' in French - * We deliberately don't deal with 'I', 'O', 'P', 'T', 'Z' and 'e' in date format (timezones) - */ - if ( ( !empty( $yourls_locale_formats->month ) ) && ( !empty( $yourls_locale_formats->weekday ) ) ) { - $datemonth = $yourls_locale_formats->get_month( date( 'm', $timestamp ) ); - $datemonth_abbrev = $yourls_locale_formats->get_month_abbrev( $datemonth ); - $dateweekday = $yourls_locale_formats->get_weekday( date( 'w', $timestamp ) ); - $dateweekday_abbrev = $yourls_locale_formats->get_weekday_abbrev( $dateweekday ); - $datemeridiem = $yourls_locale_formats->get_meridiem( date( 'a', $timestamp ) ); - $datemeridiem_capital = $yourls_locale_formats->get_meridiem( date( 'A', $timestamp ) ); - - $dateformatstring = ' '.$dateformatstring; - $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . yourls_backslashit( $dateweekday_abbrev ), $dateformatstring ); - $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . yourls_backslashit( $datemonth ), $dateformatstring ); - $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . yourls_backslashit( $dateweekday ), $dateformatstring ); - $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . yourls_backslashit( $datemonth_abbrev ), $dateformatstring ); - $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . yourls_backslashit( $datemeridiem ), $dateformatstring ); - $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . yourls_backslashit( $datemeridiem_capital ), $dateformatstring ); - - $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 ); - } - - $date = date( $dateformatstring, $timestamp ); - - // Allow plugins to redo this entirely for languages with untypical grammars - return yourls_apply_filter('date_i18n', $date, $req_format, $timestamp); + } + + // store original value for language with untypical grammars + $req_format = $dateformatstring; + + /** + * Replace the date format characters with their translatation, if found + * Example: + * 'l d F Y' gets replaced with '\L\u\n\d\i d \M\a\i Y' in French + * We deliberately don't deal with 'I', 'O', 'P', 'T', 'Z' and 'e' in date format (timezones) + */ + if ( ( !empty( $yourls_locale_formats->month ) ) && ( !empty( $yourls_locale_formats->weekday ) ) ) { + $datemonth = $yourls_locale_formats->get_month( date( 'm', $timestamp ) ); + $datemonth_abbrev = $yourls_locale_formats->get_month_abbrev( $datemonth ); + $dateweekday = $yourls_locale_formats->get_weekday( date( 'w', $timestamp ) ); + $dateweekday_abbrev = $yourls_locale_formats->get_weekday_abbrev( $dateweekday ); + $datemeridiem = $yourls_locale_formats->get_meridiem( date( 'a', $timestamp ) ); + $datemeridiem_capital = $yourls_locale_formats->get_meridiem( date( 'A', $timestamp ) ); + + $dateformatstring = ' '.$dateformatstring; + $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . yourls_backslashit( $dateweekday_abbrev ), $dateformatstring ); + $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . yourls_backslashit( $datemonth ), $dateformatstring ); + $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . yourls_backslashit( $dateweekday ), $dateformatstring ); + $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . yourls_backslashit( $datemonth_abbrev ), $dateformatstring ); + $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . yourls_backslashit( $datemeridiem ), $dateformatstring ); + $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . yourls_backslashit( $datemeridiem_capital ), $dateformatstring ); + + $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 ); + } + + $date = date( $dateformatstring, $timestamp ); + + // Allow plugins to redo this entirely for languages with untypical grammars + return yourls_apply_filter('date_i18n', $date, $req_format, $timestamp); } /** @@ -673,332 +673,332 @@ function yourls_date_i18n( $dateformatstring, $timestamp = false ) { * @since 1.6 */ class YOURLS_Locale_Formats { - /** - * Stores the translated strings for the full weekday names. - * - * @since 1.6 - * @var array - * @access private - */ - var $weekday; - - /** - * Stores the translated strings for the one character weekday names. - * - * There is a hack to make sure that Tuesday and Thursday, as well - * as Sunday and Saturday, don't conflict. See init() method for more. - * - * @see YOURLS_Locale_Formats::init() for how to handle the hack. - * - * @since 1.6 - * @var array - * @access private - */ - var $weekday_initial; - - /** - * Stores the translated strings for the abbreviated weekday names. - * - * @since 1.6 - * @var array - * @access private - */ - var $weekday_abbrev; - - /** - * Stores the translated strings for the full month names. - * - * @since 1.6 - * @var array - * @access private - */ - var $month; - - /** - * Stores the translated strings for the abbreviated month names. - * - * @since 1.6 - * @var array - * @access private - */ - var $month_abbrev; - - /** - * Stores the translated strings for 'am' and 'pm'. - * - * Also the capitalized versions. - * - * @since 1.6 - * @var array - * @access private - */ - var $meridiem; - - /** - * Stores the translated number format - * - * @since 1.6 - * @var array - * @access private - */ - var $number_format; - - /** - * The text direction of the locale language. - * - * Default is left to right 'ltr'. - * - * @since 1.6 - * @var string - * @access private - */ - var $text_direction = 'ltr'; - - /** - * Sets up the translated strings and object properties. - * - * The method creates the translatable strings for various - * calendar elements. Which allows for specifying locale - * specific calendar names and text direction. - * - * @since 1.6 - * @access private + /** + * Stores the translated strings for the full weekday names. + * + * @since 1.6 + * @var array + * @access private + */ + var $weekday; + + /** + * Stores the translated strings for the one character weekday names. + * + * There is a hack to make sure that Tuesday and Thursday, as well + * as Sunday and Saturday, don't conflict. See init() method for more. + * + * @see YOURLS_Locale_Formats::init() for how to handle the hack. + * + * @since 1.6 + * @var array + * @access private + */ + var $weekday_initial; + + /** + * Stores the translated strings for the abbreviated weekday names. + * + * @since 1.6 + * @var array + * @access private + */ + var $weekday_abbrev; + + /** + * Stores the translated strings for the full month names. + * + * @since 1.6 + * @var array + * @access private + */ + var $month; + + /** + * Stores the translated strings for the abbreviated month names. + * + * @since 1.6 + * @var array + * @access private + */ + var $month_abbrev; + + /** + * Stores the translated strings for 'am' and 'pm'. + * + * Also the capitalized versions. + * + * @since 1.6 + * @var array + * @access private + */ + var $meridiem; + + /** + * Stores the translated number format + * + * @since 1.6 + * @var array + * @access private + */ + var $number_format; + + /** + * The text direction of the locale language. + * + * Default is left to right 'ltr'. + * + * @since 1.6 + * @var string + * @access private + */ + var $text_direction = 'ltr'; + + /** + * Sets up the translated strings and object properties. + * + * The method creates the translatable strings for various + * calendar elements. Which allows for specifying locale + * specific calendar names and text direction. + * + * @since 1.6 + * @access private * @return void - */ - function init() { - // The Weekdays - $this->weekday[0] = /* //translators: weekday */ yourls__( 'Sunday' ); - $this->weekday[1] = /* //translators: weekday */ yourls__( 'Monday' ); - $this->weekday[2] = /* //translators: weekday */ yourls__( 'Tuesday' ); - $this->weekday[3] = /* //translators: weekday */ yourls__( 'Wednesday' ); - $this->weekday[4] = /* //translators: weekday */ yourls__( 'Thursday' ); - $this->weekday[5] = /* //translators: weekday */ yourls__( 'Friday' ); - $this->weekday[6] = /* //translators: weekday */ yourls__( 'Saturday' ); - - // The first letter of each day. The _%day%_initial suffix is a hack to make - // sure the day initials are unique. - $this->weekday_initial[yourls__( 'Sunday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'S_Sunday_initial' ); - $this->weekday_initial[yourls__( 'Monday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'M_Monday_initial' ); - $this->weekday_initial[yourls__( 'Tuesday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'T_Tuesday_initial' ); - $this->weekday_initial[yourls__( 'Wednesday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'W_Wednesday_initial' ); - $this->weekday_initial[yourls__( 'Thursday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'T_Thursday_initial' ); - $this->weekday_initial[yourls__( 'Friday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'F_Friday_initial' ); - $this->weekday_initial[yourls__( 'Saturday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'S_Saturday_initial' ); - - foreach ($this->weekday_initial as $weekday_ => $weekday_initial_) { - $this->weekday_initial[$weekday_] = preg_replace('/_.+_initial$/', '', $weekday_initial_); - } - - // Abbreviations for each day. - $this->weekday_abbrev[ yourls__( 'Sunday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Sun' ); - $this->weekday_abbrev[ yourls__( 'Monday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Mon' ); - $this->weekday_abbrev[ yourls__( 'Tuesday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Tue' ); - $this->weekday_abbrev[ yourls__( 'Wednesday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Wed' ); - $this->weekday_abbrev[ yourls__( 'Thursday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Thu' ); - $this->weekday_abbrev[ yourls__( 'Friday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Fri' ); - $this->weekday_abbrev[ yourls__( 'Saturday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Sat' ); - - // The Months - $this->month['01'] = /* //translators: month name */ yourls__( 'January' ); - $this->month['02'] = /* //translators: month name */ yourls__( 'February' ); - $this->month['03'] = /* //translators: month name */ yourls__( 'March' ); - $this->month['04'] = /* //translators: month name */ yourls__( 'April' ); - $this->month['05'] = /* //translators: month name */ yourls__( 'May' ); - $this->month['06'] = /* //translators: month name */ yourls__( 'June' ); - $this->month['07'] = /* //translators: month name */ yourls__( 'July' ); - $this->month['08'] = /* //translators: month name */ yourls__( 'August' ); - $this->month['09'] = /* //translators: month name */ yourls__( 'September' ); - $this->month['10'] = /* //translators: month name */ yourls__( 'October' ); - $this->month['11'] = /* //translators: month name */ yourls__( 'November' ); - $this->month['12'] = /* //translators: month name */ yourls__( 'December' ); - - // Abbreviations for each month. Uses the same hack as above to get around the - // 'May' duplication. - $this->month_abbrev[ yourls__( 'January' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jan_January_abbreviation' ); - $this->month_abbrev[ yourls__( 'February' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Feb_February_abbreviation' ); - $this->month_abbrev[ yourls__( 'March' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Mar_March_abbreviation' ); - $this->month_abbrev[ yourls__( 'April' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Apr_April_abbreviation' ); - $this->month_abbrev[ yourls__( 'May' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'May_May_abbreviation' ); - $this->month_abbrev[ yourls__( 'June' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jun_June_abbreviation' ); - $this->month_abbrev[ yourls__( 'July' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jul_July_abbreviation' ); - $this->month_abbrev[ yourls__( 'August' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Aug_August_abbreviation' ); - $this->month_abbrev[ yourls__( 'September' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Sep_September_abbreviation' ); - $this->month_abbrev[ yourls__( 'October' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Oct_October_abbreviation' ); - $this->month_abbrev[ yourls__( 'November' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Nov_November_abbreviation' ); - $this->month_abbrev[ yourls__( 'December' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Dec_December_abbreviation' ); - - foreach ($this->month_abbrev as $month_ => $month_abbrev_) { - $this->month_abbrev[$month_] = preg_replace('/_.+_abbreviation$/', '', $month_abbrev_); - } - - // The Meridiems - $this->meridiem['am'] = yourls__( 'am' ); - $this->meridiem['pm'] = yourls__( 'pm' ); - $this->meridiem['AM'] = yourls__( 'AM' ); - $this->meridiem['PM'] = yourls__( 'PM' ); - - // Numbers formatting - // See http://php.net/number_format - - /* //translators: $thousands_sep argument for http://php.net/number_format, default is , */ - $trans = yourls__( 'number_format_thousands_sep' ); - $this->number_format['thousands_sep'] = ('number_format_thousands_sep' == $trans) ? ',' : $trans; - - /* //translators: $dec_point argument for http://php.net/number_format, default is . */ - $trans = yourls__( 'number_format_decimal_point' ); - $this->number_format['decimal_point'] = ('number_format_decimal_point' == $trans) ? '.' : $trans; - - // Set text direction. - if ( isset( $GLOBALS['text_direction'] ) ) - $this->text_direction = $GLOBALS['text_direction']; - /* //translators: 'rtl' or 'ltr'. This sets the text direction for YOURLS. */ - elseif ( 'rtl' == yourls_x( 'ltr', 'text direction' ) ) - $this->text_direction = 'rtl'; - } - - /** - * Retrieve the full translated weekday word. - * - * Week starts on translated Sunday and can be fetched - * by using 0 (zero). So the week starts with 0 (zero) - * and ends on Saturday with is fetched by using 6 (six). - * - * @since 1.6 - * @access public - * - * @param int|string $weekday_number 0 for Sunday through 6 Saturday - * @return string Full translated weekday - */ - function get_weekday( $weekday_number ) { - return $this->weekday[ $weekday_number ]; - } - - /** - * Retrieve the translated weekday initial. - * - * The weekday initial is retrieved by the translated - * full weekday word. When translating the weekday initial - * pay attention to make sure that the starting letter does - * not conflict. - * - * @since 1.6 - * @access public - * - * @param string $weekday_name - * @return string - */ - function get_weekday_initial( $weekday_name ) { - return $this->weekday_initial[ $weekday_name ]; - } - - /** - * Retrieve the translated weekday abbreviation. - * - * The weekday abbreviation is retrieved by the translated - * full weekday word. - * - * @since 1.6 - * @access public - * - * @param string $weekday_name Full translated weekday word - * @return string Translated weekday abbreviation - */ - function get_weekday_abbrev( $weekday_name ) { - return $this->weekday_abbrev[ $weekday_name ]; - } - - /** - * Retrieve the full translated month by month number. - * - * The $month_number parameter has to be a string - * because it must have the '0' in front of any number - * that is less than 10. Starts from '01' and ends at - * '12'. - * - * You can use an integer instead and it will add the - * '0' before the numbers less than 10 for you. - * - * @since 1.6 - * @access public - * - * @param string|int $month_number '01' through '12' - * @return string Translated full month name - */ - function get_month( $month_number ) { - return $this->month[ sprintf( '%02s', $month_number ) ]; - } - - /** - * Retrieve translated version of month abbreviation string. - * - * The $month_name parameter is expected to be the translated or - * translatable version of the month. - * - * @since 1.6 - * @access public - * - * @param string $month_name Translated month to get abbreviated version - * @return string Translated abbreviated month - */ - function get_month_abbrev( $month_name ) { - return $this->month_abbrev[ $month_name ]; - } - - /** - * Retrieve translated version of meridiem string. - * - * The $meridiem parameter is expected to not be translated. - * - * @since 1.6 - * @access public - * - * @param string $meridiem Either 'am', 'pm', 'AM', or 'PM'. Not translated version. - * @return string Translated version - */ - function get_meridiem( $meridiem ) { - return $this->meridiem[ $meridiem ]; - } - - /** - * Global variables are deprecated. For backwards compatibility only. - * - * @deprecated For backwards compatibility only. - * @access private - * - * @since 1.6 + */ + function init() { + // The Weekdays + $this->weekday[0] = /* //translators: weekday */ yourls__( 'Sunday' ); + $this->weekday[1] = /* //translators: weekday */ yourls__( 'Monday' ); + $this->weekday[2] = /* //translators: weekday */ yourls__( 'Tuesday' ); + $this->weekday[3] = /* //translators: weekday */ yourls__( 'Wednesday' ); + $this->weekday[4] = /* //translators: weekday */ yourls__( 'Thursday' ); + $this->weekday[5] = /* //translators: weekday */ yourls__( 'Friday' ); + $this->weekday[6] = /* //translators: weekday */ yourls__( 'Saturday' ); + + // The first letter of each day. The _%day%_initial suffix is a hack to make + // sure the day initials are unique. + $this->weekday_initial[yourls__( 'Sunday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'S_Sunday_initial' ); + $this->weekday_initial[yourls__( 'Monday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'M_Monday_initial' ); + $this->weekday_initial[yourls__( 'Tuesday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'T_Tuesday_initial' ); + $this->weekday_initial[yourls__( 'Wednesday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'W_Wednesday_initial' ); + $this->weekday_initial[yourls__( 'Thursday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'T_Thursday_initial' ); + $this->weekday_initial[yourls__( 'Friday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'F_Friday_initial' ); + $this->weekday_initial[yourls__( 'Saturday' )] = /* //translators: one-letter abbreviation of the weekday */ yourls__( 'S_Saturday_initial' ); + + foreach ($this->weekday_initial as $weekday_ => $weekday_initial_) { + $this->weekday_initial[$weekday_] = preg_replace('/_.+_initial$/', '', $weekday_initial_); + } + + // Abbreviations for each day. + $this->weekday_abbrev[ yourls__( 'Sunday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Sun' ); + $this->weekday_abbrev[ yourls__( 'Monday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Mon' ); + $this->weekday_abbrev[ yourls__( 'Tuesday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Tue' ); + $this->weekday_abbrev[ yourls__( 'Wednesday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Wed' ); + $this->weekday_abbrev[ yourls__( 'Thursday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Thu' ); + $this->weekday_abbrev[ yourls__( 'Friday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Fri' ); + $this->weekday_abbrev[ yourls__( 'Saturday' ) ] = /* //translators: three-letter abbreviation of the weekday */ yourls__( 'Sat' ); + + // The Months + $this->month['01'] = /* //translators: month name */ yourls__( 'January' ); + $this->month['02'] = /* //translators: month name */ yourls__( 'February' ); + $this->month['03'] = /* //translators: month name */ yourls__( 'March' ); + $this->month['04'] = /* //translators: month name */ yourls__( 'April' ); + $this->month['05'] = /* //translators: month name */ yourls__( 'May' ); + $this->month['06'] = /* //translators: month name */ yourls__( 'June' ); + $this->month['07'] = /* //translators: month name */ yourls__( 'July' ); + $this->month['08'] = /* //translators: month name */ yourls__( 'August' ); + $this->month['09'] = /* //translators: month name */ yourls__( 'September' ); + $this->month['10'] = /* //translators: month name */ yourls__( 'October' ); + $this->month['11'] = /* //translators: month name */ yourls__( 'November' ); + $this->month['12'] = /* //translators: month name */ yourls__( 'December' ); + + // Abbreviations for each month. Uses the same hack as above to get around the + // 'May' duplication. + $this->month_abbrev[ yourls__( 'January' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jan_January_abbreviation' ); + $this->month_abbrev[ yourls__( 'February' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Feb_February_abbreviation' ); + $this->month_abbrev[ yourls__( 'March' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Mar_March_abbreviation' ); + $this->month_abbrev[ yourls__( 'April' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Apr_April_abbreviation' ); + $this->month_abbrev[ yourls__( 'May' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'May_May_abbreviation' ); + $this->month_abbrev[ yourls__( 'June' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jun_June_abbreviation' ); + $this->month_abbrev[ yourls__( 'July' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Jul_July_abbreviation' ); + $this->month_abbrev[ yourls__( 'August' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Aug_August_abbreviation' ); + $this->month_abbrev[ yourls__( 'September' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Sep_September_abbreviation' ); + $this->month_abbrev[ yourls__( 'October' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Oct_October_abbreviation' ); + $this->month_abbrev[ yourls__( 'November' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Nov_November_abbreviation' ); + $this->month_abbrev[ yourls__( 'December' ) ] = /* //translators: three-letter abbreviation of the month */ yourls__( 'Dec_December_abbreviation' ); + + foreach ($this->month_abbrev as $month_ => $month_abbrev_) { + $this->month_abbrev[$month_] = preg_replace('/_.+_abbreviation$/', '', $month_abbrev_); + } + + // The Meridiems + $this->meridiem['am'] = yourls__( 'am' ); + $this->meridiem['pm'] = yourls__( 'pm' ); + $this->meridiem['AM'] = yourls__( 'AM' ); + $this->meridiem['PM'] = yourls__( 'PM' ); + + // Numbers formatting + // See http://php.net/number_format + + /* //translators: $thousands_sep argument for http://php.net/number_format, default is , */ + $trans = yourls__( 'number_format_thousands_sep' ); + $this->number_format['thousands_sep'] = ('number_format_thousands_sep' == $trans) ? ',' : $trans; + + /* //translators: $dec_point argument for http://php.net/number_format, default is . */ + $trans = yourls__( 'number_format_decimal_point' ); + $this->number_format['decimal_point'] = ('number_format_decimal_point' == $trans) ? '.' : $trans; + + // Set text direction. + if ( isset( $GLOBALS['text_direction'] ) ) + $this->text_direction = $GLOBALS['text_direction']; + /* //translators: 'rtl' or 'ltr'. This sets the text direction for YOURLS. */ + elseif ( 'rtl' == yourls_x( 'ltr', 'text direction' ) ) + $this->text_direction = 'rtl'; + } + + /** + * Retrieve the full translated weekday word. + * + * Week starts on translated Sunday and can be fetched + * by using 0 (zero). So the week starts with 0 (zero) + * and ends on Saturday with is fetched by using 6 (six). + * + * @since 1.6 + * @access public + * + * @param int|string $weekday_number 0 for Sunday through 6 Saturday + * @return string Full translated weekday + */ + function get_weekday( $weekday_number ) { + return $this->weekday[ $weekday_number ]; + } + + /** + * Retrieve the translated weekday initial. + * + * The weekday initial is retrieved by the translated + * full weekday word. When translating the weekday initial + * pay attention to make sure that the starting letter does + * not conflict. + * + * @since 1.6 + * @access public + * + * @param string $weekday_name + * @return string + */ + function get_weekday_initial( $weekday_name ) { + return $this->weekday_initial[ $weekday_name ]; + } + + /** + * Retrieve the translated weekday abbreviation. + * + * The weekday abbreviation is retrieved by the translated + * full weekday word. + * + * @since 1.6 + * @access public + * + * @param string $weekday_name Full translated weekday word + * @return string Translated weekday abbreviation + */ + function get_weekday_abbrev( $weekday_name ) { + return $this->weekday_abbrev[ $weekday_name ]; + } + + /** + * Retrieve the full translated month by month number. + * + * The $month_number parameter has to be a string + * because it must have the '0' in front of any number + * that is less than 10. Starts from '01' and ends at + * '12'. + * + * You can use an integer instead and it will add the + * '0' before the numbers less than 10 for you. + * + * @since 1.6 + * @access public + * + * @param string|int $month_number '01' through '12' + * @return string Translated full month name + */ + function get_month( $month_number ) { + return $this->month[ sprintf( '%02s', $month_number ) ]; + } + + /** + * Retrieve translated version of month abbreviation string. + * + * The $month_name parameter is expected to be the translated or + * translatable version of the month. + * + * @since 1.6 + * @access public + * + * @param string $month_name Translated month to get abbreviated version + * @return string Translated abbreviated month + */ + function get_month_abbrev( $month_name ) { + return $this->month_abbrev[ $month_name ]; + } + + /** + * Retrieve translated version of meridiem string. + * + * The $meridiem parameter is expected to not be translated. + * + * @since 1.6 + * @access public + * + * @param string $meridiem Either 'am', 'pm', 'AM', or 'PM'. Not translated version. + * @return string Translated version + */ + function get_meridiem( $meridiem ) { + return $this->meridiem[ $meridiem ]; + } + + /** + * Global variables are deprecated. For backwards compatibility only. + * + * @deprecated For backwards compatibility only. + * @access private + * + * @since 1.6 * @return void - */ - function register_globals() { - $GLOBALS['weekday'] = $this->weekday; - $GLOBALS['weekday_initial'] = $this->weekday_initial; - $GLOBALS['weekday_abbrev'] = $this->weekday_abbrev; - $GLOBALS['month'] = $this->month; - $GLOBALS['month_abbrev'] = $this->month_abbrev; - } - - /** - * Constructor which calls helper methods to set up object variables - * - * @uses YOURLS_Locale_Formats::init() - * @uses YOURLS_Locale_Formats::register_globals() - * @since 1.6 - * - * @return YOURLS_Locale_Formats - */ - function __construct() { - $this->init(); - $this->register_globals(); - } - - /** - * Checks if current locale is RTL. - * - * @since 1.6 - * @return bool Whether locale is RTL. - */ - function is_rtl() { - return 'rtl' == $this->text_direction; - } + */ + function register_globals() { + $GLOBALS['weekday'] = $this->weekday; + $GLOBALS['weekday_initial'] = $this->weekday_initial; + $GLOBALS['weekday_abbrev'] = $this->weekday_abbrev; + $GLOBALS['month'] = $this->month; + $GLOBALS['month_abbrev'] = $this->month_abbrev; + } + + /** + * Constructor which calls helper methods to set up object variables + * + * @uses YOURLS_Locale_Formats::init() + * @uses YOURLS_Locale_Formats::register_globals() + * @since 1.6 + * + * @return YOURLS_Locale_Formats + */ + function __construct() { + $this->init(); + $this->register_globals(); + } + + /** + * Checks if current locale is RTL. + * + * @since 1.6 + * @return bool Whether locale is RTL. + */ + function is_rtl() { + return 'rtl' == $this->text_direction; + } } /** @@ -1014,7 +1014,7 @@ function is_rtl() { * @return mixed Returns nothing if locale undefined, otherwise return bool: true on success, false on failure */ function yourls_load_custom_textdomain( $domain, $path ) { - $locale = yourls_apply_filter( 'load_custom_textdomain', yourls_get_locale(), $domain ); + $locale = yourls_apply_filter( 'load_custom_textdomain', yourls_get_locale(), $domain ); if( !empty( $locale ) ) { $mofile = rtrim( $path, '/' ) . '/'. $domain . '-' . $locale . '.mo'; return yourls_load_textdomain( $domain, $mofile ); @@ -1028,11 +1028,11 @@ function yourls_load_custom_textdomain( $domain, $path ) { * @return bool Whether locale is RTL. */ function yourls_is_rtl() { - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); - return $yourls_locale_formats->is_rtl(); + return $yourls_locale_formats->is_rtl(); } /** @@ -1046,19 +1046,19 @@ function yourls_is_rtl() { * @return mixed Translated weekday abbreviation, eg "Ven" (abbrev of "Vendredi") for "Friday" or 5, or array of all weekday abbrev */ function yourls_l10n_weekday_abbrev( $weekday = '' ){ - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); - - if( $weekday === '' ) - return $yourls_locale_formats->weekday_abbrev; - - if( is_int( $weekday ) ) { - $day = $yourls_locale_formats->weekday[ $weekday ]; - return $yourls_locale_formats->weekday_abbrev[ $day ]; - } else { - return $yourls_locale_formats->weekday_abbrev[ yourls__( $weekday ) ]; - } + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); + + if( $weekday === '' ) + return $yourls_locale_formats->weekday_abbrev; + + if( is_int( $weekday ) ) { + $day = $yourls_locale_formats->weekday[ $weekday ]; + return $yourls_locale_formats->weekday_abbrev[ $day ]; + } else { + return $yourls_locale_formats->weekday_abbrev[ yourls__( $weekday ) ]; + } } /** @@ -1072,19 +1072,19 @@ function yourls_l10n_weekday_abbrev( $weekday = '' ){ * @return mixed Translated weekday initial, eg "V" (initial of "Vendredi") for "Friday" or 5, or array of all weekday initials */ function yourls_l10n_weekday_initial( $weekday = '' ){ - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); - - if( $weekday === '' ) - return $yourls_locale_formats->weekday_initial; - - if( is_int( $weekday ) ) { - $weekday = $yourls_locale_formats->weekday[ $weekday ]; - return $yourls_locale_formats->weekday_initial[ $weekday ]; - } else { - return $yourls_locale_formats->weekday_initial[ yourls__( $weekday ) ]; - } + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); + + if( $weekday === '' ) + return $yourls_locale_formats->weekday_initial; + + if( is_int( $weekday ) ) { + $weekday = $yourls_locale_formats->weekday[ $weekday ]; + return $yourls_locale_formats->weekday_initial[ $weekday ]; + } else { + return $yourls_locale_formats->weekday_initial[ yourls__( $weekday ) ]; + } } /** @@ -1098,20 +1098,20 @@ function yourls_l10n_weekday_initial( $weekday = '' ){ * @return mixed Translated month abbrev (eg "Nov"), or array of all translated abbrev months */ function yourls_l10n_month_abbrev( $month = '' ){ - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); - if( $month === '' ) - return $yourls_locale_formats->month_abbrev; + if( $month === '' ) + return $yourls_locale_formats->month_abbrev; - if( intval( $month ) > 0 ) { + if( intval( $month ) > 0 ) { $month = sprintf('%02d', intval( $month ) ); - $month = $yourls_locale_formats->month[ $month ]; - return $yourls_locale_formats->month_abbrev[ $month ]; - } else { - return $yourls_locale_formats->month_abbrev[ yourls__( $month ) ]; - } + $month = $yourls_locale_formats->month[ $month ]; + return $yourls_locale_formats->month_abbrev[ $month ]; + } else { + return $yourls_locale_formats->month_abbrev[ yourls__( $month ) ]; + } } /** @@ -1121,9 +1121,9 @@ function yourls_l10n_month_abbrev( $month = '' ){ * @return array Array of all translated months */ function yourls_l10n_months(){ - global $yourls_locale_formats; - if( !isset( $yourls_locale_formats ) ) - $yourls_locale_formats = new YOURLS_Locale_Formats(); + global $yourls_locale_formats; + if( !isset( $yourls_locale_formats ) ) + $yourls_locale_formats = new YOURLS_Locale_Formats(); - return $yourls_locale_formats->month; + return $yourls_locale_formats->month; } diff --git a/includes/functions-plugins.php b/includes/functions-plugins.php index 5bf35613d..93ec27a9c 100644 --- a/includes/functions-plugins.php +++ b/includes/functions-plugins.php @@ -123,7 +123,7 @@ function yourls_add_filter( $hook, $function_name, $priority = 10, $accepted_arg * @return void */ function yourls_add_action( $hook, $function_name, $priority = 10, $accepted_args = 1 ) { - yourls_add_filter( $hook, $function_name, $priority, $accepted_args, 'action' ); + yourls_add_filter( $hook, $function_name, $priority, $accepted_args, 'action' ); } /** @@ -175,12 +175,12 @@ function yourls_filter_unique_id($function) { * * Typical use: * - * 1) Modify a variable if a function is attached to hook 'yourls_hook' - * $yourls_var = "default value"; - * $yourls_var = yourls_apply_filter( 'yourls_hook', $yourls_var ); + * 1) Modify a variable if a function is attached to hook 'yourls_hook' + * $yourls_var = "default value"; + * $yourls_var = yourls_apply_filter( 'yourls_hook', $yourls_var ); * - * 2) Trigger functions is attached to event 'yourls_event' - * yourls_apply_filter( 'yourls_event' ); + * 2) Trigger functions is attached to event 'yourls_event' + * yourls_apply_filter( 'yourls_event' ); * (see yourls_do_action() ) * * Returns a value which may have been modified by a filter. @@ -726,7 +726,7 @@ function yourls_deactivate_plugin( $plugin ) { * @return string */ function yourls_plugin_basename( $file ) { - return trim( str_replace( yourls_sanitize_filename( YOURLS_PLUGINDIR ), '', yourls_sanitize_filename( $file ) ), '/' ); + return trim( str_replace( yourls_sanitize_filename( YOURLS_PLUGINDIR ), '', yourls_sanitize_filename( $file ) ), '/' ); } /** diff --git a/includes/functions-shorturls.php b/includes/functions-shorturls.php index 3fa74d968..a17de3758 100644 --- a/includes/functions-shorturls.php +++ b/includes/functions-shorturls.php @@ -143,7 +143,7 @@ function yourls_add_new_link( $url, $keyword = '', $title = '', $row_id = 1 ) { $return['title'] = $title; $return['html'] = yourls_table_add_row( $keyword, $url, $title, $ip, 0, time(), $row_id ); $return['shorturl'] = yourls_link($keyword); - $return['statusCode'] = 200; // 200 OK + $return['statusCode'] = '200'; // 200 OK } else { // unknown database error, couldn't store result $return['status'] = 'fail'; @@ -207,6 +207,20 @@ function yourls_is_shorturl( $shorturl ) { return yourls_apply_filter( 'is_shorturl', $is_short, $shorturl ); } +/** + * Get the list of reserved keywords for URLs. + * + * @return array Array of reserved keywords + */ +function yourls_get_reserved_URL() { + global $yourls_reserved_URL; + if ( ! isset( $yourls_reserved_URL ) || ! is_array( $yourls_reserved_URL ) ) { + return array(); + } + + return $yourls_reserved_URL; +} + /** * Check to see if a given keyword is reserved (ie reserved URL or an existing page). Returns bool * @@ -214,11 +228,10 @@ function yourls_is_shorturl( $shorturl ) { * @return bool True if keyword reserved, false if free to be used */ function yourls_keyword_is_reserved( $keyword ) { - global $yourls_reserved_URL; $keyword = yourls_sanitize_keyword( $keyword ); $reserved = false; - if ( in_array( $keyword, $yourls_reserved_URL) + if ( in_array( $keyword, yourls_get_reserved_URL() ) or yourls_is_page($keyword) or is_dir( YOURLS_ABSPATH ."/$keyword" ) ) @@ -595,12 +608,12 @@ function yourls_get_keyword_stats( $shorturl ) { if( !$res ) { // non existent link $return = array( - 'statusCode' => 404, + 'statusCode' => '404', 'message' => 'Error: short URL not found', ); } else { $return = array( - 'statusCode' => 200, + 'statusCode' => '200', 'message' => 'success', 'link' => array( 'shorturl' => yourls_link($res->keyword), diff --git a/includes/functions-upgrade.php b/includes/functions-upgrade.php index af8c28459..63d7fc900 100644 --- a/includes/functions-upgrade.php +++ b/includes/functions-upgrade.php @@ -32,28 +32,28 @@ function yourls_upgrade($step, $oldver, $newver, $oldsql, $newsql ) { yourls_maintenance_mode(true); // special case for 1.3: the upgrade is a multi step procedure - if( $oldsql == 100 ) { - yourls_upgrade_to_14( $step ); - } + if( $oldsql == 100 ) { + yourls_upgrade_to_14( $step ); + } - // other upgrades which are done in a single pass - switch( $step ) { + // other upgrades which are done in a single pass + switch( $step ) { - case 1: - case 2: - if( $oldsql < 210 ) - yourls_upgrade_to_141(); + case 1: + case 2: + if( $oldsql < 210 ) + yourls_upgrade_to_141(); - if( $oldsql < 220 ) - yourls_upgrade_to_143(); + if( $oldsql < 220 ) + yourls_upgrade_to_143(); - if( $oldsql < 250 ) - yourls_upgrade_to_15(); + if( $oldsql < 250 ) + yourls_upgrade_to_15(); - if( $oldsql < 482 ) - yourls_upgrade_482(); // that was somewhere 1.5 and 1.5.1 ... + if( $oldsql < 482 ) + yourls_upgrade_482(); // that was somewhere 1.5 and 1.5.1 ... - if( $oldsql < 506 ) { + if( $oldsql < 506 ) { /** * 505 was the botched update with the wrong collation, see #2766 * 506 is the updated collation. @@ -61,24 +61,24 @@ function yourls_upgrade($step, $oldver, $newver, $oldsql, $newsql ) { * people on 505 to update to 506 * people before 505 to update to the FIXED complete upgrade */ - if( $oldsql == 505 ) { + if( $oldsql == 505 ) { yourls_upgrade_505_to_506(); } else { yourls_upgrade_to_506(); } } - yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=3" ) ); + yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=3" ) ); - break; + break; - case 3: - // Update options to reflect latest version - yourls_update_option( 'version', YOURLS_VERSION ); - yourls_update_option( 'db_version', YOURLS_DB_VERSION ); + case 3: + // Update options to reflect latest version + yourls_update_option( 'version', YOURLS_VERSION ); + yourls_update_option( 'db_version', YOURLS_DB_VERSION ); yourls_maintenance_mode(false); - break; - } + break; + } } /************************** 1.6 -> 1.8 **************************/ @@ -89,8 +89,8 @@ function yourls_upgrade($step, $oldver, $newver, $oldsql, $newsql ) { */ function yourls_upgrade_505_to_506() { echo "

Updating DB. Please wait...

"; - // Fix collation which was wrongly set at first to utf8mb4_unicode_ci - $query = sprintf('ALTER TABLE `%s` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;', YOURLS_DB_TABLE_URL); + // Fix collation which was wrongly set at first to utf8mb4_unicode_ci + $query = sprintf('ALTER TABLE `%s` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;', YOURLS_DB_TABLE_URL); try { yourls_get_db()->perform($query); @@ -155,11 +155,11 @@ function yourls_upgrade_to_506() { * */ function yourls_upgrade_482() { - // Change URL title charset to UTF8 - $table_url = YOURLS_DB_TABLE_URL; - $sql = "ALTER TABLE `$table_url` CHANGE `title` `title` TEXT CHARACTER SET utf8;"; - yourls_get_db()->perform( $sql ); - echo "

Updating table structure. Please wait...

"; + // Change URL title charset to UTF8 + $table_url = YOURLS_DB_TABLE_URL; + $sql = "ALTER TABLE `$table_url` CHANGE `title` `title` TEXT CHARACTER SET utf8;"; + yourls_get_db()->perform( $sql ); + echo "

Updating table structure. Please wait...

"; } /************************** 1.4.3 -> 1.5 **************************/ @@ -169,20 +169,20 @@ function yourls_upgrade_482() { * */ function yourls_upgrade_to_15( ) { - // Create empty 'active_plugins' entry in the option if needed - if( yourls_get_option( 'active_plugins' ) === false ) - yourls_add_option( 'active_plugins', array() ); - echo "

Enabling the plugin API. Please wait...

"; - - // Alter URL table to store titles - $table_url = YOURLS_DB_TABLE_URL; - $sql = "ALTER TABLE `$table_url` ADD `title` TEXT AFTER `url`;"; - yourls_get_db()->perform( $sql ); - echo "

Updating table structure. Please wait...

"; - - // Update .htaccess - yourls_create_htaccess(); - echo "

Updating .htaccess file. Please wait...

"; + // Create empty 'active_plugins' entry in the option if needed + if( yourls_get_option( 'active_plugins' ) === false ) + yourls_add_option( 'active_plugins', array() ); + echo "

Enabling the plugin API. Please wait...

"; + + // Alter URL table to store titles + $table_url = YOURLS_DB_TABLE_URL; + $sql = "ALTER TABLE `$table_url` ADD `title` TEXT AFTER `url`;"; + yourls_get_db()->perform( $sql ); + echo "

Updating table structure. Please wait...

"; + + // Update .htaccess + yourls_create_htaccess(); + echo "

Updating .htaccess file. Please wait...

"; } /************************** 1.4.1 -> 1.4.3 **************************/ @@ -192,16 +192,16 @@ function yourls_upgrade_to_15( ) { * */ function yourls_upgrade_to_143( ) { - // Check if we have 'keyword' (borked install) or 'shorturl' (ok install) - $ydb = yourls_get_db(); - $table_log = YOURLS_DB_TABLE_LOG; - $sql = "SHOW COLUMNS FROM `$table_log`"; - $cols = $ydb->fetchObjects( $sql ); - if ( $cols[2]->Field == 'keyword' ) { - $sql = "ALTER TABLE `$table_log` CHANGE `keyword` `shorturl` VARCHAR( 200 ) BINARY;"; - $ydb->query( $sql ); - } - echo "

Structure of existing tables updated. Please wait...

"; + // Check if we have 'keyword' (borked install) or 'shorturl' (ok install) + $ydb = yourls_get_db(); + $table_log = YOURLS_DB_TABLE_LOG; + $sql = "SHOW COLUMNS FROM `$table_log`"; + $cols = $ydb->fetchObjects( $sql ); + if ( $cols[2]->Field == 'keyword' ) { + $sql = "ALTER TABLE `$table_log` CHANGE `keyword` `shorturl` VARCHAR( 200 ) BINARY;"; + $ydb->query( $sql ); + } + echo "

Structure of existing tables updated. Please wait...

"; } /************************** 1.4 -> 1.4.1 **************************/ @@ -211,13 +211,13 @@ function yourls_upgrade_to_143( ) { * */ function yourls_upgrade_to_141( ) { - // Kill old cookies from 1.3 and prior - setcookie('yourls_username', '', time() - 3600 ); - setcookie('yourls_password', '', time() - 3600 ); - // alter table URL - yourls_alter_url_table_to_141(); - // recreate the htaccess file if needed - yourls_create_htaccess(); + // Kill old cookies from 1.3 and prior + setcookie('yourls_username', '', time() - 3600 ); + setcookie('yourls_password', '', time() - 3600 ); + // alter table URL + yourls_alter_url_table_to_141(); + // recreate the htaccess file if needed + yourls_create_htaccess(); } /** @@ -225,10 +225,10 @@ function yourls_upgrade_to_141( ) { * */ function yourls_alter_url_table_to_141() { - $table_url = YOURLS_DB_TABLE_URL; - $alter = "ALTER TABLE `$table_url` CHANGE `keyword` `keyword` VARCHAR( 200 ) BINARY, CHANGE `url` `url` TEXT BINARY "; - yourls_get_db()->perform( $alter ); - echo "

Structure of existing tables updated. Please wait...

"; + $table_url = YOURLS_DB_TABLE_URL; + $alter = "ALTER TABLE `$table_url` CHANGE `keyword` `keyword` VARCHAR( 200 ) BINARY, CHANGE `url` `url` TEXT BINARY "; + yourls_get_db()->perform( $alter ); + echo "

Structure of existing tables updated. Please wait...

"; } @@ -240,35 +240,35 @@ function yourls_alter_url_table_to_141() { */ function yourls_upgrade_to_14( $step ) { - switch( $step ) { - case 1: - // create table log & table options - // update table url structure - // update .htaccess - yourls_create_tables_for_14(); // no value returned, assuming it went OK - yourls_alter_url_table_to_14(); // no value returned, assuming it went OK - $clean = yourls_clean_htaccess_for_14(); // returns bool - $create = yourls_create_htaccess(); // returns bool - if ( !$create ) - echo "

Please create your .htaccess file (I could not do it for you). Please refer to http://yourls.org/htaccess."; - yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ), $create ); - break; - - case 2: - // convert each link in table url - yourls_update_table_to_14(); - break; - - case 3: - // update table url structure part 2: recreate indexes - yourls_alter_url_table_to_14_part_two(); - // update version & db_version & next_id in the option table - // attempt to drop YOURLS_DB_TABLE_NEXTDEC - yourls_update_options_to_14(); - // Now upgrade to 1.4.1 - yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=1&oldver=1.4&newver=1.4.1&oldsql=200&newsql=210" ) ); - break; - } + switch( $step ) { + case 1: + // create table log & table options + // update table url structure + // update .htaccess + yourls_create_tables_for_14(); // no value returned, assuming it went OK + yourls_alter_url_table_to_14(); // no value returned, assuming it went OK + $clean = yourls_clean_htaccess_for_14(); // returns bool + $create = yourls_create_htaccess(); // returns bool + if ( !$create ) + echo "

Please create your .htaccess file (I could not do it for you). Please refer to http://yourls.org/htaccess."; + yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ), $create ); + break; + + case 2: + // convert each link in table url + yourls_update_table_to_14(); + break; + + case 3: + // update table url structure part 2: recreate indexes + yourls_alter_url_table_to_14_part_two(); + // update version & db_version & next_id in the option table + // attempt to drop YOURLS_DB_TABLE_NEXTDEC + yourls_update_options_to_14(); + // Now upgrade to 1.4.1 + yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=1&oldver=1.4&newver=1.4.1&oldsql=200&newsql=210" ) ); + break; + } } /** @@ -276,17 +276,17 @@ function yourls_upgrade_to_14( $step ) { * */ function yourls_update_options_to_14() { - yourls_update_option( 'version', '1.4' ); - yourls_update_option( 'db_version', '200' ); - - if( defined('YOURLS_DB_TABLE_NEXTDEC') ) { - $table = YOURLS_DB_TABLE_NEXTDEC; - $next_id = yourls_get_db()->fetchValue("SELECT `next_id` FROM `$table`"); - yourls_update_option( 'next_id', $next_id ); - yourls_get_db()->perform( "DROP TABLE `$table`" ); - } else { - yourls_update_option( 'next_id', 1 ); // In case someone mistakenly deleted the next_id constant or table too early - } + yourls_update_option( 'version', '1.4' ); + yourls_update_option( 'db_version', '200' ); + + if( defined('YOURLS_DB_TABLE_NEXTDEC') ) { + $table = YOURLS_DB_TABLE_NEXTDEC; + $next_id = yourls_get_db()->fetchValue("SELECT `next_id` FROM `$table`"); + yourls_update_option( 'next_id', $next_id ); + yourls_get_db()->perform( "DROP TABLE `$table`" ); + } else { + yourls_update_option( 'next_id', 1 ); // In case someone mistakenly deleted the next_id constant or table too early + } } /** @@ -294,37 +294,37 @@ function yourls_update_options_to_14() { * */ function yourls_create_tables_for_14() { - $ydb = yourls_get_db(); - - $queries = array(); - - $queries[YOURLS_DB_TABLE_OPTIONS] = - 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. - '`option_id` int(11) unsigned NOT NULL auto_increment,'. - '`option_name` varchar(64) NOT NULL default "",'. - '`option_value` longtext NOT NULL,'. - 'PRIMARY KEY (`option_id`,`option_name`),'. - 'KEY `option_name` (`option_name`)'. - ');'; - - $queries[YOURLS_DB_TABLE_LOG] = - 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. - '`click_id` int(11) NOT NULL auto_increment,'. - '`click_time` datetime NOT NULL,'. - '`shorturl` varchar(200) NOT NULL,'. - '`referrer` varchar(200) NOT NULL,'. - '`user_agent` varchar(255) NOT NULL,'. - '`ip_address` varchar(41) NOT NULL,'. - '`country_code` char(2) NOT NULL,'. - 'PRIMARY KEY (`click_id`),'. - 'KEY `shorturl` (`shorturl`)'. - ');'; - - foreach( $queries as $query ) { - $ydb->perform( $query ); // There's no result to be returned to check if table was created (except making another query to check table existence, which we'll avoid) - } - - echo "

New tables created. Please wait...

"; + $ydb = yourls_get_db(); + + $queries = array(); + + $queries[YOURLS_DB_TABLE_OPTIONS] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_OPTIONS.'` ('. + '`option_id` int(11) unsigned NOT NULL auto_increment,'. + '`option_name` varchar(64) NOT NULL default "",'. + '`option_value` longtext NOT NULL,'. + 'PRIMARY KEY (`option_id`,`option_name`),'. + 'KEY `option_name` (`option_name`)'. + ');'; + + $queries[YOURLS_DB_TABLE_LOG] = + 'CREATE TABLE IF NOT EXISTS `'.YOURLS_DB_TABLE_LOG.'` ('. + '`click_id` int(11) NOT NULL auto_increment,'. + '`click_time` datetime NOT NULL,'. + '`shorturl` varchar(200) NOT NULL,'. + '`referrer` varchar(200) NOT NULL,'. + '`user_agent` varchar(255) NOT NULL,'. + '`ip_address` varchar(41) NOT NULL,'. + '`country_code` char(2) NOT NULL,'. + 'PRIMARY KEY (`click_id`),'. + 'KEY `shorturl` (`shorturl`)'. + ');'; + + foreach( $queries as $query ) { + $ydb->perform( $query ); // There's no result to be returned to check if table was created (except making another query to check table existence, which we'll avoid) + } + + echo "

New tables created. Please wait...

"; } @@ -333,20 +333,20 @@ function yourls_create_tables_for_14() { * */ function yourls_alter_url_table_to_14() { - $ydb = yourls_get_db(); - $table = YOURLS_DB_TABLE_URL; + $ydb = yourls_get_db(); + $table = YOURLS_DB_TABLE_URL; - $alters = array(); - $results = array(); - $alters[] = "ALTER TABLE `$table` CHANGE `id` `keyword` VARCHAR( 200 ) NOT NULL"; - $alters[] = "ALTER TABLE `$table` CHANGE `url` `url` TEXT NOT NULL"; - $alters[] = "ALTER TABLE `$table` DROP PRIMARY KEY"; + $alters = array(); + $results = array(); + $alters[] = "ALTER TABLE `$table` CHANGE `id` `keyword` VARCHAR( 200 ) NOT NULL"; + $alters[] = "ALTER TABLE `$table` CHANGE `url` `url` TEXT NOT NULL"; + $alters[] = "ALTER TABLE `$table` DROP PRIMARY KEY"; - foreach ( $alters as $query ) { - $ydb->perform( $query ); - } + foreach ( $alters as $query ) { + $ydb->perform( $query ); + } - echo "

Structure of existing tables updated. Please wait...

"; + echo "

Structure of existing tables updated. Please wait...

"; } /** @@ -354,19 +354,19 @@ function yourls_alter_url_table_to_14() { * */ function yourls_alter_url_table_to_14_part_two() { - $ydb = yourls_get_db(); - $table = YOURLS_DB_TABLE_URL; + $ydb = yourls_get_db(); + $table = YOURLS_DB_TABLE_URL; - $alters = array(); - $alters[] = "ALTER TABLE `$table` ADD PRIMARY KEY ( `keyword` )"; - $alters[] = "ALTER TABLE `$table` ADD INDEX ( `ip` )"; - $alters[] = "ALTER TABLE `$table` ADD INDEX ( `timestamp` )"; + $alters = array(); + $alters[] = "ALTER TABLE `$table` ADD PRIMARY KEY ( `keyword` )"; + $alters[] = "ALTER TABLE `$table` ADD INDEX ( `ip` )"; + $alters[] = "ALTER TABLE `$table` ADD INDEX ( `timestamp` )"; - foreach ( $alters as $query ) { - $ydb->perform( $query ); - } + foreach ( $alters as $query ) { + $ydb->perform( $query ); + } - echo "

New table index created

"; + echo "

New table index created

"; } /** @@ -374,52 +374,52 @@ function yourls_alter_url_table_to_14_part_two() { * */ function yourls_update_table_to_14() { - $ydb = yourls_get_db(); - $table = YOURLS_DB_TABLE_URL; - - // Modify each link to reflect new structure - $chunk = 45; - $from = isset($_GET['from']) ? intval( $_GET['from'] ) : 0 ; - $total = yourls_get_db_stats(); - $total = $total['total_links']; - - $sql = "SELECT `keyword`,`url` FROM `$table` WHERE 1=1 ORDER BY `url` ASC LIMIT $from, $chunk ;"; - - $rows = $ydb->fetchObjects($sql); - - $count = 0; - $queries = 0; - foreach( $rows as $row ) { - $keyword = $row->keyword; - $url = $row->url; - $newkeyword = yourls_int2string( $keyword ); - if( true === $ydb->perform("UPDATE `$table` SET `keyword` = '$newkeyword' WHERE `url` = '$url';") ) { - $queries++; - } else { - echo "

Huho... Could not update rown with url='$url', from keyword '$keyword' to keyword '$newkeyword'

"; // Find what went wrong :/ - } - $count++; - } - - // All done for this chunk of queries, did it all go as expected? - $success = true; - if( $count != $queries ) { - $success = false; - $num = $count - $queries; - echo "

$num error(s) occurred while updating the URL table :(

"; - } - - if ( $count == $chunk ) { - // there are probably other rows to convert - $from = $from + $chunk; - $remain = $total - $from; - echo "

Converted $chunk database rows ($remain remaining). Continuing... Please do not close this window until it's finished!

"; - yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200&from=$from" ), $success ); - } else { - // All done - echo '

All rows converted! Please wait...

'; - yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=3&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ), $success ); - } + $ydb = yourls_get_db(); + $table = YOURLS_DB_TABLE_URL; + + // Modify each link to reflect new structure + $chunk = 45; + $from = isset($_GET['from']) ? intval( $_GET['from'] ) : 0 ; + $total = yourls_get_db_stats(); + $total = $total['total_links']; + + $sql = "SELECT `keyword`,`url` FROM `$table` WHERE 1=1 ORDER BY `url` ASC LIMIT $from, $chunk ;"; + + $rows = $ydb->fetchObjects($sql); + + $count = 0; + $queries = 0; + foreach( $rows as $row ) { + $keyword = $row->keyword; + $url = $row->url; + $newkeyword = yourls_int2string( $keyword ); + if( true === $ydb->perform("UPDATE `$table` SET `keyword` = '$newkeyword' WHERE `url` = '$url';") ) { + $queries++; + } else { + echo "

Huho... Could not update rown with url='$url', from keyword '$keyword' to keyword '$newkeyword'

"; // Find what went wrong :/ + } + $count++; + } + + // All done for this chunk of queries, did it all go as expected? + $success = true; + if( $count != $queries ) { + $success = false; + $num = $count - $queries; + echo "

$num error(s) occurred while updating the URL table :(

"; + } + + if ( $count == $chunk ) { + // there are probably other rows to convert + $from = $from + $chunk; + $remain = $total - $from; + echo "

Converted $chunk database rows ($remain remaining). Continuing... Please do not close this window until it's finished!

"; + yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200&from=$from" ), $success ); + } else { + // All done + echo '

All rows converted! Please wait...

'; + yourls_redirect_javascript( yourls_admin_url( "upgrade.php?step=3&oldver=1.3&newver=1.4&oldsql=100&newsql=200" ), $success ); + } } @@ -428,26 +428,26 @@ function yourls_update_table_to_14() { * */ function yourls_clean_htaccess_for_14() { - $filename = YOURLS_ABSPATH.'/.htaccess'; - - $result = false; - if( is_writeable( $filename ) ) { - $contents = implode( '', file( $filename ) ); - // remove "ShortURL" block - $contents = preg_replace( '/# BEGIN ShortURL.*# END ShortURL/s', '', $contents ); - // comment out deprecated RewriteRule - $find = 'RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]'; - $replace = "# You can safely remove this 5 lines block -- it's no longer used in YOURLS\n". - "# $find"; - $contents = str_replace( $find, $replace, $contents ); - - // Write cleaned file - $f = fopen( $filename, 'w' ); - fwrite( $f, $contents ); - fclose( $f ); - - $result = true; - } - - return $result; + $filename = YOURLS_ABSPATH.'/.htaccess'; + + $result = false; + if( is_writeable( $filename ) ) { + $contents = implode( '', file( $filename ) ); + // remove "ShortURL" block + $contents = preg_replace( '/# BEGIN ShortURL.*# END ShortURL/s', '', $contents ); + // comment out deprecated RewriteRule + $find = 'RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]'; + $replace = "# You can safely remove this 5 lines block -- it's no longer used in YOURLS\n". + "# $find"; + $contents = str_replace( $find, $replace, $contents ); + + // Write cleaned file + $f = fopen( $filename, 'w' ); + fwrite( $f, $contents ); + fclose( $f ); + + $result = true; + } + + return $result; } diff --git a/includes/functions.php b/includes/functions.php index 138746a65..2d0609c40 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -22,22 +22,22 @@ function yourls_make_regexp_pattern( $string ) { * @return string */ function yourls_get_IP() { - $ip = ''; - - // Precedence: if set, X-Forwarded-For > HTTP_X_FORWARDED_FOR > HTTP_CLIENT_IP > HTTP_VIA > REMOTE_ADDR - $headers = [ 'X-Forwarded-For', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_VIA', 'REMOTE_ADDR' ]; - foreach( $headers as $header ) { - if ( !empty( $_SERVER[ $header ] ) ) { - $ip = $_SERVER[ $header ]; - break; - } - } - - // headers can contain multiple IPs (X-Forwarded-For = client, proxy1, proxy2). Take first one. - if ( strpos( $ip, ',' ) !== false ) - $ip = substr( $ip, 0, strpos( $ip, ',' ) ); - - return (string)yourls_apply_filter( 'get_IP', yourls_sanitize_ip( $ip ) ); + $ip = ''; + + // Precedence: if set, X-Forwarded-For > HTTP_X_FORWARDED_FOR > HTTP_CLIENT_IP > HTTP_VIA > REMOTE_ADDR + $headers = [ 'X-Forwarded-For', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_VIA', 'REMOTE_ADDR' ]; + foreach( $headers as $header ) { + if ( !empty( $_SERVER[ $header ] ) ) { + $ip = $_SERVER[ $header ]; + break; + } + } + + // headers can contain multiple IPs (X-Forwarded-For = client, proxy1, proxy2). Take first one. + if ( strpos( $ip, ',' ) !== false ) + $ip = substr( $ip, 0, strpos( $ip, ',' ) ); + + return (string)yourls_apply_filter( 'get_IP', yourls_sanitize_ip( $ip ) ); } /** @@ -47,7 +47,7 @@ function yourls_get_IP() { * @return int id of next link */ function yourls_get_next_decimal() { - return (int)yourls_apply_filter( 'get_next_decimal', (int)yourls_get_option( 'next_id' ) ); + return (int)yourls_apply_filter( 'get_next_decimal', (int)yourls_get_option( 'next_id' ) ); } /** @@ -64,10 +64,10 @@ function yourls_get_next_decimal() { * @return bool true or false depending on if there has been an actual MySQL query. See note above. */ function yourls_update_next_decimal( $int = 0 ) { - $int = ( $int == 0 ) ? yourls_get_next_decimal() + 1 : (int)$int ; - $update = yourls_update_option( 'next_id', $int ); - yourls_do_action( 'update_next_decimal', $int, $update ); - return $update; + $int = ( $int == 0 ) ? yourls_get_next_decimal() + 1 : (int)$int ; + $update = yourls_update_option( 'next_id', $int ); + yourls_do_action( 'update_next_decimal', $int, $update ); + return $update; } /** @@ -88,15 +88,15 @@ function yourls_xml_encode( $array ) { * @return int 0 or 1 for error/success */ function yourls_update_clicks( $keyword, $clicks = false ) { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_update_clicks', false, $keyword, $clicks ); - if ( false !== $pre ) { + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_update_clicks', false, $keyword, $clicks ); + if ( false !== $pre ) { return $pre; } - $keyword = yourls_sanitize_keyword( $keyword ); - $table = YOURLS_DB_TABLE_URL; - if ( $clicks !== false && is_int( $clicks ) && $clicks >= 0 ) { + $keyword = yourls_sanitize_keyword( $keyword ); + $table = YOURLS_DB_TABLE_URL; + if ( $clicks !== false && is_int( $clicks ) && $clicks >= 0 ) { $update = "UPDATE `$table` SET `clicks` = :clicks WHERE `keyword` = :keyword"; $values = [ 'clicks' => $clicks, 'keyword' => $keyword ]; } else { @@ -104,16 +104,16 @@ function yourls_update_clicks( $keyword, $clicks = false ) { $values = [ 'keyword' => $keyword ]; } - // Try and update click count. An error probably means a concurrency problem : just skip the update + // Try and update click count. An error probably means a concurrency problem : just skip the update try { $result = yourls_get_db()->fetchAffected($update, $values); } catch (Exception $e) { - $result = 0; + $result = 0; } - yourls_do_action( 'update_clicks', $keyword, $result, $clicks ); + yourls_do_action( 'update_clicks', $keyword, $result, $clicks ); - return $result; + return $result; } @@ -126,55 +126,55 @@ function yourls_update_clicks( $keyword, $clicks = false ) { * @return array Array of links */ function yourls_get_stats($filter = 'top', $limit = 10, $start = 0) { - switch( $filter ) { - case 'bottom': - $sort_by = '`clicks`'; - $sort_order = 'asc'; - break; - case 'last': - $sort_by = '`timestamp`'; - $sort_order = 'desc'; - break; - case 'rand': - case 'random': - $sort_by = 'RAND()'; - $sort_order = ''; - break; - case 'top': - default: - $sort_by = '`clicks`'; - $sort_order = 'desc'; - break; - } - - // Fetch links - $limit = intval( $limit ); - $start = intval( $start ); - if ( $limit > 0 ) { - - $table_url = YOURLS_DB_TABLE_URL; - $results = yourls_get_db()->fetchObjects( "SELECT * FROM `$table_url` WHERE 1=1 ORDER BY $sort_by $sort_order LIMIT $start, $limit;" ); - - $return = []; - $i = 1; - - foreach ( (array)$results as $res ) { - $return['links']['link_'.$i++] = [ - 'shorturl' => yourls_link($res->keyword), - 'url' => $res->url, - 'title' => $res->title, - 'timestamp'=> $res->timestamp, - 'ip' => $res->ip, - 'clicks' => $res->clicks, + switch( $filter ) { + case 'bottom': + $sort_by = '`clicks`'; + $sort_order = 'asc'; + break; + case 'last': + $sort_by = '`timestamp`'; + $sort_order = 'desc'; + break; + case 'rand': + case 'random': + $sort_by = 'RAND()'; + $sort_order = ''; + break; + case 'top': + default: + $sort_by = '`clicks`'; + $sort_order = 'desc'; + break; + } + + // Fetch links + $limit = intval( $limit ); + $start = intval( $start ); + if ( $limit > 0 ) { + + $table_url = YOURLS_DB_TABLE_URL; + $results = yourls_get_db()->fetchObjects( "SELECT * FROM `$table_url` WHERE 1=1 ORDER BY $sort_by $sort_order LIMIT $start, $limit;" ); + + $return = []; + $i = 1; + + foreach ( (array)$results as $res ) { + $return['links']['link_'.$i++] = [ + 'shorturl' => yourls_link($res->keyword), + 'url' => $res->url, + 'title' => $res->title, + 'timestamp'=> $res->timestamp, + 'ip' => $res->ip, + 'clicks' => $res->clicks, ]; - } - } + } + } - $return['stats'] = yourls_get_db_stats(); + $return['stats'] = yourls_get_db_stats(); - $return['statusCode'] = 200; + $return['statusCode'] = '200'; - return yourls_apply_filter( 'get_stats', $return, $filter, $limit, $start ); + return yourls_apply_filter( 'get_stats', $return, $filter, $limit, $start ); } /** @@ -188,12 +188,12 @@ function yourls_get_stats($filter = 'top', $limit = 10, $start = 0) { * @return array */ function yourls_get_db_stats( $where = [ 'sql' => '', 'binds' => [] ] ) { - $table_url = YOURLS_DB_TABLE_URL; + $table_url = YOURLS_DB_TABLE_URL; - $totals = yourls_get_db()->fetchObject( "SELECT COUNT(keyword) as count, SUM(clicks) as sum FROM `$table_url` WHERE 1=1 " . $where['sql'] , $where['binds'] ); - $return = [ 'total_links' => $totals->count, 'total_clicks' => $totals->sum ]; + $totals = yourls_get_db()->fetchObject( "SELECT COUNT(keyword) as count, SUM(clicks) as sum FROM `$table_url` WHERE 1=1 " . $where['sql'] , $where['binds'] ); + $return = [ 'total_links' => $totals->count, 'total_clicks' => $totals->sum ]; - return yourls_apply_filter( 'get_db_stats', $return, $where ); + return yourls_apply_filter( 'get_db_stats', $return, $where ); } /** @@ -239,25 +239,25 @@ function yourls_get_referrer() { * @return int 1 for header redirection, 2 for js redirection, 3 otherwise (CLI) */ function yourls_redirect( $location, $code = 301 ) { - yourls_do_action( 'pre_redirect', $location, $code ); - $location = yourls_apply_filter( 'redirect_location', $location, $code ); - $code = yourls_apply_filter( 'redirect_code', $code, $location ); - - // Redirect, either properly if possible, or via Javascript otherwise - if( !headers_sent() ) { - yourls_status_header( $code ); - header( "Location: $location" ); + yourls_do_action( 'pre_redirect', $location, $code ); + $location = yourls_apply_filter( 'redirect_location', $location, $code ); + $code = yourls_apply_filter( 'redirect_code', $code, $location ); + + // Redirect, either properly if possible, or via Javascript otherwise + if( !headers_sent() ) { + yourls_status_header( $code ); + header( "Location: $location" ); return 1; - } + } - // Headers sent : redirect with JS if not in CLI - if( php_sapi_name() !== 'cli') { + // Headers sent : redirect with JS if not in CLI + if( php_sapi_name() !== 'cli') { yourls_redirect_javascript( $location ); return 2; - } + } - // We're in CLI - return 3; + // We're in CLI + return 3; } /** @@ -355,12 +355,12 @@ function yourls_no_frame_header() { */ function yourls_content_type_header( $type ) { yourls_do_action( 'content_type_header', $type ); - if( !headers_sent() ) { - $charset = yourls_apply_filter( 'content_type_header_charset', 'utf-8' ); - header( "Content-Type: $type; charset=$charset" ); - return true; - } - return false; + if( !headers_sent() ) { + $charset = yourls_apply_filter( 'content_type_header_charset', 'utf-8' ); + header( "Content-Type: $type; charset=$charset" ); + return true; + } + return false; } /** @@ -371,19 +371,19 @@ function yourls_content_type_header( $type ) { * @return bool whether header was sent */ function yourls_status_header( $code = 200 ) { - yourls_do_action( 'status_header', $code ); + yourls_do_action( 'status_header', $code ); - if( headers_sent() ) - return false; + if( headers_sent() ) + return false; - $protocol = $_SERVER['SERVER_PROTOCOL']; - if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol ) - $protocol = 'HTTP/1.0'; + $protocol = $_SERVER['SERVER_PROTOCOL']; + if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol ) + $protocol = 'HTTP/1.0'; - $code = intval( $code ); - $desc = yourls_get_HTTP_status( $code ); + $code = intval( $code ); + $desc = yourls_get_HTTP_status( $code ); - @header ("$protocol $code $desc"); // This causes problems on IIS and some FastCGI setups + @header ("$protocol $code $desc"); // This causes problems on IIS and some FastCGI setups return true; } @@ -402,10 +402,10 @@ function yourls_redirect_javascript( $location, $dontwait = true ) { if ( $dontwait ) { $message = yourls_s( 'if you are not redirected after 10 seconds, please click here', $location ); echo << - window.location="$location"; - - ($message) + + ($message) REDIR; } else { @@ -421,63 +421,63 @@ function yourls_redirect_javascript( $location, $dontwait = true ) { * @return string */ function yourls_get_HTTP_status( $code ) { - $code = intval( $code ); - $headers_desc = [ - 100 => 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-Status', - 226 => 'IM Used', - - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 306 => 'Reserved', - 307 => 'Temporary Redirect', - - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 424 => 'Failed Dependency', - 426 => 'Upgrade Required', - - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates', - 507 => 'Insufficient Storage', - 510 => 'Not Extended' + $code = intval( $code ); + $headers_desc = [ + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 226 => 'IM Used', + + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => 'Reserved', + 307 => 'Temporary Redirect', + + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 426 => 'Upgrade Required', + + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates', + 507 => 'Insufficient Storage', + 510 => 'Not Extended' ]; return $headers_desc[$code] ?? ''; @@ -494,17 +494,17 @@ function yourls_get_HTTP_status( $code ) { * @return mixed Result of the INSERT query (1 on success) */ function yourls_log_redirect( $keyword ) { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_log_redirect', false, $keyword ); - if ( false !== $pre ) { + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_log_redirect', false, $keyword ); + if ( false !== $pre ) { return $pre; } - if (!yourls_do_log_redirect()) { + if (!yourls_do_log_redirect()) { return true; } - $table = YOURLS_DB_TABLE_LOG; + $table = YOURLS_DB_TABLE_LOG; $ip = yourls_get_IP(); $binds = [ 'now' => date( 'Y-m-d H:i:s' ), @@ -531,7 +531,7 @@ function yourls_log_redirect( $keyword ) { * @return bool */ function yourls_do_log_redirect() { - return ( !defined( 'YOURLS_NOSTATS' ) || YOURLS_NOSTATS != true ); + return ( !defined( 'YOURLS_NOSTATS' ) || YOURLS_NOSTATS != true ); } /** @@ -622,54 +622,54 @@ function yourls_allow_duplicate_longurls() { */ function yourls_check_IP_flood( $ip = '' ) { - // Allow plugins to short-circuit the whole function - $pre = yourls_apply_filter( 'shunt_check_IP_flood', false, $ip ); - if ( false !== $pre ) - return $pre; - - yourls_do_action( 'pre_check_ip_flood', $ip ); // at this point $ip can be '', check it if your plugin hooks in here - - // Raise white flag if installing or if no flood delay defined - if( - ( defined('YOURLS_FLOOD_DELAY_SECONDS') && YOURLS_FLOOD_DELAY_SECONDS === 0 ) || - !defined('YOURLS_FLOOD_DELAY_SECONDS') || - yourls_is_installing() - ) - return true; - - // Don't throttle logged in users - if( yourls_is_private() ) { - if( yourls_is_valid_user() === true ) - return true; - } - - // Don't throttle whitelist IPs - if( defined( 'YOURLS_FLOOD_IP_WHITELIST' ) && YOURLS_FLOOD_IP_WHITELIST ) { - $whitelist_ips = explode( ',', YOURLS_FLOOD_IP_WHITELIST ); - foreach( (array)$whitelist_ips as $whitelist_ip ) { - $whitelist_ip = trim( $whitelist_ip ); - if ( $whitelist_ip == $ip ) - return true; - } - } - - $ip = ( $ip ? yourls_sanitize_ip( $ip ) : yourls_get_IP() ); - - yourls_do_action( 'check_ip_flood', $ip ); - - $table = YOURLS_DB_TABLE_URL; - $lasttime = yourls_get_db()->fetchValue( "SELECT `timestamp` FROM $table WHERE `ip` = :ip ORDER BY `timestamp` DESC LIMIT 1", [ 'ip' => $ip ] ); - if( $lasttime ) { - $now = date( 'U' ); - $then = date( 'U', strtotime( $lasttime ) ); - if( ( $now - $then ) <= YOURLS_FLOOD_DELAY_SECONDS ) { - // Flood! - yourls_do_action( 'ip_flood', $ip, $now - $then ); - yourls_die( yourls__( 'Too many URLs added too fast. Slow down please.' ), yourls__( 'Too Many Requests' ), 429 ); - } - } - - return true; + // Allow plugins to short-circuit the whole function + $pre = yourls_apply_filter( 'shunt_check_IP_flood', false, $ip ); + if ( false !== $pre ) + return $pre; + + yourls_do_action( 'pre_check_ip_flood', $ip ); // at this point $ip can be '', check it if your plugin hooks in here + + // Raise white flag if installing or if no flood delay defined + if( + ( defined('YOURLS_FLOOD_DELAY_SECONDS') && YOURLS_FLOOD_DELAY_SECONDS === 0 ) || + !defined('YOURLS_FLOOD_DELAY_SECONDS') || + yourls_is_installing() + ) + return true; + + // Don't throttle logged in users + if( yourls_is_private() ) { + if( yourls_is_valid_user() === true ) + return true; + } + + // Don't throttle whitelist IPs + if( defined( 'YOURLS_FLOOD_IP_WHITELIST' ) && YOURLS_FLOOD_IP_WHITELIST ) { + $whitelist_ips = explode( ',', YOURLS_FLOOD_IP_WHITELIST ); + foreach( (array)$whitelist_ips as $whitelist_ip ) { + $whitelist_ip = trim( $whitelist_ip ); + if ( $whitelist_ip == $ip ) + return true; + } + } + + $ip = ( $ip ? yourls_sanitize_ip( $ip ) : yourls_get_IP() ); + + yourls_do_action( 'check_ip_flood', $ip ); + + $table = YOURLS_DB_TABLE_URL; + $lasttime = yourls_get_db()->fetchValue( "SELECT `timestamp` FROM $table WHERE `ip` = :ip ORDER BY `timestamp` DESC LIMIT 1", [ 'ip' => $ip ] ); + if( $lasttime ) { + $now = date( 'U' ); + $then = date( 'U', strtotime( $lasttime ) ); + if( ( $now - $then ) <= YOURLS_FLOOD_DELAY_SECONDS ) { + // Flood! + yourls_do_action( 'ip_flood', $ip, $now - $then ); + yourls_die( yourls__( 'Too many URLs added too fast. Slow down please.' ), yourls__( 'Too Many Requests' ), 429 ); + } + } + + return true; } /** @@ -679,7 +679,7 @@ function yourls_check_IP_flood( $ip = '' ) { * @return bool */ function yourls_is_installing() { - return (bool)yourls_apply_filter( 'is_installing', defined( 'YOURLS_INSTALLING' ) && YOURLS_INSTALLING ); + return (bool)yourls_apply_filter( 'is_installing', defined( 'YOURLS_INSTALLING' ) && YOURLS_INSTALLING ); } /** @@ -702,7 +702,7 @@ function yourls_is_upgrading() { * @return bool */ function yourls_is_installed() { - return (bool)yourls_apply_filter( 'is_installed', yourls_get_db()->is_installed() ); + return (bool)yourls_apply_filter( 'is_installed', yourls_get_db()->is_installed() ); } /** @@ -822,7 +822,7 @@ function yourls_is_admin() { * @return bool */ function yourls_is_windows() { - return defined( 'DIRECTORY_SEPARATOR' ) && DIRECTORY_SEPARATOR == '\\'; + return defined( 'DIRECTORY_SEPARATOR' ) && DIRECTORY_SEPARATOR == '\\'; } /** @@ -952,22 +952,22 @@ function yourls_get_remote_title( $url ) { * @return bool */ function yourls_is_mobile_device() { - // Strings searched - $mobiles = [ - 'android', 'blackberry', 'blazer', - 'compal', 'elaine', 'fennec', 'hiptop', - 'iemobile', 'iphone', 'ipod', 'ipad', - 'iris', 'kindle', 'opera mobi', 'opera mini', - 'palm', 'phone', 'pocket', 'psp', 'symbian', - 'treo', 'wap', 'windows ce', 'windows phone' + // Strings searched + $mobiles = [ + 'android', 'blackberry', 'blazer', + 'compal', 'elaine', 'fennec', 'hiptop', + 'iemobile', 'iphone', 'ipod', 'ipad', + 'iris', 'kindle', 'opera mobi', 'opera mini', + 'palm', 'phone', 'pocket', 'psp', 'symbian', + 'treo', 'wap', 'windows ce', 'windows phone' ]; - // Current user-agent - $current = strtolower( $_SERVER['HTTP_USER_AGENT'] ); + // Current user-agent + $current = strtolower( $_SERVER['HTTP_USER_AGENT'] ); - // Check and return - $is_mobile = ( str_replace( $mobiles, '', $current ) != $current ); - return (bool)yourls_apply_filter( 'is_mobile_device', $is_mobile ); + // Check and return + $is_mobile = ( str_replace( $mobiles, '', $current ) != $current ); + return (bool)yourls_apply_filter( 'is_mobile_device', $is_mobile ); } /** @@ -1091,20 +1091,20 @@ function yourls_fix_request_uri() { * @return void */ function yourls_check_maintenance_mode() { - $dot_file = YOURLS_ABSPATH . '/.maintenance' ; + $dot_file = YOURLS_ABSPATH . '/.maintenance' ; if ( !file_exists( $dot_file ) || yourls_is_upgrading() || yourls_is_installing() ) { return; } - global $maintenance_start; - yourls_include_file_sandbox( $dot_file ); - // If the $maintenance_start timestamp is older than 10 minutes, don't die. - if ( ( time() - $maintenance_start ) >= 600 ) { + global $maintenance_start; + yourls_include_file_sandbox( $dot_file ); + // If the $maintenance_start timestamp is older than 10 minutes, don't die. + if ( ( time() - $maintenance_start ) >= 600 ) { return; } - // Use any /user/maintenance.php file + // Use any /user/maintenance.php file $file = YOURLS_USERDIR . '/maintenance.php'; if(file_exists($file)) { if(yourls_include_file_sandbox( $file ) == true) { @@ -1158,15 +1158,15 @@ function yourls_is_allowed_protocol( $url, $protocols = [] ) { * @return string Protocol, with slash slash if applicable. Empty string if no protocol */ function yourls_get_protocol( $url ) { - /* - http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax - The scheme name consists of a sequence of characters beginning with a letter and followed by any - combination of letters, digits, plus ("+"), period ("."), or hyphen ("-"). Although schemes are - case-insensitive, the canonical form is lowercase and documents that specify schemes must do so - with lowercase letters. It is followed by a colon (":"). - */ + /* + http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax + The scheme name consists of a sequence of characters beginning with a letter and followed by any + combination of letters, digits, plus ("+"), period ("."), or hyphen ("-"). Although schemes are + case-insensitive, the canonical form is lowercase and documents that specify schemes must do so + with lowercase letters. It is followed by a colon (":"). + */ preg_match( '!^[a-zA-Z][a-zA-Z0-9+.-]+:(//)?!', $url, $matches ); - return (string)yourls_apply_filter( 'get_protocol', isset( $matches[0] ) ? $matches[0] : '', $url ); + return (string)yourls_apply_filter( 'get_protocol', isset( $matches[0] ) ? $matches[0] : '', $url ); } /** @@ -1219,15 +1219,15 @@ function yourls_get_relative_url( $url, $strict = true ) { */ function yourls_deprecated_function( $function, $version, $replacement = null ) { - yourls_do_action( 'deprecated_function', $function, $replacement, $version ); + yourls_do_action( 'deprecated_function', $function, $replacement, $version ); - // Allow plugin to filter the output error trigger - if ( yourls_get_debug_mode() && yourls_apply_filter( 'deprecated_function_trigger_error', true ) ) { - if ( ! is_null( $replacement ) ) - trigger_error( sprintf( yourls__('%1$s is deprecated since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) ); - else - trigger_error( sprintf( yourls__('%1$s is deprecated since version %2$s with no alternative available.'), $function, $version ) ); - } + // Allow plugin to filter the output error trigger + if ( yourls_get_debug_mode() && yourls_apply_filter( 'deprecated_function_trigger_error', true ) ) { + if ( ! is_null( $replacement ) ) + trigger_error( sprintf( yourls__('%1$s is deprecated since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) ); + else + trigger_error( sprintf( yourls__('%1$s is deprecated since version %2$s with no alternative available.'), $function, $version ) ); + } } /** @@ -1313,7 +1313,7 @@ function yourls_tell_if_new_version() { function yourls_include_file_sandbox($file) { try { if (is_readable( $file )) { - include_once $file; + require_once $file; yourls_debug_log("loaded $file"); return true; } diff --git a/includes/geo/COPYRIGHT.txt b/includes/geo/COPYRIGHT.txt index 6a82b38a3..7076361ff 100644 --- a/includes/geo/COPYRIGHT.txt +++ b/includes/geo/COPYRIGHT.txt @@ -1 +1 @@ -Database and Contents Copyright (c) 2023 MaxMind, Inc. +Database and Contents Copyright (c) 2025 MaxMind, Inc. diff --git a/includes/geo/GeoLite2-Country.mmdb b/includes/geo/GeoLite2-Country.mmdb index c818ebcd6..bb9cf15ac 100644 Binary files a/includes/geo/GeoLite2-Country.mmdb and b/includes/geo/GeoLite2-Country.mmdb differ diff --git a/includes/vendor/aura/sql/README.md b/includes/vendor/aura/sql/README.md index c7e707578..3dbdee976 100644 --- a/includes/vendor/aura/sql/README.md +++ b/includes/vendor/aura/sql/README.md @@ -54,8 +54,8 @@ Alternatively, [download a release][], or clone this repository, then map the ## Dependencies -This package requires PHP 5.6 or later; it has also been tested on PHP 7 and -HHVM. We recommend using the latest available version of PHP as a matter of +This package requires PHP 8.1 or later; it has also been tested on PHP 8.1-8.2. +We recommend using the latest available version of PHP as a matter of principle. Aura library packages may sometimes depend on external interfaces, but never on @@ -65,9 +65,9 @@ without compromising flexibility. For specifics, please examine the package ## Quality -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/badges/quality-score.png?b=3.x)](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/) -[![Code Coverage](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/badges/coverage.png?b=3.x)](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/) -[![Build Status](https://travis-ci.org/auraphp/Aura.Sql.png?branch=3.x)](https://travis-ci.org/auraphp/Aura.Sql) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/) +[![Code Coverage](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/badges/coverage.png?b=5.x)](https://scrutinizer-ci.com/g/auraphp/Aura.Sql/) +[![Build Status](https://github.com/auraphp/Aura.Sql/actions/workflows/continuous-integration.yml/badge.svg?branch=5.x)](https://github.com/auraphp/Aura.Sql/actions/workflows/continuous-integration.yml) [![PDS Skeleton](https://img.shields.io/badge/pds-skeleton-blue.svg?style=flat-square)](https://github.com/php-pds/skeleton) This project adheres to [Semantic Versioning](http://semver.org/). diff --git a/includes/vendor/aura/sql/src/AbstractExtendedPdo.php b/includes/vendor/aura/sql/src/AbstractExtendedPdo.php index 604d0c292..3b73af32d 100644 --- a/includes/vendor/aura/sql/src/AbstractExtendedPdo.php +++ b/includes/vendor/aura/sql/src/AbstractExtendedPdo.php @@ -8,10 +8,10 @@ */ namespace Aura\Sql; -use Aura\Sql\Exception; use Aura\Sql\Parser\ParserInterface; use Aura\Sql\Profiler\ProfilerInterface; use BadMethodCallException; +use Generator; use PDO; use PDOStatement; @@ -29,10 +29,10 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * * The internal PDO connection. * - * @var PDO + * @var PDO|null * */ - protected $pdo; + protected ?PDO $pdo = null; /** * @@ -41,7 +41,7 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @var ProfilerInterface * */ - protected $profiler; + protected ProfilerInterface $profiler; /** * @@ -50,7 +50,7 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @var ParserInterface * */ - protected $parser; + protected ParserInterface $parser; /** * @@ -59,7 +59,7 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @var string * */ - protected $quoteNamePrefix = '"'; + protected string $quoteNamePrefix = '"'; /** * @@ -68,7 +68,7 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @var string * */ - protected $quoteNameSuffix = '"'; + protected string $quoteNameSuffix = '"'; /** * @@ -77,7 +77,7 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @var string * */ - protected $quoteNameEscapeFind = '"'; + protected string $quoteNameEscapeFind = '"'; /** * @@ -86,7 +86,7 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @var string * */ - protected $quoteNameEscapeRepl = '""'; + protected string $quoteNameEscapeRepl = '""'; /** * @@ -103,13 +103,13 @@ abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface * @throws BadMethodCallException when the method does not exist. * */ - public function __call($name, array $arguments) + public function __call(string $name, array $arguments) { - $this->connect(); + $this->lazyConnect(); if (! method_exists($this->pdo, $name)) { $class = get_class($this); - $message = "Class '{$class}' does not have a method '{$name}'"; + $message = "Class '$class' does not have a method '$name'"; throw new BadMethodCallException($message); } @@ -125,10 +125,9 @@ public function __call($name, array $arguments) * @see http://php.net/manual/en/pdo.begintransaction.php * */ - #[\ReturnTypeWillChange] - public function beginTransaction() + public function beginTransaction(): bool { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); $result = $this->pdo->beginTransaction(); $this->profiler->finish(); @@ -144,10 +143,9 @@ public function beginTransaction() * @see http://php.net/manual/en/pdo.commit.php * */ - #[\ReturnTypeWillChange] - public function commit() + public function commit(): bool { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); $result = $this->pdo->commit(); $this->profiler->finish(); @@ -158,31 +156,28 @@ public function commit() * * Connects to the database. * - * @return null - * + * @return void */ - abstract public function connect(); + abstract public function lazyConnect(): void; /** * * Disconnects from the database. * - * @return null - * + * @return void */ - abstract public function disconnect(); + abstract public function disconnect(): void; /** * * Gets the most recent error code. * - * @return string + * @return string|null * */ - #[\ReturnTypeWillChange] - public function errorCode() + public function errorCode(): ?string { - $this->connect(); + $this->lazyConnect(); return $this->pdo->errorCode(); } @@ -193,10 +188,9 @@ public function errorCode() * @return array * */ - #[\ReturnTypeWillChange] - public function errorInfo() + public function errorInfo(): array { - $this->connect(); + $this->lazyConnect(); return $this->pdo->errorInfo(); } @@ -211,10 +205,9 @@ public function errorInfo() * @see http://php.net/manual/en/pdo.exec.php * */ - #[\ReturnTypeWillChange] - public function exec($statement) + public function exec(string $statement): int|false { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); $affectedRows = $this->pdo->exec($statement); $this->profiler->finish($statement); @@ -232,7 +225,7 @@ public function exec($statement) * @return int * */ - public function fetchAffected($statement, array $values = []) + public function fetchAffected(string $statement, array $values = []): int { $sth = $this->perform($statement, $values); return $sth->rowCount(); @@ -250,7 +243,7 @@ public function fetchAffected($statement, array $values = []) * @return array * */ - public function fetchAll($statement, array $values = []) + public function fetchAll(string $statement, array $values = []): array { $sth = $this->perform($statement, $values); return $sth->fetchAll(self::FETCH_ASSOC); @@ -272,7 +265,7 @@ public function fetchAll($statement, array $values = []) * @return array * */ - public function fetchAssoc($statement, array $values = []) + public function fetchAssoc(string $statement, array $values = []): array { $sth = $this->perform($statement, $values); $data = []; @@ -293,7 +286,7 @@ public function fetchAssoc($statement, array $values = []) * @return array * */ - public function fetchCol($statement, array $values = []) + public function fetchCol(string $statement, array $values = []): array { $sth = $this->perform($statement, $values); return $sth->fetchAll(self::FETCH_COLUMN, 0); @@ -315,10 +308,10 @@ public function fetchCol($statement, array $values = []) * */ public function fetchGroup( - $statement, + string $statement, array $values = [], - $style = PDO::FETCH_COLUMN - ) { + int $style = PDO::FETCH_COLUMN + ): array { $sth = $this->perform($statement, $values); return $sth->fetchAll(self::FETCH_GROUP | $style); } @@ -343,15 +336,15 @@ public function fetchGroup( * * @param array $args Arguments to pass to the object constructor. * - * @return object|false + * @return object * */ public function fetchObject( - $statement, + string $statement, array $values = [], - $class = 'stdClass', + string $class = 'stdClass', array $args = [] - ) { + ): object|false { $sth = $this->perform($statement, $values); if (! empty($args)) { @@ -387,11 +380,11 @@ public function fetchObject( * */ public function fetchObjects( - $statement, + string $statement, array $values = [], - $class = 'stdClass', + string $class = 'stdClass', array $args = [] - ) { + ): array { $sth = $this->perform($statement, $values); if (! empty($args)) { @@ -409,10 +402,10 @@ public function fetchObjects( * * @param array $values Values to bind to the query. * - * @return array + * @return array|false * */ - public function fetchOne($statement, array $values = []) + public function fetchOne(string $statement, array $values = []): array|false { $sth = $this->perform($statement, $values); return $sth->fetch(self::FETCH_ASSOC); @@ -430,7 +423,7 @@ public function fetchOne($statement, array $values = []) * @return array * */ - public function fetchPairs($statement, array $values = []) + public function fetchPairs(string $statement, array $values = []): array { $sth = $this->perform($statement, $values); return $sth->fetchAll(self::FETCH_KEY_PAIR); @@ -447,7 +440,7 @@ public function fetchPairs($statement, array $values = []) * @return mixed * */ - public function fetchValue($statement, array $values = []) + public function fetchValue(string $statement, array $values = []): mixed { $sth = $this->perform($statement, $values); return $sth->fetchColumn(0); @@ -460,7 +453,7 @@ public function fetchValue($statement, array $values = []) * @return ParserInterface * */ - public function getParser() + public function getParser(): ParserInterface { return $this->parser; } @@ -472,7 +465,7 @@ public function getParser() * @return \PDO * */ - public function getPdo() + public function getPdo(): PDO { return $this->pdo; } @@ -484,7 +477,7 @@ public function getPdo() * @return ProfilerInterface * */ - public function getProfiler() + public function getProfiler(): ProfilerInterface { return $this->profiler; } @@ -498,10 +491,9 @@ public function getProfiler() * @see http://php.net/manual/en/pdo.intransaction.php * */ - #[\ReturnTypeWillChange] - public function inTransaction() + public function inTransaction(): bool { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); $result = $this->pdo->inTransaction(); $this->profiler->finish(); @@ -515,7 +507,7 @@ public function inTransaction() * @return bool * */ - public function isConnected() + public function isConnected(): bool { return (bool) $this->pdo; } @@ -524,18 +516,16 @@ public function isConnected() * * Returns the last inserted autoincrement sequence value. * - * @param string $name The name of the sequence to check; typically needed + * @param string|null $name The name of the sequence to check; typically needed * only for PostgreSQL, where it takes the form of `__seq`. * * @return string|false * * @see http://php.net/manual/en/pdo.lastinsertid.php - * */ - #[\ReturnTypeWillChange] - public function lastInsertId($name = null) + public function lastInsertId(?string $name = null): string|false { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); $result = $this->pdo->lastInsertId($name); $this->profiler->finish(); @@ -554,12 +544,13 @@ public function lastInsertId($name = null) * * @return PDOStatement * + * @throws \Aura\Sql\Exception\CannotBindValue * @see quote() * */ - public function perform($statement, array $values = []) + public function perform(string $statement, array $values = []): PDOStatement { - $this->connect(); + $this->lazyConnect(); $sth = $this->prepareWithValues($statement, $values); $this->profiler->start(__FUNCTION__); $sth->execute(); @@ -571,7 +562,7 @@ public function perform($statement, array $values = []) * * Prepares an SQL statement for execution. * - * @param string $statement The SQL statement to prepare for execution. + * @param string $query The SQL statement to prepare for execution. * * @param array $options Set these attributes on the returned * PDOStatement. @@ -581,11 +572,10 @@ public function perform($statement, array $values = []) * @see http://php.net/manual/en/pdo.prepare.php * */ - #[\ReturnTypeWillChange] - public function prepare($statement, $options = []) + public function prepare(string $query, array $options = []): PDOStatement|false { - $this->connect(); - $sth = $this->pdo->prepare($statement, $options); + $this->lazyConnect(); + $sth = $this->pdo->prepare($query, $options); return $sth; } @@ -606,12 +596,13 @@ public function prepare($statement, $options = []) * * @param array $values The values to bind to the statement, if any. * - * @return PDOStatement|false + * @return PDOStatement * + * @throws \Aura\Sql\Exception\CannotBindValue * @see http://php.net/manual/en/pdo.prepare.php * */ - public function prepareWithValues($statement, array $values = []) + public function prepareWithValues(string $statement, array $values = []): PDOStatement { // if there are no values to bind ... if (empty($values)) { @@ -619,11 +610,11 @@ public function prepareWithValues($statement, array $values = []) return $this->prepare($statement); } - $this->connect(); + $this->lazyConnect(); // rebuild the statement and values $parser = clone $this->parser; - list ($statement, $values) = $parser->rebuild($statement, $values); + list($statement, $values) = $parser->rebuild($statement, $values); // prepare the statement $sth = $this->pdo->prepare($statement); @@ -641,21 +632,22 @@ public function prepareWithValues($statement, array $values = []) * * Queries the database and returns a PDOStatement. * - * @param string $statement The SQL statement to prepare and execute. + * @param string $query The SQL statement to prepare and execute. + * + * @param int|null $fetchMode * - * @param mixed ...$fetch Optional fetch-related parameters. + * @param mixed ...$fetch_mode_args Optional fetch-related parameters. * * @return PDOStatement|false * * @see http://php.net/manual/en/pdo.query.php * */ - #[\ReturnTypeWillChange] - public function query($statement, ...$fetch) + public function query(string $query, ?int $fetchMode = null, mixed ...$fetch_mode_args): PDOStatement|false { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); - $sth = $this->pdo->query($statement, ...$fetch); + $sth = $this->pdo->query($query, $fetchMode, ...$fetch_mode_args); $this->profiler->finish($sth->queryString); return $sth; } @@ -667,23 +659,24 @@ public function query($statement, ...$fetch) * This differs from `PDO::quote()` in that it will convert an array into * a string of comma-separated quoted values. * - * @param mixed $value The value to quote. + * @param string|int|array|float|null $value The value to quote. * * @param int $type A data type hint for the database driver. * - * @return string|false The quoted value. + * @return string|false The quoted value or false if the driver does not support quoting in this way. * * @see http://php.net/manual/en/pdo.quote.php * */ - #[\ReturnTypeWillChange] - public function quote($value, $type = self::PARAM_STR) + public function quote(string|int|array|float|null $value, int $type = self::PARAM_STR): string|false { - $this->connect(); + $this->lazyConnect(); + + $value = $value ?? ""; // non-array quoting if (! is_array($value)) { - return $this->pdo->quote((string) $value, $type); + return $this->pdo->quote($value, $type); } // quote array values, not keys, then combine with commas @@ -702,9 +695,9 @@ public function quote($value, $type = self::PARAM_STR) * @return string The multi-part identifier name, quoted. * */ - public function quoteName($name) + public function quoteName(string $name): string { - if (strpos($name, '.') === false) { + if (! str_contains($name, '.')) { return $this->quoteSingleName($name); } @@ -726,7 +719,7 @@ public function quoteName($name) * @return string The quoted identifier name. * */ - public function quoteSingleName($name) + public function quoteSingleName(string $name): string { $name = str_replace( $this->quoteNameEscapeFind, @@ -747,10 +740,9 @@ public function quoteSingleName($name) * @see http://php.net/manual/en/pdo.rollback.php * */ - #[\ReturnTypeWillChange] - public function rollBack() + public function rollBack(): bool { - $this->connect(); + $this->lazyConnect(); $this->profiler->start(__FUNCTION__); $result = $this->pdo->rollBack(); $this->profiler->finish(); @@ -764,7 +756,7 @@ public function rollBack() * @param ParserInterface $parser The Parser instance. * */ - public function setParser(ParserInterface $parser) + public function setParser(ParserInterface $parser): void { $this->parser = $parser; } @@ -776,7 +768,7 @@ public function setParser(ParserInterface $parser) * @param ProfilerInterface $profiler The Profiler instance. * */ - public function setProfiler(ProfilerInterface $profiler) + public function setProfiler(ProfilerInterface $profiler): void { $this->profiler = $profiler; } @@ -792,7 +784,7 @@ public function setProfiler(ProfilerInterface $profiler) * @return \Generator * */ - public function yieldAll($statement, array $values = []) + public function yieldAll(string $statement, array $values = []): Generator { $sth = $this->perform($statement, $values); while ($row = $sth->fetch(self::FETCH_ASSOC)) { @@ -811,7 +803,7 @@ public function yieldAll($statement, array $values = []) * @return \Generator * */ - public function yieldAssoc($statement, array $values = []) + public function yieldAssoc(string $statement, array $values = []): Generator { $sth = $this->perform($statement, $values); while ($row = $sth->fetch(self::FETCH_ASSOC)) { @@ -831,7 +823,7 @@ public function yieldAssoc($statement, array $values = []) * @return \Generator * */ - public function yieldCol($statement, array $values = []) + public function yieldCol(string $statement, array $values = []): Generator { $sth = $this->perform($statement, $values); while ($row = $sth->fetch(self::FETCH_NUM)) { @@ -862,11 +854,11 @@ public function yieldCol($statement, array $values = []) * */ public function yieldObjects( - $statement, + string $statement, array $values = [], - $class = 'stdClass', + string $class = 'stdClass', array $args = [] - ) { + ): Generator { $sth = $this->perform($statement, $values); if (empty($args)) { @@ -892,7 +884,7 @@ public function yieldObjects( * @return \Generator * */ - public function yieldPairs($statement, array $values = []) + public function yieldPairs(string $statement, array $values = []): Generator { $sth = $this->perform($statement, $values); while ($row = $sth->fetch(self::FETCH_NUM)) { @@ -910,13 +902,13 @@ public function yieldPairs($statement, array $values = []) * * @param mixed $val The value to bind to the statement. * - * @return boolean + * @return bool * * @throws Exception\CannotBindValue when the value to be bound is not * bindable (e.g., array, object, or resource). * */ - protected function bindValue(PDOStatement $sth, $key, $val) + protected function bindValue(PDOStatement $sth, mixed $key, mixed $val): bool { if (is_int($val)) { return $sth->bindValue($key, $val, self::PARAM_INT); @@ -949,11 +941,11 @@ protected function bindValue(PDOStatement $sth, $key, $val) * @return ParserInterface * */ - protected function newParser($driver) + protected function newParser(string $driver): ParserInterface { $class = 'Aura\Sql\Parser\\' . ucfirst($driver) . 'Parser'; if (! class_exists($class)) { - $class = 'Aura\Sql\Parser\SqliteParser'; + $class = 'Aura\Sql\Parser\SqliteParser'; } return new $class(); } @@ -964,10 +956,10 @@ protected function newParser($driver) * * @param string $driver The PDO driver name. * - * @return null + * @return void * */ - protected function setQuoteName($driver) + protected function setQuoteName(string $driver): void { switch ($driver) { case 'mysql': @@ -996,12 +988,11 @@ protected function setQuoteName($driver) * Retrieve a database connection attribute * * @param int $attribute - * @return mixed + * @return bool|int|string|array|null */ - #[\ReturnTypeWillChange] - public function getAttribute($attribute) + public function getAttribute(int $attribute): bool|int|string|array|null { - $this->connect(); + $this->lazyConnect(); return $this->pdo->getAttribute($attribute); } @@ -1013,10 +1004,9 @@ public function getAttribute($attribute) * @param mixed $value * @return bool */ - #[\ReturnTypeWillChange] - public function setAttribute($attribute, $value) + public function setAttribute(int $attribute, mixed $value): bool { - $this->connect(); + $this->lazyConnect(); return $this->pdo->setAttribute($attribute, $value); } } diff --git a/includes/vendor/aura/sql/src/ConnectionLocator.php b/includes/vendor/aura/sql/src/ConnectionLocator.php index 80a8fbe0c..66cb1fa60 100644 --- a/includes/vendor/aura/sql/src/ConnectionLocator.php +++ b/includes/vendor/aura/sql/src/ConnectionLocator.php @@ -33,7 +33,7 @@ class ConnectionLocator implements ConnectionLocatorInterface * @var array * */ - protected $read = []; + protected array $read = []; /** * @@ -42,13 +42,13 @@ class ConnectionLocator implements ConnectionLocatorInterface * @var array * */ - protected $write = []; + protected array $write = []; /** * * Constructor. * - * @param callable $default A callable to create a default connection. + * @param callable|null $default A callable to create a default connection. * * @param array $read An array of callables to create read connections. * @@ -56,7 +56,7 @@ class ConnectionLocator implements ConnectionLocatorInterface * */ public function __construct( - $default = null, + ?callable $default = null, array $read = [], array $write = [] ) { @@ -77,10 +77,9 @@ public function __construct( * * @param callable $callable The factory for the connection. * - * @return null - * + * @return void */ - public function setDefault(callable $callable) + public function setDefault(callable $callable): void { $this->default = $callable; } @@ -91,9 +90,14 @@ public function setDefault(callable $callable) * * @return ExtendedPdoInterface * + * @throws Exception\ConnectionNotFound */ - public function getDefault() + public function getDefault(): ExtendedPdoInterface { + if (! $this->default) { + throw new Exception\ConnectionNotFound("default"); + } + if (! $this->default instanceof ExtendedPdo) { $this->default = call_user_func($this->default); } @@ -109,10 +113,9 @@ public function getDefault() * * @param callable $callable The factory for the connection. * - * @return null - * + * @return void */ - public function setRead($name, callable $callable) + public function setRead(string $name, callable $callable): void { $this->read[$name] = $callable; } @@ -127,8 +130,9 @@ public function setRead($name, callable $callable) * * @return ExtendedPdoInterface * + * @throws \Aura\Sql\Exception\ConnectionNotFound */ - public function getRead($name = '') + public function getRead(string $name = ''): ExtendedPdoInterface { return $this->getConnection('read', $name); } @@ -141,10 +145,9 @@ public function getRead($name = '') * * @param callable $callable The factory for the connection. * - * @return null - * + * @return void */ - public function setWrite($name, callable $callable) + public function setWrite(string $name, callable $callable): void { $this->write[$name] = $callable; } @@ -159,8 +162,9 @@ public function setWrite($name, callable $callable) * * @return ExtendedPdoInterface * + * @throws \Aura\Sql\Exception\ConnectionNotFound */ - public function getWrite($name = '') + public function getWrite(string $name = ''): ExtendedPdoInterface { return $this->getConnection('write', $name); } @@ -178,7 +182,7 @@ public function getWrite($name = '') * @throws Exception\ConnectionNotFound * */ - protected function getConnection($type, $name) + protected function getConnection(string $type, string $name): ExtendedPdoInterface { $conn = &$this->{$type}; @@ -191,7 +195,7 @@ protected function getConnection($type, $name) } if (! isset($conn[$name])) { - throw new Exception\ConnectionNotFound("{$type}:{$name}"); + throw new Exception\ConnectionNotFound("$type:$name"); } if (! $conn[$name] instanceof ExtendedPdo) { diff --git a/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php b/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php index 5daf99c24..e30beb6f0 100644 --- a/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php +++ b/includes/vendor/aura/sql/src/ConnectionLocatorInterface.php @@ -23,10 +23,9 @@ interface ConnectionLocatorInterface * * @param callable $callable The registry entry. * - * @return null - * + * @return void */ - public function setDefault(callable $callable); + public function setDefault(callable $callable): void; /** * @@ -35,7 +34,7 @@ public function setDefault(callable $callable); * @return ExtendedPdoInterface * */ - public function getDefault(); + public function getDefault(): ExtendedPdoInterface; /** * @@ -45,10 +44,9 @@ public function getDefault(); * * @param callable $callable The registry entry. * - * @return null - * + * @return void */ - public function setRead($name, callable $callable); + public function setRead(string $name, callable $callable): void; /** * @@ -61,7 +59,7 @@ public function setRead($name, callable $callable); * @return ExtendedPdoInterface * */ - public function getRead($name = ''); + public function getRead(string $name = ''): ExtendedPdoInterface; /** * @@ -71,10 +69,9 @@ public function getRead($name = ''); * * @param callable $callable The registry entry. * - * @return null - * + * @return void */ - public function setWrite($name, callable $callable); + public function setWrite(string $name, callable $callable): void; /** * @@ -87,5 +84,5 @@ public function setWrite($name, callable $callable); * @return ExtendedPdoInterface * */ - public function getWrite($name = ''); + public function getWrite(string $name = ''): ExtendedPdoInterface; } diff --git a/includes/vendor/aura/sql/src/DecoratedPdo.php b/includes/vendor/aura/sql/src/DecoratedPdo.php index 8916b86ae..7dd2fc82d 100644 --- a/includes/vendor/aura/sql/src/DecoratedPdo.php +++ b/includes/vendor/aura/sql/src/DecoratedPdo.php @@ -30,31 +30,42 @@ class DecoratedPdo extends AbstractExtendedPdo * * @param PDO $pdo An existing PDO instance to decorate. * - * @param ProfilerInterface $profiler Tracks and logs query profiles. + * @param ProfilerInterface|null $profiler Tracks and logs query profiles. * */ - public function __construct(PDO $pdo, ProfilerInterface $profiler = null) + public function __construct(PDO $pdo, ?ProfilerInterface $profiler = null) { $this->pdo = $pdo; - if ($profiler === null) { - $profiler = new Profiler(); - } - $this->setProfiler($profiler); + $this->setProfiler($profiler ?? new Profiler()); $driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); $this->setParser($this->newParser($driver)); $this->setQuoteName($driver); } + public static function connect( + string $dsn, + ?string $username = null, + ?string $password = null, + ?array $options = null, + ?ProfilerInterface $profiler = null + ): static { + if (version_compare(PHP_VERSION, '8.4.0', '>=')) { + return new static(\PDO::connect($dsn, $username, $password, $options)); + } else { + return new static(new PDO($dsn, $username, $password, $options), $profiler); + } + } + /** * * Connects to the database. * - * @return null + * @return void * */ - public function connect() + public function lazyConnect(): void { // already connected } @@ -63,10 +74,11 @@ public function connect() * * Disconnects from the database; disallowed with decorated PDO connections. * - * @return null + * @return void * + * @throws Exception\CannotDisconnect */ - public function disconnect() + public function disconnect(): void { $message = "Cannot disconnect a DecoratedPdo instance."; throw new Exception\CannotDisconnect($message); diff --git a/includes/vendor/aura/sql/src/ExtendedPdo.php b/includes/vendor/aura/sql/src/ExtendedPdo.php index 18820e68d..700889e67 100644 --- a/includes/vendor/aura/sql/src/ExtendedPdo.php +++ b/includes/vendor/aura/sql/src/ExtendedPdo.php @@ -21,6 +21,9 @@ */ class ExtendedPdo extends AbstractExtendedPdo { + public const CONNECT_IMMEDIATELY = 'auraSqlImmediate'; + public const DRIVER_SPECIFIC = 'auraSqlDriverSpecific'; + /** * * Constructor arguments for instantiating the PDO connection. @@ -28,7 +31,15 @@ class ExtendedPdo extends AbstractExtendedPdo * @var array * */ - protected $args = []; + protected array $args = []; + + /** + * + * Flag for how to construct the PDO object + * + * @var bool + */ + protected bool $driverSpecific = false; /** * @@ -39,32 +50,37 @@ class ExtendedPdo extends AbstractExtendedPdo * * @param string $dsn The data source name for the connection. * - * @param string $username The username for the connection. + * @param string|null $username The username for the connection. * - * @param string $password The password for the connection. + * @param string|null $password The password for the connection. * * @param array $options Driver-specific options for the connection. * * @param array $queries Queries to execute after the connection. * - * @param ProfilerInterface $profiler Tracks and logs query profiles. + * @param \Aura\Sql\Profiler\ProfilerInterface|null $profiler Tracks and logs query profiles. * * @see http://php.net/manual/en/pdo.construct.php - * */ public function __construct( - $dsn, - $username = null, - $password = null, + string $dsn, + ?string $username = null, + ?string $password = null, array $options = [], array $queries = [], - ProfilerInterface $profiler = null + ?ProfilerInterface $profiler = null ) { // if no error mode is specified, use exceptions if (! isset($options[PDO::ATTR_ERRMODE])) { $options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION; } + // check option for driver specific construct and set flag for lazy loading later + if (isset($options[static::DRIVER_SPECIFIC])) { + $this->driverSpecific = (bool)$options[static::DRIVER_SPECIFIC]; + unset($options[static::DRIVER_SPECIFIC]); + } + // retain the arguments for later $this->args = [ $dsn, @@ -75,28 +91,46 @@ public function __construct( ]; // retain a profiler, instantiating a default one if needed - if ($profiler === null) { - $profiler = new Profiler(); - } - $this->setProfiler($profiler); + $this->setProfiler($profiler ?? new Profiler()); // retain a query parser - $parts = explode(':', $dsn); + $parts = explode(":", $dsn); $parser = $this->newParser($parts[0]); $this->setParser($parser); // set quotes for identifier names $this->setQuoteName($parts[0]); + + // create a connection immediately + if (isset($options[static::CONNECT_IMMEDIATELY])) { + $connectImmediately = (bool)$options[static::CONNECT_IMMEDIATELY]; + unset($options[static::CONNECT_IMMEDIATELY]); + if ($connectImmediately) { + $this->lazyConnect(); + } + } + } + + public static function connect( + string $dsn, + ?string $username = null, + ?string $password = null, + ?array $options = null, + array $queries = [], + ?ProfilerInterface $profiler = null + ): static { + $options ??= []; + $options[static::DRIVER_SPECIFIC] = true; + return new static($dsn, $username, $password, $options, $queries, $profiler); } /** * * Connects to the database. * - * @return null - * + * @return void */ - public function connect() + public function lazyConnect(): void { if ($this->pdo) { return; @@ -105,6 +139,11 @@ public function connect() // connect $this->profiler->start(__FUNCTION__); list($dsn, $username, $password, $options, $queries) = $this->args; + if ($this->driverSpecific && version_compare(PHP_VERSION, '8.4.0', '>=')) { + $this->pdo = PDO::connect($dsn, $username, $password, $options); + } else { + $this->pdo = new PDO($dsn, $username, $password, $options); + } $this->pdo = new PDO($dsn, $username, $password, $options); $this->profiler->finish(); @@ -118,10 +157,10 @@ public function connect() * * Disconnects from the database. * - * @return null + * @return void * */ - public function disconnect() + public function disconnect(): void { $this->profiler->start(__FUNCTION__); $this->pdo = null; @@ -135,7 +174,7 @@ public function disconnect() * @return array * */ - public function __debugInfo() + public function __debugInfo(): array { return [ 'args' => [ @@ -144,7 +183,7 @@ public function __debugInfo() '****', $this->args[3], $this->args[4], - ] + ], ]; } @@ -155,9 +194,9 @@ public function __debugInfo() * @return \PDO * */ - public function getPdo() + public function getPdo(): PDO { - $this->connect(); + $this->lazyConnect(); return $this->pdo; } } diff --git a/includes/vendor/aura/sql/src/ExtendedPdoInterface.php b/includes/vendor/aura/sql/src/ExtendedPdoInterface.php index 323c3f659..0aaa3f433 100644 --- a/includes/vendor/aura/sql/src/ExtendedPdoInterface.php +++ b/includes/vendor/aura/sql/src/ExtendedPdoInterface.php @@ -10,7 +10,9 @@ use Aura\Sql\Parser\ParserInterface; use Aura\Sql\Profiler\ProfilerInterface; +use Generator; use PDO; +use PDOStatement; /** * @@ -26,14 +28,14 @@ interface ExtendedPdoInterface extends PdoInterface * Connects to the database. * */ - public function connect(); + public function lazyConnect(): void; /** * * Disconnects from the database. * */ - public function disconnect(); + public function disconnect(): void; /** * @@ -46,7 +48,7 @@ public function disconnect(); * @return int * */ - public function fetchAffected($statement, array $values = []); + public function fetchAffected(string $statement, array $values = []): int; /** * @@ -60,7 +62,7 @@ public function fetchAffected($statement, array $values = []); * @return array * */ - public function fetchAll($statement, array $values = []); + public function fetchAll(string $statement, array $values = []): array; /** * @@ -78,7 +80,7 @@ public function fetchAll($statement, array $values = []); * @return array * */ - public function fetchAssoc($statement, array $values = []); + public function fetchAssoc(string $statement, array $values = []): array; /** * @@ -91,7 +93,7 @@ public function fetchAssoc($statement, array $values = []); * @return array * */ - public function fetchCol($statement, array $values = []); + public function fetchCol(string $statement, array $values = []): array; /** * @@ -109,10 +111,10 @@ public function fetchCol($statement, array $values = []); * */ public function fetchGroup( - $statement, + string $statement, array $values = [], - $style = PDO::FETCH_COLUMN - ); + int $style = PDO::FETCH_COLUMN + ): array; /** * @@ -133,15 +135,15 @@ public function fetchGroup( * * @param array $args Arguments to pass to the object constructor. * - * @return object + * @return object|false * */ public function fetchObject( - $statement, + string $statement, array $values = [], - $class = 'stdClass', + string $class = 'stdClass', array $args = [] - ); + ): object|false; /** * @@ -168,11 +170,11 @@ public function fetchObject( * */ public function fetchObjects( - $statement, + string $statement, array $values = [], - $class = 'stdClass', + string $class = 'stdClass', array $args = [] - ); + ): array; /** * @@ -182,10 +184,10 @@ public function fetchObjects( * * @param array $values Values to bind to the query. * - * @return array + * @return array|false * */ - public function fetchOne($statement, array $values = []); + public function fetchOne(string $statement, array $values = []): array|false; /** * @@ -199,7 +201,7 @@ public function fetchOne($statement, array $values = []); * @return array * */ - public function fetchPairs($statement, array $values = []); + public function fetchPairs(string $statement, array $values = []): array; /** * @@ -212,7 +214,7 @@ public function fetchPairs($statement, array $values = []); * @return mixed * */ - public function fetchValue($statement, array $values = []); + public function fetchValue(string $statement, array $values = []): mixed; /** * @@ -221,7 +223,7 @@ public function fetchValue($statement, array $values = []); * @return ParserInterface * */ - public function getParser(); + public function getParser(): ParserInterface; /** * @@ -230,7 +232,7 @@ public function getParser(); * @return \PDO * */ - public function getPdo(); + public function getPdo(): PDO; /** * @@ -239,7 +241,7 @@ public function getPdo(); * @return ProfilerInterface * */ - public function getProfiler(); + public function getProfiler(): ProfilerInterface; /** * @@ -250,7 +252,7 @@ public function getProfiler(); * @return string The multi-part identifier name, quoted. * */ - public function quoteName($name); + public function quoteName(string $name): string; /** * @@ -261,7 +263,7 @@ public function quoteName($name); * @return string The quoted identifier name. * */ - public function quoteSingleName($name); + public function quoteSingleName(string $name): string; /** * @@ -270,7 +272,7 @@ public function quoteSingleName($name); * @return bool * */ - public function isConnected(); + public function isConnected(): bool; /** * @@ -279,7 +281,7 @@ public function isConnected(); * @param ParserInterface $parser The Parser instance. * */ - public function setParser(ParserInterface $parser); + public function setParser(ParserInterface $parser): void; /** * @@ -288,7 +290,7 @@ public function setParser(ParserInterface $parser); * @param ProfilerInterface $profiler The Profiler instance. * */ - public function setProfiler(ProfilerInterface $profiler); + public function setProfiler(ProfilerInterface $profiler): void; /** * @@ -301,7 +303,7 @@ public function setProfiler(ProfilerInterface $profiler); * @return \Generator * */ - public function yieldAll($statement, array $values = []); + public function yieldAll(string $statement, array $values = []): Generator; /** * @@ -314,7 +316,7 @@ public function yieldAll($statement, array $values = []); * @return \Generator * */ - public function yieldAssoc($statement, array $values = []); + public function yieldAssoc(string $statement, array $values = []): Generator; /** * @@ -327,7 +329,7 @@ public function yieldAssoc($statement, array $values = []); * @return \Generator * */ - public function yieldCol($statement, array $values = []); + public function yieldCol(string $statement, array $values = []): Generator; /** * @@ -352,11 +354,11 @@ public function yieldCol($statement, array $values = []); * */ public function yieldObjects( - $statement, + string $statement, array $values = [], - $class = 'stdClass', + string $class = 'stdClass', array $args = [] - ); + ): Generator; /** * @@ -370,7 +372,7 @@ public function yieldObjects( * @return \Generator * */ - public function yieldPairs($statement, array $values = []); + public function yieldPairs(string $statement, array $values = []): Generator; /** * @@ -384,7 +386,7 @@ public function yieldPairs($statement, array $values = []); * @return \PDOStatement * */ - public function perform($statement, array $values = []); + public function perform(string $statement, array $values = []): PDOStatement; /** * @@ -408,5 +410,5 @@ public function perform($statement, array $values = []); * @see http://php.net/manual/en/pdo.prepare.php * */ - public function prepareWithValues($statement, array $values = []); + public function prepareWithValues(string $statement, array $values = []): PDOStatement; } diff --git a/includes/vendor/aura/sql/src/Parser/AbstractParser.php b/includes/vendor/aura/sql/src/Parser/AbstractParser.php index 4405dfff0..007244de4 100644 --- a/includes/vendor/aura/sql/src/Parser/AbstractParser.php +++ b/includes/vendor/aura/sql/src/Parser/AbstractParser.php @@ -29,7 +29,7 @@ abstract class AbstractParser implements ParserInterface * @var array * */ - protected $split = [ + protected array $split = [ // single-quoted string "'(?:[^'\\\\]|\\\\'?)*'", // double-quoted string @@ -43,7 +43,7 @@ abstract class AbstractParser implements ParserInterface * @var string * */ - protected $skip = '/^(\'|\"|\:[^a-zA-Z_])/um'; + protected string $skip = '/^(\'|\"|\:[^a-zA-Z_])/um'; /** * @@ -52,7 +52,7 @@ abstract class AbstractParser implements ParserInterface * @var int * */ - protected $num = 0; + protected int $num = 0; /** * @@ -61,7 +61,7 @@ abstract class AbstractParser implements ParserInterface * @var array * */ - protected $count = [ + protected array $count = [ '__' => null, ]; @@ -72,7 +72,7 @@ abstract class AbstractParser implements ParserInterface * @var array * */ - protected $values = []; + protected array $values = []; /** * @@ -81,7 +81,7 @@ abstract class AbstractParser implements ParserInterface * @var array * */ - protected $final_values = []; + protected array $final_values = []; /** * @@ -95,7 +95,7 @@ abstract class AbstractParser implements ParserInterface * element 1 is the rebuilt array of values. * */ - public function rebuild($statement, array $values = []) + public function rebuild(string $statement, array $values = []): array { // match standard PDO execute() behavior of zero-indexed arrays if (array_key_exists(0, $values)) { @@ -116,7 +116,7 @@ public function rebuild($statement, array $values = []) * @return string The rebuilt statement. * */ - protected function rebuildStatement($statement) + protected function rebuildStatement(string $statement): string { $parts = $this->getParts($statement); return $this->rebuildParts($parts); @@ -131,7 +131,7 @@ protected function rebuildStatement($statement) * @return string The rebuilt statement. * */ - protected function rebuildParts(array $parts) + protected function rebuildParts(array $parts): string { $statement = ''; foreach ($parts as $part) { @@ -149,7 +149,7 @@ protected function rebuildParts(array $parts) * @return string The rebuilt statement. * */ - protected function rebuildPart($part) + protected function rebuildPart(string $part): string { if (preg_match($this->skip, $part)) { return $part; @@ -176,7 +176,7 @@ protected function rebuildPart($part) * @return string The prepared subparts. * */ - protected function prepareValuePlaceholders(array $subs) + protected function prepareValuePlaceholders(array $subs): string { $str = ''; foreach ($subs as $i => $sub) { @@ -230,7 +230,7 @@ protected function prepareNumberedPlaceholder() * @return string The prepared query subpart. * */ - protected function prepareNamedPlaceholder($sub) + protected function prepareNamedPlaceholder(string $sub): string { $orig = substr($sub, 1); if (array_key_exists($orig, $this->values) === false) { @@ -260,7 +260,7 @@ protected function prepareNamedPlaceholder($sub) * @return string * */ - protected function getPlaceholderName($orig) + protected function getPlaceholderName(string $orig): string { if (! isset($this->count[$orig])) { $this->count[$orig] = 0; @@ -283,7 +283,7 @@ protected function getPlaceholderName($orig) * @return string * */ - protected function expandNamedPlaceholder($prefix, array $values) + protected function expandNamedPlaceholder(string $prefix, array $values): string { $i = 0; $expanded = []; @@ -305,7 +305,7 @@ protected function expandNamedPlaceholder($prefix, array $values) * @return array * */ - protected function getParts($statement) + protected function getParts(string $statement): array { $split = implode('|', $this->split); return preg_split( diff --git a/includes/vendor/aura/sql/src/Parser/MysqlParser.php b/includes/vendor/aura/sql/src/Parser/MysqlParser.php index f516f551e..7066abac7 100644 --- a/includes/vendor/aura/sql/src/Parser/MysqlParser.php +++ b/includes/vendor/aura/sql/src/Parser/MysqlParser.php @@ -24,7 +24,7 @@ class MysqlParser extends AbstractParser * @var array * */ - protected $split = [ + protected array $split = [ // single-quoted string "'(?:[^'\\\\]|\\\\'?)*'", // double-quoted string @@ -40,5 +40,5 @@ class MysqlParser extends AbstractParser * @var string * */ - protected $skip = '/^(\'|\"|\`)/um'; + protected string $skip = '/^(\'|\"|\`)/um'; } diff --git a/includes/vendor/aura/sql/src/Parser/NullParser.php b/includes/vendor/aura/sql/src/Parser/NullParser.php index 09af509ab..a6534a390 100644 --- a/includes/vendor/aura/sql/src/Parser/NullParser.php +++ b/includes/vendor/aura/sql/src/Parser/NullParser.php @@ -22,15 +22,15 @@ class NullParser implements ParserInterface * * Leaves the query and parameters alone. * - * @param string $statement The query statement string. + * @param string $string The query statement string. * - * @param array $values Bind these values into the query. + * @param array $parameters Bind these values into the query. * * @return array * */ - public function rebuild($statement, array $values = []) + public function rebuild(string $string, array $parameters = []): array { - return [$statement, $values]; + return [$string, $parameters]; } } diff --git a/includes/vendor/aura/sql/src/Parser/ParserInterface.php b/includes/vendor/aura/sql/src/Parser/ParserInterface.php index dc1380792..b90dd922b 100644 --- a/includes/vendor/aura/sql/src/Parser/ParserInterface.php +++ b/includes/vendor/aura/sql/src/Parser/ParserInterface.php @@ -30,5 +30,5 @@ interface ParserInterface * element 1 is the rebuilt array of values. * */ - public function rebuild($string, array $parameters = []); + public function rebuild(string $string, array $parameters = []): array; } diff --git a/includes/vendor/aura/sql/src/Parser/PgsqlParser.php b/includes/vendor/aura/sql/src/Parser/PgsqlParser.php index ead10f732..261cf5da5 100644 --- a/includes/vendor/aura/sql/src/Parser/PgsqlParser.php +++ b/includes/vendor/aura/sql/src/Parser/PgsqlParser.php @@ -24,7 +24,7 @@ class PgsqlParser extends AbstractParser * @var array * */ - protected $split = [ + protected array $split = [ // single-quoted string "'(?:[^'\\\\]|\\\\'?)*'", // double-quoted string @@ -42,5 +42,5 @@ class PgsqlParser extends AbstractParser * @var string * */ - protected $skip = '/^(\'|\"|\$|\:[^a-zA-Z_])/um'; + protected string $skip = '/^(\'|\"|\$|\:[^a-zA-Z_])/um'; } diff --git a/includes/vendor/aura/sql/src/Parser/SqliteParser.php b/includes/vendor/aura/sql/src/Parser/SqliteParser.php index ac43b50c1..2806d749b 100644 --- a/includes/vendor/aura/sql/src/Parser/SqliteParser.php +++ b/includes/vendor/aura/sql/src/Parser/SqliteParser.php @@ -20,17 +20,17 @@ class SqliteParser extends AbstractParser /** * {@inheritDoc} */ - protected $split = [ + protected array $split = [ // single-quoted string "'(?:[^'\\\\]|\\\\'?)*'", // double-quoted string '"(?:[^"\\\\]|\\\\"?)*"', // backticked column names - '`(?:[^`\\\\]|\\\\`?)*`', + '`(?:[^`\\\\]|\\\\`?)*`', ]; - + /** * {@inheritDoc} */ - protected $skip = '/^(\'|"|`|\:[^a-zA-Z_])/um'; + protected string $skip = '/^(\'|"|`|\:[^a-zA-Z_])/um'; } diff --git a/includes/vendor/aura/sql/src/PdoInterface.php b/includes/vendor/aura/sql/src/PdoInterface.php index 23754c0a5..7f2954576 100644 --- a/includes/vendor/aura/sql/src/PdoInterface.php +++ b/includes/vendor/aura/sql/src/PdoInterface.php @@ -9,6 +9,7 @@ namespace Aura\Sql; use PDO; +use PDOStatement; /** * @@ -28,7 +29,7 @@ interface PdoInterface * @see http://php.net/manual/en/pdo.begintransaction.php * */ - public function beginTransaction(); + public function beginTransaction(): bool; /** * @@ -39,16 +40,38 @@ public function beginTransaction(); * @see http://php.net/manual/en/pdo.commit.php * */ - public function commit(); + public function commit(): bool; /** * - * Gets the most recent error code. + * Introduced in 6.x due to PHP 8.4 change. This is a BC break for Aura.Sql. + * + * @param string $dsn The Data Source Name, or DSN, contains the information required to connect to the database. + * + * @param string | null $username The user name for the DSN string. This parameter is optional for some PDO drivers. + * + * @param string | null $password The password for the DSN string. This parameter is optional for some PDO drivers. * - * @return mixed + * @param array | null $options A key=>value array of driver-specific connection options. * + * @return \PDO Returns an instance of a generic PDO instance. + * + * @see https://www.php.net/manual/en/pdo.connect.php */ - public function errorCode(); + public static function connect( + string $dsn, + ?string $username = null, + #[\SensitiveParameter] ?string $password = null, + ?array $options = null + ): static; + + /** + * + * Gets the most recent error code. + * + * @return string|null + */ + public function errorCode(): ?string; /** * @@ -57,7 +80,7 @@ public function errorCode(); * @return array * */ - public function errorInfo(); + public function errorInfo(): array; /** * @@ -65,23 +88,32 @@ public function errorInfo(); * * @param string $statement The SQL statement to execute. * - * @return int The number of rows affected. + * @return int|false The number of rows affected. * * @see http://php.net/manual/en/pdo.exec.php * */ - public function exec($statement); + public function exec(string $statement): int|false; /** * * Gets a PDO attribute value. * - * @param mixed $attribute The PDO::ATTR_* constant. + * @param int $attribute The PDO::ATTR_* constant. * - * @return mixed The value for the attribute. + * @return bool|int|string|array|null The value for the attribute. * */ - public function getAttribute($attribute); + public function getAttribute(int $attribute): bool|int|string|array|null; + + /** + * + * Returns all currently available PDO drivers. + * + * @return array + * + */ + public static function getAvailableDrivers(): array; /** * @@ -92,67 +124,68 @@ public function getAttribute($attribute); * @see http://php.net/manual/en/pdo.intransaction.php * */ - public function inTransaction(); + public function inTransaction(): bool; /** * * Returns the last inserted autoincrement sequence value. * - * @param string $name The name of the sequence to check; typically needed + * @param string|null $name The name of the sequence to check; typically needed * only for PostgreSQL, where it takes the form of `
__seq`. * - * @return string + * @return string|false * * @see http://php.net/manual/en/pdo.lastinsertid.php * */ - public function lastInsertId($name = null); + public function lastInsertId(?string $name = null): string|false; /** * * Prepares an SQL statement for execution. * - * @param string $statement The SQL statement to prepare for execution. + * @param string $query The SQL statement to prepare for execution. * * @param array $options Set these attributes on the returned * PDOStatement. * - * @return \PDOStatement + * @return \PDOStatement|false * * @see http://php.net/manual/en/pdo.prepare.php - * */ - public function prepare($statement, $options = null); + public function prepare(string $query, array $options = []): PDOStatement|false; /** * * Queries the database and returns a PDOStatement. * - * @param string $statement The SQL statement to prepare and execute. + * @param string $query The SQL statement to prepare and execute. + * + * @param int|null $fetchMode * - * @param mixed ...$fetch Optional fetch-related parameters. + * @param mixed ...$fetch_mode_args Optional fetch-related parameters. * - * @return \PDOStatement + * @return \PDOStatement|false * * @see http://php.net/manual/en/pdo.query.php * */ - public function query($statement, ...$fetch); + public function query(string $query, ?int $fetchMode = null, ...$fetch_mode_args): PDOStatement|false; /** * * Quotes a value for use in an SQL statement. * - * @param mixed $value The value to quote. + * @param string|int|array|float|null $value The value to quote. * - * @param int $parameter_type A data type hint for the database driver. + * @param int $type A data type hint for the database driver. * - * @return string The quoted value. + * @return string|false The quoted value. * * @see http://php.net/manual/en/pdo.quote.php * */ - public function quote($value, $parameter_type = PDO::PARAM_STR); + public function quote(string|int|array|float|null $value, int $type = PDO::PARAM_STR): string|false; /** * @@ -163,27 +196,18 @@ public function quote($value, $parameter_type = PDO::PARAM_STR); * @see http://php.net/manual/en/pdo.rollback.php * */ - public function rollBack(); + public function rollBack(): bool; /** * * Sets a PDO attribute value. * - * @param mixed $attribute The PDO::ATTR_* constant. + * @param int $attribute The PDO::ATTR_* constant. * * @param mixed $value The value for the attribute. * * @return bool * */ - public function setAttribute($attribute, $value); - - /** - * - * Returns all currently available PDO drivers. - * - * @return array - * - */ - public static function getAvailableDrivers(); + public function setAttribute(int $attribute, mixed $value): bool; } diff --git a/includes/vendor/aura/sql/src/Profiler/MemoryLogger.php b/includes/vendor/aura/sql/src/Profiler/MemoryLogger.php index c94e564f8..78184eed5 100644 --- a/includes/vendor/aura/sql/src/Profiler/MemoryLogger.php +++ b/includes/vendor/aura/sql/src/Profiler/MemoryLogger.php @@ -26,7 +26,7 @@ class MemoryLogger extends AbstractLogger * @var array * */ - protected $messages = []; + protected array $messages = []; /** * @@ -38,10 +38,9 @@ class MemoryLogger extends AbstractLogger * * @param array $context Data to interpolate into the message. * - * @return null - * + * @return void */ - public function log($level, $message, array $context = []) + public function log($level, $message, array $context = []): void { $replace = []; foreach ($context as $key => $val) { @@ -57,7 +56,7 @@ public function log($level, $message, array $context = []) * @return array * */ - public function getMessages() + public function getMessages(): array { return $this->messages; } diff --git a/includes/vendor/aura/sql/src/Profiler/Profiler.php b/includes/vendor/aura/sql/src/Profiler/Profiler.php index 6f341bc81..42d591b6b 100644 --- a/includes/vendor/aura/sql/src/Profiler/Profiler.php +++ b/includes/vendor/aura/sql/src/Profiler/Profiler.php @@ -28,7 +28,7 @@ class Profiler implements ProfilerInterface * @var array * */ - protected $context = []; + protected array $context = []; /** * @@ -37,7 +37,7 @@ class Profiler implements ProfilerInterface * @var LoggerInterface * */ - protected $logger; + protected LoggerInterface $logger; /** * @@ -48,7 +48,7 @@ class Profiler implements ProfilerInterface * @see setActive() * */ - protected $active = false; + protected bool $active = false; /** * @@ -59,7 +59,7 @@ class Profiler implements ProfilerInterface * @see setLogLevel() * */ - protected $logLevel = LogLevel::DEBUG; + protected string $logLevel = LogLevel::DEBUG; /** * @@ -70,21 +70,17 @@ class Profiler implements ProfilerInterface * @see setLogFormat() * */ - protected $logFormat = "{function} ({duration} seconds): {statement} {backtrace}"; + protected string $logFormat = "{function} ({duration} seconds): {statement} {backtrace}"; /** * * Constructor. * - * @param LoggerInterface $logger Record profiles through this interface. - * + * @param \Psr\Log\LoggerInterface|null $logger Record profiles through this interface. */ - public function __construct(LoggerInterface $logger = null) + public function __construct(?LoggerInterface $logger = null) { - if ($logger === null) { - $logger = new MemoryLogger(); - } - $this->logger = $logger; + $this->logger = $logger ?? new MemoryLogger(); } /** @@ -94,9 +90,9 @@ public function __construct(LoggerInterface $logger = null) * @param bool $active * */ - public function setActive($active) + public function setActive(bool $active) { - $this->active = (bool) $active; + $this->active = $active; } /** @@ -106,7 +102,7 @@ public function setActive($active) * @return bool * */ - public function isActive() + public function isActive(): bool { return $this->active; } @@ -118,7 +114,7 @@ public function isActive() * @return \Psr\Log\LoggerInterface * */ - public function getLogger() + public function getLogger(): LoggerInterface { return $this->logger; } @@ -130,7 +126,7 @@ public function getLogger() * @return string * */ - public function getLogLevel() + public function getLogLevel(): string { return $this->logLevel; } @@ -141,10 +137,9 @@ public function getLogLevel() * * @param string $logLevel A PSR LogLevel constant. * - * @return null - * + * @return void */ - public function setLogLevel($logLevel) + public function setLogLevel(string $logLevel): void { $this->logLevel = $logLevel; } @@ -156,7 +151,7 @@ public function setLogLevel($logLevel) * @return string * */ - public function getLogFormat() + public function getLogFormat(): string { return $this->logFormat; } @@ -167,10 +162,9 @@ public function getLogFormat() * * @param string $logFormat * - * @return null - * + * @return void */ - public function setLogFormat($logFormat) + public function setLogFormat(string $logFormat): void { $this->logFormat = $logFormat; } @@ -181,10 +175,9 @@ public function setLogFormat($logFormat) * * @param string $function The function starting the profile entry. * - * @return null - * + * @return void */ - public function start($function) + public function start(string $function): void { if (! $this->active) { return; @@ -200,14 +193,13 @@ public function start($function) * * Finishes and logs a profile entry. * - * @param string $statement The statement being profiled, if any. + * @param string|null $statement The statement being profiled, if any. * * @param array $values The values bound to the statement, if any. * - * @return null - * + * @return void */ - public function finish($statement = null, array $values = []) + public function finish(?string $statement = null, array $values = []): void { if (! $this->active) { return; diff --git a/includes/vendor/aura/sql/src/Profiler/ProfilerInterface.php b/includes/vendor/aura/sql/src/Profiler/ProfilerInterface.php index 14d114b42..ae1f6a89d 100644 --- a/includes/vendor/aura/sql/src/Profiler/ProfilerInterface.php +++ b/includes/vendor/aura/sql/src/Profiler/ProfilerInterface.php @@ -24,7 +24,7 @@ interface ProfilerInterface * @param bool $active * */ - public function setActive($active); + public function setActive(bool $active); /** * @@ -33,7 +33,7 @@ public function setActive($active); * @return bool * */ - public function isActive(); + public function isActive(): bool; /** * @@ -42,7 +42,7 @@ public function isActive(); * @return \Psr\Log\LoggerInterface * */ - public function getLogger(); + public function getLogger(): \Psr\Log\LoggerInterface; /** * @@ -51,7 +51,7 @@ public function getLogger(); * @return string * */ - public function getLogLevel(); + public function getLogLevel(): string; /** * @@ -59,10 +59,9 @@ public function getLogLevel(); * * @param string $logLevel A PSR LogLevel constant. * - * @return null - * + * @return void */ - public function setLogLevel($logLevel); + public function setLogLevel(string $logLevel): void; /** * @@ -71,7 +70,7 @@ public function setLogLevel($logLevel); * @return string * */ - public function getLogFormat(); + public function getLogFormat(): string; /** * @@ -79,10 +78,9 @@ public function getLogFormat(); * * @param string $logFormat * - * @return null - * + * @return void */ - public function setLogFormat($logFormat); + public function setLogFormat(string $logFormat): void; /** * @@ -90,21 +88,19 @@ public function setLogFormat($logFormat); * * @param string $function The function starting the profile entry. * - * @return null - * + * @return void */ - public function start($function); + public function start(string $function): void; /** * * Finishes and logs a profile entry. * - * @param string $statement The statement being profiled, if any. + * @param string|null $statement The statement being profiled, if any. * * @param array $values The values bound to the statement, if any. * - * @return null - * + * @return void */ - public function finish($statement = null, array $values = []); + public function finish(?string $statement = null, array $values = []): void; } diff --git a/includes/vendor/autoload.php b/includes/vendor/autoload.php index 4767bb2a8..ebbf8747b 100644 --- a/includes/vendor/autoload.php +++ b/includes/vendor/autoload.php @@ -22,4 +22,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::getLoader(); +return ComposerAutoloaderInit1d5e2036274043d1e0e9e3243991653e::getLoader(); diff --git a/includes/vendor/composer/ClassLoader.php b/includes/vendor/composer/ClassLoader.php index afef3fa2a..7824d8f7e 100644 --- a/includes/vendor/composer/ClassLoader.php +++ b/includes/vendor/composer/ClassLoader.php @@ -42,35 +42,37 @@ */ class ClassLoader { - /** @var ?string */ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ private $vendorDir; // PSR-4 /** - * @var array[] - * @psalm-var array> + * @var array> */ private $prefixLengthsPsr4 = array(); /** - * @var array[] - * @psalm-var array> + * @var array> */ private $prefixDirsPsr4 = array(); /** - * @var array[] - * @psalm-var array + * @var list */ private $fallbackDirsPsr4 = array(); // PSR-0 /** - * @var array[] - * @psalm-var array> + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> */ private $prefixesPsr0 = array(); /** - * @var array[] - * @psalm-var array + * @var list */ private $fallbackDirsPsr0 = array(); @@ -78,8 +80,7 @@ class ClassLoader private $useIncludePath = false; /** - * @var string[] - * @psalm-var array + * @var array */ private $classMap = array(); @@ -87,29 +88,29 @@ class ClassLoader private $classMapAuthoritative = false; /** - * @var bool[] - * @psalm-var array + * @var array */ private $missingClasses = array(); - /** @var ?string */ + /** @var string|null */ private $apcuPrefix; /** - * @var self[] + * @var array */ private static $registeredLoaders = array(); /** - * @param ?string $vendorDir + * @param string|null $vendorDir */ public function __construct($vendorDir = null) { $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); } /** - * @return string[] + * @return array> */ public function getPrefixes() { @@ -121,8 +122,7 @@ public function getPrefixes() } /** - * @return array[] - * @psalm-return array> + * @return array> */ public function getPrefixesPsr4() { @@ -130,8 +130,7 @@ public function getPrefixesPsr4() } /** - * @return array[] - * @psalm-return array + * @return list */ public function getFallbackDirs() { @@ -139,8 +138,7 @@ public function getFallbackDirs() } /** - * @return array[] - * @psalm-return array + * @return list */ public function getFallbackDirsPsr4() { @@ -148,8 +146,7 @@ public function getFallbackDirsPsr4() } /** - * @return string[] Array of classname => path - * @psalm-return array + * @return array Array of classname => path */ public function getClassMap() { @@ -157,8 +154,7 @@ public function getClassMap() } /** - * @param string[] $classMap Class to filename map - * @psalm-param array $classMap + * @param array $classMap Class to filename map * * @return void */ @@ -175,24 +171,25 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories * * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -201,19 +198,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -222,9 +219,9 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException * @@ -232,17 +229,18 @@ public function add($prefix, $paths, $prepend = false) */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -252,18 +250,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -272,8 +270,8 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories * * @return void */ @@ -290,8 +288,8 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException * @@ -425,7 +423,8 @@ public function unregister() public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } @@ -476,9 +475,9 @@ public function findFile($class) } /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. + * Returns the currently registered loaders keyed by their corresponding vendor directories. * - * @return self[] + * @return array */ public static function getRegisteredLoaders() { @@ -555,18 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - * @private - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/includes/vendor/composer/InstalledVersions.php b/includes/vendor/composer/InstalledVersions.php index c6b54af7b..07b32ed6e 100644 --- a/includes/vendor/composer/InstalledVersions.php +++ b/includes/vendor/composer/InstalledVersions.php @@ -98,7 +98,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true) { foreach (self::getInstalled() as $installed) { if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; } } @@ -119,7 +119,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true) */ public static function satisfies(VersionParser $parser, $packageName, $constraint) { - $constraint = $parser->parseConstraints($constraint); + $constraint = $parser->parseConstraints((string) $constraint); $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); return $provided->matches($constraint); @@ -322,15 +322,20 @@ private static function getInstalled() } $installed = array(); + $copiedLocalDir = false; if (self::$canGetVendors) { foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { - $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $required; + $copiedLocalDir = true; } } } @@ -340,12 +345,17 @@ private static function getInstalled() // only require the installed.php file if this file is loaded from its dumped location, // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = require __DIR__ . '/installed.php'; + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; } else { self::$installed = array(); } } - $installed[] = self::$installed; + + if (self::$installed !== array() && !$copiedLocalDir) { + $installed[] = self::$installed; + } return $installed; } diff --git a/includes/vendor/composer/autoload_files.php b/includes/vendor/composer/autoload_files.php index 74d0a74d3..8493be270 100644 --- a/includes/vendor/composer/autoload_files.php +++ b/includes/vendor/composer/autoload_files.php @@ -7,7 +7,6 @@ return array( 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', 'b45b351e6b6f7487d819961fef2fda77' => $vendorDir . '/jakeasmith/http_build_url/src/http_build_url.php', '941748b3c8cae4466c827dfb5ca9602a' => $vendorDir . '/rmccue/requests/library/Deprecated.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', diff --git a/includes/vendor/composer/autoload_psr4.php b/includes/vendor/composer/autoload_psr4.php index 2a301dd00..5f3334d2e 100644 --- a/includes/vendor/composer/autoload_psr4.php +++ b/includes/vendor/composer/autoload_psr4.php @@ -8,12 +8,11 @@ return array( 'YOURLS\\' => array($baseDir . '/includes'), 'WpOrg\\Requests\\' => array($vendorDir . '/rmccue/requests/src'), - 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 'Spatie\\ArrayToXml\\' => array($vendorDir . '/spatie/array-to-xml/src'), - 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), 'POMO\\' => array($vendorDir . '/pomo/pomo/src'), 'MaxMind\\WebService\\' => array($vendorDir . '/maxmind/web-service-common/src/WebService'), 'MaxMind\\Exception\\' => array($vendorDir . '/maxmind/web-service-common/src/Exception'), diff --git a/includes/vendor/composer/autoload_real.php b/includes/vendor/composer/autoload_real.php index a4a77b5ae..2b0563f08 100644 --- a/includes/vendor/composer/autoload_real.php +++ b/includes/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit2d6d15a8f6cc4bfbfd4a2943a6c4df59 +class ComposerAutoloaderInit1d5e2036274043d1e0e9e3243991653e { private static $loader; @@ -24,34 +24,27 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit2d6d15a8f6cc4bfbfd4a2943a6c4df59', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit1d5e2036274043d1e0e9e3243991653e', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit2d6d15a8f6cc4bfbfd4a2943a6c4df59', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit1d5e2036274043d1e0e9e3243991653e', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit1d5e2036274043d1e0e9e3243991653e::getInitializer($loader)); $loader->register(true); - $includeFiles = \Composer\Autoload\ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::$files; - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire2d6d15a8f6cc4bfbfd4a2943a6c4df59($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInit1d5e2036274043d1e0e9e3243991653e::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -/** - * @param string $fileIdentifier - * @param string $file - * @return void - */ -function composerRequire2d6d15a8f6cc4bfbfd4a2943a6c4df59($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - - require $file; - } -} diff --git a/includes/vendor/composer/autoload_static.php b/includes/vendor/composer/autoload_static.php index acd7aa557..db0fa2a53 100644 --- a/includes/vendor/composer/autoload_static.php +++ b/includes/vendor/composer/autoload_static.php @@ -4,11 +4,10 @@ namespace Composer\Autoload; -class ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59 +class ComposerStaticInit1d5e2036274043d1e0e9e3243991653e { public static $files = array ( 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', 'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php', '941748b3c8cae4466c827dfb5ca9602a' => __DIR__ . '/..' . '/rmccue/requests/library/Deprecated.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', @@ -26,7 +25,6 @@ class ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59 ), 'S' => array ( - 'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, @@ -66,10 +64,6 @@ class ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59 array ( 0 => __DIR__ . '/..' . '/rmccue/requests/src', ), - 'Symfony\\Polyfill\\Php72\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', - ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', @@ -88,7 +82,7 @@ class ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59 ), 'Psr\\Log\\' => array ( - 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + 0 => __DIR__ . '/..' . '/psr/log/src', ), 'POMO\\' => array ( @@ -139,10 +133,10 @@ class ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::$prefixesPsr0; - $loader->classMap = ComposerStaticInit2d6d15a8f6cc4bfbfd4a2943a6c4df59::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit1d5e2036274043d1e0e9e3243991653e::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit1d5e2036274043d1e0e9e3243991653e::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInit1d5e2036274043d1e0e9e3243991653e::$prefixesPsr0; + $loader->classMap = ComposerStaticInit1d5e2036274043d1e0e9e3243991653e::$classMap; }, null, ClassLoader::class); } diff --git a/includes/vendor/composer/ca-bundle/composer.json b/includes/vendor/composer/ca-bundle/composer.json index ed6a1b364..c2ce2bb8e 100644 --- a/includes/vendor/composer/ca-bundle/composer.json +++ b/includes/vendor/composer/ca-bundle/composer.json @@ -24,13 +24,13 @@ "require": { "ext-openssl": "*", "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2 || ^5", - "phpstan/phpstan": "^0.12.55", - "psr/log": "^1.0", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + "phpunit/phpunit": "^8 || ^9", + "phpstan/phpstan": "^1.10", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "autoload": { "psr-4": { @@ -48,7 +48,7 @@ } }, "scripts": { - "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit", - "phpstan": "vendor/bin/phpstan analyse" + "test": "@php phpunit", + "phpstan": "@php phpstan analyse" } } diff --git a/includes/vendor/composer/ca-bundle/res/cacert.pem b/includes/vendor/composer/ca-bundle/res/cacert.pem index 0c69f9fc7..e8cc6c1c0 100644 --- a/includes/vendor/composer/ca-bundle/res/cacert.pem +++ b/includes/vendor/composer/ca-bundle/res/cacert.pem @@ -1,7 +1,9 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Oct 11 03:12:05 2022 GMT +## Certificate data from Mozilla as of: Tue Dec 31 04:12:05 2024 GMT +## +## Find updated versions here: https://curl.se/docs/caextract.html ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +16,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 3ff8bd209b5f2e739b9f2b96eacb694a774114685b02978257824f37ff528f71 +## SHA256: c99d6d3f8d3d4e47719ba2b648992f5b58b150128d3aca3c05c566d8dc98e116 ## @@ -200,27 +202,6 @@ vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- @@ -489,29 +470,6 @@ IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== -----END CERTIFICATE----- -Network Solutions Certificate Authority -======================================= ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG -EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr -IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx -MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx -jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT -aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT -crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc -/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB -AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv -bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA -A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q -4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ -GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD -ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - COMODO ECC Certification Authority ================================== -----BEGIN CERTIFICATE----- @@ -626,47 +584,6 @@ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - -SecureSign RootCA11 -=================== ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi -SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS -b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw -KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 -cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL -TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO -wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq -g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP -O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA -bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX -t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh -OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r -bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ -Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 -y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 -lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - Microsec e-Szigno Root CA 2009 ============================== -----BEGIN CERTIFICATE----- @@ -712,39 +629,6 @@ YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r kpeDMdmztcpHWD9f -----END CERTIFICATE----- -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - Izenpe.com ========== -----BEGIN CERTIFICATE----- @@ -1284,40 +1168,6 @@ Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -E-Tugra Certification Authority -=============================== ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w -DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls -ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw -NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx -QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl -cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD -DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd -hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K -CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g -ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ -BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 -E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz -rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq -jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 -dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB -/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG -MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK -kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO -XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 -VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo -a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc -dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV -KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT -Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 -8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G -C7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - T-TeleSec GlobalRoot Class 2 ============================ -----BEGIN CERTIFICATE----- @@ -1654,36 +1504,6 @@ uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- -Staat der Nederlanden EV Root CA -================================ ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE -CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g -RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M -MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl -cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk -SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW -O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r -0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 -Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV -XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr -08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV -0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd -74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx -fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa -ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu -c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq -5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN -b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN -f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi -5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 -WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK -DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy -eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== ------END CERTIFICATE----- - IdenTrust Commercial Root CA 1 ============================== -----BEGIN CERTIFICATE----- @@ -2135,87 +1955,6 @@ F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== -----END CERTIFICATE----- -TrustCor RootCert CA-1 -====================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP -MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig -U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx -MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu -YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe -VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy -dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq -jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4 -pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0 -JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h -gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw -/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j -BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5 -mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf -ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C -qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P -3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk= ------END CERTIFICATE----- - -TrustCor RootCert CA-2 -====================== ------BEGIN CERTIFICATE----- -MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w -DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT -eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0 -eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy -MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h -bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0 -IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb -ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk -RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1 -oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb -XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1 -/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q -jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP -eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg -rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh -8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU -2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h -Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp -kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv -2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3 -S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw -PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv -DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU -RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE -xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX -RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ ------END CERTIFICATE----- - -TrustCor ECA-1 -============== ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP -MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig -U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw -N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5 -MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y -IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR -MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23 -xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc -p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+ -fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj -YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL -f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF -AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u -/ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F -hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs -J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC -jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g== ------END CERTIFICATE----- - SSL.com Root Certification Authority RSA ======================================== -----BEGIN CERTIFICATE----- @@ -2559,40 +2298,6 @@ hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB dBb9HxEGmpv0 -----END CERTIFICATE----- -Entrust Root Certification Authority - G4 -========================================= ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu -bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1 -dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT -AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D -umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV -3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds -8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ -e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7 -ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X -xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV -7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW -Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n -MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q -jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht -7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK -YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt -jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+ -m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW -RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA -JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G -+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT -kcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- - Microsoft ECC Root Certificate Authority 2017 ============================================= -----BEGIN CERTIFICATE----- @@ -3410,85 +3115,6 @@ AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -E-Tugra Global Root CA RSA v3 -============================= ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ -BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb -BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 -IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU -UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF -LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg -djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx -jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL -sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF -/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q -QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw -bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 -04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB -eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM -bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg -h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 -LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ -gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 -38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q -ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s -SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY -sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl -DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X -nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH -IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX -YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -E-Tugra Global Root CA ECC v3 -============================= ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV -BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB -IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP -MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 -w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 -Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ -zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO -PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W -Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 ------END CERTIFICATE----- - -Security Communication RootCA3 -============================== ------BEGIN CERTIFICATE----- -MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw -IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD -b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw -CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE -AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r -hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE -NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 -/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm -npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY -XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK -p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC -3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf -GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw -CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB -/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS -YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu -Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O -H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx -YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ -XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml -+LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn -KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 -dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm -6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== ------END CERTIFICATE----- - Security Communication ECC RootCA1 ================================== -----BEGIN CERTIFICATE----- @@ -3504,3 +3130,482 @@ BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e N9k= -----END CERTIFICATE----- + +BJCA Global Root CA1 +==================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG +EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK +Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG +A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD +DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm +CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS +sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn +P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW +yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj +eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn +MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b +OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh +GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK +H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB +AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ +dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 +60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh +TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW +4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp +GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx +4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps +3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S +SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= +-----END CERTIFICATE----- + +BJCA Global Root CA2 +==================== +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD +TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg +R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE +BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC +SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl +SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK +/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI +1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 +W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g +UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root E46 +============================================= +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH +QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 +ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 +WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 +aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 +NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud +DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH +lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U +SAGKcw== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root R46 +============================================= +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 +OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k +1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf +GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP +FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu +ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz +Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A +wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF +plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ +EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW +6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI +IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp +E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 +exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M +0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI +84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m +pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd +Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b +E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm +J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +SSL.com TLS RSA Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG +EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg +Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC +VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u +9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y +7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac +oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M +R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG +D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW +TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk +8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq +g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk +7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu +N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN +j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by +iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU +o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo +ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib +MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi +vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 +P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 +9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +SSL.com TLS ECC Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v +dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx +GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy +JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 +5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 +81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG +MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w +7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 +Zn6g6g== +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA ECC TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB +dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD +VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg +VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT +AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K +DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS +b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX +NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ +uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY +a3cpetskz2VAv9LcjBHo9H1/IISpQuQo +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA RSA TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD +DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw +CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 +b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV +BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB +l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG +vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK +ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt +0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK +PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY +sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY +Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ +rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa +fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G +CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl +Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX +AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G +slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt +afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q +TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj +1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l +PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W +HYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +TrustAsia Global Root CA G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG +A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM +G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw +MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu +MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz +lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ +Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V +P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag +dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm +9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc +D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg +WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea +mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF +TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj +7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1 +D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T +G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj +duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl +cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys ++TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli +2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y +aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS +ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR +JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH +-----END CERTIFICATE----- + +TrustAsia Global Root CA G4 +=========================== +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE +BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry +dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa +MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw +IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8 +m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/ +pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA +bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk +dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNaFw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLx +eP0CflfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJEhRGnSjot +6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggqhkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2 +Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liW +pDVfG2XqYZpwI7UNo5uSUm9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRaFw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/M +MDALj2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmUv4RDsNuE +SgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggqhkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9 +Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/nich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs7 +3u1Z/GtMMH9ZzkXpc2AVmkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45Ft +nYSkYZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslhsuitQDy6 +uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0alDrJLpA6lfO741GIDuZNq +ihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3OjWiE260f6GBfZumbCk6SP/F2krfxQapWs +vCQz0b2If4b19bJzKo98rwjyGpg/qYFlP8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/c +Zip8UlF1y5mO6D1cv547KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTif +BSeolz7pUcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/kQO9 +lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JOHg9O5j9ZpSPcPYeo +KFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkBEa801M/XrmLTBQe0MXXgDW1XT2mH ++VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6UCBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm4 +5P3luG0wDQYJKoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQnmhUQo8mUuJM +3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+QgvfKNmwrZggvkN80V4aCRck +jXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2vtrV0KnahP/t1MJ+UXjulYPPLXAziDslg+Mkf +Foom3ecnf+slpoq9uC02EJqxWE2aaE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/W +NyVntHKLr4W96ioDj8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+ +o/E4Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0wlREQKC6/ +oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHnYfkUyq+Dj7+vsQpZXdxc +1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVocicCMb3SgazNNtQEo/a2tiRc7ppqEvOuM +6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3V +rCLENQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0kyI9p+Kx +7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1CrWDaSWqVcN3SAOLMV2MC +e5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxzhkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2W +Wy09X6GDRl224yW4fKcZgBzqZUPckXk2LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rp +M9kzXzehxfCrPfp4sOcsn/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIf +hs1w/tkuFT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5kQMr +eyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3wNemKfrb3vOTlycE +VS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6vwQcQeKwRoi9C8DfF8rhW3Q5iLc4t +Vn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7Gx +cJXvYXowDQYJKoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3+VGXu6TwYofF +1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbymeAPnCKfWxkxlSaRosTKCL4BWa +MS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3NyqpgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xd +gSGn2rtO/+YHqP65DSdsu3BaVXoT6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2O +HG1QAk8mGEPej1WFsQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+Nm +YWvtPjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2dlklyALKr +dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ +iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN +lM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- + +Telekom Security TLS ECC Root 2020 +================================== +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE +RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl +a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz +NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg +R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG +SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1 +2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC +MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ +Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU +ga/sf+Rn27iQ7t0l +-----END CERTIFICATE----- + +Telekom Security TLS RSA Root 2023 +================================== +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG +EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU +ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy +NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp +dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC +KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP +GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx +UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo +l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9 +FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v +zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg +rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML +KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S +WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+ +sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp +kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy +/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4 +mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz +aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa +oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8 +wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE +HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0 +o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +FIRMAPROFESIONAL CA ROOT-A WEB +============================== +-----BEGIN CERTIFICATE----- +MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF +UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4 +MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2 +WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h +bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM +IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6 +iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg +st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD +Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB +/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL +cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ +pYXFuXqUPoeovQA= +-----END CERTIFICATE----- + +TWCA CYBER Root CA +================== +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s +Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh +V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT +o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT +Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK +/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH +IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM +fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF +2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR +wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83 +QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN +c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x +X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR +IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq +/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R +FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe +Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv +It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl +IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +SecureSign Root CA12 +==================== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3 +emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mtp7JIKwcc +J/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zdJ1M3s6oYwlkm7Fsf0uZl +fO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gurFzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBF +EaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1Uef +NzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOC +AQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQi +LUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpce +mik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPS +vWKErI4cqc1avTc7bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhga +aaI5gdka9at/yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +SecureSign Root CA14 +==================== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh +1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn +bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb +1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa +/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE +kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx +jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz +ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0 +dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY +AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq +YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA +ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds +Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG +FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q +nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/ +OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa +OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO +pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN +eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S +-----END CERTIFICATE----- + +SecureSign Root CA15 +==================== +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE +BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1 +cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV +BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj +dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G +dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB +2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J +fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ +SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- diff --git a/includes/vendor/composer/ca-bundle/src/CaBundle.php b/includes/vendor/composer/ca-bundle/src/CaBundle.php index d99c00f69..2d6b48c56 100644 --- a/includes/vendor/composer/ca-bundle/src/CaBundle.php +++ b/includes/vendor/composer/ca-bundle/src/CaBundle.php @@ -24,8 +24,6 @@ class CaBundle private static $caPath; /** @var array */ private static $caFileValidity = array(); - /** @var bool|null */ - private static $useOpensslParse; /** * Returns the system CA bundle path, or a path to the bundled one @@ -64,7 +62,7 @@ class CaBundle * @param LoggerInterface $logger optional logger for information about which CA files were loaded * @return string path to a CA bundle file or directory */ - public static function getSystemCaRootBundlePath(LoggerInterface $logger = null) + public static function getSystemCaRootBundlePath(?LoggerInterface $logger = null) { if (self::$caPath !== null) { return self::$caPath; @@ -86,21 +84,19 @@ public static function getSystemCaRootBundlePath(LoggerInterface $logger = null) '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package) '/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package) '/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package) - '/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package) '/usr/ssl/certs/ca-bundle.crt', // Cygwin '/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package '/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option) '/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat? '/etc/ssl/cert.pem', // OpenBSD - '/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x '/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package '/usr/local/etc/openssl@1.1/cert.pem', // OS X homebrew, openssl@1.1 package + '/opt/homebrew/etc/openssl@3/cert.pem', // macOS silicon homebrew, openssl@3 package + '/opt/homebrew/etc/openssl@1.1/cert.pem', // macOS silicon homebrew, openssl@1.1 package + '/etc/pki/tls/certs', + '/etc/ssl/certs', // FreeBSD ); - foreach($otherLocations as $location) { - $otherLocations[] = dirname($location); - } - $caBundlePaths = array_merge($caBundlePaths, $otherLocations); foreach ($caBundlePaths as $caBundle) { @@ -158,7 +154,7 @@ public static function getBundledCaBundlePath() * * @return bool */ - public static function validateCaFile($filename, LoggerInterface $logger = null) + public static function validateCaFile($filename, ?LoggerInterface $logger = null) { static $warned = false; @@ -168,19 +164,7 @@ public static function validateCaFile($filename, LoggerInterface $logger = null) $contents = file_get_contents($filename); - // assume the CA is valid if php is vulnerable to - // https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html - if (!static::isOpensslParseSafe()) { - if (!$warned && $logger) { - $logger->warning(sprintf( - 'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.', - PHP_VERSION - )); - $warned = true; - } - - $isValid = !empty($contents); - } elseif (is_string($contents) && strlen($contents) > 0) { + if (is_string($contents) && strlen($contents) > 0) { $contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents); if (null === $contents) { // regex extraction failed @@ -209,100 +193,7 @@ public static function validateCaFile($filename, LoggerInterface $logger = null) */ public static function isOpensslParseSafe() { - if (null !== self::$useOpensslParse) { - return self::$useOpensslParse; - } - - if (PHP_VERSION_ID >= 50600) { - return self::$useOpensslParse = true; - } - - // Vulnerable: - // PHP 5.3.0 - PHP 5.3.27 - // PHP 5.4.0 - PHP 5.4.22 - // PHP 5.5.0 - PHP 5.5.6 - if ( - (PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328) - || (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423) - || PHP_VERSION_ID >= 50507 - ) { - // This version of PHP has the fix for CVE-2013-6420 applied. - return self::$useOpensslParse = true; - } - - if (defined('PHP_WINDOWS_VERSION_BUILD')) { - // Windows is probably insecure in this case. - return self::$useOpensslParse = false; - } - - $compareDistroVersionPrefix = function ($prefix, $fixedVersion) { - $regex = '{^'.preg_quote($prefix).'([0-9]+)$}'; - - if (preg_match($regex, PHP_VERSION, $m)) { - return ((int) $m[1]) >= $fixedVersion; - } - - return false; - }; - - // Hard coded list of PHP distributions with the fix backported. - if ( - $compareDistroVersionPrefix('5.3.3-7+squeeze', 18) // Debian 6 (Squeeze) - || $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) // Debian 7 (Wheezy) - || $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) // Ubuntu 12.04 (Precise) - ) { - return self::$useOpensslParse = true; - } - - // Symfony Process component is missing so we assume it is unsafe at this point - if (!class_exists('Symfony\Component\Process\PhpProcess')) { - return self::$useOpensslParse = false; - } - - // This is where things get crazy, because distros backport security - // fixes the chances are on NIX systems the fix has been applied but - // it's not possible to verify that from the PHP version. - // - // To verify exec a new PHP process and run the issue testcase with - // known safe input that replicates the bug. - - // Based on testcase in https://github.com/php/php-src/commit/c1224573c773b6845e83505f717fbf820fc18415 - // changes in https://github.com/php/php-src/commit/76a7fd893b7d6101300cc656058704a73254d593 - $cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K'; - $script = <<<'EOT' - -error_reporting(-1); -$info = openssl_x509_parse(base64_decode('%s')); -var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']); - -EOT; - $script = '<'."?php\n".sprintf($script, $cert); - - try { - $process = new PhpProcess($script); - $process->mustRun(); - } catch (\Exception $e) { - // In the case of any exceptions just accept it is not possible to - // determine the safety of openssl_x509_parse and bail out. - return self::$useOpensslParse = false; - } - - $output = preg_split('{\r?\n}', trim($process->getOutput())); - $errorOutput = trim($process->getErrorOutput()); - - if ( - is_array($output) - && count($output) === 3 - && $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION) - && $output[1] === 'string(27) "stefan.esser@sektioneins.de"' - && $output[2] === 'int(-1)' - && preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput) - ) { - // This PHP has the fix backported probably by a distro security team. - return self::$useOpensslParse = true; - } - - return self::$useOpensslParse = false; + return true; } /** @@ -313,7 +204,6 @@ public static function reset() { self::$caFileValidity = array(); self::$caPath = null; - self::$useOpensslParse = null; } /** @@ -338,12 +228,12 @@ private static function getEnvVariable($name) * @param LoggerInterface|null $logger * @return bool */ - private static function caFileUsable($certFile, LoggerInterface $logger = null) + private static function caFileUsable($certFile, ?LoggerInterface $logger = null) { return $certFile - && static::isFile($certFile, $logger) - && static::isReadable($certFile, $logger) - && static::validateCaFile($certFile, $logger); + && self::isFile($certFile, $logger) + && self::isReadable($certFile, $logger) + && self::validateCaFile($certFile, $logger); } /** @@ -351,12 +241,12 @@ private static function caFileUsable($certFile, LoggerInterface $logger = null) * @param LoggerInterface|null $logger * @return bool */ - private static function caDirUsable($certDir, LoggerInterface $logger = null) + private static function caDirUsable($certDir, ?LoggerInterface $logger = null) { return $certDir - && static::isDir($certDir, $logger) - && static::isReadable($certDir, $logger) - && static::glob($certDir . '/*', $logger); + && self::isDir($certDir, $logger) + && self::isReadable($certDir, $logger) + && self::glob($certDir . '/*', $logger); } /** @@ -364,7 +254,7 @@ private static function caDirUsable($certDir, LoggerInterface $logger = null) * @param LoggerInterface|null $logger * @return bool */ - private static function isFile($certFile, LoggerInterface $logger = null) + private static function isFile($certFile, ?LoggerInterface $logger = null) { $isFile = @is_file($certFile); if (!$isFile && $logger) { @@ -379,7 +269,7 @@ private static function isFile($certFile, LoggerInterface $logger = null) * @param LoggerInterface|null $logger * @return bool */ - private static function isDir($certDir, LoggerInterface $logger = null) + private static function isDir($certDir, ?LoggerInterface $logger = null) { $isDir = @is_dir($certDir); if (!$isDir && $logger) { @@ -394,7 +284,7 @@ private static function isDir($certDir, LoggerInterface $logger = null) * @param LoggerInterface|null $logger * @return bool */ - private static function isReadable($certFileOrDir, LoggerInterface $logger = null) + private static function isReadable($certFileOrDir, ?LoggerInterface $logger = null) { $isReadable = @is_readable($certFileOrDir); if (!$isReadable && $logger) { @@ -409,7 +299,7 @@ private static function isReadable($certFileOrDir, LoggerInterface $logger = nul * @param LoggerInterface|null $logger * @return bool */ - private static function glob($pattern, LoggerInterface $logger = null) + private static function glob($pattern, ?LoggerInterface $logger = null) { $certs = glob($pattern); if ($certs === false) { diff --git a/includes/vendor/composer/installed.json b/includes/vendor/composer/installed.json index 9598e030b..b6245f368 100644 --- a/includes/vendor/composer/installed.json +++ b/includes/vendor/composer/installed.json @@ -2,28 +2,29 @@ "packages": [ { "name": "aura/sql", - "version": "3.1.0", - "version_normalized": "3.1.0.0", + "version": "6.0.0", + "version_normalized": "6.0.0.0", "source": { "type": "git", "url": "https://github.com/auraphp/Aura.Sql.git", - "reference": "88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca" + "reference": "8e2bb362e8953198df3682c9122e8b9edab5ff20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/auraphp/Aura.Sql/zipball/88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca", - "reference": "88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca", + "url": "https://api.github.com/repos/auraphp/Aura.Sql/zipball/8e2bb362e8953198df3682c9122e8b9edab5ff20", + "reference": "8e2bb362e8953198df3682c9122e8b9edab5ff20", "shasum": "" }, "require": { - "php": ">=5.6.0", - "psr/log": "^1.0 || ^2.0" + "ext-pdo": "*", + "php": "^8.4", + "psr/log": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "pds/skeleton": "~1.0", - "yoast/phpunit-polyfills": "~1.0" + "phpunit/phpunit": "^9.5" }, - "time": "2022-04-28T05:11:23+00:00", + "time": "2025-01-22T06:43:21+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -56,37 +57,37 @@ ], "support": { "issues": "https://github.com/auraphp/Aura.Sql/issues", - "source": "https://github.com/auraphp/Aura.Sql/tree/3.1.0" + "source": "https://github.com/auraphp/Aura.Sql/tree/6.0.0" }, "install-path": "../aura/sql" }, { "name": "composer/ca-bundle", - "version": "1.3.4", - "version_normalized": "1.3.4.0", + "version": "1.5.5", + "version_normalized": "1.5.5.0", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5" + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/69098eca243998b53eed7a48d82dedd28b447cd5", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/08c50d5ec4c6ced7d0271d2862dec8c1033283e6", + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6", "shasum": "" }, "require": { "ext-openssl": "*", "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "psr/log": "^1.0", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, - "time": "2022-10-12T12:08:29+00:00", + "time": "2025-01-08T16:17:16+00:00", "type": "library", "extra": { "branch-alias": { @@ -121,7 +122,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.4" + "source": "https://github.com/composer/ca-bundle/tree/1.5.5" }, "funding": [ { @@ -145,7 +146,7 @@ "version_normalized": "2.13.0.0", "source": { "type": "git", - "url": "git@github.com:maxmind/GeoIP2-php.git", + "url": "https://github.com/maxmind/GeoIP2-php.git", "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23" }, "dist": { @@ -194,6 +195,10 @@ "geolocation", "maxmind" ], + "support": { + "issues": "https://github.com/maxmind/GeoIP2-php/issues", + "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.13.0" + }, "install-path": "../geoip2/geoip2" }, { @@ -230,34 +235,36 @@ } ], "description": "Provides functionality for http_build_url() to environments without pecl_http.", + "support": { + "issues": "https://github.com/jakeasmith/http_build_url/issues", + "source": "https://github.com/jakeasmith/http_build_url" + }, "install-path": "../jakeasmith/http_build_url" }, { "name": "maxmind-db/reader", - "version": "v1.11.0", - "version_normalized": "1.11.0.0", + "version": "v1.12.0", + "version_normalized": "1.12.0.0", "source": { "type": "git", "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", - "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b" + "reference": "5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b1f3c0699525336d09cc5161a2861268d9f2ae5b", - "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90", + "reference": "5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90", "shasum": "" }, "require": { "php": ">=7.2" }, "conflict": { - "ext-maxminddb": "<1.10.1,>=2.0.0" + "ext-maxminddb": "<1.11.1 || >=2.0.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.*", - "php-coveralls/php-coveralls": "^2.1", "phpstan/phpstan": "*", - "phpunit/phpcov": ">=6.0.0", "phpunit/phpunit": ">=8.0.0,<10.0.0", "squizlabs/php_codesniffer": "3.*" }, @@ -266,7 +273,7 @@ "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" }, - "time": "2021-10-18T15:23:10+00:00", + "time": "2024-11-14T22:43:47+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -296,30 +303,30 @@ ], "support": { "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", - "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.11.0" + "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.12.0" }, "install-path": "../maxmind-db/reader" }, { "name": "maxmind/web-service-common", - "version": "v0.9.0", - "version_normalized": "0.9.0.0", + "version": "v0.10.0", + "version_normalized": "0.10.0.0", "source": { "type": "git", "url": "https://github.com/maxmind/web-service-common-php.git", - "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53" + "reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", - "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4", + "reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0.3", "ext-curl": "*", "ext-json": "*", - "php": ">=7.2" + "php": ">=8.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.*", @@ -327,7 +334,7 @@ "phpunit/phpunit": "^8.0 || ^9.0", "squizlabs/php_codesniffer": "3.*" }, - "time": "2022-03-28T17:43:20+00:00", + "time": "2024-11-14T23:14:52+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -350,7 +357,7 @@ "homepage": "https://github.com/maxmind/web-service-common-php", "support": { "issues": "https://github.com/maxmind/web-service-common-php/issues", - "source": "https://github.com/maxmind/web-service-common-php/tree/v0.9.0" + "source": "https://github.com/maxmind/web-service-common-php/tree/v0.10.0" }, "install-path": "../maxmind/web-service-common" }, @@ -475,33 +482,33 @@ }, { "name": "psr/log", - "version": "1.1.4", - "version_normalized": "1.1.4.0", + "version": "3.0.2", + "version_normalized": "3.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, - "time": "2021-05-03T11:20:27+00:00", + "time": "2024-09-11T13:17:53+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -522,23 +529,23 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, "install-path": "../psr/log" }, { "name": "rmccue/requests", - "version": "v2.0.5", - "version_normalized": "2.0.5.0", + "version": "v2.0.15", + "version_normalized": "2.0.15.0", "source": { "type": "git", "url": "https://github.com/WordPress/Requests.git", - "reference": "b717f1d2f4ef7992ec0c127747ed8b7e170c2f49" + "reference": "877cd66169755899682f1595e057334b40d9d149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/Requests/zipball/b717f1d2f4ef7992ec0c127747ed8b7e170c2f49", - "reference": "b717f1d2f4ef7992ec0c127747ed8b7e170c2f49", + "url": "https://api.github.com/repos/WordPress/Requests/zipball/877cd66169755899682f1595e057334b40d9d149", + "reference": "877cd66169755899682f1595e057334b40d9d149", "shasum": "" }, "require": { @@ -556,7 +563,13 @@ "wp-coding-standards/wpcs": "^2.0", "yoast/phpunit-polyfills": "^1.0.0" }, - "time": "2022-10-11T08:15:28+00:00", + "suggest": { + "art4/requests-psr18-adapter": "For using Requests as a PSR-18 HTTP Client", + "ext-curl": "For improved performance", + "ext-openssl": "For secure transport support", + "ext-zlib": "For improved performance when decompressing encoded streams" + }, + "time": "2025-01-21T10:13:31+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -679,36 +692,32 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2022-11-03T14:55:06+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -749,7 +758,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { @@ -769,34 +778,31 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2022-11-03T14:55:06+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -836,7 +842,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -856,21 +862,21 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -878,15 +884,12 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2022-11-03T14:55:06+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -922,7 +925,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -939,85 +942,6 @@ } ], "install-path": "../symfony/polyfill-mbstring" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2022-11-03T14:55:06+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-php72" } ], "dev": true, diff --git a/includes/vendor/composer/installed.php b/includes/vendor/composer/installed.php index 4358d2d3d..d14431897 100644 --- a/includes/vendor/composer/installed.php +++ b/includes/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'yourls/yourls', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '9f7806c525ef266bb74bdd501463799e45fe2be5', + 'reference' => '2af3c2bc8b959cb3c543d06bbfc80512c87eed22', 'type' => 'project', 'install_path' => __DIR__ . '/../../../', 'aliases' => array(), @@ -11,18 +11,18 @@ ), 'versions' => array( 'aura/sql' => array( - 'pretty_version' => '3.1.0', - 'version' => '3.1.0.0', - 'reference' => '88d8b8ed1bcfd588a649fdc7e7ac89ec047abbca', + 'pretty_version' => '6.0.0', + 'version' => '6.0.0.0', + 'reference' => '8e2bb362e8953198df3682c9122e8b9edab5ff20', 'type' => 'library', 'install_path' => __DIR__ . '/../aura/sql', 'aliases' => array(), 'dev_requirement' => false, ), 'composer/ca-bundle' => array( - 'pretty_version' => '1.3.4', - 'version' => '1.3.4.0', - 'reference' => '69098eca243998b53eed7a48d82dedd28b447cd5', + 'pretty_version' => '1.5.5', + 'version' => '1.5.5.0', + 'reference' => '08c50d5ec4c6ced7d0271d2862dec8c1033283e6', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(), @@ -47,18 +47,18 @@ 'dev_requirement' => false, ), 'maxmind-db/reader' => array( - 'pretty_version' => 'v1.11.0', - 'version' => '1.11.0.0', - 'reference' => 'b1f3c0699525336d09cc5161a2861268d9f2ae5b', + 'pretty_version' => 'v1.12.0', + 'version' => '1.12.0.0', + 'reference' => '5b2d7a721dedfaef9dc20822c5fe7d26f9f8eb90', 'type' => 'library', 'install_path' => __DIR__ . '/../maxmind-db/reader', 'aliases' => array(), 'dev_requirement' => false, ), 'maxmind/web-service-common' => array( - 'pretty_version' => 'v0.9.0', - 'version' => '0.9.0.0', - 'reference' => '4dc5a3e8df38aea4ca3b1096cee3a038094e9b53', + 'pretty_version' => 'v0.10.0', + 'version' => '0.10.0.0', + 'reference' => 'd7c7c42fc31bff26e0ded73a6e187bcfb193f9c4', 'type' => 'library', 'install_path' => __DIR__ . '/../maxmind/web-service-common', 'aliases' => array(), @@ -83,18 +83,18 @@ 'dev_requirement' => false, ), 'psr/log' => array( - 'pretty_version' => '1.1.4', - 'version' => '1.1.4.0', - 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'pretty_version' => '3.0.2', + 'version' => '3.0.2.0', + 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => false, ), 'rmccue/requests' => array( - 'pretty_version' => 'v2.0.5', - 'version' => '2.0.5.0', - 'reference' => 'b717f1d2f4ef7992ec0c127747ed8b7e170c2f49', + 'pretty_version' => 'v2.0.15', + 'version' => '2.0.15.0', + 'reference' => '877cd66169755899682f1595e057334b40d9d149', 'type' => 'library', 'install_path' => __DIR__ . '/../rmccue/requests', 'aliases' => array(), @@ -110,45 +110,36 @@ 'dev_requirement' => false, ), 'symfony/polyfill-intl-idn' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '639084e360537a19f9ee352433b84ce831f3d2da', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => 'c36586dcf89a12315939e00ec9b4474adcb1d773', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-intl-normalizer' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '19bd1e4fcd5b91116f14d8533c57831ed00571b6', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '3833d7255cc303546435cb650316bff708a1c75c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534', + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => false, ), - 'symfony/polyfill-php72' => array( - 'pretty_version' => 'v1.27.0', - 'version' => '1.27.0.0', - 'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-php72', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'yourls/yourls' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '9f7806c525ef266bb74bdd501463799e45fe2be5', + 'reference' => '2af3c2bc8b959cb3c543d06bbfc80512c87eed22', 'type' => 'project', 'install_path' => __DIR__ . '/../../../', 'aliases' => array(), diff --git a/includes/vendor/composer/platform_check.php b/includes/vendor/composer/platform_check.php index 580fa9609..4c3a5d68f 100644 --- a/includes/vendor/composer/platform_check.php +++ b/includes/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 70400)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/includes/vendor/maxmind-db/reader/README.md b/includes/vendor/maxmind-db/reader/README.md index 49fa28001..afefc3fd1 100644 --- a/includes/vendor/maxmind-db/reader/README.md +++ b/includes/vendor/maxmind-db/reader/README.md @@ -132,7 +132,7 @@ make test sudo make install ``` -You then must load your extension. The recommend method is to add the +You then must load your extension. The recommended method is to add the following to your `php.ini` file: ``` @@ -180,6 +180,6 @@ The MaxMind DB Reader PHP API uses [Semantic Versioning](https://semver.org/). ## Copyright and License ## -This software is Copyright (c) 2014-2020 by MaxMind, Inc. +This software is Copyright (c) 2014-2024 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. diff --git a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php index 4dfaef442..12c6b0950 100644 --- a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php +++ b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php @@ -4,15 +4,10 @@ namespace MaxMind\Db; -use ArgumentCountError; -use BadMethodCallException; -use Exception; -use InvalidArgumentException; use MaxMind\Db\Reader\Decoder; use MaxMind\Db\Reader\InvalidDatabaseException; use MaxMind\Db\Reader\Metadata; use MaxMind\Db\Reader\Util; -use UnexpectedValueException; /** * Instances of this class provide a reader for the MaxMind DB format. IP @@ -24,14 +19,17 @@ class Reader * @var int */ private static $DATA_SECTION_SEPARATOR_SIZE = 16; + /** * @var string */ private static $METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com"; + /** - * @var int + * @var int<0, max> */ private static $METADATA_START_MARKER_LENGTH = 14; + /** * @var int */ @@ -41,18 +39,22 @@ class Reader * @var Decoder */ private $decoder; + /** * @var resource */ private $fileHandle; + /** * @var int */ private $fileSize; + /** * @var int */ private $ipV4Start; + /** * @var Metadata */ @@ -62,25 +64,31 @@ class Reader * Constructs a Reader for the MaxMind DB format. The file passed to it must * be a valid MaxMind DB file such as a GeoIp2 database file. * - * @param string $database - * the MaxMind DB file to use + * @param string $database the MaxMind DB file to use * - * @throws InvalidArgumentException for invalid database path or unknown arguments + * @throws \InvalidArgumentException for invalid database path or unknown arguments * @throws InvalidDatabaseException - * if the database is invalid or there is an error reading - * from it + * if the database is invalid or there is an error reading + * from it */ public function __construct(string $database) { if (\func_num_args() !== 1) { - throw new ArgumentCountError( - sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) + throw new \ArgumentCountError( + \sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) + ); + } + + if (is_dir($database)) { + // This matches the error that the C extension throws. + throw new InvalidDatabaseException( + "Error opening database file ($database). Is this a valid MaxMind DB file?" ); } $fileHandle = @fopen($database, 'rb'); if ($fileHandle === false) { - throw new InvalidArgumentException( + throw new \InvalidArgumentException( "The file \"$database\" does not exist or is not readable." ); } @@ -88,7 +96,7 @@ public function __construct(string $database) $fileSize = @filesize($database); if ($fileSize === false) { - throw new UnexpectedValueException( + throw new \UnexpectedValueException( "Error determining the size of \"$database\"." ); } @@ -108,22 +116,21 @@ public function __construct(string $database) /** * Retrieves the record for the IP address. * - * @param string $ipAddress - * the IP address to look up + * @param string $ipAddress the IP address to look up * - * @throws BadMethodCallException if this method is called on a closed database - * @throws InvalidArgumentException if something other than a single IP address is passed to the method + * @throws \BadMethodCallException if this method is called on a closed database + * @throws \InvalidArgumentException if something other than a single IP address is passed to the method * @throws InvalidDatabaseException - * if the database is invalid or there is an error reading - * from it + * if the database is invalid or there is an error reading + * from it * * @return mixed the record for the IP address */ public function get(string $ipAddress) { if (\func_num_args() !== 1) { - throw new ArgumentCountError( - sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) + throw new \ArgumentCountError( + \sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) ); } [$record] = $this->getWithPrefixLen($ipAddress); @@ -134,28 +141,27 @@ public function get(string $ipAddress) /** * Retrieves the record for the IP address and its associated network prefix length. * - * @param string $ipAddress - * the IP address to look up + * @param string $ipAddress the IP address to look up * - * @throws BadMethodCallException if this method is called on a closed database - * @throws InvalidArgumentException if something other than a single IP address is passed to the method + * @throws \BadMethodCallException if this method is called on a closed database + * @throws \InvalidArgumentException if something other than a single IP address is passed to the method * @throws InvalidDatabaseException - * if the database is invalid or there is an error reading - * from it + * if the database is invalid or there is an error reading + * from it * - * @return array an array where the first element is the record and the - * second the network prefix length for the record + * @return array{0:mixed, 1:int} an array where the first element is the record and the + * second the network prefix length for the record */ public function getWithPrefixLen(string $ipAddress): array { if (\func_num_args() !== 1) { - throw new ArgumentCountError( - sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) + throw new \ArgumentCountError( + \sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) ); } if (!\is_resource($this->fileHandle)) { - throw new BadMethodCallException( + throw new \BadMethodCallException( 'Attempt to read from a closed MaxMind DB.' ); } @@ -168,16 +174,24 @@ public function getWithPrefixLen(string $ipAddress): array return [$this->resolveDataPointer($pointer), $prefixLen]; } + /** + * @return array{0:int, 1:int} + */ private function findAddressInTree(string $ipAddress): array { $packedAddr = @inet_pton($ipAddress); if ($packedAddr === false) { - throw new InvalidArgumentException( + throw new \InvalidArgumentException( "The value \"$ipAddress\" is not a valid IP address." ); } $rawAddress = unpack('C*', $packedAddr); + if ($rawAddress === false) { + throw new InvalidDatabaseException( + 'Could not unpack the unsigned char of the packed in_addr representation.' + ); + } $bitCount = \count($rawAddress) * 8; @@ -194,7 +208,7 @@ private function findAddressInTree(string $ipAddress): array $node = $this->ipV4Start; } } elseif ($metadata->ipVersion === 4 && $bitCount === 128) { - throw new InvalidArgumentException( + throw new \InvalidArgumentException( "Error looking up $ipAddress. You attempted to look up an" . ' IPv6 address in an IPv4-only database.' ); @@ -245,7 +259,13 @@ private function readNode(int $nodeNumber, int $index): int switch ($this->metadata->recordSize) { case 24: $bytes = Util::read($this->fileHandle, $baseOffset + $index * 3, 3); - [, $node] = unpack('N', "\x00" . $bytes); + $rc = unpack('N', "\x00" . $bytes); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack the unsigned long of the node.' + ); + } + [, $node] = $rc; return $node; @@ -256,13 +276,25 @@ private function readNode(int $nodeNumber, int $index): int } else { $middle = 0x0F & \ord($bytes[0]); } - [, $node] = unpack('N', \chr($middle) . substr($bytes, $index, 3)); + $rc = unpack('N', \chr($middle) . substr($bytes, $index, 3)); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack the unsigned long of the node.' + ); + } + [, $node] = $rc; return $node; case 32: $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 4); - [, $node] = unpack('N', $bytes); + $rc = unpack('N', $bytes); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack the unsigned long of the node.' + ); + } + [, $node] = $rc; return $node; @@ -301,6 +333,11 @@ private function findMetadataStart(string $filename): int { $handle = $this->fileHandle; $fstat = fstat($handle); + if ($fstat === false) { + throw new InvalidDatabaseException( + "Error getting file information ($filename)." + ); + } $fileSize = $fstat['size']; $marker = self::$METADATA_START_MARKER; $markerLength = self::$METADATA_START_MARKER_LENGTH; @@ -325,23 +362,23 @@ private function findMetadataStart(string $filename): int } /** - * @throws InvalidArgumentException if arguments are passed to the method - * @throws BadMethodCallException if the database has been closed + * @throws \InvalidArgumentException if arguments are passed to the method + * @throws \BadMethodCallException if the database has been closed * * @return Metadata object for the database */ public function metadata(): Metadata { if (\func_num_args()) { - throw new ArgumentCountError( - sprintf('%s() expects exactly 0 parameters, %d given', __METHOD__, \func_num_args()) + throw new \ArgumentCountError( + \sprintf('%s() expects exactly 0 parameters, %d given', __METHOD__, \func_num_args()) ); } // Not technically required, but this makes it consistent with // C extension and it allows us to change our implementation later. if (!\is_resource($this->fileHandle)) { - throw new BadMethodCallException( + throw new \BadMethodCallException( 'Attempt to read from a closed MaxMind DB.' ); } @@ -352,19 +389,19 @@ public function metadata(): Metadata /** * Closes the MaxMind DB and returns resources to the system. * - * @throws Exception - * if an I/O error occurs + * @throws \Exception + * if an I/O error occurs */ public function close(): void { if (\func_num_args()) { - throw new ArgumentCountError( - sprintf('%s() expects exactly 0 parameters, %d given', __METHOD__, \func_num_args()) + throw new \ArgumentCountError( + \sprintf('%s() expects exactly 0 parameters, %d given', __METHOD__, \func_num_args()) ); } if (!\is_resource($this->fileHandle)) { - throw new BadMethodCallException( + throw new \BadMethodCallException( 'Attempt to close a closed MaxMind DB.' ); } diff --git a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php index babaed878..1bb673167 100644 --- a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php +++ b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php @@ -5,7 +5,6 @@ namespace MaxMind\Db\Reader; // @codingStandardsIgnoreLine -use RuntimeException; class Decoder { @@ -13,20 +12,19 @@ class Decoder * @var resource */ private $fileStream; + /** * @var int */ private $pointerBase; - /** - * @var float - */ - private $pointerBaseByteSize; + /** * This is only used for unit testing. * * @var bool */ private $pointerTestHack; + /** * @var bool */ @@ -44,8 +42,8 @@ class Decoder private const _UINT64 = 9; private const _UINT128 = 10; private const _ARRAY = 11; - private const _CONTAINER = 12; - private const _END_MARKER = 13; + // 12 is the container type + // 13 is the end marker type private const _BOOLEAN = 14; private const _FLOAT = 15; @@ -60,12 +58,14 @@ public function __construct( $this->fileStream = $fileStream; $this->pointerBase = $pointerBase; - $this->pointerBaseByteSize = $pointerBase > 0 ? log($pointerBase, 2) / 8 : 0; $this->pointerTestHack = $pointerTestHack; $this->switchByteOrder = $this->isPlatformLittleEndian(); } + /** + * @return array + */ public function decode(int $offset): array { $ctrlByte = \ord(Util::read($this->fileStream, $offset, 1)); @@ -111,6 +111,11 @@ public function decode(int $offset): array return $this->decodeByType($type, $offset, $size); } + /** + * @param int<0, max> $size + * + * @return array{0:mixed, 1:int} + */ private function decodeByType(int $type, int $offset, int $size): array { switch ($type) { @@ -167,6 +172,9 @@ private function verifySize(int $expected, int $actual): void } } + /** + * @return array{0:array, 1:int} + */ private function decodeArray(int $size, int $offset): array { $array = []; @@ -188,7 +196,13 @@ private function decodeDouble(string $bytes): float { // This assumes IEEE 754 doubles, but most (all?) modern platforms // use them. - [, $double] = unpack('E', $bytes); + $rc = unpack('E', $bytes); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack a double value from the given bytes.' + ); + } + [, $double] = $rc; return $double; } @@ -197,7 +211,13 @@ private function decodeFloat(string $bytes): float { // This assumes IEEE 754 floats, but most (all?) modern platforms // use them. - [, $float] = unpack('G', $bytes); + $rc = unpack('G', $bytes); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack a float value from the given bytes.' + ); + } + [, $float] = $rc; return $float; } @@ -224,11 +244,20 @@ private function decodeInt32(string $bytes, int $size): int ); } - [, $int] = unpack('l', $this->maybeSwitchByteOrder($bytes)); + $rc = unpack('l', $this->maybeSwitchByteOrder($bytes)); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack a 32bit integer value from the given bytes.' + ); + } + [, $int] = $rc; return $int; } + /** + * @return array{0:array, 1:int} + */ private function decodeMap(int $size, int $offset): array { $map = []; @@ -242,24 +271,39 @@ private function decodeMap(int $size, int $offset): array return [$map, $offset]; } + /** + * @return array{0:int, 1:int} + */ private function decodePointer(int $ctrlByte, int $offset): array { $pointerSize = (($ctrlByte >> 3) & 0x3) + 1; $buffer = Util::read($this->fileStream, $offset, $pointerSize); - $offset = $offset + $pointerSize; + $offset += $pointerSize; switch ($pointerSize) { case 1: $packed = \chr($ctrlByte & 0x7) . $buffer; - [, $pointer] = unpack('n', $packed); + $rc = unpack('n', $packed); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack an unsigned short value from the given bytes (pointerSize is 1).' + ); + } + [, $pointer] = $rc; $pointer += $this->pointerBase; break; case 2: $packed = "\x00" . \chr($ctrlByte & 0x7) . $buffer; - [, $pointer] = unpack('N', $packed); + $rc = unpack('N', $packed); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack an unsigned long value from the given bytes (pointerSize is 2).' + ); + } + [, $pointer] = $rc; $pointer += $this->pointerBase + 2048; break; @@ -269,7 +313,13 @@ private function decodePointer(int $ctrlByte, int $offset): array // It is safe to use 'N' here, even on 32 bit machines as the // first bit is 0. - [, $pointer] = unpack('N', $packed); + $rc = unpack('N', $packed); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack an unsigned long value from the given bytes (pointerSize is 3).' + ); + } + [, $pointer] = $rc; $pointer += $this->pointerBase + 526336; break; @@ -284,7 +334,7 @@ private function decodePointer(int $ctrlByte, int $offset): array if (\PHP_INT_MAX - $pointerBase >= $pointerOffset) { $pointer = $pointerOffset + $pointerBase; } else { - throw new RuntimeException( + throw new \RuntimeException( 'The database offset is too large to be represented on your platform.' ); } @@ -307,34 +357,44 @@ private function decodeUint(string $bytes, int $byteLength) return 0; } - $integer = 0; - // PHP integers are signed. PHP_INT_SIZE - 1 is the number of // complete bytes that can be converted to an integer. However, // we can convert another byte if the leading bit is zero. $useRealInts = $byteLength <= \PHP_INT_SIZE - 1 || ($byteLength === \PHP_INT_SIZE && (\ord($bytes[0]) & 0x80) === 0); + if ($useRealInts) { + $integer = 0; + for ($i = 0; $i < $byteLength; ++$i) { + $part = \ord($bytes[$i]); + $integer = ($integer << 8) + $part; + } + + return $integer; + } + + // We only use gmp or bcmath if the final value is too big + $integerAsString = '0'; for ($i = 0; $i < $byteLength; ++$i) { $part = \ord($bytes[$i]); - // We only use gmp or bcmath if the final value is too big - if ($useRealInts) { - $integer = ($integer << 8) + $part; - } elseif (\extension_loaded('gmp')) { - $integer = gmp_strval(gmp_add(gmp_mul((string) $integer, '256'), $part)); + if (\extension_loaded('gmp')) { + $integerAsString = gmp_strval(gmp_add(gmp_mul($integerAsString, '256'), $part)); } elseif (\extension_loaded('bcmath')) { - $integer = bcadd(bcmul((string) $integer, '256'), (string) $part); + $integerAsString = bcadd(bcmul($integerAsString, '256'), (string) $part); } else { - throw new RuntimeException( + throw new \RuntimeException( 'The gmp or bcmath extension must be installed to read this database.' ); } } - return $integer; + return $integerAsString; } + /** + * @return array{0:int, 1:int} + */ private function sizeFromCtrlByte(int $ctrlByte, int $offset): array { $size = $ctrlByte & 0x1F; @@ -349,10 +409,22 @@ private function sizeFromCtrlByte(int $ctrlByte, int $offset): array if ($size === 29) { $size = 29 + \ord($bytes); } elseif ($size === 30) { - [, $adjust] = unpack('n', $bytes); + $rc = unpack('n', $bytes); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack an unsigned short value from the given bytes.' + ); + } + [, $adjust] = $rc; $size = 285 + $adjust; } else { - [, $adjust] = unpack('N', "\x00" . $bytes); + $rc = unpack('N', "\x00" . $bytes); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack an unsigned long value from the given bytes.' + ); + } + [, $adjust] = $rc; $size = $adjust + 65821; } @@ -368,7 +440,13 @@ private function isPlatformLittleEndian(): bool { $testint = 0x00FF; $packed = pack('S', $testint); + $rc = unpack('v', $packed); + if ($rc === false) { + throw new InvalidDatabaseException( + 'Could not unpack an unsigned short value from the given bytes.' + ); + } - return $testint === current(unpack('v', $packed)); + return $testint === current($rc); } } diff --git a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php index 532310703..b1da1ed24 100644 --- a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php +++ b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php @@ -4,11 +4,8 @@ namespace MaxMind\Db\Reader; -use Exception; - /** * This class should be thrown when unexpected data is found in the database. */ -class InvalidDatabaseException extends Exception -{ -} +// phpcs:disable +class InvalidDatabaseException extends \Exception {} diff --git a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php index 873064b0a..9cade2221 100644 --- a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php +++ b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php @@ -4,8 +4,6 @@ namespace MaxMind\Db\Reader; -use ArgumentCountError; - /** * This class provides the metadata for the MaxMind DB file. */ @@ -18,6 +16,7 @@ class Metadata * @var int */ public $binaryFormatMajorVersion; + /** * This is an unsigned 16-bit integer indicating the minor version number * for the database's binary format. @@ -25,6 +24,7 @@ class Metadata * @var int */ public $binaryFormatMinorVersion; + /** * This is an unsigned 64-bit integer that contains the database build * timestamp as a Unix epoch value. @@ -32,6 +32,7 @@ class Metadata * @var int */ public $buildEpoch; + /** * This is a string that indicates the structure of each data record * associated with an IP address. The actual definition of these @@ -40,15 +41,17 @@ class Metadata * @var string */ public $databaseType; + /** * This key will always point to a map (associative array). The keys of * that map will be language codes, and the values will be a description * in that language as a UTF-8 string. May be undefined for some * databases. * - * @var array + * @var array */ public $description; + /** * This is an unsigned 16-bit integer which is always 4 or 6. It indicates * whether the database contains IPv4 or IPv6 address data. @@ -56,18 +59,21 @@ class Metadata * @var int */ public $ipVersion; + /** * An array of strings, each of which is a language code. A given record * may contain data items that have been localized to some or all of * these languages. This may be undefined. * - * @var array + * @var array */ public $languages; + /** * @var int */ public $nodeByteSize; + /** * This is an unsigned 32-bit integer indicating the number of nodes in * the search tree. @@ -75,6 +81,7 @@ class Metadata * @var int */ public $nodeCount; + /** * This is an unsigned 16-bit integer. It indicates the number of bits in a * record in the search tree. Note that each node consists of two records. @@ -82,16 +89,20 @@ class Metadata * @var int */ public $recordSize; + /** * @var int */ public $searchTreeSize; + /** + * @param array $metadata + */ public function __construct(array $metadata) { if (\func_num_args() !== 1) { - throw new ArgumentCountError( - sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) + throw new \ArgumentCountError( + \sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args()) ); } diff --git a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php index 89db715e3..c2c3212d9 100644 --- a/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php +++ b/includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php @@ -7,7 +7,8 @@ class Util { /** - * @param resource $stream + * @param resource $stream + * @param int<0, max> $numberOfBytes */ public static function read($stream, int $offset, int $numberOfBytes): string { diff --git a/includes/vendor/maxmind/web-service-common/README.md b/includes/vendor/maxmind/web-service-common/README.md index d987e4936..4344ec601 100644 --- a/includes/vendor/maxmind/web-service-common/README.md +++ b/includes/vendor/maxmind/web-service-common/README.md @@ -5,7 +5,7 @@ shared code between MaxMind's various web service client APIs. ## Requirements ## -The library requires PHP 7.2 or greater. +The library requires PHP 8.1 or greater. There are several other dependencies as defined in the `composer.json` file. @@ -16,10 +16,10 @@ style guidelines. Please include unit tests whenever possible. ## Versioning ## -This API uses [Semantic Versioning](http://semver.org/). +This API uses [Semantic Versioning](https://semver.org/). ## Copyright and License ## -This software is Copyright (c) 2015-2020 by MaxMind, Inc. +This software is Copyright (c) 2015-2024 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php b/includes/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php index 5b016ce51..9e045d2ec 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php @@ -7,6 +7,5 @@ /** * This class represents an error authenticating. */ -class AuthenticationException extends InvalidRequestException -{ -} +// phpcs:disable +class AuthenticationException extends InvalidRequestException {} diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/HttpException.php b/includes/vendor/maxmind/web-service-common/src/Exception/HttpException.php index 2bb302aca..904b8582d 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/HttpException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/HttpException.php @@ -26,7 +26,7 @@ public function __construct( string $message, int $httpStatus, string $uri, - \Exception $previous = null + ?\Exception $previous = null ) { $this->uri = $uri; parent::__construct($message, $httpStatus, $previous); diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php b/includes/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php index 283145650..a29da89f3 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php @@ -7,6 +7,5 @@ /** * Thrown when the account is out of credits. */ -class InsufficientFundsException extends InvalidRequestException -{ -} +// phpcs:disable +class InsufficientFundsException extends InvalidRequestException {} diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php b/includes/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php index 0d3c51c23..e7b7a7df7 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php @@ -9,6 +9,5 @@ * web service. For example, if the array cannot be encoded as JSON or if there * is a missing or invalid field. */ -class InvalidInputException extends WebServiceException -{ -} +// phpcs:disable +class InvalidInputException extends WebServiceException {} diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php b/includes/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php index 95fd7dbf6..aaee45167 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php @@ -28,7 +28,7 @@ public function __construct( string $error, int $httpStatus, string $uri, - \Exception $previous = null + ?\Exception $previous = null ) { $this->error = $error; parent::__construct($message, $httpStatus, $uri, $previous); diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php b/includes/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php index 581db488b..b3bf84d59 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php @@ -4,6 +4,5 @@ namespace MaxMind\Exception; -class IpAddressNotFoundException extends InvalidRequestException -{ -} +// phpcs:disable +class IpAddressNotFoundException extends InvalidRequestException {} diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php b/includes/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php index facc1f60f..109d35d6e 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php @@ -7,6 +7,5 @@ /** * This exception is thrown when the service requires permission to access. */ -class PermissionRequiredException extends InvalidRequestException -{ -} +// phpcs:disable +class PermissionRequiredException extends InvalidRequestException {} diff --git a/includes/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php b/includes/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php index 9489c89f9..12363f4c0 100644 --- a/includes/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php +++ b/includes/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php @@ -7,6 +7,5 @@ /** * This class represents a generic web service error. */ -class WebServiceException extends \Exception -{ -} +// phpcs:disable +class WebServiceException extends \Exception {} diff --git a/includes/vendor/maxmind/web-service-common/src/WebService/Client.php b/includes/vendor/maxmind/web-service-common/src/WebService/Client.php index 2f2744ea0..185bd4478 100644 --- a/includes/vendor/maxmind/web-service-common/src/WebService/Client.php +++ b/includes/vendor/maxmind/web-service-common/src/WebService/Client.php @@ -77,17 +77,17 @@ class Client private $accountId; /** - * @param int $accountId your MaxMind account ID - * @param string $licenseKey your MaxMind license key - * @param array $options an array of options. Possible keys: - * * `host` - The host to use when connecting to the web service. - * * `useHttps` - A boolean flag for sending the request via https.(True by default) - * * `userAgent` - The prefix of the User-Agent to use in the request. - * * `caBundle` - The bundle of CA root certificates to use in the request. - * * `connectTimeout` - The connect timeout to use for the request. - * * `timeout` - The timeout to use for the request. - * * `proxy` - The HTTP proxy to use. May include a schema, port, - * username, and password, e.g., `http://username:password@127.0.0.1:10`. + * @param int $accountId your MaxMind account ID + * @param string $licenseKey your MaxMind license key + * @param array $options an array of options. Possible keys: + * * `host` - The host to use when connecting to the web service. + * * `useHttps` - Set to false to disable HTTPS. + * * `userAgent` - The prefix of the User-Agent to use in the request. + * * `caBundle` - The bundle of CA root certificates to use in the request. + * * `connectTimeout` - The connect timeout to use for the request. + * * `timeout` - The timeout to use for the request. + * * `proxy` - The HTTP proxy to use. May include a schema, port, + * username, and password, e.g., `http://username:password@127.0.0.1:10`. */ public function __construct( int $accountId, @@ -127,9 +127,9 @@ public function __construct( } /** - * @param string $service name of the service querying - * @param string $path the URI path to use - * @param array $input the data to be posted as JSON + * @param string $service name of the service querying + * @param string $path the URI path to use + * @param array $input the data to be posted as JSON * * @throws InvalidInputException when the request has missing or invalid * data @@ -142,7 +142,7 @@ public function __construct( * @throws WebServiceException when some other error occurs. This also * serves as the base class for the above exceptions. * - * @return array|null The decoded content of a successful response + * @return array|null The decoded content of a successful response */ public function post(string $service, string $path, array $input): ?array { @@ -170,6 +170,9 @@ public function post(string $service, string $path, array $input): ?array ); } + /** + * @return array|null + */ public function get(string $service, string $path): ?array { $request = $this->createRequest( @@ -195,6 +198,9 @@ private function userAgent(): string ' curl/' . $curlVersion['version']; } + /** + * @param array $headers + */ private function createRequest(string $path, array $headers = []): Http\Request { array_push( @@ -233,7 +239,7 @@ private function createRequest(string $path, array $headers = []): Http\Request * @throws WebServiceException when some other error occurs. This also * serves as the base class for the above exceptions * - * @return array|null The decoded content of a successful response + * @return array|null The decoded content of a successful response */ private function handleResponse( int $statusCode, @@ -463,7 +469,7 @@ private function handleUnexpectedStatus(int $statusCode, string $service, string * included, or is expected and included * but cannot be decoded as JSON * - * @return array|null the decoded request body + * @return array|null the decoded request body */ private function handleSuccess(int $statusCode, ?string $body, string $service): ?array { diff --git a/includes/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php b/includes/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php index 64db29f63..73b551fbe 100644 --- a/includes/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php +++ b/includes/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php @@ -24,10 +24,13 @@ class CurlRequest implements Request private $url; /** - * @var array + * @var array */ private $options; + /** + * @param array $options + */ public function __construct(string $url, array $options) { $this->url = $url; @@ -37,6 +40,8 @@ public function __construct(string $url, array $options) /** * @throws HttpException + * + * @return array{0:int, 1:string|null, 2:string|null} */ public function post(string $body): array { @@ -48,6 +53,9 @@ public function post(string $body): array return $this->execute($curl); } + /** + * @return array{0:int, 1:string|null, 2:string|null} + */ public function get(): array { $curl = $this->createCurl(); @@ -106,6 +114,8 @@ private function createCurl() * @param \CurlHandle $curl * * @throws HttpException + * + * @return array{0:int, 1:string|null, 2:string|null} */ private function execute($curl): array { @@ -129,7 +139,7 @@ private function execute($curl): array // indicates server did not send valid Content-Type: header" for // CURLINFO_CONTENT_TYPE. However, it will return FALSE if no header // is set. To keep our types simple, we return null in this case. - ($contentType === false ? null : $contentType), + $contentType === false ? null : $contentType, $body, ]; } diff --git a/includes/vendor/maxmind/web-service-common/src/WebService/Http/Request.php b/includes/vendor/maxmind/web-service-common/src/WebService/Http/Request.php index 994c46964..9a03e5fac 100644 --- a/includes/vendor/maxmind/web-service-common/src/WebService/Http/Request.php +++ b/includes/vendor/maxmind/web-service-common/src/WebService/Http/Request.php @@ -11,9 +11,18 @@ */ interface Request { + /** + * @param array $options + */ public function __construct(string $url, array $options); + /** + * @return array{0:int, 1:string|null, 2:string|null} + */ public function post(string $body): array; + /** + * @return array{0:int, 1:string|null, 2:string|null} + */ public function get(): array; } diff --git a/includes/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php b/includes/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php index 9d03fb206..12b0421f9 100644 --- a/includes/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php +++ b/includes/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php @@ -39,6 +39,9 @@ private function getCurlHandle() return $this->ch; } + /** + * @param array $options + */ public function request(string $url, array $options): Request { $options['curlHandle'] = $this->getCurlHandle(); diff --git a/includes/vendor/psr/log/Psr/Log/AbstractLogger.php b/includes/vendor/psr/log/Psr/Log/AbstractLogger.php deleted file mode 100644 index e02f9daf3..000000000 --- a/includes/vendor/psr/log/Psr/Log/AbstractLogger.php +++ /dev/null @@ -1,128 +0,0 @@ -log(LogLevel::EMERGENCY, $message, $context); - } - - /** - * Action must be taken immediately. - * - * Example: Entire website down, database unavailable, etc. This should - * trigger the SMS alerts and wake you up. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function alert($message, array $context = array()) - { - $this->log(LogLevel::ALERT, $message, $context); - } - - /** - * Critical conditions. - * - * Example: Application component unavailable, unexpected exception. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function critical($message, array $context = array()) - { - $this->log(LogLevel::CRITICAL, $message, $context); - } - - /** - * Runtime errors that do not require immediate action but should typically - * be logged and monitored. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function error($message, array $context = array()) - { - $this->log(LogLevel::ERROR, $message, $context); - } - - /** - * Exceptional occurrences that are not errors. - * - * Example: Use of deprecated APIs, poor use of an API, undesirable things - * that are not necessarily wrong. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function warning($message, array $context = array()) - { - $this->log(LogLevel::WARNING, $message, $context); - } - - /** - * Normal but significant events. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function notice($message, array $context = array()) - { - $this->log(LogLevel::NOTICE, $message, $context); - } - - /** - * Interesting events. - * - * Example: User logs in, SQL logs. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function info($message, array $context = array()) - { - $this->log(LogLevel::INFO, $message, $context); - } - - /** - * Detailed debug information. - * - * @param string $message - * @param mixed[] $context - * - * @return void - */ - public function debug($message, array $context = array()) - { - $this->log(LogLevel::DEBUG, $message, $context); - } -} diff --git a/includes/vendor/psr/log/Psr/Log/Test/DummyTest.php b/includes/vendor/psr/log/Psr/Log/Test/DummyTest.php deleted file mode 100644 index 9638c1101..000000000 --- a/includes/vendor/psr/log/Psr/Log/Test/DummyTest.php +++ /dev/null @@ -1,18 +0,0 @@ - ". - * - * Example ->error('Foo') would yield "error Foo". - * - * @return string[] - */ - abstract public function getLogs(); - - public function testImplements() - { - $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); - } - - /** - * @dataProvider provideLevelsAndMessages - */ - public function testLogsAtAllLevels($level, $message) - { - $logger = $this->getLogger(); - $logger->{$level}($message, array('user' => 'Bob')); - $logger->log($level, $message, array('user' => 'Bob')); - - $expected = array( - $level.' message of level '.$level.' with context: Bob', - $level.' message of level '.$level.' with context: Bob', - ); - $this->assertEquals($expected, $this->getLogs()); - } - - public function provideLevelsAndMessages() - { - return array( - LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), - LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), - LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), - LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), - LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), - LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), - LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), - LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), - ); - } - - /** - * @expectedException \Psr\Log\InvalidArgumentException - */ - public function testThrowsOnInvalidLevel() - { - $logger = $this->getLogger(); - $logger->log('invalid level', 'Foo'); - } - - public function testContextReplacement() - { - $logger = $this->getLogger(); - $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); - - $expected = array('info {Message {nothing} Bob Bar a}'); - $this->assertEquals($expected, $this->getLogs()); - } - - public function testObjectCastToString() - { - if (method_exists($this, 'createPartialMock')) { - $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); - } else { - $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); - } - $dummy->expects($this->once()) - ->method('__toString') - ->will($this->returnValue('DUMMY')); - - $this->getLogger()->warning($dummy); - - $expected = array('warning DUMMY'); - $this->assertEquals($expected, $this->getLogs()); - } - - public function testContextCanContainAnything() - { - $closed = fopen('php://memory', 'r'); - fclose($closed); - - $context = array( - 'bool' => true, - 'null' => null, - 'string' => 'Foo', - 'int' => 0, - 'float' => 0.5, - 'nested' => array('with object' => new DummyTest), - 'object' => new \DateTime, - 'resource' => fopen('php://memory', 'r'), - 'closed' => $closed, - ); - - $this->getLogger()->warning('Crazy context data', $context); - - $expected = array('warning Crazy context data'); - $this->assertEquals($expected, $this->getLogs()); - } - - public function testContextExceptionKeyCanBeExceptionOrOtherValues() - { - $logger = $this->getLogger(); - $logger->warning('Random message', array('exception' => 'oops')); - $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); - - $expected = array( - 'warning Random message', - 'critical Uncaught Exception!' - ); - $this->assertEquals($expected, $this->getLogs()); - } -} diff --git a/includes/vendor/psr/log/Psr/Log/Test/TestLogger.php b/includes/vendor/psr/log/Psr/Log/Test/TestLogger.php deleted file mode 100644 index 1be323049..000000000 --- a/includes/vendor/psr/log/Psr/Log/Test/TestLogger.php +++ /dev/null @@ -1,147 +0,0 @@ - $level, - 'message' => $message, - 'context' => $context, - ]; - - $this->recordsByLevel[$record['level']][] = $record; - $this->records[] = $record; - } - - public function hasRecords($level) - { - return isset($this->recordsByLevel[$level]); - } - - public function hasRecord($record, $level) - { - if (is_string($record)) { - $record = ['message' => $record]; - } - return $this->hasRecordThatPasses(function ($rec) use ($record) { - if ($rec['message'] !== $record['message']) { - return false; - } - if (isset($record['context']) && $rec['context'] !== $record['context']) { - return false; - } - return true; - }, $level); - } - - public function hasRecordThatContains($message, $level) - { - return $this->hasRecordThatPasses(function ($rec) use ($message) { - return strpos($rec['message'], $message) !== false; - }, $level); - } - - public function hasRecordThatMatches($regex, $level) - { - return $this->hasRecordThatPasses(function ($rec) use ($regex) { - return preg_match($regex, $rec['message']) > 0; - }, $level); - } - - public function hasRecordThatPasses(callable $predicate, $level) - { - if (!isset($this->recordsByLevel[$level])) { - return false; - } - foreach ($this->recordsByLevel[$level] as $i => $rec) { - if (call_user_func($predicate, $rec, $i)) { - return true; - } - } - return false; - } - - public function __call($method, $args) - { - if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { - $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; - $level = strtolower($matches[2]); - if (method_exists($this, $genericMethod)) { - $args[] = $level; - return call_user_func_array([$this, $genericMethod], $args); - } - } - throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); - } - - public function reset() - { - $this->records = []; - $this->recordsByLevel = []; - } -} diff --git a/includes/vendor/psr/log/src/AbstractLogger.php b/includes/vendor/psr/log/src/AbstractLogger.php new file mode 100644 index 000000000..d60a091af --- /dev/null +++ b/includes/vendor/psr/log/src/AbstractLogger.php @@ -0,0 +1,15 @@ +logger = $logger; } diff --git a/includes/vendor/psr/log/Psr/Log/LoggerInterface.php b/includes/vendor/psr/log/src/LoggerInterface.php similarity index 63% rename from includes/vendor/psr/log/Psr/Log/LoggerInterface.php rename to includes/vendor/psr/log/src/LoggerInterface.php index 2206cfde4..cb4cf648b 100644 --- a/includes/vendor/psr/log/Psr/Log/LoggerInterface.php +++ b/includes/vendor/psr/log/src/LoggerInterface.php @@ -22,12 +22,9 @@ interface LoggerInterface /** * System is unusable. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function emergency($message, array $context = array()); + public function emergency(string|\Stringable $message, array $context = []): void; /** * Action must be taken immediately. @@ -35,35 +32,26 @@ public function emergency($message, array $context = array()); * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function alert($message, array $context = array()); + public function alert(string|\Stringable $message, array $context = []): void; /** * Critical conditions. * * Example: Application component unavailable, unexpected exception. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function critical($message, array $context = array()); + public function critical(string|\Stringable $message, array $context = []): void; /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function error($message, array $context = array()); + public function error(string|\Stringable $message, array $context = []): void; /** * Exceptional occurrences that are not errors. @@ -71,55 +59,40 @@ public function error($message, array $context = array()); * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function warning($message, array $context = array()); + public function warning(string|\Stringable $message, array $context = []): void; /** * Normal but significant events. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function notice($message, array $context = array()); + public function notice(string|\Stringable $message, array $context = []): void; /** * Interesting events. * * Example: User logs in, SQL logs. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function info($message, array $context = array()); + public function info(string|\Stringable $message, array $context = []): void; /** * Detailed debug information. * - * @param string $message * @param mixed[] $context - * - * @return void */ - public function debug($message, array $context = array()); + public function debug(string|\Stringable $message, array $context = []): void; /** * Logs with an arbitrary level. * - * @param mixed $level - * @param string $message + * @param mixed $level * @param mixed[] $context * - * @return void - * * @throws \Psr\Log\InvalidArgumentException */ - public function log($level, $message, array $context = array()); + public function log($level, string|\Stringable $message, array $context = []): void; } diff --git a/includes/vendor/psr/log/Psr/Log/LoggerTrait.php b/includes/vendor/psr/log/src/LoggerTrait.php similarity index 57% rename from includes/vendor/psr/log/Psr/Log/LoggerTrait.php rename to includes/vendor/psr/log/src/LoggerTrait.php index e392fef0a..a5d9980b6 100644 --- a/includes/vendor/psr/log/Psr/Log/LoggerTrait.php +++ b/includes/vendor/psr/log/src/LoggerTrait.php @@ -14,13 +14,8 @@ trait LoggerTrait { /** * System is unusable. - * - * @param string $message - * @param array $context - * - * @return void */ - public function emergency($message, array $context = array()) + public function emergency(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::EMERGENCY, $message, $context); } @@ -30,13 +25,8 @@ public function emergency($message, array $context = array()) * * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. - * - * @param string $message - * @param array $context - * - * @return void */ - public function alert($message, array $context = array()) + public function alert(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ALERT, $message, $context); } @@ -45,13 +35,8 @@ public function alert($message, array $context = array()) * Critical conditions. * * Example: Application component unavailable, unexpected exception. - * - * @param string $message - * @param array $context - * - * @return void */ - public function critical($message, array $context = array()) + public function critical(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::CRITICAL, $message, $context); } @@ -59,13 +44,8 @@ public function critical($message, array $context = array()) /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. - * - * @param string $message - * @param array $context - * - * @return void */ - public function error($message, array $context = array()) + public function error(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ERROR, $message, $context); } @@ -75,26 +55,16 @@ public function error($message, array $context = array()) * * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. - * - * @param string $message - * @param array $context - * - * @return void */ - public function warning($message, array $context = array()) + public function warning(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::WARNING, $message, $context); } /** * Normal but significant events. - * - * @param string $message - * @param array $context - * - * @return void */ - public function notice($message, array $context = array()) + public function notice(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::NOTICE, $message, $context); } @@ -103,26 +73,16 @@ public function notice($message, array $context = array()) * Interesting events. * * Example: User logs in, SQL logs. - * - * @param string $message - * @param array $context - * - * @return void */ - public function info($message, array $context = array()) + public function info(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::INFO, $message, $context); } /** * Detailed debug information. - * - * @param string $message - * @param array $context - * - * @return void */ - public function debug($message, array $context = array()) + public function debug(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::DEBUG, $message, $context); } @@ -130,13 +90,9 @@ public function debug($message, array $context = array()) /** * Logs with an arbitrary level. * - * @param mixed $level - * @param string $message - * @param array $context - * - * @return void + * @param mixed $level * * @throws \Psr\Log\InvalidArgumentException */ - abstract public function log($level, $message, array $context = array()); + abstract public function log($level, string|\Stringable $message, array $context = []): void; } diff --git a/includes/vendor/psr/log/Psr/Log/NullLogger.php b/includes/vendor/psr/log/src/NullLogger.php similarity index 74% rename from includes/vendor/psr/log/Psr/Log/NullLogger.php rename to includes/vendor/psr/log/src/NullLogger.php index c8f7293b1..de0561e2a 100644 --- a/includes/vendor/psr/log/Psr/Log/NullLogger.php +++ b/includes/vendor/psr/log/src/NullLogger.php @@ -15,15 +15,11 @@ class NullLogger extends AbstractLogger /** * Logs with an arbitrary level. * - * @param mixed $level - * @param string $message - * @param array $context - * - * @return void + * @param mixed[] $context * * @throws \Psr\Log\InvalidArgumentException */ - public function log($level, $message, array $context = array()) + public function log($level, string|\Stringable $message, array $context = []): void { // noop } diff --git a/includes/vendor/rmccue/requests/README.md b/includes/vendor/rmccue/requests/README.md index c8680b0ed..756bc5321 100644 --- a/includes/vendor/rmccue/requests/README.md +++ b/includes/vendor/rmccue/requests/README.md @@ -151,6 +151,24 @@ If you'd like to run a single set of tests, specify just the name: $ phpunit Transport/cURL ``` +Requests and PSR-7/PSR-18 +------------------------- + +[PSR-7][psr-7] describes common interfaces for representing HTTP messages. +[PSR-18][psr-18] describes a common interface for sending HTTP requests and receiving HTTP responses. + +Both PSR-7 as well as PSR-18 were created after Requests' conception. +At this time, there is no intention to add a native PSR-7/PSR-18 implementation to the Requests library. + +However, the amazing [Artur Weigandt][art4] has created a [package][requests-psr-18], which allows you to use Requests as a PSR-7 compatible PSR-18 HTTP Client. +If you are interested in a PSR-7/PSR-18 compatible version of Requests, we highly recommend you check out [this package][requests-psr-18]. + +[psr-7]: https://www.php-fig.org/psr/psr-7/ +[psr-18]: https://www.php-fig.org/psr/psr-18/ +[art4]: https://github.com/Art4 +[requests-psr-18]: https://packagist.org/packages/art4/requests-psr18-adapter + + Contribute ---------- diff --git a/includes/vendor/rmccue/requests/certificates/cacert.pem b/includes/vendor/rmccue/requests/certificates/cacert.pem index 2ae7b6cb2..f04c55123 100644 --- a/includes/vendor/rmccue/requests/certificates/cacert.pem +++ b/includes/vendor/rmccue/requests/certificates/cacert.pem @@ -1,12 +1,14 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Jan 10 04:12:06 2023 GMT +## Certificate data from Mozilla as of: Tue Sep 9 03:12:01 2025 GMT +## +## Find updated versions here: https://curl.se/docs/caextract.html ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates ## file (certdata.txt). This file can be found in the mozilla source tree: -## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## https://raw.githubusercontent.com/mozilla-firefox/firefox/refs/heads/release/security/nss/lib/ckfw/builtins/certdata.txt ## ## It contains the certificates in PEM format and therefore ## can be directly used with curl / libcurl / php_curl, or with @@ -14,76 +16,10 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 90c470e705b4b5f36f09684dc50e2b79c8b86989a848b62cd1a7bd6460ee65f6 +## SHA256: 0078e6bdd280fd89e1b883174387aae84b3eae2ee263416a5f8a14ee7f179ae9 ## -GlobalSign Root CA -================== ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx -GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds -b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD -VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa -DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc -THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb -Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP -c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX -gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF -AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj -Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG -j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH -hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC -X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -Entrust.net Premium 2048 Secure Server CA -========================================= ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u -ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp -bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV -BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx -NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 -d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl -MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u -ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL -Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr -hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW -nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi -VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ -KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy -T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT -J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e -nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= ------END CERTIFICATE----- - -Baltimore CyberTrust Root -========================= ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE -ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li -ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC -SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs -dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME -uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB -UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C -G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 -XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr -l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI -VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB -BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh -cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 -hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa -Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H -RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - Entrust Root Certification Authority ==================================== -----BEGIN CERTIFICATE----- @@ -110,30 +46,6 @@ W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -Comodo AAA Services root -======================== ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw -MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl -c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV -BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG -C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs -i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW -Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH -Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK -Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f -BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl -cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz -LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm -7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z -8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C -12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - QuoVadis Root CA 2 ================== -----BEGIN CERTIFICATE----- @@ -200,99 +112,6 @@ vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - -XRamp Global CA Root -==================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE -BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj -dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx -HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg -U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu -IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx -foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE -zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs -AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry -xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap -oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC -AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc -/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n -nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz -8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -Go Daddy Class 2 CA -=================== ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY -VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG -A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g -RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD -ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv -2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 -qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j -YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY -vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O -BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o -atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu -MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG -A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim -PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt -I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI -Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b -vZ8= ------END CERTIFICATE----- - -Starfield Class 2 CA -==================== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc -U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo -MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG -A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG -SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY -bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ -JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm -epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN -F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF -MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f -hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo -bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g -QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs -afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM -PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD -KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 -QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - DigiCert Assured ID Root CA =========================== -----BEGIN CERTIFICATE----- @@ -390,37 +209,6 @@ NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- -SwissSign Silver CA - G2 -======================== ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT -BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X -DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 -aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG -9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 -N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm -+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH -6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu -MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h -qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 -FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs -ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc -celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X -CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB -tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P -4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F -kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L -3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx -/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa -DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP -e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu -WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ -DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub -DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- - SecureTrust CA ============== -----BEGIN CERTIFICATE----- @@ -603,47 +391,6 @@ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - -SecureSign RootCA11 -=================== ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi -SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS -b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw -KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 -cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL -TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO -wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq -g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP -O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA -bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX -t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh -OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r -bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ -Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 -y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 -lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - Microsec e-Szigno Root CA 2009 ============================== -----BEGIN CERTIFICATE----- @@ -689,39 +436,6 @@ YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r kpeDMdmztcpHWD9f -----END CERTIFICATE----- -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - Izenpe.com ========== -----BEGIN CERTIFICATE----- @@ -1261,40 +975,6 @@ Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -E-Tugra Certification Authority -=============================== ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w -DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls -ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw -NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx -QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl -cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD -DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd -hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K -CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g -ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ -BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 -E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz -rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq -jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 -dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB -/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG -MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK -kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO -XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 -VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo -a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc -dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV -KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT -Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 -8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G -C7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - T-TeleSec GlobalRoot Class 2 ============================ -----BEGIN CERTIFICATE----- @@ -2425,40 +2105,6 @@ hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB dBb9HxEGmpv0 -----END CERTIFICATE----- -Entrust Root Certification Authority - G4 -========================================= ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu -bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1 -dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT -AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D -umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV -3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds -8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ -e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7 -ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X -xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV -7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW -Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n -MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q -jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht -7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK -YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt -jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+ -m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW -RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA -JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G -+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT -kcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- - Microsoft ECC Root Certificate Authority 2017 ============================================= -----BEGIN CERTIFICATE----- @@ -3276,85 +2922,6 @@ AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -E-Tugra Global Root CA RSA v3 -============================= ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ -BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb -BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 -IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU -UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF -LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg -djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx -jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL -sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF -/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q -QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw -bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 -04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB -eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM -bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg -h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 -LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ -gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 -38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q -ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s -SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY -sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl -DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X -nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH -IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX -YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -E-Tugra Global Root CA ECC v3 -============================= ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV -BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB -IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP -MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 -w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 -Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ -zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO -PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W -Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 ------END CERTIFICATE----- - -Security Communication RootCA3 -============================== ------BEGIN CERTIFICATE----- -MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw -IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD -b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw -CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE -AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r -hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE -NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 -/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm -npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY -XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK -p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC -3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf -GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw -CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB -/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS -YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu -Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O -H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx -YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ -XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml -+LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn -KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 -dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm -6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== ------END CERTIFICATE----- - Security Communication ECC RootCA1 ================================== -----BEGIN CERTIFICATE----- @@ -3370,3 +2937,620 @@ BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e N9k= -----END CERTIFICATE----- + +BJCA Global Root CA1 +==================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG +EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK +Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG +A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD +DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm +CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS +sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn +P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW +yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj +eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn +MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b +OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh +GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK +H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB +AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ +dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 +60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh +TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW +4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp +GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx +4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps +3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S +SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= +-----END CERTIFICATE----- + +BJCA Global Root CA2 +==================== +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD +TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg +R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE +BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC +SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl +SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK +/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI +1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 +W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g +UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root E46 +============================================= +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH +QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 +ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 +WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 +aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 +NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud +DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH +lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U +SAGKcw== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root R46 +============================================= +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 +OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k +1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf +GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP +FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu +ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz +Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A +wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF +plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ +EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW +6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI +IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp +E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 +exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M +0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI +84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m +pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd +Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b +E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm +J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +SSL.com TLS RSA Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG +EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg +Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC +VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u +9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y +7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac +oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M +R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG +D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW +TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk +8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq +g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk +7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu +N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN +j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by +iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU +o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo +ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib +MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi +vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 +P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 +9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +SSL.com TLS ECC Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v +dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx +GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy +JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 +5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 +81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG +MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w +7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 +Zn6g6g== +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA ECC TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB +dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD +VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg +VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT +AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K +DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS +b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX +NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ +uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY +a3cpetskz2VAv9LcjBHo9H1/IISpQuQo +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA RSA TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD +DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw +CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 +b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV +BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB +l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG +vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK +ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt +0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK +PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY +sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY +Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ +rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa +fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G +CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl +Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX +AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G +slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt +afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q +TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj +1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l +PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W +HYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +TrustAsia Global Root CA G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG +A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM +G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw +MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu +MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz +lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ +Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V +P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag +dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm +9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc +D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg +WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea +mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF +TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj +7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1 +D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T +G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj +duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl +cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys ++TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli +2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y +aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS +ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR +JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH +-----END CERTIFICATE----- + +TrustAsia Global Root CA G4 +=========================== +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE +BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry +dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa +MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw +IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8 +m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/ +pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA +bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk +dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNaFw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLx +eP0CflfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJEhRGnSjot +6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggqhkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2 +Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liW +pDVfG2XqYZpwI7UNo5uSUm9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRaFw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/M +MDALj2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmUv4RDsNuE +SgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggqhkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9 +Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/nich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs7 +3u1Z/GtMMH9ZzkXpc2AVmkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45Ft +nYSkYZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslhsuitQDy6 +uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0alDrJLpA6lfO741GIDuZNq +ihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3OjWiE260f6GBfZumbCk6SP/F2krfxQapWs +vCQz0b2If4b19bJzKo98rwjyGpg/qYFlP8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/c +Zip8UlF1y5mO6D1cv547KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTif +BSeolz7pUcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/kQO9 +lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JOHg9O5j9ZpSPcPYeo +KFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkBEa801M/XrmLTBQe0MXXgDW1XT2mH ++VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6UCBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm4 +5P3luG0wDQYJKoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQnmhUQo8mUuJM +3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+QgvfKNmwrZggvkN80V4aCRck +jXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2vtrV0KnahP/t1MJ+UXjulYPPLXAziDslg+Mkf +Foom3ecnf+slpoq9uC02EJqxWE2aaE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/W +NyVntHKLr4W96ioDj8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+ +o/E4Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0wlREQKC6/ +oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHnYfkUyq+Dj7+vsQpZXdxc +1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVocicCMb3SgazNNtQEo/a2tiRc7ppqEvOuM +6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3V +rCLENQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0kyI9p+Kx +7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1CrWDaSWqVcN3SAOLMV2MC +e5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxzhkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2W +Wy09X6GDRl224yW4fKcZgBzqZUPckXk2LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rp +M9kzXzehxfCrPfp4sOcsn/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIf +hs1w/tkuFT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5kQMr +eyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3wNemKfrb3vOTlycE +VS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6vwQcQeKwRoi9C8DfF8rhW3Q5iLc4t +Vn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7Gx +cJXvYXowDQYJKoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3+VGXu6TwYofF +1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbymeAPnCKfWxkxlSaRosTKCL4BWa +MS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3NyqpgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xd +gSGn2rtO/+YHqP65DSdsu3BaVXoT6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2O +HG1QAk8mGEPej1WFsQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+Nm +YWvtPjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2dlklyALKr +dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ +iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN +lM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- + +Telekom Security TLS ECC Root 2020 +================================== +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE +RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl +a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz +NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg +R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG +SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1 +2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC +MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ +Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU +ga/sf+Rn27iQ7t0l +-----END CERTIFICATE----- + +Telekom Security TLS RSA Root 2023 +================================== +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG +EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU +ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy +NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp +dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC +KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP +GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx +UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo +l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9 +FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v +zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg +rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML +KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S +WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+ +sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp +kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy +/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4 +mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz +aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa +oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8 +wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE +HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0 +o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +FIRMAPROFESIONAL CA ROOT-A WEB +============================== +-----BEGIN CERTIFICATE----- +MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF +UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4 +MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2 +WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h +bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM +IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6 +iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg +st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD +Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB +/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL +cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ +pYXFuXqUPoeovQA= +-----END CERTIFICATE----- + +TWCA CYBER Root CA +================== +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s +Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh +V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT +o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT +Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK +/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH +IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM +fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF +2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR +wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83 +QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN +c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x +X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR +IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq +/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R +FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe +Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv +It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl +IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +SecureSign Root CA12 +==================== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3 +emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mtp7JIKwcc +J/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zdJ1M3s6oYwlkm7Fsf0uZl +fO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gurFzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBF +EaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1Uef +NzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOC +AQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQi +LUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpce +mik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPS +vWKErI4cqc1avTc7bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhga +aaI5gdka9at/yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +SecureSign Root CA14 +==================== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh +1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn +bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb +1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa +/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE +kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx +jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz +ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0 +dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY +AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq +YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA +ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds +Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG +FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q +nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/ +OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa +OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO +pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN +eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S +-----END CERTIFICATE----- + +SecureSign Root CA15 +==================== +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE +BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1 +cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV +BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj +dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G +dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB +2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J +fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ +SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- + +D-TRUST BR Root CA 2 2023 +========================= +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBIMQswCQYDVQQG +EwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0Eg +MiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUwOTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTAT +BgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCT +cfKri3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNEgXtRr90z +sWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8k12b9py0i4a6Ibn08OhZ +WiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCTRphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6 +++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LUL +QyReS2tNZ9/WtT5PeB+UcSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIv +x9gvdhFP/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bSuREV +MweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+0bpwHJwh5Q8xaRfX +/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4NDfTisl01gLmB1IRpkQLLddCNxbU9 +CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUZ5Dw1t61GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRC +MEAwPqA8oDqGOGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tIFoE9c+CeJyrr +d6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67nriv6uvw8l5VAk1/DLQOj7aRv +U9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTRVFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4 +nj8+AybmTNudX0KEPUUDAxxZiMrcLmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdij +YQ6qgYF/6FKC0ULn4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff +/vtDhQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsGkoHU6XCP +pz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46ls/pdu4D58JDUjxqgejB +WoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aSEcr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/ +5usWDiJFAbzdNpQ0qTUmiteXue4Icr80knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jt +n/mtd+ArY0+ew+43u3gJhJ65bvspmZDogNOfJA== +-----END CERTIFICATE----- + +TrustAsia TLS ECC Root CA +========================= +-----BEGIN CERTIFICATE----- +MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMwWDELMAkGA1UE +BhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIjAgBgNVBAMTGVRy +dXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQwNTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBY +MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAG +A1UEAxMZVHJ1c3RBc2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/ +pVs/AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDpguMqWzJ8 +S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49 +BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15K +eAIxAKORh/IRM4PDwYqROkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== +-----END CERTIFICATE----- + +TrustAsia TLS RSA Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEMBQAwWDELMAkG +A1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIjAgBgNVBAMT +GVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcNMjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2 +WjBYMQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEi +MCAGA1UEAxMZVHJ1c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+NmDQDIPN +lOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJQ1DNDX3eRA5gEk9bNb2/ +mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fk +zv93uMltrOXVmPGZLmzjyUT5tUMnCE32ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYo +zza/+lcK7Fs/6TAWe8TbxNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyr +z2I8sMeXi9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQUNoy +IBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+jTnhMmCWr8n4uIF6C +FabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DTbE3txci3OE9kxJRMT6DNrqXGJyV1 +J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnT +q1mt1tve1CuBAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZ +ylomkadFK/hTMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 +Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4iqME3mmL5Dw8 +veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt7DlK9RME7I10nYEKqG/odv6L +TytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHx +tlotJnMnlvm5P1vQiJ3koP26TpUJg3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp +27RIGAAtvKLEiUUjpQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87q +qA8MpugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongPXvPKnbwb +PKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIweSsCI3zWQzj8C9GRh3sfI +B5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNz +FrwFuHnYWa8G5z9nODmxfKuU4CkUpijy323imttUQ/hHWKNddBWcwauwxzQ= +-----END CERTIFICATE----- + +D-TRUST EV Root CA 2 2023 +========================= +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBIMQswCQYDVQQG +EwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0Eg +MiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUwOTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTAT +BgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1 +sJkKF8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE7CUXFId/ +MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFeEMbsh2aJgWi6zCudR3Mf +vc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6lHPTGGkKSv/BAQP/eX+1SH977ugpbzZM +lWGG2Pmic4ruri+W7mjNPU0oQvlFKzIbRlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3 +YG14C8qKXO0elg6DpkiVjTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq910 +7PncjLgcjmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZxTnXo +nMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ARZZaBhDM7DS3LAa +QzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nkhbDhezGdpn9yo7nELC7MmVcOIQxF +AZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knFNXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUqvyREBuHkV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRC +MEAwPqA8oDqGOGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14QvBukEdHjqOS +Mo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4pZt+UPJ26oUFKidBK7GB0aL2 +QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xD +UmPBEcrCRbH0O1P1aa4846XerOhUt7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V +4U/M5d40VxDJI3IXcI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuo +dNv8ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT2vFp4LJi +TZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs7dpn1mKmS00PaaLJvOwi +S5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNPgofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/ +HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAstNl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L ++KIkBI3Y4WNeApI02phhXBxvWHZks/wCuPWdCg== +-----END CERTIFICATE----- + +SwissSign RSA TLS Root CA 2022 - 1 +================================== +-----BEGIN CERTIFICATE----- +MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UEAxMiU3dpc3NTaWduIFJTQSBU +TFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgxMTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJ +BgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0Eg +VExTIFJvb3QgQ0EgMjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmji +C8NXvDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7LCTLf5Im +gKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX5XH8irCRIFucdFJtrhUn +WXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyEEPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlf +GUEGjw5NBuBwQCMBauTLE5tzrE0USJIt/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36q +OTw7D59Ke4LKa2/KIj4x0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLO +EGrOyvi5KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM0ZPl +EuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shdOxtYk8EXlFXIC+OC +eYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrtaclXvyFu1cvh43zcgTFeRc5JzrBh3 +Q4IgaezprClG5QtO+DdziZaKHG29777YtvTKwP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow +4UD2p8P98Q+4DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL +BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO310aewCoSPY6W +lkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgzHqp41eZUBDqyggmNzhYzWUUo +8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQiJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zp +y1FVCypM9fJkT6lc/2cyjlUtMoIcgC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3Cjlvr +zG4ngRhZi0Rjn9UMZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6M +OuhFLhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJpzv1/THfQ +wUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/TdAo9QAwKxuDdollDruF/U +KIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0n +hzck5npgL7XTgwSqT0N1osGDsieYK7EOgLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rw +tnu64ZzZ +-----END CERTIFICATE----- diff --git a/includes/vendor/rmccue/requests/certificates/cacert.pem.sha256 b/includes/vendor/rmccue/requests/certificates/cacert.pem.sha256 index 374e704f7..c2c8c73c3 100644 --- a/includes/vendor/rmccue/requests/certificates/cacert.pem.sha256 +++ b/includes/vendor/rmccue/requests/certificates/cacert.pem.sha256 @@ -1 +1 @@ -fb1ecd641d0a02c01bc9036d513cb658bbda62a75e246bedbc01764560a639f0 cacert.pem +f290e6acaf904a4121424ca3ebdd70652780707e28e8af999221786b86bb1975 cacert.pem diff --git a/includes/vendor/rmccue/requests/library/Requests.php b/includes/vendor/rmccue/requests/library/Requests.php index 05250640f..14dcba4c0 100644 --- a/includes/vendor/rmccue/requests/library/Requests.php +++ b/includes/vendor/rmccue/requests/library/Requests.php @@ -19,7 +19,7 @@ if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error trigger_error( - 'The PSR-0 `Requests_...` class names in the Request library are deprecated.' + 'The PSR-0 `Requests_...` class names in the Requests library are deprecated.' . ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.', E_USER_DEPRECATED ); diff --git a/includes/vendor/rmccue/requests/src/Autoload.php b/includes/vendor/rmccue/requests/src/Autoload.php index 26dd280ee..669ddecaf 100644 --- a/includes/vendor/rmccue/requests/src/Autoload.php +++ b/includes/vendor/rmccue/requests/src/Autoload.php @@ -166,7 +166,7 @@ public static function load($class_name) { if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error trigger_error( - 'The PSR-0 `Requests_...` class names in the Request library are deprecated.' + 'The PSR-0 `Requests_...` class names in the Requests library are deprecated.' . ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.', E_USER_DEPRECATED ); diff --git a/includes/vendor/rmccue/requests/src/Capability.php b/includes/vendor/rmccue/requests/src/Capability.php index 87b8340a3..30572bab2 100644 --- a/includes/vendor/rmccue/requests/src/Capability.php +++ b/includes/vendor/rmccue/requests/src/Capability.php @@ -28,7 +28,7 @@ interface Capability { * * Note: this does not automatically mean that the capability will be supported for your chosen transport! * - * @var array + * @var string[] */ const ALL = [ self::SSL, diff --git a/includes/vendor/rmccue/requests/src/Cookie.php b/includes/vendor/rmccue/requests/src/Cookie.php index ccbbc73db..2cc821d64 100644 --- a/includes/vendor/rmccue/requests/src/Cookie.php +++ b/includes/vendor/rmccue/requests/src/Cookie.php @@ -36,8 +36,8 @@ class Cookie { /** * Cookie attributes * - * Valid keys are (currently) path, domain, expires, max-age, secure and - * httponly. + * Valid keys are `'path'`, `'domain'`, `'expires'`, `'max-age'`, `'secure'` and + * `'httponly'`. * * @var \WpOrg\Requests\Utility\CaseInsensitiveDictionary|array Array-like object */ @@ -46,8 +46,7 @@ class Cookie { /** * Cookie flags * - * Valid keys are (currently) creation, last-access, persistent and - * host-only. + * Valid keys are `'creation'`, `'last-access'`, `'persistent'` and `'host-only'`. * * @var array */ @@ -66,11 +65,13 @@ class Cookie { /** * Create a new cookie object * - * @param string $name - * @param string $value + * @param string $name The name of the cookie. + * @param string $value The value for the cookie. * @param array|\WpOrg\Requests\Utility\CaseInsensitiveDictionary $attributes Associative array of attribute data - * @param array $flags - * @param int|null $reference_time + * @param array $flags The flags for the cookie. + * Valid keys are `'creation'`, `'last-access'`, + * `'persistent'` and `'host-only'`. + * @param int|null $reference_time Reference time for relative calculations. * * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $name argument is not a string. * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $value argument is not a string. @@ -279,7 +280,11 @@ public function path_matches($request_path) { public function normalize() { foreach ($this->attributes as $key => $value) { $orig_value = $value; - $value = $this->normalize_attribute($key, $value); + + if (is_string($key)) { + $value = $this->normalize_attribute($key, $value); + } + if ($value === null) { unset($this->attributes[$key]); continue; @@ -299,7 +304,7 @@ public function normalize() { * Handles parsing individual attributes from the cookie values. * * @param string $name Attribute name - * @param string|boolean $value Attribute value (string value, or true if empty/flag) + * @param string|int|bool $value Attribute value (string/integer value, or true if empty/flag) * @return mixed Value if available, or null if the attribute value is invalid (and should be skipped) */ protected function normalize_attribute($name, $value) { @@ -465,13 +470,19 @@ public static function parse($cookie_header, $name = '', $reference_time = null) * @param \WpOrg\Requests\Iri|null $origin URI for comparing cookie origins * @param int|null $time Reference time for expiration calculation * @return array + * + * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $origin argument is not null or an instance of the Iri class. */ - public static function parse_from_headers(Headers $headers, Iri $origin = null, $time = null) { + public static function parse_from_headers(Headers $headers, $origin = null, $time = null) { $cookie_headers = $headers->getValues('Set-Cookie'); if (empty($cookie_headers)) { return []; } + if ($origin !== null && !($origin instanceof Iri)) { + throw InvalidArgument::create(2, '$origin', Iri::class . ' or null', gettype($origin)); + } + $cookies = []; foreach ($cookie_headers as $header) { $parsed = self::parse($header, '', $time); diff --git a/includes/vendor/rmccue/requests/src/Cookie/Jar.php b/includes/vendor/rmccue/requests/src/Cookie/Jar.php index dfbb8b739..7633786b9 100644 --- a/includes/vendor/rmccue/requests/src/Cookie/Jar.php +++ b/includes/vendor/rmccue/requests/src/Cookie/Jar.php @@ -49,7 +49,8 @@ public function __construct($cookies = []) { /** * Normalise cookie data into a \WpOrg\Requests\Cookie * - * @param string|\WpOrg\Requests\Cookie $cookie + * @param string|\WpOrg\Requests\Cookie $cookie Cookie header value, possibly pre-parsed (object). + * @param string $key Optional. The name for this cookie. * @return \WpOrg\Requests\Cookie */ public function normalize_cookie($cookie, $key = '') { @@ -106,7 +107,7 @@ public function offsetSet($offset, $value) { /** * Unset the given header * - * @param string $offset + * @param string $offset The key for the item to unset. */ #[ReturnTypeWillChange] public function offsetUnset($offset) { @@ -171,7 +172,7 @@ public function before_request($url, &$headers, &$data, &$type, &$options) { /** * Parse all cookies from a response and attach them to the response * - * @param \WpOrg\Requests\Response $response + * @param \WpOrg\Requests\Response $response Response as received. */ public function before_redirect_check(Response $response) { $url = $response->url; diff --git a/includes/vendor/rmccue/requests/src/IdnaEncoder.php b/includes/vendor/rmccue/requests/src/IdnaEncoder.php index 094fff3d5..9f235527b 100644 --- a/includes/vendor/rmccue/requests/src/IdnaEncoder.php +++ b/includes/vendor/rmccue/requests/src/IdnaEncoder.php @@ -137,7 +137,7 @@ public static function to_ascii($text) { * * @internal (Testing found regex was the fastest implementation) * - * @param string $text + * @param string $text Text to examine. * @return bool Is the text string ASCII-only? */ protected static function is_ascii($text) { @@ -148,7 +148,7 @@ protected static function is_ascii($text) { * Prepare a text string for use as an IDNA name * * @todo Implement this based on RFC 3491 and the newer 5891 - * @param string $text + * @param string $text Text to prepare. * @return string Prepared string */ protected static function nameprep($text) { @@ -160,7 +160,7 @@ protected static function nameprep($text) { * * Based on \WpOrg\Requests\Iri::replace_invalid_with_pct_encoding() * - * @param string $input + * @param string $input Text to convert. * @return array Unicode code points * * @throws \WpOrg\Requests\Exception Invalid UTF-8 codepoint (`idna.invalidcodepoint`) @@ -216,18 +216,18 @@ protected static function utf8_to_codepoints($input) { } if (// Non-shortest form sequences are invalid - $length > 1 && $character <= 0x7F - || $length > 2 && $character <= 0x7FF - || $length > 3 && $character <= 0xFFFF + ($length > 1 && $character <= 0x7F) + || ($length > 2 && $character <= 0x7FF) + || ($length > 3 && $character <= 0xFFFF) // Outside of range of ucschar codepoints // Noncharacters || ($character & 0xFFFE) === 0xFFFE - || $character >= 0xFDD0 && $character <= 0xFDEF + || ($character >= 0xFDD0 && $character <= 0xFDEF) || ( // Everything else not in ucschar - $character > 0xD7FF && $character < 0xF900 + ($character > 0xD7FF && $character < 0xF900) || $character < 0x20 - || $character > 0x7E && $character < 0xA0 + || ($character > 0x7E && $character < 0xA0) || $character > 0xEFFFD ) ) { @@ -329,10 +329,10 @@ public static function punycode_encode($input) { } // output the code point for digit t + ((q - t) mod (base - t)) - $digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t)); + $digit = (int) ($t + (($q - $t) % (self::BOOTSTRAP_BASE - $t))); $output .= self::digit_to_char($digit); // let q = (q - t) div (base - t) - $q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t)); + $q = (int) floor(($q - $t) / (self::BOOTSTRAP_BASE - $t)); } // end // output the code point for digit q $output .= self::digit_to_char($q); @@ -381,7 +381,7 @@ protected static function digit_to_char($digit) { * @param int $delta * @param int $numpoints * @param bool $firsttime - * @return int New bias + * @return int|float New bias * * function adapt(delta,numpoints,firsttime): */ diff --git a/includes/vendor/rmccue/requests/src/Ipv6.php b/includes/vendor/rmccue/requests/src/Ipv6.php index a90ab8a83..bcdd63649 100644 --- a/includes/vendor/rmccue/requests/src/Ipv6.php +++ b/includes/vendor/rmccue/requests/src/Ipv6.php @@ -161,7 +161,7 @@ public static function check_ipv6($ip) { list($ipv6, $ipv4) = self::split_v6_v4($ip); $ipv6 = explode(':', $ipv6); $ipv4 = explode('.', $ipv4); - if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) { + if ((count($ipv6) === 8 && count($ipv4) === 1) || (count($ipv6) === 6 && count($ipv4) === 4)) { foreach ($ipv6 as $ipv6_part) { // The section can't be empty if ($ipv6_part === '') { diff --git a/includes/vendor/rmccue/requests/src/Iri.php b/includes/vendor/rmccue/requests/src/Iri.php index 244578d34..c452c7365 100644 --- a/includes/vendor/rmccue/requests/src/Iri.php +++ b/includes/vendor/rmccue/requests/src/Iri.php @@ -395,11 +395,11 @@ protected function remove_dot_segments($input) { // preceding "/" (if any) from the output buffer; otherwise, elseif (strpos($input, '/../') === 0) { $input = substr($input, 3); - $output = substr_replace($output, '', strrpos($output, '/')); + $output = substr_replace($output, '', (strrpos($output, '/') ?: 0)); } elseif ($input === '/..') { $input = '/'; - $output = substr_replace($output, '', strrpos($output, '/')); + $output = substr_replace($output, '', (strrpos($output, '/') ?: 0)); } // D: if the input buffer consists only of "." or "..", then remove // that from the input buffer; otherwise, @@ -824,7 +824,8 @@ protected function set_authority($authority) { else { $iuserinfo = null; } - if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false) { + + if (($port_start = strpos($remaining, ':', (strpos($remaining, ']') ?: 0))) !== false) { $port = substr($remaining, $port_start + 1); if ($port === false || $port === '') { $port = null; diff --git a/includes/vendor/rmccue/requests/src/Requests.php b/includes/vendor/rmccue/requests/src/Requests.php index a8d9d7e53..9dec0abe4 100644 --- a/includes/vendor/rmccue/requests/src/Requests.php +++ b/includes/vendor/rmccue/requests/src/Requests.php @@ -148,7 +148,7 @@ class Requests { * * @var string */ - const VERSION = '2.0.5'; + const VERSION = '2.0.15'; /** * Selected transport name @@ -642,12 +642,14 @@ public static function set_certificate_path($path) { /** * Set the default values * + * The $options parameter is updated with the results. + * * @param string $url URL to request * @param array $headers Extra headers to send with the request * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests * @param string $type HTTP request type * @param array $options Options for the request - * @return void $options is updated with the results + * @return void * * @throws \WpOrg\Requests\Exception When the $url is not an http(s) URL. */ @@ -824,9 +826,11 @@ protected static function parse_response($headers, $url, $req_headers, $req_data * Internal use only. Converts a raw HTTP response to a \WpOrg\Requests\Response * while still executing a multiple request. * + * `$response` is either set to a \WpOrg\Requests\Response instance, or a \WpOrg\Requests\Exception object + * * @param string $response Full response text including headers and body (will be overwritten with Response instance) * @param array $request Request data as passed into {@see \WpOrg\Requests\Requests::request_multiple()} - * @return void `$response` is either set to a \WpOrg\Requests\Response instance, or a \WpOrg\Requests\Exception object + * @return void */ public static function parse_multiple(&$response, $request) { try { diff --git a/includes/vendor/rmccue/requests/src/Response.php b/includes/vendor/rmccue/requests/src/Response.php index 8964521a8..86a0438ba 100644 --- a/includes/vendor/rmccue/requests/src/Response.php +++ b/includes/vendor/rmccue/requests/src/Response.php @@ -137,16 +137,16 @@ public function throw_for_status($allow_redirects = true) { * * @link https://php.net/json-decode * - * @param ?bool $associative Optional. When `true`, JSON objects will be returned as associative arrays; - * When `false`, JSON objects will be returned as objects. - * When `null`, JSON objects will be returned as associative arrays - * or objects depending on whether `JSON_OBJECT_AS_ARRAY` is set in the flags. - * Defaults to `true` (in contrast to the PHP native default of `null`). - * @param int $depth Optional. Maximum nesting depth of the structure being decoded. - * Defaults to `512`. - * @param int $options Optional. Bitmask of JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, - * JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR. - * Defaults to `0` (no options set). + * @param bool|null $associative Optional. When `true`, JSON objects will be returned as associative arrays; + * When `false`, JSON objects will be returned as objects. + * When `null`, JSON objects will be returned as associative arrays + * or objects depending on whether `JSON_OBJECT_AS_ARRAY` is set in the flags. + * Defaults to `true` (in contrast to the PHP native default of `null`). + * @param int $depth Optional. Maximum nesting depth of the structure being decoded. + * Defaults to `512`. + * @param int $options Optional. Bitmask of JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE, + * JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR. + * Defaults to `0` (no options set). * * @return array * diff --git a/includes/vendor/rmccue/requests/src/Response/Headers.php b/includes/vendor/rmccue/requests/src/Response/Headers.php index eb4f68736..b4d0fcf91 100644 --- a/includes/vendor/rmccue/requests/src/Response/Headers.php +++ b/includes/vendor/rmccue/requests/src/Response/Headers.php @@ -27,7 +27,7 @@ class Headers extends CaseInsensitiveDictionary { * Avoid using this where commas may be used unquoted in values, such as * Set-Cookie headers. * - * @param string $offset + * @param string $offset Name of the header to retrieve. * @return string|null Header value */ public function offsetGet($offset) { @@ -69,7 +69,7 @@ public function offsetSet($offset, $value) { /** * Get all values for a given header * - * @param string $offset + * @param string $offset Name of the header to retrieve. * @return array|null Header values * * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not valid as an array key. @@ -79,7 +79,10 @@ public function getValues($offset) { throw InvalidArgument::create(1, '$offset', 'string|int', gettype($offset)); } - $offset = strtolower($offset); + if (is_string($offset)) { + $offset = strtolower($offset); + } + if (!isset($this->data[$offset])) { return null; } diff --git a/includes/vendor/rmccue/requests/src/Transport/Curl.php b/includes/vendor/rmccue/requests/src/Transport/Curl.php index 8b0a13080..7316987b5 100644 --- a/includes/vendor/rmccue/requests/src/Transport/Curl.php +++ b/includes/vendor/rmccue/requests/src/Transport/Curl.php @@ -465,7 +465,7 @@ private function setup_handle($url, $headers, $data, $options) { * @param string $response Response data from the body * @param array $options Request options * @return string|false HTTP response data including headers. False if non-blocking. - * @throws \WpOrg\Requests\Exception + * @throws \WpOrg\Requests\Exception If the request resulted in a cURL error. */ public function process_response($response, $options) { if ($options['blocking'] === false) { @@ -561,7 +561,7 @@ public function stream_body($handle, $data) { /** * Format a URL given GET data * - * @param string $url + * @param string $url Original URL. * @param array|object $data Data to build query using, see {@link https://www.php.net/http_build_query} * @return string URL with data */ diff --git a/includes/vendor/rmccue/requests/src/Transport/Fsockopen.php b/includes/vendor/rmccue/requests/src/Transport/Fsockopen.php index c3bd4a63d..6bd82a32f 100644 --- a/includes/vendor/rmccue/requests/src/Transport/Fsockopen.php +++ b/includes/vendor/rmccue/requests/src/Transport/Fsockopen.php @@ -51,6 +51,11 @@ final class Fsockopen implements Transport { */ private $max_bytes = false; + /** + * Cache for received connection errors. + * + * @var string + */ private $connect_error = ''; /** @@ -139,7 +144,15 @@ public function request($url, $headers = [], $data = [], $options = []) { $verifyname = false; } - stream_context_set_option($context, ['ssl' => $context_options]); + // Handle the PHP 8.4 deprecation (PHP 9.0 removal) of the function signature we use for stream_context_set_option(). + // Ref: https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures#stream_context_set_option + if (function_exists('stream_context_set_options')) { + // PHP 8.3+. + stream_context_set_options($context, ['ssl' => $context_options]); + } else { + // PHP < 8.3. + stream_context_set_option($context, ['ssl' => $context_options]); + } } else { $remote_socket = 'tcp://' . $host; } @@ -405,7 +418,7 @@ private static function accept_encoding() { /** * Format a URL given GET data * - * @param array $url_parts + * @param array $url_parts Array of URL parts as received from {@link https://www.php.net/parse_url} * @param array|object $data Data to build query using, see {@link https://www.php.net/http_build_query} * @return string URL with data */ diff --git a/includes/vendor/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php b/includes/vendor/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php index 3c24cebd4..0e1a914cd 100644 --- a/includes/vendor/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php +++ b/includes/vendor/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php @@ -95,7 +95,7 @@ public function offsetSet($offset, $value) { /** * Unset the given header * - * @param string $offset + * @param string $offset The key for the item to unset. */ #[ReturnTypeWillChange] public function offsetUnset($offset) { diff --git a/includes/vendor/rmccue/requests/src/Utility/FilteredIterator.php b/includes/vendor/rmccue/requests/src/Utility/FilteredIterator.php index 973a5d25a..4865966c4 100644 --- a/includes/vendor/rmccue/requests/src/Utility/FilteredIterator.php +++ b/includes/vendor/rmccue/requests/src/Utility/FilteredIterator.php @@ -28,7 +28,7 @@ final class FilteredIterator extends ArrayIterator { /** * Create a new iterator * - * @param array $data + * @param array $data The array or object to be iterated on. * @param callable $callback Callback to be called on each value * * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data argument is not iterable. @@ -46,14 +46,25 @@ public function __construct($data, $callback) { } /** - * @inheritdoc + * Prevent unserialization of the object for security reasons. * * @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound + * + * @param array $data Restored array of data originally serialized. + * + * @return void */ #[ReturnTypeWillChange] public function __unserialize($data) {} // phpcs:enable + /** + * Perform reinitialization tasks. + * + * Prevents a callback from being injected during unserialization of an object. + * + * @return void + */ public function __wakeup() { unset($this->callback); } @@ -75,7 +86,11 @@ public function current() { } /** - * @inheritdoc + * Prevent creating a PHP value from a stored representation of the object for security reasons. + * + * @param string $data The serialized string. + * + * @return void */ #[ReturnTypeWillChange] public function unserialize($data) {} diff --git a/includes/vendor/symfony/polyfill-intl-idn/Idn.php b/includes/vendor/symfony/polyfill-intl-idn/Idn.php index 86710b94e..334f8ee70 100644 --- a/includes/vendor/symfony/polyfill-intl-idn/Idn.php +++ b/includes/vendor/symfony/polyfill-intl-idn/Idn.php @@ -11,8 +11,6 @@ namespace Symfony\Polyfill\Intl\Idn; -use Exception; -use Normalizer; use Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges; use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex; @@ -147,7 +145,7 @@ final class Idn */ public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) { - if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) { + if (self::INTL_IDNA_VARIANT_2003 === $variant) { @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); } @@ -167,7 +165,7 @@ public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, if (1 === preg_match('/[^\x00-\x7F]/', $label)) { try { $label = 'xn--'.self::punycodeEncode($label); - } catch (Exception $e) { + } catch (\Exception $e) { $info->errors |= self::ERROR_PUNYCODE; } @@ -200,7 +198,7 @@ public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, */ public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) { - if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) { + if (self::INTL_IDNA_VARIANT_2003 === $variant) { @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); } @@ -282,10 +280,6 @@ private static function mapCodePoints($input, array $options, Info $info) switch ($data['status']) { case 'disallowed': - $info->errors |= self::ERROR_DISALLOWED; - - // no break. - case 'valid': $str .= mb_chr($codePoint, 'utf-8'); @@ -296,7 +290,7 @@ private static function mapCodePoints($input, array $options, Info $info) break; case 'mapped': - $str .= $data['mapping']; + $str .= $transitional && 0x1E9E === $codePoint ? 'ss' : $data['mapping']; break; @@ -335,8 +329,8 @@ private static function process($domain, array $options, Info $info) $domain = self::mapCodePoints($domain, $options, $info); // Step 2. Normalize the domain name string to Unicode Normalization Form C. - if (!Normalizer::isNormalized($domain, Normalizer::FORM_C)) { - $domain = Normalizer::normalize($domain, Normalizer::FORM_C); + if (!\Normalizer::isNormalized($domain, \Normalizer::FORM_C)) { + $domain = \Normalizer::normalize($domain, \Normalizer::FORM_C); } // Step 3. Break the string into labels at U+002E (.) FULL STOP. @@ -348,9 +342,21 @@ private static function process($domain, array $options, Info $info) $validationOptions = $options; if ('xn--' === substr($label, 0, 4)) { + // Step 4.1. If the label contains any non-ASCII code point (i.e., a code point greater than U+007F), + // record that there was an error, and continue with the next label. + if (preg_match('/[^\x00-\x7F]/', $label)) { + $info->errors |= self::ERROR_PUNYCODE; + + continue; + } + + // Step 4.2. Attempt to convert the rest of the label to Unicode according to Punycode [RFC3492]. If + // that conversion fails, record that there was an error, and continue + // with the next label. Otherwise replace the original label in the string by the results of the + // conversion. try { $label = self::punycodeDecode(substr($label, 4)); - } catch (Exception $e) { + } catch (\Exception $e) { $info->errors |= self::ERROR_PUNYCODE; continue; @@ -496,7 +502,7 @@ private static function validateLabel($label, Info $info, array $options, $canBe } // Step 1. The label must be in Unicode Normalization Form C. - if (!Normalizer::isNormalized($label, Normalizer::FORM_C)) { + if (!\Normalizer::isNormalized($label, \Normalizer::FORM_C)) { $info->errors |= self::ERROR_INVALID_ACE_LABEL; } @@ -518,6 +524,8 @@ private static function validateLabel($label, Info $info, array $options, $canBe if ('-' === substr($label, -1, 1)) { $info->errors |= self::ERROR_TRAILING_HYPHEN; } + } elseif ('xn--' === substr($label, 0, 4)) { + $info->errors |= self::ERROR_PUNYCODE; } // Step 4. The label must not contain a U+002E (.) FULL STOP. @@ -583,7 +591,7 @@ private static function punycodeDecode($input) for ($j = 0; $j < $b; ++$j) { if ($bytes[$j] > 0x7F) { - throw new Exception('Invalid input'); + throw new \Exception('Invalid input'); } $output[$out++] = $input[$j]; @@ -599,17 +607,17 @@ private static function punycodeDecode($input) for ($k = self::BASE; /* no condition */; $k += self::BASE) { if ($in >= $inputLength) { - throw new Exception('Invalid input'); + throw new \Exception('Invalid input'); } $digit = self::$basicToDigit[$bytes[$in++] & 0xFF]; if ($digit < 0) { - throw new Exception('Invalid input'); + throw new \Exception('Invalid input'); } if ($digit > intdiv(self::MAX_INT - $i, $w)) { - throw new Exception('Integer overflow'); + throw new \Exception('Integer overflow'); } $i += $digit * $w; @@ -629,7 +637,7 @@ private static function punycodeDecode($input) $baseMinusT = self::BASE - $t; if ($w > intdiv(self::MAX_INT, $baseMinusT)) { - throw new Exception('Integer overflow'); + throw new \Exception('Integer overflow'); } $w *= $baseMinusT; @@ -639,7 +647,7 @@ private static function punycodeDecode($input) $bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi); if (intdiv($i, $outPlusOne) > self::MAX_INT - $n) { - throw new Exception('Integer overflow'); + throw new \Exception('Integer overflow'); } $n += intdiv($i, $outPlusOne); @@ -694,7 +702,7 @@ private static function punycodeEncode($input) } if ($m - $n > intdiv(self::MAX_INT - $delta, $h + 1)) { - throw new Exception('Integer overflow'); + throw new \Exception('Integer overflow'); } $delta += ($m - $n) * ($h + 1); @@ -702,7 +710,7 @@ private static function punycodeEncode($input) foreach ($iter as $codePoint) { if ($codePoint < $n && 0 === ++$delta) { - throw new Exception('Integer overflow'); + throw new \Exception('Integer overflow'); } if ($codePoint === $n) { diff --git a/includes/vendor/symfony/polyfill-intl-idn/LICENSE b/includes/vendor/symfony/polyfill-intl-idn/LICENSE index 03c5e2577..fd0a0626a 100644 --- a/includes/vendor/symfony/polyfill-intl-idn/LICENSE +++ b/includes/vendor/symfony/polyfill-intl-idn/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2019 Fabien Potencier and Trevor Rowbotham +Copyright (c) 2018-present Fabien Potencier and Trevor Rowbotham Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php b/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php index 5bb70e48a..d285acd13 100644 --- a/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php +++ b/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; /** diff --git a/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php b/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php index 5c1c51dde..3c6af0c13 100644 --- a/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php +++ b/includes/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; /** diff --git a/includes/vendor/symfony/polyfill-intl-idn/composer.json b/includes/vendor/symfony/polyfill-intl-idn/composer.json index 105e3d06c..760debcd2 100644 --- a/includes/vendor/symfony/polyfill-intl-idn/composer.json +++ b/includes/vendor/symfony/polyfill-intl-idn/composer.json @@ -20,9 +20,8 @@ } ], "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" }, @@ -33,9 +32,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE b/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE index 4cd8bdd30..6e3afce69 100644 --- a/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE +++ b/includes/vendor/symfony/polyfill-intl-normalizer/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2019 Fabien Potencier +Copyright (c) 2015-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/includes/vendor/symfony/polyfill-intl-normalizer/composer.json b/includes/vendor/symfony/polyfill-intl-normalizer/composer.json index 65f72d645..9bd04e887 100644 --- a/includes/vendor/symfony/polyfill-intl-normalizer/composer.json +++ b/includes/vendor/symfony/polyfill-intl-normalizer/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, @@ -28,9 +28,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/includes/vendor/symfony/polyfill-mbstring/LICENSE b/includes/vendor/symfony/polyfill-mbstring/LICENSE index 4cd8bdd30..6e3afce69 100644 --- a/includes/vendor/symfony/polyfill-mbstring/LICENSE +++ b/includes/vendor/symfony/polyfill-mbstring/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2019 Fabien Potencier +Copyright (c) 2015-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/includes/vendor/symfony/polyfill-mbstring/Mbstring.php b/includes/vendor/symfony/polyfill-mbstring/Mbstring.php index bce5c4a84..3d45c9d9a 100644 --- a/includes/vendor/symfony/polyfill-mbstring/Mbstring.php +++ b/includes/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -48,6 +48,11 @@ * - mb_strstr - Finds first occurrence of a string within another * - mb_strwidth - Return width of string * - mb_substr_count - Count the number of substring occurrences + * - mb_ucfirst - Make a string's first character uppercase + * - mb_lcfirst - Make a string's first character lowercase + * - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string + * - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string + * - mb_rtrim - Strip whitespace (or other characters) from the end of a string * * Not implemented: * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) @@ -69,7 +74,7 @@ final class Mbstring { public const MB_CASE_FOLD = \PHP_INT_MAX; - private const CASE_FOLD = [ + private const SIMPLE_CASE_FOLD = [ ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], ]; @@ -80,6 +85,15 @@ final class Mbstring public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { + if (\is_array($s)) { + $r = []; + foreach ($s as $str) { + $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding); + } + + return $r; + } + if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); } else { @@ -301,7 +315,11 @@ public static function mb_convert_case($s, $mode, $encoding = null) $map = $upper; } else { if (self::MB_CASE_FOLD === $mode) { - $s = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s); + static $caseFolding = null; + if (null === $caseFolding) { + $caseFolding = self::getData('caseFolding'); + } + $s = strtr($s, $caseFolding); } static $lower = null; @@ -413,7 +431,20 @@ public static function mb_check_encoding($var = null, $encoding = null) $encoding = self::$internalEncoding; } - return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); + if (!\is_array($var)) { + return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); + } + + foreach ($var as $key => $value) { + if (!self::mb_check_encoding($key, $encoding)) { + return false; + } + if (!self::mb_check_encoding($value, $encoding)) { + return false; + } + } + + return true; } public static function mb_detect_encoding($str, $encodingList = null, $strict = false) @@ -638,8 +669,10 @@ public static function mb_substr($s, $start, $length = null, $encoding = null) public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { - $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); - $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); + [$haystack, $needle] = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [ + self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), + self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding), + ]); return self::mb_strpos($haystack, $needle, $offset, $encoding); } @@ -674,8 +707,11 @@ public static function mb_strrichr($haystack, $needle, $part = false, $encoding public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { - $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); - $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); + $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding); + $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); + + $haystack = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); + $needle = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); return self::mb_strrpos($haystack, $needle, $offset, $encoding); } @@ -798,6 +834,69 @@ public static function mb_ord($s, $encoding = null) return $code; } + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string + { + if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + } + + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given'); + } + + if (self::mb_strlen($pad_string, $encoding) <= 0) { + throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); + } + + $paddingRequired = $length - self::mb_strlen($string, $encoding); + + if ($paddingRequired < 1) { + return $string; + } + + switch ($pad_type) { + case \STR_PAD_LEFT: + return self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding).$string; + case \STR_PAD_RIGHT: + return $string.self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); + default: + $leftPaddingLength = floor($paddingRequired / 2); + $rightPaddingLength = $paddingRequired - $leftPaddingLength; + + return self::mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.self::mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); + } + } + + public static function mb_ucfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + + public static function mb_lcfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + private static function getSubpart($pos, $part, $haystack, $encoding) { if (false === $pos) { @@ -871,4 +970,76 @@ private static function getEncoding($encoding) return $encoding; } + + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__); + } + + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given'); + } + + if ('' === $characters) { + return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding); + } + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $string)) { + $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string); + } + if (null !== $characters && !preg_match('//u', $characters)) { + $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters); + } + } else { + $string = iconv($encoding, 'UTF-8//IGNORE', $string); + + if (null !== $characters) { + $characters = iconv($encoding, 'UTF-8//IGNORE', $characters); + } + } + + if (null === $characters) { + $characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}"; + } else { + $characters = preg_quote($characters); + } + + $string = preg_replace(sprintf($regex, $characters), '', $string); + + if (null === $encoding) { + return $string; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $string); + } + + private static function assertEncoding(string $encoding, string $errorFormat): void + { + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + } } diff --git a/includes/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php b/includes/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php new file mode 100644 index 000000000..512bba0bf --- /dev/null +++ b/includes/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php @@ -0,0 +1,119 @@ + 'i̇', + 'µ' => 'μ', + 'ſ' => 's', + 'ͅ' => 'ι', + 'ς' => 'σ', + 'ϐ' => 'β', + 'ϑ' => 'θ', + 'ϕ' => 'φ', + 'ϖ' => 'π', + 'ϰ' => 'κ', + 'ϱ' => 'ρ', + 'ϵ' => 'ε', + 'ẛ' => 'ṡ', + 'ι' => 'ι', + 'ß' => 'ss', + 'ʼn' => 'ʼn', + 'ǰ' => 'ǰ', + 'ΐ' => 'ΐ', + 'ΰ' => 'ΰ', + 'և' => 'եւ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẚ' => 'aʾ', + 'ẞ' => 'ss', + 'ὐ' => 'ὐ', + 'ὒ' => 'ὒ', + 'ὔ' => 'ὔ', + 'ὖ' => 'ὖ', + 'ᾀ' => 'ἀι', + 'ᾁ' => 'ἁι', + 'ᾂ' => 'ἂι', + 'ᾃ' => 'ἃι', + 'ᾄ' => 'ἄι', + 'ᾅ' => 'ἅι', + 'ᾆ' => 'ἆι', + 'ᾇ' => 'ἇι', + 'ᾈ' => 'ἀι', + 'ᾉ' => 'ἁι', + 'ᾊ' => 'ἂι', + 'ᾋ' => 'ἃι', + 'ᾌ' => 'ἄι', + 'ᾍ' => 'ἅι', + 'ᾎ' => 'ἆι', + 'ᾏ' => 'ἇι', + 'ᾐ' => 'ἠι', + 'ᾑ' => 'ἡι', + 'ᾒ' => 'ἢι', + 'ᾓ' => 'ἣι', + 'ᾔ' => 'ἤι', + 'ᾕ' => 'ἥι', + 'ᾖ' => 'ἦι', + 'ᾗ' => 'ἧι', + 'ᾘ' => 'ἠι', + 'ᾙ' => 'ἡι', + 'ᾚ' => 'ἢι', + 'ᾛ' => 'ἣι', + 'ᾜ' => 'ἤι', + 'ᾝ' => 'ἥι', + 'ᾞ' => 'ἦι', + 'ᾟ' => 'ἧι', + 'ᾠ' => 'ὠι', + 'ᾡ' => 'ὡι', + 'ᾢ' => 'ὢι', + 'ᾣ' => 'ὣι', + 'ᾤ' => 'ὤι', + 'ᾥ' => 'ὥι', + 'ᾦ' => 'ὦι', + 'ᾧ' => 'ὧι', + 'ᾨ' => 'ὠι', + 'ᾩ' => 'ὡι', + 'ᾪ' => 'ὢι', + 'ᾫ' => 'ὣι', + 'ᾬ' => 'ὤι', + 'ᾭ' => 'ὥι', + 'ᾮ' => 'ὦι', + 'ᾯ' => 'ὧι', + 'ᾲ' => 'ὰι', + 'ᾳ' => 'αι', + 'ᾴ' => 'άι', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾶι', + 'ᾼ' => 'αι', + 'ῂ' => 'ὴι', + 'ῃ' => 'ηι', + 'ῄ' => 'ήι', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῆι', + 'ῌ' => 'ηι', + 'ῒ' => 'ῒ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'ῢ' => 'ῢ', + 'ῤ' => 'ῤ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'ῲ' => 'ὼι', + 'ῳ' => 'ωι', + 'ῴ' => 'ώι', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῶι', + 'ῼ' => 'ωι', + 'ff' => 'ff', + 'fi' => 'fi', + 'fl' => 'fl', + 'ffi' => 'ffi', + 'ffl' => 'ffl', + 'ſt' => 'st', + 'st' => 'st', + 'ﬓ' => 'մն', + 'ﬔ' => 'մե', + 'ﬕ' => 'մի', + 'ﬖ' => 'վն', + 'ﬗ' => 'մխ', +]; diff --git a/includes/vendor/symfony/polyfill-mbstring/bootstrap.php b/includes/vendor/symfony/polyfill-mbstring/bootstrap.php index 1fedd1f7c..ff51ae079 100644 --- a/includes/vendor/symfony/polyfill-mbstring/bootstrap.php +++ b/includes/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -132,6 +132,31 @@ function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } } +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + + if (extension_loaded('mbstring')) { return; } diff --git a/includes/vendor/symfony/polyfill-mbstring/bootstrap80.php b/includes/vendor/symfony/polyfill-mbstring/bootstrap80.php index 82f5ac4d0..5be7d2018 100644 --- a/includes/vendor/symfony/polyfill-mbstring/bootstrap80.php +++ b/includes/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -93,7 +93,7 @@ function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?strin function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_get_info')) { - function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } + function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); } } if (!function_exists('mb_http_output')) { function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } @@ -128,6 +128,30 @@ function mb_scrub(?string $string, ?string $encoding = null): string { $encoding function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } } +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + if (extension_loaded('mbstring')) { return; } diff --git a/includes/vendor/symfony/polyfill-mbstring/composer.json b/includes/vendor/symfony/polyfill-mbstring/composer.json index 44895536b..4ed241a33 100644 --- a/includes/vendor/symfony/polyfill-mbstring/composer.json +++ b/includes/vendor/symfony/polyfill-mbstring/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -30,9 +30,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/includes/vendor/symfony/polyfill-php72/LICENSE b/includes/vendor/symfony/polyfill-php72/LICENSE deleted file mode 100644 index 4cd8bdd30..000000000 --- a/includes/vendor/symfony/polyfill-php72/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/includes/vendor/symfony/polyfill-php72/Php72.php b/includes/vendor/symfony/polyfill-php72/Php72.php deleted file mode 100644 index 7bf96c996..000000000 --- a/includes/vendor/symfony/polyfill-php72/Php72.php +++ /dev/null @@ -1,217 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php72; - -/** - * @author Nicolas Grekas - * @author Dariusz Rumiński - * - * @internal - */ -final class Php72 -{ - private static $hashMask; - - public static function utf8_encode($s) - { - $s .= $s; - $len = \strlen($s); - - for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) { - switch (true) { - case $s[$i] < "\x80": $s[$j] = $s[$i]; break; - case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break; - default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break; - } - } - - return substr($s, 0, $j); - } - - public static function utf8_decode($s) - { - $s = (string) $s; - $len = \strlen($s); - - for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { - switch ($s[$i] & "\xF0") { - case "\xC0": - case "\xD0": - $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F"); - $s[$j] = $c < 256 ? \chr($c) : '?'; - break; - - case "\xF0": - ++$i; - // no break - - case "\xE0": - $s[$j] = '?'; - $i += 2; - break; - - default: - $s[$j] = $s[$i]; - } - } - - return substr($s, 0, $j); - } - - public static function php_os_family() - { - if ('\\' === \DIRECTORY_SEPARATOR) { - return 'Windows'; - } - - $map = [ - 'Darwin' => 'Darwin', - 'DragonFly' => 'BSD', - 'FreeBSD' => 'BSD', - 'NetBSD' => 'BSD', - 'OpenBSD' => 'BSD', - 'Linux' => 'Linux', - 'SunOS' => 'Solaris', - ]; - - return $map[\PHP_OS] ?? 'Unknown'; - } - - public static function spl_object_id($object) - { - if (null === self::$hashMask) { - self::initHashMask(); - } - if (null === $hash = spl_object_hash($object)) { - return; - } - - // On 32-bit systems, PHP_INT_SIZE is 4, - return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); - } - - public static function sapi_windows_vt100_support($stream, $enable = null) - { - if (!\is_resource($stream)) { - trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING); - - return false; - } - - $meta = stream_get_meta_data($stream); - - if ('STDIO' !== $meta['stream_type']) { - trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING); - - return false; - } - - // We cannot actually disable vt100 support if it is set - if (false === $enable || !self::stream_isatty($stream)) { - return false; - } - - // The native function does not apply to stdin - $meta = array_map('strtolower', $meta); - $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri']; - - return !$stdin - && (false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM') - || 'Hyper' === getenv('TERM_PROGRAM')); - } - - public static function stream_isatty($stream) - { - if (!\is_resource($stream)) { - trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING); - - return false; - } - - if ('\\' === \DIRECTORY_SEPARATOR) { - $stat = @fstat($stream); - // Check if formatted mode is S_IFCHR - return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; - } - - return \function_exists('posix_isatty') && @posix_isatty($stream); - } - - private static function initHashMask() - { - $obj = (object) []; - self::$hashMask = -1; - - // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below - $obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush']; - foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) { - if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) { - $frame['line'] = 0; - break; - } - } - if (!empty($frame['line'])) { - ob_start(); - debug_zval_dump($obj); - self::$hashMask = (int) substr(ob_get_clean(), 17); - } - - self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); - } - - public static function mb_chr($code, $encoding = null) - { - if (0x80 > $code %= 0x200000) { - $s = \chr($code); - } elseif (0x800 > $code) { - $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); - } elseif (0x10000 > $code) { - $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } else { - $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } - - if ('UTF-8' !== $encoding = $encoding ?? mb_internal_encoding()) { - $s = mb_convert_encoding($s, $encoding, 'UTF-8'); - } - - return $s; - } - - public static function mb_ord($s, $encoding = null) - { - if (null === $encoding) { - $s = mb_convert_encoding($s, 'UTF-8'); - } elseif ('UTF-8' !== $encoding) { - $s = mb_convert_encoding($s, 'UTF-8', $encoding); - } - - if (1 === \strlen($s)) { - return \ord($s); - } - - $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; - if (0xF0 <= $code) { - return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; - } - if (0xE0 <= $code) { - return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; - } - if (0xC0 <= $code) { - return (($code - 0xC0) << 6) + $s[2] - 0x80; - } - - return $code; - } -} diff --git a/includes/vendor/symfony/polyfill-php72/README.md b/includes/vendor/symfony/polyfill-php72/README.md deleted file mode 100644 index ed1905055..000000000 --- a/includes/vendor/symfony/polyfill-php72/README.md +++ /dev/null @@ -1,35 +0,0 @@ -Symfony Polyfill / Php72 -======================== - -This component provides functions added to PHP 7.2 core: - -- [`spl_object_id`](https://php.net/spl_object_id) -- [`stream_isatty`](https://php.net/stream_isatty) - -And also functions added to PHP 7.2 mbstring: - -- [`mb_ord`](https://php.net/mb_ord) -- [`mb_chr`](https://php.net/mb_chr) -- [`mb_scrub`](https://php.net/mb_scrub) - -On Windows only: - -- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support) - -Moved to core since 7.2 (was in the optional XML extension earlier): - -- [`utf8_encode`](https://php.net/utf8_encode) -- [`utf8_decode`](https://php.net/utf8_decode) - -Also, it provides constants added to PHP 7.2: - -- [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig) -- [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family) - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/includes/vendor/symfony/polyfill-php72/bootstrap.php b/includes/vendor/symfony/polyfill-php72/bootstrap.php deleted file mode 100644 index b5c92d4c7..000000000 --- a/includes/vendor/symfony/polyfill-php72/bootstrap.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php72 as p; - -if (\PHP_VERSION_ID >= 70200) { - return; -} - -if (!defined('PHP_FLOAT_DIG')) { - define('PHP_FLOAT_DIG', 15); -} -if (!defined('PHP_FLOAT_EPSILON')) { - define('PHP_FLOAT_EPSILON', 2.2204460492503E-16); -} -if (!defined('PHP_FLOAT_MIN')) { - define('PHP_FLOAT_MIN', 2.2250738585072E-308); -} -if (!defined('PHP_FLOAT_MAX')) { - define('PHP_FLOAT_MAX', 1.7976931348623157E+308); -} -if (!defined('PHP_OS_FAMILY')) { - define('PHP_OS_FAMILY', p\Php72::php_os_family()); -} - -if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) { - function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); } -} -if (!function_exists('stream_isatty')) { - function stream_isatty($stream) { return p\Php72::stream_isatty($stream); } -} -if (!function_exists('utf8_encode')) { - function utf8_encode($string) { return p\Php72::utf8_encode($string); } -} -if (!function_exists('utf8_decode')) { - function utf8_decode($string) { return p\Php72::utf8_decode($string); } -} -if (!function_exists('spl_object_id')) { - function spl_object_id($object) { return p\Php72::spl_object_id($object); } -} -if (!function_exists('mb_ord')) { - function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); } -} -if (!function_exists('mb_chr')) { - function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); } -} -if (!function_exists('mb_scrub')) { - function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } -} diff --git a/includes/vendor/symfony/polyfill-php72/composer.json b/includes/vendor/symfony/polyfill-php72/composer.json deleted file mode 100644 index 5f17af343..000000000 --- a/includes/vendor/symfony/polyfill-php72/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "symfony/polyfill-php72", - "type": "library", - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Php72\\": "" }, - "files": [ "bootstrap.php" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/includes/version.php b/includes/version.php index 7c8990355..e65d285b6 100644 --- a/includes/version.php +++ b/includes/version.php @@ -9,7 +9,7 @@ * MAJOR.MINOR.PATCH-SOMETHING (1.8.1-donotuse) * */ -define( 'YOURLS_VERSION', '1.9.2' ); +define( 'YOURLS_VERSION', '1.10.3-dev' ); /** * YOURLS DB version. Increments when changes are made to the DB schema, to trigger a DB update diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0c61fbc4c..de7f05ff3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,44 +1,46 @@ - - - - ./tests/tests - - - - - ajax - - - - + bootstrap="tests/bootstrap.php" + > + + ./includes - - ./includes/vendors - - - - - - - - - - - - - - - - - - + + + ./includes/vendors + + + + + ./tests/tests + ./tests/tests/auth/AbstractLoginTestCase.php + ./tests/tests/auth/LoginAssertionTrait.php + + + + + ajax + + + + + + + + + + + + + + + + + diff --git a/readme.html b/readme.html index a27f70bff..4fc1fd296 100644 --- a/readme.html +++ b/readme.html @@ -273,7 +273,7 @@

YOURLS: Your Own YOURLS is made by awesome people.

-

Keep up to date: read the official YOURLS Blog.

+

Keep up to date: read the official YOURLS Blog.

@@ -504,7 +504,7 @@

YOURLS: Your Own

Sample return in XML format for the expand action

@@ -531,7 +531,7 @@

YOURLS: Your Own

Server requirements and recommendations

    -
  1. We recommend PHP 7.4 or above
  2. +
  3. PHP 8.1 or above is required
  4. You will need at least MYSQL 5
  5. A web server with mod_rewrite enabled
    Note: YOURLS can also run on Nginx, @@ -557,8 +557,8 @@

    YOURLS: Your Own

    Getting a short domain name for your YOURLS install

    • Unless you plan on making it public and as popular as bit.ly, any shared hosting will be fine. Ozh runs all his YOURLS instance on Dreamhost and it works just great.
    • -
    • Domainr is a fun search tool that might inspire and help you
    • -
    • Aim for exotic top-level domains (.in, .im, .li ...), they're often cheap and a lot are still available. Gandi is a pretty comprehensive registrar, for instance.
    • +
    • Domainr is a fun search tool that might inspire and help you. TLD List has each and every existing top level domain.
    • +
    • Aim for exotic top-level domains (.in, .im, .li, .xyz ...), they're often cheap and a lot are still available.

    YOURLS needs its own .htaccess

    diff --git a/tests/README.md b/tests/README.md index 778018a93..fde3d4653 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,33 +1,35 @@ -Unit Tests for [YOURLS](https://github.com/YOURLS/YOURLS/) -================= +# Unit Tests for [YOURLS](https://github.com/YOURLS/YOURLS/) +## About -About ------ +This is the unit test suite for YOURLS: a collection of hundreds of tests to make sure that whenever something in YOURLS is added, changed or removed, everything still works under all the supported PHP versions. -This is the unit test suite for YOURLS : a collection of hundreds of tests to make sure that whenever something in YOURLS is added, changed or removed, everything still works under all the supported PHP versions. +## Getting Started -Tests ------------ If you want to run tests locally: -0. Install PHPUnit -1. Create an empty MySQL database and user. **Do not use an exisiting database** or you will lose data, guaranteed. -3. Copy `tests/data/config/yourls-tests-config-sample.php` to `/tests/yourls-tests-config.php` and edit it to match your setup. +0. Install PHPUnit. + ```bash + composer -d tests/ install + ``` +1. Create an empty MySQL database and user. **Do not use an exisiting database** or you will lose data, guaranteed. +3. Copy `tests/data/config/yourls-tests-config-sample.php` to `/tests/yourls-tests-config.php` and edit it to match your setup. + ```bash + cp tests/data/config/yourls-tests-config-sample.php tests/yourls-tests-config.php + ``` 4. In YOURLS root directory, you can now run the shell command: -```bash -$ phpunit -``` + ```bash + composer -d tests/ run test -- --configuration=../phpunit.xml.dist .. + ``` Hopefully you should see something like the following appear: ``` YOURLS installed, starting PHPUnit -PHPUnit 7.5.20 by Sebastian Bergmann and contributors. +PHPUnit by Sebastian Bergmann and contributors. -Runtime: PHP 7.4.3 -Configuration: D:\home\planetozh\ozh.in\phpunit.xml.dist +Configuration: ...\phpunit.xml.dist ............................................................... 63 / 519 ( 12%) ............................................................... 126 / 519 ( 24%) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index cccc0cd6f..414b27206 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -11,8 +11,8 @@ $yourls_locale, $yourls_l10n, $yourls_locale_formats, // used by L10N API $yourls_allowedentitynames, $yourls_allowedprotocols; // used by KSES -require_once dirname( __FILE__ ) . '/includes/utils.php'; -require_once dirname( __FILE__ ) . '/includes/install.php'; +require_once __DIR__ . '/includes/utils.php'; +require_once __DIR__ . '/includes/install.php'; // Include relevant config file define('YOURLS_CONFIGFILE', yut_find_config()); @@ -20,7 +20,7 @@ // Bootstrap YOURLS require_once YOURLS_ABSPATH . '/includes/vendor/autoload.php'; -define('YOURLS_TESTDATA_DIR', dirname( __FILE__ ) . '/data'); +define('YOURLS_TESTDATA_DIR', __DIR__ . '/data'); define('YOURLS_LANG_DIR', YOURLS_TESTDATA_DIR.'/pomo'); define('YOURLS_PLUGINDIR', YOURLS_TESTDATA_DIR.'/plugins'); define('YOURLS_PAGEDIR', YOURLS_TESTDATA_DIR.'/pages'); @@ -61,3 +61,6 @@ } ); echo "YOURLS installed, starting PHPUnit\n\n"; + +require_once __DIR__ . "/tests/auth/AbstractLoginTestCase.php"; +require_once __DIR__ . "/tests/auth/LoginAssertionTrait.php"; diff --git a/tests/composer.lock b/tests/composer.lock index 78d24698a..5f50e7ca1 100644 --- a/tests/composer.lock +++ b/tests/composer.lock @@ -6,96 +6,32 @@ ], "content-hash": "9fcd71b761cb2ca79908f32b4f52bfd1", "packages": [ - { - "name": "doctrine/instantiator", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2020-11-10T18:47:58+00:00" - }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "024473a478be9df5fdaca2c793f2232fe788e414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", + "reference": "024473a478be9df5fdaca2c793f2232fe788e414", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { @@ -120,7 +56,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" }, "funding": [ { @@ -128,29 +64,31 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -158,7 +96,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -182,26 +120,27 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -242,9 +181,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -297,273 +242,46 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" - }, - "time": "2022-01-04T19:58:01+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, { "name": "phpunit/php-code-coverage", - "version": "9.2.11", + "version": "11.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f" + "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/14d63fbcca18457e49c6f8bebaa91a87e8e188d7", + "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "nikic/php-parser": "^5.4.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.5.2" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -591,7 +309,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.9" }, "funding": [ { @@ -599,32 +318,32 @@ "type": "github" } ], - "time": "2022-02-18T12:46:09+00:00" + "time": "2025-02-25T13:26:39+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -651,7 +370,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, "funding": [ { @@ -659,28 +379,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2024-08-27T05:02:59+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcntl": "*" @@ -688,7 +408,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -714,7 +434,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -722,32 +443,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -773,7 +494,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -781,32 +503,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -832,7 +554,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -840,59 +563,52 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "9.5.14", + "version": "11.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189" + "reference": "d5df2b32d729562ff8db634678d71085ee579006" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d5df2b32d729562ff8db634678d71085ee579006", + "reference": "d5df2b32d729562ff8db634678d71085ee579006", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3.4", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" + "myclabs/deep-copy": "^1.13.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.2", + "sebastian/comparator": "^6.3.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -900,7 +616,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-main": "11.5-dev" } }, "autoload": { @@ -931,7 +647,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.10" }, "funding": [ { @@ -941,34 +658,38 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2022-02-18T12:54:07+00:00" + "time": "2025-02-25T06:11:48+00:00" }, { "name": "sebastian/cli-parser", - "version": "1.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -991,7 +712,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, "funding": [ { @@ -999,32 +721,32 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-07-03T04:41:36+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1047,7 +769,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" }, "funding": [ { @@ -1055,32 +778,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2024-12-12T09:59:06+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1102,7 +825,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -1110,34 +834,39 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.2-dev" } }, "autoload": { @@ -1176,7 +905,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.0" }, "funding": [ { @@ -1184,33 +914,33 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2025-01-06T10:28:19+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1233,7 +963,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, "funding": [ { @@ -1241,33 +972,33 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^11.0", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1299,7 +1030,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, "funding": [ { @@ -1307,27 +1039,27 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-posix": "*" @@ -1335,7 +1067,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -1354,7 +1086,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -1362,7 +1094,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" }, "funding": [ { @@ -1370,34 +1103,34 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2024-07-03T04:54:44+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -1439,7 +1172,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" }, "funding": [ { @@ -1447,38 +1181,35 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2024-12-05T09:17:50+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -1497,13 +1228,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" }, "funding": [ { @@ -1511,33 +1243,33 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1560,7 +1292,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { @@ -1568,34 +1301,34 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1617,7 +1350,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -1625,32 +1359,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1672,7 +1406,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { @@ -1680,32 +1415,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1732,10 +1467,11 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, "funding": [ { @@ -1743,87 +1479,32 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1846,7 +1527,8 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" }, "funding": [ { @@ -1854,29 +1536,29 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2024-09-17T13:12:04+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1899,7 +1581,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { @@ -1907,102 +1590,72 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.24.0", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, - "suggest": { - "ext-ctype": "For best performance" + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" + "classmap": [ + "lib/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", + "description": "A static analysis tool to detect side effects in PHP code", "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" + "static analysis" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/staabm", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -2031,7 +1684,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -2039,74 +1692,16 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/tests/data/auth/config-test-auth.php b/tests/data/auth/config-test-auth.php index 8a7b3950a..7b89a2275 100644 --- a/tests/data/auth/config-test-auth.php +++ b/tests/data/auth/config-test-auth.php @@ -9,5 +9,5 @@ 'quote2' => "'ahah'", 'utf8fun' => 'أنا أحب النقانق', 's[p]e(c)i{a}!@#$%^&*-=l<>,/?' => 'password', - ); + ); diff --git a/tests/data/config/yourls-tests-config-ci.php b/tests/data/config/yourls-tests-config-ci.php index 30810f669..1dcd2564f 100644 --- a/tests/data/config/yourls-tests-config-ci.php +++ b/tests/data/config/yourls-tests-config-ci.php @@ -30,15 +30,15 @@ define('YOURLS_DEBUG', true); $yourls_reserved_URL = array( - 'porn', 'sex', 'nigger', 'fuck', 'cunt', 'dick', + 'porn', 'sex', 'nigger', 'fuck', 'cunt', 'dick', ); $yourls_user_passwords = array( - 'yourls' => 'secret-ci-test', - 'clear' => 'somepassword', - 'md5' => 'md5:12373:e52e4488f79a740bd341f229e3c163c8', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with md5 and salt - 'phpass' => 'phpass:!2a!08!T1ptMlBSxu7g3odpbUXgd.9wbKvg8k7cJt.HbwSqUNrlLPudWnf/6', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with old PHPass library - 'phpass2' => 'phpass:$2a$08$gt2bnpfUyuCX3hrp0RPOieFR1RwBnLsMzpq/NvPXwCdV3LqI3RGYi', // password: also '3cd6944201fa7bbc5e0fe852e36b1096' with old PHPass lib but without YOURLS internal char substitution + 'yourls' => 'secret-ci-test', + 'clear' => 'somepassword', + 'md5' => 'md5:12373:e52e4488f79a740bd341f229e3c163c8', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with md5 and salt + 'phpass' => 'phpass:!2a!08!T1ptMlBSxu7g3odpbUXgd.9wbKvg8k7cJt.HbwSqUNrlLPudWnf/6', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with old PHPass library + 'phpass2' => 'phpass:$2a$08$gt2bnpfUyuCX3hrp0RPOieFR1RwBnLsMzpq/NvPXwCdV3LqI3RGYi', // password: also '3cd6944201fa7bbc5e0fe852e36b1096' with old PHPass lib but without YOURLS internal char substitution 'phpass3' => 'phpass:!2y!10!.FjK.vQR0JVivkMwckiiIesFUFhtMxX/f9pes.i/ccp/W0IuUSxPW', // password: also '3cd6944201fa7bbc5e0fe852e36b1096' hashed with password_hash 'phpass4' => 'phpass:$2y$10$KPP/sv7pv0JL2GwcixNBfuXRPElC4KxQUgetqBfCboB.q30yKwKG6', // password: also '3cd6944201fa7bbc5e0fe852e36b1096' hashed with password_hash but without YOURLS internal char substitution '1994' => '@$*', diff --git a/tests/data/config/yourls-tests-config-sample.php b/tests/data/config/yourls-tests-config-sample.php index 6ec26b433..213c907e5 100644 --- a/tests/data/config/yourls-tests-config-sample.php +++ b/tests/data/config/yourls-tests-config-sample.php @@ -32,13 +32,13 @@ define('YOURLS_DEBUG', true); $yourls_reserved_URL = array( - 'porn', 'sex', 'nigger', 'fuck', 'cunt', 'dick', + 'porn', 'sex', 'nigger', 'fuck', 'cunt', 'dick', ); $yourls_user_passwords = array( - 'yourls' => 'secret-ci-test', - 'clear' => 'somepassword', - 'md5' => 'md5:12373:e52e4488f79a740bd341f229e3c163c8', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with md5 and salt + 'yourls' => 'secret-ci-test', + 'clear' => 'somepassword', + 'md5' => 'md5:12373:e52e4488f79a740bd341f229e3c163c8', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with md5 and salt 'phpass' => 'phpass:!2a!08!T1ptMlBSxu7g3odpbUXgd.9wbKvg8k7cJt.HbwSqUNrlLPudWnf/6', // password: '3cd6944201fa7bbc5e0fe852e36b1096' with old PHPass library 'phpass2' => 'phpass:$2a$08$gt2bnpfUyuCX3hrp0RPOieFR1RwBnLsMzpq/NvPXwCdV3LqI3RGYi', // password: also '3cd6944201fa7bbc5e0fe852e36b1096' with old PHPass lib but without YOURLS internal char substitution 'phpass3' => 'phpass:!2y!10!.FjK.vQR0JVivkMwckiiIesFUFhtMxX/f9pes.i/ccp/W0IuUSxPW', // password: also '3cd6944201fa7bbc5e0fe852e36b1096' hashed with password_hash diff --git a/tests/data/plugins/test-plugin/uninstall.php b/tests/data/plugins/test-plugin/uninstall.php index 5cab13ebb..188f24dd6 100644 --- a/tests/data/plugins/test-plugin/uninstall.php +++ b/tests/data/plugins/test-plugin/uninstall.php @@ -5,7 +5,7 @@ */ // No direct call. -if( !defined( 'YOURLS_UNINSTALL_PLUGIN' ) ) die(); +if( !defined( 'YOURLS_UNINSTALL_PLUGIN' ) ) return; // The uninstallation process itself diff --git a/tests/data/plugins/test-plugin2/uninstall.php b/tests/data/plugins/test-plugin2/uninstall.php index 5cab13ebb..188f24dd6 100644 --- a/tests/data/plugins/test-plugin2/uninstall.php +++ b/tests/data/plugins/test-plugin2/uninstall.php @@ -5,7 +5,7 @@ */ // No direct call. -if( !defined( 'YOURLS_UNINSTALL_PLUGIN' ) ) die(); +if( !defined( 'YOURLS_UNINSTALL_PLUGIN' ) ) return; // The uninstallation process itself diff --git a/tests/includes/install.php b/tests/includes/install.php index 41bcba17c..9d9f1479c 100644 --- a/tests/includes/install.php +++ b/tests/includes/install.php @@ -8,18 +8,18 @@ function yut_install_yourls() { yut_drop_all_tables_if_local(); - if (!yourls_check_database_version()) { - die( sprintf( 'MySQL version too old. Version is: %s', yourls_get_database_version() ) ); - } + if (!yourls_check_database_version()) { + die( sprintf( 'MySQL version too old. Version is: %s', yourls_get_database_version() ) ); + } - if (!yourls_check_php_version()) { - die( sprintf( 'PHP version too old. Version is: %s', phpversion() ) ); - } + if (!yourls_check_php_version()) { + die( sprintf( 'PHP version too old. Version is: %s', phpversion() ) ); + } - $create = yourls_create_sql_tables(); - if (array() != $create['error']) { - die( sprintf( 'Could not run SQL. Error is: %s', implode( "\n\n", $create['error'] ) ) ); - } + $create = yourls_create_sql_tables(); + if (array() != $create['error']) { + die( sprintf( 'Could not run SQL. Error is: %s', implode( "\n\n", $create['error'] ) ) ); + } } @@ -44,7 +44,7 @@ function yut_find_config() { } } - die( sprintf( "ERROR: config file missing. Current directory: %s\n", dirname(__DIR__) ) ); + die( sprintf( "ERROR: YOURLS config file missing. Current directory: %s\n", dirname(__DIR__) ) ); } /** @@ -55,10 +55,10 @@ function yut_find_config() { * @return void */ function yut_drop_all_tables_if_local() { - if( !yut_is_local() ) - return; + if( !yut_is_local() ) + return; - // If not running in Travis environment, drop any tables from the selected database prior to starting tests + // If not running in Travis environment, drop any tables from the selected database prior to starting tests $tables = sprintf('%s,%s,%s', YOURLS_DB_TABLE_URL, YOURLS_DB_TABLE_OPTIONS, YOURLS_DB_TABLE_LOG); $sql = sprintf('DROP TABLE IF EXISTS %s', $tables); yourls_get_db()->perform($sql); diff --git a/tests/includes/utils.php b/tests/includes/utils.php index 2a4cbc4bc..28171f720 100644 --- a/tests/includes/utils.php +++ b/tests/includes/utils.php @@ -12,7 +12,7 @@ * @return string Random string */ function rand_str( $len=32 ) { - return substr( md5( uniqid( rand() ) ), 0, $len ); + return substr( md5( uniqid( rand() ) ), 0, $len ); } /** @@ -21,7 +21,7 @@ function rand_str( $len=32 ) { * @since 0.1 */ function yut_is_local() { - return ! defined( 'YOURLS_TESTS_CI' ) || YOURLS_TESTS_CI === false; + return ! defined( 'YOURLS_TESTS_CI' ) || YOURLS_TESTS_CI === false; } /** @@ -116,27 +116,27 @@ function yourls_ut_var_dump( ...$what ) { */ class Log_in_File { - public static $has_logged = false; + public static $has_logged = false; - public static function log( $what ) { - // Don't mess with Travis - if( !yut_is_local() ) - return; + public static function log( $what ) { + // Don't mess with Travis + if( !yut_is_local() ) + return; - if( ! self::$has_logged ) { - self::$has_logged = true; - self::start_log(); - } + if( ! self::$has_logged ) { + self::$has_logged = true; + self::start_log(); + } - ob_start(); - var_dump( $what ); - $what = ob_get_clean(); + ob_start(); + var_dump( $what ); + $what = ob_get_clean(); - error_log( $what."\n", 3, dirname( dirname( __FILE__ ) ) . '/log.txt' ); - } + error_log( $what."\n", 3, dirname( dirname( __FILE__ ) ) . '/log.txt' ); + } - public static function start_log() { - self::log( "---------------- START TESTS ----------------" ); - } + public static function start_log() { + self::log( "---------------- START TESTS ----------------" ); + } } diff --git a/tests/tests/OptionTest.php b/tests/tests/OptionTest.php new file mode 100644 index 000000000..7bc82644b --- /dev/null +++ b/tests/tests/OptionTest.php @@ -0,0 +1,135 @@ +assertFalse( yourls_get_option( 'doesnotexist' ) ); + $this->assertTrue( yourls_add_option( $key, $value ) ); + $this->assertEquals( $value, yourls_get_option( $key ) ); + $this->assertFalse( yourls_add_option( $key, $value ) ); // Already exists + $this->assertFalse( yourls_update_option( $key, $value ) ); // Value is the same + $this->assertTrue( yourls_update_option( $key, $value2 ) ); + $this->assertEquals( $value2, yourls_get_option( $key ) ); + + $this->assertFalse( yourls_add_option( $key, $value ) ); + $this->assertEquals( $value2, yourls_get_option( $key ) ); + $this->assertTrue( yourls_delete_option( $key ) ); + $this->assertFalse( yourls_get_option( $key ) ); + $this->assertFalse( yourls_delete_option( $key ) ); + + $this->assertTrue( yourls_update_option( $key2, $value2 ) ); + $this->assertEquals( $value2, yourls_get_option( $key2 ) ); + $this->assertTrue( yourls_delete_option( $key2 ) ); + $this->assertFalse( yourls_get_option( $key2 ) ); + } + + /** + * Check with array and objects + * + * @since 0.1 + */ + public function test_serialized_data() { + $key = rand_str(); + $value = array( 'foo' => true, 'bar' => true ); + + $this->assertTrue( yourls_add_option( $key, $value ) ); + $this->assertEquals( $value, yourls_get_option( $key ) ); + + $value = (object) $value; + $this->assertTrue( yourls_update_option( $key, $value ) ); + $this->assertEquals( $value, yourls_get_option( $key ) ); + $this->assertTrue( yourls_delete_option( $key ) ); + } + + /** + * Data provider of bad option names + */ + public static function bad_option_names(): \Iterator + { + yield array( '' ); + yield array( '0' ); + yield array( ' ' ); + yield array( 0 ); + yield array( false ); + yield array( null ); + } + + /** + * Check with bad option names + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('bad_option_names')] + public function test_bad_option_names($empty) { + $this->assertFalse( yourls_get_option( $empty ) ); + $this->assertFalse( yourls_add_option( $empty, '' ) ); + $this->assertFalse( yourls_update_option( $empty, '' ) ); + $this->assertFalse( yourls_delete_option( $empty ) ); + } + + function setUp(): void { + parent::setUp(); + $this->slash_1 = 'String with 1 slash \\'; + $this->slash_2 = 'String with 2 slashes \\\\'; + $this->slash_3 = 'String with 3 slashes \\\\\\'; + $this->slash_4 = 'String with 4 slashes \\\\\\\\'; + $this->slash_5 = 'String with 5 slashes \\\\\\\\\\'; + $this->slash_6 = 'String with 6 slashes \\\\\\\\\\\\'; + $this->slash_7 = 'String with 7 slashes \\\\\\\\\\\\\\'; + } + + /** + * Tests the model function that expects un-slashed data + * + * @since 0.1 + */ + function test_add_option() { + yourls_add_option( 'slash_test_1', $this->slash_1 ); + yourls_add_option( 'slash_test_2', $this->slash_2 ); + yourls_add_option( 'slash_test_3', $this->slash_3 ); + yourls_add_option( 'slash_test_4', $this->slash_4 ); + + $this->assertEquals( $this->slash_1, yourls_get_option( 'slash_test_1' ) ); + $this->assertEquals( $this->slash_2, yourls_get_option( 'slash_test_2' ) ); + $this->assertEquals( $this->slash_3, yourls_get_option( 'slash_test_3' ) ); + $this->assertEquals( $this->slash_4, yourls_get_option( 'slash_test_4' ) ); + } + + /** + * Tests the model function that expects un-slashed data + * + * @since 0.1 + */ + function test_update_option() { + yourls_add_option( 'slash_test_5', 'foo' ); + + yourls_update_option( 'slash_test_5', $this->slash_1 ); + $this->assertEquals( $this->slash_1, yourls_get_option( 'slash_test_5' ) ); + + yourls_update_option( 'slash_test_5', $this->slash_2 ); + $this->assertEquals( $this->slash_2, yourls_get_option( 'slash_test_5' ) ); + + yourls_update_option( 'slash_test_5', $this->slash_3 ); + $this->assertEquals( $this->slash_3, yourls_get_option( 'slash_test_5' ) ); + + yourls_update_option( 'slash_test_5', $this->slash_4 ); + $this->assertEquals( $this->slash_4, yourls_get_option( 'slash_test_5' ) ); + } +} diff --git a/tests/tests/api/FuncTest.php b/tests/tests/api/FuncTest.php new file mode 100644 index 000000000..bac61a401 --- /dev/null +++ b/tests/tests/api/FuncTest.php @@ -0,0 +1,36 @@ +assertTrue( is_callable( $function ) ); + $this->assertTrue( is_array( $function() ) ); + } + +} diff --git a/tests/tests/api/output.php b/tests/tests/api/OutputTest.php similarity index 76% rename from tests/tests/api/output.php rename to tests/tests/api/OutputTest.php index 8fce9e736..ad94bbc9b 100644 --- a/tests/tests/api/output.php +++ b/tests/tests/api/OutputTest.php @@ -3,10 +3,10 @@ /** * Main API Output tests (content and headers sent) * - * @group API * @since 0.1 */ -class API_Output_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('API')] +class OutputTest extends PHPUnit\Framework\TestCase { protected $header_content; @@ -43,22 +43,21 @@ public function get_status_header( $args ) { /** * Provide API output mode and the associated expected content-type header */ - public function API_type() { - return array( - array( 'xml', 'application/xml' ), - array( 'json', 'application/json' ), - array( 'jsonp', 'application/javascript' ), - array( 'simple', 'text/plain' ), - array( rand_str(), 'text/plain' ), - ); + public static function API_type(): \Iterator + { + yield array( 'xml', 'application/xml' ); + yield array( 'json', 'application/json' ); + yield array( 'jsonp', 'application/javascript' ); + yield array( 'simple', 'text/plain' ); + yield array( rand_str(), 'text/plain' ); } /** * Check that yourls_api_output selectively sends expected content-type headers * - * @dataProvider API_type * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('API_type')] public function test_output_content_headers( $type, $expected_header ) { yourls_add_action( 'content_type_header', array( $this, 'get_content_header' ) ); yourls_add_action( 'status_header', array( $this, 'get_status_header' ) ); @@ -72,27 +71,24 @@ public function test_output_content_headers( $type, $expected_header ) { /** * Provide mocked API output and the expected status codes */ - public function status_code() { + public static function status_code(): \Iterator { $success_code = mt_rand( 1, 10 ); $error_code = mt_rand( 1, 10 ); $content_success = array( 'statusCode' => $success_code ); $content_error = array( 'errorCode' => $error_code ); $content_random = array( 'thereIsNoCode' => rand_str() ); - - return array( - array( $content_success, $success_code ), - array( $content_error, $error_code ), - array( $content_random, 200 ), - ); + yield array( $content_success, $success_code ); + yield array( $content_error, $error_code ); + yield array( $content_random, 200 ); } /** * Check that yourls_api_output status header * - * @dataProvider status_code * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('status_code')] public function test_output_status_headers( $content, $expected_status ) { yourls_add_action( 'status_header', array( $this, 'get_status_header' ) ); diff --git a/tests/tests/api/funcs.php b/tests/tests/api/funcs.php deleted file mode 100644 index 980c99e67..000000000 --- a/tests/tests/api/funcs.php +++ /dev/null @@ -1,37 +0,0 @@ -assertTrue( is_callable( $function ) ); - $this->assertTrue( is_array( $function() ) ); - } - -} diff --git a/tests/tests/auth/AbstractLoginTestCase.php b/tests/tests/auth/AbstractLoginTestCase.php new file mode 100644 index 000000000..37155462e --- /dev/null +++ b/tests/tests/auth/AbstractLoginTestCase.php @@ -0,0 +1,21 @@ +backup_request = $_REQUEST; + $_REQUEST['nonce'] = yourls_create_nonce('admin_login'); + } + + protected function tearDown(): void { + $_REQUEST = $this->backup_request; + yourls_remove_all_actions('pre_yourls_die'); + } + +} diff --git a/tests/tests/auth/auth.php b/tests/tests/auth/AuthTest.php similarity index 94% rename from tests/tests/auth/auth.php rename to tests/tests/auth/AuthTest.php index 703acbb19..a59c19bbb 100644 --- a/tests/tests/auth/auth.php +++ b/tests/tests/auth/AuthTest.php @@ -2,10 +2,9 @@ /** * Auth functions other than login and logout - * - * @group auth */ -class Auth_Func_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('auth')] +class AuthTest extends PHPUnit\Framework\TestCase { protected static $random_password; @@ -80,24 +79,21 @@ public function test_has_phpass() { /** * Provide strings to hash */ - public function strings_to_hash() { - - return array( - array( rand_str() ), - array( 'lol .\+*?[^]$(){}=!<>|:-/' . "'" . '"' ), - array( 'أنا أحب النقانق' ), - array( '"double quotes"' ), - array( "'single quotes'" ), - array( '@$*' ), - array( 'أنا أحب النقانق' ), - ); + public static function strings_to_hash(): \Iterator + { + yield array( rand_str() ); + yield array( 'lol .\+*?[^]$(){}=!<>|:-/' . "'" . '"' ); + yield array( 'أنا أحب النقانق' ); + yield array( '"double quotes"' ); + yield array( "'single quotes'" ); + yield array( '@$*' ); + yield array( 'أنا أحب النقانق' ); } /** * Check that a hash can be verified - * - * @dataProvider strings_to_hash */ + #[\PHPUnit\Framework\Attributes\DataProvider('strings_to_hash')] public function test_hash_and_check( $string ) { $hash = yourls_phpass_hash( $string ); $this->assertTrue( yourls_phpass_check( $string, $hash ) ); @@ -173,7 +169,7 @@ public function test_hash_passwords_now() { } exec( YOURLS_PHP_BIN . ' -l ' . escapeshellarg( $config_file ), $output, $return ); - $this->assertEquals( 0, $return ); + $this->assertSame( 0, $return ); } /** @@ -254,7 +250,7 @@ public function test_hash_passwords_special_chars_now() { } exec( YOURLS_PHP_BIN . ' -l ' . escapeshellarg( $config_file ), $output, $return ); - $this->assertEquals( 0, $return ); + $this->assertSame( 0, $return ); } /** diff --git a/tests/tests/auth/login_secure.php b/tests/tests/auth/LoginAPISecureTest.php similarity index 78% rename from tests/tests/auth/login_secure.php rename to tests/tests/auth/LoginAPISecureTest.php index 4b21ebef4..b0d5b958b 100644 --- a/tests/tests/auth/login_secure.php +++ b/tests/tests/auth/LoginAPISecureTest.php @@ -1,15 +1,15 @@ backup_request = $_REQUEST; - $_REQUEST['nonce'] = yourls_create_nonce('admin_login'); - } - - protected function tearDown(): void { - $_REQUEST = $this->backup_request; - yourls_remove_all_actions('pre_yourls_die'); - } - - /** - * Check that user, as submitted by REQUEST (see phpunit XML config file), is valid - * - * @since 0.1 - */ - public function test_login() { +trait LoginAssertionTrait +{ + /** + * Check that user, as submitted by REQUEST (see phpunit XML config file), is valid + * + * @since 0.1 + */ + public function test_login() { $pre_login = yourls_did_action( 'pre_login' ); $login = yourls_did_action( 'login' ); $login_failed = yourls_did_action( 'login_failed' ); - $this->assertTrue( yourls_is_valid_user() ); + $this->assertTrue( yourls_is_valid_user() ); - $this->assertEquals( $pre_login + 1, yourls_did_action( 'pre_login' ) ); - $this->assertEquals( $login + 1, yourls_did_action( 'login' ) ); - $this->assertEquals( $login_failed, yourls_did_action( 'login_failed' ) ); - } + $this->assertEquals( $pre_login + 1, yourls_did_action( 'pre_login' ) ); + $this->assertEquals( $login + 1, yourls_did_action( 'login' ) ); + $this->assertEquals( $login_failed, yourls_did_action( 'login_failed' ) ); + } /** * Check that auth is shuntable @@ -58,8 +42,8 @@ public function test_login_with_no_credential() { $this->assertNotTrue( yourls_is_valid_user() ); - $this->assertEquals( $login, yourls_did_action( 'login' ) ); - $this->assertEquals( $login_failed + 1, yourls_did_action( 'login_failed' ) ); + $this->assertEquals( $login, yourls_did_action( 'login' ) ); + $this->assertEquals( $login_failed + 1, yourls_did_action( 'login_failed' ) ); } /** @@ -74,8 +58,8 @@ public function test_login_with_empty_credential() { $this->assertNotTrue( yourls_is_valid_user() ); - $this->assertEquals( $login, yourls_did_action( 'login' ) ); - $this->assertEquals( $login_failed + 1, yourls_did_action( 'login_failed' ) ); + $this->assertEquals( $login, yourls_did_action( 'login' ) ); + $this->assertEquals( $login_failed + 1, yourls_did_action( 'login_failed' ) ); } /** @@ -89,7 +73,7 @@ public function test_login_with_random_credentials() { $login_failed = yourls_did_action( 'login_failed' ); // with "normal" logins, we simulate the login forms and the presence of a nonce - if (get_class($this) == 'Auth_Login_Normal_Tests') { + if (get_class($this) == 'LoginNormalTest') { $this->expectException(Exception::class); $this->expectExceptionMessage('I have died'); // intercept yourls_die() before it actually dies @@ -98,5 +82,4 @@ public function test_login_with_random_credentials() { $this->assertNotTrue( yourls_is_valid_user() ); } - } diff --git a/tests/tests/auth/login_cookie.php b/tests/tests/auth/LoginCookieTest.php similarity index 70% rename from tests/tests/auth/login_cookie.php rename to tests/tests/auth/LoginCookieTest.php index 050671da1..5c76a90a7 100644 --- a/tests/tests/auth/login_cookie.php +++ b/tests/tests/auth/LoginCookieTest.php @@ -2,12 +2,12 @@ /** * Login tests - via Cookies * - * @group auth - * @group login - * @group cookies * @since 0.1 */ -class Auth_Login_Cookie_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('auth')] +#[\PHPUnit\Framework\Attributes\Group('login')] +#[\PHPUnit\Framework\Attributes\Group('cookies')] +class LoginCookieTest extends PHPUnit\Framework\TestCase { protected $cookie; protected $request; @@ -35,31 +35,31 @@ public static function tearDownAfterClass(): void { yourls_remove_filter( 'is_API', 'yourls_return_false' ); } - /** - * Check for valid cookie name - */ - public function test_cookie_name() { + /** + * Check for valid cookie name + */ + public function test_cookie_name() { $this->assertTrue( is_string(yourls_cookie_name()) ); } - /** - * Check for valid cookie value - */ - public function test_cookie_value() { + /** + * Check for valid cookie value + */ + public function test_cookie_value() { $this->assertTrue( is_string(yourls_cookie_value(rand_str())) ); } - /** - * Check for valid cookie life - */ - public function test_cookie_life() { + /** + * Check for valid cookie life + */ + public function test_cookie_life() { $this->assertTrue( is_int(yourls_get_cookie_life()) ); } - /** - * Test login with valid cookie - also check that cookie is set - */ - public function test_login_valid_cookie() { + /** + * Test login with valid cookie - also check that cookie is set + */ + public function test_login_valid_cookie() { global $yourls_user_passwords; $random_user = array_rand($yourls_user_passwords); $_COOKIE[yourls_cookie_name()] = yourls_cookie_value( $random_user ); @@ -71,10 +71,10 @@ public function test_login_valid_cookie() { $this->assertSame( 1, yourls_did_action('pre_setcookie') ); } - /** - * Test login with invalid cookie - also check that no cookie is set - */ - public function test_login_invalid_cookie() { + /** + * Test login with invalid cookie - also check that no cookie is set + */ + public function test_login_invalid_cookie() { $_COOKIE[yourls_cookie_name()] = yourls_cookie_value( rand_str() ); unset($_REQUEST); diff --git a/tests/tests/auth/LoginNormalTest.php b/tests/tests/auth/LoginNormalTest.php new file mode 100644 index 000000000..f3a579465 --- /dev/null +++ b/tests/tests/auth/LoginNormalTest.php @@ -0,0 +1,14 @@ +assertTrue($valid); - $this->assertSame(self::$user, 'yourls'); + $this->assertSame('yourls', self::$user); } /** * Check logout procedure - phase 2 - we're logging out and checking that cookie was reset - * @depends test_logout_user_is_logged_in */ + #[\PHPUnit\Framework\Attributes\Depends('test_logout_user_is_logged_in')] public function test_logout_user_logs_out() { $_GET['action'] = 'logout'; $_REQUEST['nonce'] = yourls_create_nonce('admin_logout', 'logout'); $invalid = yourls_is_valid_user(); $this->assertNotTrue( $invalid ); - $this->assertSame(self::$user, ''); + $this->assertSame('', self::$user); } /** * Check logout procedure - phase 3 - check we can log in again - * @depends test_logout_user_logs_out */ + #[\PHPUnit\Framework\Attributes\Depends('test_logout_user_logs_out')] public function test_logout_user_is_logged_in_back() { $_REQUEST['nonce'] = yourls_create_nonce('admin_login'); $valid = yourls_is_valid_user(); $this->assertTrue( $valid ); - $this->assertSame(self::$user, 'yourls'); + $this->assertSame('yourls', self::$user); } } diff --git a/tests/tests/auth/misc.php b/tests/tests/auth/MiscAuthTest.php similarity index 79% rename from tests/tests/auth/misc.php rename to tests/tests/auth/MiscAuthTest.php index 611568644..a6acc672c 100644 --- a/tests/tests/auth/misc.php +++ b/tests/tests/auth/MiscAuthTest.php @@ -2,10 +2,9 @@ /** * Misc test - * - * @group auth */ -class Misc_Auth_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('auth')] +class MiscAuthTest extends PHPUnit\Framework\TestCase { protected function tearDown(): void { yourls_remove_all_filters( 'hmac_algo' ); @@ -20,7 +19,7 @@ public function test_yourls_salt_return_string() { } public function test_yourls_hmac_algo_default() { - $this->assertTrue( in_array(yourls_hmac_algo(), hash_hmac_algos()) ); + $this->assertContains(yourls_hmac_algo(), hash_hmac_algos()); } public function test_yourls_hmac_algo_custom() { @@ -36,7 +35,7 @@ public function test_yourls_hmac_algo_custom() { } public function test_yourls_hmac_algo_non_existent() { - $this->assertSame( yourls_hmac_algo('omgozh'), 'sha256' ); + $this->assertSame( 'sha256', yourls_hmac_algo('omgozh') ); } } diff --git a/tests/tests/auth/nonces.php b/tests/tests/auth/NonceTest.php similarity index 73% rename from tests/tests/auth/nonces.php rename to tests/tests/auth/NonceTest.php index ba7ffed61..d293c3152 100644 --- a/tests/tests/auth/nonces.php +++ b/tests/tests/auth/NonceTest.php @@ -2,41 +2,41 @@ /** * Nonce tests * - * @group auth - * @group nonces * @since 0.1 */ -class Auth_Nonce_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('auth')] +#[\PHPUnit\Framework\Attributes\Group('nonces')] +class NonceTest extends PHPUnit\Framework\TestCase { protected function tearDown(): void { yourls_remove_all_actions('pre_yourls_die'); } - /** - * Check for valid nonce life - */ - public function test_nonce_life() { + /** + * Check for valid nonce life + */ + public function test_nonce_life() { $this->assertTrue( is_int(yourls_get_cookie_life()) ); } - /** - * Check for valid tick - */ - public function test_tick() { + /** + * Check for valid tick + */ + public function test_tick() { $this->assertTrue( is_float(yourls_tick()) ); } - /** - * Check nonce creation - */ - public function test_create_nonce() { + /** + * Check nonce creation + */ + public function test_create_nonce() { $this->assertTrue( is_string(yourls_create_nonce(rand_str(), rand_str())) ); } - /** - * Check nonce field creation and output - */ - public function test_create_nonce_field_echo() { + /** + * Check nonce field creation and output + */ + public function test_create_nonce_field_echo() { $action = rand_str(); $name = rand_str(); $user = rand_str(); @@ -46,18 +46,18 @@ public function test_create_nonce_field_echo() { $field = yourls_nonce_field( $action, $name, $user, true ); } - /** - * Check nonce URL creation - */ - public function test_create_nonce_url() { + /** + * Check nonce URL creation + */ + public function test_create_nonce_url() { $url = yourls_nonce_url( rand_str(), rand_str(), rand_str(), rand_str() ); $this->assertTrue( is_string($url) ); } - /** - * Test valid nonce - */ - public function test_valid_nonce() { + /** + * Test valid nonce + */ + public function test_valid_nonce() { $action = rand_str(); $user = rand_str(); @@ -67,10 +67,10 @@ public function test_valid_nonce() { $this->assertTrue(yourls_verify_nonce($action, $valid, $user)); } - /** - * Test invalid nonce - */ - public function test_invalid_nonce() { + /** + * Test invalid nonce + */ + public function test_invalid_nonce() { $this->expectException(Exception::class); $this->expectExceptionMessage('I have died'); diff --git a/tests/tests/auth/login_redirection.php b/tests/tests/auth/RedirectionTest.php similarity index 65% rename from tests/tests/auth/login_redirection.php rename to tests/tests/auth/RedirectionTest.php index a64aa7152..7979e2e0c 100644 --- a/tests/tests/auth/login_redirection.php +++ b/tests/tests/auth/RedirectionTest.php @@ -4,10 +4,9 @@ * Login redirection * * Check that, when submitting correct credentials, we're redirected as expected - * - * @group auth */ -class Login_Redirection_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('auth')] +class RedirectionTest extends PHPUnit\Framework\TestCase { protected $backup_request; protected $backup_server; @@ -22,13 +21,13 @@ protected function tearDown(): void { $_SERVER = $this->backup_server; } - /** - * Check that authentication on a webpage triggers a redirection - */ - public function test_login() { + /** + * Check that authentication on a webpage triggers a redirection + */ + public function test_login() { $_REQUEST['nonce'] = yourls_create_nonce('admin_login'); $_SERVER['REQUEST_URI'] = '/'; - $this->assertSame( 3, yourls_is_valid_user() ); - } + $this->assertSame( 3, yourls_is_valid_user() ); + } } diff --git a/tests/tests/auth/signatures.php b/tests/tests/auth/SigTest.php similarity index 87% rename from tests/tests/auth/signatures.php rename to tests/tests/auth/SigTest.php index c3165c1ba..f06400faf 100644 --- a/tests/tests/auth/signatures.php +++ b/tests/tests/auth/SigTest.php @@ -2,11 +2,11 @@ /** * Tests with signatures * - * @group auth - * @group signatures * @since 0.1 */ -class Auth_Sig_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('auth')] +#[\PHPUnit\Framework\Attributes\Group('signatures')] +class SigTest extends PHPUnit\Framework\TestCase { protected $backup_request; @@ -114,29 +114,26 @@ public function test_signature_timestamp_hash() { /** * Provide valid and invalid timestamps as compared to current time and nonce life */ - public function timestamps() { + public static function timestamps(): \Iterator { $now = time(); $little_in_the_future = $now + ( YOURLS_NONCE_LIFE / 2 ); $little_in_the_past = $now - ( YOURLS_NONCE_LIFE / 2 ); $far_in_the_future = $now + ( YOURLS_NONCE_LIFE * 2 ); $far_in_the_past = $now - ( YOURLS_NONCE_LIFE * 2 ); - - return array( - array( 0, false ), - array( $now, true ), - array( $little_in_the_future, true ), - array( $little_in_the_past, true ), - array( $far_in_the_future, false ), - array( $far_in_the_past, false ), - ); + yield array( 0, false ); + yield array( $now, true ); + yield array( $little_in_the_future, true ); + yield array( $little_in_the_past, true ); + yield array( $far_in_the_future, false ); + yield array( $far_in_the_past, false ); } /** * Check that timestamps are correctly handled (too old = bad, too future = bad, ...) * * @since 0.1 - * @dataProvider timestamps */ + #[\PHPUnit\Framework\Attributes\DataProvider('timestamps')] public function test_check_timestamp( $timestamp, $is_valid ) { $this->assertSame(yourls_check_timestamp( $timestamp ), $is_valid ); } diff --git a/tests/tests/auth/login_normal.php b/tests/tests/auth/login_normal.php deleted file mode 100644 index 4a2bc4f37..000000000 --- a/tests/tests/auth/login_normal.php +++ /dev/null @@ -1,14 +0,0 @@ -assertSame( $escaped, yourls_esc_attr( $attr ) ); + } + + /** + * Attribute escaping -- escaping twice shouldn't change + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('html_attributes')] + function test_esc_attr_twice( $attr, $escaped ) { + $this->assertSame( $escaped, yourls_esc_attr( yourls_esc_attr( $attr ) ) ); + } + + /** + * HTML string and how they should be escaped + */ + static function html_strings(): \Iterator + { + // Simple string + yield array( + 'The quick brown fox.', + 'The quick brown fox.', + ); + // URL with & + yield array( + 'https://127.0.0.1/admin/admin-ajax.php?id=y1120844669&action=edit&keyword=1a&nonce=bf3115ac3a', + 'https://127.0.0.1/admin/admin-ajax.php?id=y1120844669&action=edit&keyword=1a&nonce=bf3115ac3a', + ); + // More ampersands + yield array( + 'H&M and Dungeons & Dragons', + 'H&M and Dungeons & Dragons', + ); + // Simple quotes + yield array( + "SELECT stuff FROM table WHERE blah IN ('omg', 'wtf') AND foo = 1", + 'SELECT stuff FROM table WHERE blah IN ('omg', 'wtf') AND foo = 1', + ); + // Double quotes + yield array( + 'I am "special"', + 'I am "special"', + ); + // Greater and less than + yield array( + 'this > that < that ', + 'this > that < that <randomhtml />', + ); + // Ignore actual entities + yield array( + '& £ " &', + '& £ " &', + ); + // Empty string + yield array( + '', + '', + ); + } + + /** + * HTML escaping + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('html_strings')] + function test_esc_html( $html, $escaped ) { + $this->assertSame( $escaped, yourls_esc_html( $html ) ); + } + + /** + * String to escape and what they should look like once escaped + */ + public function strings_to_escape() { + return array( + array( "I'm rock n' rollin'", "I\'m rock n\' rollin\'" ), + array( 'I am "nice"', 'I am \"nice\"' ), + array( 'Back\Slash', 'Back\\\Slash' ), + array( "NULL\0NULL", 'NULL\0NULL' ), // notice the quote change + ); + } + + /** + * List of URLs and how they should be escaped + */ + static function list_of_URLs(): \Iterator + { + yield array( + 'http://example.com/?this=that&that=this', + 'http://example.com/?this=that&that=this', + ); + yield array( + 'http://example.com/?this=that&that="this"', + 'http://example.com/?this=that&that=this', + ); + yield array( + "http://example.com/?this=that&that='this'", + 'http://example.com/?this=that&that='this'', + ); + yield array( + "http://example.com/?this=that&that=", + 'http://example.com/?this=that&that=this', + ); + } + + /** + * Escape URLs for display + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_URLs')] + #[\PHPUnit\Framework\Attributes\Group('url')] + function test_esc_urls( $url, $escaped ) { + $this->assertEquals( $escaped, yourls_esc_url( $url ) ); + } + + /** + * Some strings and how they should be escaped in javascript + */ + static function list_of_JS(): \Iterator + { + yield array( + 'hello world();', + 'hello world();', + ); + yield array( + 'hello("world");', + 'hello("world");', + ); + yield array( + 'foo & bar &baz; '', + 'foo & bar &baz; '', + ); + } + + /** + * Escape JS + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_JS')] + function test_esc_js( $js, $escaped ) { + $this->assertEquals( $escaped, yourls_esc_js( $js ) ); + } + + /** + * Strings in a textarea and how they should be escaped + */ + static function list_of_textarea(): \Iterator + { + yield array( + 'hello
    world', + 'hello<br/>world', + ); + yield array( + '"omg"', + '"omg"', + ); + yield array( + "'omg'", + ''omg'', + ); + } + + /** + * Escape JS + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_textarea')] + function test_esc_textarea( $text, $escaped ) { + $this->assertEquals( $escaped, yourls_esc_textarea( $text ) ); + } + +} diff --git a/tests/tests/format/general.php b/tests/tests/format/FormatTest.php similarity index 81% rename from tests/tests/format/general.php rename to tests/tests/format/FormatTest.php index 74e0ee357..67841bdb8 100644 --- a/tests/tests/format/general.php +++ b/tests/tests/format/FormatTest.php @@ -3,48 +3,46 @@ /** * General formatting functions. * - * @group formatting * @since 0.1 */ -class Format_General extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('formatting')] +class FormatTest extends PHPUnit\Framework\TestCase { /** * Data to serialize */ - function serialize_data() { - return array( - array( null ), - array( true ), - array( false ), - array( -25 ), - array( 25 ), - array( 1.1 ), - array( 'this string will be serialized' ), - array( "a\nb" ), - array( array() ), - array( array(1,1,2,3,5,8,13) ), - array( (object)array('test' => true, '3', 4) ), - ); + static function serialize_data(): \Iterator + { + yield array( null ); + yield array( true ); + yield array( false ); + yield array( -25 ); + yield array( 25 ); + yield array( 1.1 ); + yield array( 'this string will be serialized' ); + yield array( "a\nb" ); + yield array( array() ); + yield array( array(1,1,2,3,5,8,13) ); + yield array( (object)array('test' => true, '3', 4) ); } /** * Unserialized data */ - function not_serialized_data() { - return array( - array( 'a string' ), - array( 'garbage:a:0:garbage;' ), - // array( 'b:4;' ), // this test fails in WP test suite, not sure if intentional or what... - array( 's:4:test;' ), - ); + static function not_serialized_data(): \Iterator + { + yield array( 'a string' ); + yield array( 'garbage:a:0:garbage;' ); + // array( 'b:4;' ), // this test fails in WP test suite, not sure if intentional or what... + yield array( 's:4:test;' ); } /** * Check that yourls_is_serialized detects serialized data * - * @dataProvider serialize_data * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('serialize_data')] public function test_is_serialized( $data ) { $this->assertTrue( yourls_is_serialized( serialize( $data ) ) ); } @@ -52,9 +50,9 @@ public function test_is_serialized( $data ) { /** * Check that yourls_is_serialized doesn't assume garbage is serialized * - * @dataProvider not_serialized_data * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('not_serialized_data')] public function test_is_not_serialized( $data ) { $this->assertFalse( yourls_is_serialized( $data ) ); } @@ -131,7 +129,7 @@ function test_valid_regexp() { TODO: more random char strings to test? */ - $this->assertFalse( preg_match( '![^' . $pattern . ']!', '' ) === false ); + $this->assertNotFalse( preg_match( '![^' . $pattern . ']!', '' ) ); } /** @@ -158,9 +156,9 @@ function test_trim_long_strings() { * * Note: As of 1.7.1, function yourls_seem_utf8() is still unused. In 2.0 consider simply deleting it if still not needed * - * @dataProvider valid_utf8 * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('valid_utf8')] function test_is_utf8( $string ) { $this->assertTrue( yourls_seems_utf8( $string ) ); } @@ -170,25 +168,25 @@ function test_is_utf8( $string ) { * * Note: As of 1.7.1, function yourls_seem_utf8() is still unused. In 2.0 consider simply deleting it if still not needed * - * @dataProvider invalid_utf8 * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('invalid_utf8')] function test_is_not_utf8( $string ) { $this->assertFalse( yourls_seems_utf8( $string ) ); } - function valid_utf8() { - return $this->get_data( YOURLS_TESTDATA_DIR . '/formatting/utf-8.txt' ); + static function valid_utf8() { + return self::get_data( YOURLS_TESTDATA_DIR . '/formatting/utf-8.txt' ); } - function invalid_utf8() { - return $this->get_data( YOURLS_TESTDATA_DIR . '/formatting/big5.txt' ); + static function invalid_utf8() { + return self::get_data( YOURLS_TESTDATA_DIR . '/formatting/big5.txt' ); } /** * Parse a file and return its content as a data provider */ - function get_data( $filename ) { + static function get_data( $filename ) { $strings = file( $filename ); foreach ( $strings as &$string ) { $string = (array) trim( $string ); @@ -203,8 +201,8 @@ function get_data( $filename ) { * @since 0.1 */ function test_backslashit() { - $this->assertSame( yourls_backslashit( 'hello world 123 !' ), '\h\e\l\l\o \w\o\r\l\d 123 !' ); - $this->assertSame( yourls_backslashit( '1, 2, 3' ), '\\\1, 2, 3' ); + $this->assertSame( '\h\e\l\l\o \w\o\r\l\d 123 !', yourls_backslashit( 'hello world 123 !' ) ); + $this->assertSame( '\\\1, 2, 3', yourls_backslashit( '1, 2, 3' ) ); } /** diff --git a/tests/tests/format/kses.php b/tests/tests/format/KSESTest.php similarity index 92% rename from tests/tests/format/kses.php rename to tests/tests/format/KSESTest.php index d412df579..11ae86082 100644 --- a/tests/tests/format/kses.php +++ b/tests/tests/format/KSESTest.php @@ -3,10 +3,10 @@ /** * KSES functions. Most are not used in YOURLS, so there's few tests here. * - * @group formatting * @since 0.1 */ -class Format_KSES extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('formatting')] +class KSESTest extends PHPUnit\Framework\TestCase { protected $entitynames, $protocols; diff --git a/tests/tests/format/referrers.php b/tests/tests/format/ReferrerTest.php similarity index 76% rename from tests/tests/format/referrers.php rename to tests/tests/format/ReferrerTest.php index f3bacffbb..c4d99ac05 100644 --- a/tests/tests/format/referrers.php +++ b/tests/tests/format/ReferrerTest.php @@ -3,11 +3,11 @@ /** * Formatting functions for URLs * - * @group formatting - * @group referrer * @since 0.1 */ -class Format_Referrer extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('formatting')] +#[\PHPUnit\Framework\Attributes\Group('referrer')] +class ReferrerTest extends PHPUnit\Framework\TestCase { protected $backup; @@ -21,7 +21,7 @@ protected function tearDown(): void { function test_no_referrer() { unset($_SERVER['HTTP_REFERER']); - $this->assertEquals(yourls_get_referrer(), 'direct'); + $this->assertEquals('direct', yourls_get_referrer()); } function test_referrer() { diff --git a/tests/tests/format/sanitizing.php b/tests/tests/format/SanitizeTest.php similarity index 55% rename from tests/tests/format/sanitizing.php rename to tests/tests/format/SanitizeTest.php index 31b9445aa..d36e97fd0 100644 --- a/tests/tests/format/sanitizing.php +++ b/tests/tests/format/SanitizeTest.php @@ -3,10 +3,10 @@ /** * Sanitizing functions * - * @group formatting * @since 0.1 */ -class Format_Sanitize extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('formatting')] +class SanitizeTest extends PHPUnit\Framework\TestCase { /** * Sanitize titles @@ -53,24 +53,23 @@ function test_sanitize_int() { /** * Some strings that look like IPs and a boolean showing if they should pass or not */ - function random_ips() { - return array( - array( '255.255.255.255', true ), - array( '127.1', true ), - array( '559.559.559', true ), - array( '::1', true ), - array( '127.0.0.omg', false ), - array( '1:1:omg', false ), - array( '#@~&', false ), - ); + static function random_ips(): \Iterator + { + yield array( '255.255.255.255', true ); + yield array( '127.1', true ); + yield array( '559.559.559', true ); + yield array( '::1', true ); + yield array( '127.0.0.omg', false ); + yield array( '1:1:omg', false ); + yield array( '#@~&', false ); } /** * Sanitize IPs * - * @dataProvider random_ips * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('random_ips')] function test_sanitize_ip( $ip, $is_ip ) { $this->assertSame( $ip == yourls_sanitize_ip( $ip ), $is_ip ); } @@ -78,22 +77,21 @@ function test_sanitize_ip( $ip, $is_ip ) { /** * Some strings that look like m(m)/d(d)/yyyy dates and a boolean showing if they should pass or not */ - function random_dates() { - return array( - array( '1/1/2345' , true ), - array( '12/2/2345', true ), - array( '9/10/2345', true ), - array( '90/99', false ), - array( '90/99/123', false ), - ); + static function random_dates(): \Iterator + { + yield array( '1/1/2345' , true ); + yield array( '12/2/2345', true ); + yield array( '9/10/2345', true ); + yield array( '90/99', false ); + yield array( '90/99/123', false ); } /** * Sanitize dates * - * @dataProvider random_dates * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('random_dates')] function test_sanitize_date( $date, $is_date ) { if( !$is_date ) { $this->assertFalse( yourls_sanitize_date( $date ) ); @@ -105,9 +103,9 @@ function test_sanitize_date( $date, $is_date ) { /** * Sanitize dates for SQL search * - * @dataProvider random_dates * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('random_dates')] function test_sanitize_date_sql( $date, $is_date ) { if( !$is_date ) { $this->assertFalse( yourls_sanitize_date_for_sql( $date ) ); @@ -119,21 +117,20 @@ function test_sanitize_date_sql( $date, $is_date ) { /** * Some strings that look like filenames how they should be sanitized */ - function random_filenames() { - return array( - array( '/home/ozh/plugin.php' , '/home/ozh/plugin.php' ), - array( '\home\ozh\plugin.php' , '/home/ozh/plugin.php' ), - array( '\\home\\ozh\\plugin.php' , '/home/ozh/plugin.php' ), - array( '//home/ozh/plugin.php' , '/home/ozh/plugin.php' ), - ); + static function random_filenames(): \Iterator + { + yield array( '/home/ozh/plugin.php' , '/home/ozh/plugin.php' ); + yield array( '\home\ozh\plugin.php' , '/home/ozh/plugin.php' ); + yield array( '\\home\\ozh\\plugin.php' , '/home/ozh/plugin.php' ); + yield array( '//home/ozh/plugin.php' , '/home/ozh/plugin.php' ); } /** * Sanitize filenames * - * @dataProvider random_filenames * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('random_filenames')] function test_sanitize_filename( $filename, $expected ) { $this->assertSame( $expected, yourls_sanitize_filename( $filename ) ); } @@ -141,36 +138,35 @@ function test_sanitize_filename( $filename, $expected ) { /** * Some strings that look like versions (1.2.3-alpha) how they should be sanitized */ - function random_versions() { - return array( - array('1.2.3', '1.2.3'), - array('1.2.3.4', '1.2.3.4'), - array('1.2.3-leet', '1.2.3'), - array('1.0-RC1-Almost-Final', '1.0'), - array('beta-4', ''), - array('4.something', ''), - array('4-final', ''), - array('1-2-3', ''), - array('omgmysql-5.5-ubuntu-4.20', '5.5'), - array('mysql5.5-ubuntu-4.20', '5.5'), - array('5.5-ubuntu-4.20', '5.5'), - array('5.5-beta2', '5.5'), - array('5.5.beta2', '5.5'), - array('5.5', '5.5'), - array('5.5.', '5.5'), - array('5', ''), - array('5.', ''), - array('100.1', '100.1'), - array('mysql-10.10-beta', '10.10'), - ); + static function random_versions(): \Iterator + { + yield array('1.2.3', '1.2.3'); + yield array('1.2.3.4', '1.2.3.4'); + yield array('1.2.3-leet', '1.2.3'); + yield array('1.0-RC1-Almost-Final', '1.0'); + yield array('beta-4', ''); + yield array('4.something', ''); + yield array('4-final', ''); + yield array('1-2-3', ''); + yield array('omgmysql-5.5-ubuntu-4.20', '5.5'); + yield array('mysql5.5-ubuntu-4.20', '5.5'); + yield array('5.5-ubuntu-4.20', '5.5'); + yield array('5.5-beta2', '5.5'); + yield array('5.5.beta2', '5.5'); + yield array('5.5', '5.5'); + yield array('5.5.', '5.5'); + yield array('5', ''); + yield array('5.', ''); + yield array('100.1', '100.1'); + yield array('mysql-10.10-beta', '10.10'); } /** * Sanitize versions * - * @dataProvider random_versions * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('random_versions')] function test_sanitize_version( $version, $expected ) { $this->assertSame( $expected, yourls_sanitize_version( $version ) ); } @@ -178,21 +174,20 @@ function test_sanitize_version( $version, $expected ) { /** * Some random keywords to sanitize */ - public function keywords_to_sanitize() { - return array( - array( 'hello-world', 'helloworld' ), - array( '1337ozhOZH', '1337ozhOZH' ), - array( 'yeah@#!?*', 'yeah' ), - array( 'Motörhead', 'Motrhead' ), - ); + public static function keywords_to_sanitize(): \Iterator + { + yield array( 'hello-world', 'helloworld' ); + yield array( '1337ozhOZH', '1337ozhOZH' ); + yield array( 'yeah@#!?*', 'yeah' ); + yield array( 'Motörhead', 'Motrhead' ); } - /** - * Checking that keyword are correctly sanitized - * - * @dataProvider keywords_to_sanitize - * @since 0.1 - */ + /** + * Checking that keyword are correctly sanitized + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('keywords_to_sanitize')] public function test_sanitize_keywords( $keyword, $expected ) { // the "soft" way: assume keyword can be anything we have in a URL (here, should remain unchanged) $this->assertSame( $keyword, yourls_sanitize_keyword( $keyword ) ); diff --git a/tests/tests/format/URLTest.php b/tests/tests/format/URLTest.php new file mode 100644 index 000000000..ddc004fc3 --- /dev/null +++ b/tests/tests/format/URLTest.php @@ -0,0 +1,305 @@ +assertSame( yourls_get_protocol( $test_this ), $expected ); + } + + + /** + * List of valid URLs that should not be changed when sanitized + */ + static function list_of_valid_URLs(): \Iterator + { + yield array( 'http://example.com' ); + yield array( 'http://example.com/' ); + yield array( 'http://ozh@example.com/' ); + yield array( 'http://example.com/?@OMG' ); + // #1890 + yield array( 'http://ozh@example.com#BLAH' ); + yield array( 'http://Ozh:Password@example.com/' ); + yield array( 'http://Ozh:Password@example.com#OMG' ); + yield array( 'http://Ozh:Password@example.com:1337/' ); + yield array( 'http://Ozh:Password@example.com:1337#OMG' ); + yield array( 'http://Ozh:Password@example.com/hey@ho' ); + yield array( 'http://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose:@:@' ); + yield array( 'mailto:ozh@ozh.org' ); + yield array( 'http://example.com/?watchtheallowedcharacters-~+_.#=&;,/:%!*stay' ); + yield array( 'http://example.com/search.php?search=(amistillhere)' ); + yield array( 'http://example.com/?test=%2812345%29abcdef[gh]' ); + yield array( 'http://example.com/?test=(12345)abcdef[gh]' ); + yield array( 'http://[0:0:0:0:0:0:0:1]/' ); + yield array( 'http://[2001:db8:1f70::999:de8:7648:6e8]:100/' ); + yield array( 'http://example.com/?req=http;//blah' ); + // + yield array( 'relative' ); + yield array( 'Relative/path/' ); + yield array( 'relative/Path/#yes' ); + yield array( '/absolute' ); + yield array( '/Absolute/Path/' ); + yield array( '/absolute/path/?omg#also' ); + yield array( 'http://académie-française.fr' ); + yield array( 'http://www.طارق.net/طارق?hello=%2B' ); + yield array( 'http://%d8%b7%d8%a7%d8%b1%d9%82.net/' ); + } + + /** + * Test that valid URLs are not modified + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_valid_URLs')] + function test_valid_urls( $url ) { + $this->assertEquals( $url, yourls_sanitize_url( $url ) ); + } + + /** + * URL with spaces + * + * @since 0.1 + */ + function test_url_with_spaces() { + $this->assertEquals( 'http://example.com/HelloWorld', yourls_sanitize_url( 'http://example.com/Hello World' ) ); + $this->assertEquals( 'http://example.com/Hello%20World', yourls_sanitize_url( 'http://example.com/Hello%20World' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url( 'http://example.com/ ' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url( ' http://example.com/' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url( ' http://example.com/ ' ) ); + } + + /** + * URL with bad chars + * + * @since 0.1 + */ + function test_url_with_bad_characters() { + // regular sanitize leaves %0A & %0D alone + $this->assertEquals( 'http://example.com/keep%0Dlinefeed%0A', yourls_sanitize_url( 'http://example.com/keep%0Dlinefeed%0A' ) ); + $this->assertEquals( 'http://example.com/%0%0%0DAD', yourls_sanitize_url( 'http://example.com/%0%0%0DAD' ) ); + + // sanitize with anti CRLF + $this->assertEquals( 'http://example.com/watchthelinefeedgo', yourls_sanitize_url_safe( 'http://example.com/watchthelinefeed%0Ago' ) ); + $this->assertEquals( 'http://example.com/watchthelinefeedgo', yourls_sanitize_url_safe( 'http://example.com/watchthelinefeed%0ago' ) ); + $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0Dgo' ) ); + $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0dgo' ) ); + + //Nesting Checks + $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0%0ddgo' ) ); + $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0%0DDgo' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0DAD' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0ADA' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0DAd' ) ); + $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0ADa' ) ); + } + + /** + * Test valid, missing and fake protocols + * + * @since 0.1 + */ + function test_url_with_protocols() { + $this->assertEquals( 'http://example.com', yourls_sanitize_url( 'http://example.com' ) ); + $this->assertEquals( 'example.php', yourls_sanitize_url( 'example.php' ) ); + $this->assertEquals( '', yourls_sanitize_url( 'htttp://example.com' ) ); + $this->assertEquals( 'mailto:ozh@ozh.org', yourls_sanitize_url( 'mailto:ozh@ozh.org' ) ); + // play with allowed protocols + $this->assertEquals( '', yourls_sanitize_url( 'nasty://example.com/' ) ); + $this->assertEquals( 'nasty://example.com/', yourls_sanitize_url( 'nasty://example.com/', array('nasty://') ) ); + global $yourls_allowedprotocols; + $yourls_allowedprotocols[] = 'evil://'; + $this->assertEquals( 'evil://example.com', yourls_sanitize_url( 'evil://example.com' ) ); + $yourls_allowedprotocols = yourls_kses_allowed_protocols(); + } + + /** + * List of URLs with MiXeD CaSe to test. Structure: array( sanitized url, unsanitized url with mixed case ) + */ + static function list_of_mixed_case(): \Iterator + { + yield array( 'http://example.com' , 'http://example.com' ); + # normal, no trailing slash + yield array( 'http://example.com/' , 'http://example.com/' ); + # normal, trailing slash + yield array( 'http://example.com' , 'HTTP://example.com' ); + yield array( 'http://example.com' , 'Http://example.com' ); + yield array( 'http://example.com' , 'Http://ExAmPlE.com' ); + yield array( 'http://example.com/BLAH' , 'Http://ExAmPlE.com/BLAH' ); + yield array( 'http://http/HTTP?HTTP#HTTP' , 'HTTP://HTTP/HTTP?HTTP#HTTP' ); + yield array( 'http://example.com/?@BLaH' , 'Http://ExAmPlE.com/?@BLaH' ); + #1890 + yield array( 'http://example.com#BLAH' , 'Http://ExAmPlE.com#BLAH' ); + yield array( 'http://example.com#BLAH' , 'Http://@ExAmPlE.com#BLAH' ); + yield array( 'http://example.com#BLAH' , 'Http://:@ExAmPlE.com#BLAH' ); + yield array( 'http://example.com?BLAH' , 'Http://ExAmPlE.com?BLAH' ); + yield array( 'http://Ozh:Password@example.com:1337#OMG' , 'http://Ozh:Password@Example.COM:1337#OMG' ); + yield array( 'http://User:PWd@example.com?User:PWd@Example.com' , 'http://User:PWd@Example.com?User:PWd@Example.com' ); + yield array( 'mailto:Ozh@Ozh.org?omg' , 'MAILTO:Ozh@Ozh.org?omg' ); + yield array( 'http://www.طارق.net/' , 'http://www.طارق.Net/' ); + yield array( 'http://académie-française.fr' , 'http://Académie-française.FR' ); + } + + /** + * Protocol and domain with mixed case + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_mixed_case')] + function test_url_with_protocol_case( $sanitized, $unsanitized ) { + $this->assertEquals( $sanitized, yourls_sanitize_url( $unsanitized ) ); + } + + /** + * List of URLs with IDN domain, and how YOURLS should sanitize them + */ + static function list_of_IDN(): \Iterator + { + yield array( 'http://www.طارق.Net/Omgطارق' , 'http://www.طارق.net/Omgطارق' ); + yield array( 'http://xn--mgbuq0c.Net/Omgطارق' , 'http://طارق.net/Omgطارق' ); + yield array( 'http://%d8%b7%d8%a7%d8%b1%d9%82.Net/Omgطارق' , 'http://%d8%b7%d8%a7%d8%b1%d9%82.net/Omgطارق' ); + // طارق.net, urlencoded + yield array( 'http://xn--p1ai.РФ' , 'http://рф.рф' ); + // lowercasing where applicable: РФ -> рф + yield array( 'http://РФ.xn--p1ai/' , 'http://рф.рф/' ); + yield array( 'http://xn--p1ai.xn--p1ai' , 'http://рф.рф' ); + } + + /** + * Protocol and domain with mixed case + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_IDN')] + function test_url_with_IDN( $unsanitized, $sanitized ) { + $this->assertEquals( $sanitized, yourls_sanitize_url( $unsanitized ) ); + } + + /** + * List of URLS and expected matches whether we're on SSL or not. + * Structure: array(original URL, expected URL if we're on HTTP, expected URL if we're on HTTPS) + */ + static function list_of_urls_with_and_without_https(): \Iterator + { + yield array( 'http://omg', 'http://omg', 'https://omg' ); + yield array( 'https://omg', 'https://omg', 'https://omg' ); + yield array( 'http://omg?http', 'http://omg?http', 'https://omg?http' ); + yield array( 'https://omg?http', 'https://omg?http', 'https://omg?http' ); + yield array( 'omg?http://bleh', 'omg?http://bleh', 'omg?http://bleh' ); + yield array( 'omg?https://bleh', 'omg?https://bleh', 'omg?https://bleh' ); + yield array( 'http', 'http', 'http' ); + yield array( 'https', 'https', 'https' ); + yield array( 'http://https', 'http://https', 'https://https' ); + yield array( 'https://https', 'https://https', 'https://https' ); + } + /** + * Test matching protocol with no SSL + * + * Feed URL and return a result that matches "http" + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_urls_with_and_without_https')] + function test_matching_protocols_with_no_ssl( $url, $without_ssl, $with_ssl ) { + yourls_add_filter('is_ssl', 'yourls_return_false'); + $this->assertEquals( $without_ssl, yourls_match_current_protocol($url) ); + } + + /** + * Test matching protocol with SSL + * + * Feed URL and return a result that matches "https" + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_urls_with_and_without_https')] + function test_matching_protocols_with_ssl( $url, $without_ssl, $with_ssl ) { + yourls_add_filter('is_ssl', 'yourls_return_true'); + $this->assertEquals( $with_ssl, yourls_match_current_protocol($url) ); + } + + /** + * List of various valid URL with mixed scenarios of IDN + * Structure: array(URL, expected URL after yourls_sanitize_url (and especially yourls_normalize_uri(), which deals with IDN) + */ + static function list_of_idn_punycode_utf8_rtl(): \Iterator + { + yield [ 'http://ua-test.link' , 'http://ua-test.link' ]; + // Ascii.new + yield [ 'http://ua-test.technology' , 'http://ua-test.technology' ]; + // Ascii.long + yield [ 'http://普试.top/' , 'http://普试.top/' ]; + // Idn.ascii + yield [ 'http://ua-test.世界' , 'http://ua-test.世界' ]; + // Ascii.idn + yield [ 'http://普试.世界/' , 'http://普试.世界/' ]; + // Idn.idn + yield [ 'http://ua-test.xn--rhqv96g' , 'http://ua-test.世界' ]; + // Ascii.punycode + yield [ 'http://xn--tkvo64f.top' , 'http://普试.top' ]; + // Punycode.ascii + yield [ 'http://xn--tkvo64f.xn--rhqv96g' , 'http://普试.世界' ]; + // Punycode.punycode + yield [ 'http://اختبار-القبولالعالمي.top' , 'http://اختبار-القبولالعالمي.top' ]; + // RTL.ascii + yield [ 'http://اختبار-القبولالعالمي.شبكة' , 'http://اختبار-القبولالعالمي.شبكة' ]; + // RTL.RTL + yield [ 'http://ua-test.link/我的' , 'http://ua-test.link/我的' ]; + // Ascii.new/Unicode + yield [ 'http://ua-test.technology/我的' , 'http://ua-test.technology/我的' ]; + // Ascii.long/Unicode + yield [ 'http://普试.top/我的' , 'http://普试.top/我的' ]; + // Idn.ascii/Unicode + yield [ 'http://ua-test.世界/我的' , 'http://ua-test.世界/我的' ]; + // Ascii.idn/Unicode + yield [ 'http://普试.世界/我的' , 'http://普试.世界/我的' ]; + // Idn.idn/Unicode + yield [ 'http://ختبار-القبولالعالمي.top/我的' , 'http://ختبار-القبولالعالمي.top/我的' ]; + // RTL.ascii/Unicode + yield [ 'http://اختبار-القبولالعالمي.شبكة/我的' , 'http://اختبار-القبولالعالمي.شبكة/我的' ]; + } + + /** + * Test various cases : domain name / TLD / path with ascii, punycode, utf8 and RTL + */ + #[\PHPUnit\Framework\Attributes\DataProvider('list_of_idn_punycode_utf8_rtl')] + function test_various_idn_cases($url, $expected) { + $this->assertEquals( yourls_sanitize_url($url), $expected ); + } + +} diff --git a/tests/tests/format/escaping.php b/tests/tests/format/escaping.php deleted file mode 100644 index 5bb03c83a..000000000 --- a/tests/tests/format/escaping.php +++ /dev/null @@ -1,222 +0,0 @@ -assertSame( $escaped, yourls_esc_attr( $attr ) ); - } - - /** - * Attribute escaping -- escaping twice shouldn't change - * - * @dataProvider html_attributes - * @since 0.1 - */ - function test_esc_attr_twice( $attr, $escaped ) { - $this->assertSame( $escaped, yourls_esc_attr( yourls_esc_attr( $attr ) ) ); - } - - /** - * HTML string and how they should be escaped - */ - function html_strings() { - return array( - // Simple string - array( - 'The quick brown fox.', - 'The quick brown fox.', - ), - // URL with & - array( - 'https://127.0.0.1/admin/admin-ajax.php?id=y1120844669&action=edit&keyword=1a&nonce=bf3115ac3a', - 'https://127.0.0.1/admin/admin-ajax.php?id=y1120844669&action=edit&keyword=1a&nonce=bf3115ac3a', - ), - // More ampersands - array( - 'H&M and Dungeons & Dragons', - 'H&M and Dungeons & Dragons', - ), - // Simple quotes - array( - "SELECT stuff FROM table WHERE blah IN ('omg', 'wtf') AND foo = 1", - 'SELECT stuff FROM table WHERE blah IN ('omg', 'wtf') AND foo = 1', - ), - // Double quotes - array( - 'I am "special"', - 'I am "special"', - ), - // Greater and less than - array( - 'this > that < that ', - 'this > that < that <randomhtml />', - ), - // Ignore actual entities - array( - '& £ " &', - '& £ " &', - ), - // Empty string - array( - '', - '', - ), - ); - } - - /** - * HTML escaping - * - * @dataProvider html_strings - * @since 0.1 - */ - function test_esc_html( $html, $escaped ) { - $this->assertSame( $escaped, yourls_esc_html( $html ) ); - } - - /** - * String to escape and what they should look like once escaped - */ - public function strings_to_escape() { - return array( - array( "I'm rock n' rollin'", "I\'m rock n\' rollin\'" ), - array( 'I am "nice"', 'I am \"nice\"' ), - array( 'Back\Slash', 'Back\\\Slash' ), - array( "NULL\0NULL", 'NULL\0NULL' ), // notice the quote change - ); - } - - /** - * List of URLs and how they should be escaped - */ - function list_of_URLs() { - return array( - array( - 'http://example.com/?this=that&that=this', - 'http://example.com/?this=that&that=this', - ), - array( - 'http://example.com/?this=that&that="this"', - 'http://example.com/?this=that&that=this', - ), - array( - "http://example.com/?this=that&that='this'", - 'http://example.com/?this=that&that='this'', - ), - array( - "http://example.com/?this=that&that=", - 'http://example.com/?this=that&that=this', - ), - ); - } - - /** - * Escape URLs for display - * - * @since 0.1 - * @group url - * @dataProvider list_of_URLs - */ - function test_esc_urls( $url, $escaped ) { - $this->assertEquals( $escaped, yourls_esc_url( $url ) ); - } - - /** - * Some strings and how they should be escaped in javascript - */ - function list_of_JS() { - return array( - array( - 'hello world();', - 'hello world();', - ), - array( - 'hello("world");', - 'hello("world");', - ), - array( - 'foo & bar &baz; '', - 'foo & bar &baz; '', - ), - ); - } - - /** - * Escape JS - * - * @since 0.1 - * @dataProvider list_of_JS - */ - function test_esc_js( $js, $escaped ) { - $this->assertEquals( $escaped, yourls_esc_js( $js ) ); - } - - /** - * Strings in a textarea and how they should be escaped - */ - function list_of_textarea() { - return array( - array( - 'hello
    world', - 'hello<br/>world', - ), - array( - '"omg"', - '"omg"', - ), - array( - "'omg'", - ''omg'', - ), - ); - } - - /** - * Escape JS - * - * @since 0.1 - * @dataProvider list_of_textarea - */ - function test_esc_textarea( $text, $escaped ) { - $this->assertEquals( $escaped, yourls_esc_textarea( $text ) ); - } - -} diff --git a/tests/tests/format/urls.php b/tests/tests/format/urls.php deleted file mode 100644 index 1b5686543..000000000 --- a/tests/tests/format/urls.php +++ /dev/null @@ -1,295 +0,0 @@ -assertSame( yourls_get_protocol( $test_this ), $expected ); - } - - - /** - * List of valid URLs that should not be changed when sanitized - */ - function list_of_valid_URLs() { - return array( - array( 'http://example.com' ), - array( 'http://example.com/' ), - array( 'http://ozh@example.com/' ), - array( 'http://example.com/?@OMG' ), // #1890 - array( 'http://ozh@example.com#BLAH' ), - array( 'http://Ozh:Password@example.com/' ), - array( 'http://Ozh:Password@example.com#OMG' ), - array( 'http://Ozh:Password@example.com:1337/' ), - array( 'http://Ozh:Password@example.com:1337#OMG' ), - array( 'http://Ozh:Password@example.com/hey@ho' ), - array( 'http://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose:@:@' ), - array( 'mailto:ozh@ozh.org' ), - array( 'http://example.com/?watchtheallowedcharacters-~+_.#=&;,/:%!*stay' ), - array( 'http://example.com/search.php?search=(amistillhere)' ), - array( 'http://example.com/?test=%2812345%29abcdef[gh]' ), - array( 'http://example.com/?test=(12345)abcdef[gh]' ), - array( 'http://[0:0:0:0:0:0:0:1]/' ), - array( 'http://[2001:db8:1f70::999:de8:7648:6e8]:100/' ), - array( 'http://example.com/?req=http;//blah' ), // - array( 'relative' ), - array( 'Relative/path/' ), - array( 'relative/Path/#yes' ), - array( '/absolute' ), - array( '/Absolute/Path/' ), - array( '/absolute/path/?omg#also' ), - array( 'http://académie-française.fr' ), - array( 'http://www.طارق.net/طارق?hello=%2B' ), - array( 'http://%d8%b7%d8%a7%d8%b1%d9%82.net/' ), // this is طارق.net, encoded. I _think_ it qualifies as valid - ); - } - - /** - * Test that valid URLs are not modified - * - * @since 0.1 - * @dataProvider list_of_valid_URLs - */ - function test_valid_urls( $url ) { - $this->assertEquals( $url, yourls_sanitize_url( $url ) ); - } - - /** - * URL with spaces - * - * @since 0.1 - */ - function test_url_with_spaces() { - $this->assertEquals( 'http://example.com/HelloWorld', yourls_sanitize_url( 'http://example.com/Hello World' ) ); - $this->assertEquals( 'http://example.com/Hello%20World', yourls_sanitize_url( 'http://example.com/Hello%20World' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url( 'http://example.com/ ' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url( ' http://example.com/' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url( ' http://example.com/ ' ) ); - } - - /** - * URL with bad chars - * - * @since 0.1 - */ - function test_url_with_bad_characters() { - // regular sanitize leaves %0A & %0D alone - $this->assertEquals( 'http://example.com/keep%0Dlinefeed%0A', yourls_sanitize_url( 'http://example.com/keep%0Dlinefeed%0A' ) ); - $this->assertEquals( 'http://example.com/%0%0%0DAD', yourls_sanitize_url( 'http://example.com/%0%0%0DAD' ) ); - - // sanitize with anti CRLF - $this->assertEquals( 'http://example.com/watchthelinefeedgo', yourls_sanitize_url_safe( 'http://example.com/watchthelinefeed%0Ago' ) ); - $this->assertEquals( 'http://example.com/watchthelinefeedgo', yourls_sanitize_url_safe( 'http://example.com/watchthelinefeed%0ago' ) ); - $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0Dgo' ) ); - $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0dgo' ) ); - - //Nesting Checks - $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0%0ddgo' ) ); - $this->assertEquals( 'http://example.com/watchthecarriagereturngo', yourls_sanitize_url_safe( 'http://example.com/watchthecarriagereturn%0%0DDgo' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0DAD' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0ADA' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0DAd' ) ); - $this->assertEquals( 'http://example.com/', yourls_sanitize_url_safe( 'http://example.com/%0%0%0ADa' ) ); - } - - /** - * Test valid, missing and fake protocols - * - * @since 0.1 - */ - function test_url_with_protocols() { - $this->assertEquals( 'http://example.com', yourls_sanitize_url( 'http://example.com' ) ); - $this->assertEquals( 'example.php', yourls_sanitize_url( 'example.php' ) ); - $this->assertEquals( '', yourls_sanitize_url( 'htttp://example.com' ) ); - $this->assertEquals( 'mailto:ozh@ozh.org', yourls_sanitize_url( 'mailto:ozh@ozh.org' ) ); - // play with allowed protocols - $this->assertEquals( '', yourls_sanitize_url( 'nasty://example.com/' ) ); - $this->assertEquals( 'nasty://example.com/', yourls_sanitize_url( 'nasty://example.com/', array('nasty://') ) ); - global $yourls_allowedprotocols; - $yourls_allowedprotocols[] = 'evil://'; - $this->assertEquals( 'evil://example.com', yourls_sanitize_url( 'evil://example.com' ) ); - $yourls_allowedprotocols = yourls_kses_allowed_protocols(); - } - - /** - * List of URLs with MiXeD CaSe to test. Structure: array( sanitized url, unsanitized url with mixed case ) - */ - function list_of_mixed_case() { - return array( - array( 'http://example.com' , 'http://example.com' ), # normal, no trailing slash - array( 'http://example.com/' , 'http://example.com/' ), # normal, trailing slash - array( 'http://example.com' , 'HTTP://example.com' ), - array( 'http://example.com' , 'Http://example.com' ), - array( 'http://example.com' , 'Http://ExAmPlE.com' ), - array( 'http://example.com/BLAH' , 'Http://ExAmPlE.com/BLAH' ), - array( 'http://http/HTTP?HTTP#HTTP' , 'HTTP://HTTP/HTTP?HTTP#HTTP' ), - array( 'http://example.com/?@BLaH' , 'Http://ExAmPlE.com/?@BLaH' ), #1890 - array( 'http://example.com#BLAH' , 'Http://ExAmPlE.com#BLAH' ), - array( 'http://example.com#BLAH' , 'Http://@ExAmPlE.com#BLAH' ), - array( 'http://example.com#BLAH' , 'Http://:@ExAmPlE.com#BLAH' ), - array( 'http://example.com?BLAH' , 'Http://ExAmPlE.com?BLAH' ), - array( 'http://Ozh:Password@example.com:1337#OMG' , 'http://Ozh:Password@Example.COM:1337#OMG' ), - array( 'http://User:PWd@example.com?User:PWd@Example.com' , 'http://User:PWd@Example.com?User:PWd@Example.com' ), - array( 'mailto:Ozh@Ozh.org?omg' , 'MAILTO:Ozh@Ozh.org?omg' ), - array( 'http://www.طارق.net/' , 'http://www.طارق.Net/' ), - array( 'http://académie-française.fr' , 'http://Académie-française.FR' ), - ); - } - - /** - * Protocol and domain with mixed case - * - * @since 0.1 - * @dataProvider list_of_mixed_case - */ - function test_url_with_protocol_case( $sanitized, $unsanitized ) { - $this->assertEquals( $sanitized, yourls_sanitize_url( $unsanitized ) ); - } - - /** - * List of URLs with IDN domain, and how YOURLS should sanitize them - */ - function list_of_IDN() { - return array( - array( 'http://www.طارق.Net/Omgطارق' , 'http://www.طارق.net/Omgطارق' ), - array( 'http://xn--mgbuq0c.Net/Omgطارق' , 'http://طارق.net/Omgطارق' ), - array( 'http://%d8%b7%d8%a7%d8%b1%d9%82.Net/Omgطارق' , 'http://%d8%b7%d8%a7%d8%b1%d9%82.net/Omgطارق' ), // طارق.net, urlencoded - array( 'http://xn--p1ai.РФ' , 'http://рф.рф' ), // lowercasing where applicable: РФ -> рф - array( 'http://РФ.xn--p1ai/' , 'http://рф.рф/' ), - array( 'http://xn--p1ai.xn--p1ai' , 'http://рф.рф' ), - ); - } - - /** - * Protocol and domain with mixed case - * - * @dataProvider list_of_IDN - */ - function test_url_with_IDN( $unsanitized, $sanitized ) { - $this->assertEquals( $sanitized, yourls_sanitize_url( $unsanitized ) ); - } - - /** - * List of URLS and expected matches whether we're on SSL or not. - * Structure: array(original URL, expected URL if we're on HTTP, expected URL if we're on HTTPS) - */ - function list_of_urls_with_and_without_https() { - return array( - array( 'http://omg', 'http://omg', 'https://omg' ), - array( 'https://omg', 'https://omg', 'https://omg' ), - array( 'http://omg?http', 'http://omg?http', 'https://omg?http' ), - array( 'https://omg?http', 'https://omg?http', 'https://omg?http' ), - array( 'omg?http://bleh', 'omg?http://bleh', 'omg?http://bleh' ), - array( 'omg?https://bleh', 'omg?https://bleh', 'omg?https://bleh' ), - array( 'http', 'http', 'http' ), - array( 'https', 'https', 'https' ), - array( 'http://https', 'http://https', 'https://https' ), - array( 'https://https', 'https://https', 'https://https' ), - ); - } - /** - * Test matching protocol with no SSL - * - * Feed URL and return a result that matches "http" - * - * @dataProvider list_of_urls_with_and_without_https - */ - function test_matching_protocols_with_no_ssl( $url, $without_ssl, $with_ssl ) { - yourls_add_filter('is_ssl', 'yourls_return_false'); - $this->assertEquals( $without_ssl, yourls_match_current_protocol($url) ); - } - - /** - * Test matching protocol with SSL - * - * Feed URL and return a result that matches "https" - * - * @dataProvider list_of_urls_with_and_without_https - */ - function test_matching_protocols_with_ssl( $url, $without_ssl, $with_ssl ) { - yourls_add_filter('is_ssl', 'yourls_return_true'); - $this->assertEquals( $with_ssl, yourls_match_current_protocol($url) ); - } - - /** - * List of various valid URL with mixed scenarios of IDN - * Structure: array(URL, expected URL after yourls_sanitize_url (and especially yourls_normalize_uri(), which deals with IDN) - */ - function list_of_idn_punycode_utf8_rtl() { - return array( - [ 'http://ua-test.link' , 'http://ua-test.link' ], // Ascii.new - [ 'http://ua-test.technology' , 'http://ua-test.technology' ], // Ascii.long - [ 'http://普试.top/' , 'http://普试.top/' ], // Idn.ascii - [ 'http://ua-test.世界' , 'http://ua-test.世界' ], // Ascii.idn - [ 'http://普试.世界/' , 'http://普试.世界/' ], // Idn.idn - [ 'http://ua-test.xn--rhqv96g' , 'http://ua-test.世界' ], // Ascii.punycode - [ 'http://xn--tkvo64f.top' , 'http://普试.top' ], // Punycode.ascii - [ 'http://xn--tkvo64f.xn--rhqv96g' , 'http://普试.世界' ], // Punycode.punycode - [ 'http://اختبار-القبولالعالمي.top' , 'http://اختبار-القبولالعالمي.top' ], // RTL.ascii - [ 'http://اختبار-القبولالعالمي.شبكة' , 'http://اختبار-القبولالعالمي.شبكة' ], // RTL.RTL - [ 'http://ua-test.link/我的' , 'http://ua-test.link/我的' ], // Ascii.new/Unicode - [ 'http://ua-test.technology/我的' , 'http://ua-test.technology/我的' ], // Ascii.long/Unicode - [ 'http://普试.top/我的' , 'http://普试.top/我的' ], // Idn.ascii/Unicode - [ 'http://ua-test.世界/我的' , 'http://ua-test.世界/我的' ], // Ascii.idn/Unicode - [ 'http://普试.世界/我的' , 'http://普试.世界/我的' ], // Idn.idn/Unicode - [ 'http://ختبار-القبولالعالمي.top/我的' , 'http://ختبار-القبولالعالمي.top/我的' ], // RTL.ascii/Unicode - [ 'http://اختبار-القبولالعالمي.شبكة/我的' , 'http://اختبار-القبولالعالمي.شبكة/我的' ], // RTL.RTL/Unicode - - // Damn, due to these UTF8 chars not being fixed width, we cannot neatly - // justify the code and comments. How disappointing. - ); - } - - /** - * Test various cases : domain name / TLD / path with ascii, punycode, utf8 and RTL - * - * @dataProvider list_of_idn_punycode_utf8_rtl - */ - function test_various_idn_cases($url, $expected) { - $this->assertEquals( yourls_sanitize_url($url), $expected ); - } - -} diff --git a/tests/tests/geoip/GeoIPTest.php b/tests/tests/geoip/GeoIPTest.php new file mode 100644 index 000000000..ca51143aa --- /dev/null +++ b/tests/tests/geoip/GeoIPTest.php @@ -0,0 +1,77 @@ +assertEquals( $country, yourls_geo_ip_to_countrycode( $ip, 'none' ) ); + } + + /** + * Check that a few IPv6 resolve to the correct country code + */ + #[\PHPUnit\Framework\Attributes\DataProvider('ipv6_samples')] + public function test_ip_to_countrycode_ipv6( $ip, $country ) { + $this->assertEquals( $country, yourls_geo_ip_to_countrycode( $ip, 'none' ) ); + } + + /** + * Check a few country code => country name pairs + */ + #[\PHPUnit\Framework\Attributes\DataProvider('country_codes')] + public function test_countrycode_to_countryname( $code, $country ) { + $this->assertEquals( $country, yourls_geo_countrycode_to_countryname( $code ) ); + } + + /** + * Check a few code return a string when getting their country flag + */ + public function test_country_images() { + $this->assertIsString(yourls_geo_get_flag('AU')); // something like http://yourls/includes/geo/flags/flag_au.gif + $this->assertIsString(yourls_geo_get_flag('')); // something like http://yourls/includes/geo/flags/flag_.gif + $this->assertIsString(yourls_geo_get_flag('OMGLOL')); // fall back to default '' + } + + /** + * Data provider : array of arrays of ( 'ip', 'country code' ) in IPv4 notation + */ + public static function ipv4_samples(): \Iterator + { + yield array( '8.8.8.8', 'US' ); + yield array( '13.37.13.37', 'FR' ); + yield array( '79.79.79.79', 'GB' ); + yield array( '10.0.0.1', 'none' ); + yield array( 'helloworld', 'none' ); + } + + /** + * Data provider : array of arrays of ( 'ip', 'country code' ) in IPv6 various notations + */ + public static function ipv6_samples(): \Iterator + { + yield array( '::80.24.24.24', 'ES' ); + // yield array( '2606:4700:4700::1111', 'US' ); + yield array( '2001:0240:2000::', 'JP' ); + yield array( '::1', 'none' ); + yield array( 'mynameisozh', 'none' ); + } + + /** + * Data provider : array of arrays of ( 'country code', 'country name' ) + */ + public static function country_codes(): \Iterator + { + yield array( 'AU', 'Australia' ); + yield array( 'BZ', 'Belize' ); + yield array( 'CA', 'Canada' ); + yield array( 'WW', '' ); + } + +} diff --git a/tests/tests/geoip/geoip.php b/tests/tests/geoip/geoip.php deleted file mode 100644 index b23ad8039..000000000 --- a/tests/tests/geoip/geoip.php +++ /dev/null @@ -1,85 +0,0 @@ -assertEquals( $country, yourls_geo_ip_to_countrycode( $ip, 'none' ) ); - } - - /** - * Check that a few IPv6 resolve to the correct country code - * - * @dataProvider ipv6_samples - */ - public function test_ip_to_countrycode_ipv6( $ip, $country ) { - $this->assertEquals( $country, yourls_geo_ip_to_countrycode( $ip, 'none' ) ); - } - - /** - * Check a few country code => country name pairs - * - * @dataProvider country_codes - */ - public function test_countrycode_to_countryname( $code, $country ) { - $this->assertEquals( $country, yourls_geo_countrycode_to_countryname( $code ) ); - } - - /** - * Check a few code return a string when getting their country flag - */ - public function test_country_images() { - $this->assertIsString(yourls_geo_get_flag('AU')); // something like http://yourls/includes/geo/flags/flag_au.gif - $this->assertIsString(yourls_geo_get_flag('')); // something like http://yourls/includes/geo/flags/flag_.gif - $this->assertIsString(yourls_geo_get_flag('OMGLOL')); // fall back to default '' - } - - /** - * Data provider : array of arrays of ( 'ip', 'country code' ) in IPv4 notation - */ - public function ipv4_samples() { - return array( - array( '8.8.8.8', 'US' ), - array( '13.37.13.37', 'FR' ), - array( '79.79.79.79', 'GB' ), - array( '10.0.0.1', 'none' ), - array( 'helloworld', 'none' ), - ); - } - - /** - * Data provider : array of arrays of ( 'ip', 'country code' ) in IPv6 various notations - */ - public function ipv6_samples() { - return array( - array( '::80.24.24.24', 'ES' ), - array( '2001:4860:0:1001::68', 'US' ), - array( '2001:0240:2000:0000:0000:0000:0000:0000', 'JP' ), - array( '::1', 'none' ), - array( 'mynameisozh', 'none' ), - ); - } - - /** - * Data provider : array of arrays of ( 'country code', 'country name' ) - */ - public function country_codes() { - return array( - array( 'AU', 'Australia' ), - array( 'BZ', 'Belize' ), - array( 'CA', 'Canada' ), - array( 'WW', '' ), // fake code - ); - } - -} diff --git a/tests/tests/http/api-check.php b/tests/tests/http/AYOTest.php similarity index 91% rename from tests/tests/http/api-check.php rename to tests/tests/http/AYOTest.php index 831bc0dee..431c18f14 100644 --- a/tests/tests/http/api-check.php +++ b/tests/tests/http/AYOTest.php @@ -3,11 +3,11 @@ /** * HTTP functions related to api.yourls.org * - * @group http - * @group AYO * @since 0.1 */ -class HTTP_AYO_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('http')] +#[\PHPUnit\Framework\Attributes\Group('AYO')] +class AYOTest extends PHPUnit\Framework\TestCase { protected $actions, $core_version_checks; @@ -122,7 +122,7 @@ public function test_check_only_in_admin() { /** * Generate an object to mock last attempt of checking against api.yourls.org */ - public function return_case_object( $failed_attempts, $last_attempt, $version_checked ) { + public static function return_case_object( $failed_attempts, $last_attempt, $version_checked ) { $checks = new stdClass(); $checks->last_result = rand_str(); $checks->failed_attempts = $failed_attempts; @@ -135,7 +135,7 @@ public function return_case_object( $failed_attempts, $last_attempt, $version_ch /** * Provider of various test cases for test_api_check_in_various_scenario() */ - public function case_scenario() { + public static function case_scenario() { $return = array(); @@ -159,7 +159,7 @@ public function case_scenario() { * Then : we DO want to check */ $name = 'Case 1'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 0, // 0 previously failed attempt time() - 26 * 3600, // 26 hours ago YOURLS_VERSION // version match @@ -175,7 +175,7 @@ public function case_scenario() { * Then : we DO want to check */ $name = 'Case 2'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 0, // 0 previously failed attempt time() - 26 * 3600, // 26 hours ago rand_str() // version mismatch @@ -191,7 +191,7 @@ public function case_scenario() { * Then : we DON'T want to check */ $name = 'Case 3'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 0, // 0 previously failed attempt time() - 10 * 3600, // 10 hours ago YOURLS_VERSION // version match @@ -207,7 +207,7 @@ public function case_scenario() { * Then : we DO want to check */ $name = 'Case 4'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 0, // 0 previously failed attempt time() - 10 * 3600, // 10 hours ago rand_str() // version mismatch @@ -223,7 +223,7 @@ public function case_scenario() { * Then : we DO want to check */ $name = 'Case 5'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 1337, // some previously failed attempts time() - 3 * 3600, // 3 hours ago YOURLS_VERSION // version match @@ -239,7 +239,7 @@ public function case_scenario() { * Then : we DO want to check */ $name = 'Case 6'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 1337, // some previously failed attempts time() - 3 * 3600, // 3 hours ago rand_str() // version mismatch @@ -255,7 +255,7 @@ public function case_scenario() { * Then : we DON'T want to check */ $name = 'Case 7'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 1337, // some previously failed attempts time() - 1 * 3600, // 1 hour ago YOURLS_VERSION // version match @@ -271,7 +271,7 @@ public function case_scenario() { * Then : we DO want to check */ $name = 'Case 8'; - $checks = $this->return_case_object( + $checks = self::return_case_object( 1337, // some previously failed attempts time() - 1 * 3600, // 1 hour ago rand_str() // version mismatch @@ -285,9 +285,9 @@ public function case_scenario() { /** * Check if we should poll api.yourls.org under various circumstances * - * @dataProvider case_scenario * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('case_scenario')] public function test_api_check_in_various_scenario( $name, $checks, $expected ) { yourls_add_filter('shunt_yourls_http_request', array($this,'fake_http_request_success') ); @@ -300,7 +300,7 @@ public function test_api_check_in_various_scenario( $name, $checks, $expected ) /** * Provide fake JSON responses from api.yourls.org and a boolean stating if they should be accepted or not */ - public function json_responses() { + public static function json_responses() { $return = array(); $return['expected'] = array( @@ -366,9 +366,9 @@ public function json_responses() { /** * Validate various json responses from api.yourls.org and make sure they're legit * - * @dataProvider json_responses * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('json_responses')] public function test_validate_api_json_response($json, $expected) { $this->assertSame( $expected, yourls_validate_core_version_response($json) ); } @@ -376,7 +376,7 @@ public function test_validate_api_json_response($json, $expected) { /** * Provide fake and true github repo URLs */ - public function fake_and_true_github_repo_urls() { + public static function fake_and_true_github_repo_urls() { $return = array(); $return['true'] = ['https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3', true]; $return['not github'] = ['https://api.g1thub.com/repos/YOURLS/YOURLS/zipball/1.2.3', false]; @@ -388,9 +388,8 @@ public function fake_and_true_github_repo_urls() { /** * Test yourls_is_valid_github_repo_url() - * - * @dataProvider fake_and_true_github_repo_urls */ + #[\PHPUnit\Framework\Attributes\DataProvider('fake_and_true_github_repo_urls')] public function test_is_valid_github_repo_url($url, $expected) { $this->assertSame( yourls_is_valid_github_repo_url($url), $expected ); } @@ -398,7 +397,7 @@ public function test_is_valid_github_repo_url($url, $expected) { /** * Provide various scenarios for version reported by api.yourls.org / current version to check if notice is shown */ - public function new_version_scenarios() { + public static function new_version_scenarios() { $return = array(); // AYO current notice @@ -418,9 +417,8 @@ public function new_version_scenarios() { /** * Test various YOURLS version strings from api.yourls.org, compare them to the actual version * and make sure we display the correct update notice - * - * @dataProvider new_version_scenarios */ + #[\PHPUnit\Framework\Attributes\DataProvider('new_version_scenarios')] public function test_new_version_notice( $api_version, $current_version, $expected ) { // fake the api response $check = (object)array( @@ -438,7 +436,7 @@ public function test_new_version_notice( $api_version, $current_version, $expect /** * Test various zipball URLs and get version number from it */ - function various_zipball_url_version() { + static function various_zipball_url_version() { $return = []; $return[] = ['https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3', '1.2.3']; @@ -453,9 +451,8 @@ function various_zipball_url_version() { /** * Test various zipball URLs and get version number from it - * - * @dataProvider various_zipball_url_version */ + #[\PHPUnit\Framework\Attributes\DataProvider('various_zipball_url_version')] public function test_get_version_from_zipball_url($url, $expected) { $this->assertSame($expected, yourls_get_version_from_zipball_url($url)); } @@ -464,7 +461,7 @@ public function test_get_version_from_zipball_url($url, $expected) { /** * test various core version JSON responses from api.yourls.org */ - function get_various_json_response_keys() { + static function get_various_json_response_keys() { $return = []; $return['latest & zipurl'] = [['latest' => 'ok', 'zipurl' => 'ok'], true]; @@ -481,8 +478,8 @@ function get_various_json_response_keys() { /** * Check yourls_validate_core_version_response_keys() works as expected - * @dataProvider get_various_json_response_keys */ + #[\PHPUnit\Framework\Attributes\DataProvider('get_various_json_response_keys')] function test_yourls_validate_core_version_response_keys($json, $expected) { $this->assertSame(yourls_validate_core_version_response_keys((object)$json), $expected); } @@ -490,11 +487,10 @@ function test_yourls_validate_core_version_response_keys($json, $expected) { /** * Return all possible api.yourls.org/core/version URL */ - function get_api_yourls_core() { - return [ - ['https://api.yourls.org/core/version/1.1/'], - ['http://api.yourls.org/core/version/1.0/'], - ]; + static function get_api_yourls_core(): \Iterator + { + yield ['https://api.yourls.org/core/version/1.1/']; + yield ['http://api.yourls.org/core/version/1.0/']; } /** @@ -502,9 +498,8 @@ function get_api_yourls_core() { * * This test may fail is the server is unreachable or the API is down. * TODO: make this test evolve as the API evolves - * - * @dataProvider get_api_yourls_core */ + #[\PHPUnit\Framework\Attributes\DataProvider('get_api_yourls_core')] function test_yourls_get_core_version_json($url) { $req = yourls_http_get($url); diff --git a/tests/tests/http/HTTPHeadersTest.php b/tests/tests/http/HTTPHeadersTest.php new file mode 100644 index 000000000..41064fa93 --- /dev/null +++ b/tests/tests/http/HTTPHeadersTest.php @@ -0,0 +1,86 @@ +\s*window.location="http://somewhere";!m'; + + $this->expectOutputRegex($regexp); + yourls_redirect_javascript('http://somewhere'); + } + + public static function status_codes(): \Iterator + { + yield array(100, 'Continue'); + yield array(101, 'Switching Protocols'); + yield array(102, 'Processing'); + yield array(200, 'OK'); + yield array(201, 'Created'); + yield array(202, 'Accepted'); + yield array(203, 'Non-Authoritative Information'); + yield array(204, 'No Content'); + yield array(205, 'Reset Content'); + yield array(206, 'Partial Content'); + yield array(207, 'Multi-Status'); + yield array(226, 'IM Used'); + yield array(300, 'Multiple Choices'); + yield array(301, 'Moved Permanently'); + yield array(302, 'Found'); + yield array(303, 'See Other'); + yield array(304, 'Not Modified'); + yield array(305, 'Use Proxy'); + yield array(306, 'Reserved'); + yield array(307, 'Temporary Redirect'); + yield array(400, 'Bad Request'); + yield array(401, 'Unauthorized'); + yield array(402, 'Payment Required'); + yield array(403, 'Forbidden'); + yield array(404, 'Not Found'); + yield array(405, 'Method Not Allowed'); + yield array(406, 'Not Acceptable'); + yield array(407, 'Proxy Authentication Required'); + yield array(408, 'Request Timeout'); + yield array(409, 'Conflict'); + yield array(410, 'Gone'); + yield array(411, 'Length Required'); + yield array(412, 'Precondition Failed'); + yield array(413, 'Request Entity Too Large'); + yield array(414, 'Request-URI Too Long'); + yield array(415, 'Unsupported Media Type'); + yield array(416, 'Requested Range Not Satisfiable'); + yield array(417, 'Expectation Failed'); + yield array(422, 'Unprocessable Entity'); + yield array(423, 'Locked'); + yield array(424, 'Failed Dependency'); + yield array(426, 'Upgrade Required'); + yield array(500, 'Internal Server Error'); + yield array(501, 'Not Implemented'); + yield array(502, 'Bad Gateway'); + yield array(503, 'Service Unavailable'); + yield array(504, 'Gateway Timeout'); + yield array(505, 'HTTP Version Not Supported'); + yield array(506, 'Variant Also Negotiates'); + yield array(507, 'Insufficient Storage'); + yield array(510, 'Not Extended'); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('status_codes')] + public function test_get_HTTP_status($code, $status) { + $this->assertSame(yourls_get_HTTP_status($code), $status); + } + + public function test_get_HTTP_status_invalid() { + $this->assertSame('', yourls_get_HTTP_status(1337)); + } +} diff --git a/tests/tests/http/requests.php b/tests/tests/http/HTTPRequestsTest.php similarity index 89% rename from tests/tests/http/requests.php rename to tests/tests/http/HTTPRequestsTest.php index fc42ad9c5..9e1ddca21 100644 --- a/tests/tests/http/requests.php +++ b/tests/tests/http/HTTPRequestsTest.php @@ -5,13 +5,13 @@ * * We're not testing the Request library itself, it is fully tested on its own, see https://github.com/rmccue/Requests * - * @group http * @since 0.1 */ -class HTTP_Requests_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('http')] +class HTTPRequestsTest extends PHPUnit\Framework\TestCase { private function url( $what = '' ) { - return 'https://httpbin.org/' . $what; + return 'https://httpbin.io/' . $what; } /** diff --git a/tests/tests/http/misc.php b/tests/tests/http/HTTPTest.php similarity index 83% rename from tests/tests/http/misc.php rename to tests/tests/http/HTTPTest.php index dd3a95bc7..f2d8ad56a 100644 --- a/tests/tests/http/misc.php +++ b/tests/tests/http/HTTPTest.php @@ -2,11 +2,9 @@ /** * Utilities - * - * @group http */ - -class Misc_HTTP_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('http')] +class HTTPTest extends PHPUnit\Framework\TestCase { public function test_get_user_agent() { $this->assertIsString(yourls_get_user_agent()); diff --git a/tests/tests/http/general.php b/tests/tests/http/MiscTest.php similarity index 94% rename from tests/tests/http/general.php rename to tests/tests/http/MiscTest.php index d9527fca6..ad05911d2 100644 --- a/tests/tests/http/general.php +++ b/tests/tests/http/MiscTest.php @@ -3,10 +3,10 @@ /** * HTTP misc utilities and helpers * - * @group http * @since 0.1 */ -class HTTP_Misc_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('http')] +class MiscTest extends PHPUnit\Framework\TestCase { protected function tearDown(): void { yourls_remove_filter( 'http_get_proxy', 'yourls_return_true' ); diff --git a/tests/tests/http/proxy.php b/tests/tests/http/ProxyTest.php similarity index 54% rename from tests/tests/http/proxy.php rename to tests/tests/http/ProxyTest.php index 38be9beed..90171e504 100644 --- a/tests/tests/http/proxy.php +++ b/tests/tests/http/ProxyTest.php @@ -3,10 +3,10 @@ /** * HTTP proxy support functions * - * @group http * @since 0.1 */ -class HTTP_Proxy_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('http')] +class ProxyTest extends PHPUnit\Framework\TestCase { protected function tearDown(): void { yourls_remove_all_filters( 'http_get_proxy_bypass_host' ); @@ -15,27 +15,26 @@ protected function tearDown(): void { /** * List of hosts and wether they should go through proxy or not */ - public function proxy() { - return array( - array( 'invalid', false ), - array( 'http://localhost', false ), - array( 'http://127.0.0.1', false ), - array( 'http://127.1', false ), - array( 'http://[::1]', false ), - array( YOURLS_SITE, false ), - array( 'http://' . rand_str() , true ), - - array( 'http://bypass.me' , true ), // these two will be added to the by-pass list - array( 'http://skipthem.all' , true ), // in the next test - ); + public static function proxy(): \Iterator + { + yield array( 'invalid', false ); + yield array( 'http://localhost', false ); + yield array( 'http://127.0.0.1', false ); + yield array( 'http://127.1', false ); + yield array( 'http://[::1]', false ); + yield array( YOURLS_SITE, false ); + yield array( 'http://' . rand_str() , true ); + yield array( 'http://bypass.me' , true ); + // these two will be added to the by-pass list + yield array( 'http://skipthem.all' , true ); } /** * Check what URLs we should send through a proxy, if defined * - * @dataProvider proxy * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('proxy')] public function test_proxy( $url, $goes_through_proxy ) { $this->assertSame( $goes_through_proxy, yourls_send_through_proxy( $url ) ); } @@ -43,28 +42,25 @@ public function test_proxy( $url, $goes_through_proxy ) { /** * List of hosts and wether they should go through proxy or not, with 'bypass.me, *.skipthem.all' defined as by-passing hosts */ - public function proxy_bypass_wildcard() { - return array( - array( 'invalid', false ), - array( 'http://localhost', false ), - array( 'http://127.0.0.1', false ), - array( 'http://127.1', false ), - array( 'http://[::1]', false ), - array( YOURLS_SITE, false ), - array( 'http://' . rand_str() , true ), - - array( 'http://bypass.me' , false ), - array( 'http://bypass.me/some/thing' , false ), - array( 'http://notbypass.me' , true ), - array( 'http://bypass.menot' , true ), - array( 'http://dont.bypass.me' , true ), - - array( 'http://skipthem.all' , false ), - array( 'http://notskipthem.all' , true ), - array( 'http://skipthem.allnot' , true ), - array( 'http://really.skipthem.all' , false ), - array( 'http://yeah.really.skipthem.all/some/thing' , false ), - ); + public static function proxy_bypass_wildcard(): \Iterator + { + yield array( 'invalid', false ); + yield array( 'http://localhost', false ); + yield array( 'http://127.0.0.1', false ); + yield array( 'http://127.1', false ); + yield array( 'http://[::1]', false ); + yield array( YOURLS_SITE, false ); + yield array( 'http://' . rand_str() , true ); + yield array( 'http://bypass.me' , false ); + yield array( 'http://bypass.me/some/thing' , false ); + yield array( 'http://notbypass.me' , true ); + yield array( 'http://bypass.menot' , true ); + yield array( 'http://dont.bypass.me' , true ); + yield array( 'http://skipthem.all' , false ); + yield array( 'http://notskipthem.all' , true ); + yield array( 'http://skipthem.allnot' , true ); + yield array( 'http://really.skipthem.all' , false ); + yield array( 'http://yeah.really.skipthem.all/some/thing' , false ); } public function bypass_hosts_wildcard() { @@ -74,9 +70,9 @@ public function bypass_hosts_wildcard() { /** * Check what URLs we should send through a proxy with 'bypass.me, *.skipthem.all' defined as by-passing hosts * - * @dataProvider proxy_bypass_wildcard * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\DataProvider('proxy_bypass_wildcard')] public function test_proxy_bypass_wildcard( $url, $goes_through_proxy ) { yourls_add_filter( 'http_get_proxy_bypass_host', array( $this, 'bypass_hosts_wildcard' ) ); $this->assertSame( $goes_through_proxy, yourls_send_through_proxy( $url ) ); diff --git a/tests/tests/http/headers.php b/tests/tests/http/headers.php deleted file mode 100644 index 8b2339a42..000000000 --- a/tests/tests/http/headers.php +++ /dev/null @@ -1,94 +0,0 @@ -\s*window.location="http://somewhere";!m'; - - $this->expectOutputRegex($regexp); - yourls_redirect_javascript('http://somewhere'); - } - - public function status_codes() { - return array( - array(100, 'Continue'), - array(101, 'Switching Protocols'), - array(102, 'Processing'), - - array(200, 'OK'), - array(201, 'Created'), - array(202, 'Accepted'), - array(203, 'Non-Authoritative Information'), - array(204, 'No Content'), - array(205, 'Reset Content'), - array(206, 'Partial Content'), - array(207, 'Multi-Status'), - array(226, 'IM Used'), - - array(300, 'Multiple Choices'), - array(301, 'Moved Permanently'), - array(302, 'Found'), - array(303, 'See Other'), - array(304, 'Not Modified'), - array(305, 'Use Proxy'), - array(306, 'Reserved'), - array(307, 'Temporary Redirect'), - - array(400, 'Bad Request'), - array(401, 'Unauthorized'), - array(402, 'Payment Required'), - array(403, 'Forbidden'), - array(404, 'Not Found'), - array(405, 'Method Not Allowed'), - array(406, 'Not Acceptable'), - array(407, 'Proxy Authentication Required'), - array(408, 'Request Timeout'), - array(409, 'Conflict'), - array(410, 'Gone'), - array(411, 'Length Required'), - array(412, 'Precondition Failed'), - array(413, 'Request Entity Too Large'), - array(414, 'Request-URI Too Long'), - array(415, 'Unsupported Media Type'), - array(416, 'Requested Range Not Satisfiable'), - array(417, 'Expectation Failed'), - array(422, 'Unprocessable Entity'), - array(423, 'Locked'), - array(424, 'Failed Dependency'), - array(426, 'Upgrade Required'), - - array(500, 'Internal Server Error'), - array(501, 'Not Implemented'), - array(502, 'Bad Gateway'), - array(503, 'Service Unavailable'), - array(504, 'Gateway Timeout'), - array(505, 'HTTP Version Not Supported'), - array(506, 'Variant Also Negotiates'), - array(507, 'Insufficient Storage'), - array(510, 'Not Extended'), - ); - } - - /** - * @dataProvider status_codes - */ - public function test_get_HTTP_status($code, $status) { - $this->assertSame(yourls_get_HTTP_status($code), $status); - } - - public function test_get_HTTP_status_invalid() { - $this->assertSame(yourls_get_HTTP_status(1337), ''); - } -} diff --git a/tests/tests/install/htaccess.php b/tests/tests/install/HtaccessTest.php similarity index 63% rename from tests/tests/install/htaccess.php rename to tests/tests/install/HtaccessTest.php index 60d4191f1..0736bada8 100644 --- a/tests/tests/install/htaccess.php +++ b/tests/tests/install/HtaccessTest.php @@ -2,10 +2,9 @@ /** * Test htaccess creation & modification functions - * - * @group install */ -class Install_htaccess_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('install')] +class HtaccessTest extends PHPUnit\Framework\TestCase { protected $server; @@ -27,21 +26,20 @@ public function tearDown(): void { * Provide server signatures, wether they're Apache (true) or something else (false) and * the name of the redirect rule file (.htaccess or web.config) */ - public function servers() { - return array( - array( 'Very Common Apache', true, '.htaccess' ), - array( 'LiteSpeed So Fast', true, '.htaccess' ), - array( 'meh IIS meh', false, 'web.config' ), - ); + public static function servers(): \Iterator + { + yield array( 'Very Common Apache', true, '.htaccess' ); + yield array( 'LiteSpeed So Fast', true, '.htaccess' ); + yield array( 'meh IIS meh', false, 'web.config' ); } - /** - * Check .htaccess creation - general function, checking if file is created - * - * @dataProvider servers - * @since 0.1 - */ - public function test_htaccess( $server, $is_apache, $file ) { + /** + * Check .htaccess creation - general function, checking if file is created + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('servers')] + public function test_htaccess( $server, $is_apache, $file ) { $_SERVER['SERVER_SOFTWARE'] = $server; $this->assertSame( $is_apache, yourls_is_apache() ); @@ -49,30 +47,29 @@ public function test_htaccess( $server, $is_apache, $file ) { if( file_exists( YOURLS_ABSPATH . '/' . $file ) ) @unlink( YOURLS_ABSPATH . '/' . $file ); - $this->assertTrue( yourls_create_htaccess() ); - $this->assertFileExists( YOURLS_ABSPATH . '/' . $file ); - } + $this->assertTrue( yourls_create_htaccess() ); + $this->assertFileExists( YOURLS_ABSPATH . '/' . $file ); + } /** * Files in which we want to insert content */ - public function htaccess_content() { - return array( - array( 'original_nofile.txt' ), - array( 'original_empty.txt' ), - array( 'original_fresh-YOURLS-content.txt' ), - array( 'original_old-YOURLS-content.txt' ), - array( 'original_other-content.txt' ), - ); + public static function htaccess_content(): \Iterator + { + yield array( 'original_nofile.txt' ); + yield array( 'original_empty.txt' ); + yield array( 'original_fresh-YOURLS-content.txt' ); + yield array( 'original_old-YOURLS-content.txt' ); + yield array( 'original_other-content.txt' ); } - /** - * Check .htaccess creation - specific cases, checking file contents - * - * @dataProvider htaccess_content - * @since 0.1 - */ - public function test_htaccess_content( $filename ) { + /** + * Check .htaccess creation - specific cases, checking file contents + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\DataProvider('htaccess_content')] + public function test_htaccess_content( $filename ) { $newfile = str_replace( 'original_', 'test_', $filename ); $expected = str_replace( 'original_', 'expected_', $filename ); @@ -103,6 +100,6 @@ public function test_htaccess_content( $filename ) { $new = array_map( function($line) {return str_replace(array("\r", "\n"), '', $line);}, file($newfile)); $this->assertSame($exp, $new); unlink( $newfile ); - } + } } diff --git a/tests/tests/install/install.php b/tests/tests/install/InstallTest.php similarity index 78% rename from tests/tests/install/install.php rename to tests/tests/install/InstallTest.php index 5387520b7..2731f5d28 100644 --- a/tests/tests/install/install.php +++ b/tests/tests/install/InstallTest.php @@ -2,31 +2,30 @@ /** * Checks install misc functions - * - * @group install */ -class Install_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('install')] +class InstallTest extends PHPUnit\Framework\TestCase { /** - * Check if YOURLS is declared installed - */ - public function test_install() { - $this->assertTrue( yourls_is_installed() ); - } - - /** - * Check that tables were correctly populated during install - */ - public function test_init_tables() { - // This should fail because these inserts have been taken care of during install - $this->assertFalse( yourls_initialize_options() ); - $this->assertFalse( yourls_insert_sample_links() ); - } - - /** - * Test (sort of) table creation - */ - public function test_create_tables() { + * Check if YOURLS is declared installed + */ + public function test_install() { + $this->assertTrue( yourls_is_installed() ); + } + + /** + * Check that tables were correctly populated during install + */ + public function test_init_tables() { + // This should fail because these inserts have been taken care of during install + $this->assertFalse( yourls_initialize_options() ); + $this->assertFalse( yourls_insert_sample_links() ); + } + + /** + * Test (sort of) table creation + */ + public function test_create_tables() { /* The expected result has: * - success messages: the table are created with a "CREATE IF NOT EXISTS", @@ -54,11 +53,11 @@ public function test_create_tables() { ); $this->assertSame( $expected, yourls_create_sql_tables() ); - } + } - /** - * Test (sort of) defining constants - */ + /** + * Test (sort of) defining constants + */ public function test_correct_config() { $test = new \YOURLS\Config\Config(YOURLS_CONFIGFILE); @@ -77,9 +76,9 @@ public function test_correct_config() { $this->assertSame($before,$after); } - /** - * Test incorrect config provided - */ + /** + * Test incorrect config provided + */ public function test_incorrect_config() { $this->expectException(YOURLS\Exceptions\ConfigException::class); $this->expectExceptionMessageMatches('/User defined config not found at \'[0-9a-z]+\'/'); @@ -88,9 +87,9 @@ public function test_incorrect_config() { $test->find_config(); } - /** - * Test config not found - */ + /** + * Test config not found + */ public function test_not_found_config() { $this->expectException(YOURLS\Exceptions\ConfigException::class); $this->expectExceptionMessage('Cannot find config.php. Please read the readme.html to learn how to install YOURLS'); @@ -100,9 +99,9 @@ public function test_not_found_config() { $test->find_config(); } - /** - * Test Init actions. Not sure this is a good idea, might become cumbersome to maintain? - */ + /** + * Test Init actions. Not sure this is a good idea, might become cumbersome to maintain? + */ public function test_init_defaults() { $test = new \YOURLS\Config\InitDefaults(); diff --git a/tests/tests/install/version.php b/tests/tests/install/VersionTest.php similarity index 70% rename from tests/tests/install/version.php rename to tests/tests/install/VersionTest.php index a042156ef..9eb69e4a7 100644 --- a/tests/tests/install/version.php +++ b/tests/tests/install/VersionTest.php @@ -2,10 +2,9 @@ /** * Checks version getters & checkers - * - * @group install */ -class Install_Version_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('install')] +class VersionTest extends PHPUnit\Framework\TestCase { protected $ydb_copy; @@ -26,22 +25,20 @@ public function tearDown(): void { /** * Provide various real-life-ish versions and how they should be sanitized */ - public function versions() { - return array( - array( 'omgmysql-5.5-ubuntu-4.20', '5.5' ), - array( 'mysql5.5-ubuntu-4.20', '5.5' ), - array( '5.5-ubuntu-4.20', '5.5' ), - array( '5.5-beta2', '5.5' ), - array( 'mysql-5.5', '5.5' ), - array( '5.5', '5.5' ), - ); + public static function versions(): \Iterator + { + yield array( 'omgmysql-5.5-ubuntu-4.20', '5.5' ); + yield array( 'mysql5.5-ubuntu-4.20', '5.5' ); + yield array( '5.5-ubuntu-4.20', '5.5' ); + yield array( '5.5-beta2', '5.5' ); + yield array( 'mysql-5.5', '5.5' ); + yield array( '5.5', '5.5' ); } /** * Test mysql version getter & version comparer - * - * @dataProvider versions */ + #[\PHPUnit\Framework\Attributes\DataProvider('versions')] public function test_mysql_version( $version, $sanitized ) { yourls_set_db( new Mock_Version( $version ) ); diff --git a/tests/tests/l10n/domain.php b/tests/tests/l10n/DomainTest.php similarity index 72% rename from tests/tests/l10n/domain.php rename to tests/tests/l10n/DomainTest.php index d2a3faa41..709209ae6 100644 --- a/tests/tests/l10n/domain.php +++ b/tests/tests/l10n/DomainTest.php @@ -3,10 +3,10 @@ /** * Localization domain functions * - * @group l10n * @since 0.1 */ -class Translation_Domain_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('l10n')] +class DomainTest extends PHPUnit\Framework\TestCase { public static function tearDownAfterClass(): void { yourls_unload_textdomain( 'test' ); @@ -29,10 +29,12 @@ public function test_load_default_textdomain() { * @since 0.1 */ public function test_custom_fake_domain() { - $this->expectError(); - $this->expectErrorMessageMatches('/Cannot read file [0-9a-z]+\/[0-9a-z]+-fr_FR\.mo\. Make sure there is a language file installed. More info: http:\/\/yourls\.org\/translations/'); + $this->markTestSkipped( + 'Notice are not checked by PHPUnit anymore. https://github.com/sebastianbergmann/phpunit/issues/5222', + ); + // $this->expectExceptionMessageMatches('/Cannot read file [0-9a-z]+\/[0-9a-z]+-fr_FR\.mo\. Make sure there is a language file installed. More info: http:\/\/yourls\.org\/translations/'); - yourls_load_custom_textdomain( rand_str(), rand_str() ); + // yourls_load_custom_textdomain( rand_str(), rand_str() ); } /** @@ -59,9 +61,9 @@ public function test_load_custom_domain() { /** * Custom domain unloading * - * @depends test_load_custom_domain * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\Depends('test_load_custom_domain')] public function test_custom_domain_unload() { $this->assertTrue( yourls_unload_textdomain( 'test' ) ); $this->assertFalse( yourls_unload_textdomain( 'test' ) ); diff --git a/tests/tests/l10n/general.php b/tests/tests/l10n/GeneralTest.php similarity index 93% rename from tests/tests/l10n/general.php rename to tests/tests/l10n/GeneralTest.php index 74028cee5..93b322faa 100644 --- a/tests/tests/l10n/general.php +++ b/tests/tests/l10n/GeneralTest.php @@ -3,10 +3,10 @@ /** * Localization helper functions * - * @group l10n * @since 0.1 */ -class Translation_General_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('l10n')] +class GeneralTest extends PHPUnit\Framework\TestCase { protected $locale_backup; diff --git a/tests/tests/l10n/formats.php b/tests/tests/l10n/L10nFormatTest.php similarity index 97% rename from tests/tests/l10n/formats.php rename to tests/tests/l10n/L10nFormatTest.php index e457cfa03..fb11bfafa 100644 --- a/tests/tests/l10n/formats.php +++ b/tests/tests/l10n/L10nFormatTest.php @@ -3,10 +3,10 @@ /** * Localization date & calendar & formatting functions * - * @group l10n * @since 0.1 */ -class Translation_Format_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('l10n')] +class L10nFormatTest extends PHPUnit\Framework\TestCase { public function setUp(): void { yourls_load_textdomain( 'default', YOURLS_TESTDATA_DIR . '/pomo/fr_FR.mo' ); diff --git a/tests/tests/l10n/translations.php b/tests/tests/l10n/TranslationTest.php similarity index 98% rename from tests/tests/l10n/translations.php rename to tests/tests/l10n/TranslationTest.php index 545a0587e..59e7632c1 100644 --- a/tests/tests/l10n/translations.php +++ b/tests/tests/l10n/TranslationTest.php @@ -3,10 +3,10 @@ /** * Localization functions : helper functions * - * @group l10n * @since 0.1 */ -class Translation_Translation_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('l10n')] +class TranslationTest extends PHPUnit\Framework\TestCase { public static function setUpBeforeClass(): void { yourls_load_textdomain( 'test', YOURLS_TESTDATA_DIR . '/pomo/test-fr_FR.mo' ); diff --git a/tests/tests/links/yourls_links.php b/tests/tests/links/LinkTest.php similarity index 77% rename from tests/tests/links/yourls_links.php rename to tests/tests/links/LinkTest.php index 4bb8e695a..6ccecd78a 100644 --- a/tests/tests/links/yourls_links.php +++ b/tests/tests/links/LinkTest.php @@ -2,12 +2,10 @@ /** * Links - * - * @group links - * @group idn */ - -class YOURLS_Link_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('links')] +#[\PHPUnit\Framework\Attributes\Group('idn')] +class LinkTest extends PHPUnit\Framework\TestCase { protected function tearDown(): void { yourls_remove_all_filters( 'get_yourls_site' ); @@ -42,8 +40,8 @@ public function test_yourls_statlink() { */ public function test_yourls_link_IDN() { yourls_add_filter( 'get_yourls_site', function() {return 'http://xn--hh-bjab.com';} ); - $this->assertEquals( yourls_link('suicidal'), 'http://héhé.com/suicidal' ); - $this->assertEquals( yourls_statlink('angels'), 'http://héhé.com/angels+' ); + $this->assertEquals( 'http://héhé.com/suicidal', yourls_link('suicidal') ); + $this->assertEquals( 'http://héhé.com/angels+', yourls_statlink('angels') ); } } diff --git a/tests/tests/options.php b/tests/tests/options.php deleted file mode 100644 index 7244aef96..000000000 --- a/tests/tests/options.php +++ /dev/null @@ -1,136 +0,0 @@ -assertFalse( yourls_get_option( 'doesnotexist' ) ); - $this->assertTrue( yourls_add_option( $key, $value ) ); - $this->assertEquals( $value, yourls_get_option( $key ) ); - $this->assertFalse( yourls_add_option( $key, $value ) ); // Already exists - $this->assertFalse( yourls_update_option( $key, $value ) ); // Value is the same - $this->assertTrue( yourls_update_option( $key, $value2 ) ); - $this->assertEquals( $value2, yourls_get_option( $key ) ); - - $this->assertFalse( yourls_add_option( $key, $value ) ); - $this->assertEquals( $value2, yourls_get_option( $key ) ); - $this->assertTrue( yourls_delete_option( $key ) ); - $this->assertFalse( yourls_get_option( $key ) ); - $this->assertFalse( yourls_delete_option( $key ) ); - - $this->assertTrue( yourls_update_option( $key2, $value2 ) ); - $this->assertEquals( $value2, yourls_get_option( $key2 ) ); - $this->assertTrue( yourls_delete_option( $key2 ) ); - $this->assertFalse( yourls_get_option( $key2 ) ); - } - - /** - * Check with array and objects - * - * @since 0.1 - */ - public function test_serialized_data() { - $key = rand_str(); - $value = array( 'foo' => true, 'bar' => true ); - - $this->assertTrue( yourls_add_option( $key, $value ) ); - $this->assertEquals( $value, yourls_get_option( $key ) ); - - $value = (object) $value; - $this->assertTrue( yourls_update_option( $key, $value ) ); - $this->assertEquals( $value, yourls_get_option( $key ) ); - $this->assertTrue( yourls_delete_option( $key ) ); - } - - /** - * Data provider of bad option names - */ - public function bad_option_names() { - return array( - array( '' ), - array( '0' ), - array( ' ' ), - array( 0 ), - array( false ), - array( null ), - ); - } - - /** - * Check with bad option names - * - * @dataProvider bad_option_names - * @since 0.1 - */ - public function test_bad_option_names($empty) { - $this->assertFalse( yourls_get_option( $empty ) ); - $this->assertFalse( yourls_add_option( $empty, '' ) ); - $this->assertFalse( yourls_update_option( $empty, '' ) ); - $this->assertFalse( yourls_delete_option( $empty ) ); - } - - function setUp(): void { - parent::setUp(); - $this->slash_1 = 'String with 1 slash \\'; - $this->slash_2 = 'String with 2 slashes \\\\'; - $this->slash_3 = 'String with 3 slashes \\\\\\'; - $this->slash_4 = 'String with 4 slashes \\\\\\\\'; - $this->slash_5 = 'String with 5 slashes \\\\\\\\\\'; - $this->slash_6 = 'String with 6 slashes \\\\\\\\\\\\'; - $this->slash_7 = 'String with 7 slashes \\\\\\\\\\\\\\'; - } - - /** - * Tests the model function that expects un-slashed data - * - * @since 0.1 - */ - function test_add_option() { - yourls_add_option( 'slash_test_1', $this->slash_1 ); - yourls_add_option( 'slash_test_2', $this->slash_2 ); - yourls_add_option( 'slash_test_3', $this->slash_3 ); - yourls_add_option( 'slash_test_4', $this->slash_4 ); - - $this->assertEquals( $this->slash_1, yourls_get_option( 'slash_test_1' ) ); - $this->assertEquals( $this->slash_2, yourls_get_option( 'slash_test_2' ) ); - $this->assertEquals( $this->slash_3, yourls_get_option( 'slash_test_3' ) ); - $this->assertEquals( $this->slash_4, yourls_get_option( 'slash_test_4' ) ); - } - - /** - * Tests the model function that expects un-slashed data - * - * @since 0.1 - */ - function test_update_option() { - yourls_add_option( 'slash_test_5', 'foo' ); - - yourls_update_option( 'slash_test_5', $this->slash_1 ); - $this->assertEquals( $this->slash_1, yourls_get_option( 'slash_test_5' ) ); - - yourls_update_option( 'slash_test_5', $this->slash_2 ); - $this->assertEquals( $this->slash_2, yourls_get_option( 'slash_test_5' ) ); - - yourls_update_option( 'slash_test_5', $this->slash_3 ); - $this->assertEquals( $this->slash_3, yourls_get_option( 'slash_test_5' ) ); - - yourls_update_option( 'slash_test_5', $this->slash_4 ); - $this->assertEquals( $this->slash_4, yourls_get_option( 'slash_test_5' ) ); - } -} diff --git a/tests/tests/pages/pages.php b/tests/tests/pages/PagesTest.php similarity index 88% rename from tests/tests/pages/pages.php rename to tests/tests/pages/PagesTest.php index 54f200502..2c19333b3 100644 --- a/tests/tests/pages/pages.php +++ b/tests/tests/pages/PagesTest.php @@ -2,11 +2,9 @@ /** * Pages - * - * @group pages */ - -class Pages_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('pages')] +class PagesTest extends PHPUnit\Framework\TestCase { public function test_page_is_reserved() { $this->assertTrue( yourls_keyword_is_reserved('examplepage') ); diff --git a/tests/tests/plugins/actions.php b/tests/tests/plugins/ActionsTest.php similarity index 80% rename from tests/tests/plugins/actions.php rename to tests/tests/plugins/ActionsTest.php index efa13af56..36e3af718 100644 --- a/tests/tests/plugins/actions.php +++ b/tests/tests/plugins/ActionsTest.php @@ -3,20 +3,19 @@ /** * Action related tests * - * @group plugins * @since 0.1 */ +#[\PHPUnit\Framework\Attributes\Group('plugins')] +class ActionsTest extends PHPUnit\Framework\TestCase { -class Plugin_Actions_Tests extends PHPUnit\Framework\TestCase { - - /** - * Check adding an action with a simple function name + /** + * Check adding an action with a simple function name * * Syntax tested: yourls_add_action( $hook, 'func_name' ); - * - * @since 0.1 - */ - public function test_add_action_funcname() { + * + * @since 0.1 + */ + public function test_add_action_funcname() { // Random function name $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); @@ -30,7 +29,7 @@ public function test_add_action_funcname() { $this->assertTrue( yourls_has_action( $hook ) ); return $hook; - } + } /** * Remove an action @@ -65,7 +64,7 @@ public function test_add_several_actions_default_priority() { $this->assertTrue( yourls_has_action( $hook ) ); global $yourls_filters; - $this->assertSame( $times, count( $yourls_filters[ $hook ][10] ) ); + $this->assertCount( $times, $yourls_filters[ $hook ][10] ); } /** @@ -173,13 +172,13 @@ public function test_remove_only_actions_with_given_prio() { $this->assertSame( $remaining, $times - $removed ); } - /** - * Check 'doing' an action hooked with a simple function name - * - * @depends test_add_action_funcname - * @since 0.1 - */ - public function test_do_action_funcname( $hook ) { + /** + * Check 'doing' an action hooked with a simple function name + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_action_funcname')] + public function test_do_action_funcname( $hook ) { $var_name = rand_str(); $var_value = rand_str(); $GLOBALS['test_var'] = $var_name; @@ -192,14 +191,14 @@ public function test_do_action_funcname( $hook ) { $this->assertNotSame( $var_value, $GLOBALS[ $var_name ] ); return $hook; - } - - /** - * Check we keep correct track of the number of time an action is done - * - * @since 0.1 - */ - public function test_do_action_several_times_and_count() { + } + + /** + * Check we keep correct track of the number of time an action is done + * + * @since 0.1 + */ + public function test_do_action_several_times_and_count() { $hook = rand_str(); $this->assertSame( 0, yourls_did_action( $hook ) ); @@ -209,17 +208,17 @@ public function test_do_action_several_times_and_count() { } $this->assertSame( $times, yourls_did_action( $hook ) ); - } + } - /** - * Check adding an action with an anonymous function using create_function() + /** + * Check adding an action with an anonymous function using create_function() * * Syntax tested: yourls_add_action( $hook, create_function() ); - * - * @since 0.1 - */ - public function test_add_action_create_function() { + * + * @since 0.1 + */ + public function test_add_action_create_function() { $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); yourls_add_action( $hook, function() { @@ -228,15 +227,15 @@ public function test_add_action_create_function() { $this->assertTrue( yourls_has_action( $hook ) ); return $hook; - } - - /** - * Check 'doing' an action hooked with an anonymous function using create_function() - * - * @depends test_add_action_create_function - * @since 0.1 - */ - public function test_do_action_create_function( $hook ) { + } + + /** + * Check 'doing' an action hooked with an anonymous function using create_function() + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_action_create_function')] + public function test_do_action_create_function( $hook ) { $var_name = rand_str(); $var_value = rand_str(); $GLOBALS['test_var'] = $var_name; @@ -249,32 +248,32 @@ public function test_do_action_create_function( $hook ) { $this->assertNotSame( $var_value, $GLOBALS[ $var_name ] ); return $hook; - } + } - /** - * Check adding an action with function within class + /** + * Check adding an action with function within class * * Syntax tested: yourls_add_action( $hook, 'Class::Function' ); - * - * @since 0.1 - */ - public function test_add_action_within_class() { + * + * @since 0.1 + */ + public function test_add_action_within_class() { $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); yourls_add_action( $hook, 'Change_One_Global::change_it' ); $this->assertTrue( yourls_has_action( $hook ) ); return $hook; - } - - /** - * Check 'doing' an action hooked with function within class - * - * @depends test_add_action_within_class - * @since 0.1 - */ - public function test_do_action_within_class( $hook ) { + } + + /** + * Check 'doing' an action hooked with function within class + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_action_within_class')] + public function test_do_action_within_class( $hook ) { $var_name = rand_str(); $var_value = rand_str(); $GLOBALS['test_var'] = $var_name; @@ -287,32 +286,32 @@ public function test_do_action_within_class( $hook ) { $this->assertNotSame( $var_value, $GLOBALS[ $var_name ] ); return $hook; - } + } - /** - * Check adding an action with function within class using an array + /** + * Check adding an action with function within class using an array * * Syntax tested: yourls_add_action( $hook, array( 'Class', 'Function' ) ); - * - * @since 0.1 - */ - public function test_add_action_within_class_array() { + * + * @since 0.1 + */ + public function test_add_action_within_class_array() { $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); yourls_add_action( $hook, array( 'Change_One_Global', 'change_it' ) ); $this->assertTrue( yourls_has_action( $hook ) ); return $hook; - } - - /** - * Check 'doing' an action hooked with function within class - * - * @depends test_add_action_within_class_array - * @since 0.1 - */ - public function test_do_action_within_class_array( $hook ) { + } + + /** + * Check 'doing' an action hooked with function within class + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_action_within_class_array')] + public function test_do_action_within_class_array( $hook ) { $var_name = rand_str(); $var_value = rand_str(); $GLOBALS['test_var'] = $var_name; @@ -325,32 +324,32 @@ public function test_do_action_within_class_array( $hook ) { $this->assertNotSame( $var_value, $GLOBALS[ $var_name ] ); return $hook; - } + } - /** - * Check adding an action with function within class instance + /** + * Check adding an action with function within class instance * * Syntax tested: yourls_add_action( $hook, array( $class, 'function' ) ); - * - * @since 0.1 - */ - public function test_add_action_within_class_instance() { + * + * @since 0.1 + */ + public function test_add_action_within_class_instance() { $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); yourls_add_action( $hook, array( $this, 'change_one_global' ) ); $this->assertTrue( yourls_has_action( $hook ) ); return $hook; - } - - /** - * Check 'doing' an action hooked with function within class instance - * - * @depends test_add_action_within_class_instance - * @since 0.1 - */ - public function test_do_action_within_class_instance( $hook ) { + } + + /** + * Check 'doing' an action hooked with function within class instance + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_action_within_class_instance')] + public function test_do_action_within_class_instance( $hook ) { $var_name = rand_str(); $var_value = rand_str(); $GLOBALS['test_var'] = $var_name; @@ -363,15 +362,15 @@ public function test_do_action_within_class_instance( $hook ) { $this->assertNotSame( $var_value, $GLOBALS[ $var_name ] ); return $hook; - } + } - /** - * Check that hooking to 'Class::Method' or array( 'Class', 'Method') is the same + /** + * Check that hooking to 'Class::Method' or array( 'Class', 'Method') is the same * - * @since 0.1 - */ - public function test_add_action_class_and_array() { + * @since 0.1 + */ + public function test_add_action_class_and_array() { $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); @@ -379,32 +378,32 @@ public function test_add_action_class_and_array() { yourls_add_action( $hook, array( 'Class', 'Method' ) ); $this->assertSame( 10, yourls_has_action( $hook, array( 'Class', 'Method' ) ) ); $this->assertSame( 10, yourls_has_action( $hook, 'Class::Method' ) ); - } + } - /** - * Check adding an action with anonymous function using closure + /** + * Check adding an action with anonymous function using closure * * Syntax tested: yourls_add_action( $hook, function(){ // do stuff } ); - * - * @since 0.1 - */ - public function test_add_action_closure() { + * + * @since 0.1 + */ + public function test_add_action_closure() { $hook = rand_str(); $this->assertFalse( yourls_has_action( $hook ) ); yourls_add_action( $hook, function() { $var_name = $GLOBALS['test_var']; $GLOBALS[ $var_name ] = rand_str(); } ); $this->assertTrue( yourls_has_action( $hook ) ); return $hook; - } - - /** - * Check 'doing' an action hooked with anonymous function using closure - * - * @depends test_add_action_closure - * @since 0.1 - */ - public function test_do_action_closure( $hook ) { + } + + /** + * Check 'doing' an action hooked with anonymous function using closure + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_action_closure')] + public function test_do_action_closure( $hook ) { $var_name = rand_str(); $var_value = rand_str(); $GLOBALS['test_var'] = $var_name; @@ -417,7 +416,7 @@ public function test_do_action_closure( $hook ) { $this->assertNotSame( $var_value, $GLOBALS[ $var_name ] ); return $hook; - } + } /** * Check that applied function must exist @@ -508,8 +507,8 @@ public function test_get_actions() { yourls_add_action( $hook, 'some_other_function', 1337 ); $actions = yourls_get_actions( $hook ); - $this->assertTrue(isset($actions[10]['some_function'])); - $this->assertTrue(isset($actions[1337]['some_other_function'])); + $this->assertArrayHasKey('some_function', $actions[10]); + $this->assertArrayHasKey('some_other_function', $actions[1337]); $this->assertSame( [], yourls_get_actions( rand_str() ) ); } diff --git a/tests/tests/plugins/FilesTest.php b/tests/tests/plugins/FilesTest.php new file mode 100644 index 000000000..c268b994d --- /dev/null +++ b/tests/tests/plugins/FilesTest.php @@ -0,0 +1,190 @@ +set_plugins( array() ); + } + + /** + * Return array of files from tests/data/plugins/invalid-code + */ + public static function get_invalid_code_plugins() { + $plugins = array(); + foreach ( glob(YOURLS_PLUGINDIR . '/invalid-code/*.php') as $file ) { + $plugins[] = array($file); + } + return $plugins; + } + + /** + * Return one of the "valid" test plugins from tests/data/plugins + */ + public function pick_a_plugin() { + $plugins = array_keys( yourls_get_plugins() ); + $plugin = $plugins[ array_rand( $plugins ) ]; + return $plugin; + } + + /** + * Check that only 2 "valid" plugins are found in tests/data/plugins + */ + public function test_get_plugins() { + $plugins = array_keys( yourls_get_plugins() ); + $expected = [ + '0' => 'test-plugin/plugin.php', + '1' => 'test-plugin2/plugin.php', + ]; + $this->assertSame($expected, $plugins); + } + + /** + * Check that a random "valid" plugin file validates as a plugin file + */ + public function test_plugin_validate() { + $plugin = $this->pick_a_plugin(); + $this->assertTrue( yourls_is_a_plugin_file(YOURLS_PLUGINDIR . '/' . $plugin ) ); + } + + /** + * Check that a nonexistent plugin file does not validate as a plugin file + */ + public function test_missing_plugin_validate() { + $plugin = rand_str(); + $this->assertFalse( yourls_is_a_plugin_file(YOURLS_PLUGINDIR . '/' . $plugin ) ); + } + + /** + * Check that an invalid plugin file does not validate as a plugin file + */ + #[\PHPUnit\Framework\Attributes\DataProvider('get_invalid_code_plugins')] + public function test_invalid_plugin_validate($plugin) { + $this->assertFalse( yourls_is_a_plugin_file($plugin) ); + } + + /** + * Check that a random valid plugin activates correctly + */ + public function test_plugin_activate() { + $plugin = $this->pick_a_plugin(); + + // Make sure the plugin.php is NOT present in get_included_files() + // We sanitize the array to deal with different platforms (D:\hello\Windows vs /home/user/hello/Linux) + $this->assertNotContains(yourls_sanitize_filename(YOURLS_PLUGINDIR.'/'.$plugin), array_map('yourls_sanitize_filename', get_included_files())); + + // Activate the plugin + $this->assertTrue( yourls_activate_plugin( $plugin ) ); + $this->assertGreaterThan( 0, yourls_has_active_plugins() ); + $this->assertTrue( yourls_is_active_plugin( $plugin ) ); + + // Make sure the plugin.php is now present in get_included_files() + $included_files = array_map('yourls_sanitize_filename', get_included_files()) ; + $this->assertContains(yourls_sanitize_filename(YOURLS_PLUGINDIR.'/'.$plugin), $included_files); + + // Make sure the plugin's uninstall.php is NOT present in get_included_files() + $this->assertNotContains(yourls_sanitize_filename(YOURLS_PLUGINDIR.'/'.dirname($plugin).'/uninstall.php'), $included_files); + + // We should NOT have YOURLS_UNINSTALL_PLUGIN defined + $this->assertFalse(defined('YOURLS_UNINSTALL_PLUGIN')); + + return $plugin; + } + + /** + * Check that an active plugin does not activate + */ + #[\PHPUnit\Framework\Attributes\Depends('test_plugin_activate')] + public function test_plugin_activate_twice( $plugin ) { + $this->assertSame( yourls__( 'Plugin already activated' ), yourls_activate_plugin( $plugin ) ); + } + + /** + * Simulate initial plugin loading + */ + #[\PHPUnit\Framework\Attributes\Depends('test_plugin_activate')] + public function test_load_plugins( $plugin ) { + $ydb = yourls_get_db(); + + // at this point, we have exactly 1 plugin activated + $this->assertSame( $ydb->get_plugins(), array( $plugin ) ); + + // Register a nonexistent plugin to simulate one that was once activated but deleted since + $fake_plugin = rand_str() . '/plugin.php'; + $ydb->add_plugin($fake_plugin); + + // Register a broken code plugin to simulate one that was once activated but now is broken + $broken_plugin = $this->get_invalid_code_plugins()[ array_rand( $this->get_invalid_code_plugins() ) ][0]; + $ydb->add_plugin($broken_plugin); + + yourls_update_option( 'active_plugins', $ydb->get_plugins() ); + + // Check we have 1 activated and 2 removed + $load = yourls_load_plugins(); + $this->assertTrue( $load['loaded'] ); + $this->assertSame( '1 activated, 2 removed', $load['info'] ); + + // Check only our valid plugin is left registered + $this->assertSame( $ydb->get_plugins(), array( $plugin ) ); + $this->assertSame( 1, yourls_has_active_plugins() ); + } + + /** + * Check that valid plugin deactivates correctly + */ + #[\PHPUnit\Framework\Attributes\Depends('test_plugin_activate')] + public function test_plugin_deactivate( $plugin ) { + $this->assertTrue( yourls_deactivate_plugin($plugin) ); + $this->assertSame( 0, yourls_has_active_plugins() ); + $this->assertFalse( yourls_is_active_plugin($plugin) ); + return $plugin; + } + + /** + * Check that deactivating a plugin correctly ran the uninstall script + */ + #[\PHPUnit\Framework\Attributes\Depends('test_plugin_deactivate')] + public function test_plugin_uninstall( $plugin ) { + // Make sure uninstall.php is NOW present in get_included_files() + $this->assertContains(yourls_sanitize_filename(YOURLS_PLUGINDIR . '/' . dirname($plugin) . '/uninstall.php'), array_map('yourls_sanitize_filename', get_included_files())); + + // we should now have YOURLS_UNINSTALL_PLUGIN set to true + $this->assertTrue( defined('YOURLS_UNINSTALL_PLUGIN') && YOURLS_UNINSTALL_PLUGIN ); + } + + /** + * Check that an missing plugin does not activate + */ + public function test_invalid_plugin_activate() { + $plugin = rand_str(); + + $this->assertSame( yourls__( 'Not a valid plugin file' ), yourls_activate_plugin( $plugin ) ); + $this->assertFalse( yourls_is_active_plugin( $plugin ) ); + } + + /** + * Check that a missing plugin does not deactivate + */ + public function test_invalid_plugin_deactivate() { + $plugin = rand_str(); + + $this->assertFalse( yourls_is_active_plugin( $plugin ) ); + $this->assertSame( yourls__( 'Plugin not active' ), yourls_deactivate_plugin( $plugin ) ); + } + + /** + * Check that a plugin with invalid code does not activate + */ + #[\PHPUnit\Framework\Attributes\DataProvider('get_invalid_code_plugins')] + public function test_invalid_plugin_does_not_activate($plugin) { + $this->assertNotTrue( yourls_include_file_sandbox( $plugin ) ); + $this->assertNotTrue( yourls_activate_plugin( $plugin ) ); + $this->assertNotTrue( yourls_is_active_plugin( $plugin ) ); + } +} diff --git a/tests/tests/plugins/filters.php b/tests/tests/plugins/FiltersTest.php similarity index 76% rename from tests/tests/plugins/filters.php rename to tests/tests/plugins/FiltersTest.php index fa44c0382..c145a55c2 100644 --- a/tests/tests/plugins/filters.php +++ b/tests/tests/plugins/FiltersTest.php @@ -3,25 +3,24 @@ /** * Filter related tests * - * @group plugins * @since 0.1 */ - -class Plugin_Filters_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('plugins')] +class FiltersTest extends PHPUnit\Framework\TestCase { /** * this var will allow to share "$this" across multiple tests here */ public static $instance; - /** - * Check adding a filter with a simple function name + /** + * Check adding a filter with a simple function name * * Syntax tested: yourls_add_filter( $hook, 'func_name' ); - * - * @since 0.1 - */ - public function test_add_filter_funcname() { + * + * @since 0.1 + */ + public function test_add_filter_funcname() { // Random function name $hook = rand_str(); $this->assertFalse( yourls_has_filter( $hook ) ); @@ -35,20 +34,20 @@ public function test_add_filter_funcname() { $this->assertTrue( yourls_has_filter( $hook ) ); return $hook; - } - - /** - * Check applying a filter hooked with a simple function name - * - * @depends test_add_filter_funcname - * @since 0.1 - */ - public function test_apply_filter_funcname( $hook ) { + } + + /** + * Check applying a filter hooked with a simple function name + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_funcname')] + public function test_apply_filter_funcname( $hook ) { $var = rand_str(); $filtered = yourls_apply_filter( $hook, $var ); $this->assertNotSame( $var, $filtered ); - } + } /** @@ -109,14 +108,14 @@ public function test_remove_filter_priority() { } - /** - * Check adding a filter with an anonymous function using create_function() + /** + * Check adding a filter with an anonymous function using create_function() * * Syntax tested: yourls_add_filter( $hook, create_function() ); - * - * @since 0.1 - */ - public function test_add_filter_create_function() { + * + * @since 0.1 + */ + public function test_add_filter_create_function() { $hook = rand_str(); $this->assertFalse( yourls_has_filter( $hook ) ); yourls_add_filter( $hook, function() { @@ -125,57 +124,57 @@ public function test_add_filter_create_function() { $this->assertTrue( yourls_has_filter( $hook ) ); return $hook; - } - - /** - * Check applying a filter hooked with an anonymous function using create_function() - * - * @depends test_add_filter_create_function - * @since 0.1 - */ - public function test_apply_filter_create_function( $hook ) { + } + + /** + * Check applying a filter hooked with an anonymous function using create_function() + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_create_function')] + public function test_apply_filter_create_function( $hook ) { $var = rand_str(); $filtered = yourls_apply_filter( $hook, $var ); $this->assertNotSame( $var, $filtered ); - } + } - /** - * Check adding a filter with function within class + /** + * Check adding a filter with function within class * * Syntax tested: yourls_add_filter( $hook, 'Class::Function' ); - * - * @since 0.1 - */ - public function test_add_filter_within_class() { + * + * @since 0.1 + */ + public function test_add_filter_within_class() { $hook = rand_str(); $this->assertFalse( yourls_has_filter( $hook ) ); yourls_add_filter( $hook, 'Change_Variable::change_it' ); $this->assertTrue( yourls_has_filter( $hook ) ); return $hook; - } - - /** - * Check applying a filter hooked with function within class - * - * @depends test_add_filter_within_class - * @since 0.1 - */ - public function test_apply_filter_within_class( $hook ) { + } + + /** + * Check applying a filter hooked with function within class + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_within_class')] + public function test_apply_filter_within_class( $hook ) { $var = rand_str(); $filtered = yourls_apply_filter( $hook, $var ); $this->assertNotSame( $var, $filtered ); - } + } /** * Check removing a filter hooked with function within class * - * @depends test_add_filter_within_class * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_within_class')] public function test_remove_filter_within_class( $hook ) { $removed = yourls_remove_filter( $hook, 'Change_Variable::change_it' ); $this->assertTrue( $removed ); @@ -183,40 +182,40 @@ public function test_remove_filter_within_class( $hook ) { } - /** - * Check adding filter with function within class using an array + /** + * Check adding filter with function within class using an array * * Syntax tested: yourls_add_filter( $hook, array( 'Class', 'Function' ) ); - * - * @since 0.1 - */ - public function test_add_filter_within_class_array() { + * + * @since 0.1 + */ + public function test_add_filter_within_class_array() { $hook = rand_str(); $this->assertFalse( yourls_has_filter( $hook ) ); yourls_add_filter( $hook, array( 'Change_Variable', 'change_it' ) ); $this->assertTrue( yourls_has_filter( $hook ) ); return $hook; - } - - /** - * Check applying a filter hooked with function within class - * - * @depends test_add_filter_within_class_array - * @since 0.1 - */ - public function test_apply_filter_within_class_array( $hook ) { + } + + /** + * Check applying a filter hooked with function within class + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_within_class_array')] + public function test_apply_filter_within_class_array( $hook ) { $var = rand_str(); $filtered = yourls_apply_filter( $hook, $var ); $this->assertNotSame( $var, $filtered ); - } + } /** * Check removing a filter hooked with function within class using an array * - * @depends test_add_filter_within_class_array * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_within_class_array')] public function test_remove_filter_within_class_array( $hook ) { $removed = yourls_remove_filter( $hook, array( 'Change_Variable', 'change_it' ) ); $this->assertTrue( $removed ); @@ -224,14 +223,14 @@ public function test_remove_filter_within_class_array( $hook ) { } - /** - * Check adding a filter with function within class instance + /** + * Check adding a filter with function within class instance * * Syntax tested: yourls_add_filter( $hook, array( $class, 'function' ) ); - * - * @since 0.1 - */ - public function test_add_filter_within_class_instance() { + * + * @since 0.1 + */ + public function test_add_filter_within_class_instance() { /* Note : in the unit tests context, we cannot rely on "$this" keeping the same * between tests, whereas it totally works in a "normal" class context * For this reason, using yourls_add_filter($hook, array($this, 'some_func')) in one test and @@ -245,26 +244,26 @@ public function test_add_filter_within_class_instance() { $this->assertTrue( yourls_has_filter( $hook ) ); return $hook; - } - - /** - * Check applying a filter hooked with function within class instance - * - * @depends test_add_filter_within_class_instance - * @since 0.1 - */ - public function test_apply_filter_within_class_instance( $hook ) { + } + + /** + * Check applying a filter hooked with function within class instance + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_within_class_instance')] + public function test_apply_filter_within_class_instance( $hook ) { $var = rand_str(); $filtered = yourls_apply_filter( $hook, $var ); $this->assertNotSame( $var, $filtered ); - } + } /** * Check removing a filter hooked with function within class * - * @depends test_add_filter_within_class_instance * @since 0.1 */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_within_class_instance')] public function test_remove_filter_within_class_instance( $hook ) { $this->assertTrue( yourls_has_filter( $hook ) ); $removed = yourls_remove_filter( $hook, array( self::$instance, 'change_variable' ) ); @@ -272,12 +271,12 @@ public function test_remove_filter_within_class_instance( $hook ) { $this->assertFalse( yourls_has_filter( $hook ) ); } - /** - * Check that hooking to 'Class::Method' or array( 'Class', 'Method') is the same + /** + * Check that hooking to 'Class::Method' or array( 'Class', 'Method') is the same * - * @since 0.1 - */ - public function test_add_filter_class_and_array() { + * @since 0.1 + */ + public function test_add_filter_class_and_array() { $hook = rand_str(); $this->assertFalse( yourls_has_filter( $hook ) ); @@ -285,44 +284,44 @@ public function test_add_filter_class_and_array() { yourls_add_filter( $hook, array( 'Class', 'Method' ) ); $this->assertSame( 10, yourls_has_filter( $hook, array( 'Class', 'Method' ) ) ); $this->assertSame( 10, yourls_has_filter( $hook, 'Class::Method' ) ); - } + } - /** - * Check adding a filter with anonymous function using closure + /** + * Check adding a filter with anonymous function using closure * * Syntax tested: yourls_add_filter( $hook, function(){ // do stuff } ); - * - * @since 0.1 - */ - public function test_add_filter_closure() { + * + * @since 0.1 + */ + public function test_add_filter_closure() { $hook = rand_str(); $this->assertFalse( yourls_has_filter( $hook ) ); yourls_add_filter( $hook, function() { return rand_str(); } ); $this->assertTrue( yourls_has_filter( $hook ) ); return $hook; - } - - /** - * Check applying a filter hooked with anonymous function using closure - * - * @depends test_add_filter_closure - * @since 0.1 - */ - public function test_apply_filter_closure( $hook ) { + } + + /** + * Check applying a filter hooked with anonymous function using closure + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_filter_closure')] + public function test_apply_filter_closure( $hook ) { $var = rand_str(); $filtered = yourls_apply_filter( $hook, $var ); $this->assertNotSame( $var, $filtered ); - } - - /** - * Check applying multiple filters to one hook - * - * @since 0.1 - */ - public function test_multiple_filter() { + } + + /** + * Check applying multiple filters to one hook + * + * @since 0.1 + */ + public function test_multiple_filter() { $hook = rand_str(); $var = rand_str(); @@ -331,7 +330,7 @@ public function test_multiple_filter() { $filtered = yourls_apply_filter( $hook, $var ); $this->assertSame( $var . "1" . "2", $filtered ); - } + } /** * Check applying multiple filters with priorities to one hook @@ -385,8 +384,8 @@ public function test_get_filters() { yourls_add_filter( $hook, 'some_other_function', 1337 ); $filters = yourls_get_filters( $hook ); - $this->assertTrue(isset($filters[10]['some_function'])); - $this->assertTrue(isset($filters[1337]['some_other_function'])); + $this->assertArrayHasKey('some_function', $filters[10]); + $this->assertArrayHasKey('some_other_function', $filters[1337]); $this->assertSame( [], yourls_get_filters( rand_str() ) ); } @@ -420,27 +419,27 @@ public function test_filter_specified_arguments() { $hook = rand_str(); yourls_add_filter( $hook, function( $var1 = '', $var2 = '' ) { return "$var1 $var2"; }, 10, 2 ); $test = yourls_apply_filter( $hook, 'hello', 'world' ); - $this->assertSame( $test, 'hello world' ); + $this->assertSame( 'hello world', $test ); // Ask for 1 argument and provide 2 $hook = rand_str(); yourls_add_filter( $hook, function( $var1 = '', $var2 = '' ) { return "$var1 $var2"; }, 10, 1 ); $test = yourls_apply_filter( $hook, 'hello', 'world' ); - $this->assertSame( $test, 'hello ' ); + $this->assertSame( 'hello ', $test ); // Ask for 2 arguments and provide 1 $hook = rand_str(); yourls_add_filter( $hook, function( $var1 = '', $var2 = '' ) { return "$var1 $var2"; }, 10, 2 ); $test = yourls_apply_filter( $hook, 'hello' ); - $this->assertSame( $test, 'hello ' ); + $this->assertSame( 'hello ', $test ); } - /** - * Make sure yourls_apply_filter accepts an arbitrary number of elements if unspecified - * - * @since 0.1 - */ - public function test_filter_arbitrary_arguments() { + /** + * Make sure yourls_apply_filter accepts an arbitrary number of elements if unspecified + * + * @since 0.1 + */ + public function test_filter_arbitrary_arguments() { $hook = rand_str(); $var1 = rand_str(); $var2 = rand_str(); diff --git a/tests/tests/plugins/headers.php b/tests/tests/plugins/HeadersTest.php similarity index 71% rename from tests/tests/plugins/headers.php rename to tests/tests/plugins/HeadersTest.php index 20fcda5dc..7327340bd 100644 --- a/tests/tests/plugins/headers.php +++ b/tests/tests/plugins/HeadersTest.php @@ -3,15 +3,15 @@ /** * Header plugin functions * - * @group plugins * @since 0.1 */ -class Plugin_Header_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('plugins')] +class HeadersTest extends PHPUnit\Framework\TestCase { /** - * Regular header - */ - public function test_regular_header() { + * Regular header + */ + public function test_regular_header() { $expected = array( 'Plugin Name' => 'regular', 'Plugin URI' => 'regular', @@ -24,9 +24,9 @@ public function test_regular_header() { } /** - * PHPDoc header - */ - public function test_phpdoc_header() { + * PHPDoc header + */ + public function test_phpdoc_header() { $expected = array( 'Plugin Name' => 'phpdoc', 'Description' => 'phpdoc', @@ -39,9 +39,9 @@ public function test_phpdoc_header() { } /** - * Incomplete header - */ - public function test_incomplete_header() { + * Incomplete header + */ + public function test_incomplete_header() { $expected = array( 'Plugin Name' => 'incomplete', 'Description' => 'incomplete', @@ -51,23 +51,23 @@ public function test_incomplete_header() { } /** - * Incorrect header - */ - public function test_incorrect_header() { + * Incorrect header + */ + public function test_incorrect_header() { $this->assertEquals( [] , yourls_get_plugin_data( YOURLS_PLUGINDIR . '/headers/header_incorrect.php' ) ); } /** - * Missing header - */ - public function test_missing_header() { + * Missing header + */ + public function test_missing_header() { $this->assertEquals( [] , yourls_get_plugin_data( YOURLS_PLUGINDIR . '/headers/header_missing.php' ) ); } /** - * Missing header - no comment at all - */ - public function test_missing_header_no_comment() { + * Missing header - no comment at all + */ + public function test_missing_header_no_comment() { $this->assertEquals( [] , yourls_get_plugin_data( YOURLS_PLUGINDIR . '/headers/header_nocomment.php' ) ); } diff --git a/tests/tests/plugins/helpers.php b/tests/tests/plugins/HelpersTest.php similarity index 64% rename from tests/tests/plugins/helpers.php rename to tests/tests/plugins/HelpersTest.php index d954c0cec..e19df3f34 100644 --- a/tests/tests/plugins/helpers.php +++ b/tests/tests/plugins/HelpersTest.php @@ -2,30 +2,27 @@ /** * Misc helper functions - * - * @group plugins */ -class Plugin_Helpers_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('plugins')] +class HelpersTest extends PHPUnit\Framework\TestCase { /** * Return values for yourls_return_something() */ - public function helpers() { - return array( - array( true , 'yourls_return_true' ), - array( false, 'yourls_return_false' ), - array( 0 , 'yourls_return_zero' ), - array( [] , 'yourls_return_empty_array' ), - array( null , 'yourls_return_null' ), - array( '' , 'yourls_return_empty_string' ), - ); + public static function helpers(): \Iterator + { + yield array( true , 'yourls_return_true' ); + yield array( false, 'yourls_return_false' ); + yield array( 0 , 'yourls_return_zero' ); + yield array( [] , 'yourls_return_empty_array' ); + yield array( null , 'yourls_return_null' ); + yield array( '' , 'yourls_return_empty_string' ); } /** * Check return values of yourls_return_something() - * - * @dataProvider helpers */ + #[\PHPUnit\Framework\Attributes\DataProvider('helpers')] public function test_check_timestamp( $value, $func ) { $this->assertSame( $value, call_user_func($func) ); } diff --git a/tests/tests/plugins/pages.php b/tests/tests/plugins/PluginPagesTest.php similarity index 95% rename from tests/tests/plugins/pages.php rename to tests/tests/plugins/PluginPagesTest.php index ef6657f49..2cb128b67 100644 --- a/tests/tests/plugins/pages.php +++ b/tests/tests/plugins/PluginPagesTest.php @@ -6,10 +6,10 @@ * This test class should revert everything before each test: be cautious not to introduce * tests with a "depends" annotation * - * @group plugins * @since 0.1 */ -class Plugin_Pages_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('plugins')] +class PluginPagesTest extends PHPUnit\Framework\TestCase { protected function tearDown(): void { // remove filters and actions @@ -89,11 +89,11 @@ public function test_register_plugin_page() { $func = rand_str(); // no plugin page registered - $this->assertEquals( 0, count( $ydb->get_plugin_pages() ) ); + $this->assertEmpty($ydb->get_plugin_pages()); // register one and check yourls_register_plugin_page( $plugin, $title, $func ); - $this->assertEquals( 1, count( $ydb->get_plugin_pages() ) ); + $this->assertCount( 1, $ydb->get_plugin_pages() ); $expected = array( 'slug' => $plugin, 'title' => $title, @@ -123,7 +123,7 @@ public function test_list_plugin_page() { yourls_register_plugin_page( $plugin, $title, $func ); $pages = yourls_list_plugin_admin_pages(); - $this->assertSame( 1, count( $pages ) ); + $this->assertCount( 1, $pages ); $this->assertArrayHasKey( 'url', $pages[ $plugin ] ); $this->assertArrayHasKey( 'anchor', $pages[ $plugin ] ); } diff --git a/tests/tests/plugins/files.php b/tests/tests/plugins/files.php deleted file mode 100644 index 632df5553..000000000 --- a/tests/tests/plugins/files.php +++ /dev/null @@ -1,200 +0,0 @@ -set_plugins( array() ); - } - - /** - * Return array of files from tests/data/plugins/invalid-code - */ - public function get_invalid_code_plugins() { - $plugins = array(); - foreach ( glob(YOURLS_PLUGINDIR . '/invalid-code/*.php') as $file ) { - $plugins[] = array($file); - } - return $plugins; - } - - /** - * Return one of the "valid" test plugins from tests/data/plugins - */ - public function pick_a_plugin() { - $plugins = array_keys( yourls_get_plugins() ); - $plugin = $plugins[ array_rand( $plugins ) ]; - return $plugin; - } - - /** - * Check that only 2 "valid" plugins are found in tests/data/plugins - */ - public function test_get_plugins() { - $plugins = array_keys( yourls_get_plugins() ); - $expected = [ - '0' => 'test-plugin/plugin.php', - '1' => 'test-plugin2/plugin.php', - ]; - $this->assertSame($expected, $plugins); - } - - /** - * Check that a random "valid" plugin file validates as a plugin file - */ - public function test_plugin_validate() { - $plugin = $this->pick_a_plugin(); - $this->assertTrue( yourls_is_a_plugin_file(YOURLS_PLUGINDIR . '/' . $plugin ) ); - } - - /** - * Check that a nonexistent plugin file does not validate as a plugin file - */ - public function test_missing_plugin_validate() { - $plugin = rand_str(); - $this->assertFalse( yourls_is_a_plugin_file(YOURLS_PLUGINDIR . '/' . $plugin ) ); - } - - /** - * Check that an invalid plugin file does not validate as a plugin file - * - * @dataProvider get_invalid_code_plugins - */ - public function test_invalid_plugin_validate($plugin) { - $this->assertFalse( yourls_is_a_plugin_file($plugin) ); - } - - /** - * Check that a random valid plugin activates correctly - */ - public function test_plugin_activate() { - $plugin = $this->pick_a_plugin(); - - // Make sure the plugin.php is NOT present in get_included_files() - // We sanitize the array to deal with different platforms (D:\hello\Windows vs /home/user/hello/Linux) - $this->assertFalse(in_array(yourls_sanitize_filename(YOURLS_PLUGINDIR.'/'.$plugin), - array_map('yourls_sanitize_filename', get_included_files()))); - - // Activate the plugin - $this->assertTrue( yourls_activate_plugin( $plugin ) ); - $this->assertGreaterThan( 0, yourls_has_active_plugins() ); - $this->assertTrue( yourls_is_active_plugin( $plugin ) ); - - // Make sure the plugin.php is now present in get_included_files() - $included_files = array_map('yourls_sanitize_filename', get_included_files()) ; - $this->assertTrue(in_array(yourls_sanitize_filename(YOURLS_PLUGINDIR.'/'.$plugin), $included_files)); - - // Make sure the plugin's uninstall.php is NOT present in get_included_files() - $this->assertFalse(in_array(yourls_sanitize_filename(YOURLS_PLUGINDIR.'/'.dirname($plugin).'/uninstall.php'),$included_files)); - - // We should NOT have YOURLS_UNINSTALL_PLUGIN defined - $this->assertFalse(defined('YOURLS_UNINSTALL_PLUGIN')); - - return $plugin; - } - - /** - * Check that an active plugin does not activate - * - * @depends test_plugin_activate - */ - public function test_plugin_activate_twice( $plugin ) { - $this->assertNotSame( true, yourls_activate_plugin( $plugin ) ); - // Note: we assertNotSame() with true because the function either returns true or a string - return $plugin; - } - - /** - * Simulate initial plugin loading - * - * @depends test_plugin_activate - */ - public function test_load_plugins( $plugin ) { - $ydb = yourls_get_db(); - - // at this point, we have exactly 1 plugin activated - $this->assertSame( $ydb->get_plugins(), array( $plugin ) ); - - // Register a nonexistent plugin to simulate one that was once activated but deleted since - $fake_plugin = rand_str() . '/plugin.php'; - $ydb->add_plugin($fake_plugin); - - // Register a broken code plugin to simulate one that was once activated but now is broken - $broken_plugin = $this->get_invalid_code_plugins()[ array_rand( $this->get_invalid_code_plugins() ) ][0]; - $ydb->add_plugin($broken_plugin); - - yourls_update_option( 'active_plugins', $ydb->get_plugins() ); - - // Check we have 1 activated and 2 removed - $load = yourls_load_plugins(); - $this->assertTrue( $load['loaded'] ); - $this->assertSame( $load['info'], '1 activated, 2 removed' ); - - // Check only our valid plugin is left registered - $this->assertSame( $ydb->get_plugins(), array( $plugin ) ); - $this->assertSame( 1, yourls_has_active_plugins() ); - } - - /** - * Check that valid plugin deactivates correctly - * - * @depends test_plugin_activate - */ - public function test_plugin_deactivate( $plugin ) { - $this->assertTrue( yourls_deactivate_plugin($plugin) ); - $this->assertSame( 0, yourls_has_active_plugins() ); - $this->assertFalse( yourls_is_active_plugin($plugin) ); - return $plugin; - } - - /** - * Check that deactivating a plugin correctly ran the uninstall script - * - * @depends test_plugin_deactivate - */ - public function test_plugin_uninstall( $plugin ) { - // Make sure uninstall.php is NOW present in get_included_files() - $this->assertTrue( in_array( yourls_sanitize_filename(YOURLS_PLUGINDIR . '/' . dirname($plugin) . '/uninstall.php'), - array_map('yourls_sanitize_filename', get_included_files())) ); - - // we should now have YOURLS_UNINSTALL_PLUGIN set to true - $this->assertTrue( defined('YOURLS_UNINSTALL_PLUGIN') && YOURLS_UNINSTALL_PLUGIN ); - } - - /** - * Check that an missing plugin does not activate - */ - public function test_invalid_plugin_activate() { - $plugin = rand_str(); - - $this->assertNotSame( true, yourls_activate_plugin( $plugin ) ); - $this->assertFalse( yourls_is_active_plugin( $plugin ) ); - } - - /** - * Check that a missing plugin does not deactivate - */ - public function test_invalid_plugin_deactivate() { - $plugin = rand_str(); - - $this->assertFalse( yourls_is_active_plugin( $plugin ) ); - $this->assertNotSame( true, yourls_deactivate_plugin( $plugin ) ); - } - - /** - * Check that a plugin with invalid code does not activate - * @dataProvider get_invalid_code_plugins - */ - public function test_invalid_plugin_does_not_activate($plugin) { - $this->assertNotTrue( yourls_include_file_sandbox( $plugin ) ); - $this->assertNotTrue( yourls_activate_plugin( $plugin ) ); - $this->assertNotTrue( yourls_is_active_plugin( $plugin ) ); - } -} diff --git a/tests/tests/shorturl/crud.php b/tests/tests/shorturl/CRUDTest.php similarity index 89% rename from tests/tests/shorturl/crud.php rename to tests/tests/shorturl/CRUDTest.php index 574467381..a03c1d177 100644 --- a/tests/tests/shorturl/crud.php +++ b/tests/tests/shorturl/CRUDTest.php @@ -3,11 +3,10 @@ /** * Short URLs : Create, Replace, Update, Delete tests * - * @group shorturls * @since 0.1 */ - -class ShortURL_CRUD_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('shorturls')] +class CRUDTest extends PHPUnit\Framework\TestCase { public function test_add_url() { $keyword = rand_str(); @@ -35,9 +34,7 @@ public function test_add_url() { return $keyword; } - /** - * @depends test_add_url - */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_url')] public function test_edit_title( $original_keyword ) { $new_keyword = rand_str(); $new_title = rand_str(); @@ -51,18 +48,14 @@ public function test_edit_title( $original_keyword ) { return $original_keyword; } - /** - * @depends test_add_url - */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_url')] public function test_is_shorturl( $keyword ) { $this->assertFalse( yourls_is_shorturl( rand_str() ) ); $this->assertTrue( yourls_is_shorturl( $keyword ) ); $this->assertTrue( yourls_is_shorturl( yourls_link( $keyword ) ) ); } - /** - * @depends test_add_url - */ + #[\PHPUnit\Framework\Attributes\Depends('test_add_url')] public function test_update_hits( $keyword ) { // purge cache $cache = yourls_get_keyword_infos( $keyword, false ); @@ -81,9 +74,7 @@ public function test_update_hits( $keyword ) { $this->assertEquals( 10, yourls_get_keyword_clicks( $keyword ) ); } - /** - * @depends test_edit_title - */ + #[\PHPUnit\Framework\Attributes\Depends('test_edit_title')] public function test_edit_url( $original_keyword ) { $new_keyword = rand_str(); $new_title = rand_str(); @@ -102,9 +93,7 @@ public function test_edit_url( $original_keyword ) { return $new_keyword; } - /** - * @depends test_edit_url - */ + #[\PHPUnit\Framework\Attributes\Depends('test_edit_url')] public function test_delete_url( $keyword ) { $delete = yourls_delete_link_by_keyword( rand_str() ); $this->assertEquals( 0, $delete ); diff --git a/tests/tests/shorturl/duplicate.php b/tests/tests/shorturl/DuplicateLongURLTest.php similarity index 88% rename from tests/tests/shorturl/duplicate.php rename to tests/tests/shorturl/DuplicateLongURLTest.php index 3aacf52f8..94d4f262d 100644 --- a/tests/tests/shorturl/duplicate.php +++ b/tests/tests/shorturl/DuplicateLongURLTest.php @@ -3,11 +3,10 @@ /** * Short URLs : test with "allow duplicate long URL" * - * @group shorturls * @since 0.1 */ - -class ShortURL_Duplicate_Long_URL_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('shorturls')] +class DuplicateLongURLTest extends PHPUnit\Framework\TestCase { public function test_yourls_allow_duplicate_longurls_is_bool() { $this->assertIsBool(yourls_allow_duplicate_longurls()); diff --git a/tests/tests/shorturl/misc.php b/tests/tests/shorturl/ShortURLTest.php similarity index 71% rename from tests/tests/shorturl/misc.php rename to tests/tests/shorturl/ShortURLTest.php index aad8e94ed..38d57bc19 100644 --- a/tests/tests/shorturl/misc.php +++ b/tests/tests/shorturl/ShortURLTest.php @@ -3,21 +3,29 @@ /** * Short URLs : misc functions * - * @group shorturls * @since 0.1 */ - -class ShortURL_Misc_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('shorturls')] +class ShortURLTest extends PHPUnit\Framework\TestCase { public function test_reserved_keywords() { - global $yourls_reserved_URL; + $yourls_reserved_URL = yourls_get_reserved_URL(); $reserved = $yourls_reserved_URL[ array_rand( $yourls_reserved_URL, 1 ) ]; $this->assertTrue( yourls_keyword_is_reserved( $reserved ) ); $this->assertFalse( yourls_keyword_is_reserved( rand_str() ) ); } - public function test_free_keywords() { + public function test_no_reserved_keywords() { global $yourls_reserved_URL; + $existing_keywords = $yourls_reserved_URL; + $yourls_reserved_URL = null; + $this->assertFalse( yourls_keyword_is_reserved( rand_str() ) ); + // put it back for other tests. + $yourls_reserved_URL = $existing_keywords; + } + + public function test_free_keywords() { + $yourls_reserved_URL = yourls_get_reserved_URL(); $reserved = $yourls_reserved_URL[ array_rand( $yourls_reserved_URL, 1 ) ]; $this->assertFalse( yourls_keyword_is_free( $reserved ) ); $this->assertFalse( yourls_keyword_is_free( 'ozh' ) ); diff --git a/tests/tests/stats/misc.php b/tests/tests/stats/StatsTest.php similarity index 58% rename from tests/tests/stats/misc.php rename to tests/tests/stats/StatsTest.php index e229eba87..5cbb34209 100644 --- a/tests/tests/stats/misc.php +++ b/tests/tests/stats/StatsTest.php @@ -2,11 +2,9 @@ /** * Stats functions - * - * @group stats */ - -class Misc_Stats_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('stats')] +class StatsTest extends PHPUnit\Framework\TestCase { public function test_do_log_redirect() { $this->assertIsBool(yourls_do_log_redirect()); diff --git a/tests/tests/themes/ThemesTest.php b/tests/tests/themes/ThemesTest.php new file mode 100644 index 000000000..ba8630b88 --- /dev/null +++ b/tests/tests/themes/ThemesTest.php @@ -0,0 +1,38 @@ +assertNotEmpty( $themes ); + + // Pick one random theme + $theme = $themes[ array_rand( $themes ) ]; + return dirname( $theme ); + } + + /** + * Check that a random valid theme activates correctly + * + * @since 0.1 + */ + #[\PHPUnit\Framework\Attributes\Depends('test_get_themes')] + public function test_theme_activate( $theme ) { + $this->assertTrue( yourls_activate_theme( $theme ) ); + $this->assertTrue( yourls_load_theme( $theme ) ); + $this->assertTrue( yourls_is_style_queued( $theme ) ); + $this->assertEquals( $theme, yourls_get_active_theme() ); + return $theme; + } +} diff --git a/tests/tests/themes/themes.php b/tests/tests/themes/themes.php deleted file mode 100644 index 7551e5f60..000000000 --- a/tests/tests/themes/themes.php +++ /dev/null @@ -1,43 +0,0 @@ -assertNotEmpty( $themes ); - - // Pick one random theme - $theme = $themes[ array_rand( $themes ) ]; - return dirname( $theme ); - } - - /** - * Check that a random valid theme activates correctly - * - * @depends test_get_themes - * @since 0.1 - */ - public function test_theme_activate( $theme ) { - $this->assertTrue( yourls_activate_theme( $theme ) ); - $this->assertTrue( yourls_load_theme( $theme ) ); - $this->assertTrue( yourls_is_style_queued( $theme ) ); - $this->assertEquals( $theme, yourls_get_active_theme() ); - return $theme; - } - -} - -endif; diff --git a/tests/tests/utilities/include_file_sandbox.php b/tests/tests/utilities/FileLoaderTest.php similarity index 75% rename from tests/tests/utilities/include_file_sandbox.php rename to tests/tests/utilities/FileLoaderTest.php index 09e0ab33e..7cae4b5d8 100644 --- a/tests/tests/utilities/include_file_sandbox.php +++ b/tests/tests/utilities/FileLoaderTest.php @@ -3,11 +3,10 @@ /** * Test sandboxed file loader * - * @group functions * @since 1.9.1 */ - -class FileLoader_Test extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('functions')] +class FileLoaderTest extends PHPUnit\Framework\TestCase { /** * Load valid file = true @@ -26,7 +25,7 @@ public function test_load_file_exists() { * Load missing file = string */ public function test_load_file_not_exists() { - $this->assertIsString( yourls_include_file_sandbox( YOURLS_TESTDATA_DIR . "/" . rand_str() . ".php" ) ); + $this->assertNull( yourls_include_file_sandbox( YOURLS_TESTDATA_DIR . "/" . rand_str() . ".php" ) ); } /** diff --git a/tests/tests/utilities/GetRequestTest.php b/tests/tests/utilities/GetRequestTest.php new file mode 100644 index 000000000..c624c0d43 --- /dev/null +++ b/tests/tests/utilities/GetRequestTest.php @@ -0,0 +1,90 @@ +assertSame( $expected, yourls_get_request($yourls_site, $uri) ); + } +} diff --git a/tests/tests/utilities/next_decimal.php b/tests/tests/utilities/NextDecimalTest.php similarity index 85% rename from tests/tests/utilities/next_decimal.php rename to tests/tests/utilities/NextDecimalTest.php index 8c491a59d..b83fef281 100644 --- a/tests/tests/utilities/next_decimal.php +++ b/tests/tests/utilities/NextDecimalTest.php @@ -2,11 +2,9 @@ /** * Utilities - * - * @group utils */ - -class NextDecimal_Tests extends PHPUnit\Framework\TestCase { +#[\PHPUnit\Framework\Attributes\Group('utils')] +class NextDecimalTest extends PHPUnit\Framework\TestCase { public function test_get_next_decimal() { $id = yourls_get_next_decimal(); diff --git a/tests/tests/utilities/get_request.php b/tests/tests/utilities/get_request.php deleted file mode 100644 index 8aae0d5f5..000000000 --- a/tests/tests/utilities/get_request.php +++ /dev/null @@ -1,113 +0,0 @@ -assertSame( $expected, yourls_get_request($yourls_site, $uri) ); - } -} diff --git a/user/config-sample.php b/user/config-sample.php index e0013553b..7cfc3483f 100644 --- a/user/config-sample.php +++ b/user/config-sample.php @@ -35,14 +35,14 @@ /** YOURLS installation URL ** All lowercase, no trailing slash at the end. - ** If you define it to "http://sho.rt", don't use "http://www.sho.rt" in your browser (and vice-versa) - ** To use an IDN domain (eg http://héhé.com), write its ascii form here (eg http://xn--hh-bjab.com) */ -define( 'YOURLS_SITE', 'http://your-own-domain-here.com' ); + ** If you define it to "https://sho.rt", don't use "https://www.sho.rt" in your browser (and vice-versa) + ** To use an IDN domain (eg https://héhé.com), write its ascii form here (eg https://xn--hh-bjab.com) */ +define( 'YOURLS_SITE', 'https://your-own-domain-here.com' ); /** YOURLS language ** Change this setting to use a translation file for your language, instead of the default English. ** That translation file (a .mo file) must be installed in the user/language directory. - ** See http://yourls.org/translations for more information */ + ** See https://yourls.org/translations for more information */ define( 'YOURLS_LANG', '' ); /** Allow multiple short URLs for a same long URL @@ -52,20 +52,20 @@ /** Private means the Admin area will be protected with login/pass as defined below. ** Set to false for public usage (eg on a restricted intranet or for test setups) - ** Read http://yourls.org/privatepublic for more details if you're unsure */ + ** Read https://yourls.org/privatepublic for more details if you're unsure */ define( 'YOURLS_PRIVATE', true ); /** A random secret hash used to encrypt cookies. You don't have to remember it, make it long and complicated - ** Hint: copy from http://yourls.org/cookie */ + ** Hint: copy from https://yourls.org/cookie */ define( 'YOURLS_COOKIEKEY', 'modify this text with something random' ); /** Username(s) and password(s) allowed to access the site. Passwords either in plain text or as encrypted hashes ** YOURLS will auto encrypt plain text passwords in this file - ** Read http://yourls.org/userpassword for more information */ + ** Read https://yourls.org/userpassword for more information */ $yourls_user_passwords = [ - 'username' => 'password', - // 'username2' => 'password2', - // You can have one or more 'login'=>'password' lines + 'username' => 'password', + // 'username2' => 'password2', + // You can have one or more 'login'=>'password' lines ]; /** URL shortening method: either 36 or 62 @@ -83,7 +83,13 @@ * Define here negative, unwanted or potentially misleading keywords. */ $yourls_reserved_URL = [ - 'porn', 'faggot', 'sex', 'nigger', 'fuck', 'cunt', 'dick', + 'porn', + 'faggot', + 'sex', + 'nigger', + 'fuck', + 'cunt', + 'dick', ]; /* diff --git a/user/pages/examplepage.php b/user/pages/examplepage.php index f02d6ec35..76f07762f 100644 --- a/user/pages/examplepage.php +++ b/user/pages/examplepage.php @@ -2,8 +2,8 @@ // Make sure we're in YOURLS context if( !defined( 'YOURLS_ABSPATH' ) ) { - echo "Try using a URL without the /pages/ part"; - die(); + echo "Try using a URL without the /pages/ part"; + die(); } // Display page content. Any PHP, HTML and YOURLS function can go here. diff --git a/user/plugins/hyphens-in-urls/plugin.php b/user/plugins/hyphens-in-urls/plugin.php index c604dd581..727d369ba 100644 --- a/user/plugins/hyphens-in-urls/plugin.php +++ b/user/plugins/hyphens-in-urls/plugin.php @@ -23,5 +23,5 @@ yourls_add_action('add_new_link_create_keyword', function() {yourls_remove_filter('get_shorturl_charset', 'ozh_hyphen_in_charset');}); function ozh_hyphen_in_charset( $in ) { - return $in.'-'; + return $in.'-'; } diff --git a/user/plugins/random-bg/plugin.php b/user/plugins/random-bg/plugin.php index a6768ff0d..8bba3f425 100644 --- a/user/plugins/random-bg/plugin.php +++ b/user/plugins/random-bg/plugin.php @@ -14,13 +14,13 @@ // Add the inline style yourls_add_action( 'html_head', 'ozh_yourls_randombg' ); function ozh_yourls_randombg() { - $bg = glob( __DIR__.'/img/*png' ); - $url = yourls_plugin_url( __DIR__ ); - $rnd = yourls_plugin_url( $bg[ mt_rand( 0, count( $bg ) - 1 ) ] ); - echo << - body {background:#e3f3ff url($rnd) repeat;} - + body {background:#e3f3ff url($rnd) repeat;} + CSS; } diff --git a/user/plugins/sample-page/plugin.php b/user/plugins/sample-page/plugin.php index 5f5479a87..41953454b 100644 --- a/user/plugins/sample-page/plugin.php +++ b/user/plugins/sample-page/plugin.php @@ -14,50 +14,50 @@ // Register our plugin admin page yourls_add_action( 'plugins_loaded', 'ozh_yourls_samplepage_add_page' ); function ozh_yourls_samplepage_add_page() { - yourls_register_plugin_page( 'sample_page', 'Sample Admin Page', 'ozh_yourls_samplepage_do_page' ); - // parameters: page slug, page title, and function that will display the page itself + yourls_register_plugin_page( 'sample_page', 'Sample Admin Page', 'ozh_yourls_samplepage_do_page' ); + // parameters: page slug, page title, and function that will display the page itself } // Display admin page function ozh_yourls_samplepage_do_page() { - // Check if a form was submitted - if( isset( $_POST['test_option'] ) ) { - // Check nonce - yourls_verify_nonce( 'sample_page' ); + // Check if a form was submitted + if( isset( $_POST['test_option'] ) ) { + // Check nonce + yourls_verify_nonce( 'sample_page' ); - // Process form - ozh_yourls_samplepage_update_option(); - } + // Process form + ozh_yourls_samplepage_update_option(); + } - // Get value from database - $test_option = yourls_get_option( 'test_option' ); + // Get value from database + $test_option = yourls_get_option( 'test_option' ); - // Create nonce - $nonce = yourls_create_nonce( 'sample_page' ); + // Create nonce + $nonce = yourls_create_nonce( 'sample_page' ); - echo <<Sample Plugin Administration Page

    -

    This plugin stores an integer in the option database

    -
    - -

    -

    - + echo <<Sample Plugin Administration Page

+

This plugin stores an integer in the option database

+
+ +

+

+ HTML; } // Update option in database function ozh_yourls_samplepage_update_option() { - $in = $_POST['test_option']; + $in = $_POST['test_option']; - if( $in ) { - // Validate test_option. ALWAYS validate and sanitize user input. - // Here, we want an integer - $in = intval( $in); + if( $in ) { + // Validate test_option. ALWAYS validate and sanitize user input. + // Here, we want an integer + $in = intval( $in); - // Update value in database - yourls_update_option( 'test_option', $in ); - } + // Update value in database + yourls_update_option( 'test_option', $in ); + } } diff --git a/user/plugins/sample-plugin/plugin.php b/user/plugins/sample-plugin/plugin.php index 40dc1ab9a..dcfdc4edf 100644 --- a/user/plugins/sample-plugin/plugin.php +++ b/user/plugins/sample-plugin/plugin.php @@ -28,7 +28,7 @@ */ function ozh_sample_add_menu() { - echo '
  • Ozh
  • '; + echo '
  • Ozh
  • '; } /* And that's it. Activate the plugin and notice the new menu entry. */ @@ -54,8 +54,8 @@ function ozh_sample_add_menu() { */ function ozh_sample_change_title( $value ) { - $value = $value . ' -- the sample plugin is activated'; - return $value; // a filter *always* has to return a value + $value = $value . ' -- the sample plugin is activated'; + return $value; // a filter *always* has to return a value } /* And that's it. Activate the plugin and notice how the page title changes */ diff --git a/user/plugins/sample-toolbar/plugin.php b/user/plugins/sample-toolbar/plugin.php index d48c7bcf1..7fde678bd 100644 --- a/user/plugins/sample-toolbar/plugin.php +++ b/user/plugins/sample-toolbar/plugin.php @@ -19,78 +19,78 @@ // When a redirection to a shorturl is about to happen, register variables yourls_add_action( 'redirect_shorturl', 'ozh_toolbar_add' ); function ozh_toolbar_add( $args ) { - global $ozh_toolbar; - $ozh_toolbar['do'] = true; - $ozh_toolbar['keyword'] = $args[1]; + global $ozh_toolbar; + $ozh_toolbar['do'] = true; + $ozh_toolbar['keyword'] = $args[1]; } // On redirection, check if this is a toolbar and draw it if needed yourls_add_action( 'pre_redirect', 'ozh_toolbar_do' ); function ozh_toolbar_do( $args ) { - global $ozh_toolbar; + global $ozh_toolbar; - // Does this redirection need a toolbar? - if( !$ozh_toolbar['do'] ) { - return; + // Does this redirection need a toolbar? + if( !$ozh_toolbar['do'] ) { + return; } - // Do we have a cookie stating the user doesn't want a toolbar? - if( isset( $_COOKIE['yourls_no_toolbar'] ) && $_COOKIE['yourls_no_toolbar'] == 1 ) { - return; + // Do we have a cookie stating the user doesn't want a toolbar? + if( isset( $_COOKIE['yourls_no_toolbar'] ) && $_COOKIE['yourls_no_toolbar'] == 1 ) { + return; } - // Get URL and page title - $url = $args[0]; - $pagetitle = yourls_get_keyword_title( $ozh_toolbar['keyword'] ); + // Get URL and page title + $url = $args[0]; + $pagetitle = yourls_get_keyword_title( $ozh_toolbar['keyword'] ); - // Update title if it hasn't been stored yet - if( $pagetitle == '' ) { - $pagetitle = yourls_get_remote_title( $url ); - yourls_edit_link_title( $ozh_toolbar['keyword'], $pagetitle ); - } - $_pagetitle = htmlentities( yourls_get_remote_title( $url ) ); + // Update title if it hasn't been stored yet + if( $pagetitle == '' ) { + $pagetitle = yourls_get_remote_title( $url ); + yourls_edit_link_title( $ozh_toolbar['keyword'], $pagetitle ); + } + $_pagetitle = htmlentities( yourls_get_remote_title( $url ) ); - $www = YOURLS_SITE; - $ver = YOURLS_VERSION; + $www = YOURLS_SITE; + $ver = YOURLS_VERSION; $favicon = yourls_get_yourls_favicon_url(false); - // When was the link created (in days) - $diff = abs( time() - strtotime( yourls_get_keyword_timestamp( $ozh_toolbar['keyword'] ) ) ); - $days = floor( $diff / (60*60*24) ); - if( $days == 0 ) { - $created = 'today'; - } else { - $created = $days . ' ' . yourls_n( 'day', 'days', $days ) . ' ago'; - } + // When was the link created (in days) + $diff = abs( time() - strtotime( yourls_get_keyword_timestamp( $ozh_toolbar['keyword'] ) ) ); + $days = floor( $diff / (60*60*24) ); + if( $days == 0 ) { + $created = 'today'; + } else { + $created = $days . ' ' . yourls_n( 'day', 'days', $days ) . ' ago'; + } - // How many hits on the page - $hits = 1 + yourls_get_keyword_clicks( $ozh_toolbar['keyword'] ); - $hits = $hits . ' ' . yourls_n( 'view', 'views', $hits ); + // How many hits on the page + $hits = 1 + yourls_get_keyword_clicks( $ozh_toolbar['keyword'] ); + $hits = $hits . ' ' . yourls_n( 'view', 'views', $hits ); - // Plugin URL (no URL is hardcoded) - $pluginurl = YOURLS_PLUGINURL . '/'.yourls_plugin_basename( __DIR__ ); + // Plugin URL (no URL is hardcoded) + $pluginurl = YOURLS_PLUGINURL . '/'.yourls_plugin_basename( __DIR__ ); - // All set. Draw the toolbar itself. - echo << - $pagetitle — YOURLS - - - - - + $pagetitle — YOURLS + + + + +
    -
    - Short link powered by YOURLS and created $created. $hits. -
    - -
    - close - close -
    +
    + Short link powered by YOURLS and created $created. $hits. +
    + +
    + close + close +
    @@ -99,6 +99,6 @@ function ozh_toolbar_do( $args ) { PAGE; - // Don't forget to die, to interrupt the flow of normal events (ie redirecting to long URL) - die(); + // Don't forget to die, to interrupt the flow of normal events (ie redirecting to long URL) + die(); } diff --git a/yourls-api.php b/yourls-api.php index 413abad55..8f5420653 100644 --- a/yourls-api.php +++ b/yourls-api.php @@ -17,34 +17,34 @@ // Define standard API actions $api_actions = array( - 'shorturl' => 'yourls_api_action_shorturl', - 'stats' => 'yourls_api_action_stats', - 'db-stats' => 'yourls_api_action_db_stats', - 'url-stats' => 'yourls_api_action_url_stats', - 'expand' => 'yourls_api_action_expand', - 'version' => 'yourls_api_action_version', + 'shorturl' => 'yourls_api_action_shorturl', + 'stats' => 'yourls_api_action_stats', + 'db-stats' => 'yourls_api_action_db_stats', + 'url-stats' => 'yourls_api_action_url_stats', + 'expand' => 'yourls_api_action_expand', + 'version' => 'yourls_api_action_version', ); $api_actions = yourls_apply_filter( 'api_actions', $api_actions ); // Register API actions foreach( (array) $api_actions as $_action => $_callback ) { - yourls_add_filter( 'api_action_' . $_action, $_callback, 99 ); + yourls_add_filter( 'api_action_' . $_action, $_callback, 99 ); } // Try requested API method. Properly registered actions should return an array. $return = yourls_apply_filter( 'api_action_' . $action, false ); if ( false === $return ) { - $return = array( - 'errorCode' => 400, - 'message' => 'Unknown or missing "action" parameter', - 'simple' => 'Unknown or missing "action" parameter', - ); + $return = array( + 'errorCode' => '400', + 'message' => 'Unknown or missing "action" parameter', + 'simple' => 'Unknown or missing "action" parameter', + ); } if( isset( $_REQUEST['callback'] ) ) - $return['callback'] = $_REQUEST['callback']; + $return['callback'] = $_REQUEST['callback']; elseif ( isset( $_REQUEST['jsonp'] ) ) - $return['callback'] = $_REQUEST['jsonp']; + $return['callback'] = $_REQUEST['jsonp']; $format = ( isset( $_REQUEST['format'] ) ? $_REQUEST['format'] : 'xml' ); diff --git a/yourls-go.php b/yourls-go.php index 51968dd92..fd26075db 100644 --- a/yourls-go.php +++ b/yourls-go.php @@ -4,8 +4,8 @@ // Variables should be defined in yourls-loader.php if( !isset( $keyword ) ) { - yourls_do_action( 'redirect_no_keyword' ); - yourls_redirect( YOURLS_SITE, 301 ); + yourls_do_action( 'redirect_no_keyword' ); + yourls_redirect( YOURLS_SITE, 301 ); } $keyword = yourls_sanitize_keyword($keyword); diff --git a/yourls-infos.php b/yourls-infos.php index 2cba4d23e..82893873c 100644 --- a/yourls-infos.php +++ b/yourls-infos.php @@ -6,9 +6,9 @@ // Variables should be defined in yourls-loader.php if ( !isset( $keyword ) ) { - yourls_do_action( 'infos_no_keyword' ); - yourls_redirect( YOURLS_SITE, 302 ); - exit; + yourls_do_action( 'infos_no_keyword' ); + yourls_redirect( YOURLS_SITE, 302 ); + exit; } // Get basic infos for this shortened URL @@ -20,13 +20,13 @@ // Update title if it hasn't been stored yet if( $title == '' ) { - $title = yourls_get_remote_title( $longurl ); - yourls_edit_link_title( $keyword, $title ); + $title = yourls_get_remote_title( $longurl ); + yourls_edit_link_title( $keyword, $title ); } if ( $longurl === false ) { - yourls_do_action( 'infos_keyword_not_found' ); - yourls_redirect( YOURLS_SITE, 302 ); + yourls_do_action( 'infos_keyword_not_found' ); + yourls_redirect( YOURLS_SITE, 302 ); exit; } @@ -35,177 +35,177 @@ if( yourls_do_log_redirect() ) { - $table = YOURLS_DB_TABLE_LOG; - $referrers = array(); - $direct = $notdirect = 0; - $countries = array(); - $dates = array(); - $list_of_days = array(); - $list_of_months = array(); - $list_of_years = array(); - $last_24h = array(); - - if( yourls_allow_duplicate_longurls() ) - $keyword_list = yourls_get_longurl_keywords( $longurl ); - // Define keyword query range : either a single keyword or a list of keywords - if( $aggregate ) { - $keyword_range = 'IN ( :list )'; + $table = YOURLS_DB_TABLE_LOG; + $referrers = array(); + $direct = $notdirect = 0; + $countries = array(); + $dates = array(); + $list_of_days = array(); + $list_of_months = array(); + $list_of_years = array(); + $last_24h = array(); + + if( yourls_allow_duplicate_longurls() ) + $keyword_list = yourls_get_longurl_keywords( $longurl ); + // Define keyword query range : either a single keyword or a list of keywords + if( $aggregate ) { + $keyword_range = 'IN ( :list )'; $keyword_binds = array('list' => $keyword_list); - } else { - $keyword_range = '= :keyword'; + } else { + $keyword_range = '= :keyword'; $keyword_binds = array('keyword' => $keyword); - } + } - // *** Referrers *** + // *** Referrers *** $sql = "SELECT `referrer`, COUNT(*) AS `count` FROM `$table` WHERE `shorturl` $keyword_range GROUP BY `referrer`;"; $sql = yourls_apply_filter('stat_query_referrer', $sql); - $rows = $ydb->fetchObjects($sql, $keyword_binds); - - // Loop through all results and build list of referrers, countries and hits per day - foreach( (array)$rows as $row ) { - if ( $row->referrer == 'direct' ) { - $direct = $row->count; - continue; - } - - $host = yourls_get_domain( $row->referrer ); - if( !array_key_exists( $host, $referrers ) ) - $referrers[$host] = array( ); - if( !array_key_exists( $row->referrer, $referrers[$host] ) ) { - $referrers[$host][$row->referrer] = $row->count; - $notdirect += $row->count; - } else { - $referrers[$host][$row->referrer] += $row->count; - $notdirect += $row->count; - } - } - - // Sort referrers. $referrer_sort is a array of most frequent domains - arsort( $referrers ); - $referrer_sort = array(); - $number_of_sites = count( array_keys( $referrers ) ); - foreach( $referrers as $site => $urls ) { - if( count($urls) > 1 || $number_of_sites == 1 ) - $referrer_sort[$site] = array_sum( $urls ); - } - arsort($referrer_sort); - - - // *** Countries *** - $sql = "SELECT `country_code`, COUNT(*) AS `count` FROM `$table` WHERE `shorturl` $keyword_range GROUP BY `country_code`;"; + $rows = $ydb->fetchObjects($sql, $keyword_binds); + + // Loop through all results and build list of referrers, countries and hits per day + foreach( (array)$rows as $row ) { + if ( $row->referrer == 'direct' ) { + $direct = $row->count; + continue; + } + + $host = yourls_get_domain( $row->referrer ); + if( !array_key_exists( $host, $referrers ) ) + $referrers[$host] = array( ); + if( !array_key_exists( $row->referrer, $referrers[$host] ) ) { + $referrers[$host][$row->referrer] = $row->count; + $notdirect += $row->count; + } else { + $referrers[$host][$row->referrer] += $row->count; + $notdirect += $row->count; + } + } + + // Sort referrers. $referrer_sort is a array of most frequent domains + arsort( $referrers ); + $referrer_sort = array(); + $number_of_sites = count( array_keys( $referrers ) ); + foreach( $referrers as $site => $urls ) { + if( count($urls) > 1 || $number_of_sites == 1 ) + $referrer_sort[$site] = array_sum( $urls ); + } + arsort($referrer_sort); + + + // *** Countries *** + $sql = "SELECT `country_code`, COUNT(*) AS `count` FROM `$table` WHERE `shorturl` $keyword_range GROUP BY `country_code`;"; $sql = yourls_apply_filter('stat_query_country', $sql); - $rows = $ydb->fetchObjects($sql, $keyword_binds); - - // Loop through all results and build list of countries and hits - foreach( (array)$rows as $row ) { - if ("$row->country_code") - $countries["$row->country_code"] = $row->count; - } - - // Sort countries, most frequent first - if ( $countries ) - arsort( $countries ); - - - // *** Dates : array of $dates[$year][$month][$day] = number of clicks *** - $sql = "SELECT - DATE_FORMAT(`click_time`, '%Y') AS `year`, - DATE_FORMAT(`click_time`, '%m') AS `month`, - DATE_FORMAT(`click_time`, '%d') AS `day`, - COUNT(*) AS `count` - FROM `$table` - WHERE `shorturl` $keyword_range - GROUP BY `year`, `month`, `day`;"; + $rows = $ydb->fetchObjects($sql, $keyword_binds); + + // Loop through all results and build list of countries and hits + foreach( (array)$rows as $row ) { + if ("$row->country_code") + $countries["$row->country_code"] = $row->count; + } + + // Sort countries, most frequent first + if ( $countries ) + arsort( $countries ); + + + // *** Dates : array of $dates[$year][$month][$day] = number of clicks *** + $sql = "SELECT + DATE_FORMAT(`click_time`, '%Y') AS `year`, + DATE_FORMAT(`click_time`, '%m') AS `month`, + DATE_FORMAT(`click_time`, '%d') AS `day`, + COUNT(*) AS `count` + FROM `$table` + WHERE `shorturl` $keyword_range + GROUP BY `year`, `month`, `day`;"; $sql = yourls_apply_filter('stat_query_dates', $sql); - $rows = $ydb->fetchObjects($sql, $keyword_binds); - - // Loop through all results and fill blanks - foreach( (array)$rows as $row ) { - if( !array_key_exists($row->year, $dates ) ) - $dates[$row->year] = array(); - if( !array_key_exists( $row->month, $dates[$row->year] ) ) - $dates[$row->year][$row->month] = array(); - if( !array_key_exists( $row->day, $dates[$row->year][$row->month] ) ) - $dates[$row->year][$row->month][$row->day] = $row->count; - else - $dates[$row->year][$row->month][$row->day] += $row->count; - } - - // Sort dates, chronologically from [2007][12][24] to [2009][02][19] - ksort( $dates ); - foreach( $dates as $year=>$months ) { - ksort( $dates[$year] ); - foreach( $months as $month=>$day ) { - ksort( $dates[$year][$month] ); - } - } - - // Get $list_of_days, $list_of_months, $list_of_years - reset( $dates ); - if( $dates ) { + $rows = $ydb->fetchObjects($sql, $keyword_binds); + + // Loop through all results and fill blanks + foreach( (array)$rows as $row ) { + if( !array_key_exists($row->year, $dates ) ) + $dates[$row->year] = array(); + if( !array_key_exists( $row->month, $dates[$row->year] ) ) + $dates[$row->year][$row->month] = array(); + if( !array_key_exists( $row->day, $dates[$row->year][$row->month] ) ) + $dates[$row->year][$row->month][$row->day] = $row->count; + else + $dates[$row->year][$row->month][$row->day] += $row->count; + } + + // Sort dates, chronologically from [2007][12][24] to [2009][02][19] + ksort( $dates ); + foreach( $dates as $year=>$months ) { + ksort( $dates[$year] ); + foreach( $months as $month=>$day ) { + ksort( $dates[$year][$month] ); + } + } + + // Get $list_of_days, $list_of_months, $list_of_years + reset( $dates ); + if( $dates ) { $_lists = yourls_build_list_of_days( $dates ); $list_of_days = $_lists['list_of_days']; $list_of_months = $_lists['list_of_months']; $list_of_years = $_lists['list_of_years']; unset($_lists); - } + } - $offset = yourls_get_time_offset(); + $offset = yourls_get_time_offset(); - // *** Last 24 hours : array of $last_24h[ $hour ] = number of click *** - $sql = "SELECT - DATE_FORMAT(DATE_ADD(`click_time`, INTERVAL " . $offset . " HOUR), '%H %p') AS `time`, - COUNT(*) AS `count` - FROM `$table` - WHERE `shorturl` $keyword_range AND DATE_ADD(`click_time`, INTERVAL " . $offset . " HOUR) > (DATE_ADD(CURRENT_TIMESTAMP, INTERVAL " . $offset . " HOUR) - INTERVAL 1 DAY) - GROUP BY `time`;"; + // *** Last 24 hours : array of $last_24h[ $hour ] = number of click *** + $sql = "SELECT + DATE_FORMAT(DATE_ADD(`click_time`, INTERVAL " . $offset . " HOUR), '%H %p') AS `time`, + COUNT(*) AS `count` + FROM `$table` + WHERE `shorturl` $keyword_range AND DATE_ADD(`click_time`, INTERVAL " . $offset . " HOUR) > (DATE_ADD(CURRENT_TIMESTAMP, INTERVAL " . $offset . " HOUR) - INTERVAL 1 DAY) + GROUP BY `time`;"; $sql = yourls_apply_filter('stat_query_last24h', $sql); - $rows = $ydb->fetchObjects($sql, $keyword_binds); - - $_last_24h = array(); - foreach( (array)$rows as $row ) { - if ( isset( $row->time ) ) - $_last_24h[ "$row->time" ] = $row->count; - } - - $now = intval( date('U') ); - for ($i = 23; $i >= 0; $i--) { - $h = date('H A', ($now - ($i * 60 * 60) + ($offset * 60 * 60)) ); - // If the $last_24h doesn't have all the hours, insert missing hours with value 0 - $last_24h[ $h ] = array_key_exists( $h, $_last_24h ) ? $_last_24h[ $h ] : 0 ; - } - unset( $_last_24h ); - - // *** Queries all done, phew *** - - // Filter all this junk if applicable. Be warned, some are possibly huge datasets. - $referrers = yourls_apply_filter( 'pre_yourls_info_referrers', $referrers ); - $referrer_sort = yourls_apply_filter( 'pre_yourls_info_referrer_sort', $referrer_sort ); - $direct = yourls_apply_filter( 'pre_yourls_info_direct', $direct ); - $notdirect = yourls_apply_filter( 'pre_yourls_info_notdirect', $notdirect ); - $dates = yourls_apply_filter( 'pre_yourls_info_dates', $dates ); - $list_of_days = yourls_apply_filter( 'pre_yourls_info_list_of_days', $list_of_days ); - $list_of_months = yourls_apply_filter( 'pre_yourls_info_list_of_months', $list_of_months ); - $list_of_years = yourls_apply_filter( 'pre_yourls_info_list_of_years', $list_of_years ); - $last_24h = yourls_apply_filter( 'pre_yourls_info_last_24h', $last_24h ); - $countries = yourls_apply_filter( 'pre_yourls_info_countries', $countries ); - - // I can haz debug data - /** - echo "
    ";
    -	echo "referrers: "; print_r( $referrers );
    -	echo "referrer sort: "; print_r( $referrer_sort );
    -	echo "direct: $direct\n";
    -	echo "notdirect: $notdirect\n";
    -	echo "dates: "; print_r( $dates );
    -	echo "list of days: "; print_r( $list_of_days );
    -	echo "list_of_months: "; print_r( $list_of_months );
    -	echo "list_of_years: "; print_r( $list_of_years );
    -	echo "last_24h: "; print_r( $last_24h );
    -	echo "countries: "; print_r( $countries );
    -	die();
    -	**/
    +    $rows = $ydb->fetchObjects($sql, $keyword_binds);
    +
    +    $_last_24h = array();
    +    foreach( (array)$rows as $row ) {
    +        if ( isset( $row->time ) )
    +            $_last_24h[ "$row->time" ] = $row->count;
    +    }
    +
    +    $now = intval( date('U') );
    +    for ($i = 23; $i >= 0; $i--) {
    +        $h = date('H A', ($now - ($i * 60 * 60) + ($offset * 60 * 60)) );
    +        // If the $last_24h doesn't have all the hours, insert missing hours with value 0
    +        $last_24h[ $h ] = array_key_exists( $h, $_last_24h ) ? $_last_24h[ $h ] : 0 ;
    +    }
    +    unset( $_last_24h );
    +
    +    // *** Queries all done, phew ***
    +
    +    // Filter all this junk if applicable. Be warned, some are possibly huge datasets.
    +    $referrers      = yourls_apply_filter( 'pre_yourls_info_referrers', $referrers );
    +    $referrer_sort  = yourls_apply_filter( 'pre_yourls_info_referrer_sort', $referrer_sort );
    +    $direct         = yourls_apply_filter( 'pre_yourls_info_direct', $direct );
    +    $notdirect      = yourls_apply_filter( 'pre_yourls_info_notdirect', $notdirect );
    +    $dates          = yourls_apply_filter( 'pre_yourls_info_dates', $dates );
    +    $list_of_days   = yourls_apply_filter( 'pre_yourls_info_list_of_days', $list_of_days );
    +    $list_of_months = yourls_apply_filter( 'pre_yourls_info_list_of_months', $list_of_months );
    +    $list_of_years  = yourls_apply_filter( 'pre_yourls_info_list_of_years', $list_of_years );
    +    $last_24h       = yourls_apply_filter( 'pre_yourls_info_last_24h', $last_24h );
    +    $countries      = yourls_apply_filter( 'pre_yourls_info_countries', $countries );
    +
    +    // I can haz debug data
    +    /**
    +    echo "
    ";
    +    echo "referrers: "; print_r( $referrers );
    +    echo "referrer sort: "; print_r( $referrer_sort );
    +    echo "direct: $direct\n";
    +    echo "notdirect: $notdirect\n";
    +    echo "dates: "; print_r( $dates );
    +    echo "list of days: "; print_r( $list_of_days );
    +    echo "list_of_months: "; print_r( $list_of_months );
    +    echo "list_of_years: "; print_r( $list_of_years );
    +    echo "last_24h: "; print_r( $last_24h );
    +    echo "countries: "; print_r( $countries );
    +    die();
    +    **/
     
     }
     
    @@ -218,338 +218,338 @@
     
     

    : 1 ) - echo ' '; + yourls_html_link( yourls_link($keyword) ); + if( isset( $keyword_list ) && count( $keyword_list ) > 1 ) + echo ' '; } ?>

    :

    -
    -
      - -
    • -
    • -
    • - -
    • -
    -
    +
    +
      + +
    • +
    • +
    • + +
    • +
    +
    -
    -

    - - - - - - yourls__( 'Last 24 hours' ), - '7' => yourls__( 'Last 7 days' ), - '30' => yourls__( 'Last 30 days' ), - 'all'=> yourls__( 'All time' ), - ); - - // Which graph to generate ? - $do_all = $do_30 = $do_7 = $do_24 = false; - $hits_all = array_sum( $list_of_days ); - $hits_30 = array_sum( array_slice( $list_of_days, -30 ) ); - $hits_7 = array_sum( array_slice( $list_of_days, -7 ) ); - $hits_24 = array_sum( $last_24h ); - if( $hits_all > 0 ) - $do_all = true; // graph for all days range - if( $hits_30 > 0 && count( array_slice( $list_of_days, -30 ) ) == 30 ) - $do_30 = true; // graph for last 30 days - if( $hits_7 > 0 && count( array_slice( $list_of_days, -7 ) ) == 7 ) - $do_7 = true; // graph for last 7 days - if( $hits_24 > 0 ) - $do_24 = true; // graph for last 24 hours - - // Which graph to display ? - $display_all = $display_30 = $display_7 = $display_24 = false; - if( $do_24 ) { - $display_24 = true; - } elseif ( $do_7 ) { - $display_7 = true; - } elseif ( $do_30 ) { - $display_30 = true; - } elseif ( $do_all ) { - $display_all = true; - } - ?> - -

    - - - - - -
    - - $graphtitle ) { - if( ${'do_'.$graph} == true ) { - $display = ( ${'display_'.$graph} === true ? 'display:block' : 'display:none' ); - echo "
    "; - echo '

    ' . yourls_s( 'Number of hits : %s' , $graphtitle ) . '

    '; - switch( $graph ) { - case '24': - yourls_stats_line( $last_24h, "stat_line_$graph" ); - break; - - case '7': - case '30': - $slice = array_slice( $list_of_days, intval( $graph ) * -1 ); - yourls_stats_line( $slice, "stat_line_$graph" ); - unset( $slice ); - break; - - case 'all': - yourls_stats_line( $list_of_days, "stat_line_$graph" ); - break; - } - echo "
    \n"; - } - } ?> - -
    -

    - -

    -
    -
      - $graphtitle ) { - if ( ${'do_'.$graph} ) { - $link = "$graphtitle"; - } else { - $link = $graphtitle; - } - $stat = ''; - if( ${'do_'.$graph} ) { - switch( $graph ) { - case '7': - case '30': - $stat = yourls_s( '%s per day', round( ( ${'hits_'.$graph} / intval( $graph ) ) * 100 ) / 100 ); - break; - case '24': - $stat = yourls_s( '%s per hour', round( ( ${'hits_'.$graph} / 24 ) * 100 ) / 100 ); - break; - case 'all': - if( $ago > 0 ) - $stat = yourls_s( '%s per day', round( ( ${'hits_'.$graph} / $ago ) * 100 ) / 100 ); - } - } - $hits = sprintf( yourls_n( '%s hit', '%s hits', ${'hits_'.$graph} ), ${'hits_'.$graph} ); - echo "
    • $link $hits $stat
    • \n"; - } - ?> -
    -
    - -

    - -

    %1$s hit on %2$s', '%1$s hits on %2$s', $best['max'] ), $best['max'], yourls_date_i18n( yourls_get_date_format("F j, Y"), strtotime( $best['day'] ) ) ); ?>. -

    - - -
    - - - - ' . yourls__( 'No traffic yet. Get some clicks first!' ) . '

    '; - } ?> - - - -
    -

    - - - - - - - - - - -
    -

    - -

    - - -
    -

    - -
    - - - - ' . yourls__( 'No country data.' ) . '

    '; - } ?> -
    - - -
    -

    - - - - - - - - - - - -
    -

    - 1 ) - $referrer_sort[ yourls__( 'Others' ) ] = count( $referrers ); - yourls_stats_pie( $referrer_sort, 5, '440x220', 'stat_tab_source_ref' ); - unset( $referrer_sort[yourls__('Others')] ); - ?> -

    -
      - $count ) { - $i++; - $favicon = yourls_get_favicon_url( $site ); - echo "
    • $site: $count " . yourls__( '(details)' ) . "
    • \n"; - echo "\n"; - unset( $referrers[$site] ); - } - // Any referrer left? Group in "various" - if ( $referrers ) { - echo "
    • " . yourls__( 'Various:' ) . " ". count( $referrers ). " " . yourls__( '(details)' ) . "
    • \n"; - echo "\n"; - } - ?> - -
    - -
    -

    - $direct, yourls__( 'Referrers' ) => $notdirect ), 5, '440x220', 'stat_tab_source_direct' ); - ?> -

    %s hit', '%s hits', $direct ), $direct ); ?>

    -

    %s hit', '%s hits', $notdirect ), $notdirect ); ?>

    - -
    - - - - ' . yourls__( 'No referrer data.' ) . '

    '; - } ?> - -
    +
    +

    + + + + + + yourls__( 'Last 24 hours' ), + '7' => yourls__( 'Last 7 days' ), + '30' => yourls__( 'Last 30 days' ), + 'all'=> yourls__( 'All time' ), + ); + + // Which graph to generate ? + $do_all = $do_30 = $do_7 = $do_24 = false; + $hits_all = array_sum( $list_of_days ); + $hits_30 = array_sum( array_slice( $list_of_days, -30 ) ); + $hits_7 = array_sum( array_slice( $list_of_days, -7 ) ); + $hits_24 = array_sum( $last_24h ); + if( $hits_all > 0 ) + $do_all = true; // graph for all days range + if( $hits_30 > 0 && count( array_slice( $list_of_days, -30 ) ) == 30 ) + $do_30 = true; // graph for last 30 days + if( $hits_7 > 0 && count( array_slice( $list_of_days, -7 ) ) == 7 ) + $do_7 = true; // graph for last 7 days + if( $hits_24 > 0 ) + $do_24 = true; // graph for last 24 hours + + // Which graph to display ? + $display_all = $display_30 = $display_7 = $display_24 = false; + if( $do_24 ) { + $display_24 = true; + } elseif ( $do_7 ) { + $display_7 = true; + } elseif ( $do_30 ) { + $display_30 = true; + } elseif ( $do_all ) { + $display_all = true; + } + ?> + + + + + + + +
    + + $graphtitle ) { + if( ${'do_'.$graph} == true ) { + $display = ( ${'display_'.$graph} === true ? 'display:block' : 'display:none' ); + echo "
    "; + echo '

    ' . yourls_s( 'Number of hits : %s' , $graphtitle ) . '

    '; + switch( $graph ) { + case '24': + yourls_stats_line( $last_24h, "stat_line_$graph" ); + break; + + case '7': + case '30': + $slice = array_slice( $list_of_days, intval( $graph ) * -1 ); + yourls_stats_line( $slice, "stat_line_$graph" ); + unset( $slice ); + break; + + case 'all': + yourls_stats_line( $list_of_days, "stat_line_$graph" ); + break; + } + echo "
    \n"; + } + } ?> + +
    +

    + +

    +
    +
      + $graphtitle ) { + if ( ${'do_'.$graph} ) { + $link = "$graphtitle"; + } else { + $link = $graphtitle; + } + $stat = ''; + if( ${'do_'.$graph} ) { + switch( $graph ) { + case '7': + case '30': + $stat = yourls_s( '%s per day', round( ( ${'hits_'.$graph} / intval( $graph ) ) * 100 ) / 100 ); + break; + case '24': + $stat = yourls_s( '%s per hour', round( ( ${'hits_'.$graph} / 24 ) * 100 ) / 100 ); + break; + case 'all': + if( $ago > 0 ) + $stat = yourls_s( '%s per day', round( ( ${'hits_'.$graph} / $ago ) * 100 ) / 100 ); + } + } + $hits = sprintf( yourls_n( '%s hit', '%s hits', ${'hits_'.$graph} ), ${'hits_'.$graph} ); + echo "
    • $link $hits $stat
    • \n"; + } + ?> +
    +
    + +

    + +

    %1$s hit on %2$s', '%1$s hits on %2$s', $best['max'] ), $best['max'], yourls_date_i18n( yourls_get_date_format("F j, Y"), strtotime( $best['day'] ) ) ); ?>. +

    + + +
    + + + + ' . yourls__( 'No traffic yet. Get some clicks first!' ) . '

    '; + } ?> +
    + + +
    +

    + + + + + + + + + + +
    +

    + +

    + + +
    +

    + +
    + + + + ' . yourls__( 'No country data.' ) . '

    '; + } ?> +
    + + +
    +

    + + + + + + + + + + + +
    +

    + 1 ) + $referrer_sort[ yourls__( 'Others' ) ] = count( $referrers ); + yourls_stats_pie( $referrer_sort, 5, '440x220', 'stat_tab_source_ref' ); + unset( $referrer_sort[yourls__('Others')] ); + ?> +

    +
      + $count ) { + $i++; + $favicon = yourls_get_favicon_url( $site ); + echo "
    • $site: $count " . yourls__( '(details)' ) . "
    • \n"; + echo "\n"; + unset( $referrers[$site] ); + } + // Any referrer left? Group in "various" + if ( $referrers ) { + echo "
    • " . yourls__( 'Various:' ) . " ". count( $referrers ). " " . yourls__( '(details)' ) . "
    • \n"; + echo "\n"; + } + ?> + +
    + +
    +

    + $direct, yourls__( 'Referrers' ) => $notdirect ), 5, '440x220', 'stat_tab_source_direct' ); + ?> +

    %s hit', '%s hits', $direct ), $direct ); ?>

    +

    %s hit', '%s hits', $notdirect ), $notdirect ); ?>

    + +
    + + + + ' . yourls__( 'No referrer data.' ) . '

    '; + } ?> + +
    -
    -

    +
    +

    - ' . yourls__( 'Short link' ) . '', '

    ' . yourls__( 'Quick Share' ) . '

    '); ?> + ' . yourls__( 'Short link' ) . '', '

    ' . yourls__( 'Quick Share' ) . '

    '); ?> -
    +
    diff --git a/yourls-loader.php b/yourls-loader.php index cd9d2db2c..12fb67b6c 100644 --- a/yourls-loader.php +++ b/yourls-loader.php @@ -1,17 +1,17 @@